From f58e1f626562778a5491a6bad79b18b3962a6c38 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 15 Feb 2019 01:09:37 +0000 Subject: mantis 8479: deep change DeRezObjects(..) doing independent permitions checks per action. m_useTrashOnDelete should now work except if god deletes, but still not recomended --- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 12 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 162 +++++++++------------ 2 files changed, 71 insertions(+), 103 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 7509686..eae6d6f 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -94,19 +94,15 @@ namespace OpenSim.Region.Framework.Scenes m_inventoryDeletes.Enqueue(dtis); } - if (Enabled) - lock (m_inventoryTicker) - m_inventoryTicker.Start(); - - // Visually remove it, even if it isnt really gone yet. This means that if we crash before the object - // has gone to inventory, it will reappear in the region again on restart instead of being lost. - // This is not ideal since the object will still be available for manipulation when it should be, but it's - // better than losing the object for now. if (permissionToDelete) { foreach (SceneObjectGroup g in objectGroups) g.DeleteGroupFromScene(false); } + + if (Enabled) + lock (m_inventoryTicker) + m_inventoryTicker.Start(); } private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e6e0354..6450c8b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes // build a list of eligible objects List deleteIDs = new List(); List deleteGroups = new List(); - List takeGroups = new List(); + List takeCopyGroups = new List(); List takeDeleteGroups = new List(); ScenePresence sp = null; @@ -2119,11 +2119,10 @@ namespace OpenSim.Region.Framework.Scenes else if(action != DeRezAction.Return) return; // only Return can be called without a client - // Start with true for both, then remove the flags if objects - // that we can't derez are part of the selection - bool permissionToTake = true; - bool permissionToTakeCopy = true; - bool permissionToDelete = true; + // this is not as 0.8x code + // 0.8x did refuse all operation is not allowed on all objects + // this will do it on allowed objects + // current viewers only ask if all allowed foreach (uint localID in localIDs) { @@ -2136,8 +2135,8 @@ namespace OpenSim.Region.Framework.Scenes continue; } - // Already deleted by someone else - if (part.ParentGroup.IsDeleted) + SceneObjectGroup grp = part.ParentGroup; + if (grp == null || grp.IsDeleted) { //Client still thinks the object exists, kill it deleteIDs.Add(localID); @@ -2145,128 +2144,101 @@ namespace OpenSim.Region.Framework.Scenes } // Can't delete child prims - if (part != part.ParentGroup.RootPart) + if (part != grp.RootPart) continue; - SceneObjectGroup grp = part.ParentGroup; if (grp.IsAttachment) - continue; + { + if(!sp.IsGod || action != DeRezAction.Return || action != DeRezAction.Delete) + continue; + // this may break the attachment, but its a security action + // viewers don't allow it anyways + } // If child prims have invalid perms, fix them grp.AdjustChildPrimPermissions(false); - if (remoteClient == null) + switch (action) { - // Autoreturn has a null client. Nothing else does. So - // allow only returns - if (action != DeRezAction.Return) + case DeRezAction.SaveToExistingUserInventoryItem: { - m_log.WarnFormat( - "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", - action, grp.Name, grp.UUID); - return; + if (Permissions.CanTakeCopyObject(grp, sp)) + takeCopyGroups.Add(grp); + break; } - permissionToTakeCopy = false; - } - else - { - if (action == DeRezAction.TakeCopy) + case DeRezAction.TakeCopy: { - if (!Permissions.CanTakeCopyObject(grp, sp)) - permissionToTakeCopy = false; + if (Permissions.CanTakeCopyObject(grp, sp)) + takeCopyGroups.Add(grp); + break; } - else + + case DeRezAction.Take: { - permissionToTakeCopy = false; + if (Permissions.CanTakeObject(grp, sp)) + takeDeleteGroups.Add(grp); + break; } - if (!Permissions.CanTakeObject(grp, sp)) - permissionToTake = false; - - if (!Permissions.CanDeleteObject(grp, remoteClient)) - permissionToDelete = false; - } - - // Handle god perms - if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) - { - permissionToTake = true; - permissionToTakeCopy = true; - permissionToDelete = true; - } - - // If we're re-saving, we don't even want to delete - if (action == DeRezAction.SaveToExistingUserInventoryItem) - permissionToDelete = false; - // if we want to take a copy, we also don't want to delete - // Note: after this point, the permissionToTakeCopy flag - // becomes irrelevant. It already includes the permissionToTake - // permission and after excluding no copy items here, we can - // just use that. - if (action == DeRezAction.TakeCopy) - { - // If we don't have permission, stop right here - if (!permissionToTakeCopy) + case DeRezAction.GodTakeCopy: { - remoteClient.SendAlertMessage("You don't have permission to take the object"); - return; + if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) + takeCopyGroups.Add(grp); + break; } - permissionToTake = true; - // Don't delete - permissionToDelete = false; - } - - if (action == DeRezAction.Return) - { - if (remoteClient != null) + case DeRezAction.Delete: { - if (Permissions.CanReturnObjects( - null, - remoteClient, - new List() {grp})) + if (Permissions.CanDeleteObject(grp, remoteClient)) { - permissionToTake = true; - permissionToDelete = true; - if(AddToReturns) - AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, - "parcel owner return"); + if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID)) + takeDeleteGroups.Add(grp); + else + deleteGroups.Add(grp); } + break; } - else // Auto return passes through here with null agent + + case DeRezAction.Return: { - permissionToTake = true; - permissionToDelete = true; + if (remoteClient != null) + { + if (Permissions.CanReturnObjects( null, remoteClient, new List() {grp})) + { + takeDeleteGroups.Add(grp); + if (AddToReturns) + AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, + "parcel owner return"); + } + } + else // Auto return passes through here with null agent + { + takeDeleteGroups.Add(grp); + } + break; } - } - if (permissionToDelete) - { - if (permissionToTake) - takeDeleteGroups.Add(grp); - else - deleteGroups.Add(grp); - deleteIDs.Add(grp.LocalId); + default: + break; } - else if(permissionToTake) - takeGroups.Add(grp); } - SendKillObject(deleteIDs); + if(deleteIDs.Count > 0) + SendKillObject(deleteIDs); if (takeDeleteGroups.Count > 0) { - m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, takeDeleteGroups, remoteClient, - true); + m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeDeleteGroups, + remoteClient, true); } - if (takeGroups.Count > 0) + + if (takeCopyGroups.Count > 0) { - m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, takeGroups, remoteClient, - false); + m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeCopyGroups, + remoteClient, false); } + if (deleteGroups.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) -- cgit v1.1 From 06930a180360e4ec54d8bf44c80794edb0a5a17c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 15 Feb 2019 01:10:56 +0000 Subject: don't break permitions on god object return or delete --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d6c65a1..69c1e4e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -526,16 +526,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess item.AssetType = (int)AssetType.Object; item.AssetID = asset.FullID; - if (DeRezAction.SaveToExistingUserInventoryItem == action) + if (action == DeRezAction.SaveToExistingUserInventoryItem) { m_Scene.InventoryService.UpdateItem(item); } else { - AddPermissions(item, objlist[0], objlist, remoteClient); + bool isowner = remoteClient != null && item.Owner == remoteClient.AgentId; + if(action == DeRezAction.Return) + AddPermissions(item, objlist[0], objlist, null); + else if(action == DeRezAction.Delete && !isowner) + AddPermissions(item, objlist[0], objlist, null); + else + AddPermissions(item, objlist[0], objlist, remoteClient); + m_Scene.AddInventoryItem(item); - if (remoteClient != null && item.Owner == remoteClient.AgentId) + if (isowner) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } @@ -1010,7 +1017,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); - group.ScheduleGroupForFullUpdate(); + group.ScheduleGroupForFullAnimUpdate(); } else m_Scene.AddNewSceneObject(group, true, false); -- cgit v1.1 From 98b6ba24b4340f0ed2f14d379952d3f5886f4282 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 15 Feb 2019 02:28:00 +0000 Subject: oops do show the object delete --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6450c8b..debcad3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2242,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes if (deleteGroups.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) - DeleteSceneObject(g, true); + DeleteSceneObject(g, false); } } -- cgit v1.1 From fdf5274c257286d6e438a337e61761028ff8003a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Feb 2019 02:06:25 +0000 Subject: add osKickAvatar(LSL_Key agentKey, string alert) --- .../Shared/Api/Implementation/OSSL_Api.cs | 41 +++++++++++++++++----- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 15 ++++---- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 19 ++++++---- 3 files changed, 53 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9d5f670..e114a53 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3629,7 +3629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); - World.ForEachRootScenePresence(delegate(ScenePresence sp) + World.ForEachRootScenePresence(delegate (ScenePresence sp) { if (sp.Firstname == FirstName && sp.Lastname == SurName) { @@ -3643,18 +3643,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api }); } - public LSL_Float osGetHealth(string avatar) + public void osKickAvatar(LSL_Key agentKey, string alert) + { + CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); + + UUID id; + if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero) + return; + + ScenePresence sp = World.GetScenePresence(id); + if(sp == null) + return; + + // kick client... + if (alert != null) + sp.ControllingClient.Kick(alert); + + // ...and close on our side + sp.Scene.CloseAgent(id, false); + } + + public LSL_Float osGetHealth(LSL_Key agentKey) { CheckThreatLevel(ThreatLevel.None, "osGetHealth"); LSL_Float health = new LSL_Float(-1); - ScenePresence presence = World.GetScenePresence(new UUID(avatar)); + + UUID id; + if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero) + return health; + + ScenePresence presence = World.GetScenePresence(id); if (presence != null) health = presence.Health; return health; } - public void osCauseDamage(string avatar, double damage) + public void osCauseDamage(LSL_Key avatar, LSL_Float damage) { CheckThreatLevel(ThreatLevel.High, "osCauseDamage"); @@ -3683,7 +3708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public void osCauseHealing(string avatar, double healing) + public void osCauseHealing(LSL_Key avatar, LSL_Float healing) { CheckThreatLevel(ThreatLevel.High, "osCauseHealing"); @@ -3704,7 +3729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api presence.setHealthWithUpdate(health); } - public void osSetHealth(string avatar, double health) + public void osSetHealth(LSL_Key avatar, LSL_Float health) { CheckThreatLevel(ThreatLevel.High, "osSetHealth"); @@ -3722,7 +3747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public void osSetHealRate(string avatar, double healrate) + public void osSetHealRate(LSL_Key avatar, LSL_Float healrate) { CheckThreatLevel(ThreatLevel.High, "osSetHealRate"); @@ -3737,7 +3762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api presence.HealRate = (float)healrate; } - public LSL_Float osGetHealRate(string avatar) + public LSL_Float osGetHealRate(LSL_Key avatar) { CheckThreatLevel(ThreatLevel.None, "osGetHealRate"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 12e8103..67c0261 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -379,15 +379,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces int osGetSimulatorMemory(); int osGetSimulatorMemoryKB(); - void osKickAvatar(string FirstName,string SurName,string alert); + void osKickAvatar(string FirstName, string SurName, string alert); + void osKickAvatar(LSL_Key agentId, string alert); void osSetSpeed(string UUID, LSL_Float SpeedModifier); void osSetOwnerSpeed(LSL_Float SpeedModifier); - LSL_Float osGetHealth(string avatar); - void osCauseHealing(string avatar, double healing); - void osSetHealth(string avatar, double health); - void osSetHealRate(string avatar, double health); - LSL_Float osGetHealRate(string avatar); - void osCauseDamage(string avatar, double damage); + LSL_Float osGetHealth(key agentId); + void osCauseHealing(key agentId, LSL_Float healing); + void osSetHealth(key agentId, LSL_Float health); + void osSetHealRate(key agentId, LSL_Float health); + LSL_Float osGetHealRate(key agentId); + void osCauseDamage(key avatar, LSL_Float damage); void osForceOtherSit(string avatar); void osForceOtherSit(string avatar, string target); LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 94df1ea..76d334b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -965,11 +965,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetSimulatorMemoryKB(); } - public void osKickAvatar(string FirstName,string SurName,string alert) + public void osKickAvatar(string FirstName, string SurName, string alert) { m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert); } + public void osKickAvatar(LSL_Key agentId, string alert) + { + m_OSSL_Functions.osKickAvatar(agentId, alert); + } + public void osSetSpeed(string UUID, LSL_Float SpeedModifier) { m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); @@ -980,32 +985,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osSetOwnerSpeed(SpeedModifier); } - public LSL_Float osGetHealth(string avatar) + public LSL_Float osGetHealth(key avatar) { return m_OSSL_Functions.osGetHealth(avatar); } - public void osCauseDamage(string avatar, double damage) + public void osCauseDamage(key avatar, LSL_Float damage) { m_OSSL_Functions.osCauseDamage(avatar, damage); } - public void osCauseHealing(string avatar, double healing) + public void osCauseHealing(key avatar, LSL_Float healing) { m_OSSL_Functions.osCauseHealing(avatar, healing); } - public void osSetHealth(string avatar, double health) + public void osSetHealth(key avatar, LSL_Float health) { m_OSSL_Functions.osSetHealth(avatar, health); } - public void osSetHealRate(string avatar, double health) + public void osSetHealRate(key avatar, LSL_Float health) { m_OSSL_Functions.osSetHealRate(avatar, health); } - public LSL_Float osGetHealRate(string avatar) + public LSL_Float osGetHealRate(key avatar) { return m_OSSL_Functions.osGetHealRate(avatar); } -- cgit v1.1 From b56eb2fe63a3bc1aaa954a24c46a1725d5bb704d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Feb 2019 03:05:23 +0000 Subject: estate kick now just kill user connection if on same region. The teleport home we did, does not make much sense, and would need more work anyways --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 13 ++++------- .../World/Estate/EstateManagementModule.cs | 25 +++++++++++++--------- .../CoreModules/World/Estate/EstateModule.cs | 23 +++++++++++++++++--- 3 files changed, 39 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index b7d5a80..943be07 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1677,8 +1677,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendKillObject(List localIDs) { - // foreach (uint id in localIDs) - // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); + // foreach (uint id in localIDs) + // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); // remove pending entities to reduce looping chances. lock (m_entityProps.SyncRoot) @@ -1702,10 +1702,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if(++nsent >= 200) { - kill.Header.Reliable = true; - kill.Header.Zerocoded = true; OutPacket(kill, ThrottleOutPacketType.Task); - perpacket = localIDs.Count - i - 1; if(perpacket == 0) break; @@ -1720,8 +1717,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if(nsent != 0) { - kill.Header.Reliable = true; - kill.Header.Zerocoded = true; OutPacket(kill, ThrottleOutPacketType.Task); } } @@ -10047,7 +10042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[1].Parameter), out Prey); - OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey); + OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey, false); } return true; case "teleporthomeallusers": @@ -10195,7 +10190,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[0].Parameter), out Prey); - OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey); + OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey, true); } return true; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 2e801e3..ac28cee 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -1204,28 +1204,33 @@ namespace OpenSim.Region.CoreModules.World.Estate } } - private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) + private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey, bool kick) { + if (prey == UUID.Zero) + return; + EstateTeleportOneUserHomeRequest evOverride = OnEstateTeleportOneUserHomeRequest; if(evOverride != null) { - evOverride(remover_client, invoice, senderID, prey); + evOverride(remover_client, invoice, senderID, prey, kick); return; } if (!Scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false)) return; - if (prey != UUID.Zero) + ScenePresence s = Scene.GetScenePresence(prey); + if (s != null && !s.IsDeleted && !s.IsInTransit) { - ScenePresence s = Scene.GetScenePresence(prey); - if (s != null && !s.IsDeleted && !s.IsInTransit) + if (kick) { - if (!Scene.TeleportClientHome(prey, s.ControllingClient)) - { - s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); - Scene.CloseAgent(s.UUID, false); - } + s.ControllingClient.Kick("You have been kicked"); + Scene.CloseAgent(s.UUID, false); + } + else if (!Scene.TeleportClientHome(prey, s.ControllingClient)) + { + s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed "); + Scene.CloseAgent(s.UUID, false); } } } diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs index f4a174a..c8b9032 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs @@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message); } - private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey) + private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey, bool kick) { if (prey == UUID.Zero) return; @@ -227,8 +227,20 @@ namespace OpenSim.Region.CoreModules.World.Estate ScenePresence p = scene.GetScenePresence(prey); if (p != null && !p.IsChildAgent && !p.IsDeleted && !p.IsInTransit) { - p.ControllingClient.SendTeleportStart(16); - scene.TeleportClientHome(prey, client); + if (kick) + { + p.ControllingClient.Kick("You have been kicked out"); + s.CloseAgent(p.UUID, false); + } + else + { + p.ControllingClient.SendTeleportStart(16); + if (!s.TeleportClientHome(prey, client)) + { + p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed"); + s.CloseAgent(p.UUID, false); + } + } return; } } @@ -259,6 +271,11 @@ namespace OpenSim.Region.CoreModules.World.Estate { p.ControllingClient.SendTeleportStart(16); scene.TeleportClientHome(p.ControllingClient.AgentId, client); + if (!s.TeleportClientHome(p.ControllingClient.AgentId, client)) + { + p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); + s.CloseAgent(p.UUID, false); + } } }); } -- cgit v1.1 From 7c0eab8a23a4e2998b5035c7b5de04578e3896fb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Feb 2019 04:04:35 +0000 Subject: Xengine: don't lose state change events --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 019a0d9..ef4d6ec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -699,7 +699,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // If min event delay is set then ignore any events untill the time has expired // This currently only allows 1 event of any type in the given time period. // This may need extending to allow for a time for each individual event type. - if (m_eventDelayTicks != 0) + if (m_eventDelayTicks != 0 && data.EventName != "state" && data.EventName != "state_entry" && data.EventName != "state_exit") { if (DateTime.Now.Ticks < m_nextEventTimeTicks) return; -- cgit v1.1 From ac651a168abc2c69214d2957a6d6fa83abe9dec4 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Feb 2019 04:54:32 +0000 Subject: Xengine: exclude a few more events from mineventdelay --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index ef4d6ec..351fca9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -699,7 +699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // If min event delay is set then ignore any events untill the time has expired // This currently only allows 1 event of any type in the given time period. // This may need extending to allow for a time for each individual event type. - if (m_eventDelayTicks != 0 && data.EventName != "state" && data.EventName != "state_entry" && data.EventName != "state_exit") + if (m_eventDelayTicks != 0 && + data.EventName != "state" && data.EventName != "state_entry" && data.EventName != "state_exit" + && data.EventName != "run_time_permissions" && data.EventName != "http_request" && data.EventName != "link_message") { if (DateTime.Now.Ticks < m_nextEventTimeTicks) return; -- cgit v1.1 From 72c472f98858a6609d12ad36791fe497cd9f21d5 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Feb 2019 20:12:13 +0000 Subject: Yengine: let llminEventDelay do something: it just ignores a more limited set of events than Xengine (neither do as SL) --- .../ScriptEngine/YEngine/MMRScriptEventCode.cs | 5 +--- OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs | 5 +++- .../Region/ScriptEngine/YEngine/XMRInstBackend.cs | 12 ++++---- OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs | 4 +++ OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs | 18 +++++++++++ OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs | 35 ++++++++++++++++++---- 6 files changed, 62 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs index c00e8d4..3539fa1 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs @@ -88,10 +88,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine path_update = 40, - // XMRE specific - region_cross = 63, - // marks highest numbered event, ie, number of columns in seht. - Size = 64 + Size = 41 } } diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs index 017b294..6acc293 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs @@ -930,12 +930,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine public void SetMinEventDelay(UUID itemID, double delay) { + XMRInstance instance = GetInstance(itemID); + if (instance != null) + instance.MinEventDelay = delay; } public int GetStartParameter(UUID itemID) { XMRInstance instance = GetInstance(itemID); - if(instance == null) + if (instance == null) return 0; return instance.StartParam; } diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs index 6fe11d8..7fc97e9 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs @@ -422,9 +422,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine object[] saveEHArgs = this.ehArgs; ScriptEventCode saveEventCode = this.eventCode; - this.m_DetectParams = evt.DetectParams; - this.ehArgs = evt.Params; - this.eventCode = evc; + m_DetectParams = evt.DetectParams; + ehArgs = evt.Params; + eventCode = evc; try { @@ -432,9 +432,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine } finally { - this.m_DetectParams = saveDetParams; - this.ehArgs = saveEHArgs; - this.eventCode = saveEventCode; + m_DetectParams = saveDetParams; + ehArgs = saveEHArgs; + eventCode = saveEventCode; } // Keep waiting until we find a returnable event or timeout. diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs index 3c0040c..def06b2 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs @@ -215,5 +215,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine // It's born ready, but will be reset when the detach is posted. // It will then be set again on suspend/completion private ManualResetEvent m_DetachReady = new ManualResetEvent(true); + + // llmineventdelay support + double m_minEventDelay = 0.0; + double m_nextEventTime = 0.0; } } diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs index 0af3d37..12feb7b 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs @@ -298,6 +298,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine } } + public double MinEventDelay + { + get + { + return m_minEventDelay; + } + set + { + if (value > 0.001) + m_minEventDelay = value; + else + m_minEventDelay = 0.0; + + m_nextEventTime = 0.0; // reset it + } + } + + public SceneObjectPart SceneObject { get diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs index 6c969dc..9d73a7f 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs @@ -63,8 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine */ public void PostEvent(EventParams evt) { - ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), - evt.EventName); + ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName); // Put event on end of event queue. bool startIt = false; @@ -86,6 +85,32 @@ namespace OpenSim.Region.ScriptEngine.Yengine if(!m_Running && !construct) return; + if(m_minEventDelay != 0) + { + switch (evc) + { + // ignore some events by time set by llMinEventDelay + case ScriptEventCode.collision: + case ScriptEventCode.land_collision: + case ScriptEventCode.listen: + case ScriptEventCode.not_at_target: + case ScriptEventCode.not_at_rot_target: + case ScriptEventCode.no_sensor: + case ScriptEventCode.sensor: + case ScriptEventCode.timer: + case ScriptEventCode.touch: + { + double now = Util.GetTimeStamp(); + if (now < m_nextEventTime) + return; + m_nextEventTime = now + m_minEventDelay; + break; + } + default: + break; + } + } + // Only so many of each event type allowed to queue. if((uint)evc < (uint)m_EventCounts.Length) { @@ -124,10 +149,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next) { EventParams evt2 = lln2.Value; - ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), - evt2.EventName); - if((evc2 != ScriptEventCode.state_entry) && - (evc2 != ScriptEventCode.attach)) + ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt2.EventName); + if((evc2 != ScriptEventCode.state_entry) && (evc2 != ScriptEventCode.attach)) break; } if(lln2 == null) -- cgit v1.1 From 0f574d432d6a2dd4a15a9d6bba236a7cf2656454 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 20 Feb 2019 20:36:43 +0000 Subject: Yengine:save minEventDelay in script state --- OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs | 9 +++++++++ OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs | 9 +++++++++ 2 files changed, 18 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs index 9bb894d..5798638 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs @@ -115,6 +115,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true); + if (m_minEventDelay != 0.0) + { + XmlElement minEventDelayN = doc.CreateElement("", "mEvtDly", ""); + minEventDelayN.AppendChild(doc.CreateTextNode(m_minEventDelay.ToString())); + scriptStateN.AppendChild(minEventDelayN); + m_RunOnePhase = "GetExecutionState D"; + CheckRunLockInvariants(true); + } + // More misc data. XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); scriptStateN.AppendChild(permissionsN); diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs index b140453..7e13ae4 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs @@ -527,6 +527,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit"); doGblInit = bool.Parse(doGblInitN.InnerText); + double minEventDelay = 0.0; + XmlElement minEventDelayN = (XmlElement)scriptStateN.SelectSingleNode("mEvtDly"); + if(minEventDelayN != null) + minEventDelay = Double.Parse(minEventDelayN.InnerText); + // get values used by stuff like llDetectedGrab, etc. DetectParams[] detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray")); @@ -576,6 +581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine AsyncCommandManager.CreateFromData(m_Engine, m_LocalID, m_ItemID, m_Part.UUID, pluginData); + + MinEventDelay = minEventDelay; } private void processXstate(XmlDocument doc) @@ -919,6 +926,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine AsyncCommandManager.CreateFromData(m_Engine, m_LocalID, m_ItemID, m_Part.UUID, pluginData); + + MinEventDelay = minEventDelay; } private static void getvarNames(Dictionary s, Dictionary d) -- cgit v1.1 From 17ea412da1a38f8e09d95c5604694c595f111473 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 21:54:24 +0000 Subject: fix last owner on add to object inventory --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index bf217a5..8899e96 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -154,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes // We're adding this to a prim we don't own. Force // owner change taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; - + taskItem.LastOwnerID = item.Owner; } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4934b83..bc9ab7f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -815,10 +815,10 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForWrite(true); m_items.Add(item.ItemID, item); m_items.LockItemsForWrite(false); - if (allowedDrop) - m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); - else - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + if (allowedDrop) + m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); + else + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); m_part.AggregateInnerPerms(); m_inventorySerial++; -- cgit v1.1 From 16596b6ad0af373cccde83d8faa01fa996c1023a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 21:56:27 +0000 Subject: add LSL_Key osGetInventoryLastOwner(string itemNameorid) --- .../Shared/Api/Implementation/OSSL_Api.cs | 21 +++++++++++++++++++-- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 6 ++++++ 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e114a53..070176b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -4874,8 +4874,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Math.Atan2(mcross, dot); } - -//******* link sound public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume) { m_host.AddScriptLPS(1); @@ -5406,5 +5404,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 1; } + public LSL_Key osGetInventoryLastOwner(string itemNameorid) + { + m_host.AddScriptLPS(1); + + TaskInventoryItem item = null; + UUID itemID; + if (UUID.TryParse(itemNameorid, out itemID)) + item = m_host.Inventory.GetInventoryItem(itemID); + else + item = m_host.Inventory.GetInventoryItem(itemNameorid); + + if (item == null) + return UUID.Zero.ToString(); + + UUID id = item.LastOwnerID; + if(id == UUID.Zero) + id= item.OwnerID; + return id.ToString(); + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 67c0261..7277577 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -547,5 +547,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin); LSL_Integer osApproxEquals(rotation ra, rotation rb); LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin); + LSL_Key osGetInventoryLastOwner(string itemNameOrId); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 76d334b..bc64ac4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1366,5 +1366,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osApproxEquals(ra, rb, margin); } + + public LSL_Key osGetInventoryLastOwner(string itemNameOrId) + { + return m_OSSL_Functions.osGetInventoryLastOwner(itemNameOrId); + } + } } -- cgit v1.1 From b7507b70bc71bbb935ccb1542cfbacbf5a3a273d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 22:05:38 +0000 Subject: Yengine changed position and shape events can bt throttled by mineventdelay --- OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs index 9d73a7f..1b735e3 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs @@ -106,6 +106,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine m_nextEventTime = now + m_minEventDelay; break; } + case ScriptEventCode.changed: + { + const int canignore = ~(CHANGED_SCALE | CHANGED_POSITION); + int change = (int)evt.Params[0]; + if(change == 0) // what? + return; + if((change & canignore) == 0) + { + double now = Util.GetTimeStamp(); + if (now < m_nextEventTime) + return; + m_nextEventTime = now + m_minEventDelay; + } + break; + } default: break; } -- cgit v1.1 From ece38437983440449acbc7f7202c470e72ae4e61 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 22:54:17 +0000 Subject: let changed allowed drop have lldetectedkey[0] return the dropped item id, Yengine and still testing" --- OpenSim/Region/Framework/Scenes/EventManager.cs | 6 +++--- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- .../Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/EventManager.cs | 2 +- OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs | 17 +++++++++++++++-- 5 files changed, 22 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index f76f882..edc8886 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -539,7 +539,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// public event ScriptChangedEvent OnScriptChangedEvent; - public delegate void ScriptChangedEvent(uint localID, uint change); + public delegate void ScriptChangedEvent(uint localID, uint change, object data); public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed); @@ -1185,7 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerOnScriptChangedEvent(uint localID, uint change) + public void TriggerOnScriptChangedEvent(uint localID, uint change, object parameter = null) { ScriptChangedEvent handlerScriptChangedEvent = OnScriptChangedEvent; if (handlerScriptChangedEvent != null) @@ -1194,7 +1194,7 @@ namespace OpenSim.Region.Framework.Scenes { try { - d(localID, change); + d(localID, change, parameter); } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a23ebbf..23bef74 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4439,10 +4439,10 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary()); } - public void TriggerScriptChangedEvent(Changed val) + public void TriggerScriptChangedEvent(Changed val, object data = null) { if (ParentGroup != null && ParentGroup.Scene != null) - ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val); + ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val, data); } public void TrimPermissions() diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index bc9ab7f..a0f8959 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -816,7 +816,7 @@ namespace OpenSim.Region.Framework.Scenes m_items.Add(item.ItemID, item); m_items.LockItemsForWrite(false); if (allowedDrop) - m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); + m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP, item.ItemID); else m_part.TriggerScriptChangedEvent(Changed.INVENTORY); diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index b7fc161..7c2136e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -215,7 +215,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine det)); } - public void changed(uint localID, uint change) + public void changed(uint localID, uint change, object parameter) { // Add to queue for all scripts in localID, Object pass change. myScriptEngine.PostObjectEvent(localID, new EventParams( diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs index 5a8b2a3..eb5aeeb 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs @@ -182,13 +182,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine new DetectParams[] { det })); } - public void changed(uint localID, uint change) + public void changed(uint localID, uint change, object data) { int ch = (int)change; // Add to queue for all scripts in localID, Object pass change. - this.PostObjectEvent(localID, new EventParams( + if(data == null) + { + PostObjectEvent(localID, new EventParams( "changed", new object[] { ch }, zeroDetectParams)); + return; + } + if ( data is UUID) + { + DetectParams det = new DetectParams(); + det.Key = (UUID)data; + PostObjectEvent(localID, new EventParams( + "changed", new object[] { ch }, + new DetectParams[] { det })); + return; + } } // state_entry: not processed here -- cgit v1.1 From bd27573130d4a40d678c81c687591708ab4e4f34 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 23:11:03 +0000 Subject: add LSL_String osGetInventoryName(LSL_Key itemId) and LSL_String osGetInventoryDescription(LSL_String itemNameOrId) --- .../Shared/Api/Implementation/OSSL_Api.cs | 34 +++++++++++++++++++++- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 4 ++- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 11 ++++++- 3 files changed, 46 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 070176b..e4cc3aa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -5404,7 +5404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 1; } - public LSL_Key osGetInventoryLastOwner(string itemNameorid) + public LSL_Key osGetInventoryLastOwner(LSL_String itemNameorid) { m_host.AddScriptLPS(1); @@ -5423,5 +5423,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api id= item.OwnerID; return id.ToString(); } + + public LSL_String osGetInventoryName(LSL_Key itemId) + { + m_host.AddScriptLPS(1); + + TaskInventoryItem item = null; + UUID itemID; + if (UUID.TryParse(itemId, out itemID)) + item = m_host.Inventory.GetInventoryItem(itemID); + + if (item == null) + return String.Empty; + + return item.Name; + } + + public LSL_String osGetInventoryDescription(LSL_String itemNameorid) + { + m_host.AddScriptLPS(1); + + TaskInventoryItem item = null; + UUID itemID; + if (UUID.TryParse(itemNameorid, out itemID)) + item = m_host.Inventory.GetInventoryItem(itemID); + else + item = m_host.Inventory.GetInventoryItem(itemNameorid); + + if (item == null) + return String.Empty; + + return item.Description; + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 7277577..711108b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -547,6 +547,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin); LSL_Integer osApproxEquals(rotation ra, rotation rb); LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin); - LSL_Key osGetInventoryLastOwner(string itemNameOrId); + LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId); + LSL_String osGetInventoryName(LSL_Key itemId); + LSL_String osGetInventoryDescription(LSL_String itemNameOrId); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index bc64ac4..86c8ba3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1367,10 +1367,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osApproxEquals(ra, rb, margin); } - public LSL_Key osGetInventoryLastOwner(string itemNameOrId) + public LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId) { return m_OSSL_Functions.osGetInventoryLastOwner(itemNameOrId); } + public LSL_String osGetInventoryName(LSL_Key itemId) + { + return m_OSSL_Functions.osGetInventoryName(itemId); + } + + public LSL_String osGetInventoryDescription(LSL_String itemNameOrId) + { + return m_OSSL_Functions.osGetInventoryDescription(itemNameOrId); + } } } -- cgit v1.1 From 5d78f52f7bd3aa27385a800ecae35d3579d3bee8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 23:17:53 +0000 Subject: let Xengine also have that detectedkey --- OpenSim/Region/ScriptEngine/XEngine/EventManager.cs | 17 +++++++++++++++-- OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs | 8 ++++---- 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 7c2136e..50a95a9 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -218,9 +218,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void changed(uint localID, uint change, object parameter) { // Add to queue for all scripts in localID, Object pass change. - myScriptEngine.PostObjectEvent(localID, new EventParams( - "changed",new object[] { new LSL_Types.LSLInteger(change) }, + if(parameter == null) + { + myScriptEngine.PostObjectEvent(localID, new EventParams( + "changed", new object[] { new LSL_Types.LSLInteger(change) }, new DetectParams[0])); + return; + } + if (parameter is UUID) + { + DetectParams det = new DetectParams(); + det.Key = (UUID)parameter; + myScriptEngine.PostObjectEvent(localID, new EventParams( + "changed", new object[] { new LSL_Types.LSLInteger(change) }, + new DetectParams[] { det })); + return; + } } // state_entry: not processed here diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs index eb5aeeb..65a8aed 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs @@ -182,21 +182,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine new DetectParams[] { det })); } - public void changed(uint localID, uint change, object data) + public void changed(uint localID, uint change, object parameter) { int ch = (int)change; // Add to queue for all scripts in localID, Object pass change. - if(data == null) + if(parameter == null) { PostObjectEvent(localID, new EventParams( "changed", new object[] { ch }, zeroDetectParams)); return; } - if ( data is UUID) + if ( parameter is UUID) { DetectParams det = new DetectParams(); - det.Key = (UUID)data; + det.Key = (UUID)parameter; PostObjectEvent(localID, new EventParams( "changed", new object[] { ch }, new DetectParams[] { det })); -- cgit v1.1 From 6e05695244173435067408e5716cb4bd2a2c0aef Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 21 Feb 2019 23:41:49 +0000 Subject: add LSL_Key osGetLastChangedEventKey() ( it is a alias for lldetectedkey(0) but don't tell anyone --- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 9 +++++++++ OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++++ 3 files changed, 15 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e4cc3aa..7674628 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -5455,5 +5455,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return item.Description; } + + public LSL_Key osGetLastChangedEventKey() + { + m_host.AddScriptLPS(1); + DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); + if (detectedParams == null) + return String.Empty; + return detectedParams.Key.ToString(); + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 711108b..8333af8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -550,5 +550,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId); LSL_String osGetInventoryName(LSL_Key itemId); LSL_String osGetInventoryDescription(LSL_String itemNameOrId); + LSL_Key osGetLastChangedEventKey(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 86c8ba3..f0fb745 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1381,5 +1381,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osGetInventoryDescription(itemNameOrId); } + + public LSL_Key osGetLastChangedEventKey() + { + return m_OSSL_Functions.osGetLastChangedEventKey(); + } } } -- cgit v1.1 From d89a089ca266311568febc367f41f4217b7580d1 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 22 Feb 2019 22:28:47 +0000 Subject: remove redundant osInventoryDescription() and improve osInventoryDesc() to do the same --- .../Shared/Api/Implementation/OSSL_Api.cs | 25 +--------------------- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 4 +--- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 9 ++------ 3 files changed, 4 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7674628..dabd399 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3890,29 +3890,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } /// - /// Get the description from an inventory item - /// - /// - /// Item description - public LSL_String osGetInventoryDesc(string item) - { - CheckThreatLevel(); - - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == item) - { - return inv.Value.Description.ToString(); - } - } - } - - return String.Empty; - } - - /// /// Invite user to the group this object is set to /// /// @@ -5439,7 +5416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return item.Name; } - public LSL_String osGetInventoryDescription(LSL_String itemNameorid) + public LSL_String osGetInventoryDesc(LSL_String itemNameorid) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 8333af8..49b3f74 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -401,8 +401,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osUnixTimeToTimestamp(LSL_Integer time); - LSL_String osGetInventoryDesc(string item); - LSL_Integer osInviteToGroup(LSL_Key agentId); LSL_Integer osEjectFromGroup(LSL_Key agentId); @@ -549,7 +547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin); LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId); LSL_String osGetInventoryName(LSL_Key itemId); - LSL_String osGetInventoryDescription(LSL_String itemNameOrId); + LSL_String osGetInventoryDesc(LSL_String itemNameOrId); LSL_Key osGetLastChangedEventKey(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index f0fb745..fb491e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1060,11 +1060,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osUnixTimeToTimestamp(time); } - public LSL_String osGetInventoryDesc(string item) - { - return m_OSSL_Functions.osGetInventoryDesc(item); - } - public LSL_Integer osInviteToGroup(LSL_Key agentId) { return m_OSSL_Functions.osInviteToGroup(agentId); @@ -1377,9 +1372,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetInventoryName(itemId); } - public LSL_String osGetInventoryDescription(LSL_String itemNameOrId) + public LSL_String osGetInventoryDesc(LSL_String itemNameOrId) { - return m_OSSL_Functions.osGetInventoryDescription(itemNameOrId); + return m_OSSL_Functions.osGetInventoryDesc(itemNameOrId); } public LSL_Key osGetLastChangedEventKey() -- cgit v1.1 From 009af3122f8005ae5b8ed82f8ed1da89e9843e90 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 22 Feb 2019 22:42:07 +0000 Subject: update script sintaxe --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 49f46b7..8b70128 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public partial class ScriptBaseClass { // SCRIPTS CONSTANTS - public static readonly LSLInteger OS_APIVERSION = 2; + public static readonly LSLInteger OS_APIVERSION = 3; public static readonly LSLInteger TRUE = 1; public static readonly LSLInteger FALSE = 0; -- cgit v1.1 From 800f6d6529516be22d4ee79cd8e9161479f4df34 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 24 Feb 2019 07:25:50 +0000 Subject: several changes to llHttpRequest processing: options section renamed ScriptsHttpRequestModule; throttle by prim (PrimRequestsBurst = 3, PrimRequestsPerSec = 1) and max concurrent connections per instance (MaxPoolThreads = 5), llhttprequest returns if error, nullkey if throttled, reqid otherwise --- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 165 +++++++++++++-------- .../Region/Framework/Interfaces/IHttpRequests.cs | 1 + .../Shared/Api/Implementation/LSL_Api.cs | 19 ++- .../Api/Implementation/Plugins/HttpRequest.cs | 13 +- 4 files changed, 117 insertions(+), 81 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index c3f6d6b..54936a3 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Net; using System.Net.Mail; @@ -101,11 +102,22 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest private OutboundUrlFilter m_outboundUrlFilter; private string m_proxyurl = ""; private string m_proxyexcepts = ""; + + private float m_primpersec = 1.0f; + private float m_primburst = 3f; + + private struct ThrottleData + { + public double lastTime; + public float count; + } // private Dictionary m_pendingRequests; + private ConcurrentQueue m_CompletedRequests; + private ConcurrentDictionary m_RequestsThrottle; + private Scene m_scene; - // private Queue rpcQueue = new Queue(); public static SmartThreadPool ThreadPool = null; public HttpRequestModule() @@ -119,6 +131,41 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest return UUID.Zero; } + public bool CheckThrottle(uint localID) + { + ThrottleData th; + double now = Util.GetTimeStamp(); + bool ret = false; + + if (m_RequestsThrottle.TryGetValue(localID, out th)) + { + double delta = now - th.lastTime; + th.lastTime = now; + + float add = (float)(m_primpersec * delta); + th.count += add; + if (th.count > m_primburst) + th.count = m_primburst; + + ret = th.count > 0; + } + else + { + th = new ThrottleData() + { + lastTime = now, + count = m_primburst + }; + ret = true; + } + + if (ret) + th.count--; + + m_RequestsThrottle[localID] = th; + return ret; + } + public UUID StartHttpRequest( uint localID, UUID itemID, string url, List parameters, Dictionary headers, string body, out HttpInitialRequestStatus status) @@ -243,9 +290,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest return false; lock (HttpListLock) - { m_pendingRequests.Add(req.ReqID, req); - } req.Process(); @@ -256,14 +301,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { if (m_pendingRequests != null) { + List toremove = new List(); lock (HttpListLock) { - HttpRequestClass tmpReq; - if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) + foreach (HttpRequestClass tmpReq in m_pendingRequests.Values) { - tmpReq.Stop(); - m_pendingRequests.Remove(m_itemID); + if(tmpReq.ItemID == m_itemID) + { + tmpReq.Stop(); + toremove.Add(tmpReq.ReqID); + } } + foreach(UUID id in toremove) + m_pendingRequests.Remove(id); } } } @@ -276,37 +326,37 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest * finished. I thought about setting up a queue for this, but * it will need some refactoring and this works 'enough' right now */ - - public IServiceRequest GetNextCompletedRequest() + public void GotCompletedRequest(HttpRequestClass req) { + if(req.Removed) + return; lock (HttpListLock) { - foreach (UUID luid in m_pendingRequests.Keys) - { - HttpRequestClass tmpReq; + m_pendingRequests.Remove(req.ReqID); + m_CompletedRequests.Enqueue(req); + } + } - if (m_pendingRequests.TryGetValue(luid, out tmpReq)) - { - if (tmpReq.Finished) - { - return tmpReq; - } - } - } + public IServiceRequest GetNextCompletedRequest() + { + HttpRequestClass req; + while(m_CompletedRequests.TryDequeue(out req)) + { + if(!req.Removed) + return req; } return null; } - public void RemoveCompletedRequest(UUID id) + public void RemoveCompletedRequest(UUID reqId) { lock (HttpListLock) { HttpRequestClass tmpReq; - if (m_pendingRequests.TryGetValue(id, out tmpReq)) + if (m_pendingRequests.TryGetValue(reqId, out tmpReq)) { tmpReq.Stop(); - tmpReq = null; - m_pendingRequests.Remove(id); + m_pendingRequests.Remove(reqId); } } } @@ -322,17 +372,20 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384); - m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); - int maxThreads = 15; - IConfig httpConfig = config.Configs["HttpRequestModule"]; + int maxThreads = 5; + IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"]; if (httpConfig != null) { maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); + m_primburst = httpConfig.GetFloat("PrimRequestsBurst", m_primburst); + m_primpersec = httpConfig.GetFloat("PrimRequestsPerSec", m_primpersec); } m_pendingRequests = new Dictionary(); + m_CompletedRequests = new ConcurrentQueue(); + m_RequestsThrottle = new ConcurrentDictionary(); // First instance sets this up for all sims if (ThreadPool == null) @@ -406,11 +459,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest /// public HttpRequestModule RequestModule { get; set; } - private bool _finished; - public bool Finished - { - get { return _finished; } - } + public bool Finished { get; private set;} + public bool Removed{ get; set;} public static int HttpBodyMaxLenMAX = 16384; @@ -427,19 +477,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public bool HttpPragmaNoCache = true; // Request info - private UUID _itemID; - public UUID ItemID - { - get { return _itemID; } - set { _itemID = value; } - } - private uint _localID; - public uint LocalID - { - get { return _localID; } - set { _localID = value; } - } - public DateTime Next; + public UUID ReqID { get; set; } + public UUID ItemID { get; set;} + public uint LocalID { get; set;} + public string proxyurl; public string proxyexcepts; @@ -454,12 +495,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public int MaxRedirects { get; set; } public string OutboundBody; - private UUID _reqID; - public UUID ReqID - { - get { return _reqID; } - set { _reqID = value; } - } + public HttpWebRequest Request; public string ResponseBody; public List ResponseMetadata; @@ -469,10 +505,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - _finished = false; - - lock (HttpRequestModule.ThreadPool) - WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null); + WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null); } private object StpSendWrapper(object o) @@ -521,6 +554,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void SendRequest() { + if(Removed) + return; + HttpWebResponse response = null; Stream resStream = null; byte[] buf = new byte[HttpBodyMaxLenMAX + 16]; @@ -672,7 +708,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest if (response != null) response.Close(); - // We need to resubmit if ( (Status == (int)HttpStatusCode.MovedPermanently @@ -684,7 +719,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { Status = (int)OSHttpStatusCode.ClientErrorJoker; ResponseBody = "Number of redirects exceeded max redirects"; - _finished = true; + WorkItem = null; + RequestModule.GotCompletedRequest(this); } else { @@ -694,13 +730,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { Status = (int)OSHttpStatusCode.ClientErrorJoker; ResponseBody = "HTTP redirect code but no location header"; - _finished = true; + WorkItem = null; + RequestModule.GotCompletedRequest(this); } else if (!RequestModule.CheckAllowed(new Uri(location))) { Status = (int)OSHttpStatusCode.ClientErrorJoker; ResponseBody = "URL from HTTP redirect blocked: " + location; - _finished = true; + WorkItem = null; + RequestModule.GotCompletedRequest(this); } else { @@ -717,9 +755,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest } else { - _finished = true; + WorkItem = null; if (ResponseBody == null) ResponseBody = String.Empty; + RequestModule.GotCompletedRequest(this); } } } @@ -728,10 +767,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { + Removed = true; + if(WorkItem == null) + return; + if (!WorkItem.Cancel()) - { WorkItem.Cancel(true); - } } catch (Exception) { diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs index 978c248..3ab1f6c 100644 --- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs +++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs @@ -87,5 +87,6 @@ namespace OpenSim.Region.Framework.Interfaces void StopHttpRequest(uint m_localID, UUID m_itemID); IServiceRequest GetNextCompletedRequest(); void RemoveCompletedRequest(UUID id); + bool CheckThrottle(uint localID); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 943141c..6cea821 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -13945,14 +13945,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body) { - // Partial implementation: support for parameter flags needed - // see http://wiki.secondlife.com/wiki/LlHTTPRequest - // parameter flags support are implemented in ScriptsHttpRequests.cs - // in StartHttpRequest - m_host.AddScriptLPS(1); - IHttpRequestModule httpScriptMod = - m_ScriptEngine.World.RequestModuleInterface(); + IHttpRequestModule httpScriptMod = m_ScriptEngine.World.RequestModuleInterface(); + if(httpScriptMod == null) + return ""; + + if(!httpScriptMod.CheckThrottle(m_host.LocalId)) + return UUID.Zero.ToString(); + List param = new List(); bool ok; Int32 flag; @@ -14123,8 +14123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } HttpInitialRequestStatus status; - UUID reqID - = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status); + UUID reqID = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status); if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER) Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url)); @@ -14132,7 +14131,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (reqID != UUID.Zero) return reqID.ToString(); else - return null; + return ""; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs index 629b14b..166f2d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs @@ -48,14 +48,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins if (m_CmdManager.m_ScriptEngine.World == null) return; - IHttpRequestModule iHttpReq = - m_CmdManager.m_ScriptEngine.World.RequestModuleInterface(); - - HttpRequestClass httpInfo = null; - - if (iHttpReq != null) - httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest(); + IHttpRequestModule iHttpReq = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface(); + if(iHttpReq == null) + return; + HttpRequestClass httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest(); while (httpInfo != null) { //m_log.Debug("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status); @@ -67,8 +64,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // implemented here yet anyway. Should be fixed if/when maxsize // is supported - iHttpReq.RemoveCompletedRequest(httpInfo.ReqID); - object[] resobj = new object[] { new LSL_Types.LSLString(httpInfo.ReqID.ToString()), -- cgit v1.1 From cd5a6daa84a153fdc3dc7cc3a65363b36d441b34 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 24 Feb 2019 09:46:55 +0000 Subject: also throttle llhttprequest by owner, options: PrimOwnerRequestsBurst = 5, PrimOwnerRequestsPerSec = 25; increase concurrency to 8 --- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 152 ++++++++++++--------- .../Region/Framework/Interfaces/IHttpRequests.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 2 +- 3 files changed, 86 insertions(+), 70 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 54936a3..83d91c4 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -95,16 +95,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private object HttpListLock = new object(); - private int httpTimeout = 30000; + private object m_httpListLock = new object(); + private int m_httpTimeout = 30000; private string m_name = "HttpScriptRequests"; private OutboundUrlFilter m_outboundUrlFilter; private string m_proxyurl = ""; private string m_proxyexcepts = ""; - - private float m_primpersec = 1.0f; - private float m_primburst = 3f; + + private float m_primPerSec = 1.0f; + private float m_primBurst = 3.0f; + private float m_primOwnerPerSec = 25.0f; + private float m_primOwnerBurst = 5.0f; private struct ThrottleData { @@ -116,8 +118,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest private Dictionary m_pendingRequests; private ConcurrentQueue m_CompletedRequests; private ConcurrentDictionary m_RequestsThrottle; + private ConcurrentDictionary m_OwnerRequestsThrottle; - private Scene m_scene; public static SmartThreadPool ThreadPool = null; public HttpRequestModule() @@ -131,38 +133,64 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest return UUID.Zero; } - public bool CheckThrottle(uint localID) + public bool CheckThrottle(uint localID, UUID ownerID) { ThrottleData th; double now = Util.GetTimeStamp(); - bool ret = false; + bool ret; if (m_RequestsThrottle.TryGetValue(localID, out th)) { double delta = now - th.lastTime; th.lastTime = now; - float add = (float)(m_primpersec * delta); + float add = (float)(m_primPerSec * delta); th.count += add; - if (th.count > m_primburst) - th.count = m_primburst; + if (th.count > m_primBurst) + th.count = m_primBurst; ret = th.count > 0; + if (ret) + th.count--; } else { th = new ThrottleData() { lastTime = now, - count = m_primburst + count = m_primBurst - 1 }; ret = true; } + m_RequestsThrottle[localID] = th; - if (ret) - th.count--; + if(!ret) + return false; + + if (m_OwnerRequestsThrottle.TryGetValue(ownerID, out th)) + { + double delta = now - th.lastTime; + th.lastTime = now; + + float add = (float)(m_primOwnerPerSec * delta); + th.count += add; + if (th.count > m_primOwnerBurst) + th.count = m_primOwnerBurst; + + ret = th.count > 0; + if (ret) + th.count--; + } + else + { + th = new ThrottleData() + { + lastTime = now, + count = m_primOwnerBurst - 1 + }; + } + m_OwnerRequestsThrottle[ownerID] = th; - m_RequestsThrottle[localID] = th; return ret; } @@ -170,6 +198,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest uint localID, UUID itemID, string url, List parameters, Dictionary headers, string body, out HttpInitialRequestStatus status) { + if (!CheckAllowed(new Uri(url))) + { + status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER; + return UUID.Zero; + } + UUID reqID = UUID.Random(); HttpRequestClass htc = new HttpRequestClass(); @@ -254,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest htc.ItemID = itemID; htc.Url = url; htc.ReqID = reqID; - htc.HttpTimeout = httpTimeout; + htc.HttpTimeout = m_httpTimeout; htc.OutboundBody = body; htc.ResponseHeaders = headers; htc.proxyurl = m_proxyurl; @@ -263,16 +297,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest // Same number as default HttpWebRequest.MaximumAutomaticRedirections htc.MaxRedirects = 50; - if (StartHttpRequest(htc)) - { - status = HttpInitialRequestStatus.OK; - return htc.ReqID; - } - else - { - status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER; - return UUID.Zero; - } + lock (m_httpListLock) + m_pendingRequests.Add(reqID, htc); + + htc.Process(); + status = HttpInitialRequestStatus.OK; + return reqID; } /// @@ -284,37 +314,21 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest return m_outboundUrlFilter.CheckAllowed(url); } - public bool StartHttpRequest(HttpRequestClass req) - { - if (!CheckAllowed(new Uri(req.Url))) - return false; - - lock (HttpListLock) - m_pendingRequests.Add(req.ReqID, req); - - req.Process(); - - return true; - } - public void StopHttpRequest(uint m_localID, UUID m_itemID) { - if (m_pendingRequests != null) + List toremove = new List(); + lock (m_httpListLock) { - List toremove = new List(); - lock (HttpListLock) + foreach (HttpRequestClass tmpReq in m_pendingRequests.Values) { - foreach (HttpRequestClass tmpReq in m_pendingRequests.Values) + if(tmpReq.ItemID == m_itemID) { - if(tmpReq.ItemID == m_itemID) - { - tmpReq.Stop(); - toremove.Add(tmpReq.ReqID); - } + tmpReq.Stop(); + toremove.Add(tmpReq.ReqID); } - foreach(UUID id in toremove) - m_pendingRequests.Remove(id); } + foreach(UUID id in toremove) + m_pendingRequests.Remove(id); } } @@ -328,10 +342,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest */ public void GotCompletedRequest(HttpRequestClass req) { - if(req.Removed) - return; - lock (HttpListLock) + lock (m_httpListLock) { + if (req.Removed) + return; m_pendingRequests.Remove(req.ReqID); m_CompletedRequests.Enqueue(req); } @@ -340,17 +354,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public IServiceRequest GetNextCompletedRequest() { HttpRequestClass req; - while(m_CompletedRequests.TryDequeue(out req)) - { - if(!req.Removed) - return req; - } + if(m_CompletedRequests.TryDequeue(out req)) + return req; + return null; } public void RemoveCompletedRequest(UUID reqId) { - lock (HttpListLock) + lock (m_httpListLock) { HttpRequestClass tmpReq; if (m_pendingRequests.TryGetValue(reqId, out tmpReq)) @@ -374,18 +386,26 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); - int maxThreads = 5; + int maxThreads = 8; IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"]; if (httpConfig != null) { maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); - m_primburst = httpConfig.GetFloat("PrimRequestsBurst", m_primburst); - m_primpersec = httpConfig.GetFloat("PrimRequestsPerSec", m_primpersec); + m_primBurst = httpConfig.GetFloat("PrimRequestsBurst", m_primBurst); + m_primPerSec = httpConfig.GetFloat("PrimRequestsPerSec", m_primPerSec); + m_primOwnerBurst = httpConfig.GetFloat("PrimOwnerRequestsBurst", m_primOwnerBurst); + m_primOwnerPerSec = httpConfig.GetFloat("PrimOwnerRequestsPerSec", m_primOwnerPerSec); + m_httpTimeout = httpConfig.GetInt("RequestsTimeOut", m_httpTimeout); + if(m_httpTimeout > 60000) + m_httpTimeout = 60000; + else if(m_httpTimeout < 200) + m_httpTimeout = 200; } m_pendingRequests = new Dictionary(); m_CompletedRequests = new ConcurrentQueue(); m_RequestsThrottle = new ConcurrentDictionary(); + m_OwnerRequestsThrottle = new ConcurrentDictionary(); // First instance sets this up for all sims if (ThreadPool == null) @@ -405,16 +425,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void AddRegion(Scene scene) { - m_scene = scene; - - m_scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) { scene.UnregisterModuleInterface(this); - if (scene == m_scene) - m_scene = null; } public void PostInitialise() @@ -570,6 +586,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request.AllowAutoRedirect = false; Request.KeepAlive = false; + Request.Timeout = HttpTimeout; //This works around some buggy HTTP Servers like Lighttpd Request.ServicePoint.Expect100Continue = false; @@ -629,7 +646,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest bstream.Write(data, 0, data.Length); } - Request.Timeout = HttpTimeout; try { // execute the request diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs index 3ab1f6c..2c75844 100644 --- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs +++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs @@ -87,6 +87,6 @@ namespace OpenSim.Region.Framework.Interfaces void StopHttpRequest(uint m_localID, UUID m_itemID); IServiceRequest GetNextCompletedRequest(); void RemoveCompletedRequest(UUID id); - bool CheckThrottle(uint localID); + bool CheckThrottle(uint localID, UUID onerID); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6cea821..bb4bab0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -13950,7 +13950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if(httpScriptMod == null) return ""; - if(!httpScriptMod.CheckThrottle(m_host.LocalId)) + if(!httpScriptMod.CheckThrottle(m_host.LocalId, m_host.OwnerID)) return UUID.Zero.ToString(); List param = new List(); -- cgit v1.1 From d01165818dad7bd81aed07fa983951fecc5a80cd Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 25 Feb 2019 21:46:23 +0000 Subject: change UDPPacketBuffer pools (does waste a bit of memory) --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 8 - .../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 23 +-- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 212 +++++---------------- .../ClientStack/Linden/UDP/LLUDPServerCommands.cs | 37 ---- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 197 +++++++++---------- .../Linden/UDP/UnackedPacketCollection.cs | 2 + 6 files changed, 156 insertions(+), 323 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 943be07..3cb9388 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12555,14 +12555,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// provide your own method. protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) { - -/* this is causing packet loss for some reason - if(!m_udpClient.IsConnected) - { - PacketPool.Instance.ReturnPacket(packet); - return; - } -*/ if (m_outPacketsToDrop != null) { if (m_outPacketsToDrop.Contains(packet.Type.ToString())) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 439621a..bc75d82 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -120,7 +120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Circuit code that this client is connected on public readonly uint CircuitCode; /// Sequence numbers of packets we've received (for duplicate checking) - public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); + public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(256); /// Packets we have sent that need to be ACKed by the client public UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); @@ -803,8 +803,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - - /// /// Fires the OnQueueEmpty callback and sets the minimum time that it /// can be called again @@ -843,6 +841,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP return 0; } + public void FreeUDPBuffer(UDPPacketBuffer buf) + { + m_udpServer.FreeUDPBuffer(buf); + } + /// /// Converts a integer to a /// flag value @@ -853,20 +856,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { ThrottleOutPacketType category = (ThrottleOutPacketType)i; - /* - * Land = 1, - /// Wind data - Wind = 2, - /// Cloud data - Cloud = 3, - /// Any packets that do not fit into the other throttles - Task = 4, - /// Texture assets - Texture = 5, - /// Non-texture assets - Asset = 6, - */ - switch (category) { case ThrottleOutPacketType.Land: diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 35d29a5..4739ae8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -344,18 +344,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected ExpiringCache> m_pendingCache = new ExpiringCache>(); - protected Pool m_incomingPacketPool; - - /// - /// Stat for number of packets in the main pool awaiting use. - /// - protected Stat m_poolCountStat; - - /// - /// Stat for number of packets in the inbound packet pool awaiting use. - /// - protected Stat m_incomingPacketPoolStat; - protected int m_defaultRTO = 0; protected int m_maxRTO = 0; protected int m_ackTimeout = 0; @@ -498,7 +486,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // if (usePools) // EnablePools(); - base.DisablePools(); } public void Start() @@ -554,83 +541,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP OqrEngine.Stop(); } - public override bool EnablePools() - { - if (!UsePools) - { - base.EnablePools(); - - m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500); - - return true; - } - - return false; - } - - public override bool DisablePools() - { - if (UsePools) - { - base.DisablePools(); - - StatsManager.DeregisterStat(m_incomingPacketPoolStat); - - // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. - - return true; - } - - return false; - } - - /// - /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene - /// stats. - /// - protected internal void EnablePoolStats() - { - m_poolCountStat - = new Stat( - "UDPPacketBufferPoolCount", - "Objects within the UDPPacketBuffer pool", - "The number of objects currently stored within the UDPPacketBuffer pool", - "", - "clientstack", - Scene.Name, - StatType.Pull, - stat => stat.Value = Pool.Count, - StatVerbosity.Debug); - - StatsManager.RegisterStat(m_poolCountStat); - - m_incomingPacketPoolStat - = new Stat( - "IncomingPacketPoolCount", - "Objects within incoming packet pool", - "The number of objects currently stored within the incoming packet pool", - "", - "clientstack", - Scene.Name, - StatType.Pull, - stat => stat.Value = m_incomingPacketPool.Count, - StatVerbosity.Debug); - - StatsManager.RegisterStat(m_incomingPacketPoolStat); - } - - /// - /// Disables pool stats. - /// - protected internal void DisablePoolStats() - { - StatsManager.DeregisterStat(m_poolCountStat); - m_poolCountStat = null; - - StatsManager.DeregisterStat(m_incomingPacketPoolStat); - m_incomingPacketPoolStat = null; - } - /// /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. /// @@ -658,8 +568,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), "INCOMING PACKET ASYNC HANDLING ENGINE"); */ - OqrEngine - = new JobEngine( + OqrEngine = new JobEngine( string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), "OUTGOING QUEUE REFILL ENGINE"); @@ -769,15 +678,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP stat => stat.Value = OqrEngine.JobsWaiting, StatVerbosity.Debug)); - // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by - // scene name - if (UsePools) - EnablePoolStats(); - + StatsManager.RegisterStat( + new Stat( + "UDPBuffersPoolCount", + "Buffers in the UDP buffers pool", + "The number of buffers currently stored within the UDP buffers pool", + "", + "clientstack", + Scene.Name, + StatType.Pull, + stat => stat.Value = m_udpBuffersPoolPtr, + StatVerbosity.Debug)); LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); commands.Register(); - } public bool HandlesRegion(Location x) @@ -939,9 +853,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here // to accomodate for both common scenarios and provide ample room for ACK appending in both - int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; + //int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; - UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); + //UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); + UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint); // Zerocode if needed if (doZerocode) @@ -971,7 +886,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // If the packet data wasn't already copied during zerocoding, copy it now if (doCopy) { - if (dataLength <= buffer.Data.Length) + //if (dataLength <= buffer.Data.Length) + if (dataLength <= LLUDPServer.MTU) { Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); } @@ -979,7 +895,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); - buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); + // buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); + buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint); Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); } } @@ -1168,22 +1085,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Set the appended ACKs flag on this packet buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); } + buffer.DataLength = dataLength; } - buffer.DataLength = dataLength; - if (!isResend) { // Not a resend, assign a new sequence number uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence); Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); outgoingPacket.SequenceNumber = sequenceNumber; - - if (isReliable) - { - // Add this packet to the list of ACK responses we are waiting on from the server - udpClient.NeedAcks.Add(outgoingPacket); - } } else { @@ -1196,9 +1106,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP PacketsSentCount++; SyncSend(buffer); + // Keep track of when this packet was sent out (right now) outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; + if (outgoingPacket.UnackedMethod == null) + FreeUDPBuffer(buffer); + else if(!isResend) + { + // Add this packet to the list of ACK responses we are waiting on from the server + udpClient.NeedAcks.Add(outgoingPacket); + } + if (udpClient.DebugDataOutLevel > 0) m_log.DebugFormat( "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", @@ -1240,7 +1159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); RecordMalformedInboundPacket(endPoint); - + FreeUDPBuffer(buffer); return; // Drop undersized packet } @@ -1260,21 +1179,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); RecordMalformedInboundPacket(endPoint); - + FreeUDPBuffer(buffer); return; // Malformed header } try { -// packet = Packet.BuildPacket(buffer.Data, ref packetEnd, -// // Only allocate a buffer for zerodecoding if the packet is zerocoded -// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); + packet = Packet.BuildPacket(buffer.Data, ref packetEnd, + // Only allocate a buffer for zerodecoding if the packet is zerocoded + ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all // bytes are copied out). - packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, +// packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, // Only allocate a buffer for zerodecoding if the packet is zerocoded - ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); +// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); } catch (Exception e) { @@ -1292,7 +1211,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } RecordMalformedInboundPacket(endPoint); - + FreeUDPBuffer(buffer); return; } @@ -1311,17 +1230,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP lock (m_pendingCache) { if (m_pendingCache.Contains(endPoint)) + { + FreeUDPBuffer(buffer); return; + } m_pendingCache.AddOrUpdate(endPoint, new Queue(), 60); } - // We need to copy the endpoint so that it doesn't get changed when another thread reuses the - // buffer. - object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; - - Util.FireAndForget(HandleUseCircuitCode, array); - + Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet }); + FreeUDPBuffer(buffer); return; } } @@ -1336,24 +1254,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP queue.Enqueue(buffer); return; } - -/* - else if (packet.Type == PacketType.CompleteAgentMovement) - { - // Send ack straight away to let the viewer know that we got it. - SendAckImmediate(endPoint, packet.Header.Sequence); - - // We need to copy the endpoint so that it doesn't get changed when another thread reuses the - // buffer. - object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; - - Util.FireAndForget(HandleCompleteMovementIntoRegion, array); - - return; - } - */ } + FreeUDPBuffer(buffer); + // Determine which agent this packet came from if (client == null || !(client is LLClientView)) { @@ -1471,10 +1375,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); #endregion BinaryStats - -//AgentUpdate removed from here - - #region Ping Check Handling if (packet.Type == PacketType.StartPingCheck) @@ -1506,17 +1406,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP IncomingPacket incomingPacket; - // Inbox insertion - if (UsePools) - { - incomingPacket = m_incomingPacketPool.GetObject(); - incomingPacket.Client = (LLClientView)client; - incomingPacket.Packet = packet; - } - else - { - incomingPacket = new IncomingPacket((LLClientView)client, packet); - } + incomingPacket = new IncomingPacket((LLClientView)client, packet); // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || // incomingPacket.Packet.Type == PacketType.ChatFromViewer) @@ -1525,7 +1415,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // else // packetInbox.Enqueue(incomingPacket); packetInbox.Add(incomingPacket); - } #region BinaryStats @@ -1881,13 +1770,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[] packetData = ack.ToBytes(); int length = packetData.Length; - UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length); + UDPPacketBuffer buffer = GetNewUDPBuffer(remoteEndpoint); buffer.DataLength = length; Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); // AsyncBeginSend(buffer); SyncSend(buffer); + FreeUDPBuffer(buffer); } protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) @@ -1982,17 +1872,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP Scene.ThreadAlive(1); try { - packetInbox.TryTake(out incomingPacket, 250); + packetInbox.TryTake(out incomingPacket, 4500); if (incomingPacket != null && IsRunningInbound) { ProcessInPacket(incomingPacket); - - if (UsePools) - { - incomingPacket.Client = null; - m_incomingPacketPool.ReturnObject(incomingPacket); - } incomingPacket = null; } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs index 012a57d..a4d7eb9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs @@ -777,41 +777,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpServer.StopOutbound(); } - private void HandlePoolCommand(string module, string[] args) - { - if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) - return; - - if (args.Length != 4) - { - MainConsole.Instance.Output("Usage: debug lludp pool "); - return; - } - - string enabled = args[3]; - - if (enabled == "on") - { - if (m_udpServer.EnablePools()) - { - m_udpServer.EnablePoolStats(); - MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name); - } - } - else if (enabled == "off") - { - if (m_udpServer.DisablePools()) - { - m_udpServer.DisablePoolStats(); - MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name); - } - } - else - { - MainConsole.Instance.Output("Usage: debug lludp pool "); - } - } - private void HandleAgentUpdateCommand(string module, string[] args) { if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) @@ -834,8 +799,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP MainConsole.Instance.OutputFormat( "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled"); - MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off"); - MainConsole.Instance.OutputFormat( "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index f362b06..0bfd86c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Threading; @@ -57,15 +58,9 @@ namespace OpenMetaverse /// UDP socket, used in either client or server mode private Socket m_udpSocket; - /// - /// Are we to use object pool(s) to reduce memory churn when receiving data? - /// - public bool UsePools { get; protected set; } - - /// - /// Pool to use for handling data. May be null if UsePools = false; - /// - protected OpenSim.Framework.Pool Pool { get; private set; } + public static Object m_udpBuffersPoolLock = new Object(); + public static UDPPacketBuffer[] m_udpBuffersPool = new UDPPacketBuffer[1000]; + public static int m_udpBuffersPoolPtr = -1; /// Returns true if the server is currently listening for inbound packets, otherwise false public bool IsRunningInbound { get; private set; } @@ -186,6 +181,52 @@ namespace OpenMetaverse if(m_udpSocket !=null) try { m_udpSocket.Close(); } catch { } } + + public UDPPacketBuffer GetNewUDPBuffer() + { + lock (m_udpBuffersPoolLock) + { + if (m_udpBuffersPoolPtr >= 0) + { + UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr]; + m_udpBuffersPool[m_udpBuffersPoolPtr] = null; + m_udpBuffersPoolPtr--; + buf.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + return buf; + } + } + return new UDPPacketBuffer(new IPEndPoint(IPAddress.Any, 0)); + } + + public UDPPacketBuffer GetNewUDPBuffer(IPEndPoint remoteEndpoint) + { + lock (m_udpBuffersPoolLock) + { + if (m_udpBuffersPoolPtr >= 0) + { + UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr]; + m_udpBuffersPool[m_udpBuffersPoolPtr] = null; + m_udpBuffersPoolPtr--; + buf.RemoteEndPoint = remoteEndpoint; + return buf; + } + } + return new UDPPacketBuffer(remoteEndpoint); + } + + public void FreeUDPBuffer(UDPPacketBuffer buf) + { + lock (m_udpBuffersPoolLock) + { + if (m_udpBuffersPoolPtr < 999) + { + buf.RemoteEndPoint = null; + m_udpBuffersPoolPtr++; + m_udpBuffersPool[m_udpBuffersPoolPtr] = buf; + } + } + } + /// /// Start inbound UDP packet handling. /// @@ -202,6 +243,7 @@ namespace OpenMetaverse /// manner (not throwing an exception when the remote side resets the /// connection). This call is ignored on Mono where the flag is not /// necessary + public virtual void StartInbound(int recvBufferSize) { if (!IsRunningInbound) @@ -306,101 +348,64 @@ namespace OpenMetaverse IsRunningOutbound = false; } - public virtual bool EnablePools() + private void AsyncBeginReceive() { - if (!UsePools) - { - Pool = new Pool(() => new UDPPacketBuffer(), 500); - - UsePools = true; - - return true; - } - - return false; - } + if (!IsRunningInbound) + return; - public virtual bool DisablePools() - { - if (UsePools) + UDPPacketBuffer buf = GetNewUDPBuffer(); + try { - UsePools = false; - - // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. - - return true; + // kick off an async read + m_udpSocket.BeginReceiveFrom( + //wrappedBuffer.Instance.Data, + buf.Data, + 0, + UDPPacketBuffer.BUFFER_SIZE, + SocketFlags.None, + ref buf.RemoteEndPoint, + AsyncEndReceive, + //wrappedBuffer); + buf); } - - return false; - } - - private void AsyncBeginReceive() - { - UDPPacketBuffer buf; - - // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other - // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux. - // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation. -// if (UsePools) -// buf = Pool.GetObject(); -// else - buf = new UDPPacketBuffer(); - - if (IsRunningInbound) + catch (SocketException e) { - try + if (e.SocketErrorCode == SocketError.ConnectionReset) { - // kick off an async read - m_udpSocket.BeginReceiveFrom( - //wrappedBuffer.Instance.Data, - buf.Data, - 0, - UDPPacketBuffer.BUFFER_SIZE, - SocketFlags.None, - ref buf.RemoteEndPoint, - AsyncEndReceive, - //wrappedBuffer); - buf); - } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.ConnectionReset) + m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); + bool salvaged = false; + while (!salvaged) { - m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); - bool salvaged = false; - while (!salvaged) + try { - try - { - m_udpSocket.BeginReceiveFrom( - //wrappedBuffer.Instance.Data, - buf.Data, - 0, - UDPPacketBuffer.BUFFER_SIZE, - SocketFlags.None, - ref buf.RemoteEndPoint, - AsyncEndReceive, - //wrappedBuffer); - buf); - salvaged = true; - } - catch (SocketException) { } - catch (ObjectDisposedException) { return; } + m_udpSocket.BeginReceiveFrom( + //wrappedBuffer.Instance.Data, + buf.Data, + 0, + UDPPacketBuffer.BUFFER_SIZE, + SocketFlags.None, + ref buf.RemoteEndPoint, + AsyncEndReceive, + //wrappedBuffer); + buf); + salvaged = true; } - - m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); + catch (SocketException) { } + catch (ObjectDisposedException) { return; } } + + m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); } - catch (ObjectDisposedException e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); - } - catch (Exception e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); - } + } + catch (ObjectDisposedException e) + { + m_log.Error( + string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); + } + catch (Exception e) + { + m_log.Error( + string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); } } @@ -465,14 +470,12 @@ namespace OpenMetaverse } finally { -// if (UsePools) -// Pool.ReturnObject(buffer); - AsyncBeginReceive(); } } } +/* not in use public void AsyncBeginSend(UDPPacketBuffer buf) { // if (IsRunningOutbound) @@ -511,7 +514,7 @@ namespace OpenMetaverse catch (SocketException) { } catch (ObjectDisposedException) { } } - +*/ public void SyncSend(UDPPacketBuffer buf) { try diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs index 76f4c6f..e0eee53 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs @@ -203,6 +203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (ackedPacket != null) { m_packets.Remove(pendingAcknowledgement.SequenceNumber); + ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer); // As with other network applications, assume that an acknowledged packet is an // indication that the network can handle a little more load, speed up the transmission @@ -241,6 +242,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (removedPacket != null) { m_packets.Remove(pendingRemove); + removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); // Update stats Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); -- cgit v1.1 From 91fab702361ecaf8a442e7cf3a469aaa6daead44 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 25 Feb 2019 23:05:11 +0000 Subject: removed a redundant function; try to make a particular vi coder happy about removed comments --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | 12 ++++++------ .../Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 18 +----------------- 2 files changed, 7 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index bc75d82..e0cca05 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -859,17 +859,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP switch (category) { case ThrottleOutPacketType.Land: - return ThrottleOutPacketTypeFlags.Land; + return ThrottleOutPacketTypeFlags.Land; // Terrain data case ThrottleOutPacketType.Wind: - return ThrottleOutPacketTypeFlags.Wind; + return ThrottleOutPacketTypeFlags.Wind; // Wind data case ThrottleOutPacketType.Cloud: - return ThrottleOutPacketTypeFlags.Cloud; + return ThrottleOutPacketTypeFlags.Cloud; // Cloud data case ThrottleOutPacketType.Task: - return ThrottleOutPacketTypeFlags.Task; + return ThrottleOutPacketTypeFlags.Task; // Object updates and everything not on the other categories case ThrottleOutPacketType.Texture: - return ThrottleOutPacketTypeFlags.Texture; + return ThrottleOutPacketTypeFlags.Texture; // Textures data (also impacts http texture and mesh by default) case ThrottleOutPacketType.Asset: - return ThrottleOutPacketTypeFlags.Asset; + return ThrottleOutPacketTypeFlags.Asset; // Non-texture Assets data default: return 0; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 0bfd86c..7f6a292 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -182,22 +182,6 @@ namespace OpenMetaverse try { m_udpSocket.Close(); } catch { } } - public UDPPacketBuffer GetNewUDPBuffer() - { - lock (m_udpBuffersPoolLock) - { - if (m_udpBuffersPoolPtr >= 0) - { - UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr]; - m_udpBuffersPool[m_udpBuffersPoolPtr] = null; - m_udpBuffersPoolPtr--; - buf.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - return buf; - } - } - return new UDPPacketBuffer(new IPEndPoint(IPAddress.Any, 0)); - } - public UDPPacketBuffer GetNewUDPBuffer(IPEndPoint remoteEndpoint) { lock (m_udpBuffersPoolLock) @@ -353,7 +337,7 @@ namespace OpenMetaverse if (!IsRunningInbound) return; - UDPPacketBuffer buf = GetNewUDPBuffer(); + UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least try { // kick off an async read -- cgit v1.1 From d5d4dc475461f889194a84aa682fbd555aad303f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 25 Feb 2019 23:30:01 +0000 Subject: zero decode using a buffer from the pool --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 4739ae8..e931f3b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1185,15 +1185,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - packet = Packet.BuildPacket(buffer.Data, ref packetEnd, - // Only allocate a buffer for zerodecoding if the packet is zerocoded - ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); + // get a buffer for zero decode using the udp buffers pool + UDPPacketBuffer zerodecodebufferholder = null; + byte[] zerodecodebuffer = null; + // only if needed + if (((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0)) + { + zerodecodebufferholder = GetNewUDPBuffer(null); + zerodecodebuffer = zerodecodebufferholder.Data; + } + + packet = Packet.BuildPacket(buffer.Data, ref packetEnd, zerodecodebuffer); // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all // bytes are copied out). -// packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, - // Only allocate a buffer for zerodecoding if the packet is zerocoded -// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); + // packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, zerodecodebuffer); + if(zerodecodebufferholder != null) + FreeUDPBuffer(zerodecodebufferholder); } catch (Exception e) { -- cgit v1.1 From a07951b04471ff4d0c6204f2c13c49248f0b7d19 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 26 Feb 2019 00:43:44 +0000 Subject: fix UDPBuffersPoolCount value (readable with stats show clientstack --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index e931f3b..ba5a2f3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -687,7 +687,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP "clientstack", Scene.Name, StatType.Pull, - stat => stat.Value = m_udpBuffersPoolPtr, + stat => stat.Value = m_udpBuffersPoolPtr + 1, StatVerbosity.Debug)); LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); @@ -1582,7 +1582,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); return; - } m_pendingCache.Remove(endPoint); } -- cgit v1.1 From 91569e00a0a4f9b9124979b73e00a4e88020c6cd Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 26 Feb 2019 01:16:30 +0000 Subject: buffers in pool have no data, better mk that clear --- OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 7f6a292..5fa4637 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -205,6 +205,7 @@ namespace OpenMetaverse if (m_udpBuffersPoolPtr < 999) { buf.RemoteEndPoint = null; + buf.DataLength = 0; m_udpBuffersPoolPtr++; m_udpBuffersPool[m_udpBuffersPoolPtr] = buf; } -- cgit v1.1 From e24adb9ea12d68f743b5936d6b04899dcef83dfc Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 26 Feb 2019 13:38:03 +0000 Subject: mantis 6569: restore full health on invulnerable set to true; combat module is outdated and needs work. By then the proposal on this mantis should be reviewed --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cfb1be4..f3e2179 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -523,7 +523,12 @@ namespace OpenSim.Region.Framework.Scenes public bool Invulnerable { - set { m_invulnerable = value; } + set + { + m_invulnerable = value; + if(value && Health != 100.0f) + Health = 100.0f; + } get { return m_invulnerable; } } -- cgit v1.1 From 4de5e14e542cd9724625e87622f29fecf5652642 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 26 Feb 2019 15:02:57 +0000 Subject: issues with udp buffers pool on heavy load --- .../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 30 ++++++++++++++++------ .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 29 +++++++++++---------- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 22 ++++------------ .../Linden/UDP/UnackedPacketCollection.cs | 14 +++++++--- 4 files changed, 53 insertions(+), 42 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index e0cca05..fca7943 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -650,6 +650,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP // leaving a dequeued packet still waiting to be sent out. Try to // send it again OutgoingPacket nextPacket = m_nextPackets[i]; + if(nextPacket.Buffer == null) + { + if (m_packetOutboxes[i].Count < 5) + emptyCategories |= CategoryToFlag(i); + continue; + } if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) { // Send the packet @@ -681,21 +687,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // A packet was pulled off the queue. See if we have // enough tokens in the bucket to send it out - if (bucket.RemoveTokens(packet.Buffer.DataLength)) + if(packet.Buffer == null) { - // Send the packet - m_udpServer.SendPacketFinal(packet); - packetSent = true; - + // packet canceled elsewhere (by a ack for example) if (queue.Count < 5) emptyCategories |= CategoryToFlag(i); } else { - // Save the dequeued packet for the next iteration - m_nextPackets[i] = packet; + if (bucket.RemoveTokens(packet.Buffer.DataLength)) + { + // Send the packet + m_udpServer.SendPacketFinal(packet); + packetSent = true; + + if (queue.Count < 5) + emptyCategories |= CategoryToFlag(i); + } + else + { + // Save the dequeued packet for the next iteration + m_nextPackets[i] = packet; + } } - } else { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index ba5a2f3..d324623 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -983,7 +983,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { LLUDPClient udpClient = client.UDPClient; - if (!udpClient.IsConnected) + if (!client.IsActive || !udpClient.IsConnected) return; // Disconnect an agent if no packets are received for some time @@ -1053,14 +1053,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP internal void SendPacketFinal(OutgoingPacket outgoingPacket) { UDPPacketBuffer buffer = outgoingPacket.Buffer; + if(buffer == null) // canceled packet + return; + LLUDPClient udpClient = outgoingPacket.Client; + if (!udpClient.IsConnected) + return; + byte flags = buffer.Data[0]; bool isResend = (flags & Helpers.MSG_RESENT) != 0; bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; - LLUDPClient udpClient = outgoingPacket.Client; - - if (!udpClient.IsConnected) - return; int dataLength = buffer.DataLength; @@ -1916,7 +1918,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { Scene.ThreadAlive(2); - try { m_packetSent = false; @@ -1971,7 +1972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else if (!m_packetSent) // Thread.Sleep((int)TickCountResolution); outch this is bad on linux - Thread.Sleep(15); // match the 16ms of windows7, dont ask 16 or win may decide to do 32ms. + Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms. Watchdog.UpdateThread(); } @@ -1995,14 +1996,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (udpClient.IsConnected) { - if (m_resendUnacked) + if (client.IsActive && m_resendUnacked) HandleUnacked(llClient); - if (m_sendAcks) - SendAcks(udpClient); + if (client.IsActive) + { + if (m_sendAcks) + SendAcks(udpClient); - if (m_sendPing) - SendPing(udpClient); + if (m_sendPing) + SendPing(udpClient); + } // Dequeue any outgoing packets that are within the throttle limits if (udpClient.DequeueOutgoing()) @@ -2015,7 +2019,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_log.Error( string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); } - client = null; } #region Emergency Monitoring diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 5fa4637..6f346d3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -343,14 +343,12 @@ namespace OpenMetaverse { // kick off an async read m_udpSocket.BeginReceiveFrom( - //wrappedBuffer.Instance.Data, buf.Data, 0, - UDPPacketBuffer.BUFFER_SIZE, + buf.Data.Length, SocketFlags.None, ref buf.RemoteEndPoint, AsyncEndReceive, - //wrappedBuffer); buf); } catch (SocketException e) @@ -364,14 +362,12 @@ namespace OpenMetaverse try { m_udpSocket.BeginReceiveFrom( - //wrappedBuffer.Instance.Data, buf.Data, 0, - UDPPacketBuffer.BUFFER_SIZE, + buf.Data.Length, SocketFlags.None, ref buf.RemoteEndPoint, AsyncEndReceive, - //wrappedBuffer); buf); salvaged = true; } @@ -382,11 +378,6 @@ namespace OpenMetaverse m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); } } - catch (ObjectDisposedException e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); - } catch (Exception e) { m_log.Error( @@ -443,11 +434,6 @@ namespace OpenMetaverse UdpReceives, se.ErrorCode), se); } - catch (ObjectDisposedException e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e); - } catch (Exception e) { m_log.Error( @@ -502,6 +488,8 @@ namespace OpenMetaverse */ public void SyncSend(UDPPacketBuffer buf) { + if(buf.RemoteEndPoint == null) + return; // was already expired try { m_udpSocket.SendTo( @@ -515,7 +503,7 @@ namespace OpenMetaverse } catch (SocketException e) { - m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message); + m_log.WarnFormat("[UDPBASE]: sync send SocketException {0} {1}", buf.RemoteEndPoint, e.Message); } catch (ObjectDisposedException) { } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs index e0eee53..1f978e1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs @@ -189,8 +189,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Process all the pending adds OutgoingPacket pendingAdd; while (m_pendingAdds.TryDequeue(out pendingAdd)) + { if (pendingAdd != null) m_packets[pendingAdd.SequenceNumber] = pendingAdd; + } // Process all the pending removes, including updating statistics and round-trip times PendingAck pendingAcknowledgement; @@ -203,15 +205,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (ackedPacket != null) { m_packets.Remove(pendingAcknowledgement.SequenceNumber); + + // Update stats + Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); + ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer); + ackedPacket.Buffer = null; // As with other network applications, assume that an acknowledged packet is an // indication that the network can handle a little more load, speed up the transmission ackedPacket.Client.FlowThrottle.AcknowledgePackets(1); - // Update stats - Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); - if (!pendingAcknowledgement.FromResend) { // Calculate the round-trip time for this packet and its ACK @@ -242,10 +246,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (removedPacket != null) { m_packets.Remove(pendingRemove); - removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); // Update stats Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); + + removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); + removedPacket.Buffer = null; } } } -- cgit v1.1 From fe46f8cd1ddbf3d37e8be4a3771ce5124024d6f8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 26 Feb 2019 15:09:18 +0000 Subject: avoid packet split on terseupdates --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 106 +++++++++++++++------ 1 file changed, 76 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 3cb9388..f28534b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4094,11 +4094,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; List objectUpdateBlocks = null; - List compressedUpdateBlocks = null; - List terseUpdateBlocks = null; - List terseAgentUpdateBlocks = null; + // List compressedUpdateBlocks = null; List objectUpdates = null; - List compressedUpdates = null; + // List compressedUpdates = null; List terseUpdates = null; List terseAgentUpdates = null; List ObjectAnimationUpdates = null; @@ -4321,32 +4319,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP if ((updateFlags & canNotUseImprovedMask) == 0) { - ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock = - CreateImprovedTerseBlock(update.Entity); if (update.Entity is ScenePresence) { // ALL presence updates go into a special list - if (terseAgentUpdateBlocks == null) + if (terseAgentUpdates == null) { - terseAgentUpdateBlocks = new List(); terseAgentUpdates = new List(); + maxUpdatesBytes -= 18; } - terseAgentUpdateBlocks.Add(ablock); terseAgentUpdates.Add(update); + maxUpdatesBytes -= 63; // no texture entry } else { // Everything else goes here - if (terseUpdateBlocks == null) + if (terseUpdates == null) { - terseUpdateBlocks = new List(); terseUpdates = new List(); + maxUpdatesBytes -= 18; } - terseUpdateBlocks.Add(ablock); terseUpdates.Add(update); + maxUpdatesBytes -= 47; // no texture entry } - maxUpdatesBytes -= ablock.Length; } else { @@ -4359,6 +4354,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { objectUpdateBlocks = new List(); objectUpdates = new List(); + maxUpdatesBytes -= 18; } objectUpdateBlocks.Add(ablock); objectUpdates.Add(update); @@ -4377,16 +4373,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); - if (terseAgentUpdateBlocks != null) + if (terseAgentUpdates != null) { + const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry + int blocks = terseAgentUpdates.Count; + ImprovedTerseObjectUpdatePacket packet - = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.TimeDilation = timeDilation; - packet.ObjectData = terseAgentUpdateBlocks.ToArray(); - terseAgentUpdateBlocks.Clear(); - OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates, oPacket); }); + int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; + List tau = new List(curNBlocks); + packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; + + int count = 0; + foreach (EntityUpdate eu in terseAgentUpdates) + { + packet.ObjectData[count++] = CreateImprovedTerseBlock(eu.Entity); + tau.Add(eu); + --blocks; + if (count == curNBlocks && blocks > 0) + { + OutPacket(packet, ThrottleOutPacketType.Unknown, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); + packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + packet.RegionData.TimeDilation = timeDilation; + + curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; + tau = new List(curNBlocks); + packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; + count = 0; + } + } + + if (tau.Count > 0) + OutPacket(packet, ThrottleOutPacketType.Unknown, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); } if (objectUpdateBlocks != null) @@ -4399,7 +4421,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates, oPacket); }); } - +/* if (compressedUpdateBlocks != null) { ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); @@ -4410,20 +4432,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates, oPacket); }); } - - if (terseUpdateBlocks != null) +*/ + if (terseUpdates != null) { - ImprovedTerseObjectUpdatePacket packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( - PacketType.ImprovedTerseObjectUpdate); + const int maxNBlocks = (LLUDPServer.MTU - 18) / 47; // no texture entry + int blocks = terseUpdates.Count; + + ImprovedTerseObjectUpdatePacket packet = + (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.TimeDilation = timeDilation; - packet.ObjectData = terseUpdateBlocks.ToArray(); - terseUpdateBlocks.Clear(); - OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates, oPacket); }); + int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; + List tau = new List(curNBlocks); + packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; + + int count = 0; + foreach (EntityUpdate eu in terseUpdates) + { + packet.ObjectData[count++] = CreateImprovedTerseBlock(eu.Entity); + tau.Add(eu); + --blocks; + if (count == curNBlocks && blocks > 0) + { + OutPacket(packet, ThrottleOutPacketType.Task, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); + packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + packet.RegionData.TimeDilation = timeDilation; + + curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; + tau = new List(curNBlocks); + packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; + count = 0; + } + } + + if (tau.Count > 0) + OutPacket(packet, ThrottleOutPacketType.Task, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); } - if(ObjectAnimationUpdates != null) + if (ObjectAnimationUpdates != null) { foreach (SceneObjectPart sop in ObjectAnimationUpdates) { @@ -4637,9 +4685,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // These are used to implement an adaptive backoff in the number // of updates converted to packets. Since we don't want packets // to sit in the queue with old data, only convert enough updates - // to packets that can be sent in 200ms. -// private Int32 m_LastQueueFill = 0; -// private Int32 m_maxUpdates = 0; + // to packets that can be sent in 30ms. void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) { -- cgit v1.1 From bcf05afd64d3b38c66d6d117a51e336a7e98dfc3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 27 Feb 2019 10:07:25 +0000 Subject: direct encode terseupdates --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 210 ++++++++++++++++++--- .../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 11 +- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 21 +++ .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 2 +- 4 files changed, 207 insertions(+), 37 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f28534b..a9edf08 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4084,6 +4084,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP ResendPrimUpdate(update); } + static private readonly byte[] terseUpdateHeader = new byte[] { + Helpers.MSG_RELIABLE, + 0, 0, 0, 0, // sequence number + 0, // extra + 15 // ID (high frequency) + }; + private void ProcessEntityUpdates(int maxUpdatesBytes) { if (!IsActive) @@ -4377,38 +4384,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP { const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry int blocks = terseAgentUpdates.Count; - - ImprovedTerseObjectUpdatePacket packet - = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - packet.RegionData.TimeDilation = timeDilation; - int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; List tau = new List(curNBlocks); - packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + + //setup header and regioninfo block + Array.Copy(terseUpdateHeader, buf.Data, 7); + Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); + Utils.UInt16ToBytes(timeDilation, buf.Data, 15); + buf.Data[17] = (byte)curNBlocks; + int pos = 18; int count = 0; foreach (EntityUpdate eu in terseAgentUpdates) { - packet.ObjectData[count++] = CreateImprovedTerseBlock(eu.Entity); + CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos); tau.Add(eu); + ++count; --blocks; if (count == curNBlocks && blocks > 0) { - OutPacket(packet, ThrottleOutPacketType.Unknown, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); - packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - packet.RegionData.TimeDilation = timeDilation; + // we need more packets + UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + Array.Copy(buf.Data, newbuf.Data, 17); // start is the same + + buf.DataLength = pos; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; tau = new List(curNBlocks); - packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; count = 0; + + buf = newbuf; + buf.Data[17] = (byte)curNBlocks; + pos = 18; } } - if (tau.Count > 0) - OutPacket(packet, ThrottleOutPacketType.Unknown, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); + if (count > 0) + { + buf.DataLength = pos; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); + } } if (objectUpdateBlocks != null) @@ -4437,38 +4457,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP { const int maxNBlocks = (LLUDPServer.MTU - 18) / 47; // no texture entry int blocks = terseUpdates.Count; - - ImprovedTerseObjectUpdatePacket packet = - (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - packet.RegionData.TimeDilation = timeDilation; - int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; List tau = new List(curNBlocks); - packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + + //setup header and regioninfo block + Array.Copy(terseUpdateHeader, buf.Data, 7); + Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); + Utils.UInt16ToBytes(timeDilation, buf.Data, 15); + buf.Data[17] = (byte)curNBlocks; + int pos = 18; int count = 0; foreach (EntityUpdate eu in terseUpdates) { - packet.ObjectData[count++] = CreateImprovedTerseBlock(eu.Entity); + CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos); tau.Add(eu); + ++count; --blocks; if (count == curNBlocks && blocks > 0) { - OutPacket(packet, ThrottleOutPacketType.Task, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); - packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - packet.RegionData.TimeDilation = timeDilation; + // we need more packets + UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + Array.Copy(buf.Data, newbuf.Data, 17); // start is the same + + buf.DataLength = pos; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; tau = new List(curNBlocks); - packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[curNBlocks]; count = 0; + + buf = newbuf; + buf.Data[17] = (byte)curNBlocks; + pos = 18; } } - if (tau.Count > 0) - OutPacket(packet, ThrottleOutPacketType.Task, false, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }); + if (count > 0) + { + buf.DataLength = pos; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); + } } if (ObjectAnimationUpdates != null) @@ -5686,6 +5719,123 @@ namespace OpenSim.Region.ClientStack.LindenUDP return block; } + + protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos) + { + #region ScenePresence/SOP Handling + + bool avatar = (entity is ScenePresence); + uint localID = entity.LocalId; + uint attachPoint; + Vector4 collisionPlane; + Vector3 position, velocity, acceleration, angularVelocity; + Quaternion rotation; + byte datasize; + + if (avatar) + { + ScenePresence presence = (ScenePresence)entity; + + position = presence.OffsetPosition; + velocity = presence.Velocity; + acceleration = Vector3.Zero; + rotation = presence.Rotation; + // tpvs can only see rotations around Z in some cases + if (!presence.Flying && !presence.IsSatOnObject) + { + rotation.X = 0f; + rotation.Y = 0f; + } + rotation.Normalize(); + angularVelocity = presence.AngularVelocity; + + // m_log.DebugFormat( + // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name); + + attachPoint = presence.State; + collisionPlane = presence.CollisionPlane; + + datasize = 60; + } + else + { + SceneObjectPart part = (SceneObjectPart)entity; + + attachPoint = part.ParentGroup.AttachmentPoint; + attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16)); + // m_log.DebugFormat( + // "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", + // attachPoint, part.Name, part.LocalId, Name); + + collisionPlane = Vector4.Zero; + position = part.RelativePosition; + velocity = part.Velocity; + acceleration = part.Acceleration; + angularVelocity = part.AngularVelocity; + rotation = part.RotationOffset; + + datasize = 44; + } + + #endregion ScenePresence/SOP Handling + //object block size + data[pos++] = datasize; + + // LocalID + Utils.UIntToBytes(localID, data, pos); + pos += 4; + + // Avatar/CollisionPlane + data[pos++] = (byte)attachPoint; + if (avatar) + { + data[pos++] = 1; + + if (collisionPlane == Vector4.Zero) + collisionPlane = Vector4.UnitW; + //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane); + collisionPlane.ToBytes(data, pos); + pos += 16; + } + else + { + data[pos++] = 0; + } + + // Position + position.ToBytes(data, pos); + pos += 12; + + // Velocity + ClampVectorForUint(ref velocity, 128f); + Utils.FloatToUInt16Bytes(velocity.X, 128.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(velocity.Y, 128.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(velocity.Z, 128.0f, data, pos); pos += 2; + + // Acceleration + ClampVectorForUint(ref acceleration, 64f); + Utils.FloatToUInt16Bytes(acceleration.X, 64.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(acceleration.Y, 64.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(acceleration.Z, 64.0f, data, pos); pos += 2; + + // Rotation + Utils.FloatToUInt16Bytes(rotation.X, 1.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(rotation.Y, 1.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(rotation.Z, 1.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(rotation.W, 1.0f, data, pos); pos += 2; + + // Angular Velocity + ClampVectorForUint(ref angularVelocity, 64f); + Utils.FloatToUInt16Bytes(angularVelocity.X, 64.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(angularVelocity.Y, 64.0f, data, pos); pos += 2; + Utils.FloatToUInt16Bytes(angularVelocity.Z, 64.0f, data, pos); pos += 2; + + // texture entry block size + data[pos++] = 0; + data[pos++] = 0; + // total size 63 or 47 + } + protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) { Vector3 offsetPosition = data.OffsetPosition; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index fca7943..d0d2152 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -575,22 +575,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP { DoubleLocklessQueue queue = m_packetOutboxes[category]; - if (m_deliverPackets == false) + if (forceQueue || m_deliverPackets == false) { queue.Enqueue(packet, highPriority); return true; } - TokenBucket bucket = m_throttleCategories[category]; - - // Don't send this packet if queue is not empty + // need to enqueue if queue is not empty if (queue.Count > 0 || m_nextPackets[category] != null) { queue.Enqueue(packet, highPriority); return true; } - if (!forceQueue && bucket.CheckTokens(packet.Buffer.DataLength)) + // check bandwidth + TokenBucket bucket = m_throttleCategories[category]; + if (bucket.CheckTokens(packet.Buffer.DataLength)) { // enough tokens so it can be sent imediatly by caller bucket.RemoveTokens(packet.Buffer.DataLength); @@ -608,7 +608,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // We don't have a token bucket for this category, so it will not be queued return false; } - } /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index d324623..f12b3b9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -934,6 +934,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Queue or Send } + public void SendUDPPacket( + LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue) + { + bool highPriority = false; + + if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) + { + category = (ThrottleOutPacketType)((int)category & 127); + highPriority = true; + } + + OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); + + // If we were not provided a method for handling unacked, use the UDPServer default method + if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0) + outgoingPacket.UnackedMethod = ((method == null) ? delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); + + if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forcequeue, highPriority)) + SendPacketFinal(outgoingPacket); + } + public void SendAcks(LLUDPClient udpClient) { uint ack; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 6f346d3..49aca3c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -489,7 +489,7 @@ namespace OpenMetaverse public void SyncSend(UDPPacketBuffer buf) { if(buf.RemoteEndPoint == null) - return; // was already expired + return; // already expired try { m_udpSocket.SendTo( -- cgit v1.1 From 9e182c27fbf598aaa418562a031f6ef8678b2710 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 27 Feb 2019 13:18:38 +0000 Subject: combat module: those parcel changes are now handled elsewhere --- .../Avatar/Attachments/AttachmentsModule.cs | 9 ++----- .../CoreModules/Avatar/Combat/CombatModule.cs | 28 ---------------------- 2 files changed, 2 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d36d770..5205576 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -953,13 +953,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } - // Saving attachments for NPCs messes them up for the real owner! - INPCModule module = m_scene.RequestModuleInterface(); - if (module != null) - { - if (module.IsNPC(sp.UUID, m_scene)) - return; - } + if(sp.IsNPC) + return; if (grp.HasGroupChanged) { diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 4e1958a..10bc6aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs @@ -77,7 +77,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule } scene.EventManager.OnAvatarKilled += KillAvatar; - scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; } public void RemoveRegion(Scene scene) @@ -86,7 +85,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule m_scenel.Remove(scene.RegionInfo.RegionHandle); scene.EventManager.OnAvatarKilled -= KillAvatar; - scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; } public void RegionLoaded(Scene scene) @@ -177,31 +175,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule deadAvatar.setHealthWithUpdate(100.0f); deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); } - - private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID) - { - try - { - ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - if (obj == null) - return; - if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 - || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) - { - avatar.Invulnerable = false; - } - else - { - avatar.Invulnerable = true; - if (avatar.Health < 100.0f) - { - avatar.setHealthWithUpdate(100.0f); - } - } - } - catch (Exception) - { - } - } } } -- cgit v1.1 From bd1b992aaf57154fd57403348a1ab63bfd918ad9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 27 Feb 2019 07:49:52 -0800 Subject: Add Thread.ResetAbort() to various thread loops to clean up errors on shutdown. Fixes Mantis #8494. Threads are aborted when shutting down and ThreadAbortException is odd in that it is rethrown at the end of the catch unless the abort is reset. No functional changes but fewer error messages on shutdown. --- .../ClientStack/Linden/Caps/GetAssetsModule.cs | 25 ++++++++++++++-------- .../Linden/Caps/WebFetchInvDescModule.cs | 23 ++++++++++++++------ .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 6 +++++- .../Api/Implementation/AsyncCommandManager.cs | 9 ++++++-- 4 files changed, 44 insertions(+), 19 deletions(-) mode change 100644 => 100755 OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs mode change 100644 => 100755 OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs mode change 100644 => 100755 OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs mode change 100644 => 100755 OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs old mode 100644 new mode 100755 index 9187979..734425b --- a/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs @@ -204,19 +204,26 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoAssetRequests() { - while (m_NumberScenes > 0) + try { - APollRequest poolreq; - if(m_queue.TryTake(out poolreq, 4500)) + while (m_NumberScenes > 0) { - if (m_NumberScenes <= 0) - break; + APollRequest poolreq; + if (m_queue.TryTake(out poolreq, 4500)) + { + if (m_NumberScenes <= 0) + break; + Watchdog.UpdateThread(); + if (poolreq.reqID != UUID.Zero) + poolreq.thepoll.Process(poolreq); + poolreq = null; + } Watchdog.UpdateThread(); - if (poolreq.reqID != UUID.Zero) - poolreq.thepoll.Process(poolreq); - poolreq = null; } - Watchdog.UpdateThread(); + } + catch (ThreadAbortException) + { + Thread.ResetAbort(); } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs old mode 100644 new mode 100755 index 41d70a3..9a01567 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -395,17 +395,26 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoInventoryRequests() { - while (true) + bool running = true; + while (running) { - APollRequest poolreq; - if (m_queue.TryTake(out poolreq, 4500)) + try { + APollRequest poolreq; + if (m_queue.TryTake(out poolreq, 4500)) + { + Watchdog.UpdateThread(); + if (poolreq.thepoll != null) + poolreq.thepoll.Process(poolreq); + poolreq = null; + } Watchdog.UpdateThread(); - if (poolreq.thepoll != null) - poolreq.thepoll.Process(poolreq); - poolreq = null; } - Watchdog.UpdateThread(); + catch (ThreadAbortException) + { + Thread.ResetAbort(); + running = false; + } } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs old mode 100644 new mode 100755 index f12b3b9..653f648 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1910,7 +1910,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP incomingPacket = null; } } - catch(Exception ex) + catch (ThreadAbortException) + { + Thread.ResetAbort(); + } + catch (Exception ex) { m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs old mode 100644 new mode 100755 index 3120d04..a6a2dd8 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs @@ -221,7 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// private static void CmdHandlerThreadLoop() { - while (true) + bool running = true; + while (running) { try { @@ -230,7 +231,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api DoOneCmdHandlerPass(); Watchdog.UpdateThread(); } - catch ( System.Threading.ThreadAbortException) { } + catch ( System.Threading.ThreadAbortException) + { + Thread.ResetAbort(); + running = false; + } catch (Exception e) { m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e); -- cgit v1.1 From 87733b196bdc36a21aee775860c962c1141d44af Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 1 Mar 2019 11:48:00 +0000 Subject: reduce the chance of using a invalid avatar physics actor --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f3e2179..1c5d23d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -507,7 +507,19 @@ namespace OpenSim.Region.Framework.Scenes /// /// Physical scene representation of this Avatar. /// - public PhysicsActor PhysicsActor { get; private set; } + + PhysicsActor m_physActor; + public PhysicsActor PhysicsActor + { + get + { + return m_physActor; + } + private set + { + m_physActor = value; + } + } /// /// Record user movement inputs. @@ -1641,15 +1653,15 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveFromPhysicalScene() { - if (PhysicsActor != null) + PhysicsActor pa = Interlocked.Exchange(ref m_physActor, null); + if (pa != null) { // PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; - PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; - PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; - PhysicsActor.UnSubscribeEvents(); - m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); - PhysicsActor = null; + pa.OnOutOfBounds -= OutOfBoundsCall; + pa.OnCollisionUpdate -= PhysicsCollisionUpdate; + pa.UnSubscribeEvents(); + m_scene.PhysicsScene.RemoveAvatar(pa); } // else // { @@ -2542,7 +2554,7 @@ namespace OpenSim.Region.Framework.Scenes m_pos.X = 127f; m_pos.Y = 127f; m_pos.Z = 127f; - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); + m_log.Error("[AVATAR]: NonFinite Avatar on lastFiniteposition also. Reset Position. Mantis this please. Error #9999903"); } if(isphysical) @@ -5012,16 +5024,17 @@ namespace OpenSim.Region.Framework.Scenes PhysicsScene scene = m_scene.PhysicsScene; Vector3 pVec = AbsolutePosition; - PhysicsActor = scene.AddAvatar( + PhysicsActor pa = scene.AddAvatar( LocalId, Firstname + "." + Lastname, pVec, Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying); - PhysicsActor.Orientation = m_bodyRot; + pa.Orientation = m_bodyRot; //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; - PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; - PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong - PhysicsActor.SubscribeEvents(100); - PhysicsActor.LocalID = LocalId; - PhysicsActor.SetAlwaysRun = m_setAlwaysRun; + pa.OnCollisionUpdate += PhysicsCollisionUpdate; + pa.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong + pa.SubscribeEvents(100); + pa.LocalID = LocalId; + pa.SetAlwaysRun = m_setAlwaysRun; + PhysicsActor = pa; } private void OutOfBoundsCall(Vector3 pos) -- cgit v1.1 From 8a8ce8b10a4f595ebe25d52e439b1f1708c4262c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 1 Mar 2019 11:57:52 +0000 Subject: put back assetViewer cap code, to allow viewers testing. It is disabled at OpenSimDefaults, and should not be enabled until all major viewers do it right on opensim --- OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs index 734425b..c071bd1 100755 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.Linden private string m_GetTextureURL; private string m_GetMeshURL; private string m_GetMesh2URL; -// private string m_GetAssetURL; + private string m_GetAssetURL; class APollRequest { @@ -87,7 +87,7 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDictTexture = new Dictionary(); private Dictionary m_capsDictGetMesh = new Dictionary(); private Dictionary m_capsDictGetMesh2 = new Dictionary(); - //private Dictionary m_capsDictGetAsset = new Dictionary(); + private Dictionary m_capsDictGetAsset = new Dictionary(); #region Region Module interfaceBase Members @@ -113,11 +113,11 @@ namespace OpenSim.Region.ClientStack.Linden m_GetMesh2URL = config.GetString("Cap_GetMesh2", string.Empty); if (m_GetMesh2URL != string.Empty) m_Enabled = true; -/* + m_GetAssetURL = config.GetString("Cap_GetAsset", string.Empty); if (m_GetAssetURL != string.Empty) m_Enabled = true; -*/ + } public void AddRegion(Scene pScene) @@ -448,7 +448,6 @@ namespace OpenSim.Region.ClientStack.Linden else if (m_GetMesh2URL != string.Empty) caps.RegisterHandler("GetMesh2", m_GetMesh2URL); -/* we can't support this cap. Current viewers connect to the wrong regions. //ViewerAsset if (m_GetAssetURL == "localhost") { @@ -466,7 +465,7 @@ namespace OpenSim.Region.ClientStack.Linden } else if (m_GetAssetURL != string.Empty) caps.RegisterHandler("ViewerAsset", m_GetMesh2URL); -*/ + } private void DeregisterCaps(UUID agentID, Caps caps) @@ -487,13 +486,12 @@ namespace OpenSim.Region.ClientStack.Linden MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl); m_capsDictGetMesh2.Remove(agentID); } -/* + if (m_capsDictGetAsset.TryGetValue(agentID, out capUrl)) { MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl); m_capsDictGetAsset.Remove(agentID); } -*/ } } } -- cgit v1.1 From 9da1ca2b44556d8c27fb3db104aa2ace2501e4ea Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 2 Mar 2019 15:38:36 +0000 Subject: ll rez objects: silent ginore null object id; remove redundante llSetColor code --- .../Shared/Api/Implementation/LSL_Api.cs | 41 +--------------------- 1 file changed, 1 insertion(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bb4bab0..95d7a7a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1936,45 +1936,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; - Primitive.TextureEntry tex = part.Shape.Textures; - int nsides = GetNumberOfSides(part); - Color4 texcolor; - - if (face >= 0 && face < nsides) - { - texcolor = tex.CreateFace((uint)face).RGBA; - texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); - texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); - texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); - tex.FaceTextures[face].RGBA = texcolor; - part.UpdateTextureEntry(tex); - return; - } - else if (face == ScriptBaseClass.ALL_SIDES) - { - for (uint i = 0; i < nsides; i++) - { - if (tex.FaceTextures[i] != null) - { - texcolor = tex.FaceTextures[i].RGBA; - texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); - texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); - texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); - tex.FaceTextures[i].RGBA = texcolor; - } - texcolor = tex.DefaultTexture.RGBA; - texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); - texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); - texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); - tex.DefaultTexture.RGBA = texcolor; - } - part.UpdateTextureEntry(tex); - return; - } - - if (face == ScriptBaseClass.ALL_SIDES) - face = SceneObjectPart.ALL_SIDES; - m_host.SetFaceColorAlpha(face, color, null); } @@ -3577,7 +3538,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot) { m_host.AddScriptLPS(1); - if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) + if (string.IsNullOrEmpty(inventory) || Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) return; float dist = (float)llVecDist(llGetPos(), pos); -- cgit v1.1 From ca1993c72d53d5052cea4fef56481c9a54645fca Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 2 Mar 2019 18:23:29 +0000 Subject: direct encode lludp terse object update, let contain texture entry --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 93 +++++++++++++++------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 25 +++--- 2 files changed, 78 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a9edf08..da4c1fb 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4120,10 +4120,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP float cullingrange = 64.0f; Vector3 mypos = Vector3.Zero; - bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; + //bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; + bool orderedDequeue = false; // temporary off HashSet GroupsNeedFullUpdate = new HashSet(); + if (doCulling) { cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; @@ -4304,7 +4306,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity | - PrimUpdateFlags.CollisionPlane + PrimUpdateFlags.CollisionPlane | + PrimUpdateFlags.Textures ); #endregion UpdateFlags to packet type conversion @@ -4347,7 +4350,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP maxUpdatesBytes -= 18; } terseUpdates.Add(update); - maxUpdatesBytes -= 47; // no texture entry + maxUpdatesBytes -= 47; + if ((updateFlags & PrimUpdateFlags.Textures) != 0) + maxUpdatesBytes -= 100; // aprox } } else @@ -4390,7 +4395,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); //setup header and regioninfo block - Array.Copy(terseUpdateHeader, buf.Data, 7); + Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7); Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); Utils.UInt16ToBytes(timeDilation, buf.Data, 15); buf.Data[17] = (byte)curNBlocks; @@ -4399,7 +4404,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP int count = 0; foreach (EntityUpdate eu in terseAgentUpdates) { - CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos); + CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, false); tau.Add(eu); ++count; --blocks; @@ -4407,7 +4412,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // we need more packets UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); - Array.Copy(buf.Data, newbuf.Data, 17); // start is the same + Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, 17); // start is the same buf.DataLength = pos; m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, @@ -4455,49 +4460,57 @@ namespace OpenSim.Region.ClientStack.LindenUDP */ if (terseUpdates != null) { - const int maxNBlocks = (LLUDPServer.MTU - 18) / 47; // no texture entry int blocks = terseUpdates.Count; - int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; - List tau = new List(curNBlocks); + List tau = new List(30); UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); //setup header and regioninfo block - Array.Copy(terseUpdateHeader, buf.Data, 7); + Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7); Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); Utils.UInt16ToBytes(timeDilation, buf.Data, 15); - buf.Data[17] = (byte)curNBlocks; int pos = 18; + int lastpos = 0; int count = 0; foreach (EntityUpdate eu in terseUpdates) { - CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos); - tau.Add(eu); - ++count; - --blocks; - if (count == curNBlocks && blocks > 0) + lastpos = pos; + CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, (eu.Flags & PrimUpdateFlags.Textures) != 0); + if (pos <= LLUDPServer.MTU) + { + tau.Add(eu); + ++count; + --blocks; + } + else if (blocks > 0) { // we need more packets UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); - Array.Copy(buf.Data, newbuf.Data, 17); // start is the same + Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, 17); // start is the same + // copy what we done in excess + int extralen = pos - lastpos; + if(extralen > 0) + Buffer.BlockCopy(newbuf.Data, 18, buf.Data, lastpos, extralen); - buf.DataLength = pos; + pos = 18 + extralen; + + buf.Data[17] = (byte)count; + buf.DataLength = lastpos; m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); - curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; - tau = new List(curNBlocks); - count = 0; - + tau = new List(30); + tau.Add(eu); + count = 1; + --blocks; buf = newbuf; - buf.Data[17] = (byte)curNBlocks; - pos = 18; } } if (count > 0) { + buf.Data[17] = (byte)count; buf.DataLength = pos; m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); @@ -5720,7 +5733,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } - protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos) + protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture) { #region ScenePresence/SOP Handling @@ -5731,6 +5744,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Vector3 position, velocity, acceleration, angularVelocity; Quaternion rotation; byte datasize; + byte[] te = null; if (avatar) { @@ -5775,6 +5789,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP rotation = part.RotationOffset; datasize = 44; + if(includeTexture) + te = part.Shape.TextureEntry; } #endregion ScenePresence/SOP Handling @@ -5785,8 +5801,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP Utils.UIntToBytes(localID, data, pos); pos += 4; - // Avatar/CollisionPlane data[pos++] = (byte)attachPoint; + + // Avatar/CollisionPlane if (avatar) { data[pos++] = 1; @@ -5829,11 +5846,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP Utils.FloatToUInt16Bytes(angularVelocity.X, 64.0f, data, pos); pos += 2; Utils.FloatToUInt16Bytes(angularVelocity.Y, 64.0f, data, pos); pos += 2; Utils.FloatToUInt16Bytes(angularVelocity.Z, 64.0f, data, pos); pos += 2; - + // texture entry block size - data[pos++] = 0; - data[pos++] = 0; - // total size 63 or 47 + if(te == null) + { + data[pos++] = 0; + data[pos++] = 0; + } + else + { + int len = te.Length & 0x7fff; + int totlen = len + 4; + data[pos++] = (byte)totlen; + data[pos++] = (byte)(totlen >> 8); + data[pos++] = (byte)len; // wtf ??? + data[pos++] = (byte)(len >> 8); + data[pos++] = 0; + data[pos++] = 0; + Buffer.BlockCopy(te, 0, data, pos, len); + pos += len; + } + // total size 63 or 47 + (texture size + 4) } protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 23bef74..a1296ba 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3242,8 +3242,6 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup.Scene.GetNumberOfClients() == 0) return; - ParentGroup.QueueForUpdateCheck(); - bool isfull = false; if (ParentGroup.IsAttachment) { @@ -3254,6 +3252,8 @@ namespace OpenSim.Region.Framework.Scenes lock (UpdateFlagLock) UpdateFlag |= update; + ParentGroup.QueueForUpdateCheck(); + ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull); } @@ -5133,8 +5133,7 @@ namespace OpenSim.Region.Framework.Scenes m_shape.TextureEntry = newTex.GetBytes(); TriggerScriptChangedEvent(changeFlags); ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); - + ScheduleUpdate(PrimUpdateFlags.Textures); } /// @@ -5163,7 +5162,7 @@ namespace OpenSim.Region.Framework.Scenes m_shape.TextureEntry = newTex.GetBytes(); TriggerScriptChangedEvent(changeFlags); ParentGroup.HasGroupChanged = true; - ScheduleFullUpdate(); + ScheduleUpdate(PrimUpdateFlags.Textures); } internal void UpdatePhysicsSubscribedEvents() @@ -5575,20 +5574,26 @@ namespace OpenSim.Region.Framework.Scenes // handle osVolumeDetect public void ScriptSetVolumeDetect(bool makeVolumeDetect) { + if(ParentGroup.IsDeleted) + return; + if(_parentID == 0) { - // if root prim do it via SOG + // if root prim do it is like llVolumeDetect ParentGroup.ScriptSetVolumeDetect(makeVolumeDetect); return; } - bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); - bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); - bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); + if(ParentGroup.IsVolumeDetect) + return; // entire linkset is phantom already + + bool wasUsingPhysics = ParentGroup.UsesPhysics; + bool wasTemporary = ParentGroup.IsTemporary; + bool wasPhantom = ParentGroup.IsPhantom; if(PhysActor != null) PhysActor.Building = true; - UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false); + UpdatePrimFlags(wasUsingPhysics, wasTemporary, wasPhantom, makeVolumeDetect, false); } protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL); -- cgit v1.1 From 80056abbe71a5946b6f20d33069e12c952af9eeb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 3 Mar 2019 12:15:28 +0000 Subject: OOOPPPSSS --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index da4c1fb..e039fbf 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4477,7 +4477,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lastpos = pos; CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, (eu.Flags & PrimUpdateFlags.Textures) != 0); - if (pos <= LLUDPServer.MTU) + if (pos < LLUDPServer.MTU) { tau.Add(eu); ++count; @@ -4491,7 +4491,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // copy what we done in excess int extralen = pos - lastpos; if(extralen > 0) - Buffer.BlockCopy(newbuf.Data, 18, buf.Data, lastpos, extralen); + Buffer.BlockCopy(buf.Data, lastpos, newbuf.Data, 18, extralen); pos = 18 + extralen; -- cgit v1.1 From b5ad1b7dcc3592dfa49298636948ea117132e6ff Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Mar 2019 09:22:34 +0000 Subject: remove lludp throttle texture rate cannibal option. That rate is used by http, and beeing http is still trafic --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | 14 -------------- OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs | 9 --------- 2 files changed, 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index d0d2152..2981337 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -210,12 +210,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - /// - /// This is the percentage of the udp texture queue to add to the task queue since - /// textures are now generally handled through http. - /// - private double m_cannibalrate = 0.0; - private ClientInfo m_info = new ClientInfo(); /// @@ -257,8 +251,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Create an array of token buckets for this clients different throttle categories m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; - m_cannibalrate = rates.CannibalizeTextureRate; - m_burst = rates.Total * rates.BrustTime; for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) @@ -449,12 +441,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP asset = Math.Max(asset, LLUDPServer.MTU); */ - // Since most textures are now delivered through http, make it possible - // to cannibalize some of the bw from the texture throttle to use for - // the task queue (e.g. object updates) - task = task + (int)(m_cannibalrate * texture); - texture = (int)((1 - m_cannibalrate) * texture); - int total = resend + land + wind + cloud + task + texture + asset; float m_burst = total * m_burstTime; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs index f8ec97a..3277638 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs @@ -66,9 +66,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public Int64 MinimumAdaptiveThrottleRate; - /// Amount of the texture throttle to steal for the task throttle - public double CannibalizeTextureRate; - public int ClientMaxRate; public float BrustTime; @@ -104,12 +101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false); AdaptiveThrottlesEnabled = false; MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000); - - // http textures do use udp bandwidth setting -// CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f); -// CannibalizeTextureRate = Util.Clamp(CannibalizeTextureRate,0.0, 0.9); - CannibalizeTextureRate = 0f; - } catch (Exception) { } } -- cgit v1.1 From 0944a965172668827a3f1cd83c1f99230299cbb7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Mar 2019 16:01:29 +0000 Subject: llupd direct encode object updates for agents; let terse updates be zeroencoded. This is not as spec but does work --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 251 ++++++++++++--------- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 70 +++++- 2 files changed, 212 insertions(+), 109 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index e039fbf..f8ff3c4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3891,29 +3891,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (ent == null) return; - ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); - objupdate.Header.Zerocoded = true; - - objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); - objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - - if(ent is ScenePresence) + if (ent is ScenePresence) { ScenePresence presence = ent as ScenePresence; - objupdate.RegionData.RegionHandle = presence.RegionHandle; - objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + + //setup header and regioninfo block + Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); + Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); + Utils.UInt16ToBytes(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f), buf.Data, 15); + + buf.Data[17] = 1; + int pos = 18; + CreateAvatarUpdateBlock(presence, buf.Data, ref pos); + + buf.DataLength = pos; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true); } + else if(ent is SceneObjectPart) { + ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); + objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); + objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; + SceneObjectPart part = ent as SceneObjectPart; objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); - } + objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); - OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); + OutPacket(objupdate, ThrottleOutPacketType.Task); + } // We need to record the avatar local id since the root prim of an attachment points to this. -// m_attachmentsSent.Add(avatar.LocalId); + // m_attachmentsSent.Add(avatar.LocalId); } public void SendEntityTerseUpdateImmediate(ISceneEntity ent) @@ -4084,8 +4095,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP ResendPrimUpdate(update); } + static private readonly byte[] objectUpdateHeader = new byte[] { + Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, + 0, 0, 0, 0, // sequence number + 0, // extra + 12 // ID (high frequency) + }; + static private readonly byte[] terseUpdateHeader = new byte[] { - Helpers.MSG_RELIABLE, + Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec 0, 0, 0, 0, // sequence number 0, // extra 15 // ID (high frequency) @@ -4105,7 +4123,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP List objectUpdates = null; // List compressedUpdates = null; List terseUpdates = null; - List terseAgentUpdates = null; List ObjectAnimationUpdates = null; // Check to see if this is a flush @@ -4275,7 +4292,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if(ObjectAnimationUpdates == null) ObjectAnimationUpdates = new List(); ObjectAnimationUpdates.Add(sop); - maxUpdatesBytes -= 32 * sop.Animations.Count + 16; + maxUpdatesBytes -= 20 * sop.Animations.Count + 24; } } } @@ -4329,37 +4346,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP if ((updateFlags & canNotUseImprovedMask) == 0) { + if (terseUpdates == null) + { + terseUpdates = new List(); + maxUpdatesBytes -= 18; + } + terseUpdates.Add(update); if (update.Entity is ScenePresence) - { - // ALL presence updates go into a special list - if (terseAgentUpdates == null) - { - terseAgentUpdates = new List(); - maxUpdatesBytes -= 18; - } - terseAgentUpdates.Add(update); maxUpdatesBytes -= 63; // no texture entry - } else { - // Everything else goes here - if (terseUpdates == null) - { - terseUpdates = new List(); - maxUpdatesBytes -= 18; - } - terseUpdates.Add(update); - maxUpdatesBytes -= 47; - if ((updateFlags & PrimUpdateFlags.Textures) != 0) - maxUpdatesBytes -= 100; // aprox + if ((updateFlags & PrimUpdateFlags.Textures) == 0) + maxUpdatesBytes -= 47; + else + maxUpdatesBytes -= 150; // aprox } } else { ObjectUpdatePacket.ObjectDataBlock ablock; if (update.Entity is ScenePresence) + { ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); + } else ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); if(objectUpdateBlocks == null) @@ -4385,57 +4395,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); - if (terseAgentUpdates != null) - { - const int maxNBlocks = (LLUDPServer.MTU - 18) / 63; // no texture entry - int blocks = terseAgentUpdates.Count; - int curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; - List tau = new List(curNBlocks); - - UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); - - //setup header and regioninfo block - Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7); - Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); - Utils.UInt16ToBytes(timeDilation, buf.Data, 15); - buf.Data[17] = (byte)curNBlocks; - int pos = 18; - - int count = 0; - foreach (EntityUpdate eu in terseAgentUpdates) - { - CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, false); - tau.Add(eu); - ++count; - --blocks; - if (count == curNBlocks && blocks > 0) - { - // we need more packets - UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); - Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, 17); // start is the same - - buf.DataLength = pos; - m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, - delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); - - curNBlocks = blocks > maxNBlocks ? maxNBlocks : blocks; - tau = new List(curNBlocks); - count = 0; - - buf = newbuf; - buf.Data[17] = (byte)curNBlocks; - pos = 18; - } - } - - if (count > 0) - { - buf.DataLength = pos; - m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, - delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); - } - } - if (objectUpdateBlocks != null) { ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); @@ -4497,8 +4456,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP buf.Data[17] = (byte)count; buf.DataLength = lastpos; + // zero encode is not as spec m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, - delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true); tau = new List(30); tau.Add(eu); @@ -4513,7 +4473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP buf.Data[17] = (byte)count; buf.DataLength = pos; m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, - delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false); + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true); } } @@ -4534,13 +4494,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID[] ids = null; int[] seqs = null; int count = sop.GetAnimations(out ids, out seqs); - if(count < 0) - continue; ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation); ani.Sender = new ObjectAnimationPacket.SenderBlock(); ani.Sender.ID = sop.UUID; - ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[sop.Animations.Count]; + ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[count]; for(int i = 0; i< count; i++) { @@ -5732,7 +5690,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return block; } - protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture) { #region ScenePresence/SOP Handling @@ -5871,7 +5828,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) { - Vector3 offsetPosition = data.OffsetPosition; Quaternion rotation = data.Rotation; // tpvs can only see rotations around Z in some cases if(!data.Flying && !data.IsSatOnObject) @@ -5881,27 +5837,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP } rotation.Normalize(); - uint parentID = data.ParentID; - // m_log.DebugFormat( // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); byte[] objectData = new byte[76]; - Vector3 velocity = new Vector3(0, 0, 0); - Vector3 acceleration = new Vector3(0, 0, 0); + //Vector3 velocity = Vector3.Zero; + Vector3 acceleration = Vector3.Zero; + Vector3 angularvelocity = Vector3.Zero; data.CollisionPlane.ToBytes(objectData, 0); - offsetPosition.ToBytes(objectData, 16); - velocity.ToBytes(objectData, 28); + data.OffsetPosition.ToBytes(objectData, 16); + data.Velocity.ToBytes(objectData, 28); acceleration.ToBytes(objectData, 40); rotation.ToBytes(objectData, 52); - data.AngularVelocity.ToBytes(objectData, 64); + angularvelocity.ToBytes(objectData, 64); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.Data = Utils.EmptyBytes; - update.ExtraParams = new byte[1]; + update.ExtraParams = Utils.EmptyBytes; update.FullID = data.UUID; update.ID = data.LocalId; update.Material = (byte)Material.Flesh; @@ -5938,7 +5893,99 @@ namespace OpenSim.Region.ClientStack.LindenUDP return update; } -// protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) + protected void CreateAvatarUpdateBlock(ScenePresence data, byte[] dest, ref int pos) + { + Quaternion rotation = data.Rotation; + // tpvs can only see rotations around Z in some cases + if (!data.Flying && !data.IsSatOnObject) + { + rotation.X = 0f; + rotation.Y = 0f; + } + rotation.Normalize(); + + //Vector3 velocity = Vector3.Zero; + //Vector3 acceleration = Vector3.Zero; + //Vector3 angularvelocity = Vector3.Zero; + + Utils.UIntToBytesSafepos(data.LocalId, dest, pos); pos += 4; + dest[pos++] = 0; // state + data.UUID.ToBytes(dest, pos); pos += 16; + Utils.UIntToBytesSafepos(0 , dest, pos); pos += 4; // crc + dest[pos++] = (byte)PCode.Avatar; + dest[pos++] = (byte)Material.Flesh; + dest[pos++] = 0; // clickaction + data.Appearance.AvatarSize.ToBytes(dest, pos); pos += 12; + + // objectdata block + dest[pos++] = 76; + data.CollisionPlane.ToBytes(dest, pos); pos += 16; + data.OffsetPosition.ToBytes(dest, pos); pos += 12; + data.Velocity.ToBytes(dest, pos); pos += 12; + + //acceleration.ToBytes(dest, pos); pos += 12; + Array.Clear(dest, pos, 12); pos += 12; + + rotation.ToBytes(dest, pos); pos += 12; + + //angularvelocity.ToBytes(dest, pos); pos += 12; + Array.Clear(dest, pos, 12); pos += 12; + + SceneObjectPart parentPart = data.ParentPart; + if (parentPart != null) + { + Utils.UIntToBytesSafepos(parentPart.ParentGroup.LocalId, dest, pos); + pos += 4; + } + else + { +// Utils.UIntToBytesSafepos(0, dest, pos); +// pos += 4; + dest[pos++] = 0; + dest[pos++] = 0; + dest[pos++] = 0; + dest[pos++] = 0; + } + + //Utils.UIntToBytesSafepos(0, dest, pos); pos += 4; //update flags + dest[pos++] = 0; + dest[pos++] = 0; + dest[pos++] = 0; + dest[pos++] = 0; + + //pbs + dest[pos++] = 16; + dest[pos++] = 1; + //Utils.UInt16ToBytes(0, dest, pos); pos += 2; + //Utils.UInt16ToBytes(0, dest, pos); pos += 2; + dest[pos++] = 0; + dest[pos++] = 0; + dest[pos++] = 0; + dest[pos++] = 0; + + dest[pos++] = 100; + dest[pos++] = 100; + + // rest of pbs is 0 (15), texture entry (2) and texture anim (1) + const int pbszeros = 15 + 2 + 1; + Array.Clear(dest, pos, pbszeros); pos += pbszeros; + + //NameValue + byte[] nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + + data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); + int len = nv.Length; + dest[pos++] = (byte)len; + dest[pos++] = (byte)(len >> 8); + Buffer.BlockCopy(nv, 0, dest, pos, len); pos += len; + + // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1), + // sound id(16), sound owner(16) gain (4), flags (1), radius (4) + // jointtype(1) joint pivot(12) joint offset(12) + const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12; + Array.Clear(dest, pos, lastzeros); pos += lastzeros; + } + + // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) { byte[] objectData = new byte[60]; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 653f648..6fd782a 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -274,10 +274,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// The measured resolution of Environment.TickCount public readonly float TickCountResolution; - /// Number of prim updates to put on the queue each time the - /// OnQueueEmpty event is triggered for updates - public readonly int PrimUpdatesPerCallback; - /// Number of texture packets to put on the queue each time the /// OnQueueEmpty event is triggered for textures public readonly int TextureSendLimit; @@ -440,7 +436,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); - PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100); TextureSendLimit = config.GetInt("TextureSendLimit", 20); m_defaultRTO = config.GetInt("DefaultRTO", 0); @@ -451,7 +446,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - PrimUpdatesPerCallback = 100; TextureSendLimit = 20; m_ackTimeout = 1000 * 60; // 1 minute m_pausedAckTimeout = 1000 * 300; // 5 minutes @@ -934,11 +928,73 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Queue or Send } + public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input) + { + UDPPacketBuffer zb = GetNewUDPBuffer(null); + int srclen = input.DataLength; + byte[] src = input.Data; + byte[] dest = zb.Data; + + int zerolen = 6; + byte zerocount = 0; + + for (int i = zerolen; i < srclen; i++) + { + if (src[i] == 0x00) + { + zerocount++; + if (zerocount == 0) + { + dest[zerolen++] = 0x00; + dest[zerolen++] = 0xff; + zerocount++; + } + } + else + { + if (zerocount != 0) + { + dest[zerolen++] = 0x00; + dest[zerolen++] = zerocount; + zerocount = 0; + } + + dest[zerolen++] = src[i]; + } + } + + if (zerocount != 0) + { + dest[zerolen++] = 0x00; + dest[zerolen++] = zerocount; + } + + if(zerolen >= srclen) + { + FreeUDPBuffer(zb); + + src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED); + return input; + } + + Buffer.BlockCopy(src, 0, dest, 0, 6); + + zb.RemoteEndPoint = input.RemoteEndPoint; + zb.DataLength = zerolen; + + FreeUDPBuffer(input); + + return zb; + } + public void SendUDPPacket( - LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue) + LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode) { bool highPriority = false; + if(zerocode) + buffer = ZeroEncode(buffer); + if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) { category = (ThrottleOutPacketType)((int)category & 127); -- cgit v1.1 From 39f73b82d4d0a5a43443c8275c8fe94297c51410 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Mar 2019 17:03:17 +0000 Subject: dont try to backup a object in the middle of possible multipack link --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b526fe9..ea037be 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1913,9 +1913,8 @@ namespace OpenSim.Region.Framework.Scenes { if (parentGroup.OwnerID == child.OwnerID) { - parentGroup.LinkToGroup(child); - child.DetachFromBackup(); + parentGroup.LinkToGroup(child); // this is here so physics gets updated! // Don't remove! Bad juju! Stay away! or fix physics! @@ -1943,7 +1942,6 @@ namespace OpenSim.Region.Framework.Scenes */ parentGroup.AdjustChildPrimPermissions(false); parentGroup.HasGroupChanged = true; - parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true); parentGroup.ScheduleGroupForFullAnimUpdate(); Monitor.Exit(m_linkLock); } -- cgit v1.1 From 87c81b5172e98a31405d924cbdb4b7ef271f3c38 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 6 Mar 2019 10:29:46 -0800 Subject: BulletSim: Add delay to stationary check after adding force to Avatar. Fix to Mantis 8496. Add parameter [BulletSim] AvatarAddForceFrames. --- .../PhysicsModules/BulletS/BSActorAvatarMove.cs | 24 ++++++++++++++-------- .../Region/PhysicsModules/BulletS/BSCharacter.cs | 2 +- OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | 3 +++ 3 files changed, 19 insertions(+), 10 deletions(-) mode change 100644 => 100755 OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs index 40c6b98..4e9216d 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs @@ -47,9 +47,9 @@ public class BSActorAvatarMove : BSActor // The amount the step up is applying. Used to smooth stair walking. float m_lastStepUp; - // There are times the velocity is set but we don't want to inforce stationary until the - // real velocity drops. - bool m_waitingForLowVelocityForStationary = false; + // There are times the velocity or force is set but we don't want to inforce + // stationary until some tick in the future and the real velocity drops. + int m_waitingForLowVelocityForStationary = 0; public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) : base(physicsScene, pObj, actorName) @@ -114,14 +114,18 @@ public class BSActorAvatarMove : BSActor m_velocityMotor.Enabled = true; m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}", m_controllingPrim.LocalID, vel, targ); - m_waitingForLowVelocityForStationary = false; + m_waitingForLowVelocityForStationary = 0; } }); } public void SuppressStationayCheckUntilLowVelocity() { - m_waitingForLowVelocityForStationary = true; + m_waitingForLowVelocityForStationary = 1; + } + public void SuppressStationayCheckUntilLowVelocity(int waitTicks) + { + m_waitingForLowVelocityForStationary = waitTicks; } // If a movement motor has not been created, create one and start the movement @@ -143,7 +147,7 @@ public class BSActorAvatarMove : BSActor m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; m_walkingUpStairs = 0; - m_waitingForLowVelocityForStationary = false; + m_waitingForLowVelocityForStationary = 0; } } @@ -194,15 +198,17 @@ public class BSActorAvatarMove : BSActor // if colliding with something stationary and we're not doing volume detect . if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) { - if (m_waitingForLowVelocityForStationary) + if (m_waitingForLowVelocityForStationary-- <= 0) { // if waiting for velocity to drop and it has finally dropped, we can be stationary + // m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVelocity {1}", + // m_controllingPrim.LocalID, m_waitingForLowVelocityForStationary); if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) { - m_waitingForLowVelocityForStationary = false; + m_waitingForLowVelocityForStationary = 0; } } - if (!m_waitingForLowVelocityForStationary) + if (m_waitingForLowVelocityForStationary <= 0) { m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); m_controllingPrim.IsStationary = true; diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs old mode 100644 new mode 100755 index 2ca7dbc..f971e59 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs @@ -701,7 +701,7 @@ public sealed class BSCharacter : BSPhysObject } if (m_moveActor != null) { - m_moveActor.SuppressStationayCheckUntilLowVelocity(); + m_moveActor.SuppressStationayCheckUntilLowVelocity(BSParam.AvatarAddForceFrames); } }); } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index 495f752..d80b050 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs @@ -149,6 +149,7 @@ public static class BSParam public static float AvatarHeightHighFudge { get; private set; } public static float AvatarFlyingGroundMargin { get; private set; } public static float AvatarFlyingGroundUpForce { get; private set; } + public static int AvatarAddForceFrames { get; private set; } public static float AvatarTerminalVelocity { get; private set; } public static float AvatarContactProcessingThreshold { get; private set; } public static float AvatarAddForcePushFactor { get; private set; } @@ -634,6 +635,8 @@ public static class BSParam 5f ), new ParameterDefn("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin", 2.0f ), + new ParameterDefn("AvatarAddForceFrames", "Frames to allow AddForce to apply before checking for stationary", + 10 ), new ParameterDefn("AvatarTerminalVelocity", "Terminal Velocity of falling avatar", -54.0f ), new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", -- cgit v1.1 From cf0f3954a80c480e34c2e5556e2b0581c4c23f88 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 6 Mar 2019 20:00:39 +0000 Subject: lludp do inline zeroencode of some(most) agent full updates (runprebuild) --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 114 ++++++--- .../ClientStack/Linden/UDP/LLUDPZeroEncoder.cs | 279 +++++++++++++++++++++ 2 files changed, 356 insertions(+), 37 deletions(-) create mode 100644 OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f8ff3c4..dd06e40 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3894,22 +3894,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (ent is ScenePresence) { ScenePresence presence = ent as ScenePresence; - UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); - //setup header and regioninfo block Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); - Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); - Utils.UInt16ToBytes(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f), buf.Data, 15); - - buf.Data[17] = 1; - int pos = 18; - CreateAvatarUpdateBlock(presence, buf.Data, ref pos); - buf.DataLength = pos; - m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true); + LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); + zc.Position = 7; + zc.AddUInt64(m_scene.RegionInfo.RegionHandle); + zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); + zc.AddByte(1); // block count + CreateAvatarUpdateBlock(presence, zc); + buf.DataLength = zc.Finish(); + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, false); } - else if(ent is SceneObjectPart) { ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); @@ -5985,6 +5982,75 @@ namespace OpenSim.Region.ClientStack.LindenUDP Array.Clear(dest, pos, lastzeros); pos += lastzeros; } + protected void CreateAvatarUpdateBlock(ScenePresence data, LLUDPZeroEncoder zc) + { + Quaternion rotation = data.Rotation; + // tpvs can only see rotations around Z in some cases + if (!data.Flying && !data.IsSatOnObject) + { + rotation.X = 0f; + rotation.Y = 0f; + } + rotation.Normalize(); + + zc.AddUInt(data.LocalId); + zc.AddByte(0); + zc.AddUUID(data.UUID); + zc.AddZeros(4); // crc unused + zc.AddByte((byte)PCode.Avatar); + zc.AddByte((byte)Material.Flesh); + zc.AddByte(0); // clickaction + zc.AddVector3(data.Appearance.AvatarSize); + + // objectdata block + zc.AddByte(76); // fixed avatar block size + zc.AddVector4(data.CollisionPlane); + zc.AddVector3(data.OffsetPosition); + zc.AddVector3(data.Velocity); + //zc.AddVector3(acceleration); + zc.AddZeros(12); + zc.AddNormQuat(rotation); + //zc.AddVector3(angularvelocity); + zc.AddZeros(12); + + SceneObjectPart parentPart = data.ParentPart; + if (parentPart != null) + zc.AddUInt(parentPart.ParentGroup.LocalId); + else + zc.AddZeros(4); + + zc.AddZeros(4); //update flags + + //pbs + zc.AddByte(16); + zc.AddByte(1); + //Utils.UInt16ToBytes(0, dest, pos); pos += 2; + //Utils.UInt16ToBytes(0, dest, pos); pos += 2; + zc.AddZeros(4); + + zc.AddByte(100); + zc.AddByte(100); + + // rest of pbs is 0 (15), texture entry (2) and texture anim (1) + const int pbszeros = 15 + 2 + 1; + zc.AddZeros(pbszeros); + + //NameValue + byte[] nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + + data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); + int len = nv.Length; + zc.AddByte((byte)len); + zc.AddByte((byte)(len >> 8)); + zc.AddBytes(nv, len); + + // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1), + // sound id(16), sound owner(16) gain (4), flags (1), radius (4) + // jointtype(1) joint pivot(12) joint offset(12) + const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12; + zc.AddZeros(lastzeros); + } + + // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) { @@ -6008,32 +6074,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP //update.JointPivot = Vector3.Zero; //update.JointType = 0; update.Material = part.Material; -/* - if (data.ParentGroup.IsAttachment) - { - update.NameValue - = Util.StringToBytes256( - string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID)); - - update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); - -// m_log.DebugFormat( -// "[LLCLIENTVIEW]: Sending NameValue {0} for {1} {2} to {3}", -// Util.UTF8.GetString(update.NameValue), data.Name, data.LocalId, Name); -// -// m_log.DebugFormat( -// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}", -// update.State, data.Name, data.LocalId, Name); - } - else - { - update.NameValue = Utils.EmptyBytes; - - // The root part state is the canonical state for all parts of the object. The other part states in the - // case for attachments may contain conflicting values that can end up crashing the viewer. - update.State = data.ParentGroup.RootPart.Shape.State; - } -*/ if (part.ParentGroup.IsAttachment) { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs new file mode 100644 index 0000000..4841ada --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs @@ -0,0 +1,279 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using OpenSim.Framework; +using Nini.Config; +using OpenMetaverse; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public sealed class LLUDPZeroEncoder + { + private byte[] m_tmp = new byte[16]; + private byte[] m_dest; + private int zerocount; + private int pos; + + public LLUDPZeroEncoder() + { + } + + public LLUDPZeroEncoder(byte[] data) + { + m_dest = data; + zerocount = 0; + } + + public byte[] Data + { + get + { + return m_dest; + } + set + { + m_dest = value; + } + } + + public int ZeroCount + { + get + { + return zerocount; + } + set + { + zerocount = value; + } + } + + public int Position + { + get + { + return pos; + } + set + { + pos = value; + } + } + + public unsafe void AddZeros(int len) + { + zerocount += len; + while (zerocount > 255) + { + m_dest[pos++] = 0x00; + m_dest[pos++] = 0xff; + zerocount -= 256; + } + } + + public unsafe int Finish() + { + if(zerocount > 0) + { + m_dest[pos++] = 0x00; + m_dest[pos++] = (byte)zerocount; + } + return pos; + } + + public unsafe void AddBytes(byte[] src, int srclen) + { + for (int i = 0; i < srclen; ++i) + { + if (src[i] == 0x00) + { + zerocount++; + if (zerocount == 0) + { + m_dest[pos++] = 0x00; + m_dest[pos++] = 0xff; + zerocount++; + } + } + else + { + if (zerocount != 0) + { + m_dest[pos++] = 0x00; + m_dest[pos++] = (byte)zerocount; + zerocount = 0; + } + + m_dest[pos++] = src[i]; + } + } + } + + public void AddByte(byte v) + { + if (v == 0x00) + { + zerocount++; + if (zerocount == 0) + { + m_dest[pos++] = 0x00; + m_dest[pos++] = 0xff; + zerocount++; + } + } + else + { + if (zerocount != 0) + { + m_dest[pos++] = 0x00; + m_dest[pos++] = (byte)zerocount; + zerocount = 0; + } + + m_dest[pos++] = v; + } + } + + public void AddInt16(short v) + { + if (v == 0) + AddZeros(2); + else + { + Utils.Int16ToBytes(v, m_tmp, 0); + AddBytes(m_tmp, 2); + } + } + + public void AddUInt16(ushort v) + { + if (v == 0) + AddZeros(2); + else + { + Utils.UInt16ToBytes(v, m_tmp, 0); + AddBytes(m_tmp, 2); + } + } + + public void AddInt(int v) + { + if (v == 0) + AddZeros(4); + else + { + Utils.IntToBytesSafepos(v, m_tmp, 0); + AddBytes(m_tmp, 4); + } + } + + public unsafe void AddUInt(uint v) + { + if (v == 0) + AddZeros(4); + else + { + Utils.UIntToBytesSafepos(v, m_tmp, 0); + AddBytes(m_tmp, 4); + } + } + + public void AddFloatToUInt16(float v, float range) + { + Utils.FloatToUInt16Bytes(v, range, m_tmp, 0); + AddBytes(m_tmp, 2); + } + + public void AddFloat(float v) + { + if (v == 0f) + AddZeros(4); + else + { + Utils.FloatToBytesSafepos(v, m_tmp, 0); + AddBytes(m_tmp, 4); + } + } + + public void AddInt64(long v) + { + if (v == 0) + AddZeros(8); + else + { + Utils.Int64ToBytesSafepos(v, m_tmp, 0); + AddBytes(m_tmp, 8); + } + } + + public void AddUInt64(ulong v) + { + if (v == 0) + AddZeros(8); + else + { + Utils.UInt64ToBytesSafepos(v, m_tmp, 0); + AddBytes(m_tmp, 8); + } + } + + public void AddVector3(Vector3 v) + { + if (v == Vector3.Zero) + AddZeros(12); + else + { + v.ToBytes(m_tmp, 0); + AddBytes(m_tmp, 12); + } + } + + public void AddVector4(Vector4 v) + { + if (v == Vector4.Zero) + AddZeros(16); + else + { + v.ToBytes(m_tmp, 0); + AddBytes(m_tmp, 16); + } + } + + public void AddNormQuat(Quaternion v) + { + v.ToBytes(m_tmp, 0); + AddBytes(m_tmp, 12); + } + + public void AddUUID(UUID v) + { + v.ToBytes(m_tmp, 0); + AddBytes(m_tmp, 16); + } + } +} -- cgit v1.1 From 0970dc04e2ed5482de4be589535d9eda522d3e0c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 6 Mar 2019 22:42:37 +0000 Subject: llupd add direct encode, with inline zeroencode, of objects update ( code path currently not in use) --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 259 ++++++++++++++++++--- .../ClientStack/Linden/UDP/LLUDPZeroEncoder.cs | 2 +- 2 files changed, 227 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index dd06e40..4158adc 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3884,44 +3884,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public void SendEntityFullUpdateImmediate(ISceneEntity ent) { -// m_log.DebugFormat( -// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", -// avatar.Name, avatar.UUID, Name, AgentId); - - if (ent == null) + if (ent == null || (!(ent is ScenePresence) && !(ent is SceneObjectPart))) return; - if (ent is ScenePresence) - { - ScenePresence presence = ent as ScenePresence; - UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); - Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); + LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); + zc.Position = 7; - LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); - zc.Position = 7; - zc.AddUInt64(m_scene.RegionInfo.RegionHandle); - zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); - zc.AddByte(1); // block count - CreateAvatarUpdateBlock(presence, zc); - buf.DataLength = zc.Finish(); - m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, false); - } - else if(ent is SceneObjectPart) - { - ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); - objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); - objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; + zc.AddUInt64(m_scene.RegionInfo.RegionHandle); + zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); - SceneObjectPart part = ent as SceneObjectPart; - objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); + zc.AddByte(1); // block count - OutPacket(objupdate, ThrottleOutPacketType.Task); - } + if (ent is ScenePresence) + CreateAvatarUpdateBlock(ent as ScenePresence, zc); + else + CreatePrimUpdateBlock(ent as SceneObjectPart, (ScenePresence)SceneAgent, zc); - // We need to record the avatar local id since the root prim of an attachment points to this. - // m_attachmentsSent.Add(avatar.LocalId); + buf.DataLength = zc.Finish(); + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, false); } public void SendEntityTerseUpdateImmediate(ISceneEntity ent) @@ -6050,8 +6033,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddZeros(lastzeros); } - - // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) { byte[] objectData = new byte[60]; @@ -6193,6 +6174,218 @@ namespace OpenSim.Region.ClientStack.LindenUDP return update; } + protected void CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp, LLUDPZeroEncoder zc) + { + // prepare data + + //NameValue and state + byte[] nv = null; + byte state; + if (part.ParentGroup.IsAttachment) + { + if (part.IsRoot) + nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); + + int st = (int)part.ParentGroup.AttachmentPoint; + state = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; + } + else + state = part.Shape.State; // not sure about this + + #region PrimFlags + // prim/update flags + PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp); + // Don't send the CreateSelected flag to everyone + primflags &= ~PrimFlags.CreateSelected; + if (sp.UUID == part.OwnerID) + { + if (part.CreateSelected) + { + // Only send this flag once, then unset it + primflags |= PrimFlags.CreateSelected; + part.CreateSelected = false; + } + } + #endregion PrimFlags + + // filter out mesh faces hack + ushort profileBegin = part.Shape.ProfileBegin; + ushort profileHollow = part.Shape.ProfileHollow; + byte profileCurve = part.Shape.ProfileCurve; + byte pathScaleY = part.Shape.PathScaleY; + + if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack + { + profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f); + // fix old values that confused viewers + if (profileBegin == 1) + profileBegin = 9375; + if (profileHollow == 1) + profileHollow = 27500; + // fix torus hole size Y that also confuse some viewers + if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150) + pathScaleY = 150; + } + + // data block + byte[] data = null; + switch ((PCode)part.Shape.PCode) + { + case PCode.Grass: + case PCode.Tree: + case PCode.NewTree: + data = new byte[] { part.Shape.State }; + break; + default: + break; + } + + // do encode the things + zc.AddUInt(part.LocalId); + zc.AddByte(state); // state + zc.AddUUID(part.UUID); + zc.AddZeros(4); // crc unused + zc.AddByte(part.Shape.PCode); + zc.AddByte(part.Material); + zc.AddByte(part.ClickAction); // clickaction + zc.AddVector3(part.Shape.Scale); + + // objectdata block + zc.AddByte(60); // fixed object block size + zc.AddVector3(part.RelativePosition); + zc.AddVector3(part.Velocity); + zc.AddVector3(part.Acceleration); + Quaternion rotation = part.RotationOffset; + rotation.Normalize(); + zc.AddNormQuat(rotation); + zc.AddVector3(part.AngularVelocity); + + zc.AddUInt(part.ParentID); + zc.AddUInt((uint)primflags); //update flags + + //pbs + zc.AddByte(part.Shape.PathCurve); + zc.AddByte(profileCurve); + zc.AddUInt16(part.Shape.PathBegin); + zc.AddUInt16(part.Shape.PathEnd); + zc.AddByte(part.Shape.PathScaleX); + zc.AddByte(pathScaleY); + zc.AddByte(part.Shape.PathShearX); + zc.AddByte(part.Shape.PathShearY); + zc.AddByte((byte)part.Shape.PathTwist); + zc.AddByte((byte)part.Shape.PathTwistBegin); + zc.AddByte((byte)part.Shape.PathRadiusOffset); + zc.AddByte((byte)part.Shape.PathTaperX); + zc.AddByte((byte)part.Shape.PathTaperY); + zc.AddByte(part.Shape.PathRevolutions); + zc.AddByte((byte)part.Shape.PathSkew); + zc.AddUInt16(profileBegin); + zc.AddUInt16(part.Shape.ProfileEnd); + zc.AddUInt16(profileHollow); + + // texture + byte[] tentry = part.Shape.TextureEntry; + if (tentry == null) + zc.AddZeros(2); + else + { + int len = tentry.Length; + zc.AddUInt((ushort)len); + zc.AddBytes(tentry, len); + } + + // texture animation + byte[] tanim = part.TextureAnimation; + if (tanim == null) + zc.AddZeros(1); + else + { + int len = tanim.Length; + zc.AddByte((byte)len); + zc.AddBytes(tanim, len); + } + + //NameValue + if(nv == null) + zc.AddZeros(2); + else + { + int len = nv.Length; + zc.AddByte((byte)len); + zc.AddByte((byte)(len >> 8)); + zc.AddBytes(nv, len); + } + + // data + if (data == null) + zc.AddZeros(2); + else + { + int len = data.Length; + zc.AddByte((byte)len); + zc.AddByte((byte)(len >> 8)); + zc.AddBytes(data, len); + } + + //text + if (part.Text.Length == 0) + zc.AddZeros(1); + else + { + byte[] tbuf = Util.StringToBytes(part.Text, 255); + int len = tbuf.Length; + zc.AddByte((byte)len); + zc.AddBytes(tbuf, len); + } + + //textcolor + byte[] tc = part.GetTextColor().GetBytes(false); + zc.AddBytes(tc, 4); + + //media url + if (part.MediaUrl.Length == 0) + zc.AddZeros(1); + else + { + byte[] tbuf = Util.StringToBytes(part.MediaUrl, 255); + int len = tbuf.Length; + zc.AddByte((byte)len); + zc.AddBytes(tbuf, len); + } + + //particle system + byte[] ps = part.ParticleSystem; + if (ps == null) + zc.AddZeros(1); + else + { + int len = ps.Length; + zc.AddByte((byte)len); + zc.AddBytes(ps, len); + } + + //Extraparams + byte[] ep = part.Shape.ExtraParams; + if (ep == null) + zc.AddZeros(1); + else + { + int len = ep.Length; + zc.AddByte((byte)len); + zc.AddBytes(ep, len); + } + + zc.AddUUID(part.Sound); + zc.AddUUID(part.OwnerID); + zc.AddFloat((float)part.SoundGain); + zc.AddByte(part.SoundFlags); + zc.AddFloat((float)part.SoundRadius); + + // jointtype(1) joint pivot(12) joint offset(12) + const int lastzeros = 1 + 12 + 12; + zc.AddZeros(lastzeros); + } + protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) { // TODO: Implement this diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs index 4841ada..8ed2cf1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs @@ -134,7 +134,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public void AddByte(byte v) + public unsafe void AddByte(byte v) { if (v == 0x00) { -- cgit v1.1 From fdb1ce827bc2058b294fadd4cd76f43fd23e8bd7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 6 Mar 2019 22:48:00 +0000 Subject: fix packet type --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4158adc..c049cc8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3898,13 +3898,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddByte(1); // block count + ThrottleOutPacketType ptype = ThrottleOutPacketType.Task; if (ent is ScenePresence) + { CreateAvatarUpdateBlock(ent as ScenePresence, zc); + ptype |= ThrottleOutPacketType.HighPriority; + } else CreatePrimUpdateBlock(ent as SceneObjectPart, (ScenePresence)SceneAgent, zc); buf.DataLength = zc.Finish(); - m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, false); + m_udpServer.SendUDPPacket(m_udpClient, buf, ptype , null, false, false); } public void SendEntityTerseUpdateImmediate(ISceneEntity ent) -- cgit v1.1 From 9487f5cdd37c3d1eae5f183d0952426a4a7eade9 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Mar 2019 04:50:05 +0000 Subject: don't send irrelevant data --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 61 +++++++++++++--------- 1 file changed, 36 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c049cc8..691b7bb 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6008,18 +6008,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddZeros(4); //update flags - //pbs - zc.AddByte(16); - zc.AddByte(1); - //Utils.UInt16ToBytes(0, dest, pos); pos += 2; - //Utils.UInt16ToBytes(0, dest, pos); pos += 2; - zc.AddZeros(4); - - zc.AddByte(100); - zc.AddByte(100); - - // rest of pbs is 0 (15), texture entry (2) and texture anim (1) - const int pbszeros = 15 + 2 + 1; + //pbs volume data 23 + //texture entry 2 + //texture anim (1) + const int pbszeros = 23 + 2 + 1; zc.AddZeros(pbszeros); //NameValue @@ -6154,15 +6146,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion PrimFlags - if (part.Sound != UUID.Zero || part.SoundFlags != 0) + bool hassound = part.Sound != UUID.Zero || part.SoundFlags != 0; + if (hassound) { update.Sound = part.Sound; - update.OwnerID = part.OwnerID; update.Gain = (float)part.SoundGain; update.Radius = (float)part.SoundRadius; update.Flags = part.SoundFlags; } + if(hassound || update.PSBlock.Length > 1) + update.OwnerID = part.OwnerID; + switch ((PCode)part.Shape.PCode) { case PCode.Grass: @@ -6333,18 +6328,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP //text if (part.Text.Length == 0) - zc.AddZeros(1); + zc.AddZeros(5); else { - byte[] tbuf = Util.StringToBytes(part.Text, 255); + byte[] tbuf = Util.StringToBytes(part.Text, 254); int len = tbuf.Length; zc.AddByte((byte)len); zc.AddBytes(tbuf, len); - } - //textcolor - byte[] tc = part.GetTextColor().GetBytes(false); - zc.AddBytes(tc, 4); + //textcolor + byte[] tc = part.GetTextColor().GetBytes(false); + zc.AddBytes(tc, 4); + } //media url if (part.MediaUrl.Length == 0) @@ -6357,6 +6352,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddBytes(tbuf, len); } + bool hasps = false; //particle system byte[] ps = part.ParticleSystem; if (ps == null) @@ -6366,6 +6362,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP int len = ps.Length; zc.AddByte((byte)len); zc.AddBytes(ps, len); + hasps = len > 1; } //Extraparams @@ -6379,11 +6376,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddBytes(ep, len); } - zc.AddUUID(part.Sound); - zc.AddUUID(part.OwnerID); - zc.AddFloat((float)part.SoundGain); - zc.AddByte(part.SoundFlags); - zc.AddFloat((float)part.SoundRadius); + bool hassound = part.Sound != UUID.Zero || part.SoundFlags != 0; + if (hassound) + zc.AddUUID(part.Sound); + else + zc.AddZeros(16); + + if (hassound || hasps) + zc.AddUUID(part.OwnerID); + else + zc.AddZeros(16); + + if (hassound) + { + zc.AddFloat((float)part.SoundGain); + zc.AddByte(part.SoundFlags); + zc.AddFloat((float)part.SoundRadius); + } + else + zc.AddZeros(9); // jointtype(1) joint pivot(12) joint offset(12) const int lastzeros = 1 + 12 + 12; -- cgit v1.1 From fbd741ece37b688d7ec2860f4e4f35767213e09f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Mar 2019 12:12:11 +0000 Subject: prims have at most 9 face textures --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs | 4 ++-- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a1296ba..312ce26 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5130,7 +5130,7 @@ namespace OpenSim.Region.Framework.Scenes if (changeFlags == 0) return; - m_shape.TextureEntry = newTex.GetBytes(); + m_shape.TextureEntry = newTex.GetBytes(9); TriggerScriptChangedEvent(changeFlags); ParentGroup.HasGroupChanged = true; ScheduleUpdate(PrimUpdateFlags.Textures); @@ -5159,7 +5159,7 @@ namespace OpenSim.Region.Framework.Scenes if (changeFlags == 0) return; - m_shape.TextureEntry = newTex.GetBytes(); + m_shape.TextureEntry = newTex.GetBytes(9); TriggerScriptChangedEvent(changeFlags); ParentGroup.HasGroupChanged = true; ScheduleUpdate(PrimUpdateFlags.Textures); diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs index 516f9eb..822439f 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs @@ -323,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Materials } if(facechanged) - part.Shape.TextureEntry = te.GetBytes(); + part.Shape.TextureEntry = te.GetBytes(9); if(facechanged || partchanged) { @@ -632,7 +632,7 @@ namespace OpenSim.Region.OptionalModules.Materials faceEntry.MaterialID = id; //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually - sop.Shape.TextureEntry = te.GetBytes(); + sop.Shape.TextureEntry = te.GetBytes(9); } if(oldid != UUID.Zero) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 95d7a7a..ab3562f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10614,7 +10614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return false; texface.MaterialID = id; - part.Shape.TextureEntry = tex.GetBytes(); + part.Shape.TextureEntry = tex.GetBytes(9); m_materialsModule.RemoveMaterial(oldid); return true; } @@ -10671,7 +10671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return false; texface.MaterialID = id; - part.Shape.TextureEntry = tex.GetBytes(); + part.Shape.TextureEntry = tex.GetBytes(9); m_materialsModule.RemoveMaterial(oldid); return true; } @@ -10738,7 +10738,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return false; texface.MaterialID = id; - part.Shape.TextureEntry = tex.GetBytes(); + part.Shape.TextureEntry = tex.GetBytes(9); m_materialsModule.RemoveMaterial(oldid); return true; } -- cgit v1.1 From 9ccc3ed756fae1626d7d9fe374f131424c52cb21 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Mar 2019 14:53:32 +0000 Subject: make use of direct object update encoding --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 111 ++++++++++++++++----- 1 file changed, 88 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 691b7bb..171f8c6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4102,7 +4102,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (mysp == null) return; - List objectUpdateBlocks = null; // List compressedUpdateBlocks = null; List objectUpdates = null; // List compressedUpdates = null; @@ -4349,22 +4348,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - ObjectUpdatePacket.ObjectDataBlock ablock; if (update.Entity is ScenePresence) - { - ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); - } + maxUpdatesBytes -= 150; // crude estimation else - ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); - if(objectUpdateBlocks == null) + maxUpdatesBytes -= 300; + + if(objectUpdates == null) { - objectUpdateBlocks = new List(); objectUpdates = new List(); maxUpdatesBytes -= 18; } - objectUpdateBlocks.Add(ablock); objectUpdates.Add(update); - maxUpdatesBytes -= ablock.Length; } #endregion Block Construction @@ -4379,16 +4373,86 @@ namespace OpenSim.Region.ClientStack.LindenUDP timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); - if (objectUpdateBlocks != null) + if(objectUpdates != null) { - ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); - packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; - packet.RegionData.TimeDilation = timeDilation; - packet.ObjectData = objectUpdateBlocks.ToArray(); - objectUpdateBlocks.Clear(); + int blocks = objectUpdates.Count; + List tau = new List(30); + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); + + LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); + zc.Position = 7; + + zc.AddUInt64(m_scene.RegionInfo.RegionHandle); + zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); + + zc.AddByte(1); // tmp block count + + int countposition = zc.Position - 1; + + int lastpos = 0; + int lastzc = 0; + + int count = 0; + foreach (EntityUpdate eu in objectUpdates) + { + lastpos = zc.Position; + lastzc = zc.ZeroCount; + if (eu.Entity is ScenePresence) + CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc); + else + CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc); + if (zc.Position < LLUDPServer.MTU - 5) + { + tau.Add(eu); + ++count; + --blocks; + } + else if (blocks > 0) + { + // we need more packets + UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same + + buf.Data[countposition] = (byte)count; + // get pending zeros at cut point + if(lastzc > 0) + { + buf.Data[lastpos++] = 0; + buf.Data[lastpos++] = (byte)lastzc; + } + buf.DataLength = lastpos; + + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); + + buf = newbuf; + zc.Data = buf.Data; + zc.ZeroCount = 0; + zc.Position = countposition + 1; + // im lazy now, just do last again + if (eu.Entity is ScenePresence) + CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc); + else + CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc); + + tau = new List(30); + tau.Add(eu); + count = 1; + --blocks; + } + } - OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates, oPacket); }); + if (count > 0) + { + buf.Data[countposition] = (byte)count; + buf.DataLength = zc.Finish(); + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, + delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); + } } + /* if (compressedUpdateBlocks != null) { @@ -6289,7 +6353,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { int len = tentry.Length; - zc.AddUInt((ushort)len); + zc.AddByte((byte)len); + zc.AddByte((byte)(len >> 8)); zc.AddBytes(tentry, len); } @@ -6327,7 +6392,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } //text - if (part.Text.Length == 0) + if (part.Text == null || part.Text.Length == 0) zc.AddZeros(5); else { @@ -6342,7 +6407,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } //media url - if (part.MediaUrl.Length == 0) + if (part.MediaUrl == null || part.MediaUrl.Length == 0) zc.AddZeros(1); else { @@ -6355,19 +6420,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP bool hasps = false; //particle system byte[] ps = part.ParticleSystem; - if (ps == null) + if (ps == null || ps.Length < 1) zc.AddZeros(1); else { int len = ps.Length; zc.AddByte((byte)len); zc.AddBytes(ps, len); - hasps = len > 1; + hasps = true; } //Extraparams byte[] ep = part.Shape.ExtraParams; - if (ep == null) + if (ep == null || ep.Length < 2) zc.AddZeros(1); else { -- cgit v1.1 From 4e7cddc6a8a764a76b270dbb7aeb3a16e2bff56c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Mar 2019 17:11:52 +0000 Subject: vegetation is special --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 99 ++++++++++++++++------ 1 file changed, 71 insertions(+), 28 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 171f8c6..f984009 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6241,20 +6241,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // prepare data - //NameValue and state - byte[] nv = null; - byte state; - if (part.ParentGroup.IsAttachment) - { - if (part.IsRoot) - nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); - - int st = (int)part.ParentGroup.AttachmentPoint; - state = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; - } - else - state = part.Shape.State; // not sure about this - #region PrimFlags // prim/update flags PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp); @@ -6271,6 +6257,76 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion PrimFlags + // data block + byte[] data = null; + byte state = part.Shape.State; + PCode pcode = (PCode)part.Shape.PCode; + + //vegetation is special so just do it inline + if(pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree) + { + zc.AddUInt(part.LocalId); + zc.AddByte(state); // state + zc.AddUUID(part.UUID); + zc.AddZeros(4); // crc unused + zc.AddByte((byte)pcode); + // material 1 + // clickaction 1 + zc.AddZeros(2); + zc.AddVector3(part.Shape.Scale); + + // objectdata block + zc.AddByte(60); // fixed object block size + zc.AddVector3(part.RelativePosition); + zc.AddZeros(24); + Quaternion rot = part.RotationOffset; + rot.Normalize(); + zc.AddNormQuat(rot); + zc.AddZeros(12); + + zc.AddUInt(part.ParentID); + zc.AddUInt((uint)primflags); //update flags + + //pbs volume data 23 + //texture entry 2 + //texture anim 1 + //name value 2 + zc.AddZeros(23 + 2 + 1 + 2); + + //data + zc.AddByte(1); + zc.AddZeros(1); + zc.AddByte(state); + + // text 5 + // media url 1 + // particle system 1 + // Extraparams 1 + // sound id 16 + // ownwer 16 + // sound gain 4 + // sound flags 1 + // sound radius 4 + // jointtype 1 + // joint pivot 12 + // joint offset 12 + zc.AddZeros(5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12); + + return; + } + + //NameValue and state + byte[] nv = null; + + if (part.ParentGroup.IsAttachment) + { + if (part.IsRoot) + nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); + + int st = (int)part.ParentGroup.AttachmentPoint; + state = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; + } + // filter out mesh faces hack ushort profileBegin = part.Shape.ProfileBegin; ushort profileHollow = part.Shape.ProfileHollow; @@ -6290,25 +6346,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP pathScaleY = 150; } - // data block - byte[] data = null; - switch ((PCode)part.Shape.PCode) - { - case PCode.Grass: - case PCode.Tree: - case PCode.NewTree: - data = new byte[] { part.Shape.State }; - break; - default: - break; - } - // do encode the things zc.AddUInt(part.LocalId); zc.AddByte(state); // state zc.AddUUID(part.UUID); zc.AddZeros(4); // crc unused - zc.AddByte(part.Shape.PCode); + zc.AddByte((byte)pcode); zc.AddByte(part.Material); zc.AddByte(part.ClickAction); // clickaction zc.AddVector3(part.Shape.Scale); -- cgit v1.1 From 95c4de614427ca9d6b376408b0b56b6167bb41ce Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Mar 2019 18:20:17 +0000 Subject: grass even more --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 45 ++++++++++++++++++---- 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f984009..4d62bbe 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6266,7 +6266,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP if(pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree) { zc.AddUInt(part.LocalId); - zc.AddByte(state); // state + if(pcode == PCode.Grass) + zc.AddByte(state); // state + else + zc.AddZeros(1); zc.AddUUID(part.UUID); zc.AddZeros(4); // crc unused zc.AddByte((byte)pcode); @@ -6278,22 +6281,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP // objectdata block zc.AddByte(60); // fixed object block size zc.AddVector3(part.RelativePosition); - zc.AddZeros(24); - Quaternion rot = part.RotationOffset; - rot.Normalize(); - zc.AddNormQuat(rot); - zc.AddZeros(12); + if (pcode == PCode.Grass) + zc.AddZeros(48); + else + { + zc.AddZeros(24); + Quaternion rot = part.RotationOffset; + rot.Normalize(); + zc.AddNormQuat(rot); + zc.AddZeros(12); + } zc.AddUInt(part.ParentID); zc.AddUInt((uint)primflags); //update flags + if (pcode == PCode.Grass) + { + //pbs volume data 23 + //texture entry 2 + //texture anim 1 + //name value 2 + // data 1 + // text 5 + // media url 1 + // particle system 1 + // Extraparams 1 + // sound id 16 + // ownwer 16 + // sound gain 4 + // sound flags 1 + // sound radius 4 + // jointtype 1 + // joint pivot 12 + // joint offset 12 + zc.AddZeros(23 + 2 + 1 + 2 + 1 + 5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12); + return; + } + //pbs volume data 23 //texture entry 2 //texture anim 1 //name value 2 zc.AddZeros(23 + 2 + 1 + 2); - //data + //data: the tree type zc.AddByte(1); zc.AddZeros(1); zc.AddByte(state); -- cgit v1.1 From 155e4994573a1ad12ce75e8363e0e92c675bc0b6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Mar 2019 18:57:13 +0000 Subject: well let trees have special state and grass data block again. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4d62bbe..fb876de 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6266,10 +6266,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if(pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree) { zc.AddUInt(part.LocalId); - if(pcode == PCode.Grass) - zc.AddByte(state); // state - else - zc.AddZeros(1); + zc.AddByte(state); // state zc.AddUUID(part.UUID); zc.AddZeros(4); // crc unused zc.AddByte((byte)pcode); @@ -6295,6 +6292,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddUInt(part.ParentID); zc.AddUInt((uint)primflags); //update flags + /* if (pcode == PCode.Grass) { //pbs volume data 23 @@ -6317,6 +6315,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP zc.AddZeros(23 + 2 + 1 + 2 + 1 + 5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12); return; } + */ //pbs volume data 23 //texture entry 2 -- cgit v1.1 From a32060180fd6e24c7188b24769e294146133d9a0 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 8 Mar 2019 19:14:09 +0000 Subject: agent animation object ids are only for self avatar --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 50 +++++++++++++++++----- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index fb876de..6ec87ab 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3833,24 +3833,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation); // TODO: don't create new blocks if recycling an old packet - ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[animations.Length]; ani.Sender = new AvatarAnimationPacket.SenderBlock(); ani.Sender.ID = sourceAgentId; ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[animations.Length]; ani.PhysicalAvatarEventList = new AvatarAnimationPacket.PhysicalAvatarEventListBlock[0]; - for (int i = 0; i < animations.Length; ++i) + //self animations + if (sourceAgentId == AgentId) { - ani.AnimationList[i] = new AvatarAnimationPacket.AnimationListBlock(); - ani.AnimationList[i].AnimID = animations[i]; - ani.AnimationList[i].AnimSequenceID = seqs[i]; + List withobjects = new List(animations.Length); + List noobjects = new List(animations.Length); + for(int i = 0; i < animations.Length; ++i) + { + if(objectIDs[i] == sourceAgentId || objectIDs[i] == UUID.Zero) + noobjects.Add(i); + else + withobjects.Add(i); + } - ani.AnimationSourceList[i] = new AvatarAnimationPacket.AnimationSourceListBlock(); - if (objectIDs[i].Equals(sourceAgentId)) - ani.AnimationSourceList[i].ObjectID = UUID.Zero; - else - ani.AnimationSourceList[i].ObjectID = objectIDs[i]; + ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[withobjects.Count]; + int k = 0; + foreach (int i in withobjects) + { + ani.AnimationList[k] = new AvatarAnimationPacket.AnimationListBlock(); + ani.AnimationList[k].AnimID = animations[i]; + ani.AnimationList[k].AnimSequenceID = seqs[i]; + ani.AnimationSourceList[k] = new AvatarAnimationPacket.AnimationSourceListBlock(); + ani.AnimationSourceList[k].ObjectID = objectIDs[i]; + k++; + } + foreach (int i in noobjects) + { + ani.AnimationList[k] = new AvatarAnimationPacket.AnimationListBlock(); + ani.AnimationList[k].AnimID = animations[i]; + ani.AnimationList[k].AnimSequenceID = seqs[i]; + k++; + } + } + else + { + ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[0]; + for (int i = 0; i < animations.Length; ++i) + { + ani.AnimationList[i] = new AvatarAnimationPacket.AnimationListBlock(); + ani.AnimationList[i].AnimID = animations[i]; + ani.AnimationList[i].AnimSequenceID = seqs[i]; + } } + OutPacket(ani, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); } -- cgit v1.1 From e9d7ced733e99904de315d71d7b851e8ff7a3a67 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 8 Mar 2019 21:14:08 +0000 Subject: just direct encode avatar animation also --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 74 ++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6ec87ab..5d42ecd 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3827,6 +3827,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(avp, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); } +/* public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) { // m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name); @@ -3883,6 +3884,79 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(ani, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); } +*/ + + static private readonly byte[] AvatarAnimationHeader = new byte[] { + Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec + 0, 0, 0, 0, // sequence number + 0, // extra + 20 // ID (high frequency) + }; + + public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) + { + // m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name); + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + byte[] data = buf.Data; + //setup header + Buffer.BlockCopy(AvatarAnimationHeader, 0, data, 0, 7); + //agent block + sourceAgentId.ToBytes(data, 7); + + // animations count + data[23] = (byte)animations.Length; + + int pos = 24; + + //self animations + if (sourceAgentId == AgentId) + { + List withobjects = new List(animations.Length); + List noobjects = new List(animations.Length); + for (int i = 0; i < animations.Length; ++i) + { + if (objectIDs[i] == sourceAgentId || objectIDs[i] == UUID.Zero) + noobjects.Add(i); + else + withobjects.Add(i); + } + + // first the ones with corresponding objects + foreach (int i in withobjects) + { + animations[i].ToBytes(data, pos); pos += 16; + Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4; + } + // then the rest + foreach (int i in noobjects) + { + animations[i].ToBytes(data, pos); pos += 16; + Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4; + } + // object ids block + data[pos++] = (byte)withobjects.Count; + foreach (int i in withobjects) + { + objectIDs[i].ToBytes(data, pos); pos += 16; + } + } + else + { + for(int i = 0; i < animations.Length; ++i) + { + animations[i].ToBytes(data, pos); pos += 16; + Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4; + } + data[pos++] = 0; // no object ids + } + + data[pos++] = 0; // no physical avatar events + + buf.DataLength = pos; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, + null, false, false); + } public void SendObjectAnimations(UUID[] animations, int[] seqs, UUID senderId) { -- cgit v1.1 From 6bc37f348e70909bfa91319aefa76e76ffd7b398 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 8 Mar 2019 22:28:57 +0000 Subject: ooops bad zeroencode flag --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5d42ecd..5353194 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3887,7 +3887,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP */ static private readonly byte[] AvatarAnimationHeader = new byte[] { - Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec + Helpers.MSG_RELIABLE, 0, 0, 0, 0, // sequence number 0, // extra 20 // ID (high frequency) -- cgit v1.1 From 343239c7c395bf81cd07057bd89a846d81d263a7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 9 Mar 2019 12:04:26 +0000 Subject: do not send animated attachments to viewers that do not support them. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5353194..ecae8c8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4285,7 +4285,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP } if (grp.IsAttachment) - { // Someone else's HUD, why are we getting these? + { + // animated attachments are nasty if not supported by viewer + if(!m_SupportObjectAnimations && grp.RootPart.Shape.MeshFlagEntry) + continue; + + // Someone else's HUD, why are we getting these? if (grp.OwnerID != AgentId && grp.HasPrivateAttachmentPoint) continue; -- cgit v1.1 From 7b55d42b11d899456d8e5a153fb097e8691b92e8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 10 Mar 2019 11:23:38 +0000 Subject: lludp fix max packet size on ack appends --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 6fd782a..2300800 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -256,6 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Maximum transmission unit, or UDP packet size, for the LLUDP protocol public const int MTU = 1400; + public const int MAXPAYLOAD = 1250; /// Number of forced client logouts due to no receipt of packets before timeout. public int ClientLogoutsDueToNoReceives { get; protected set; } @@ -1150,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // no more ACKs to append int ackCount = 0; uint ack; - while (dataLength + 5 < buffer.Data.Length && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack)) + while (dataLength + 5 < MTU && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack)) { Utils.UIntToBytesBig(ack, buffer.Data, dataLength); dataLength += 4; -- cgit v1.1 From 32a03a49fc06edb65cb016b8c69f88e3c595be1d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 10 Mar 2019 15:56:14 +0000 Subject: lludp: direct encode terrain patchs packets --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 86 ++++++++++++++++++++-- .../Region/Framework/Scenes/TerrainCompressor.cs | 2 + 2 files changed, 83 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ecae8c8..ac041f5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1257,6 +1257,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendLayerTopRight(x1 + 1, y1, x2, y2 - 1); } + static private readonly byte[] TerrainPacketHeader = new byte[] { + Helpers.MSG_RELIABLE, // zero code is not as spec + 0, 0, 0, 0, // sequence number + 0, // extra + 11, // ID (high frequency) + }; + + private const int END_OF_PATCHES = 97; + private const int STRIDE = 264; + public void SendLayerData(int[] map) { if(map == null) @@ -1264,9 +1274,75 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - List packets = OpenSimTerrainCompressor.CreateLayerDataPackets(m_scene.Heightmap.GetTerrainData(), map); - foreach (LayerDataPacket pkt in packets) - OutPacket(pkt, ThrottleOutPacketType.Land); + TerrainData terrData = m_scene.Heightmap.GetTerrainData(); + byte landPacketType = (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) ? + (byte)TerrainPatch.LayerType.LandExtended : (byte)TerrainPatch.LayerType.Land; + + int numberPatchs = map.Length / 2; + + UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + byte[] data = buf.Data; + + Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7); + + data[7] = landPacketType; + //data[8] and data[9] == datablock size to fill later + + data[10] = 0; // BitPack needs this on reused packets + + // start data + BitPack bitpack = new BitPack(data, 10); + bitpack.PackBits(STRIDE, 16); + bitpack.PackBitsFromByte(16); + bitpack.PackBitsFromByte(landPacketType); + + int s; + int datasize = 0; + for (int i = 0; i < numberPatchs; i++) + { + s = 2 * i; + OpenSimTerrainCompressor.CreatePatchFromTerrainData(bitpack, terrData, map[s], map[s + 1]); + if (bitpack.BytePos > 950 && i != numberPatchs - 1) + { + //finish this packet + bitpack.PackBitsFromByte(END_OF_PATCHES); + + // fix the datablock lenght + datasize = bitpack.BytePos - 9; + data[8] = (byte)datasize; + data[9] = (byte)(datasize >> 8); + + buf.DataLength = bitpack.BytePos + 1; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); + + // start another + buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); + data = buf.Data; + + Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7); + + data[7] = landPacketType; + //data[8] and data[9] == datablock size to fill later + + data[10] = 0; // BitPack needs this + // start data + bitpack = new BitPack(data, 10); + + bitpack.PackBits(STRIDE, 16); + bitpack.PackBitsFromByte(16); + bitpack.PackBitsFromByte(landPacketType); + } + } + + bitpack.PackBitsFromByte(END_OF_PATCHES); + + datasize = bitpack.BytePos - 9; + data[8] = (byte)datasize; + data[9] = (byte)(datasize >> 8); + + buf.DataLength = bitpack.BytePos + 1; + m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); + } catch (Exception e) { @@ -4512,7 +4588,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc); else CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc); - if (zc.Position < LLUDPServer.MTU - 5) + if (zc.Position < LLUDPServer.MAXPAYLOAD) { tau.Add(eu); ++count; @@ -4593,7 +4669,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lastpos = pos; CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, (eu.Flags & PrimUpdateFlags.Textures) != 0); - if (pos < LLUDPServer.MTU) + if (pos < LLUDPServer.MAXPAYLOAD) { tau.Add(eu); ++count; diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs index a60381a..020c7be 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs @@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return iout; } +/* // new using terrain data and patchs indexes public static List CreateLayerDataPackets(TerrainData terrData, int[] map) { @@ -213,6 +214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return ret; } +*/ public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY) { -- cgit v1.1