/***************************************************************************** Plugin changeTexture editor part Version: 1.0 Authors:Sébastien DENEUX Last update : 05/01 Change the texture of an object *****************************************************************************/ /***************************************************************************** _LDbitmap et _LDjeg en commentaires (inexistantes sous unix) *****************************************************************************/ struct AllData = [ clis_admin : [CLIENT r1], /*list of the client that have started the showChgTextureInterfaceS action*/ currentexture : S, /*the name of the current texture set on the material*/ oldTexture : S, /*the name of the old texture set on the material */ texturesList : [S r1], /*list of textures */ currentPosInTextureList : I, /*current position in the texture list */ loop : S, /*indicates that the ObtextureList list loops when uses functions .next, .prev*/ cli_uploading : CLIENT, /*the client that is currently uploading a file */ file_uploading : S, timer_uploading : Timer ]mkAllData;; typeof class=S;; var configPath="locked/conf/changeTexture/";;/*path used to save current texture and reload it when restarting server*/ var pathTexture="tmp/textures/";; /*path where textures are stored*/ var defaultMaxTextureFileSize=20480;; /*default maximum size of a texture that is uploading on the server by a client*/ /*-------------*/ fun cliByCli(a,b)=a==b;; /************************************************************************************* update config file for current ob o -> objAnchor : anchor textureList -> [S r1] : liste des textures currentTexture -> S : name of the current texture currentPos -> I : current position in the texture list **************************************************************************************/ fun updateConfigFile(o,texturesList,currentTexture,currentPos)= let _getlongname (linebuild texturesList) "" "#" -> sign in let strcatn configPath::(substr _getlongname strcat this.fileDMI ObName o "" "#" 1 8)::".conf"::nil -> configFileName in _storepack strbuild ("texture"::currentTexture::nil)::("pos"::(itoa currentPos)::nil)::("sign"::sign::nil)::nil configFileName; 0 ;; /************************************************************************************** send current texture and current position for current ob to all clients cli -> CLIENT : current client o -> objAnchor: anchor texture -> S : name of the new texture pos -> I : new position ***************************************************************************************/ fun sendCurrentTextureToAllClients(cli,o,texture,pos)= UsendMessage (ObUi o) nil "setTexture" texture; /*update client*/ UsendMessage (ObUi o) nil "setPos" itoa pos /*update client pos in list*/ ;; /***************************************************************************************** suppression d'un client ui -> UserI : user instance cli -> Client : client datas -> struct AllData ******************************************************************************************/ fun cbDelCli(o,cli,datas)= if datas.cli_uploading==cli then /*if client is currently uploading*/ ( set datas.cli_uploading = nil; 0 ) else ( set datas.clis_admin = (remove_from_list datas.clis_admin cli); 0 ) ;; /* ---- fonction a creer si necessaire -------------- fun registerS(o, from, cli, actin, param, reply,a)= nil ;; fun unregisterS(o, from, cli, actin, param, reply,a)= nil ;; ---------------.----------------------------------------------*/ /*************************************************************************************** donne l'odre au client d'affichier l'interface de changement de texture o -> objAnchor : anchor from -> cli -> CLIENT :client action -> S : action param -> S : parameters reply -> datas -> AllData ***************************************************************************************/ fun cbshowChgTextureInterface(o, from, cli, action, param, reply,datas)= set datas.clis_admin = cli::(remove_from_list datas.clis_admin cli); UsendMessage (ObUi o) cli "showChgTextureInterface" nil ;; /************************************************************************************** choix de la texture au hazzard o -> objAnchor : anchor from -> cli -> CLIENT :client action -> S : action param -> S : parameters reply -> datas -> AllData ***************************************************************************************/ fun cbsetRandomAll(o, from, cli, action, param, reply,datas)= if datas.texturesList==nil then nil /*textures list empty*/ else let mod rand sizelist datas.texturesList -> randPos in let nth_list datas.texturesList randPos -> newTexture in ( set datas.currentexture = newTexture; set datas.currentPosInTextureList = randPos; updateConfigFile o datas.texturesList newTexture randPos; sendCurrentTextureToAllClients cli o newTexture randPos ) ;; /************************************************************************************** choix de la texture dans la liste o -> objAnchor : anchor from -> cli -> CLIENT : client action -> S : action param -> S : parameters reply -> datas -> AllData ***************************************************************************************/ fun cbsetTexturePosInTexturesListAll(o, from, cli, actin, param, reply,datas)= if param != nil then if datas.texturesList==nil then nil /*textures list empty*/ else let atoi param -> newPos in if (newPos>=0) && newPos<(sizelist (datas.texturesList)) then let nth_list datas.texturesList newPos -> newTexture in ( set datas.currentexture = newTexture; set datas.currentPosInTextureList = newPos; updateConfigFile o datas.texturesList newTexture newPos; sendCurrentTextureToAllClients cli o newTexture newPos ) else let nth_list datas.texturesList datas.currentPosInTextureList -> newPosTexture in sendCurrentTextureToAllClients cli o newPosTexture datas.currentPosInTextureList else nil ;; /************************************************************************************** passage à la texture suivante o -> objAnchor : anchor from -> cli -> CLIENT : client action -> S : action param -> S : parameters reply -> datas -> AllData ***************************************************************************************/ fun cbnextTextureAll(o, from, cli, actin, param, reply,datas)= if datas.texturesList==nil then nil /*textures list empty*/ else ( let (sizelist datas.texturesList) -> size in ( if datas.currentPosInTextureList==size-1 then _DMSevent this cli strcatn (ObName o)::"."::"endListALL"::nil nil nil else nil; if datas.currentPosInTextureList < size-1 then let nth_list datas.texturesList (datas.currentPosInTextureList+1)-> newTexture in ( set datas.currentexture = newTexture; set datas.currentPosInTextureList = (datas.currentPosInTextureList+1); updateConfigFile o datas.texturesList newTexture (datas.currentPosInTextureList+1); sendCurrentTextureToAllClients cli o newTexture datas.currentPosInTextureList+1; /*if datas.currentPosInTextureList==size-2 then _DMSevent this cli strcatn (ObName o)::"."::"endListALL"::nil nil nil else nil*/ ) else if !strcmp datas.loop "1" then let nth_list datas.texturesList 0 -> newTexture in ( set datas.currentexture = newTexture; set datas.currentPosInTextureList = 0; updateConfigFile o datas.texturesList newTexture 0; sendCurrentTextureToAllClients cli o newTexture 0 ) else let nth_list datas.texturesList datas.currentPosInTextureList -> newPosTexture in sendCurrentTextureToAllClients cli o newPosTexture datas.currentPosInTextureList ) ) ;; /****************************************************************************************** passage à la texture precedente. o -> objAnchor : anchor from -> cli -> CLIENT : client action -> S : action param -> S : parameters reply -> datas -> AllData *******************************************************************************************/ fun cbpreviousTextureAll(o, from, cli, actin, param, reply,datas)= if datas.texturesList==nil then nil /*textures list empty*/ else ( if datas.currentPosInTextureList==0 then _DMSevent this cli strcatn (ObName o)::"."::"beginListALL"::nil nil nil else nil; if datas.currentPosInTextureList > 0 then let nth_list datas.texturesList (datas.currentPosInTextureList-1)-> newTexture in ( set datas.currentexture = newTexture; set datas.currentPosInTextureList = (datas.currentPosInTextureList-1); sendCurrentTextureToAllClients cli o newTexture datas.currentPosInTextureList-1; /*if datas.currentPosInTextureList==1 then _DMSevent this cli strcatn (ObName o)::"."::"beginListALL"::nil nil nil else nil*/ ) else if !strcmp datas.loop "1" then let (sizelist datas.texturesList)-1 -> newPos in let nth_list datas.texturesList newPos -> newTexture in ( updateConfigFile o datas.texturesList newTexture newPos; set datas.currentexture = newTexture; set datas.currentPosInTextureList = newPos; sendCurrentTextureToAllClients cli o newTexture newPos ) else let nth_list datas.texturesList datas.currentPosInTextureList -> newPosTexture in sendCurrentTextureToAllClients cli o newPosTexture datas.currentPosInTextureList ) ;; /*************************************************************************************** envoie de la texture au client ui -> cli -> CLIENT : client action -> S param -> S : parameters b -> [objAnchor AllData] ****************************************************************************************/ fun cbUploadingTextureFile(ui,cli,action,param,b)= let b -> [o datas] in let ObUi o -> ui2 in ( if (search_in_list datas.clis_admin @cliByCli cli)==nil then nil /*the client has not started the showChgTextureInterfaceS action*/ else if datas.cli_uploading==nil then ( set datas.file_uploading =nil; set datas.cli_uploading = cli; UsendMessage ui cli "OKuploadingTextureFile" nil ) else /*inform the client that another client is already uploading a file*/ UsendMessage ui cli "error" "2" ) ;; /******************************************************************************************** demande de la texture actuel par le client ui -> UserI : user instance cli -> CLIENT : client action -> S param -> S : parameters b -> [objAnchor AllData] *********************************************************************************************/ fun cbQtexture(ui,cli,action,param,b)= let b -> [o datas] in if datas.currentexture!=nil then /*the client ask for the current texture*/ ( UsendMessage ui cli "setTextureUploaded" datas.currentexture; /*in case of a texture has been uploaded, download it on the client*/ UsendMessage ui cli "setPos" itoa datas.currentPosInTextureList ) else nil ;; /********************************************************************************************* le delai du timer a expiré timer -> Timer : timer d'upload datas -> struct : données **********************************************************************************************/ fun cbTimerOut (timer, datas) = _deltimer datas.timer_uploading; set datas.file_uploading = nil; set datas.cli_uploading = nil; 0 ;; /******************************************************************************************** demande de la texture actuel par le client ui -> UserI : user instance cli -> CLIENT : client action -> S param -> S : parameters b -> [objAnchor AllData] *********************************************************************************************/ fun cbTextureFilePacket (ui, cli, action, param, b) = let b -> [o datas] in ( _deltimer datas.timer_uploading; if (datas.cli_uploading!=cli) then nil else if param==nil then /*end file*/ ( let _getlongname datas.file_uploading "texture" "#" -> sign in /*calculate a signature*/ let strcat pathTexture sign -> textureFileName in ( _storepack datas.file_uploading textureFileName; /*record the file on the disk*/ let _checkpack textureFileName -> p in let hd UgetParam ui "maxtexturefileSize" -> size in /*get maxTextureFileSize*/ let (if size==nil then defaultMaxTextureFileSize else atoi size) -> maxTextureFileSize in if /*(((_LDbitmap _channel p)==nil) && ((_LDjpeg _channel p)==nil)) */ /*test if the file format is valid*/ ((_fileSize p) > maxTextureFileSize) then /*check the filesize*/ ( set datas.cli_uploading = nil; set datas.file_uploading = nil; UsendCli this cli (ObUi o) "error" "1" /*inform the client that the file format is invalid or file is too big*/ ) else /*bitmap OK*/ ( _RSregister this textureFileName RScontrol datas.file_uploading; /*register the file*/ updateConfigFile o datas.texturesList textureFileName datas.currentPosInTextureList; set datas.cli_uploading = nil; set datas.file_uploading = nil; set datas.currentPosInTextureList = nil; set datas.currentexture = textureFileName; UsendCli this cli (ObUi o) "UploadSuccessfull" nil; /*inform the client that upload was successfull*/ UsendCli this nil (ObUi o) "setTextureUploaded" textureFileName /*inform all clients that the texture has changed*/ ); ); 0 ) else ( set datas.file_uploading = strcat datas.file_uploading param; set datas.timer_uploading = _rfltimer _starttimer _channel 3000 @cbTimerOut datas; 0 ) ) ;; /******************************************************************************************** demande de la texture actuel par le client ui -> UserI : user instance cli -> CLIENT : client action -> S param -> S : parameters b -> [objAnchor AllData] *********************************************************************************************/ fun cbNextPacket (ui, cli, action, param, b) = let b -> [o data] in if (data.cli_uploading != cli) then nil else UsendCli this cli (ObUi o) "OKnextPacket" nil; 0 ;; /*-------------*/ /* Demarrage d'une nouvelle instance */ fun newOb(o)= let strcatn configPath::(substr _getlongname strcat this.fileDMI ObName o "" "#" 1 8)::".conf"::nil -> configFileName in let (lineextr hd UgetParam ObUi o "texturesList") -> texturesList in let (hd UgetParam ObUi o "loop") -> loop in let _getlongname (linebuild texturesList) "" "#" -> newSign in let if (atoi hd UgetParam ObUi o "keepDynamicChanges")==1 then /*if keepDynamicChanges==1*/ let strextr _getpack _checkpack configFileName -> l in let getInfo l "sign" -> sign in let getInfo l "texture" -> texture in let _checkpack texture -> p in if (!strcmp sign newSign) then let atoi getInfo l "pos" -> pos in ( _RSregister this texture RScontrol+RSfile texture; /*register the file*/ _storepack strbuild ("texture"::texture::nil)::("pos"::(itoa pos)::nil)::("sign"::newSign::nil)::nil configFileName; [nil texture nil texturesList pos loop nil nil nil] ) else /*do not load old values : set iniPos if possible*/ let atoi (hd UgetParam ObUi o "iniPos") -> iniPos in if texturesList!=nil && iniPos>=0 && iniPos<(sizelist texturesList) then let nth_list texturesList iniPos -> textureName in ( _storepack strbuild ("texture"::textureName::nil)::("pos"::(itoa iniPos)::nil)::("sign"::newSign::nil)::nil configFileName; [nil textureName nil texturesList iniPos loop nil nil nil] ) else ( _storepack strbuild ("texture"::nil)::("pos"::nil)::("sign"::newSign::nil)::nil configFileName; [nil nil nil texturesList 0 loop nil nil nil] ) else /*keepDynamicChanges==0, set iniPos if possible*/ let atoi (hd UgetParam ObUi o "iniPos") -> iniPos in if texturesList!=nil && iniPos>=0 && iniPos<(sizelist texturesList) then let nth_list texturesList iniPos -> textureName in ( _storepack strbuild ("texture"::textureName::nil)::("pos"::(itoa iniPos)::nil)::("sign"::newSign::nil)::nil configFileName; [nil textureName nil texturesList iniPos loop nil nil nil] ) else ( _storepack strbuild ("texture"::nil)::("pos"::nil)::("sign"::nil)::nil configFileName; [nil nil nil texturesList 0 loop nil nil nil] ) -> a in /*clis_admin timerTimeout timerTimeoutFlag currentCliUploading tempBuffer ObCurrentTexture ObOldtexture ObtextureList currentPosInTexturesList loop*/ let mkAllData a -> datas in ( _RSregisterfiles this texturesList RScontrol+RSfile; /*register the files contains in the textures list*/ ObRegisterAction o (strcatn (ObName o)::".setRandomALL"::nil) mkfun7 @cbsetRandomAll datas; ObRegisterAction o (strcatn (ObName o)::".setTexturePosInTexturesListALL"::nil) mkfun7 @cbsetTexturePosInTexturesListAll datas; ObRegisterAction o (strcatn (ObName o)::".nextTextureALL"::nil) mkfun7 @cbnextTextureAll datas; ObRegisterAction o (strcatn (ObName o)::".previousTextureALL"::nil) mkfun7 @cbpreviousTextureAll datas; ObRegisterAction o (strcatn (ObName o)::".showChgTextureInterface"::nil) mkfun7 @cbshowChgTextureInterface datas; UcbMessage ObUi o ["texture?" mkfun5 @cbQtexture [o datas]]:: ["UploadingTextureFile?" mkfun5 @cbUploadingTextureFile [o datas]]:: ["nextPacket?" mkfun5 @cbNextPacket [o datas]]:: ["TextureFilePacket" mkfun5 @cbTextureFilePacket [o datas]]:: nil; OB_CBclientDestroyed o mkfun3 @cbDelCli datas; 0 ); 0 ;; /*-------------*/ fun IniPlug(file)= srand _tickcount;/*initialize random*/ set class=getInfo strextr _getpack _checkpack file "name"; PlugRegister class @newOb nil; 0;;