/***************************************************************/ /* */ /* IDSRV.PKG */ /* */ /* plugin ItemsDistribution */ /* server */ /* */ /* by Loïc Berthelot, CryoNetworks, fev 2001 */ /* */ /***************************************************************/ /********************************************************************************/ /********************************************************************************/ /** **/ /** D A T A **/ /** **/ /********************************************************************************/ /********************************************************************************/ typeof class=S;; /* item structure */ struct ItemD = [ /* instance 3d */ o_ITMD : Ob, /* name of m3d file */ filename_ITMD : S, /* item name */ objName_ITMD : S, /* list of positions */ posList_ITMD : [[[S r1] r1] r1], /* size of list */ nbPos_ITMD : I, /* current item position */ currentPos_ITMD : [[S r1] r1], /* 1 if activated, 0 if not */ stateFlag_ITMD : I, /* delay before item appears again */ timeout_ITMD : I ] mkItemD;; /* items list */ typeof itemsList = [ItemD r1];; /* clients list */ /* [client code_show] */ typeof IDcliList = [[CLIENT I] r1];; /********************************************************************************/ /********************************************************************************/ /** **/ /** B O D Y **/ /** **/ /********************************************************************************/ /********************************************************************************/ /******************************************************/ /* */ /* utils functions for search in lists */ /* */ /******************************************************/ fun itdSrv_itemByItem (el, objName) = !strcmp el.objName_ITMD objName;; fun itdSrv_posByPos (el, posName) = let el -> [ [elPosName _] _] in !strcmp elPosName posName;; fun itdSrv_cliByCli (el, cli) = let el -> [elcli _] in elcli == cli ;; /****************************************************/ /* itdSrv_makeItemAppearOnCli [[CLIENT I] [Ob S]] I */ /* */ /* make the item appear on the specific client */ /* */ /****************************************************/ fun itdSrv_makeItemAppearOnCli (cliel, tuple) = let cliel -> [cli showCode] in if (showCode == 0) then nil else let tuple -> [o pos] in UsendMessage (ObUi o) cli "active" pos; 1;; fun itdSrv_makeDisappearOnCli (item, cliel) = let cliel -> [cli _] in if (item.stateFlag_ITMD) then ( UsendMessage (ObUi item.o_ITMD) cli "hide" nil; 1; ) else nil;; fun itdSrv_makeAppearOnCli (item, cli) = if (item.stateFlag_ITMD) then ( UsendMessage (ObUi item.o_ITMD) cli "active" (strbuild item.currentPos_ITMD); 1; ) else ( nil; );; /***********************************************/ /* itdSrv_makeAppear [[Ob ItemD]] I */ /* */ /* broadcast transmission to all clients : */ /* make the item appear */ /* */ /***********************************************/ fun itdSrv_makeAppear (item) = if (!item.stateFlag_ITMD) then nil else ( apply_on_list IDcliList @itdSrv_makeItemAppearOnCli [item.o_ITMD (strbuild item.currentPos_ITMD)]; ); 1;; /***********************************************/ /* itdSrv_active [Timer ItemD] I */ /* */ /* activate the item */ /* */ /***********************************************/ fun itdSrv_active (t, item) = if (t != nil) then _deltimer t else nil; /* determine the new position, */ /* with a random process of the positions list */ if item.nbPos_ITMD == 0 then nil else let mod rand item.nbPos_ITMD -> index in let nth_list item.posList_ITMD index -> pos in ( set item.stateFlag_ITMD = 1; set item.currentPos_ITMD = pos; itdSrv_makeAppear item; ); 1;; /***************************************************/ /* itdSrv_take [S [UserI r1] I ItemD] I */ /* */ /* action to authorize server to authorize client */ /* to take the item :) */ /* */ /***************************************************/ fun itdSrv_take (param, users, item) = set item.stateFlag_ITMD = 0; /* item disappear from all clients */ UsendMessage (ObUi item.o_ITMD) nil "hide" nil; let _starttimer _channel item.timeout_ITMD -> t in _rfltimer t @itdSrv_active item; 1;; /***************************************************/ /* itdSrv_indicate [UserI CLIENT S S ItemD] I */ /* */ /* client ask server to authorize him to pick */ /* the item */ /* */ /***************************************************/ fun itdSrv_indicate (ui, cli, action, param, item) = if (item.stateFlag_ITMD) then ( _DMSeventTag this (CtoU cli) (strcat class ".indicate") item.objName_ITMD nil [mkfun3 @itdSrv_take item 3600 0]; ) else /* the item is already taken */ nil; 1;; /*************************************************/ /* itdSrv_addPos [UserI CLIENT S S ItemD] I */ /* */ /* client transmits an item position, */ /* server adds it to the positions list. */ /* */ /*************************************************/ fun itdSrv_addPos (ui, cli, action, param, item) = if (param == nil) then ( /* if position == nil, the transmission */ /* is over. activate the item activated */ /* and make it appear on the client browsers */ if (item.stateFlag_ITMD) then nil else itdSrv_active nil item; ) else ( let strextr param -> params in /* get the position name, and search for it */ /* in the list */ let params -> [ [posName _] _] in let search_in_list item.posList_ITMD @itdSrv_posByPos posName -> el in if (el != nil) then /* already has been registered, */ /* don't do it twice */ nil else ( /* add position to the list */ set item.nbPos_ITMD = item.nbPos_ITMD + 1; set item.posList_ITMD = params::item.posList_ITMD; ); 1; );; fun ClientDeleted(o,cli)= let search_in_list IDcliList @itdSrv_cliByCli cli -> el in if (el == nil) then nil else set IDcliList = remove_from_list IDcliList el; 0 ;; /***********************************************/ /* itdSrv_register [UserI CLIENT S S ItemD] I */ /* */ /* client registers to server */ /* */ /***********************************************/ fun itdSrv_register (ui, cli, action, param, item) = let search_in_list IDcliList @itdSrv_cliByCli cli -> e in /*seb*/ if e == nil then ( set IDcliList = [cli 0]::IDcliList; 0 ) else let e -> [_ showCode] in if showCode then apply_on_list itemsList @itdSrv_makeAppearOnCli cli else nil; /* ask for item positions */ let IDcliList -> [[fstCli _] _] in if ( ((sizelist IDcliList) == 1) && (cli == fstCli)) then UsendMessage ui cli "addPos" nil else nil; 0 ;; /**********************************************/ /* itdSrv_addItem [Ob S S I] ItemD */ /* */ /* add the item to the server items list , */ /* and return the item created. */ /* */ /**********************************************/ fun itdSrv_addItem (o, filename, objName, timeout) = let nil -> posList in let 0 -> nbPos in let nil -> currentPos in let 0 -> stateFlag in let mkItemD [o filename objName posList nbPos currentPos stateFlag timeout] -> newItem in ( set itemsList = newItem::itemsList; newItem; );; /**********************************************/ /* newOb [Ob] I */ /* */ /* entry of instance */ /* */ /**********************************************/ fun newOb(o)= OB_CBclientDestroyed o @ClientDeleted; /* get the parameters */ let hd UgetParam ObUi o "itemDObjName" -> objName in let hd UgetParam ObUi o "itemDTimeout" -> timeout in let hd UgetParam ObUi o "itemDFilename" -> filename in let hd UgetParam ObUi o "itemDTextureFilename" -> textureFilename in /* add the item to the list */ let itdSrv_addItem o filename objName (atoi timeout) -> newItem in ( /* allow clients to download */ /* the item files */ _RSregister this filename RSfile|RScontrol filename; _RSregister this textureFilename RSfile|RScontrol textureFilename; UcbMessage ObUi o ["addPos" mkfun5 @itdSrv_addPos newItem]:: ["indicate" mkfun5 @itdSrv_indicate newItem]:: ["register" mkfun5 @itdSrv_register newItem]::nil; 1; ) ;; fun itd_showObjects (from, user, action, param, uList, tag) = let UtoC user -> cli in let search_in_list IDcliList @itdSrv_cliByCli cli -> e in if e == nil then ( set IDcliList = [cli 1]::IDcliList; apply_on_list itemsList @itdSrv_makeAppearOnCli cli; 0 ) else let e -> [_ showCode] in if showCode then nil else ( mutate e <- [_ 1]; apply_on_list itemsList @itdSrv_makeAppearOnCli cli; 0 ) ;; fun itd_hideObjects (from, user, action, param, uList, tag) = let search_in_list IDcliList @itdSrv_cliByCli (UtoC user) -> el in if el == nil then nil else let el -> [cli showCode] in if !showCode then nil else ( mutate el <- [_ 0]; apply_on_list itemsList @itdSrv_makeDisappearOnCli el; 0 ) ;; /*********************************************/ /* */ /* INITIALISATION */ /* */ /*********************************************/ fun IniPlug(file)= srand time; set class=getInfo strextr _getpack _checkpack file "name"; PlugRegister class @newOb nil; _DMSdefineActions this [(strcat class ".showObjects") @itd_showObjects]:: [(strcat class ".hideObjects") @itd_hideObjects]::nil; 0;;