From ca722ecdd89f4e06d5767d87bf156cfd514d862b Mon Sep 17 00:00:00 2001 From: Adil El Farissi <144741970+AdilElFarissi@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:36:33 +0000 Subject: [PATCH 1/3] Add some OSSL functions related to child prims inventory manipulations Add functions: + osGiveLinkInventory(integer linkNumber, key destination, string inventory) Give an item located in a child prim inventory. + osGetInventoryNames(integer type) Return a list of items names by type (or INVENTORY_ALL) located in the prim inventory. + osGetLinkInventoryNames(integer linkNumber, integer type) Return a list of items names by type (or INVENTORY_ALL) located in a child prim inventory. + osGetInventoryKeys(integer type) Return a list of the items UUIDs by type (or INVENTORY_ALL) located in the prim inventory. + osGetLinkInventoryKeys(integer linkNumber, integer type) Return a list of the items UUIDs by type (or INVENTORY_ALL) located in a child prim inventory. + osGetLinkInventoryKey(integer linkNumber, string name) Return the UUID of the specified item name located in a child prim inventory. + osGetLinkInventoryDesc(integer linkNumber, string itemNameorid) Return the description of an item located in a child prim inventory. + osGetLinkInventoryName(integer linkNumber, key itemId) Return the name of an item located in a child prim inventory. Note: the LinkInventory functions don't have access to the root prim contents. This may change if requested by the community... --- .../Shared/Api/Implementation/OSSL_Api.cs | 217 +++++++++++++++++- .../Shared/Api/Interface/IOSSL_Api.cs | 8 + .../Shared/Api/Runtime/OSSL_Stub.cs | 43 ++++ bin/ScriptSyntax.xml | 55 +++++ 4 files changed, 322 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 3daf57c572..21b36cce72 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -161,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected ISoundModule m_SoundModule = null; protected IEnvironmentModule m_envModule = null; protected IGroupsModule m_groupsModule = null; + protected IMessageTransferModule m_TransferModule = null; public void Initialize(IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) { //private init @@ -172,6 +173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_SoundModule = m_ScriptEngine.World.RequestModuleInterface(); m_envModule = m_ScriptEngine.World.RequestModuleInterface(); m_groupsModule = m_ScriptEngine.World.RequestModuleInterface(); + m_TransferModule = m_ScriptEngine.World.RequestModuleInterface(); //private init lock (m_OSSLLock) @@ -2135,7 +2137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void MessageObject(UUID objUUID, string message) { - object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) }; + object[] resobj = new object[] { new LSL_String(m_host.UUID.ToString()), new LSL_String(message) }; SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID); @@ -5505,6 +5507,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return (item is null) ? LSL_String.Empty : item.Name; } + public LSL_String osGetLinkInventoryName(LSL_Integer linkNumber, LSL_Key itemId) + { + if(linkNumber <= 1) + return LSL_String.Empty; + + TaskInventoryItem item = null; + SceneObjectPart part = GetSingleLinkPart(linkNumber); + if(part == null) + return LSL_String.Empty; + + if (UUID.TryParse(itemId, out UUID itemID)) + item = part.Inventory.GetInventoryItem(itemID); + + return (item is null) ? LSL_String.Empty : item.Name; + } + public LSL_String osGetInventoryDesc(LSL_String itemNameorid) { TaskInventoryItem item; @@ -5516,6 +5534,203 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return (item == null) ? LSL_String.Empty : item.Description; } + public LSL_String osGetLinkInventoryDesc(LSL_Integer linkNumber, LSL_String itemNameorid) + { + if(linkNumber <= 1) + return LSL_String.Empty; + + TaskInventoryItem item; + SceneObjectPart part = GetSingleLinkPart(linkNumber); + if(part == null) + return LSL_String.Empty; + + if (UUID.TryParse(itemNameorid, out UUID itemID)) + item = part.Inventory.GetInventoryItem(itemID); + else + item = part.Inventory.GetInventoryItem(itemNameorid); + + return (item == null) ? LSL_String.Empty : item.Description; + } + + public LSL_Key osGetLinkInventoryKey(LSL_Integer linkNumber, LSL_String name) + { + if(linkNumber <= 1) + return LSL_String.NullKey; + + SceneObjectPart part = GetSingleLinkPart(linkNumber); + if(part == null) + return LSL_String.NullKey; + + TaskInventoryItem item = part.Inventory.GetInventoryItem(name); + if (item is null) + return LSL_String.NullKey; + + if ((item.CurrentPermissions + & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) + == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) + { + return new LSL_Key(item.ItemID.ToString()); + } + + return LSL_String.NullKey; + } + + public LSL_List osGetInventoryKeys(LSL_Integer type) + { + LSL_List ret = new(); + + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) + { + if (inv.Value.Type == type || type == -1) + ret.Add(inv.Value.ItemID); + } + + m_host.TaskInventory.LockItemsForRead(false); + return ret; + } + + public LSL_List osGetLinkInventoryKeys(LSL_Integer linkNumber, LSL_Integer type) + { + LSL_List ret = new(); + if(linkNumber <= 1) + return ret; + + SceneObjectPart part = GetSingleLinkPart(linkNumber); + if(part == null) + return ret; + + part.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in part.TaskInventory) + { + if (inv.Value.Type == type || type == -1) + ret.Add(inv.Value.ItemID.ToString()); + } + + part.TaskInventory.LockItemsForRead(false); + return ret; + } + + public LSL_List osGetInventoryNames(LSL_Integer type) + { + LSL_List ret = new(); + + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) + { + if (inv.Value.Type == type || type == -1) + ret.Add(inv.Value.Name); + } + + m_host.TaskInventory.LockItemsForRead(false); + return ret; + } + + public LSL_List osGetLinkInventoryNames(LSL_Integer linkNumber, LSL_Integer type) + { + LSL_List ret = new(); + if(linkNumber <= 1) + return ret; + + SceneObjectPart part = GetSingleLinkPart(linkNumber); + if(part == null) + return ret; + + part.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in part.TaskInventory) + { + if (inv.Value.Type == type || type == -1) + ret.Add(inv.Value.Name); + } + + part.TaskInventory.LockItemsForRead(false); + return ret; + } + + /// + /// Give a specified item from a child prim inventory + /// to a destination (object or avatar). + /// + ///The link number of the child prim. + ///The UUID of the destination avatar or object. + ///The name of the item to give. + public void osGiveLinkInventory(LSL_Integer linkNumber, LSL_Key destination, LSL_String inventory) + { + if(linkNumber <= 1) + return; + + if (!UUID.TryParse(destination, out UUID destId) || destId.IsZero()) + return; + + SceneObjectPart part = GetSingleLinkPart(linkNumber); + if(part == null) + return; + + UUID inventoryID = ScriptUtils.GetAssetIdFromKeyOrItemName(part, inventory); + if (inventoryID.IsZero()) + return; + + TaskInventoryItem item = part.Inventory.GetInventoryItem(inventory); + if (item == null) + return; + + UUID objId = item.ItemID; + + // check if destination is an object + if (World.GetSceneObjectPart(destId) != null) + { + // destination is an object + World.MoveTaskInventoryItem(destId, part, objId); + } + else + { + ScenePresence presence = World.GetScenePresence(destId); + + if (presence == null) + { + + UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, destId); + + if (account == null) + { + GridUserInfo info = World.GridUserService.GetGridUserInfo(destId.ToString()); + if(info == null || info.Online == false) + return; + + } + } + + // destination is an avatar + InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, part, objId, out string message); + + if (agentItem == null) + { + m_LSL_Api.llSay(0, message); + return; + } + + byte[] bucket = new byte[1]; + bucket[0] = (byte)item.Type; + + GridInstantMessage msg = new GridInstantMessage(World, + m_host.OwnerID, m_host.Name, destId, + (byte)InstantMessageDialog.TaskInventoryOffered, + m_host.OwnerID.Equals(m_host.GroupID), "'"+item.Name+"'. ("+m_host.Name+" is located at "+ + World.RegionInfo.RegionName + " "+ m_host.AbsolutePosition.ToString() + ")", + agentItem.ID, true, m_host.AbsolutePosition, + bucket, true); + + if (World.TryGetScenePresence(destId, out ScenePresence sp)){ + sp.ControllingClient.SendInstantMessage(msg); + } + else{ + m_TransferModule?.SendInstantMessage(msg, delegate(bool success) {}); + } + //This delay should only occur when giving inventory to avatars. + ScriptSleep(3000); + } + } + public LSL_Key osGetLastChangedEventKey() { DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index c9674b0d59..e4a9ae9607 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -561,8 +561,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin); LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId); LSL_Key osGetInventoryItemKey(LSL_String name); + LSL_Key osGetLinkInventoryKey(LSL_Integer linkNumber, LSL_String name); LSL_String osGetInventoryName(LSL_Key itemId); + LSL_String osGetLinkInventoryName(LSL_Integer linkNumber, LSL_Key itemId); LSL_String osGetInventoryDesc(LSL_String itemNameOrId); + LSL_String osGetLinkInventoryDesc(LSL_Integer linkNumber, LSL_String itemNameorid); + LSL_List osGetInventoryKeys(LSL_Integer type); + LSL_List osGetLinkInventoryKeys(LSL_Integer linkNumber, LSL_Integer type); + LSL_List osGetInventoryNames(LSL_Integer type); + LSL_List osGetLinkInventoryNames(LSL_Integer linkNumber, LSL_Integer type); + void osGiveLinkInventory(LSL_Integer linkNumber, LSL_Key destination, LSL_String inventory); LSL_Key osGetLastChangedEventKey(); LSL_Float osGetPSTWallclock(); LSL_Rotation osSlerp(LSL_Rotation a, LSL_Rotation b, LSL_Float amount); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index c7de2c9468..00d6a3ae6a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1460,18 +1460,61 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetInventoryItemKey(name); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_Key osGetLinkInventoryKey(LSL_Integer linkNumber, LSL_String name) + { + return m_OSSL_Functions.osGetLinkInventoryKey(linkNumber, name); + + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_List osGetInventoryKeys(LSL_Integer type) + { + return m_OSSL_Functions.osGetInventoryKeys(type); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_List osGetLinkInventoryKeys(LSL_Integer linkNumber, LSL_Integer type) + { + return m_OSSL_Functions.osGetLinkInventoryKeys(linkNumber, type); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public LSL_String osGetInventoryName(LSL_Key itemId) { return m_OSSL_Functions.osGetInventoryName(itemId); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_String osGetLinkInventoryName(LSL_Integer linkNumber, LSL_Key itemId) + { + return m_OSSL_Functions.osGetLinkInventoryName(linkNumber, itemId); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_List osGetLinkInventoryNames(LSL_Integer linkNumber, LSL_Integer type) + { + return m_OSSL_Functions.osGetLinkInventoryNames(linkNumber, type); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public LSL_String osGetInventoryDesc(LSL_String itemNameOrId) { return m_OSSL_Functions.osGetInventoryDesc(itemNameOrId); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_String osGetLinkInventoryDesc(LSL_Integer linkNumber, LSL_String itemNameOrId) + { + return m_OSSL_Functions.osGetLinkInventoryDesc(linkNumber, itemNameOrId); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void osGiveLinkInventory(LSL_Integer linkNumber, LSL_Key destination, LSL_String inventory) + { + m_OSSL_Functions.osGiveLinkInventory(linkNumber, destination, inventory); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public LSL_Key osGetLastChangedEventKey() { diff --git a/bin/ScriptSyntax.xml b/bin/ScriptSyntax.xml index 84685d6bc3..176432a194 100644 --- a/bin/ScriptSyntax.xml +++ b/bin/ScriptSyntax.xml @@ -7303,6 +7303,14 @@ fc2639fd-5d16-66bf-d8ab-2e4d754c816d itemNameOrIdtypestring + osGetLinkInventoryDesc + + returnstring + arguments + linkNumbertypeinteger + itemNameOrIdtypestring + + osGetInventoryItemKey returnkey @@ -7310,6 +7318,21 @@ fc2639fd-5d16-66bf-d8ab-2e4d754c816d nametypestring +osGetLinkInventoryKey + + returnkey + arguments + linkNumbertypeinteger + nametypestring + + + osGetInventoryKeys + + returnlist + arguments + typetypeinteger + + osGetInventoryLastOwner returnkey @@ -7324,6 +7347,38 @@ fc2639fd-5d16-66bf-d8ab-2e4d754c816d itemIdtypekey + osGetLinkInventoryName + + returnstring + arguments + linkNumbertypeinteger + itemIdtypekey + + + osGetLinkInventoryNames + + returnlist + arguments + linkNumbertypeinteger + typetypeinteger + + + osGetLinkInventoryKeys + + returnlist + arguments + linkNumbertypeinteger + typetypeinteger + + + osGiveLinkInventory + + arguments + linkNumbertypeinteger + destinationtypekey + inventorytypestring + + osGetLastChangedEventKey returnkey From e835a46ec842d5ce6fb1556979aaed475c479b76 Mon Sep 17 00:00:00 2001 From: Adil El Farissi <144741970+AdilElFarissi@users.noreply.github.com> Date: Tue, 20 Feb 2024 21:58:39 +0000 Subject: [PATCH 2/3] Fix uuid to string --- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 21b36cce72..a36ecd7683 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -5583,7 +5583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api foreach (KeyValuePair inv in m_host.TaskInventory) { if (inv.Value.Type == type || type == -1) - ret.Add(inv.Value.ItemID); + ret.Add(inv.Value.ItemID.ToString()); } m_host.TaskInventory.LockItemsForRead(false); From ea7417dff6003192b0fbf1e2014380a4a7815d92 Mon Sep 17 00:00:00 2001 From: Adil El Farissi <144741970+AdilElFarissi@users.noreply.github.com> Date: Wed, 21 Feb 2024 04:26:06 +0000 Subject: [PATCH 3/3] Update OSSL_Stub.cs --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 00d6a3ae6a..046a6d3af1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1491,6 +1491,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetLinkInventoryName(linkNumber, itemId); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_List osGetInventoryNames(LSL_Integer type) + { + return m_OSSL_Functions.osGetInventoryNames(type); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public LSL_List osGetLinkInventoryNames(LSL_Integer linkNumber, LSL_Integer type) {