llGiveInventory not working as documented
|
|
Jeff Kelley
Registered User
Join date: 8 Nov 2006
Posts: 223
|
12-02-2006 15:33
From: someone If the recipient is an object, and the object already has something in its inventory with this name, then Second Life will check to see if the object being given differs from the object already existing in the recipient's inventory, or if it is another copy of the same object (ie, the object is being given multiple times). If it is the same object being given multiple times, nothing happens at all, and the recipient's inventory does not change. If the object is deemed to be a different object with the same name, it will create a new copy with an incremented number, as if a user manually placed an item with a duplicate name into an object's inventory. This is not the behaviour i see: giving multiple times the same object results in Object 1, Object 2, Object 3. Did i miss somethig?
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
12-02-2006 15:38
From: Jeff Kelley This is not the behaviour i see: giving multiple times the same object results in Object 1, Object 2, Object 3. Did i miss somethig? Where is that documented from?
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
12-02-2006 15:49
From: Tyken Hightower Where is that documented from? It states that in the wiki page llGiveInventory
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
12-02-2006 16:04
From: Jesse Barnett It states that in the wiki page llGiveInventory Fun. Unfortunately, I don't know offhand whether it's been like that or if this is new behavior, since I do virtually no object to object inventory transfers. Could just be the wiki is outdated there.
|
|
Jeff Kelley
Registered User
Join date: 8 Nov 2006
Posts: 223
|
12-02-2006 17:10
From: Tyken Hightower Could just be the wiki is outdated there. Hope not! I'm remotely updating region-wide Notecards/Landmarks givers and I don't want a "Notecard 17". There is no llRenameInventory. The only solution I see is to broadcast a "update available" to trigger a llRemoveInventory, acknowledge it and wait for the server to do llGiveInventory. What a mess!
|
|
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
|
12-02-2006 17:59
From: Jeff Kelley Hope not! I'm remotely updating region-wide Notecards/Landmarks givers and I don't want a "Notecard 17". There is no llRenameInventory. The only solution I see is to broadcast a "update available" to trigger a llRemoveInventory, acknowledge it and wait for the server to do llGiveInventory. What a mess! Why not go the other direction, where each station sends a request to the server, and the server passes the agent the item(s)? THen when you update the items, you've only the one spot to deal with.
|
|
Jeff Kelley
Registered User
Join date: 8 Nov 2006
Posts: 223
|
12-02-2006 19:18
From: Jillian Callahan Why not go the other direction, where each station sends a request to the server, and the server passes the agent the item(s)? THen when you update the items, you've only the one spot to deal with. The station is a relay sending the server "GIVE ITEM name TO AGENT key"? Is that what you mean? The station can send a email, but this costs a 20s delay (or i have to multithread). It can also give the server an object carrying a message, which i think is faster but i can't figure how to encrypt this message.
|
|
Yumi Murakami
DoIt!AttachTheEarOfACat!
Join date: 27 Sep 2005
Posts: 6,860
|
12-02-2006 19:33
I wrote that piece on the wiki - it applied to the previous version, though. I posted a thread about it too (here: /54/9d/118718/1.html ) where it seemed to be acknowledged as correct.
|
|
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
|
12-02-2006 23:04
From: Jeff Kelley The station is a relay sending the server "GIVE ITEM name TO AGENT key"? Is that what you mean? The station can send a email, but this costs a 20s delay (or i have to multithread). It can also give the server an object carrying a message, which i think is faster but i can't figure how to encrypt this message. Yes, that's what I mean. And you could use email, or shouts + relays. Not sure you really need to encrypt it... LSL is terrible slow so encryptionis a mighty pain. Another option that's faster and keeps it all in the sim is to have the station rez a messenger, chat the message to it, and the messenger then warppositself to the server, where it chats its message.
|
|
Nynthan Folsom
Registered User
Join date: 29 Aug 2006
Posts: 70
|
12-03-2006 00:18
Some objects or "assets" have fixed UUIDs. Examples are textures, sounds, and animations(unless you explicitely upload 2 identical versions of any of these). So when you "copy" one of these assets from inventory to the contents of prims or between prims, you are only copying the UUID key, i.e, a reference, not the actual object. In these cases, it's pointless to duplicate the contents and llGiveInventory will just silently fail.
Other objects, however, like prims, link sets, notecards, are actually DUPLICATED so that if you modify the copy, it doesn't affect the original. In this case, the new object actually receives a new UUID key and is considered a completely new object, even though it may have the same name. But because prims cannot contain objects with the same name (unlike your own inventory), llGiveInventory will rename the new object.
|
|
Nynthan Folsom
Registered User
Join date: 29 Aug 2006
Posts: 70
|
12-03-2006 00:49
One possible solution would be to use llRemoteLoadScriptPin() to upload a script to the destination object that would first delete the notecard and then delete itself. Then use llGiveInventory to upload the card. There might be some issues with timing though. So in the destination prim create a script that sets the PIN code. default { state_entry() { default { llSetRemoteScriptAccessPin(123456); } } }Once this has executed, you can delete it becase the PIN code is a property of the prim, and not the script. Then in the the source prim create a script to delete a notecard, but make sure that it's deactivated or it will delete the original notecard and then delete itself! default { state_entry() { llRemoveInventory("your_card_name"); }
changed(integer iChange) { if(iChange & CHANGED_INVENTORY) { llRemoveInventory(llGetScriptName()); } } }And finally, create a script in the source prim that will upload the script, wait for a bit, and then upload the notecard. default { state_entry() { key destinationPrimKey = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; string deleteNotecardScriptName = "DeleteNotecardScript"; integer accessPIN = 123456; integer startScriptOnLoad = TRUE; llRemoteLoadScriptPin( destinationPrimKey, deleteNotecardScriptName, accessPin, startScriptOnLoad, // This causes the script to execute once loaded 0); // The script is delayed for 3 seconds at this point, but you could delay for // longer to make sure the script has had enough time to delete the card. llSleep(7); // Perhaps for a full 10 secs?
llGiveInventory(destinationPrimKey, "your_card_name"); } }
|
|
Jeff Kelley
Registered User
Join date: 8 Nov 2006
Posts: 223
|
12-03-2006 06:28
From: Nynthan Folsom Some objects or "assets" have fixed UUIDs. Examples are textures, sounds, and animations(unless you explicitely upload 2 identical versions of any of these). So when you "copy" one of these assets from inventory to the contents of prims or between prims, you are only copying the UUID key, i.e, a reference, not the actual object. In these cases, it's pointless to duplicate the contents and llGiveInventory will just silently fail. But it doesn't. Object1 gives "Example Notecard" to object2 twice. Object2 has "Example Notecard", "Example Notecard 1". Dumping the inventory in object2 confirms that "Example Notecard" and "Example Notecard 1" have same UUID. However, this approach will never work because what i want to give is not the same Notecard but the updated Notecard with same name, that is a different UUID with same name. I MUST delete the old Notecard before giving the new one. So, I was wrong from the beginning. From: Jillian Callahan Not sure you really need to encrypt it... LSL is terrible slow so encryption is a mighty pain. I should write "encoding", not "encryption" (sorry, same word for both in french)
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
12-03-2006 12:21
Why not pass the inventory to a prim in the linked set that isn't the one that needs updating. Then you can identify any inventory conflicts via link_messages so you can delete any conflicting notecards first.
Or better yet; why does the name matter at all? Just make it so your code can handle the duplicates and remove any old notecards.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
12-03-2006 12:59
On second thought, the best solution is to just not keep the notecards around after you receive them. Record their UUID's and then delete them from inventory; problem solved.
Or better yet, why bother with the time consuming inventory transfer. Just use chat and send the notecard UUID.
Course if you are dealing with objects you can't manipulate them with uuid.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
12-03-2006 14:13
Quick and dirty script for handling names. It might work. I will only guaranty that it compiles. Two commands: llMessageLinked(LINK_THIS, 1, "name", "#type"  ;//get the current name for this type llMessageLinked(LINK_THIS, 2, "name", "#type"  ;//remove monitoring & culling for this name You must supply name & type (type as an integer cast to a string) otherwise it will not work. See to it that the names it monitors don't collide if they have overlapping types, otherwise results will be "interesting". Will send back results on inventory change or upon a 1 request. llMessageLinked(LINK_THIS, 3, "name", "real-name"  ; list starts; list currents;
default { changed(integer a) { if(a & CHANGED_INVENTORY) { a = [] != starts; @top; while(a) {//i need sleep integer b = llList2Integer(starts, ~-a); integer c = llGetInventoryNumber(b); string d = llList2String(starts, a -= 2); integer f = llStringLength(d); string h = llList2String(currents, a); while(c) { string e = llGetInventoryName(b, --c); if(e != h) { if(d == llDeleteSubString(e, f, 0x10000)) { llMessageLinked(LINK_THIS, 3, d, e); currents = llListReplaceList(currents, [e], a >> 1, a >> 1); integer g = c; while(g) if(d == llDeleteSubString(e = llGetInventoryName(b, --g), f, 0x10000)) llRemoveInventory(e); if((llGetInventoryType(h) == b) == (!~b))//passed it? llRemoveInventory(h); jump top; } } } } } } link_message(integer a, integer b, string c, key d) { integer e = (integer)((string)d); if(b == 1) {//Get Current from Start (also adds monitoring) if(~(a = (llListFindList(starts, [c, e]) >> 1))) d = llList2Key(currents,a); else { a = llStringLength(c); b = llGetInventoryNumber(e); starts += [c, e]; while(b) { if(c == llDeleteSubString(d = llGetInventoryName(e, --b), a, 0x10000)) { currents += d; while(b) { string g = llGetInventoryName(e, --b); if(c == llDeleteSubString(g, a, 0x10000)) llRemoveInventory(g); } jump over; } } currents += (d = ""); } @over; llMessageLinked(LINK_THIS, 3, c, d); } else if(b == 2) {//Remove Start if(~(a = llListFindList(starts, [c,e]))) { starts = llDeleteSubList(starts,a, 1 + a); currents = llDeleteSubList(currents,b = (a >> 1),b); } } } }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
|
12-03-2006 22:26
From: Nynthan Folsom One possible solution would be to use llRemoteLoadScriptPin() to upload a script to the destination object that would first delete the notecard and then delete itself. Then use llGiveInventory to upload the card. There might be some issues with timing though. So in the destination prim create a script that sets the PIN code. default { state_entry() { default { llSetRemoteScriptAccessPin(123456); } } }Once this has executed, you can delete it becase the PIN code is a property of the prim, and not the script. Unfortantly if the owner makes a copy, the copy will not have the pin set. Same is true for sit targets, which is why they generaly have a script in each sitball even though it is not needed.
|
|
Nynthan Folsom
Registered User
Join date: 29 Aug 2006
Posts: 70
|
12-04-2006 09:35
Ah. In that case, leave the script in, and use an on_rez to make sure it runs when you copy the object.
|