diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
16 files changed, 309 insertions, 202 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index b06788b..921d3bf 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | |||
@@ -50,6 +50,7 @@ using OpenSim.Services.Interfaces; | |||
50 | using Caps = OpenSim.Framework.Capabilities.Caps; | 50 | using Caps = OpenSim.Framework.Capabilities.Caps; |
51 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; | 51 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; |
52 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | 52 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; |
53 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
53 | 54 | ||
54 | namespace OpenSim.Region.ClientStack.Linden | 55 | namespace OpenSim.Region.ClientStack.Linden |
55 | { | 56 | { |
@@ -105,7 +106,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
105 | private static readonly string m_ResourceCostSelectedPath = "0103/"; | 106 | private static readonly string m_ResourceCostSelectedPath = "0103/"; |
106 | private static readonly string m_UpdateAgentInformationPath = "0500/"; | 107 | private static readonly string m_UpdateAgentInformationPath = "0500/"; |
107 | 108 | ||
108 | |||
109 | // These are callbacks which will be setup by the scene so that we can update scene data when we | 109 | // These are callbacks which will be setup by the scene so that we can update scene data when we |
110 | // receive capability calls | 110 | // receive capability calls |
111 | public NewInventoryItem AddNewInventoryItem = null; | 111 | public NewInventoryItem AddNewInventoryItem = null; |
@@ -343,6 +343,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
343 | m_log.DebugFormat( | 343 | m_log.DebugFormat( |
344 | "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); | 344 | "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); |
345 | 345 | ||
346 | if (!m_HostCapsObj.WaitForActivation()) | ||
347 | return string.Empty; | ||
348 | |||
346 | if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) | 349 | if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) |
347 | { | 350 | { |
348 | m_log.WarnFormat( | 351 | m_log.WarnFormat( |
@@ -828,9 +831,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
828 | texitem.Folder = texturesFolder; | 831 | texitem.Folder = texturesFolder; |
829 | 832 | ||
830 | texitem.CurrentPermissions | 833 | texitem.CurrentPermissions |
831 | = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); | 834 | = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export); |
832 | 835 | ||
833 | texitem.BasePermissions = (uint)PermissionMask.All; | 836 | texitem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; |
834 | texitem.EveryOnePermissions = 0; | 837 | texitem.EveryOnePermissions = 0; |
835 | texitem.NextPermissions = (uint)PermissionMask.All; | 838 | texitem.NextPermissions = (uint)PermissionMask.All; |
836 | texitem.CreationDate = Util.UnixTimeSinceEpoch(); | 839 | texitem.CreationDate = Util.UnixTimeSinceEpoch(); |
@@ -1095,9 +1098,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1095 | else | 1098 | else |
1096 | { | 1099 | { |
1097 | item.CurrentPermissions | 1100 | item.CurrentPermissions |
1098 | = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); | 1101 | = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export); |
1099 | 1102 | ||
1100 | item.BasePermissions = (uint)PermissionMask.All; | 1103 | item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; |
1101 | item.EveryOnePermissions = 0; | 1104 | item.EveryOnePermissions = 0; |
1102 | item.NextPermissions = (uint)PermissionMask.All; | 1105 | item.NextPermissions = (uint)PermissionMask.All; |
1103 | } | 1106 | } |
@@ -1317,7 +1320,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1317 | object_data["PhysicsShapeType"] = obj.PhysicsShapeType; | 1320 | object_data["PhysicsShapeType"] = obj.PhysicsShapeType; |
1318 | object_data["Density"] = obj.Density; | 1321 | object_data["Density"] = obj.Density; |
1319 | object_data["Friction"] = obj.Friction; | 1322 | object_data["Friction"] = obj.Friction; |
1320 | object_data["Restitution"] = obj.Bounciness; | 1323 | object_data["Restitution"] = obj.Restitution; |
1321 | object_data["GravityMultiplier"] = obj.GravityModifier; | 1324 | object_data["GravityMultiplier"] = obj.GravityModifier; |
1322 | 1325 | ||
1323 | resp[uuid.ToString()] = object_data; | 1326 | resp[uuid.ToString()] = object_data; |
@@ -1446,7 +1449,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
1446 | string param, IOSHttpRequest httpRequest, | 1449 | string param, IOSHttpRequest httpRequest, |
1447 | IOSHttpResponse httpResponse) | 1450 | IOSHttpResponse httpResponse) |
1448 | { | 1451 | { |
1449 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); | 1452 | // OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); |
1450 | OSDMap resp = new OSDMap(); | 1453 | OSDMap resp = new OSDMap(); |
1451 | 1454 | ||
1452 | OSDMap accessPrefs = new OSDMap(); | 1455 | OSDMap accessPrefs = new OSDMap(); |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 986a665..37285e3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -97,6 +97,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
97 | + " >= 1 - turns on outgoing event logging\n" | 97 | + " >= 1 - turns on outgoing event logging\n" |
98 | + " >= 2 - turns on poll notification", | 98 | + " >= 2 - turns on poll notification", |
99 | HandleDebugEq); | 99 | HandleDebugEq); |
100 | |||
101 | MainConsole.Instance.Commands.AddCommand( | ||
102 | "Debug", | ||
103 | false, | ||
104 | "show eq", | ||
105 | "show eq", | ||
106 | "Show contents of event queues for logged in avatars. Used for debugging.", | ||
107 | HandleShowEq); | ||
100 | } | 108 | } |
101 | 109 | ||
102 | public void RemoveRegion(Scene scene) | 110 | public void RemoveRegion(Scene scene) |
@@ -138,7 +146,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
138 | 146 | ||
139 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) | 147 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) |
140 | { | 148 | { |
141 | MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]"); | 149 | MainConsole.Instance.OutputFormat("Usage: debug eq [0|1|2]"); |
142 | } | 150 | } |
143 | else | 151 | else |
144 | { | 152 | { |
@@ -148,6 +156,21 @@ namespace OpenSim.Region.ClientStack.Linden | |||
148 | } | 156 | } |
149 | } | 157 | } |
150 | 158 | ||
159 | protected void HandleShowEq(string module, string[] args) | ||
160 | { | ||
161 | MainConsole.Instance.OutputFormat("For scene {0}", m_scene.Name); | ||
162 | |||
163 | lock (queues) | ||
164 | { | ||
165 | foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues) | ||
166 | { | ||
167 | MainConsole.Instance.OutputFormat( | ||
168 | "For agent {0} there are {1} messages queued for send.", | ||
169 | kvp.Key, kvp.Value.Count); | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
151 | /// <summary> | 174 | /// <summary> |
152 | /// Always returns a valid queue | 175 | /// Always returns a valid queue |
153 | /// </summary> | 176 | /// </summary> |
@@ -467,8 +490,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
467 | responsedata["content_type"] = "text/plain"; | 490 | responsedata["content_type"] = "text/plain"; |
468 | responsedata["keepalive"] = false; | 491 | responsedata["keepalive"] = false; |
469 | responsedata["reusecontext"] = false; | 492 | responsedata["reusecontext"] = false; |
470 | responsedata["str_response_string"] = "Upstream error: "; | 493 | responsedata["str_response_string"] = "<llsd></llsd>"; |
471 | responsedata["error_status_text"] = "Upstream error:"; | 494 | responsedata["error_status_text"] = "<llsd></llsd>"; |
472 | responsedata["http_protocol_version"] = "HTTP/1.0"; | 495 | responsedata["http_protocol_version"] = "HTTP/1.0"; |
473 | return responsedata; | 496 | return responsedata; |
474 | } | 497 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index d604cf6..141af8a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | |||
@@ -44,13 +44,15 @@ using OpenSim.Tests.Common.Mock; | |||
44 | namespace OpenSim.Region.ClientStack.Linden.Tests | 44 | namespace OpenSim.Region.ClientStack.Linden.Tests |
45 | { | 45 | { |
46 | [TestFixture] | 46 | [TestFixture] |
47 | public class EventQueueTests | 47 | public class EventQueueTests : OpenSimTestCase |
48 | { | 48 | { |
49 | private TestScene m_scene; | 49 | private TestScene m_scene; |
50 | 50 | ||
51 | [SetUp] | 51 | [SetUp] |
52 | public void SetUp() | 52 | public override void SetUp() |
53 | { | 53 | { |
54 | base.SetUp(); | ||
55 | |||
54 | uint port = 9999; | 56 | uint port = 9999; |
55 | uint sslPort = 9998; | 57 | uint sslPort = 9998; |
56 | 58 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index d4dbfb9..a42c96c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | |||
@@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
56 | public PollServiceTextureEventArgs thepoll; | 56 | public PollServiceTextureEventArgs thepoll; |
57 | public UUID reqID; | 57 | public UUID reqID; |
58 | public Hashtable request; | 58 | public Hashtable request; |
59 | public bool send503; | ||
59 | } | 60 | } |
60 | 61 | ||
61 | public class aPollResponse | 62 | public class aPollResponse |
@@ -244,7 +245,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
244 | reqinfo.thepoll = this; | 245 | reqinfo.thepoll = this; |
245 | reqinfo.reqID = x; | 246 | reqinfo.reqID = x; |
246 | reqinfo.request = y; | 247 | reqinfo.request = y; |
248 | reqinfo.send503 = false; | ||
247 | 249 | ||
250 | lock (responses) | ||
251 | { | ||
252 | if (responses.Count > 0) | ||
253 | { | ||
254 | if (m_queue.Count >= 4) | ||
255 | { | ||
256 | // Never allow more than 4 fetches to wait | ||
257 | reqinfo.send503 = true; | ||
258 | } | ||
259 | } | ||
260 | } | ||
248 | m_queue.Enqueue(reqinfo); | 261 | m_queue.Enqueue(reqinfo); |
249 | }; | 262 | }; |
250 | 263 | ||
@@ -276,6 +289,22 @@ namespace OpenSim.Region.ClientStack.Linden | |||
276 | 289 | ||
277 | UUID requestID = requestinfo.reqID; | 290 | UUID requestID = requestinfo.reqID; |
278 | 291 | ||
292 | if (requestinfo.send503) | ||
293 | { | ||
294 | response = new Hashtable(); | ||
295 | |||
296 | response["int_response_code"] = 503; | ||
297 | response["str_response_string"] = "Throttled"; | ||
298 | response["content_type"] = "text/plain"; | ||
299 | response["keepalive"] = false; | ||
300 | response["reusecontext"] = false; | ||
301 | |||
302 | lock (responses) | ||
303 | responses[requestID] = new aPollResponse() {bytes = 0, response = response}; | ||
304 | |||
305 | return; | ||
306 | } | ||
307 | |||
279 | // If the avatar is gone, don't bother to get the texture | 308 | // If the avatar is gone, don't bother to get the texture |
280 | if (m_scene.GetScenePresence(Id) == null) | 309 | if (m_scene.GetScenePresence(Id) == null) |
281 | { | 310 | { |
@@ -385,6 +414,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
385 | GetTextureModule.aPollResponse response; | 414 | GetTextureModule.aPollResponse response; |
386 | if (responses.TryGetValue(key, out response)) | 415 | if (responses.TryGetValue(key, out response)) |
387 | { | 416 | { |
417 | // This is any error response | ||
418 | if (response.bytes == 0) | ||
419 | return true; | ||
388 | 420 | ||
389 | // Normal | 421 | // Normal |
390 | if (BytesSent + response.bytes <= ThrottleBytes) | 422 | if (BytesSent + response.bytes <= ThrottleBytes) |
@@ -411,12 +443,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
411 | 443 | ||
412 | return haskey; | 444 | return haskey; |
413 | } | 445 | } |
446 | |||
414 | public void ProcessTime() | 447 | public void ProcessTime() |
415 | { | 448 | { |
416 | PassTime(); | 449 | PassTime(); |
417 | } | 450 | } |
418 | 451 | ||
419 | |||
420 | private void PassTime() | 452 | private void PassTime() |
421 | { | 453 | { |
422 | currenttime = Util.EnvironmentTickCount(); | 454 | currenttime = Util.EnvironmentTickCount(); |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs index 60c1814..1b68603 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs | |||
@@ -57,7 +57,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
57 | public bool Enabled { get; private set; } | 57 | public bool Enabled { get; private set; } |
58 | 58 | ||
59 | private Scene m_scene; | 59 | private Scene m_scene; |
60 | private UUID m_agentID; | ||
61 | 60 | ||
62 | #region ISharedRegionModule Members | 61 | #region ISharedRegionModule Members |
63 | 62 | ||
@@ -118,13 +117,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
118 | public void RegisterCaps(UUID agentID, Caps caps) | 117 | public void RegisterCaps(UUID agentID, Caps caps) |
119 | { | 118 | { |
120 | IRequestHandler reqHandler | 119 | IRequestHandler reqHandler |
121 | = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString()); | 120 | = new RestHTTPHandler( |
121 | "GET", "/CAPS/" + UUID.Random(), ht => MeshUploadFlag(ht, agentID), "MeshUploadFlag", agentID.ToString()); | ||
122 | 122 | ||
123 | caps.RegisterHandler("MeshUploadFlag", reqHandler); | 123 | caps.RegisterHandler("MeshUploadFlag", reqHandler); |
124 | m_agentID = agentID; | 124 | |
125 | } | 125 | } |
126 | 126 | ||
127 | private Hashtable MeshUploadFlag(Hashtable mDhttpMethod) | 127 | private Hashtable MeshUploadFlag(Hashtable mDhttpMethod, UUID agentID) |
128 | { | 128 | { |
129 | // m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); | 129 | // m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); |
130 | 130 | ||
@@ -148,4 +148,4 @@ namespace OpenSim.Region.ClientStack.Linden | |||
148 | return responsedata; | 148 | return responsedata; |
149 | } | 149 | } |
150 | } | 150 | } |
151 | } \ No newline at end of file | 151 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs index 060a61c..595d01a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.7.5.*")] | 32 | [assembly: AssemblyVersion("0.7.6.*")] |
33 | [assembly: AssemblyFileVersion("1.0.0.0")] | 33 | |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs index fcac182..79d56c4 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs | |||
@@ -56,8 +56,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
56 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")] | 56 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")] |
57 | public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole | 57 | public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole |
58 | { | 58 | { |
59 | private static readonly ILog m_log = | 59 | // private static readonly ILog m_log = |
60 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 60 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
61 | 61 | ||
62 | private Scene m_scene; | 62 | private Scene m_scene; |
63 | private IEventQueue m_eventQueue; | 63 | private IEventQueue m_eventQueue; |
@@ -164,8 +164,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
164 | 164 | ||
165 | public class ConsoleHandler : BaseStreamHandler | 165 | public class ConsoleHandler : BaseStreamHandler |
166 | { | 166 | { |
167 | private static readonly ILog m_log = | 167 | // private static readonly ILog m_log = |
168 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 168 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
169 | 169 | ||
170 | private RegionConsoleModule m_consoleModule; | 170 | private RegionConsoleModule m_consoleModule; |
171 | private UUID m_agentID; | 171 | private UUID m_agentID; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 191bccf..7d9f935 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | |||
@@ -59,6 +59,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
59 | // private static readonly ILog m_log = | 59 | // private static readonly ILog m_log = |
60 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 60 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
61 | 61 | ||
62 | public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest; | ||
63 | |||
62 | private Scene m_scene; | 64 | private Scene m_scene; |
63 | 65 | ||
64 | /// <summary> | 66 | /// <summary> |
@@ -68,6 +70,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
68 | 70 | ||
69 | private string m_MapImageServerURL = string.Empty; | 71 | private string m_MapImageServerURL = string.Empty; |
70 | private string m_SearchURL = string.Empty; | 72 | private string m_SearchURL = string.Empty; |
73 | private bool m_ExportSupported = false; | ||
71 | 74 | ||
72 | #region ISharedRegionModule Members | 75 | #region ISharedRegionModule Members |
73 | 76 | ||
@@ -85,6 +88,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
85 | } | 88 | } |
86 | 89 | ||
87 | m_SearchURL = config.GetString("SearchServerURI", string.Empty); | 90 | m_SearchURL = config.GetString("SearchServerURI", string.Empty); |
91 | |||
92 | m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); | ||
88 | } | 93 | } |
89 | 94 | ||
90 | AddDefaultFeatures(); | 95 | AddDefaultFeatures(); |
@@ -94,6 +99,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
94 | { | 99 | { |
95 | m_scene = s; | 100 | m_scene = s; |
96 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; | 101 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; |
102 | |||
103 | m_scene.RegisterModuleInterface<ISimulatorFeaturesModule>(this); | ||
97 | } | 104 | } |
98 | 105 | ||
99 | public void RemoveRegion(Scene s) | 106 | public void RemoveRegion(Scene s) |
@@ -148,6 +155,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
148 | if (m_SearchURL != string.Empty) | 155 | if (m_SearchURL != string.Empty) |
149 | gridServicesMap["search"] = m_SearchURL; | 156 | gridServicesMap["search"] = m_SearchURL; |
150 | m_features["GridServices"] = gridServicesMap; | 157 | m_features["GridServices"] = gridServicesMap; |
158 | |||
159 | if (m_ExportSupported) | ||
160 | m_features["ExportSupported"] = true; | ||
151 | } | 161 | } |
152 | } | 162 | } |
153 | 163 | ||
@@ -156,7 +166,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
156 | IRequestHandler reqHandler | 166 | IRequestHandler reqHandler |
157 | = new RestHTTPHandler( | 167 | = new RestHTTPHandler( |
158 | "GET", "/CAPS/" + UUID.Random(), | 168 | "GET", "/CAPS/" + UUID.Random(), |
159 | HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString()); | 169 | x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString()); |
160 | 170 | ||
161 | caps.RegisterHandler("SimulatorFeatures", reqHandler); | 171 | caps.RegisterHandler("SimulatorFeatures", reqHandler); |
162 | } | 172 | } |
@@ -185,18 +195,33 @@ namespace OpenSim.Region.ClientStack.Linden | |||
185 | return new OSDMap(m_features); | 195 | return new OSDMap(m_features); |
186 | } | 196 | } |
187 | 197 | ||
188 | private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod) | 198 | private OSDMap DeepCopy() |
199 | { | ||
200 | // This isn't the cheapest way of doing this but the rate | ||
201 | // of occurrence is low (on sim entry only) and it's a sure | ||
202 | // way to get a true deep copy. | ||
203 | OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features)); | ||
204 | |||
205 | return (OSDMap)copy; | ||
206 | } | ||
207 | |||
208 | private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID) | ||
189 | { | 209 | { |
190 | // m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); | 210 | // m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); |
191 | 211 | ||
212 | OSDMap copy = DeepCopy(); | ||
213 | |||
214 | SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest; | ||
215 | if (handlerOnSimulatorFeaturesRequest != null) | ||
216 | handlerOnSimulatorFeaturesRequest(agentID, ref copy); | ||
217 | |||
192 | //Send back data | 218 | //Send back data |
193 | Hashtable responsedata = new Hashtable(); | 219 | Hashtable responsedata = new Hashtable(); |
194 | responsedata["int_response_code"] = 200; | 220 | responsedata["int_response_code"] = 200; |
195 | responsedata["content_type"] = "text/plain"; | 221 | responsedata["content_type"] = "text/plain"; |
196 | responsedata["keepalive"] = false; | 222 | responsedata["keepalive"] = false; |
197 | 223 | ||
198 | lock (m_features) | 224 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy); |
199 | responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features); | ||
200 | 225 | ||
201 | return responsedata; | 226 | return responsedata; |
202 | } | 227 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 6bed95f..eca576d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs | |||
@@ -190,8 +190,15 @@ namespace OpenSim.Region.ClientStack.Linden | |||
190 | { | 190 | { |
191 | if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) | 191 | if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) |
192 | { | 192 | { |
193 | cacheItems[i].TextureID = | 193 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; |
194 | textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; | 194 | if (face == null) |
195 | { | ||
196 | textureEntry.CreateFace(cacheItems[i].TextureIndex); | ||
197 | textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = | ||
198 | AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
199 | continue; | ||
200 | } | ||
201 | cacheItems[i].TextureID =face.TextureID; | ||
195 | if (m_scene.AssetService != null) | 202 | if (m_scene.AssetService != null) |
196 | cacheItems[i].TextureAsset = | 203 | cacheItems[i].TextureAsset = |
197 | m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); | 204 | m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); |
@@ -213,8 +220,16 @@ namespace OpenSim.Region.ClientStack.Linden | |||
213 | { | 220 | { |
214 | if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) | 221 | if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) |
215 | { | 222 | { |
223 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; | ||
224 | if (face == null) | ||
225 | { | ||
226 | textureEntry.CreateFace(cacheItems[i].TextureIndex); | ||
227 | textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = | ||
228 | AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
229 | continue; | ||
230 | } | ||
216 | cacheItems[i].TextureID = | 231 | cacheItems[i].TextureID = |
217 | textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; | 232 | face.TextureID; |
218 | } | 233 | } |
219 | else | 234 | else |
220 | { | 235 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 04cd474..707cc93 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -39,10 +39,13 @@ using OpenSim.Framework.Servers; | |||
39 | using OpenSim.Framework.Servers.HttpServer; | 39 | using OpenSim.Framework.Servers.HttpServer; |
40 | using OpenSim.Region.Framework.Interfaces; | 40 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Framework.Capabilities; | ||
42 | using OpenSim.Services.Interfaces; | 43 | using OpenSim.Services.Interfaces; |
43 | using Caps = OpenSim.Framework.Capabilities.Caps; | 44 | using Caps = OpenSim.Framework.Capabilities.Caps; |
44 | using OpenSim.Capabilities.Handlers; | 45 | using OpenSim.Capabilities.Handlers; |
45 | using OpenSim.Framework.Monitoring; | 46 | using OpenSim.Framework.Monitoring; |
47 | using OpenMetaverse; | ||
48 | using OpenMetaverse.StructuredData; | ||
46 | 49 | ||
47 | namespace OpenSim.Region.ClientStack.Linden | 50 | namespace OpenSim.Region.ClientStack.Linden |
48 | { | 51 | { |
@@ -52,11 +55,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
52 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] | 55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] |
53 | public class WebFetchInvDescModule : INonSharedRegionModule | 56 | public class WebFetchInvDescModule : INonSharedRegionModule |
54 | { | 57 | { |
55 | struct aPollRequest | 58 | class aPollRequest |
56 | { | 59 | { |
57 | public PollServiceInventoryEventArgs thepoll; | 60 | public PollServiceInventoryEventArgs thepoll; |
58 | public UUID reqID; | 61 | public UUID reqID; |
59 | public Hashtable request; | 62 | public Hashtable request; |
63 | public ScenePresence presence; | ||
64 | public List<UUID> folders; | ||
60 | } | 65 | } |
61 | 66 | ||
62 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -71,8 +76,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
71 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); | 76 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); |
72 | private static Thread[] m_workerThreads = null; | 77 | private static Thread[] m_workerThreads = null; |
73 | 78 | ||
74 | private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue = | 79 | private static DoubleQueue<aPollRequest> m_queue = |
75 | new OpenMetaverse.BlockingQueue<aPollRequest>(); | 80 | new DoubleQueue<aPollRequest>(); |
76 | 81 | ||
77 | #region ISharedRegionModule Members | 82 | #region ISharedRegionModule Members |
78 | 83 | ||
@@ -143,12 +148,18 @@ namespace OpenSim.Region.ClientStack.Linden | |||
143 | 148 | ||
144 | private class PollServiceInventoryEventArgs : PollServiceEventArgs | 149 | private class PollServiceInventoryEventArgs : PollServiceEventArgs |
145 | { | 150 | { |
151 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
152 | |||
146 | private Dictionary<UUID, Hashtable> responses = | 153 | private Dictionary<UUID, Hashtable> responses = |
147 | new Dictionary<UUID, Hashtable>(); | 154 | new Dictionary<UUID, Hashtable>(); |
148 | 155 | ||
149 | public PollServiceInventoryEventArgs(UUID pId) : | 156 | private Scene m_scene; |
157 | |||
158 | public PollServiceInventoryEventArgs(Scene scene, UUID pId) : | ||
150 | base(null, null, null, null, pId, int.MaxValue) | 159 | base(null, null, null, null, pId, int.MaxValue) |
151 | { | 160 | { |
161 | m_scene = scene; | ||
162 | |||
152 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; | 163 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; |
153 | GetEvents = (x, y) => | 164 | GetEvents = (x, y) => |
154 | { | 165 | { |
@@ -167,12 +178,68 @@ namespace OpenSim.Region.ClientStack.Linden | |||
167 | 178 | ||
168 | Request = (x, y) => | 179 | Request = (x, y) => |
169 | { | 180 | { |
181 | ScenePresence sp = m_scene.GetScenePresence(Id); | ||
182 | if (sp == null) | ||
183 | { | ||
184 | m_log.ErrorFormat("[INVENTORY]: Unable to find ScenePresence for {0}", Id); | ||
185 | return; | ||
186 | } | ||
187 | |||
170 | aPollRequest reqinfo = new aPollRequest(); | 188 | aPollRequest reqinfo = new aPollRequest(); |
171 | reqinfo.thepoll = this; | 189 | reqinfo.thepoll = this; |
172 | reqinfo.reqID = x; | 190 | reqinfo.reqID = x; |
173 | reqinfo.request = y; | 191 | reqinfo.request = y; |
192 | reqinfo.presence = sp; | ||
193 | reqinfo.folders = new List<UUID>(); | ||
194 | |||
195 | // Decode the request here | ||
196 | string request = y["body"].ToString(); | ||
197 | |||
198 | request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); | ||
199 | |||
200 | request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); | ||
201 | request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); | ||
202 | |||
203 | Hashtable hash = new Hashtable(); | ||
204 | try | ||
205 | { | ||
206 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | ||
207 | } | ||
208 | catch (LLSD.LLSDParseException e) | ||
209 | { | ||
210 | m_log.ErrorFormat("[INVENTORY]: Fetch error: {0}{1}" + e.Message, e.StackTrace); | ||
211 | m_log.Error("Request: " + request); | ||
212 | return; | ||
213 | } | ||
214 | catch (System.Xml.XmlException) | ||
215 | { | ||
216 | m_log.ErrorFormat("[INVENTORY]: XML Format error"); | ||
217 | } | ||
218 | |||
219 | ArrayList foldersrequested = (ArrayList)hash["folders"]; | ||
220 | |||
221 | bool highPriority = false; | ||
222 | |||
223 | for (int i = 0; i < foldersrequested.Count; i++) | ||
224 | { | ||
225 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; | ||
226 | string folder = inventoryhash["folder_id"].ToString(); | ||
227 | UUID folderID; | ||
228 | if (UUID.TryParse(folder, out folderID)) | ||
229 | { | ||
230 | if (!reqinfo.folders.Contains(folderID)) | ||
231 | { | ||
232 | if (sp.COF != UUID.Zero && sp.COF == folderID) | ||
233 | highPriority = true; | ||
234 | reqinfo.folders.Add(folderID); | ||
235 | } | ||
236 | } | ||
237 | } | ||
174 | 238 | ||
175 | m_queue.Enqueue(reqinfo); | 239 | if (highPriority) |
240 | m_queue.EnqueueHigh(reqinfo); | ||
241 | else | ||
242 | m_queue.EnqueueLow(reqinfo); | ||
176 | }; | 243 | }; |
177 | 244 | ||
178 | NoEvents = (x, y) => | 245 | NoEvents = (x, y) => |
@@ -208,7 +275,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
208 | response["reusecontext"] = false; | 275 | response["reusecontext"] = false; |
209 | 276 | ||
210 | response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( | 277 | response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( |
211 | requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); | 278 | requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); |
212 | 279 | ||
213 | lock (responses) | 280 | lock (responses) |
214 | responses[requestID] = response; | 281 | responses[requestID] = response; |
@@ -220,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
220 | string capUrl = "/CAPS/" + UUID.Random() + "/"; | 287 | string capUrl = "/CAPS/" + UUID.Random() + "/"; |
221 | 288 | ||
222 | // Register this as a poll service | 289 | // Register this as a poll service |
223 | PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); | 290 | PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID); |
224 | 291 | ||
225 | args.Type = PollServiceEventArgs.EventType.Inventory; | 292 | args.Type = PollServiceEventArgs.EventType.Inventory; |
226 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); | 293 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index fd82db7..98160c9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -51,6 +51,7 @@ using RegionFlags = OpenMetaverse.RegionFlags; | |||
51 | using Nini.Config; | 51 | using Nini.Config; |
52 | 52 | ||
53 | using System.IO; | 53 | using System.IO; |
54 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
54 | 55 | ||
55 | namespace OpenSim.Region.ClientStack.LindenUDP | 56 | namespace OpenSim.Region.ClientStack.LindenUDP |
56 | { | 57 | { |
@@ -822,6 +823,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
822 | handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); | 823 | handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); |
823 | handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; | 824 | handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; |
824 | 825 | ||
826 | handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0]; | ||
825 | // OutPacket(handshake, ThrottleOutPacketType.Task); | 827 | // OutPacket(handshake, ThrottleOutPacketType.Task); |
826 | // use same as MoveAgentIntoRegion (both should be task ) | 828 | // use same as MoveAgentIntoRegion (both should be task ) |
827 | OutPacket(handshake, ThrottleOutPacketType.Unknown); | 829 | OutPacket(handshake, ThrottleOutPacketType.Unknown); |
@@ -901,9 +903,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
901 | } | 903 | } |
902 | } | 904 | } |
903 | 905 | ||
904 | public void SendGenericMessage(string method, List<string> message) | 906 | public void SendGenericMessage(string method, UUID invoice, List<string> message) |
905 | { | 907 | { |
906 | GenericMessagePacket gmp = new GenericMessagePacket(); | 908 | GenericMessagePacket gmp = new GenericMessagePacket(); |
909 | |||
910 | gmp.AgentData.AgentID = AgentId; | ||
911 | gmp.AgentData.SessionID = m_sessionId; | ||
912 | gmp.AgentData.TransactionID = invoice; | ||
913 | |||
907 | gmp.MethodData.Method = Util.StringToBytes256(method); | 914 | gmp.MethodData.Method = Util.StringToBytes256(method); |
908 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; | 915 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; |
909 | int i = 0; | 916 | int i = 0; |
@@ -916,9 +923,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
916 | OutPacket(gmp, ThrottleOutPacketType.Task); | 923 | OutPacket(gmp, ThrottleOutPacketType.Task); |
917 | } | 924 | } |
918 | 925 | ||
919 | public void SendGenericMessage(string method, List<byte[]> message) | 926 | public void SendGenericMessage(string method, UUID invoice, List<byte[]> message) |
920 | { | 927 | { |
921 | GenericMessagePacket gmp = new GenericMessagePacket(); | 928 | GenericMessagePacket gmp = new GenericMessagePacket(); |
929 | |||
930 | gmp.AgentData.AgentID = AgentId; | ||
931 | gmp.AgentData.SessionID = m_sessionId; | ||
932 | gmp.AgentData.TransactionID = invoice; | ||
933 | |||
922 | gmp.MethodData.Method = Util.StringToBytes256(method); | 934 | gmp.MethodData.Method = Util.StringToBytes256(method); |
923 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; | 935 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; |
924 | int i = 0; | 936 | int i = 0; |
@@ -1801,7 +1813,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1801 | 1813 | ||
1802 | public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) | 1814 | public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) |
1803 | { | 1815 | { |
1804 | const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; | 1816 | // Fudge this value. It's only needed to make the CRC anyway |
1817 | const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; | ||
1805 | 1818 | ||
1806 | FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); | 1819 | FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); |
1807 | // TODO: don't create new blocks if recycling an old packet | 1820 | // TODO: don't create new blocks if recycling an old packet |
@@ -2006,7 +2019,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2006 | 2019 | ||
2007 | protected void SendBulkUpdateInventoryItem(InventoryItemBase item) | 2020 | protected void SendBulkUpdateInventoryItem(InventoryItemBase item) |
2008 | { | 2021 | { |
2009 | const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; | 2022 | const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff; |
2010 | 2023 | ||
2011 | BulkUpdateInventoryPacket bulkUpdate | 2024 | BulkUpdateInventoryPacket bulkUpdate |
2012 | = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); | 2025 | = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); |
@@ -2065,7 +2078,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2065 | /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see> | 2078 | /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see> |
2066 | public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) | 2079 | public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) |
2067 | { | 2080 | { |
2068 | const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; | 2081 | const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; |
2069 | 2082 | ||
2070 | UpdateCreateInventoryItemPacket InventoryReply | 2083 | UpdateCreateInventoryItemPacket InventoryReply |
2071 | = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket( | 2084 | = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket( |
@@ -2654,7 +2667,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2654 | byte physshapetype = part.PhysicsShapeType; | 2667 | byte physshapetype = part.PhysicsShapeType; |
2655 | float density = part.Density; | 2668 | float density = part.Density; |
2656 | float friction = part.Friction; | 2669 | float friction = part.Friction; |
2657 | float bounce = part.Bounciness; | 2670 | float bounce = part.Restitution; |
2658 | float gravmod = part.GravityModifier; | 2671 | float gravmod = part.GravityModifier; |
2659 | 2672 | ||
2660 | eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); | 2673 | eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); |
@@ -3604,7 +3617,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3604 | 3617 | ||
3605 | avp.Sender.IsTrial = false; | 3618 | avp.Sender.IsTrial = false; |
3606 | avp.Sender.ID = agentID; | 3619 | avp.Sender.ID = agentID; |
3607 | m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); | 3620 | avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; |
3621 | //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); | ||
3608 | OutPacket(avp, ThrottleOutPacketType.Task); | 3622 | OutPacket(avp, ThrottleOutPacketType.Task); |
3609 | } | 3623 | } |
3610 | 3624 | ||
@@ -3892,6 +3906,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3892 | { | 3906 | { |
3893 | part.Shape.LightEntry = false; | 3907 | part.Shape.LightEntry = false; |
3894 | } | 3908 | } |
3909 | |||
3910 | if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) | ||
3911 | { | ||
3912 | // Ensure that mesh has at least 8 valid faces | ||
3913 | part.Shape.ProfileBegin = 12500; | ||
3914 | part.Shape.ProfileEnd = 0; | ||
3915 | part.Shape.ProfileHollow = 27500; | ||
3916 | } | ||
3917 | } | ||
3918 | |||
3919 | if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) | ||
3920 | { | ||
3921 | // Ensure that mesh has at least 8 valid faces | ||
3922 | part.Shape.ProfileBegin = 12500; | ||
3923 | part.Shape.ProfileEnd = 0; | ||
3924 | part.Shape.ProfileHollow = 27500; | ||
3895 | } | 3925 | } |
3896 | } | 3926 | } |
3897 | 3927 | ||
@@ -4208,7 +4238,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4208 | pack.Stat = stats.StatsBlock; | 4238 | pack.Stat = stats.StatsBlock; |
4209 | 4239 | ||
4210 | pack.Header.Reliable = false; | 4240 | pack.Header.Reliable = false; |
4211 | 4241 | pack.RegionInfo = new SimStatsPacket.RegionInfoBlock[0]; | |
4212 | OutPacket(pack, ThrottleOutPacketType.Task); | 4242 | OutPacket(pack, ThrottleOutPacketType.Task); |
4213 | } | 4243 | } |
4214 | 4244 | ||
@@ -4599,7 +4629,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4599 | rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock(); | 4629 | rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock(); |
4600 | rinfopack.AgentData.AgentID = AgentId; | 4630 | rinfopack.AgentData.AgentID = AgentId; |
4601 | rinfopack.AgentData.SessionID = SessionId; | 4631 | rinfopack.AgentData.SessionID = SessionId; |
4602 | 4632 | rinfopack.RegionInfo3 = new RegionInfoPacket.RegionInfo3Block[0]; | |
4603 | 4633 | ||
4604 | OutPacket(rinfopack, ThrottleOutPacketType.Task); | 4634 | OutPacket(rinfopack, ThrottleOutPacketType.Task); |
4605 | } | 4635 | } |
@@ -4952,6 +4982,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4952 | position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset; | 4982 | position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset; |
4953 | rotation = part.RotationOffset * presence.Rotation; | 4983 | rotation = part.RotationOffset * presence.Rotation; |
4954 | } | 4984 | } |
4985 | angularVelocity = Vector3.Zero; | ||
4986 | } | ||
4987 | else | ||
4988 | { | ||
4989 | angularVelocity = presence.AngularVelocity; | ||
4990 | rotation = presence.Rotation; | ||
4955 | } | 4991 | } |
4956 | 4992 | ||
4957 | attachPoint = 0; | 4993 | attachPoint = 0; |
@@ -4963,9 +4999,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4963 | // in that direction, even though we don't model this on the server. Implementing this in the future | 4999 | // in that direction, even though we don't model this on the server. Implementing this in the future |
4964 | // may improve movement smoothness. | 5000 | // may improve movement smoothness. |
4965 | // acceleration = new Vector3(1, 0, 0); | 5001 | // acceleration = new Vector3(1, 0, 0); |
4966 | 5002 | ||
4967 | angularVelocity = Vector3.Zero; | ||
4968 | |||
4969 | if (sendTexture) | 5003 | if (sendTexture) |
4970 | textureEntry = presence.Appearance.Texture.GetBytes(); | 5004 | textureEntry = presence.Appearance.Texture.GetBytes(); |
4971 | else | 5005 | else |
@@ -6575,19 +6609,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6575 | #endregion | 6609 | #endregion |
6576 | 6610 | ||
6577 | AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; | 6611 | AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; |
6578 | if (handlerAgentRequestSit != null) | ||
6579 | if (!(agentRequestSit.AgentData == null | ||
6580 | || agentRequestSit.TargetObject == null | ||
6581 | || agentRequestSit.TargetObject.TargetID == null | ||
6582 | || agentRequestSit.TargetObject.Offset == null)) | ||
6583 | { | ||
6584 | var sp = m_scene.GetScenePresence(agentRequestSit.AgentData.AgentID); | ||
6585 | if (sp == null || sp.ParentID != 0) // ignore packet if agent is already sitting | ||
6586 | return true; | ||
6587 | 6612 | ||
6588 | handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, | 6613 | if (handlerAgentRequestSit != null) |
6589 | agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); | 6614 | handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, |
6590 | } | 6615 | agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); |
6591 | } | 6616 | } |
6592 | return true; | 6617 | return true; |
6593 | } | 6618 | } |
@@ -7193,7 +7218,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7193 | 7218 | ||
7194 | if (handlerUpdatePrimFlags != null) | 7219 | if (handlerUpdatePrimFlags != null) |
7195 | { | 7220 | { |
7196 | byte[] data = Pack.ToBytes(); | 7221 | // byte[] data = Pack.ToBytes(); |
7197 | // 46,47,48 are special positions within the packet | 7222 | // 46,47,48 are special positions within the packet |
7198 | // This may change so perhaps we need a better way | 7223 | // This may change so perhaps we need a better way |
7199 | // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) | 7224 | // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) |
@@ -9835,7 +9860,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9835 | EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; | 9860 | EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; |
9836 | if (handlerEconomoyDataRequest != null) | 9861 | if (handlerEconomoyDataRequest != null) |
9837 | { | 9862 | { |
9838 | handlerEconomoyDataRequest(AgentId); | 9863 | handlerEconomoyDataRequest(this); |
9839 | } | 9864 | } |
9840 | return true; | 9865 | return true; |
9841 | } | 9866 | } |
@@ -12242,11 +12267,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12242 | if (logPacket) | 12267 | if (logPacket) |
12243 | m_log.DebugFormat( | 12268 | m_log.DebugFormat( |
12244 | "[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}", | 12269 | "[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}", |
12245 | Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type); | 12270 | Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name, packet.Type); |
12246 | } | 12271 | } |
12247 | 12272 | ||
12248 | if (!ProcessPacketMethod(packet)) | 12273 | if (!ProcessPacketMethod(packet)) |
12249 | m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); | 12274 | m_log.WarnFormat( |
12275 | "[CLIENT]: Unhandled packet {0} from {1} ({2}) in {3}. Ignoring.", | ||
12276 | packet.Type, Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name); | ||
12250 | } | 12277 | } |
12251 | 12278 | ||
12252 | private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) | 12279 | private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) |
@@ -12454,6 +12481,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12454 | return String.Empty; | 12481 | return String.Empty; |
12455 | } | 12482 | } |
12456 | 12483 | ||
12484 | public OSDMap OReport(string uptime, string version) | ||
12485 | { | ||
12486 | return new OSDMap(); | ||
12487 | } | ||
12488 | |||
12457 | /// <summary> | 12489 | /// <summary> |
12458 | /// Make an asset request to the asset service in response to a client request. | 12490 | /// Make an asset request to the asset service in response to a client request. |
12459 | /// </summary> | 12491 | /// </summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index da1ccb3..4154ef2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -281,25 +281,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
281 | m_shouldCollectStats = false; | 281 | m_shouldCollectStats = false; |
282 | if (config != null) | 282 | if (config != null) |
283 | { | 283 | { |
284 | if (config.Contains("enabled") && config.GetBoolean("enabled")) | 284 | m_shouldCollectStats = config.GetBoolean("Enabled", false); |
285 | { | 285 | binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("packet_headers_period_seconds", 300)); |
286 | if (config.Contains("collect_packet_headers")) | 286 | binStatsDir = config.GetString("stats_dir", "."); |
287 | m_shouldCollectStats = config.GetBoolean("collect_packet_headers"); | 287 | m_aggregatedBWStats = config.GetBoolean("aggregatedBWStats", false); |
288 | if (config.Contains("packet_headers_period_seconds")) | 288 | } |
289 | { | 289 | #endregion BinaryStats |
290 | binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds")); | ||
291 | } | ||
292 | if (config.Contains("stats_dir")) | ||
293 | { | ||
294 | binStatsDir = config.GetString("stats_dir"); | ||
295 | } | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | m_shouldCollectStats = false; | ||
300 | } | ||
301 | } | ||
302 | #endregion BinaryStats | ||
303 | 290 | ||
304 | m_throttle = new TokenBucket(null, sceneThrottleBps); | 291 | m_throttle = new TokenBucket(null, sceneThrottleBps); |
305 | ThrottleRates = new ThrottleRates(configSource); | 292 | ThrottleRates = new ThrottleRates(configSource); |
@@ -1309,8 +1296,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1309 | static object binStatsLogLock = new object(); | 1296 | static object binStatsLogLock = new object(); |
1310 | static string binStatsDir = ""; | 1297 | static string binStatsDir = ""; |
1311 | 1298 | ||
1299 | //for Aggregated In/Out BW logging | ||
1300 | static bool m_aggregatedBWStats = false; | ||
1301 | static long m_aggregatedBytesIn = 0; | ||
1302 | static long m_aggregatedByestOut = 0; | ||
1303 | static object aggBWStatsLock = new object(); | ||
1304 | |||
1305 | public static long AggregatedLLUDPBytesIn | ||
1306 | { | ||
1307 | get { return m_aggregatedBytesIn; } | ||
1308 | } | ||
1309 | public static long AggregatedLLUDPBytesOut | ||
1310 | { | ||
1311 | get {return m_aggregatedByestOut;} | ||
1312 | } | ||
1313 | |||
1312 | public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) | 1314 | public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) |
1313 | { | 1315 | { |
1316 | if (m_aggregatedBWStats) | ||
1317 | { | ||
1318 | lock (aggBWStatsLock) | ||
1319 | { | ||
1320 | if (incoming) | ||
1321 | m_aggregatedBytesIn += size; | ||
1322 | else | ||
1323 | m_aggregatedByestOut += size; | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1314 | if (!m_shouldCollectStats) return; | 1327 | if (!m_shouldCollectStats) return; |
1315 | 1328 | ||
1316 | // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size | 1329 | // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size |
@@ -1903,112 +1916,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1903 | } | 1916 | } |
1904 | } | 1917 | } |
1905 | } | 1918 | } |
1906 | |||
1907 | internal class DoubleQueue<T> where T:class | ||
1908 | { | ||
1909 | private Queue<T> m_lowQueue = new Queue<T>(); | ||
1910 | private Queue<T> m_highQueue = new Queue<T>(); | ||
1911 | |||
1912 | private object m_syncRoot = new object(); | ||
1913 | private Semaphore m_s = new Semaphore(0, 1); | ||
1914 | |||
1915 | public DoubleQueue() | ||
1916 | { | ||
1917 | } | ||
1918 | |||
1919 | public virtual int Count | ||
1920 | { | ||
1921 | get { return m_highQueue.Count + m_lowQueue.Count; } | ||
1922 | } | ||
1923 | |||
1924 | public virtual void Enqueue(T data) | ||
1925 | { | ||
1926 | Enqueue(m_lowQueue, data); | ||
1927 | } | ||
1928 | |||
1929 | public virtual void EnqueueLow(T data) | ||
1930 | { | ||
1931 | Enqueue(m_lowQueue, data); | ||
1932 | } | ||
1933 | |||
1934 | public virtual void EnqueueHigh(T data) | ||
1935 | { | ||
1936 | Enqueue(m_highQueue, data); | ||
1937 | } | ||
1938 | |||
1939 | private void Enqueue(Queue<T> q, T data) | ||
1940 | { | ||
1941 | lock (m_syncRoot) | ||
1942 | { | ||
1943 | m_lowQueue.Enqueue(data); | ||
1944 | m_s.WaitOne(0); | ||
1945 | m_s.Release(); | ||
1946 | } | ||
1947 | } | ||
1948 | |||
1949 | public virtual T Dequeue() | ||
1950 | { | ||
1951 | return Dequeue(Timeout.Infinite); | ||
1952 | } | ||
1953 | |||
1954 | public virtual T Dequeue(int tmo) | ||
1955 | { | ||
1956 | return Dequeue(TimeSpan.FromMilliseconds(tmo)); | ||
1957 | } | ||
1958 | |||
1959 | public virtual T Dequeue(TimeSpan wait) | ||
1960 | { | ||
1961 | T res = null; | ||
1962 | |||
1963 | if (!Dequeue(wait, ref res)) | ||
1964 | return null; | ||
1965 | |||
1966 | return res; | ||
1967 | } | ||
1968 | |||
1969 | public bool Dequeue(int timeout, ref T res) | ||
1970 | { | ||
1971 | return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res); | ||
1972 | } | ||
1973 | |||
1974 | public bool Dequeue(TimeSpan wait, ref T res) | ||
1975 | { | ||
1976 | if (!m_s.WaitOne(wait)) | ||
1977 | return false; | ||
1978 | |||
1979 | lock (m_syncRoot) | ||
1980 | { | ||
1981 | if (m_highQueue.Count > 0) | ||
1982 | res = m_highQueue.Dequeue(); | ||
1983 | else | ||
1984 | res = m_lowQueue.Dequeue(); | ||
1985 | |||
1986 | if (m_highQueue.Count == 0 && m_lowQueue.Count == 0) | ||
1987 | return true; | ||
1988 | |||
1989 | try | ||
1990 | { | ||
1991 | m_s.Release(); | ||
1992 | } | ||
1993 | catch | ||
1994 | { | ||
1995 | } | ||
1996 | |||
1997 | return true; | ||
1998 | } | ||
1999 | } | ||
2000 | |||
2001 | public virtual void Clear() | ||
2002 | { | ||
2003 | |||
2004 | lock (m_syncRoot) | ||
2005 | { | ||
2006 | // Make sure sem count is 0 | ||
2007 | m_s.WaitOne(0); | ||
2008 | |||
2009 | m_lowQueue.Clear(); | ||
2010 | m_highQueue.Clear(); | ||
2011 | } | ||
2012 | } | ||
2013 | } | ||
2014 | } | 1919 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 2aeb4cc..7035e38 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -204,9 +204,12 @@ namespace OpenMetaverse | |||
204 | { | 204 | { |
205 | UDPPacketBuffer buf; | 205 | UDPPacketBuffer buf; |
206 | 206 | ||
207 | if (UsePools) | 207 | // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other |
208 | buf = Pool.GetObject(); | 208 | // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux. |
209 | else | 209 | // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation. |
210 | // if (UsePools) | ||
211 | // buf = Pool.GetObject(); | ||
212 | // else | ||
210 | buf = new UDPPacketBuffer(); | 213 | buf = new UDPPacketBuffer(); |
211 | 214 | ||
212 | if (IsRunningInbound) | 215 | if (IsRunningInbound) |
@@ -287,8 +290,8 @@ namespace OpenMetaverse | |||
287 | catch (ObjectDisposedException) { } | 290 | catch (ObjectDisposedException) { } |
288 | finally | 291 | finally |
289 | { | 292 | { |
290 | if (UsePools) | 293 | // if (UsePools) |
291 | Pool.ReturnObject(buffer); | 294 | // Pool.ReturnObject(buffer); |
292 | 295 | ||
293 | // Synchronous mode waits until the packet callback completes | 296 | // Synchronous mode waits until the packet callback completes |
294 | // before starting the receive to fetch another packet | 297 | // before starting the receive to fetch another packet |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs index af2f6f8..98ef72f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.7.5.*")] | 32 | [assembly: AssemblyVersion("0.7.6.*")] |
33 | [assembly: AssemblyFileVersion("1.0.0.0")] | 33 | |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 5fcf376..7d9f581 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs | |||
@@ -43,7 +43,7 @@ using OpenSim.Tests.Common.Mock; | |||
43 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | 43 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests |
44 | { | 44 | { |
45 | [TestFixture] | 45 | [TestFixture] |
46 | public class LLImageManagerTests | 46 | public class LLImageManagerTests : OpenSimTestCase |
47 | { | 47 | { |
48 | private AssetBase m_testImageAsset; | 48 | private AssetBase m_testImageAsset; |
49 | private Scene scene; | 49 | private Scene scene; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs index 0f88ec6..5f73a94 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs | |||
@@ -39,7 +39,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
39 | /// Tests for the LL packet handler | 39 | /// Tests for the LL packet handler |
40 | /// </summary> | 40 | /// </summary> |
41 | [TestFixture] | 41 | [TestFixture] |
42 | public class PacketHandlerTests | 42 | public class PacketHandlerTests : OpenSimTestCase |
43 | { | 43 | { |
44 | // [Test] | 44 | // [Test] |
45 | // /// <summary> | 45 | // /// <summary> |