llTransferOwnership() with flag 0x4 still allows no-copy inventory duplication.
complete
Lucia Nightfire
llTransferOwnership() with flag 0x4 still allows no-copy inventory duplication.
Call the function with flag 0x4, pending offer is created, disable Locked status, drop in no-copy object, accept pending offer, take no-copy object back to your inventory, repeat.
Similar to how the server removes no-transfer-for-owner content after owner change, it should probably remove no-copy-for-owner content in the original after this function (with flag 0x4) makes an offer.
Log In
This post was marked as
complete
Maestro Linden
tracked
Maestro Linden
Hi Lucia, I gave this a try but can't repro in Apple Cobbler 2024-11-26.12040480539. I'm seeing the expected behavior - the LSL call fails with TRANSFER_NO_PERMS. Is your setup different from mine?
- UserA: obtain an empty object that is modify/no-copy/transfer (appears as 'O:VMT' in 'debug permissions')
- UserA: Create the script shown in child comment in the object
- UserB: Touch the object. The script will then call llTransferOwnership(UserB, TRANSFER_FLAG_COPY)
Expected results (which I am seeing now):
- The llTransferOwnership() call should fail, and return TRANSFER_NO_PERMS (-6)
- The object's ownership should remain unchanged
- UserB's inventory should get no new objects
Maestro Linden
// Basic test script for llTransferOwnership
// https://wiki.secondlife.com/wiki/LlTransferOwnership
string transferReturnCodeToLabel(integer c)
{
// while the error codes are negative, we can take advantage of
// llList2String()'s negative index behavior to return the correct values
list codes = [
TRANSFER_OK,
TRANSFER_NO_ATTACHMENT,
TRANSFER_NO_PERMS,
TRANSFER_BAD_ROOT,
TRANSFER_NO_ITEMS,
TRANSFER_THROTTLE,
TRANSFER_NO_TARGET,
TRANSFER_BAD_OPTS
];
list code_labels = [
"TRANSFER_OK",
"TRANSFER_NO_ATTACHMENT",
"TRANSFER_NO_PERMS",
"TRANSFER_BAD_ROOT",
"TRANSFER_NO_ITEMS",
"TRANSFER_THROTTLE",
"TRANSFER_NO_TARGET",
"TRANSFER_BAD_OPTS"
];
return llList2String(codes, c) + " (" + llList2String(code_labels, c) + ")";
}
setOwnerText()
{
llSetText("Owned by " + (string)llGetOwner(), <1,1,1>, 1);
}
integer touch_count;
default
{
state_entry()
{
llSay(0, "Touch me to take ownership");
setOwnerText();
}
touch_start(integer total_number)
{
integer transferFlags = TRANSFER_FLAG_COPY;
string touch_event = "Touch event " + (string)(touch_count++);
llSay(0, touch_event + ": Current owner is " + (string)llGetOwner());
llSay(0, touch_event + ": Calling llTransferOwnership(\"" + (string)llDetectedKey(0)
+ "\", " + (string)transferFlags + ")");
integer result = llTransferOwnership(llDetectedKey(0), transferFlags);
llSay(0, touch_event + ": llTransferOwnership() result is " + transferReturnCodeToLabel(result));
setOwnerText();
}
changed(integer change)
{
if(change & CHANGED_OWNER)
{
llSay(0, "Changed owner. New owner is " + (string)llGetOwner());
setOwnerText();
}
}
}
Maestro Linden
needs info
Lucia Nightfire
llGiveInventory() will remove no-copy content after execution, so why not llTransferOwnership() (with flag 0x4)?