aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules')
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs66
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs194
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs289
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs82
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs148
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs19
-rw-r--r--OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs38
-rw-r--r--OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs93
-rw-r--r--OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs6
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs98
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs136
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs7
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs8
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs176
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs3
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/GodNamesModule.cs144
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs171
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs165
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs123
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs14
-rw-r--r--OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs17
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs66
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs131
-rw-r--r--OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs140
35 files changed, 2034 insertions, 342 deletions
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 89e18b0..a34f6ee 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
75 m_client = client; 75 m_client = client;
76 m_scene = scene; 76 m_scene = scene;
77 77
78 Watchdog.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); 78 WorkManager.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true);
79 } 79 }
80 80
81 private void SendServerCommand(string command) 81 private void SendServerCommand(string command)
@@ -1455,9 +1455,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1455 return new byte[0]; 1455 return new byte[0];
1456 } 1456 }
1457 1457
1458#pragma warning disable 0067
1458 public event ViewerEffectEventHandler OnViewerEffect; 1459 public event ViewerEffectEventHandler OnViewerEffect;
1459 public event Action<IClientAPI> OnLogout; 1460 public event Action<IClientAPI> OnLogout;
1460 public event Action<IClientAPI> OnConnectionClosed; 1461 public event Action<IClientAPI> OnConnectionClosed;
1462#pragma warning restore 0067
1461 1463
1462 public void SendBlueBoxMessage(UUID FromAvatarID, string FromAvatarName, string Message) 1464 public void SendBlueBoxMessage(UUID FromAvatarID, string FromAvatarName, string Message)
1463 { 1465 {
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
index 9d27386..a1682d2 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
58 58
59 m_listener.Start(50); 59 m_listener.Start(50);
60 60
61 Watchdog.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true); 61 WorkManager.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true);
62 m_baseScene = baseScene; 62 m_baseScene = baseScene;
63 } 63 }
64 64
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index ec18db0..08d0fbf 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -487,8 +487,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
487 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); 487 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
488 488
489 report.AppendFormat( 489 report.AppendFormat(
490 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n", 490 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
491 "Total", 491 "Max",
492 "Target",
493 "Actual",
492 "Resend", 494 "Resend",
493 "Land", 495 "Land",
494 "Wind", 496 "Wind",
@@ -499,7 +501,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
499 501
500 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); 502 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
501 report.AppendFormat( 503 report.AppendFormat(
502 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", 504 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
505 "kb/s",
506 "kb/s",
503 "kb/s", 507 "kb/s",
504 "kb/s", 508 "kb/s",
505 "kb/s", 509 "kb/s",
@@ -511,8 +515,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
511 515
512 report.AppendLine(); 516 report.AppendLine();
513 517
514 bool firstClient = true;
515
516 lock (m_scenes) 518 lock (m_scenes)
517 { 519 {
518 foreach (Scene scene in m_scenes.Values) 520 foreach (Scene scene in m_scenes.Values)
@@ -524,12 +526,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
524 { 526 {
525 LLClientView llClient = client as LLClientView; 527 LLClientView llClient = client as LLClientView;
526 528
527 if (firstClient)
528 {
529 report.AppendLine(GetServerThrottlesReport(llClient.UDPServer));
530 firstClient = false;
531 }
532
533 bool isChild = client.SceneAgent.IsChildAgent; 529 bool isChild = client.SceneAgent.IsChildAgent;
534 if (isChild && !showChildren) 530 if (isChild && !showChildren)
535 return; 531 return;
@@ -548,7 +544,11 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
548 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); 544 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
549 545
550 report.AppendFormat( 546 report.AppendFormat(
551 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", 547 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
548 ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-",
549 llUdpClient.FlowThrottle.AdaptiveEnabled
550 ? ((ci.targetThrottle * 8) / 1000).ToString()
551 : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(),
552 (ci.totalThrottle * 8) / 1000, 552 (ci.totalThrottle * 8) / 1000,
553 (ci.resendThrottle * 8) / 1000, 553 (ci.resendThrottle * 8) / 1000,
554 (ci.landThrottle * 8) / 1000, 554 (ci.landThrottle * 8) / 1000,
@@ -556,9 +556,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
556 (ci.cloudThrottle * 8) / 1000, 556 (ci.cloudThrottle * 8) / 1000,
557 (ci.taskThrottle * 8) / 1000, 557 (ci.taskThrottle * 8) / 1000,
558 (ci.textureThrottle * 8) / 1000, 558 (ci.textureThrottle * 8) / 1000,
559 (ci.assetThrottle * 8) / 1000); 559 (ci.assetThrottle * 8) / 1000);
560
561 report.AppendLine();
562 } 560 }
563 }); 561 });
564 } 562 }
@@ -566,36 +564,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
566 564
567 return report.ToString(); 565 return report.ToString();
568 } 566 }
569
570 protected string GetServerThrottlesReport(LLUDPServer udpServer)
571 {
572 StringBuilder report = new StringBuilder();
573
574 int columnPadding = 2;
575 int maxNameLength = 18;
576 int maxRegionNameLength = 14;
577 int maxTypeLength = 4;
578
579 string name = "SERVER AGENT RATES";
580
581 report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
582 report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding));
583 report.Append(GetColumnEntry("-", maxTypeLength, columnPadding));
584
585 ThrottleRates throttleRates = udpServer.ThrottleRates;
586 report.AppendFormat(
587 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
588 (throttleRates.Total * 8) / 1000,
589 (throttleRates.Resend * 8) / 1000,
590 (throttleRates.Land * 8) / 1000,
591 (throttleRates.Wind * 8) / 1000,
592 (throttleRates.Cloud * 8) / 1000,
593 (throttleRates.Task * 8) / 1000,
594 (throttleRates.Texture * 8) / 1000,
595 (throttleRates.Asset * 8) / 1000);
596
597 return report.ToString();
598 }
599 567
600 /// <summary> 568 /// <summary>
601 /// Show client stats data 569 /// Show client stats data
@@ -637,7 +605,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
637 string.Format( 605 string.Format(
638 "{0} ({1:0.00}%)", 606 "{0} ({1:0.00}%)",
639 llClient.TotalAgentUpdates, 607 llClient.TotalAgentUpdates,
640 (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100)); 608 cinfo.SyncRequests.ContainsKey("AgentUpdate")
609 ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100
610 : 0));
641 } 611 }
642 }); 612 });
643 } 613 }
@@ -669,7 +639,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
669 aCircuit = new AgentCircuitData(); 639 aCircuit = new AgentCircuitData();
670 640
671 if (!llClient.SceneAgent.IsChildAgent) 641 if (!llClient.SceneAgent.IsChildAgent)
672 m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, aCircuit.Viewer, aCircuit.Id0); 642 m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0);
673 643
674 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); 644 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
675 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); 645 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
@@ -706,4 +676,4 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
706 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum); 676 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum);
707 } 677 }
708 } 678 }
709} \ No newline at end of file 679}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index fa35f0f..2f9bb1e 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -51,7 +51,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
51 { 51 {
52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 54 private List<Scene> m_scenes = new List<Scene>();
55
55// private IAvatarFactoryModule m_avatarFactory; 56// private IAvatarFactoryModule m_avatarFactory;
56 57
57 public string Name { get { return "Appearance Information Module"; } } 58 public string Name { get { return "Appearance Information Module"; } }
@@ -83,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
83// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 84// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
84 85
85 lock (m_scenes) 86 lock (m_scenes)
86 m_scenes.Remove(scene.RegionInfo.RegionID); 87 m_scenes.Remove(scene);
87 } 88 }
88 89
89 public void RegionLoaded(Scene scene) 90 public void RegionLoaded(Scene scene)
@@ -91,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
91// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 92// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
92 93
93 lock (m_scenes) 94 lock (m_scenes)
94 m_scenes[scene.RegionInfo.RegionID] = scene; 95 m_scenes.Add(scene);
95 96
96 scene.AddCommand( 97 scene.AddCommand(
97 "Users", this, "show appearance", 98 "Users", this, "show appearance",
@@ -102,7 +103,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
102 scene.AddCommand( 103 scene.AddCommand(
103 "Users", this, "appearance show", 104 "Users", this, "appearance show",
104 "appearance show [<first-name> <last-name>]", 105 "appearance show [<first-name> <last-name>]",
105 "Show appearance information for each avatar in the simulator.", 106 "Show appearance information for avatars.",
106 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " 107 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. "
107 + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." 108 + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud."
108 + "\nOptionally, you can view just a particular avatar's appearance information." 109 + "\nOptionally, you can view just a particular avatar's appearance information."
@@ -132,6 +133,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
132 "Find out which avatar uses the given asset as a baked texture, if any.", 133 "Find out which avatar uses the given asset as a baked texture, if any.",
133 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", 134 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.",
134 HandleFindAppearanceCommand); 135 HandleFindAppearanceCommand);
136
137 scene.AddCommand(
138 "Users", this, "wearables show",
139 "wearables show [<first-name> <last-name>]",
140 "Show information about wearables for avatars.",
141 "If no avatar name is given then a general summary for all avatars in the scene is shown.\n"
142 + "If an avatar name is given then specific information about current wearables is shown.",
143 HandleShowWearablesCommand);
144
145 scene.AddCommand(
146 "Users", this, "wearables check",
147 "wearables check <first-name> <last-name>",
148 "Check that the wearables of a given avatar in the scene are valid.",
149 "This currently checks that the wearable assets themselves and any assets referenced by them exist.",
150 HandleCheckWearablesCommand);
135 } 151 }
136 152
137 private void HandleSendAppearanceCommand(string module, string[] cmd) 153 private void HandleSendAppearanceCommand(string module, string[] cmd)
@@ -155,7 +171,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
155 171
156 lock (m_scenes) 172 lock (m_scenes)
157 { 173 {
158 foreach (Scene scene in m_scenes.Values) 174 foreach (Scene scene in m_scenes)
159 { 175 {
160 if (targetNameSupplied) 176 if (targetNameSupplied)
161 { 177 {
@@ -186,7 +202,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
186 } 202 }
187 } 203 }
188 204
189 protected void HandleShowAppearanceCommand(string module, string[] cmd) 205 private void HandleShowAppearanceCommand(string module, string[] cmd)
190 { 206 {
191 if (cmd.Length != 2 && cmd.Length < 4) 207 if (cmd.Length != 2 && cmd.Length < 4)
192 { 208 {
@@ -207,7 +223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
207 223
208 lock (m_scenes) 224 lock (m_scenes)
209 { 225 {
210 foreach (Scene scene in m_scenes.Values) 226 foreach (Scene scene in m_scenes)
211 { 227 {
212 if (targetNameSupplied) 228 if (targetNameSupplied)
213 { 229 {
@@ -243,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
243 259
244 lock (m_scenes) 260 lock (m_scenes)
245 { 261 {
246 foreach (Scene scene in m_scenes.Values) 262 foreach (Scene scene in m_scenes)
247 { 263 {
248 ScenePresence sp = scene.GetScenePresence(firstname, lastname); 264 ScenePresence sp = scene.GetScenePresence(firstname, lastname);
249 if (sp != null && !sp.IsChildAgent) 265 if (sp != null && !sp.IsChildAgent)
@@ -263,7 +279,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
263 } 279 }
264 } 280 }
265 281
266 protected void HandleFindAppearanceCommand(string module, string[] cmd) 282 private void HandleFindAppearanceCommand(string module, string[] cmd)
267 { 283 {
268 if (cmd.Length != 3) 284 if (cmd.Length != 3)
269 { 285 {
@@ -277,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
277 293
278 lock (m_scenes) 294 lock (m_scenes)
279 { 295 {
280 foreach (Scene scene in m_scenes.Values) 296 foreach (Scene scene in m_scenes)
281 { 297 {
282 scene.ForEachRootScenePresence( 298 scene.ForEachRootScenePresence(
283 sp => 299 sp =>
@@ -304,5 +320,163 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
304 string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray())); 320 string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray()));
305 } 321 }
306 } 322 }
323
324 protected void HandleShowWearablesCommand(string module, string[] cmd)
325 {
326 if (cmd.Length != 2 && cmd.Length < 4)
327 {
328 MainConsole.Instance.OutputFormat("Usage: wearables show [<first-name> <last-name>]");
329 return;
330 }
331
332 bool targetNameSupplied = false;
333 string optionalTargetFirstName = null;
334 string optionalTargetLastName = null;
335
336 if (cmd.Length >= 4)
337 {
338 targetNameSupplied = true;
339 optionalTargetFirstName = cmd[2];
340 optionalTargetLastName = cmd[3];
341 }
342
343 StringBuilder sb = new StringBuilder();
344
345 if (targetNameSupplied)
346 {
347 lock (m_scenes)
348 {
349 foreach (Scene scene in m_scenes)
350 {
351 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
352 if (sp != null && !sp.IsChildAgent)
353 AppendWearablesDetailReport(sp, sb);
354 }
355 }
356 }
357 else
358 {
359 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
360 cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize);
361 cdt.AddColumn("Wearables", 2);
362
363 lock (m_scenes)
364 {
365 foreach (Scene scene in m_scenes)
366 {
367 scene.ForEachRootScenePresence(
368 sp =>
369 {
370 int count = 0;
371
372 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
373 count += sp.Appearance.Wearables[i].Count;
374
375 cdt.AddRow(sp.Name, count);
376 }
377 );
378 }
379 }
380
381 sb.Append(cdt.ToString());
382 }
383
384 MainConsole.Instance.Output(sb.ToString());
385 }
386
387 private void HandleCheckWearablesCommand(string module, string[] cmd)
388 {
389 if (cmd.Length != 4)
390 {
391 MainConsole.Instance.OutputFormat("Usage: wearables check <first-name> <last-name>");
392 return;
393 }
394
395 string firstname = cmd[2];
396 string lastname = cmd[3];
397
398 StringBuilder sb = new StringBuilder();
399 UuidGatherer uuidGatherer = new UuidGatherer(m_scenes[0].AssetService);
400
401 lock (m_scenes)
402 {
403 foreach (Scene scene in m_scenes)
404 {
405 ScenePresence sp = scene.GetScenePresence(firstname, lastname);
406 if (sp != null && !sp.IsChildAgent)
407 {
408 sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name);
409
410 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
411 {
412 AvatarWearable aw = sp.Appearance.Wearables[i];
413
414 if (aw.Count > 0)
415 {
416 sb.Append(Enum.GetName(typeof(WearableType), i));
417 sb.Append("\n");
418
419 for (int j = 0; j < aw.Count; j++)
420 {
421 WearableItem wi = aw[j];
422
423 ConsoleDisplayList cdl = new ConsoleDisplayList();
424 cdl.Indent = 2;
425 cdl.AddRow("Item UUID", wi.ItemID);
426 cdl.AddRow("Assets", "");
427 sb.Append(cdl.ToString());
428
429 uuidGatherer.AddForInspection(wi.AssetID);
430 uuidGatherer.GatherAll();
431 string[] assetStrings
432 = Array.ConvertAll<UUID, string>(uuidGatherer.GatheredUuids.Keys.ToArray(), u => u.ToString());
433
434 bool[] existChecks = scene.AssetService.AssetsExist(assetStrings);
435
436 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
437 cdt.Indent = 4;
438 cdt.AddColumn("Type", 10);
439 cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize);
440 cdt.AddColumn("Found", 5);
441
442 for (int k = 0; k < existChecks.Length; k++)
443 cdt.AddRow(
444 (AssetType)uuidGatherer.GatheredUuids[new UUID(assetStrings[k])],
445 assetStrings[k], existChecks[k] ? "yes" : "no");
446
447 sb.Append(cdt.ToString());
448 sb.Append("\n");
449 }
450 }
451 }
452 }
453 }
454 }
455
456 MainConsole.Instance.Output(sb.ToString());
457 }
458
459 private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb)
460 {
461 sb.AppendFormat("\nWearables for {0}\n", sp.Name);
462
463 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
464 cdt.AddColumn("Type", 10);
465 cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize);
466 cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize);
467
468 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
469 {
470 AvatarWearable aw = sp.Appearance.Wearables[i];
471
472 for (int j = 0; j < aw.Count; j++)
473 {
474 WearableItem wi = aw[j];
475 cdt.AddRow(Enum.GetName(typeof(WearableType), i), wi.ItemID, wi.AssetID);
476 }
477 }
478
479 sb.Append(cdt.ToString());
480 }
307 } 481 }
308} \ No newline at end of file 482} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
index f5bd44d..6985371 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
@@ -109,10 +109,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
109 109
110 internal int m_resetk = 0; 110 internal int m_resetk = 0;
111 111
112 // Working threads
113
114 private Thread m_listener = null;
115
116 private Object msyncConnect = new Object(); 112 private Object msyncConnect = new Object();
117 113
118 internal bool m_randomizeNick = true; // add random suffix 114 internal bool m_randomizeNick = true; // add random suffix
@@ -363,10 +359,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
363 359
364 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); 360 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port);
365 361
366 m_listener = new Thread(new ThreadStart(ListenerRun)); 362 WorkManager.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false);
367 m_listener.Name = "IRCConnectorListenerThread";
368 m_listener.IsBackground = true;
369 m_listener.Start();
370 363
371 // This is the message order recommended by RFC 2812 364 // This is the message order recommended by RFC 2812
372 if (m_password != null) 365 if (m_password != null)
@@ -510,21 +503,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
510 { 503 {
511 while (m_enabled && m_connected) 504 while (m_enabled && m_connected)
512 { 505 {
513
514 if ((inputLine = m_reader.ReadLine()) == null) 506 if ((inputLine = m_reader.ReadLine()) == null)
515 throw new Exception("Listener input socket closed"); 507 throw new Exception("Listener input socket closed");
516 508
509 Watchdog.UpdateThread();
510
517 // m_log.Info("[IRCConnector]: " + inputLine); 511 // m_log.Info("[IRCConnector]: " + inputLine);
518 512
519 if (inputLine.Contains("PRIVMSG")) 513 if (inputLine.Contains("PRIVMSG"))
520 { 514 {
521
522 Dictionary<string, string> data = ExtractMsg(inputLine); 515 Dictionary<string, string> data = ExtractMsg(inputLine);
523 516
524 // Any chat ??? 517 // Any chat ???
525 if (data != null) 518 if (data != null)
526 { 519 {
527
528 OSChatMessage c = new OSChatMessage(); 520 OSChatMessage c = new OSChatMessage();
529 c.Message = data["msg"]; 521 c.Message = data["msg"];
530 c.Type = ChatTypeEnum.Region; 522 c.Type = ChatTypeEnum.Region;
@@ -540,9 +532,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
540 c.Message = String.Format("/me {0}", c.Message.Substring(8, c.Message.Length - 9)); 532 c.Message = String.Format("/me {0}", c.Message.Substring(8, c.Message.Length - 9));
541 533
542 ChannelState.OSChat(this, c, false); 534 ChannelState.OSChat(this, c, false);
543
544 } 535 }
545
546 } 536 }
547 else 537 else
548 { 538 {
@@ -562,6 +552,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
562 552
563 if (m_enabled && (m_resetk == resetk)) 553 if (m_enabled && (m_resetk == resetk))
564 Reconnect(); 554 Reconnect();
555
556 Watchdog.RemoveThread();
565 } 557 }
566 558
567 private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)", 559 private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)",
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 2b33084..3db0781 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
65 // Capability string prefixes 65 // Capability string prefixes
66 private static readonly string m_parcelVoiceInfoRequestPath = "0207/"; 66 private static readonly string m_parcelVoiceInfoRequestPath = "0207/";
67 private static readonly string m_provisionVoiceAccountRequestPath = "0208/"; 67 private static readonly string m_provisionVoiceAccountRequestPath = "0208/";
68 private static readonly string m_chatSessionRequestPath = "0209/"; 68 //private static readonly string m_chatSessionRequestPath = "0209/";
69 69
70 // Control info 70 // Control info
71 private static bool m_Enabled = false; 71 private static bool m_Enabled = false;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index e6b14c6..f51527e 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
92 // Capability strings 92 // Capability strings
93 private static readonly string m_parcelVoiceInfoRequestPath = "0107/"; 93 private static readonly string m_parcelVoiceInfoRequestPath = "0107/";
94 private static readonly string m_provisionVoiceAccountRequestPath = "0108/"; 94 private static readonly string m_provisionVoiceAccountRequestPath = "0108/";
95 private static readonly string m_chatSessionRequestPath = "0109/"; 95 //private static readonly string m_chatSessionRequestPath = "0109/";
96 96
97 // Control info, e.g. vivox server, admin user, admin password 97 // Control info, e.g. vivox server, admin user, admin password
98 private static bool m_pluginEnabled = false; 98 private static bool m_pluginEnabled = false;
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
index 2802e2f..e1b6abb 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
@@ -55,8 +55,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
55 private IGroupsServicesConnector m_groupData = null; 55 private IGroupsServicesConnector m_groupData = null;
56 56
57 // Config Options 57 // Config Options
58 private bool m_groupMessagingEnabled = false; 58 private bool m_groupMessagingEnabled;
59 private bool m_debugEnabled = true; 59 private bool m_debugEnabled;
60 60
61 /// <summary> 61 /// <summary>
62 /// If enabled, module only tries to send group IMs to online users by querying cached presence information. 62 /// If enabled, module only tries to send group IMs to online users by querying cached presence information.
@@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
113 if (m_messageOnlineAgentsOnly) 113 if (m_messageOnlineAgentsOnly)
114 m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>(); 114 m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
115 115
116 m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); 116 m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
117 } 117 }
118 118
119 m_log.InfoFormat( 119 m_log.InfoFormat(
@@ -127,6 +127,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
127 return; 127 return;
128 128
129 scene.RegisterModuleInterface<IGroupsMessagingModule>(this); 129 scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
130
131 scene.AddCommand(
132 "Debug",
133 this,
134 "debug groups messaging verbose",
135 "debug groups messaging verbose <true|false>",
136 "This setting turns on very verbose groups messaging debugging",
137 HandleDebugGroupsMessagingVerbose);
130 } 138 }
131 139
132 public void RegionLoaded(Scene scene) 140 public void RegionLoaded(Scene scene)
@@ -218,6 +226,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
218 226
219 #endregion 227 #endregion
220 228
229 private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
230 {
231 if (args.Length < 5)
232 {
233 MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
234 return;
235 }
236
237 bool verbose = false;
238 if (!bool.TryParse(args[4], out verbose))
239 {
240 MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
241 return;
242 }
243
244 m_debugEnabled = verbose;
245
246 MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
247 }
248
221 /// <summary> 249 /// <summary>
222 /// Not really needed, but does confirm that the group exists. 250 /// Not really needed, but does confirm that the group exists.
223 /// </summary> 251 /// </summary>
@@ -237,11 +265,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
237 return false; 265 return false;
238 } 266 }
239 } 267 }
240 268
241 public void SendMessageToGroup(GridInstantMessage im, UUID groupID) 269 public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
242 { 270 {
243 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); 271 SendMessageToGroup(im, groupID, new UUID(im.fromAgentID), null);
272 }
273
274 public void SendMessageToGroup(
275 GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
276 {
277 int requestStartTick = Environment.TickCount;
278
279 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID);
244 int groupMembersCount = groupMembers.Count; 280 int groupMembersCount = groupMembers.Count;
281 HashSet<string> attemptDeliveryUuidSet = null;
245 282
246 if (m_messageOnlineAgentsOnly) 283 if (m_messageOnlineAgentsOnly)
247 { 284 {
@@ -257,10 +294,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
257 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); 294 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
258 } 295 }
259 296
260 HashSet<string> onlineAgentsUuidSet = new HashSet<string>(); 297 attemptDeliveryUuidSet
261 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); 298 = new HashSet<string>(Array.ConvertAll<PresenceInfo, string>(onlineAgents, pi => pi.UserID));
299
300 //Array.ForEach<PresenceInfo>(onlineAgents, pi => attemptDeliveryUuidSet.Add(pi.UserID));
262 301
263 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); 302 //groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
264 303
265 // if (m_debugEnabled) 304 // if (m_debugEnabled)
266// m_log.DebugFormat( 305// m_log.DebugFormat(
@@ -269,26 +308,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
269 } 308 }
270 else 309 else
271 { 310 {
311 attemptDeliveryUuidSet
312 = new HashSet<string>(groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()));
313
272 if (m_debugEnabled) 314 if (m_debugEnabled)
273 m_log.DebugFormat( 315 m_log.DebugFormat(
274 "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", 316 "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
275 groupID, groupMembers.Count); 317 groupID, groupMembers.Count);
276 } 318 }
277
278 int requestStartTick = Environment.TickCount;
279 319
280 foreach (GroupMembersData member in groupMembers) 320 foreach (GroupMembersData member in groupMembers)
281 { 321 {
282 if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) 322 if (sendCondition != null)
323 {
324 if (!sendCondition(member))
325 {
326 if (m_debugEnabled)
327 m_log.DebugFormat(
328 "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition",
329 member.AgentID);
330
331 continue;
332 }
333 }
334 else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
283 { 335 {
284 // Don't deliver messages to people who have dropped this session 336 // Don't deliver messages to people who have dropped this session
285 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); 337 if (m_debugEnabled)
338 m_log.DebugFormat(
339 "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID);
340
286 continue; 341 continue;
287 } 342 }
288 343
289 // Copy Message 344 // Copy Message
290 GridInstantMessage msg = new GridInstantMessage(); 345 GridInstantMessage msg = new GridInstantMessage();
291 msg.imSessionID = groupID.Guid; 346 msg.imSessionID = im.imSessionID;
292 msg.fromAgentName = im.fromAgentName; 347 msg.fromAgentName = im.fromAgentName;
293 msg.message = im.message; 348 msg.message = im.message;
294 msg.dialog = im.dialog; 349 msg.dialog = im.dialog;
@@ -304,26 +359,51 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
304 359
305 msg.toAgentID = member.AgentID.Guid; 360 msg.toAgentID = member.AgentID.Guid;
306 361
307 IClientAPI client = GetActiveClient(member.AgentID); 362 if (attemptDeliveryUuidSet.Contains(member.AgentID.ToString()))
308 if (client == null)
309 { 363 {
310 // If they're not local, forward across the grid 364 IClientAPI client = GetActiveClient(member.AgentID);
311 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); 365 if (client == null)
312 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); 366 {
367 int startTick = Environment.TickCount;
368
369 // If they're not local, forward across the grid
370 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
371
372 if (m_debugEnabled)
373 m_log.DebugFormat(
374 "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms",
375 member.AgentID, Environment.TickCount - startTick);
376 }
377 else
378 {
379 int startTick = Environment.TickCount;
380
381 ProcessMessageFromGroupSession(msg, client);
382
383 // Deliver locally, directly
384 if (m_debugEnabled)
385 m_log.DebugFormat(
386 "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms",
387 member.AgentID, Environment.TickCount - startTick);
388 }
313 } 389 }
314 else 390 else
315 { 391 {
316 // Deliver locally, directly 392 int startTick = Environment.TickCount;
317 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); 393
318 ProcessMessageFromGroupSession(msg); 394 m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { });
395
396 if (m_debugEnabled)
397 m_log.DebugFormat(
398 "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms",
399 member.AgentID, Environment.TickCount - startTick);
319 } 400 }
320 } 401 }
321 402
322 // Temporary for assessing how long it still takes to send messages to large online groups. 403 if (m_debugEnabled)
323 if (m_messageOnlineAgentsOnly)
324 m_log.DebugFormat( 404 m_log.DebugFormat(
325 "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", 405 "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms",
326 groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); 406 groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick);
327 } 407 }
328 408
329 #region SimGridEventHandlers 409 #region SimGridEventHandlers
@@ -348,7 +428,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
348 // Any other message type will not be delivered to a client by the 428 // Any other message type will not be delivered to a client by the
349 // Instant Message Module 429 // Instant Message Module
350 430
351
352 if (m_debugEnabled) 431 if (m_debugEnabled)
353 { 432 {
354 m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 433 m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -362,13 +441,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
362 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) 441 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
363 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) 442 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
364 { 443 {
365 ProcessMessageFromGroupSession(msg); 444 IClientAPI client = null;
445
446 if (msg.dialog == (byte)InstantMessageDialog.SessionSend)
447 {
448 client = GetActiveClient(new UUID(msg.toAgentID));
449
450 if (client != null)
451 {
452 if (m_debugEnabled)
453 m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name);
454 }
455 else
456 {
457 m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
458
459 return;
460 }
461 }
462
463 ProcessMessageFromGroupSession(msg, client);
366 } 464 }
367 } 465 }
368 466
369 private void ProcessMessageFromGroupSession(GridInstantMessage msg) 467 private void ProcessMessageFromGroupSession(GridInstantMessage msg, IClientAPI client)
370 { 468 {
371 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); 469 if (m_debugEnabled)
470 m_log.DebugFormat(
471 "[GROUPS-MESSAGING]: Session message from {0} going to agent {1}, sessionID {2}, type {3}",
472 msg.fromAgentName, msg.toAgentID, msg.imSessionID, (InstantMessageDialog)msg.dialog);
372 473
373 UUID AgentID = new UUID(msg.fromAgentID); 474 UUID AgentID = new UUID(msg.fromAgentID);
374 UUID GroupID = new UUID(msg.imSessionID); 475 UUID GroupID = new UUID(msg.imSessionID);
@@ -392,74 +493,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
392 // Add them to the session for now, and Invite them 493 // Add them to the session for now, and Invite them
393 m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); 494 m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID);
394 495
395 UUID toAgentID = new UUID(msg.toAgentID); 496 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null);
396 IClientAPI activeClient = GetActiveClient(toAgentID); 497 if (groupInfo != null)
397 if (activeClient != null)
398 { 498 {
399 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); 499 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message");
400 if (groupInfo != null) 500
401 { 501 // Force? open the group session dialog???
402 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); 502 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
403 503 IEventQueue eq = client.Scene.RequestModuleInterface<IEventQueue>();
404 // Force? open the group session dialog??? 504 eq.ChatterboxInvitation(
405 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); 505 GroupID
406 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>(); 506 , groupInfo.GroupName
407 eq.ChatterboxInvitation( 507 , new UUID(msg.fromAgentID)
408 GroupID 508 , msg.message
409 , groupInfo.GroupName 509 , new UUID(msg.toAgentID)
410 , new UUID(msg.fromAgentID) 510 , msg.fromAgentName
411 , msg.message 511 , msg.dialog
412 , new UUID(msg.toAgentID) 512 , msg.timestamp
413 , msg.fromAgentName 513 , msg.offline == 1
414 , msg.dialog 514 , (int)msg.ParentEstateID
415 , msg.timestamp 515 , msg.Position
416 , msg.offline == 1 516 , 1
417 , (int)msg.ParentEstateID 517 , new UUID(msg.imSessionID)
418 , msg.Position 518 , msg.fromGroup
419 , 1 519 , Utils.StringToBytes(groupInfo.GroupName)
420 , new UUID(msg.imSessionID) 520 );
421 , msg.fromGroup 521
422 , Utils.StringToBytes(groupInfo.GroupName) 522 eq.ChatterBoxSessionAgentListUpdates(
423 ); 523 new UUID(GroupID)
424 524 , new UUID(msg.fromAgentID)
425 eq.ChatterBoxSessionAgentListUpdates( 525 , new UUID(msg.toAgentID)
426 new UUID(GroupID) 526 , false //canVoiceChat
427 , new UUID(msg.fromAgentID) 527 , false //isModerator
428 , new UUID(msg.toAgentID) 528 , false //text mute
429 , false //canVoiceChat 529 );
430 , false //isModerator
431 , false //text mute
432 );
433 }
434 } 530 }
531
532 break;
435 } 533 }
436 else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) 534 else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID))
437 { 535 {
438 // User hasn't dropped, so they're in the session, 536 // User hasn't dropped, so they're in the session,
439 // maybe we should deliver it. 537 // maybe we should deliver it.
440 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); 538 client.SendInstantMessage(msg);
441 if (client != null)
442 {
443 // Deliver locally, directly
444 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name);
445 client.SendInstantMessage(msg);
446 }
447 else
448 {
449 m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
450 }
451 } 539 }
540
452 break; 541 break;
453 542
454 default: 543 default:
455 m_log.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); 544 client.SendInstantMessage(msg);
456 break; 545
546 break;;
457 } 547 }
458 } 548 }
459 549
460 #endregion 550 #endregion
461 551
462
463 #region ClientEvents 552 #region ClientEvents
464 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) 553 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
465 { 554 {
@@ -548,15 +637,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
548 // Don't log any normal IMs (privacy!) 637 // Don't log any normal IMs (privacy!)
549 if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) 638 if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent)
550 { 639 {
551 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); 640 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False");
552 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); 641 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", (InstantMessageDialog)im.dialog);
553 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString()); 642 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID);
554 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName.ToString()); 643 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName);
555 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString()); 644 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID);
556 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message.ToString()); 645 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message);
557 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString()); 646 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline);
558 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString()); 647 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID);
559 m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); 648 m_log.DebugFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
560 } 649 }
561 } 650 }
562 651
@@ -567,7 +656,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
567 /// </summary> 656 /// </summary>
568 private IClientAPI GetActiveClient(UUID agentID) 657 private IClientAPI GetActiveClient(UUID agentID)
569 { 658 {
570 if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); 659 if (m_debugEnabled)
660 m_log.DebugFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID);
571 661
572 IClientAPI child = null; 662 IClientAPI child = null;
573 663
@@ -579,12 +669,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
579 { 669 {
580 if (!sp.IsChildAgent) 670 if (!sp.IsChildAgent)
581 { 671 {
582 if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name); 672 if (m_debugEnabled)
673 m_log.DebugFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name);
674
583 return sp.ControllingClient; 675 return sp.ControllingClient;
584 } 676 }
585 else 677 else
586 { 678 {
587 if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name); 679 if (m_debugEnabled)
680 m_log.DebugFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name);
681
588 child = sp.ControllingClient; 682 child = sp.ControllingClient;
589 } 683 }
590 } 684 }
@@ -593,12 +687,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
593 // If we didn't find a root, then just return whichever child we found, or null if none 687 // If we didn't find a root, then just return whichever child we found, or null if none
594 if (child == null) 688 if (child == null)
595 { 689 {
596 if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); 690 if (m_debugEnabled)
691 m_log.DebugFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID);
597 } 692 }
598 else 693 else
599 { 694 {
600 if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); 695 if (m_debugEnabled)
696 m_log.DebugFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name);
601 } 697 }
698
602 return child; 699 return child;
603 } 700 }
604 701
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 2764465..0512e48 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -77,9 +77,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
77 77
78 private List<Scene> m_sceneList = new List<Scene>(); 78 private List<Scene> m_sceneList = new List<Scene>();
79 79
80 private IMessageTransferModule m_msgTransferModule = null; 80 private IMessageTransferModule m_msgTransferModule;
81
82 private IGroupsMessagingModule m_groupsMessagingModule;
81 83
82 private IGroupsServicesConnector m_groupData = null; 84 private IGroupsServicesConnector m_groupData;
83 85
84 // Configuration settings 86 // Configuration settings
85 private bool m_groupsEnabled = false; 87 private bool m_groupsEnabled = false;
@@ -185,10 +187,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
185 if (m_msgTransferModule == null) 187 if (m_msgTransferModule == null)
186 { 188 {
187 m_groupsEnabled = false; 189 m_groupsEnabled = false;
188 m_log.Warn("[GROUPS]: Could not get MessageTransferModule"); 190 m_log.Warn("[GROUPS]: Could not get IMessageTransferModule");
189 } 191 }
190 } 192 }
191 193
194 if (m_groupsMessagingModule == null)
195 {
196 m_groupsMessagingModule = scene.RequestModuleInterface<IGroupsMessagingModule>();
197
198 // No message transfer module, no notices, group invites, rejects, ejects, etc
199 if (m_groupsMessagingModule == null)
200 m_log.Warn("[GROUPS]: Could not get IGroupsMessagingModule");
201 }
202
192 lock (m_sceneList) 203 lock (m_sceneList)
193 { 204 {
194 m_sceneList.Add(scene); 205 m_sceneList.Add(scene);
@@ -363,7 +374,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
363 374
364 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) 375 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
365 { 376 {
366 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 377 if (m_debugEnabled)
378 m_log.DebugFormat(
379 "[GROUPS]: {0} called for {1}, message type {2}",
380 System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog);
367 381
368 // Group invitations 382 // Group invitations
369 if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) 383 if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
@@ -514,31 +528,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
514 OnNewGroupNotice(GroupID, NoticeID); 528 OnNewGroupNotice(GroupID, NoticeID);
515 } 529 }
516 530
517 // Send notice out to everyone that wants notices 531 if (m_debugEnabled)
518 foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID))
519 { 532 {
520 if (m_debugEnabled) 533 foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID))
521 { 534 {
522 UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); 535 if (m_debugEnabled)
523 if (targetUser != null)
524 { 536 {
525 m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); 537 UserAccount targetUser
526 } 538 = m_sceneList[0].UserAccountService.GetUserAccount(
527 else 539 remoteClient.Scene.RegionInfo.ScopeID, member.AgentID);
528 { 540
529 m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); 541 if (targetUser != null)
542 {
543 m_log.DebugFormat(
544 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
545 NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
546 }
547 else
548 {
549 m_log.DebugFormat(
550 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
551 NoticeID, member.AgentID, member.AcceptNotices);
552 }
530 } 553 }
531 } 554 }
555 }
532 556
533 if (member.AcceptNotices) 557 GridInstantMessage msg
534 { 558 = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
535 // Build notice IM
536 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
537 559
538 msg.toAgentID = member.AgentID.Guid; 560 if (m_groupsMessagingModule != null)
539 OutgoingInstantMessage(msg, member.AgentID); 561 m_groupsMessagingModule.SendMessageToGroup(
540 } 562 msg, GroupID, remoteClient.AgentId, gmd => gmd.AcceptNotices);
541 }
542 } 563 }
543 } 564 }
544 565
@@ -550,6 +571,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
550 571
551 UUID noticeID = new UUID(im.imSessionID); 572 UUID noticeID = new UUID(im.imSessionID);
552 573
574 if (m_debugEnabled)
575 m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId);
576
553 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); 577 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
554 if (notice != null) 578 if (notice != null)
555 { 579 {
@@ -559,17 +583,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
559 if (m_debugEnabled) 583 if (m_debugEnabled)
560 m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); 584 m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
561 585
586 string message;
562 InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, 587 InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
563 giver, attachmentUUID); 588 giver, attachmentUUID, out message);
564 589
565 if (itemCopy == null) 590 if (itemCopy == null)
566 { 591 {
567 remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); 592 remoteClient.SendAgentAlertMessage(message, false);
568 return; 593 return;
569 } 594 }
570 595
571 remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); 596 remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
572 } 597 }
598 else
599 {
600 if (m_debugEnabled)
601 m_log.DebugFormat(
602 "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
603 noticeID, remoteClient.AgentId);
604 }
573 } 605 }
574 606
575 // Interop, received special 210 code for ejecting a group member 607 // Interop, received special 210 code for ejecting a group member
@@ -1366,7 +1398,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1366 presence.Grouptitle = Title; 1398 presence.Grouptitle = Title;
1367 1399
1368 if (! presence.IsChildAgent) 1400 if (! presence.IsChildAgent)
1369 presence.SendAvatarDataToAllAgents(); 1401 presence.SendAvatarDataToAllClients();
1370 } 1402 }
1371 } 1403 }
1372 } 1404 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index 26d2597..e03e71d 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Net; 31using System.Net;
31using System.Reflection; 32using System.Reflection;
32using Nini.Config; 33using Nini.Config;
@@ -40,11 +41,11 @@ using OpenSim.Framework.Communications;
40using OpenSim.Framework.Servers; 41using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer; 42using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.ClientStack.Linden; 43using OpenSim.Region.ClientStack.Linden;
44using OpenSim.Region.CoreModules.Avatar.InstantMessage;
43using OpenSim.Region.CoreModules.Framework; 45using OpenSim.Region.CoreModules.Framework;
44using OpenSim.Region.Framework.Scenes; 46using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 47using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
46using OpenSim.Tests.Common; 48using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48 49
49namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests 50namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
50{ 51{
@@ -118,5 +119,150 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
118 119
119 // TODO: More checking of more actual event data. 120 // TODO: More checking of more actual event data.
120 } 121 }
122
123 [Test]
124 public void TestSendGroupNotice()
125 {
126 TestHelpers.InMethod();
127// TestHelpers.EnableLogging();
128
129 TestScene scene = new SceneHelpers().SetupScene();
130
131 MessageTransferModule mtm = new MessageTransferModule();
132 GroupsModule gm = new GroupsModule();
133 GroupsMessagingModule gmm = new GroupsMessagingModule();
134 MockGroupsServicesConnector mgsc = new MockGroupsServicesConnector();
135
136 IConfigSource configSource = new IniConfigSource();
137
138 {
139 IConfig config = configSource.AddConfig("Messaging");
140 config.Set("MessageTransferModule", mtm.Name);
141 }
142
143 {
144 IConfig config = configSource.AddConfig("Groups");
145 config.Set("Enabled", true);
146 config.Set("Module", gm.Name);
147 config.Set("DebugEnabled", true);
148 config.Set("MessagingModule", gmm.Name);
149 config.Set("MessagingEnabled", true);
150 }
151
152 SceneHelpers.SetupSceneModules(scene, configSource, mgsc, mtm, gm, gmm);
153
154 UUID userId = TestHelpers.ParseTail(0x1);
155 string subjectText = "newman";
156 string messageText = "Hello";
157 string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText);
158
159 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
160 TestClient tc = (TestClient)sp.ControllingClient;
161
162 UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true);
163 gm.JoinGroupRequest(tc, groupID);
164
165 // Create a second user who doesn't want to receive notices
166 ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2));
167 TestClient tc2 = (TestClient)sp2.ControllingClient;
168 gm.JoinGroupRequest(tc2, groupID);
169 gm.SetGroupAcceptNotices(tc2, groupID, false, true);
170
171 List<GridInstantMessage> spReceivedMessages = new List<GridInstantMessage>();
172 tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im);
173
174 List<GridInstantMessage> sp2ReceivedMessages = new List<GridInstantMessage>();
175 tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im);
176
177 GridInstantMessage noticeIm = new GridInstantMessage();
178 noticeIm.fromAgentID = userId.Guid;
179 noticeIm.toAgentID = groupID.Guid;
180 noticeIm.message = combinedSubjectMessage;
181 noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice;
182
183 tc.HandleImprovedInstantMessage(noticeIm);
184
185 Assert.That(spReceivedMessages.Count, Is.EqualTo(1));
186 Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage));
187
188 List<GroupNoticeData> notices = mgsc.GetGroupNotices(UUID.Zero, groupID);
189 Assert.AreEqual(1, notices.Count);
190
191 // OpenSimulator (possibly also SL) transport the notice ID as the session ID!
192 Assert.AreEqual(notices[0].NoticeID.Guid, spReceivedMessages[0].imSessionID);
193
194 Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0));
195 }
196
197 /// <summary>
198 /// Run test with the MessageOnlineUsersOnly flag set.
199 /// </summary>
200 [Test]
201 public void TestSendGroupNoticeOnlineOnly()
202 {
203 TestHelpers.InMethod();
204 // TestHelpers.EnableLogging();
205
206 TestScene scene = new SceneHelpers().SetupScene();
207
208 MessageTransferModule mtm = new MessageTransferModule();
209 GroupsModule gm = new GroupsModule();
210 GroupsMessagingModule gmm = new GroupsMessagingModule();
211
212 IConfigSource configSource = new IniConfigSource();
213
214 {
215 IConfig config = configSource.AddConfig("Messaging");
216 config.Set("MessageTransferModule", mtm.Name);
217 }
218
219 {
220 IConfig config = configSource.AddConfig("Groups");
221 config.Set("Enabled", true);
222 config.Set("Module", gm.Name);
223 config.Set("DebugEnabled", true);
224 config.Set("MessagingModule", gmm.Name);
225 config.Set("MessagingEnabled", true);
226 config.Set("MessageOnlineUsersOnly", true);
227 }
228
229 SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm);
230
231 UUID userId = TestHelpers.ParseTail(0x1);
232 string subjectText = "newman";
233 string messageText = "Hello";
234 string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText);
235
236 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
237 TestClient tc = (TestClient)sp.ControllingClient;
238
239 UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true);
240 gm.JoinGroupRequest(tc, groupID);
241
242 // Create a second user who doesn't want to receive notices
243 ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2));
244 TestClient tc2 = (TestClient)sp2.ControllingClient;
245 gm.JoinGroupRequest(tc2, groupID);
246 gm.SetGroupAcceptNotices(tc2, groupID, false, true);
247
248 List<GridInstantMessage> spReceivedMessages = new List<GridInstantMessage>();
249 tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im);
250
251 List<GridInstantMessage> sp2ReceivedMessages = new List<GridInstantMessage>();
252 tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im);
253
254 GridInstantMessage noticeIm = new GridInstantMessage();
255 noticeIm.fromAgentID = userId.Guid;
256 noticeIm.toAgentID = groupID.Guid;
257 noticeIm.message = combinedSubjectMessage;
258 noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice;
259
260 tc.HandleImprovedInstantMessage(noticeIm);
261
262 Assert.That(spReceivedMessages.Count, Is.EqualTo(1));
263 Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage));
264
265 Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0));
266 }
121 } 267 }
122} \ No newline at end of file 268} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index e28d0c2..a040f43 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -1012,7 +1012,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1012 Hashtable respData = (Hashtable)resp.Value; 1012 Hashtable respData = (Hashtable)resp.Value;
1013 if (respData.Contains("error") && !respData.Contains("succeed")) 1013 if (respData.Contains("error") && !respData.Contains("succeed"))
1014 { 1014 {
1015 LogRespDataToConsoleError(respData); 1015 LogRespDataToConsoleError(requestingAgentID, function, param, respData);
1016 } 1016 }
1017 1017
1018 return respData; 1018 return respData;
@@ -1040,20 +1040,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1040 return error; 1040 return error;
1041 } 1041 }
1042 1042
1043 private void LogRespDataToConsoleError(Hashtable respData) 1043 private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData)
1044 { 1044 {
1045 m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); 1045 m_log.ErrorFormat(
1046 1046 "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}",
1047 foreach (string key in respData.Keys) 1047 function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData));
1048 {
1049 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key);
1050
1051 string[] lines = respData[key].ToString().Split(new char[] { '\n' });
1052 foreach (string line in lines)
1053 {
1054 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line);
1055 }
1056 }
1057 } 1048 }
1058 1049
1059 /// <summary> 1050 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
index 0615036..bbf7168 100644
--- a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
+++ b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
@@ -37,7 +37,7 @@ using OpenSim.Region.Framework.Scenes;
37// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans 37// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans
38// the available DLLs 38// the available DLLs
39//[assembly: Addin("MyModule", "1.0")] 39//[assembly: Addin("MyModule", "1.0")]
40//[assembly: AddinDependency("OpenSim", "0.5")] 40//[assembly: AddinDependency("OpenSim", "0.8.1")]
41 41
42namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared 42namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared
43{ 43{
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
index 811a263..46fea3e 100644
--- a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
+++ b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
@@ -37,7 +37,7 @@ using OpenSim.Region.Framework.Scenes;
37// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans 37// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans
38// the available DLLs 38// the available DLLs
39//[assembly: Addin("MyModule", "1.0")] 39//[assembly: Addin("MyModule", "1.0")]
40//[assembly: AddinDependency("OpenSim", "0.5")] 40//[assembly: AddinDependency("OpenSim", "0.8.1")]
41 41
42namespace OpenSim.Region.OptionalModules.Example.BareBonesShared 42namespace OpenSim.Region.OptionalModules.Example.BareBonesShared
43{ 43{
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
index afb788b..e95889d 100644
--- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
+++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
@@ -50,7 +50,7 @@ using Ionic.Zlib;
50// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans 50// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans
51// the available DLLs 51// the available DLLs
52//[assembly: Addin("MaterialsModule", "1.0")] 52//[assembly: Addin("MaterialsModule", "1.0")]
53//[assembly: AddinDependency("OpenSim", "0.5")] 53//[assembly: AddinDependency("OpenSim", "0.8.1")]
54 54
55namespace OpenSim.Region.OptionalModules.Materials 55namespace OpenSim.Region.OptionalModules.Materials
56{ 56{
@@ -65,20 +65,23 @@ namespace OpenSim.Region.OptionalModules.Materials
65 65
66 private Scene m_scene = null; 66 private Scene m_scene = null;
67 private bool m_enabled = false; 67 private bool m_enabled = false;
68 private int m_maxMaterialsPerTransaction = 50;
68 69
69 public Dictionary<UUID, OSDMap> m_regionMaterials = new Dictionary<UUID, OSDMap>(); 70 public Dictionary<UUID, OSDMap> m_regionMaterials = new Dictionary<UUID, OSDMap>();
70 71
71 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
72 { 73 {
73 IConfig config = source.Configs["Materials"]; 74 m_enabled = true; // default is enabled
74 if (config == null)
75 return;
76 75
77 m_enabled = config.GetBoolean("enable_materials", true); 76 IConfig config = source.Configs["Materials"];
78 if (!m_enabled) 77 if (config != null)
79 return; 78 {
79 m_enabled = config.GetBoolean("enable_materials", m_enabled);
80 m_maxMaterialsPerTransaction = config.GetInt("MaxMaterialsPerTransaction", m_maxMaterialsPerTransaction);
81 }
80 82
81 m_log.DebugFormat("[Materials]: Initialized"); 83 if (m_enabled)
84 m_log.DebugFormat("[Materials]: Initialized");
82 } 85 }
83 86
84 public void Close() 87 public void Close()
@@ -146,6 +149,16 @@ namespace OpenSim.Region.OptionalModules.Materials
146 149
147 public void RegionLoaded(Scene scene) 150 public void RegionLoaded(Scene scene)
148 { 151 {
152 if (!m_enabled) return;
153
154 ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>();
155 if (featuresModule != null)
156 featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
157 }
158
159 private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
160 {
161 features["MaxMaterialsPerTransaction"] = m_maxMaterialsPerTransaction;
149 } 162 }
150 163
151 /// <summary> 164 /// <summary>
@@ -216,7 +229,12 @@ namespace OpenSim.Region.OptionalModules.Materials
216 229
217 GetLegacyStoredMaterialsInPart(part); 230 GetLegacyStoredMaterialsInPart(part);
218 231
219 GetStoredMaterialInFace(part, te.DefaultTexture); 232 if (te.DefaultTexture != null)
233 GetStoredMaterialInFace(part, te.DefaultTexture);
234 else
235 m_log.WarnFormat(
236 "[Materials]: Default texture for part {0} (part of object {1}) in {2} unexpectedly null. Ignoring.",
237 part.Name, part.ParentGroup.Name, m_scene.Name);
220 238
221 foreach (Primitive.TextureEntryFace face in te.FaceTextures) 239 foreach (Primitive.TextureEntryFace face in te.FaceTextures)
222 { 240 {
diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
index 0bf23f1..d3c46c9 100644
--- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
+++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
@@ -26,8 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
30using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
31using log4net; 32using log4net;
32using Mono.Addins; 33using Mono.Addins;
33using Nini.Config; 34using Nini.Config;
@@ -57,12 +58,10 @@ namespace OpenSim.Region.OptionalModules
57 58
58 public void Initialise(IConfigSource config) 59 public void Initialise(IConfigSource config)
59 { 60 {
60 //IConfig myConfig = config.Configs["Startup"];
61
62 string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules", 61 string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules",
63 new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); 62 new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
64 63
65 List<string> modules=new List<string>(permissionModules.Split(',')); 64 List<string> modules = new List<string>(permissionModules.Split(',').Select(m => m.Trim()));
66 65
67 if(!modules.Contains("PrimLimitsModule")) 66 if(!modules.Contains("PrimLimitsModule"))
68 return; 67 return;
@@ -103,20 +102,34 @@ namespace OpenSim.Region.OptionalModules
103 public void RegionLoaded(Scene scene) 102 public void RegionLoaded(Scene scene)
104 { 103 {
105 m_dialogModule = scene.RequestModuleInterface<IDialogModule>(); 104 m_dialogModule = scene.RequestModuleInterface<IDialogModule>();
106 } 105 }
107 106
108 private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) 107 private bool CanRezObject(int objectCount, UUID ownerID, Vector3 objectPosition, Scene scene)
109 { 108 {
110 ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); 109 ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y);
111 int usedPrims = lo.PrimCounts.Total;
112 int simulatorCapacity = lo.GetSimulatorMaxPrimCount();
113 110
114 if (objectCount + usedPrims > simulatorCapacity) 111 string response = DoCommonChecks(objectCount, ownerID, lo, scene);
112
113 if (response != null)
115 { 114 {
116 m_dialogModule.SendAlertToUser(owner, "Unable to rez object because the parcel is too full"); 115 m_dialogModule.SendAlertToUser(ownerID, response);
117 return false; 116 return false;
118 } 117 }
118 return true;
119 }
119 120
121 //OnDuplicateObject
122 private bool CanDuplicateObject(int objectCount, UUID objectID, UUID ownerID, Scene scene, Vector3 objectPosition)
123 {
124 ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y);
125
126 string response = DoCommonChecks(objectCount, ownerID, lo, scene);
127
128 if (response != null)
129 {
130 m_dialogModule.SendAlertToUser(ownerID, response);
131 return false;
132 }
120 return true; 133 return true;
121 } 134 }
122 135
@@ -140,6 +153,14 @@ namespace OpenSim.Region.OptionalModules
140 153
141 ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); 154 ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y);
142 155
156<<<<<<< HEAD
157 // newParcel will be null only if it outside of our current region. If this is the case, then the
158 // receiving permissions will perform the check.
159 if (newParcel == null)
160 return true;
161
162 // The prim hasn't crossed a region boundary so we don't need to worry
163=======
143 if (newParcel == null) 164 if (newParcel == null)
144 return true; 165 return true;
145 166
@@ -147,6 +168,7 @@ namespace OpenSim.Region.OptionalModules
147 ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); 168 ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y);
148 169
149 // The prim hasn't crossed a region boundry so we don't need to worry 170 // The prim hasn't crossed a region boundry so we don't need to worry
171>>>>>>> avn/ubitvar
150 // about prim counts here 172 // about prim counts here
151 if(oldParcel != null && oldParcel.Equals(newParcel)) 173 if(oldParcel != null && oldParcel.Equals(newParcel))
152 { 174 {
@@ -158,30 +180,53 @@ namespace OpenSim.Region.OptionalModules
158 int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); 180 int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount();
159 181
160 // TODO: Add Special Case here for temporary prims 182 // TODO: Add Special Case here for temporary prims
161 183
162 if(objectCount + usedPrims > simulatorCapacity) 184 string response = DoCommonChecks(objectCount, obj.OwnerID, newParcel, scene);
185
186 if (response != null)
163 { 187 {
164 m_dialogModule.SendAlertToUser(obj.OwnerID, "Unable to move object because the destination parcel is too full"); 188 m_dialogModule.SendAlertToUser(obj.OwnerID, response);
165 return false; 189 return false;
166 } 190 }
167
168 return true; 191 return true;
169 } 192 }
170 193
171 //OnDuplicateObject 194 private string DoCommonChecks(int objectCount, UUID ownerID, ILandObject lo, Scene scene)
172 private bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition)
173 { 195 {
174 ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); 196 string response = null;
175 int usedPrims = lo.PrimCounts.Total;
176 int simulatorCapacity = lo.GetSimulatorMaxPrimCount();
177 197
178 if(objectCount + usedPrims > simulatorCapacity) 198 int simulatorCapacity = lo.GetSimulatorMaxPrimCount();
199 if ((objectCount + lo.PrimCounts.Total) > simulatorCapacity)
179 { 200 {
180 m_dialogModule.SendAlertToUser(owner, "Unable to duplicate object because the parcel is too full"); 201 response = "Unable to rez object because the parcel is too full";
181 return false;
182 } 202 }
183 203 else
184 return true; 204 {
205 int maxPrimsPerUser = scene.RegionInfo.MaxPrimsPerUser;
206 if (maxPrimsPerUser >= 0)
207 {
208 // per-user prim limit is set
209 if (ownerID != lo.LandData.OwnerID || lo.LandData.IsGroupOwned)
210 {
211 // caller is not the sole Parcel owner
212 EstateSettings estateSettings = scene.RegionInfo.EstateSettings;
213 if (ownerID != estateSettings.EstateOwner)
214 {
215 // caller is NOT the Estate owner
216 List<UUID> mgrs = new List<UUID>(estateSettings.EstateManagers);
217 if (!mgrs.Contains(ownerID))
218 {
219 // caller is not an Estate Manager
220 if ((lo.PrimCounts.Users[ownerID] + objectCount) > maxPrimsPerUser)
221 {
222 response = "Unable to rez object because you have reached your limit";
223 }
224 }
225 }
226 }
227 }
228 }
229 return response;
185 } 230 }
186 } 231 }
187} 232}
diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs
index ba0b578..f8ad958 100644
--- a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs
@@ -30,8 +30,8 @@ using Mono.Addins;
30// Build Number 30// Build Number
31// Revision 31// Revision
32// 32//
33[assembly: AssemblyVersion("0.8.0.*")] 33[assembly: AssemblyVersion("0.8.2.*")]
34 34
35 35
36[assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] 36[assembly: Addin("OpenSim.Region.OptionalModules", OpenSim.VersionInfo.VersionNumber)]
37[assembly: AddinDependency("OpenSim", "0.5")] 37[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index 9daf9d7..ff4afbf 100755
--- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -66,6 +66,7 @@ public class ExtendedPhysics : INonSharedRegionModule
66 public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType"; 66 public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType";
67 public const string PhysFunctGetLinkType = "BulletSim.GetLinkType"; 67 public const string PhysFunctGetLinkType = "BulletSim.GetLinkType";
68 public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; 68 public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams";
69 public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits";
69 70
70 // ============================================================= 71 // =============================================================
71 72
@@ -176,6 +177,71 @@ public class ExtendedPhysics : INonSharedRegionModule
176 return ret; 177 return ret;
177 } 178 }
178 179
180 // Code for specifying params.
181 // The choice if 14700 is arbitrary and only serves to catch parameter code misuse.
182 [ScriptConstant]
183 public const int PHYS_AXIS_LOCK_LINEAR = 14700;
184 [ScriptConstant]
185 public const int PHYS_AXIS_LOCK_LINEAR_X = 14701;
186 [ScriptConstant]
187 public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702;
188 [ScriptConstant]
189 public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703;
190 [ScriptConstant]
191 public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704;
192 [ScriptConstant]
193 public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705;
194 [ScriptConstant]
195 public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706;
196 [ScriptConstant]
197 public const int PHYS_AXIS_LOCK_ANGULAR = 14707;
198 [ScriptConstant]
199 public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708;
200 [ScriptConstant]
201 public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709;
202 [ScriptConstant]
203 public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710;
204 [ScriptConstant]
205 public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711;
206 [ScriptConstant]
207 public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712;
208 [ScriptConstant]
209 public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713;
210 [ScriptConstant]
211 public const int PHYS_AXIS_UNLOCK_LINEAR = 14714;
212 [ScriptConstant]
213 public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715;
214 [ScriptConstant]
215 public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716;
216 [ScriptConstant]
217 public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717;
218 [ScriptConstant]
219 public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718;
220 [ScriptConstant]
221 public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719;
222 [ScriptConstant]
223 public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720;
224 [ScriptConstant]
225 public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721;
226 [ScriptConstant]
227 public const int PHYS_AXIS_UNLOCK = 14722;
228 // physAxisLockLimits()
229 [ScriptInvocation]
230 public int physAxisLock(UUID hostID, UUID scriptID, object[] parms)
231 {
232 int ret = -1;
233 if (!Enabled) return ret;
234
235 PhysicsActor rootPhysActor;
236 if (GetRootPhysActor(hostID, out rootPhysActor))
237 {
238 object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms);
239 ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2));
240 }
241
242 return ret;
243 }
244
179 [ScriptConstant] 245 [ScriptConstant]
180 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0; 246 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
181 [ScriptConstant] 247 [ScriptConstant]
@@ -187,7 +253,6 @@ public class ExtendedPhysics : INonSharedRegionModule
187 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) 253 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
188 { 254 {
189 int ret = -1; 255 int ret = -1;
190
191 if (!Enabled) return ret; 256 if (!Enabled) return ret;
192 257
193 // The part that is requesting the change. 258 // The part that is requesting the change.
@@ -259,34 +324,11 @@ public class ExtendedPhysics : INonSharedRegionModule
259 int ret = -1; 324 int ret = -1;
260 if (!Enabled) return ret; 325 if (!Enabled) return ret;
261 326
262 // The part that is requesting the change. 327 PhysicsActor rootPhysActor;
263 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); 328 if (GetRootPhysActor(hostID, out rootPhysActor))
264
265 if (requestingPart != null)
266 { 329 {
267 // The type is is always on the root of a linkset. 330 object[] parms2 = { rootPhysActor, null };
268 SceneObjectGroup containingGroup = requestingPart.ParentGroup; 331 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
269 SceneObjectPart rootPart = containingGroup.RootPart;
270
271 if (rootPart != null)
272 {
273 PhysicsActor rootPhysActor = rootPart.PhysActor;
274 if (rootPhysActor != null)
275 {
276 object[] parms2 = { rootPhysActor, null };
277 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
278 }
279 else
280 {
281 m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
282 LogHeader, rootPart.Name, hostID);
283 }
284 }
285 else
286 {
287 m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
288 LogHeader, requestingPart.Name, hostID);
289 }
290 } 332 }
291 else 333 else
292 { 334 {
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
index e498c6a..c38bb3e 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -276,7 +276,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
276 { 276 {
277 ovalue = OSDParser.DeserializeJson(value); 277 ovalue = OSDParser.DeserializeJson(value);
278 } 278 }
279 catch (Exception e) 279 catch (Exception)
280 { 280 {
281 if (value.StartsWith("'") && value.EndsWith("'")) 281 if (value.StartsWith("'") && value.EndsWith("'"))
282 { 282 {
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index b502a55..26044f0 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -262,7 +262,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
262 { 262 {
263 map = new JsonStore(value); 263 map = new JsonStore(value);
264 } 264 }
265 catch (Exception e) 265 catch (Exception)
266 { 266 {
267 m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value); 267 m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value);
268 return false; 268 return false;
@@ -285,8 +285,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
285 285
286 lock (m_JsonValueStore) 286 lock (m_JsonValueStore)
287 return m_JsonValueStore.Remove(storeID); 287 return m_JsonValueStore.Remove(storeID);
288
289 return true;
290 } 288 }
291 289
292 // ----------------------------------------------------------------- 290 // -----------------------------------------------------------------
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 9fbfb66..edf51a2 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -320,10 +320,25 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
320 /// </summary> 320 /// </summary>
321 // ----------------------------------------------------------------- 321 // -----------------------------------------------------------------
322 [ScriptInvocation] 322 [ScriptInvocation]
323 public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param)
324 {
325 UUID reqID = UUID.Random();
326 Util.FireAndForget(
327 o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param), null, "JsonStoreScriptModule.DoJsonRezObject");
328 return reqID;
329 }
330
331 // -----------------------------------------------------------------
332 /// <summary>
333 ///
334 /// </summary>
335 // -----------------------------------------------------------------
336 [ScriptInvocation]
323 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) 337 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
324 { 338 {
325 UUID reqID = UUID.Random(); 339 UUID reqID = UUID.Random();
326 Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier)); 340 Util.FireAndForget(
341 o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier), null, "JsonStoreScriptModule.JsonReadNotecard");
327 return reqID; 342 return reqID;
328 } 343 }
329 344
@@ -336,7 +351,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
336 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) 351 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
337 { 352 {
338 UUID reqID = UUID.Random(); 353 UUID reqID = UUID.Random();
339 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); 354 Util.FireAndForget(
355 o => DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name), null, "JsonStoreScriptModule.DoJsonWriteNotecard");
340 return reqID; 356 return reqID;
341 } 357 }
342 358
@@ -451,7 +467,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
451 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) 467 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
452 { 468 {
453 UUID reqID = UUID.Random(); 469 UUID reqID = UUID.Random();
454 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); 470 Util.FireAndForget(
471 o => DoJsonTakeValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonTakeValue");
455 return reqID; 472 return reqID;
456 } 473 }
457 474
@@ -459,7 +476,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
459 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 476 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
460 { 477 {
461 UUID reqID = UUID.Random(); 478 UUID reqID = UUID.Random();
462 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); 479 Util.FireAndForget(
480 o => DoJsonTakeValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonTakeValueJson");
463 return reqID; 481 return reqID;
464 } 482 }
465 483
@@ -472,7 +490,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
472 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) 490 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
473 { 491 {
474 UUID reqID = UUID.Random(); 492 UUID reqID = UUID.Random();
475 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); 493 Util.FireAndForget(
494 o => DoJsonReadValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonReadValue");
476 return reqID; 495 return reqID;
477 } 496 }
478 497
@@ -480,7 +499,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
480 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 499 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
481 { 500 {
482 UUID reqID = UUID.Random(); 501 UUID reqID = UUID.Random();
483 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); 502 Util.FireAndForget(
503 o => DoJsonReadValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonReadValueJson");
484 return reqID; 504 return reqID;
485 } 505 }
486 506
@@ -575,11 +595,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
575 595
576 try 596 try
577 { 597 {
578 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 598 string jsondata = SLUtil.ParseNotecardToString(a.Data);
579 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; 599 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
580 m_comms.DispatchReply(scriptID, result, "", reqID.ToString()); 600 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
581 return; 601 return;
582 } 602 }
603 catch(SLUtil.NotANotecardFormatException e)
604 {
605 m_log.WarnFormat("[JsonStoreScripts]: Notecard parsing failed; assetId {0} at line number {1}", assetID.ToString(), e.lineNumber);
606 }
583 catch (Exception e) 607 catch (Exception e)
584 { 608 {
585 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message); 609 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
@@ -682,5 +706,103 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
682 return path; 706 return path;
683 } 707 }
684 708
709 // -----------------------------------------------------------------
710 /// <summary>
711 ///
712 /// </summary>
713 // -----------------------------------------------------------------
714 private void DoJsonRezObject(UUID hostID, UUID scriptID, UUID reqID, string name, Vector3 pos, Vector3 vel, Quaternion rot, string param)
715 {
716 if (Double.IsNaN(rot.X) || Double.IsNaN(rot.Y) || Double.IsNaN(rot.Z) || Double.IsNaN(rot.W))
717 {
718 GenerateRuntimeError("Invalid rez rotation");
719 return;
720 }
721
722 SceneObjectGroup host = m_scene.GetSceneObjectGroup(hostID);
723 if (host == null)
724 {
725 GenerateRuntimeError(String.Format("Unable to find rezzing host '{0}'",hostID));
726 return;
727 }
728
729 // hpos = host.RootPart.GetWorldPosition()
730 // float dist = (float)llVecDist(hpos, pos);
731 // if (dist > m_ScriptDistanceFactor * 10.0f)
732 // return;
733
734 TaskInventoryItem item = host.RootPart.Inventory.GetInventoryItem(name);
735 if (item == null)
736 {
737 GenerateRuntimeError(String.Format("Unable to find object to rez '{0}'",name));
738 return;
739 }
740
741 if (item.InvType != (int)InventoryType.Object)
742 {
743 GenerateRuntimeError("Can't create requested object; object is missing from database");
744 return;
745 }
746
747 List<SceneObjectGroup> objlist;
748 List<Vector3> veclist;
749
750 bool success = host.RootPart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist);
751 if (! success)
752 {
753 GenerateRuntimeError("Failed to create object");
754 return;
755 }
756
757 int totalPrims = 0;
758 foreach (SceneObjectGroup group in objlist)
759 totalPrims += group.PrimCount;
760
761 if (! m_scene.Permissions.CanRezObject(totalPrims, item.OwnerID, pos))
762 {
763 GenerateRuntimeError("Not allowed to create the object");
764 return;
765 }
766
767 if (! m_scene.Permissions.BypassPermissions())
768 {
769 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
770 host.RootPart.Inventory.RemoveInventoryItem(item.ItemID);
771 }
772
773 for (int i = 0; i < objlist.Count; i++)
774 {
775 SceneObjectGroup group = objlist[i];
776 Vector3 curpos = pos + veclist[i];
777
778 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
779 {
780 group.RootPart.AttachedPos = group.AbsolutePosition;
781 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
782 }
783
784 group.FromPartID = host.RootPart.UUID;
785 m_scene.AddNewSceneObject(group, true, curpos, rot, vel);
786
787 UUID storeID = group.UUID;
788 if (! m_store.CreateStore(param, ref storeID))
789 {
790 GenerateRuntimeError("Unable to create jsonstore for new object");
791 continue;
792 }
793
794 // We can only call this after adding the scene object, since the scene object references the scene
795 // to find out if scripts should be activated at all.
796 group.RootPart.SetDieAtEdge(true);
797 group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3);
798 group.ResumeScripts();
799
800 group.ScheduleGroupForFullUpdate();
801
802 // send the reply back to the host object, use the integer param to indicate the number
803 // of remaining objects
804 m_comms.DispatchReply(scriptID, objlist.Count-i-1, group.RootPart.UUID.ToString(), reqID.ToString());
805 }
806 }
685 } 807 }
686} 808}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index bfa9937..99a7076 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api; 40using OpenSim.Region.ScriptEngine.Shared.Api;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests 44namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
46{ 45{
@@ -465,13 +464,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
465 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); 464 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
466 } 465 }
467 466
468 // Test for non-existant path 467 // Test for non-existent path
469 { 468 {
470 int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo"); 469 int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo");
471 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); 470 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
472 } 471 }
473 472
474 // Test for non-existant store 473 // Test for non-existent store
475 { 474 {
476 UUID fakeStoreId = TestHelpers.ParseTail(0x500); 475 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
477 int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, "."); 476 int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, ".");
@@ -898,4 +897,4 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
898 897
899 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } 898 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
900 } 899 }
901} \ No newline at end of file 900}
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
index 6fb28e2..4bafe2f 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
@@ -180,6 +180,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
180 /// * Internet 180 /// * Internet
181 /// * Everything 181 /// * Everything
182 /// </remarks> 182 /// </remarks>
183#pragma warning disable 0618
183 public static AppDomain CreateRestrictedDomain(string permissionSetName, string appDomainName) 184 public static AppDomain CreateRestrictedDomain(string permissionSetName, string appDomainName)
184 { 185 {
185 if (permissionSetName == null) 186 if (permissionSetName == null)
@@ -240,6 +241,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
240 241
241 return restrictedDomain; 242 return restrictedDomain;
242 } 243 }
244#pragma warning restore 0618
243 245
244 246
245 void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) 247 void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource)
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index 296ab87..870c0bb 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -105,8 +105,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
105 m_scene.LoginLock = true; 105 m_scene.LoginLock = true;
106 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; 106 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
107 107
108 // Warn level because the region cannot be used while logins are disabled 108 // This should always show up to the user but should not trigger warn/errors as these messages are
109 m_log.WarnFormat("[RegionReady]: Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name); 109 // expected and are not simulator problems. Ideally, there would be a status level in log4net but
110 // failing that, we will print out to console instead.
111 MainConsole.Instance.OutputFormat("Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name);
110 112
111 if (m_uri != string.Empty) 113 if (m_uri != string.Empty)
112 { 114 {
@@ -304,7 +306,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
304 finally 306 finally
305 { 307 {
306 if (os != null) 308 if (os != null)
307 os.Close(); 309 os.Dispose();
308 } 310 }
309 } 311 }
310 } 312 }
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs
new file mode 100644
index 0000000..7ae4223
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/CameraOnlyModeModule.cs
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Reflection;
31using System.Text;
32using System.Collections.Generic;
33using System.Threading;
34
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim;
38using OpenSim.Region;
39using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Framework;
43//using OpenSim.Framework.Capabilities;
44using OpenSim.Framework.Servers;
45using OpenSim.Framework.Servers.HttpServer;
46using Nini.Config;
47using log4net;
48using Mono.Addins;
49using OSDMap = OpenMetaverse.StructuredData.OSDMap;
50using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
51
52namespace OpenSim.Region.OptionalModules.ViewerSupport
53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CameraOnlyMode")]
55 public class CameraOnlyModeModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58
59 private Scene m_scene;
60 private SimulatorFeaturesHelper m_Helper;
61 private bool m_Enabled;
62 private int m_UserLevel;
63
64 public string Name
65 {
66 get { return "CameraOnlyModeModule"; }
67 }
68
69 public Type ReplaceableInterface
70 {
71 get { return null; }
72 }
73
74 public void Initialise(IConfigSource config)
75 {
76 IConfig moduleConfig = config.Configs["CameraOnlyModeModule"];
77 if (moduleConfig != null)
78 {
79 m_Enabled = moduleConfig.GetBoolean("enabled", false);
80 if (m_Enabled)
81 {
82 m_UserLevel = moduleConfig.GetInt("UserLevel", 0);
83 m_log.Info("[CAMERA-ONLY MODE]: CameraOnlyModeModule enabled");
84 }
85
86 }
87 }
88
89 public void Close()
90 {
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 if (m_Enabled)
96 {
97 m_scene = scene;
98 //m_scene.EventManager.OnMakeRootAgent += (OnMakeRootAgent);
99 }
100 }
101
102 //private void OnMakeRootAgent(ScenePresence obj)
103 //{
104 // throw new NotImplementedException();
105 //}
106
107 public void RegionLoaded(Scene scene)
108 {
109 if (m_Enabled)
110 {
111 IEntityTransferModule et = m_scene.RequestModuleInterface<IEntityTransferModule>();
112 m_Helper = new SimulatorFeaturesHelper(scene, et);
113
114 ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface<ISimulatorFeaturesModule>();
115 if (featuresModule != null)
116 featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
117 }
118 }
119
120 public void RemoveRegion(Scene scene)
121 {
122 }
123
124 private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
125 {
126 m_log.DebugFormat("[CAMERA-ONLY MODE]: OnSimulatorFeaturesRequest in {0}", m_scene.RegionInfo.RegionName);
127 if (m_Helper.ShouldSend(agentID) && m_Helper.UserLevel(agentID) <= m_UserLevel)
128 {
129 OSDMap extrasMap;
130 if (features.ContainsKey("OpenSimExtras"))
131 {
132 extrasMap = (OSDMap)features["OpenSimExtras"];
133 }
134 else
135 {
136 extrasMap = new OSDMap();
137 features["OpenSimExtras"] = extrasMap;
138 }
139 extrasMap["camera-only-mode"] = OSDMap.FromString("true");
140 m_log.DebugFormat("[CAMERA-ONLY MODE]: Sent in {0}", m_scene.RegionInfo.RegionName);
141
142 // Detaching attachments doesn't work for HG visitors,
143 // so I'm giving that up.
144 //Util.FireAndForget(delegate { DetachAttachments(agentID); });
145 }
146 else
147 m_log.DebugFormat("[CAMERA-ONLY MODE]: NOT Sending camera-only-mode in {0}", m_scene.RegionInfo.RegionName);
148 }
149
150 private void DetachAttachments(UUID agentID)
151 {
152 ScenePresence sp = m_scene.GetScenePresence(agentID);
153 if ((sp.TeleportFlags & TeleportFlags.ViaLogin) != 0)
154 // Wait a little, cos there's weird stuff going on at login related to
155 // the Current Outfit Folder
156 Thread.Sleep(8000);
157
158 if (sp != null && m_scene.AttachmentsModule != null)
159 {
160 List<SceneObjectGroup> attachs = sp.GetAttachments();
161 if (attachs != null && attachs.Count > 0)
162 {
163 foreach (SceneObjectGroup sog in attachs)
164 {
165 m_log.DebugFormat("[CAMERA-ONLY MODE]: Forcibly detaching attach {0} from {1} in {2}",
166 sog.Name, sp.Name, m_scene.RegionInfo.RegionName);
167
168 m_scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, sog);
169 }
170 }
171 }
172 }
173
174 }
175
176}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
index 3b3b300..fcf5e91 100644
--- a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
@@ -276,7 +276,8 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport
276 for (int i = 0 ; i < selection.Count ; i++) 276 for (int i = 0 ; i < selection.Count ; i++)
277 sel.Add(selection[i].AsUInteger()); 277 sel.Add(selection[i].AsUInteger());
278 278
279 Util.FireAndForget(x => { m_module.HandleMenuSelection(action, m_agentID, sel); }); 279 Util.FireAndForget(
280 x => { m_module.HandleMenuSelection(action, m_agentID, sel); }, null, "DynamicMenuModule.HandleMenuSelection");
280 281
281 Encoding encoding = Encoding.UTF8; 282 Encoding encoding = Encoding.UTF8;
282 return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); 283 return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD()));
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/GodNamesModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/GodNamesModule.cs
new file mode 100644
index 0000000..e0537a4
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/GodNamesModule.cs
@@ -0,0 +1,144 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39
40namespace OpenSim.Region.OptionalModules.ViewerSupport
41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodNamesModule")]
43 public class GodNamesModule : ISharedRegionModule
44 {
45 // Infrastructure
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 // Configuration
49 private static bool m_enabled = false;
50 private static List<String> m_lastNames = new List<String>();
51 private static List<String> m_fullNames = new List<String>();
52
53 public void Initialise(IConfigSource config)
54 {
55 IConfig moduleConfig = config.Configs["GodNames"];
56
57 if (moduleConfig == null) {
58 return;
59 }
60
61 if (!moduleConfig.GetBoolean("Enabled", false)) {
62 m_log.Info("[GODNAMES]: Addon is disabled");
63 return;
64 }
65
66 m_log.Info("[GODNAMES]: Enabled");
67 m_enabled = true;
68 string conf_str = moduleConfig.GetString("FullNames", String.Empty);
69 foreach (string strl in conf_str.Split(',')) {
70 string strlan = strl.Trim(" \t".ToCharArray());
71 m_log.DebugFormat("[GODNAMES]: Adding {0} as a God name", strlan);
72 m_fullNames.Add(strlan);
73 }
74
75 conf_str = moduleConfig.GetString("Surnames", String.Empty);
76 foreach (string strl in conf_str.Split(',')) {
77 string strlan = strl.Trim(" \t".ToCharArray());
78 m_log.DebugFormat("[GODNAMES]: Adding {0} as a God last name", strlan);
79 m_lastNames.Add(strlan);
80 }
81 }
82
83 public void AddRegion(Scene scene) {
84 /*no op*/
85 }
86
87 public void RemoveRegion(Scene scene) {
88 /*no op*/
89 }
90
91 public void PostInitialise() {
92 /*no op*/
93 }
94
95 public void Close() {
96 /*no op*/
97 }
98
99 public Type ReplaceableInterface {
100 get { return null; }
101 }
102
103 public string Name {
104 get { return "Godnames"; }
105 }
106
107 public bool IsSharedModule {
108 get { return true; }
109 }
110
111 public virtual void RegionLoaded(Scene scene)
112 {
113 if (!m_enabled)
114 return;
115
116 ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>();
117
118 if (featuresModule != null)
119 featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
120
121 }
122
123 private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
124 {
125 OSD namesmap = new OSDMap();
126 if (features.ContainsKey("god_names"))
127 namesmap = features["god_names"];
128 else
129 features["god_names"] = namesmap;
130
131 OSDArray fnames = new OSDArray();
132 foreach (string name in m_fullNames) {
133 fnames.Add(name);
134 }
135 ((OSDMap)namesmap)["full_names"] = fnames;
136
137 OSDArray lnames = new OSDArray();
138 foreach (string name in m_lastNames) {
139 lnames.Add(name);
140 }
141 ((OSDMap)namesmap)["last_names"] = lnames;
142 }
143 }
144}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs b/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs
new file mode 100644
index 0000000..2661522
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/SimulatorFeaturesHelper.cs
@@ -0,0 +1,171 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Reflection;
31using System.Text;
32using System.Collections.Generic;
33using System.Threading;
34
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim;
38using OpenSim.Region;
39using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Framework;
43using OpenSim.Services.Interfaces;
44//using OpenSim.Framework.Capabilities;
45using Nini.Config;
46using log4net;
47using OSDMap = OpenMetaverse.StructuredData.OSDMap;
48using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
49
50namespace OpenSim.Region.OptionalModules.ViewerSupport
51{
52 public class SimulatorFeaturesHelper
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private IEntityTransferModule m_TransferModule;
57 private Scene m_scene;
58
59 private struct RegionSend {
60 public UUID region;
61 public bool send;
62 };
63 // Using a static cache so that we don't have to perform the time-consuming tests
64 // in ShouldSend on Extra SimFeatures that go on the same response but come from
65 // different modules.
66 // This cached is indexed on the agentID and maps to a list of regions
67 private static ExpiringCache<UUID, List<RegionSend>> m_Cache = new ExpiringCache<UUID, List<RegionSend>>();
68 private const double TIMEOUT = 1.0; // time in cache
69
70 public SimulatorFeaturesHelper(Scene scene, IEntityTransferModule et)
71 {
72 m_scene = scene;
73 m_TransferModule = et;
74 }
75
76 public bool ShouldSend(UUID agentID)
77 {
78 List<RegionSend> rsendlist;
79 RegionSend rsend;
80 if (m_Cache.TryGetValue(agentID, out rsendlist))
81 {
82 rsend = rsendlist.Find(r => r.region == m_scene.RegionInfo.RegionID);
83 if (rsend.region != UUID.Zero) // Found it
84 {
85 return rsend.send;
86 }
87 }
88
89 // Relatively complex logic for deciding whether to send the extra SimFeature or not.
90 // This is because the viewer calls this cap to all sims that it knows about,
91 // including the departing sims and non-neighbors (those that are cached).
92 rsend.region = m_scene.RegionInfo.RegionID;
93 rsend.send = false;
94 IClientAPI client = null;
95 int counter = 200;
96
97 // Let's wait a little to see if we get a client here
98 while (!m_scene.TryGetClient(agentID, out client) && counter-- > 0)
99 Thread.Sleep(50);
100
101 if (client != null)
102 {
103 ScenePresence sp = WaitGetScenePresence(agentID);
104
105 if (sp != null)
106 {
107 // On the receiving region, the call to this cap may arrive before
108 // the agent is root. Make sure we only proceed from here when the agent
109 // has been made root
110 counter = 200;
111 while ((sp.IsInTransit || sp.IsChildAgent) && counter-- > 0)
112 {
113 Thread.Sleep(50);
114 }
115
116 // The viewer calls this cap on the departing sims too. Make sure
117 // that we only proceed after the agent is not in transit anymore.
118 // The agent must be root and not going anywhere
119 if (!sp.IsChildAgent && !m_TransferModule.IsInTransit(agentID))
120 rsend.send = true;
121
122 }
123 }
124 //else
125 // m_log.DebugFormat("[XXX]: client is null");
126
127
128 if (rsendlist == null)
129 {
130 rsendlist = new List<RegionSend>();
131 m_Cache.AddOrUpdate(agentID, rsendlist, TIMEOUT);
132 }
133 rsendlist.Add(rsend);
134
135 return rsend.send;
136 }
137
138 public int UserLevel(UUID agentID)
139 {
140 int level = 0;
141 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID);
142 if (account != null)
143 level = account.UserLevel;
144
145 return level;
146 }
147
148 protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
149 {
150 int ntimes = 20;
151 ScenePresence sp = null;
152 while ((sp = m_scene.GetScenePresence(agentID)) == null && (ntimes-- > 0))
153 Thread.Sleep(1000);
154
155 if (sp == null)
156 m_log.WarnFormat(
157 "[XXX]: Did not find presence with id {0} in {1} before timeout",
158 agentID, m_scene.RegionInfo.RegionName);
159 else
160 {
161 ntimes = 10;
162 while (sp.IsInTransit && (ntimes-- > 0))
163 Thread.Sleep(1000);
164 }
165
166 return sp;
167 }
168
169 }
170
171}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs
new file mode 100644
index 0000000..3fe922d
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/SpecialUIModule.cs
@@ -0,0 +1,165 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Reflection;
31using System.Text;
32using System.Collections.Generic;
33using System.Threading;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim;
37using OpenSim.Region;
38using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Framework;
42//using OpenSim.Framework.Capabilities;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using Nini.Config;
46using log4net;
47using Mono.Addins;
48using OSDMap = OpenMetaverse.StructuredData.OSDMap;
49using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
50
51namespace OpenSim.Region.OptionalModules.ViewerSupport
52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SpecialUI")]
54 public class SpecialUIModule : INonSharedRegionModule
55 {
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57 private const string VIEWER_SUPPORT_DIR = "ViewerSupport";
58
59 private Scene m_scene;
60 private SimulatorFeaturesHelper m_Helper;
61 private bool m_Enabled;
62 private int m_UserLevel;
63
64 public string Name
65 {
66 get { return "SpecialUIModule"; }
67 }
68
69 public Type ReplaceableInterface
70 {
71 get { return null; }
72 }
73
74 public void Initialise(IConfigSource config)
75 {
76 IConfig moduleConfig = config.Configs["SpecialUIModule"];
77 if (moduleConfig != null)
78 {
79 m_Enabled = moduleConfig.GetBoolean("enabled", false);
80 if (m_Enabled)
81 {
82 m_UserLevel = moduleConfig.GetInt("UserLevel", 0);
83 m_log.Info("[SPECIAL UI]: SpecialUIModule enabled");
84 }
85
86 }
87 }
88
89 public void Close()
90 {
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 if (m_Enabled)
96 {
97 m_scene = scene;
98 }
99 }
100
101 public void RegionLoaded(Scene scene)
102 {
103 if (m_Enabled)
104 {
105 IEntityTransferModule et = m_scene.RequestModuleInterface<IEntityTransferModule>();
106 m_Helper = new SimulatorFeaturesHelper(scene, et);
107
108 ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface<ISimulatorFeaturesModule>();
109 if (featuresModule != null)
110 featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
111 }
112 }
113
114 public void RemoveRegion(Scene scene)
115 {
116 }
117
118 private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
119 {
120 m_log.DebugFormat("[SPECIAL UI]: OnSimulatorFeaturesRequest in {0}", m_scene.RegionInfo.RegionName);
121 if (m_Helper.ShouldSend(agentID) && m_Helper.UserLevel(agentID) <= m_UserLevel)
122 {
123 OSDMap extrasMap;
124 OSDMap specialUI = new OSDMap();
125 using (StreamReader s = new StreamReader(Path.Combine(VIEWER_SUPPORT_DIR, "panel_toolbar.xml")))
126 {
127 if (features.ContainsKey("OpenSimExtras"))
128 extrasMap = (OSDMap)features["OpenSimExtras"];
129 else
130 {
131 extrasMap = new OSDMap();
132 features["OpenSimExtras"] = extrasMap;
133 }
134
135 specialUI["toolbar"] = OSDMap.FromString(s.ReadToEnd());
136 extrasMap["special-ui"] = specialUI;
137 }
138 m_log.DebugFormat("[SPECIAL UI]: Sending panel_toolbar.xml in {0}", m_scene.RegionInfo.RegionName);
139
140 if (Directory.Exists(Path.Combine(VIEWER_SUPPORT_DIR, "Floaters")))
141 {
142 OSDMap floaters = new OSDMap();
143 uint n = 0;
144 foreach (String name in Directory.GetFiles(Path.Combine(VIEWER_SUPPORT_DIR, "Floaters"), "*.xml"))
145 {
146 using (StreamReader s = new StreamReader(name))
147 {
148 string simple_name = Path.GetFileNameWithoutExtension(name);
149 OSDMap floater = new OSDMap();
150 floaters[simple_name] = OSDMap.FromString(s.ReadToEnd());
151 n++;
152 }
153 }
154 specialUI["floaters"] = floaters;
155 m_log.DebugFormat("[SPECIAL UI]: Sending {0} floaters", n);
156 }
157 }
158 else
159 m_log.DebugFormat("[SPECIAL UI]: NOT Sending panel_toolbar.xml in {0}", m_scene.RegionInfo.RegionName);
160
161 }
162
163 }
164
165}
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
index 1d35c54..ceb3332 100644
--- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
@@ -76,6 +76,10 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
76 /// AutoBackupBusyCheck: True/False. Default: True. 76 /// AutoBackupBusyCheck: True/False. Default: True.
77 /// If True, we will only take an auto-backup if a set of conditions are met. 77 /// If True, we will only take an auto-backup if a set of conditions are met.
78 /// These conditions are heuristics to try and avoid taking a backup when the sim is busy. 78 /// These conditions are heuristics to try and avoid taking a backup when the sim is busy.
79 /// AutoBackupSkipAssets
80 /// If true, assets are not saved to the oar file. Considerably reduces impact on simulator when backing up. Intended for when assets db is backed up separately
81 /// AutoBackupKeepFilesForDays
82 /// Backup files older than this value (in days) are deleted during the current backup process, 0 will disable this and keep all backup files indefinitely
79 /// AutoBackupScript: String. Default: not specified (disabled). 83 /// AutoBackupScript: String. Default: not specified (disabled).
80 /// File path to an executable script or binary to run when an automatic backup is taken. 84 /// File path to an executable script or binary to run when an automatic backup is taken.
81 /// The file should really be (Windows) an .exe or .bat, or (Linux/Mac) a shell script or binary. 85 /// The file should really be (Windows) an .exe or .bat, or (Linux/Mac) a shell script or binary.
@@ -111,6 +115,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
111 115
112 private delegate T DefaultGetter<T>(string settingName, T defaultValue); 116 private delegate T DefaultGetter<T>(string settingName, T defaultValue);
113 private bool m_enabled; 117 private bool m_enabled;
118 private ICommandConsole m_console;
119 private List<Scene> m_Scenes = new List<Scene> ();
120
114 121
115 /// <summary> 122 /// <summary>
116 /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState! 123 /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState!
@@ -202,8 +209,20 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
202 /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded. 209 /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded.
203 /// </summary> 210 /// </summary>
204 /// <param name="scene"></param> 211 /// <param name="scene"></param>
205 void IRegionModuleBase.AddRegion(Scene scene) 212 void IRegionModuleBase.AddRegion (Scene scene)
206 { 213 {
214 if (!this.m_enabled) {
215 return;
216 }
217 lock (m_Scenes) {
218 m_Scenes.Add (scene);
219 }
220 m_console = MainConsole.Instance;
221
222 m_console.Commands.AddCommand (
223 "AutoBackup", false, "dobackup",
224 "dobackup",
225 "do backup.", DoBackup);
207 } 226 }
208 227
209 /// <summary> 228 /// <summary>
@@ -216,7 +235,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
216 { 235 {
217 return; 236 return;
218 } 237 }
219 238 m_Scenes.Remove (scene);
220 if (this.m_states.ContainsKey(scene)) 239 if (this.m_states.ContainsKey(scene))
221 { 240 {
222 AutoBackupModuleState abms = this.m_states[scene]; 241 AutoBackupModuleState abms = this.m_states[scene];
@@ -258,6 +277,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
258 AutoBackupModuleState abms = this.ParseConfig(scene, false); 277 AutoBackupModuleState abms = this.ParseConfig(scene, false);
259 m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName); 278 m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName);
260 m_log.Debug((abms == null ? "DEFAULT" : abms.ToString())); 279 m_log.Debug((abms == null ? "DEFAULT" : abms.ToString()));
280
281 m_states.Add(scene, abms);
261 } 282 }
262 283
263 /// <summary> 284 /// <summary>
@@ -269,6 +290,28 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
269 290
270 #endregion 291 #endregion
271 292
293 private void DoBackup (string module, string[] args)
294 {
295 if (args.Length != 2) {
296 MainConsole.Instance.OutputFormat ("Usage: dobackup <regionname>");
297 return;
298 }
299 bool found = false;
300 string name = args [1];
301 lock (m_Scenes) {
302 foreach (Scene s in m_Scenes) {
303 string test = s.Name.ToString ();
304 if (test == name) {
305 found = true;
306 DoRegionBackup (s);
307 }
308 }
309 if (!found) {
310 MainConsole.Instance.OutputFormat ("No such region {0}. Nothing to backup", name);
311 }
312 }
313 }
314
272 /// <summary> 315 /// <summary>
273 /// Set up internal state for a given scene. Fairly complex code. 316 /// Set up internal state for a given scene. Fairly complex code.
274 /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene. 317 /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene.
@@ -334,7 +377,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
334 double interval = 377 double interval =
335 this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes, 378 this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes,
336 config, regionConfig) * 60000.0; 379 config, regionConfig) * 60000.0;
337 if (state == null && interval != this.m_defaultState.IntervalMinutes*60000.0) 380 if (state == null && interval != this.m_defaultState.IntervalMinutes * 60000.0)
338 { 381 {
339 state = new AutoBackupModuleState(); 382 state = new AutoBackupModuleState();
340 } 383 }
@@ -412,6 +455,32 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
412 state.BusyCheck = tmpBusyCheck; 455 state.BusyCheck = tmpBusyCheck;
413 } 456 }
414 457
458 // Included Option To Skip Assets
459 bool tmpSkipAssets = ResolveBoolean("AutoBackupSkipAssets",
460 this.m_defaultState.SkipAssets, config, regionConfig);
461 if (state == null && tmpSkipAssets != this.m_defaultState.SkipAssets)
462 {
463 state = new AutoBackupModuleState();
464 }
465
466 if (state != null)
467 {
468 state.SkipAssets = tmpSkipAssets;
469 }
470
471 // How long to keep backup files in days, 0 Disables this feature
472 int tmpKeepFilesForDays = ResolveInt("AutoBackupKeepFilesForDays",
473 this.m_defaultState.KeepFilesForDays, config, regionConfig);
474 if (state == null && tmpKeepFilesForDays != this.m_defaultState.KeepFilesForDays)
475 {
476 state = new AutoBackupModuleState();
477 }
478
479 if (state != null)
480 {
481 state.KeepFilesForDays = tmpKeepFilesForDays;
482 }
483
415 // Set file naming algorithm 484 // Set file naming algorithm
416 string stmpNamingType = ResolveString("AutoBackupNaming", 485 string stmpNamingType = ResolveString("AutoBackupNaming",
417 this.m_defaultState.NamingType.ToString(), config, regionConfig); 486 this.m_defaultState.NamingType.ToString(), config, regionConfig);
@@ -480,7 +549,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
480 catch (Exception e) 549 catch (Exception e)
481 { 550 {
482 m_log.Warn( 551 m_log.Warn(
483 "BAD NEWS. You won't be able to save backups to directory " + 552 "[AUTO BACKUP]: BAD NEWS. You won't be able to save backups to directory " +
484 state.BackupDir + 553 state.BackupDir +
485 " because it doesn't exist or there's a permissions issue with it. Here's the exception.", 554 " because it doesn't exist or there's a permissions issue with it. Here's the exception.",
486 e); 555 e);
@@ -488,6 +557,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
488 } 557 }
489 } 558 }
490 559
560 if(state == null)
561 return m_defaultState;
562
491 return state; 563 return state;
492 } 564 }
493 565
@@ -594,7 +666,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
594 bool heuristicsPassed = false; 666 bool heuristicsPassed = false;
595 if (!this.m_timerMap.ContainsKey((Timer) sender)) 667 if (!this.m_timerMap.ContainsKey((Timer) sender))
596 { 668 {
597 m_log.Debug("Code-up error: timerMap doesn't contain timer " + sender); 669 m_log.Debug("[AUTO BACKUP]: Code-up error: timerMap doesn't contain timer " + sender);
598 } 670 }
599 671
600 List<IScene> tmap = this.m_timerMap[(Timer) sender]; 672 List<IScene> tmap = this.m_timerMap[(Timer) sender];
@@ -630,6 +702,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
630 } 702 }
631 this.DoRegionBackup(scene); 703 this.DoRegionBackup(scene);
632 } 704 }
705
706 // Remove Old Backups
707 this.RemoveOldFiles(state);
633 } 708 }
634 } 709 }
635 } 710 }
@@ -640,7 +715,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
640 /// <param name="scene"></param> 715 /// <param name="scene"></param>
641 private void DoRegionBackup(IScene scene) 716 private void DoRegionBackup(IScene scene)
642 { 717 {
643 if (scene.RegionStatus != RegionStatus.Up) 718 if (!scene.Ready)
644 { 719 {
645 // We won't backup a region that isn't operating normally. 720 // We won't backup a region that isn't operating normally.
646 m_log.Warn("[AUTO BACKUP]: Not backing up region " + scene.RegionInfo.RegionName + 721 m_log.Warn("[AUTO BACKUP]: Not backing up region " + scene.RegionInfo.RegionName +
@@ -662,7 +737,41 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
662 m_pendingSaves.Add(guid, scene); 737 m_pendingSaves.Add(guid, scene);
663 state.LiveRequests.Add(guid, savePath); 738 state.LiveRequests.Add(guid, savePath);
664 ((Scene) scene).EventManager.OnOarFileSaved += new EventManager.OarFileSaved(EventManager_OnOarFileSaved); 739 ((Scene) scene).EventManager.OnOarFileSaved += new EventManager.OarFileSaved(EventManager_OnOarFileSaved);
665 iram.ArchiveRegion(savePath, guid, null); 740
741 m_log.Info("[AUTO BACKUP]: Backing up region " + scene.RegionInfo.RegionName);
742
743 // Must pass options, even if dictionary is empty!
744 Dictionary<string, object> options = new Dictionary<string, object>();
745
746 if (state.SkipAssets)
747 options["noassets"] = true;
748
749 iram.ArchiveRegion(savePath, guid, options);
750 }
751
752 // For the given state, remove backup files older than the states KeepFilesForDays property
753 private void RemoveOldFiles(AutoBackupModuleState state)
754 {
755 // 0 Means Disabled, Keep Files Indefinitely
756 if (state.KeepFilesForDays > 0)
757 {
758 string[] files = Directory.GetFiles(state.BackupDir, "*.oar");
759 DateTime CuttOffDate = DateTime.Now.AddDays(0 - state.KeepFilesForDays);
760
761 foreach (string file in files)
762 {
763 try
764 {
765 FileInfo fi = new FileInfo(file);
766 if (fi.CreationTime < CuttOffDate)
767 fi.Delete();
768 }
769 catch (Exception Ex)
770 {
771 m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message);
772 }
773 }
774 }
666 } 775 }
667 776
668 /// <summary> 777 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
index f9e118b..ce7c368 100644
--- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
@@ -45,9 +45,11 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
45 this.Enabled = false; 45 this.Enabled = false;
46 this.BackupDir = "."; 46 this.BackupDir = ".";
47 this.BusyCheck = true; 47 this.BusyCheck = true;
48 this.SkipAssets = false;
48 this.Timer = null; 49 this.Timer = null;
49 this.NamingType = NamingType.Time; 50 this.NamingType = NamingType.Time;
50 this.Script = null; 51 this.Script = null;
52 this.KeepFilesForDays = 0;
51 } 53 }
52 54
53 public Dictionary<Guid, string> LiveRequests 55 public Dictionary<Guid, string> LiveRequests
@@ -91,6 +93,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
91 set; 93 set;
92 } 94 }
93 95
96 public bool SkipAssets
97 {
98 get;
99 set;
100 }
101
94 public string Script 102 public string Script
95 { 103 {
96 get; 104 get;
@@ -109,6 +117,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
109 set; 117 set;
110 } 118 }
111 119
120 public int KeepFilesForDays
121 {
122 get;
123 set;
124 }
125
112 public new string ToString() 126 public new string ToString()
113 { 127 {
114 string retval = ""; 128 string retval = "";
diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
index bcb21d0..8565f5a 100644
--- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
+++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
@@ -103,7 +103,9 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
103 103
104 #region IMoneyModule Members 104 #region IMoneyModule Members
105 105
106#pragma warning disable 0067
106 public event ObjectPaid OnObjectPaid; 107 public event ObjectPaid OnObjectPaid;
108#pragma warning restore 0067
107 109
108 public int UploadCharge 110 public int UploadCharge
109 { 111 {
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index dcd2a52..dc1ea95 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -61,7 +61,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
61 private readonly string m_firstname; 61 private readonly string m_firstname;
62 private readonly string m_lastname; 62 private readonly string m_lastname;
63 private readonly Vector3 m_startPos; 63 private readonly Vector3 m_startPos;
64<<<<<<< HEAD
65 private readonly UUID m_uuid;
66=======
64 private UUID m_uuid = UUID.Random(); 67 private UUID m_uuid = UUID.Random();
68>>>>>>> avn/ubitvar
65 private readonly Scene m_scene; 69 private readonly Scene m_scene;
66 private readonly UUID m_ownerID; 70 private readonly UUID m_ownerID;
67 71
@@ -73,6 +77,19 @@ namespace OpenSim.Region.OptionalModules.World.NPC
73 m_firstname = firstname; 77 m_firstname = firstname;
74 m_lastname = lastname; 78 m_lastname = lastname;
75 m_startPos = position; 79 m_startPos = position;
80 m_uuid = UUID.Random();
81 m_scene = scene;
82 m_ownerID = ownerID;
83 SenseAsAgent = senseAsAgent;
84 }
85
86 public NPCAvatar(
87 string firstname, string lastname, UUID agentID, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene)
88 {
89 m_firstname = firstname;
90 m_lastname = lastname;
91 m_startPos = position;
92 m_uuid = agentID;
76 m_scene = scene; 93 m_scene = scene;
77 m_ownerID = ownerID; 94 m_ownerID = ownerID;
78 SenseAsAgent = senseAsAgent; 95 SenseAsAgent = senseAsAgent;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 226608a..2977195 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -140,8 +140,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC
140 Vector3 position, UUID owner, bool senseAsAgent, Scene scene, 140 Vector3 position, UUID owner, bool senseAsAgent, Scene scene,
141 AvatarAppearance appearance) 141 AvatarAppearance appearance)
142 { 142 {
143 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, 143 return CreateNPC(firstname, lastname, position, UUID.Zero, owner, senseAsAgent, scene, appearance);
144 owner, senseAsAgent, scene); 144 }
145
146 public UUID CreateNPC(string firstname, string lastname,
147 Vector3 position, UUID agentID, UUID owner, bool senseAsAgent, Scene scene,
148 AvatarAppearance appearance)
149 {
150 NPCAvatar npcAvatar = null;
151
152 try
153 {
154 if (agentID == UUID.Zero)
155 npcAvatar = new NPCAvatar(firstname, lastname, position,
156 owner, senseAsAgent, scene);
157 else
158 npcAvatar = new NPCAvatar(firstname, lastname, agentID, position,
159 owner, senseAsAgent, scene);
160 }
161 catch (Exception e)
162 {
163 m_log.Info("[NPC MODULE]: exception creating NPC avatar: " + e.ToString());
164 return UUID.Zero;
165 }
166
145 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, 167 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0,
146 int.MaxValue); 168 int.MaxValue);
147 169
@@ -155,8 +177,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
155 acd.lastname = lastname; 177 acd.lastname = lastname;
156 acd.ServiceURLs = new Dictionary<string, object>(); 178 acd.ServiceURLs = new Dictionary<string, object>();
157 179
158 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, 180 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
159 true);
160 acd.Appearance = npcAppearance; 181 acd.Appearance = npcAppearance;
161 182
162 /* 183 /*
@@ -207,6 +228,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
207 ScenePresence sp; 228 ScenePresence sp;
208 if (scene.TryGetScenePresence(agentID, out sp)) 229 if (scene.TryGetScenePresence(agentID, out sp))
209 { 230 {
231 if (sp.IsSatOnObject || sp.SitGround)
232 return false;
233
210// m_log.DebugFormat( 234// m_log.DebugFormat(
211// "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", 235// "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
212// sp.Name, pos, scene.RegionInfo.RegionName, 236// sp.Name, pos, scene.RegionInfo.RegionName,
@@ -368,26 +392,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC
368 392
369 public bool DeleteNPC(UUID agentID, Scene scene) 393 public bool DeleteNPC(UUID agentID, Scene scene)
370 { 394 {
395 bool doRemove = false;
396 NPCAvatar av;
371 lock (m_avatars) 397 lock (m_avatars)
372 { 398 {
373 NPCAvatar av;
374 if (m_avatars.TryGetValue(agentID, out av)) 399 if (m_avatars.TryGetValue(agentID, out av))
375 { 400 {
376 /* 401 /*
377 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", 402 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove",
378 agentID, av.Name); 403 agentID, av.Name);
379 */ 404 */
405 doRemove = true;
406 }
407 }
380 408
381 scene.CloseAgent(agentID, false); 409 if (doRemove)
382 410 {
411 scene.CloseAgent(agentID, false);
412 lock (m_avatars)
413 {
383 m_avatars.Remove(agentID); 414 m_avatars.Remove(agentID);
384
385 /*
386 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}",
387 agentID, av.Name);
388 */
389 return true;
390 } 415 }
416 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}",
417 agentID, av.Name);
418 return true;
391 } 419 }
392 /* 420 /*
393 m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", 421 m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove",
@@ -417,12 +445,24 @@ namespace OpenSim.Region.OptionalModules.World.NPC
417 /// <summary> 445 /// <summary>
418 /// Check if the caller has permission to manipulate the given NPC. 446 /// Check if the caller has permission to manipulate the given NPC.
419 /// </summary> 447 /// </summary>
448 /// <remarks>
449 /// A caller has permission if
450 /// * The caller UUID given is UUID.Zero.
451 /// * The avatar is unowned (owner is UUID.Zero).
452 /// * The avatar is owned and the owner and callerID match.
453 /// * The avatar is owned and the callerID matches its agentID.
454 /// </remarks>
420 /// <param name="av"></param> 455 /// <param name="av"></param>
421 /// <param name="callerID"></param> 456 /// <param name="callerID"></param>
422 /// <returns>true if they do, false if they don't.</returns> 457 /// <returns>true if they do, false if they don't.</returns>
423 private bool CheckPermissions(NPCAvatar av, UUID callerID) 458 private bool CheckPermissions(NPCAvatar av, UUID callerID)
424 { 459 {
460<<<<<<< HEAD
461 return callerID == UUID.Zero || av.OwnerID == UUID.Zero ||
462 av.OwnerID == callerID || av.AgentId == callerID;
463=======
425 return callerID == UUID.Zero || av.OwnerID == UUID.Zero || av.OwnerID == callerID || av.AgentId == callerID; 464 return callerID == UUID.Zero || av.OwnerID == UUID.Zero || av.OwnerID == callerID || av.AgentId == callerID;
465>>>>>>> avn/ubitvar
426 } 466 }
427 } 467 }
428} 468}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 14eb25b..2345e38 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.AvatarService; 44using OpenSim.Services.AvatarService;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.OptionalModules.World.NPC.Tests 47namespace OpenSim.Region.OptionalModules.World.NPC.Tests
49{ 48{
@@ -71,11 +70,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
71 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; 70 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
72 } 71 }
73 72
74 [SetUp] 73 public void SetUpScene()
75 public void Init()
76 { 74 {
77 base.SetUp(); 75 SetUpScene(256, 256);
76 }
78 77
78 public void SetUpScene(uint sizeX, uint sizeY)
79 {
79 IConfigSource config = new IniConfigSource(); 80 IConfigSource config = new IniConfigSource();
80 config.AddConfig("NPC"); 81 config.AddConfig("NPC");
81 config.Configs["NPC"].Set("Enabled", "true"); 82 config.Configs["NPC"].Set("Enabled", "true");
@@ -87,7 +88,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
87 m_attMod = new AttachmentsModule(); 88 m_attMod = new AttachmentsModule();
88 m_npcMod = new NPCModule(); 89 m_npcMod = new NPCModule();
89 90
90 m_scene = new SceneHelpers().SetupScene(); 91 m_scene = new SceneHelpers().SetupScene("test scene", UUID.Random(), 1000, 1000, sizeX, sizeY, config);
91 SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule()); 92 SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule());
92 } 93 }
93 94
@@ -97,6 +98,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
97 TestHelpers.InMethod(); 98 TestHelpers.InMethod();
98// log4net.Config.XmlConfigurator.Configure(); 99// log4net.Config.XmlConfigurator.Configure();
99 100
101 SetUpScene();
102
100 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 103 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
101// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); 104// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
102 105
@@ -133,6 +136,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
133 TestHelpers.InMethod(); 136 TestHelpers.InMethod();
134// log4net.Config.XmlConfigurator.Configure(); 137// log4net.Config.XmlConfigurator.Configure();
135 138
139 SetUpScene();
140
136 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 141 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
137// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); 142// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
138 143
@@ -157,6 +162,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
157 TestHelpers.InMethod(); 162 TestHelpers.InMethod();
158// TestHelpers.EnableLogging(); 163// TestHelpers.EnableLogging();
159 164
165 SetUpScene();
166
160 UUID userId = TestHelpers.ParseTail(0x1); 167 UUID userId = TestHelpers.ParseTail(0x1);
161 UserAccountHelpers.CreateUserWithInventory(m_scene, userId); 168 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
162 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); 169 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
@@ -191,11 +198,66 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
191 } 198 }
192 199
193 [Test] 200 [Test]
201 public void TestCreateWithMultiAttachments()
202 {
203 TestHelpers.InMethod();
204// TestHelpers.EnableLogging();
205
206 SetUpScene();
207// m_attMod.DebugLevel = 1;
208
209 UUID userId = TestHelpers.ParseTail(0x1);
210 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
211 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
212
213 InventoryItemBase att1Item
214 = UserInventoryHelpers.CreateInventoryItem(
215 m_scene, "att1", TestHelpers.ParseTail(0x2), TestHelpers.ParseTail(0x3), sp.UUID, InventoryType.Object);
216 InventoryItemBase att2Item
217 = UserInventoryHelpers.CreateInventoryItem(
218 m_scene, "att2", TestHelpers.ParseTail(0x12), TestHelpers.ParseTail(0x13), sp.UUID, InventoryType.Object);
219
220 m_attMod.RezSingleAttachmentFromInventory(sp, att1Item.ID, (uint)AttachmentPoint.Chest);
221 m_attMod.RezSingleAttachmentFromInventory(sp, att2Item.ID, (uint)AttachmentPoint.Chest | 0x80);
222
223 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
224
225 ScenePresence npc = m_scene.GetScenePresence(npcId);
226
227 // Check scene presence status
228 Assert.That(npc.HasAttachments(), Is.True);
229 List<SceneObjectGroup> attachments = npc.GetAttachments();
230 Assert.That(attachments.Count, Is.EqualTo(2));
231
232 // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
233 // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
234// Assert.That(attSo.Name, Is.EqualTo(attName));
235
236 TestAttachedObject(attachments[0], AttachmentPoint.Chest, npc.UUID);
237 TestAttachedObject(attachments[1], AttachmentPoint.Chest, npc.UUID);
238
239 // Attached objects on the same point must have different FromItemIDs to be shown to other avatars, at least
240 // on Singularity 1.8.5. Otherwise, only one (the first ObjectUpdate sent) appears.
241 Assert.AreNotEqual(attachments[0].FromItemID, attachments[1].FromItemID);
242 }
243
244 private void TestAttachedObject(SceneObjectGroup attSo, AttachmentPoint attPoint, UUID ownerId)
245 {
246 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)attPoint));
247 Assert.That(attSo.IsAttachment);
248 Assert.That(attSo.UsesPhysics, Is.False);
249 Assert.That(attSo.IsTemporary, Is.False);
250 Assert.That(attSo.OwnerID, Is.EqualTo(ownerId));
251 }
252
253 [Test]
194 public void TestLoadAppearance() 254 public void TestLoadAppearance()
195 { 255 {
196 TestHelpers.InMethod(); 256 TestHelpers.InMethod();
197// log4net.Config.XmlConfigurator.Configure(); 257// log4net.Config.XmlConfigurator.Configure();
198 258
259 SetUpScene();
260
199 UUID userId = TestHelpers.ParseTail(0x1); 261 UUID userId = TestHelpers.ParseTail(0x1);
200 UserAccountHelpers.CreateUserWithInventory(m_scene, userId); 262 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
201 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); 263 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
@@ -237,7 +299,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
237 public void TestMove() 299 public void TestMove()
238 { 300 {
239 TestHelpers.InMethod(); 301 TestHelpers.InMethod();
240// log4net.Config.XmlConfigurator.Configure(); 302// TestHelpers.EnableLogging();
303
304 SetUpScene();
241 305
242 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 306 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
243// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); 307// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
@@ -303,11 +367,64 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
303 } 367 }
304 368
305 [Test] 369 [Test]
370 public void TestMoveInVarRegion()
371 {
372 TestHelpers.InMethod();
373// TestHelpers.EnableLogging();
374
375 SetUpScene(512, 512);
376
377 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
378// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
379
380 Vector3 startPos = new Vector3(128, 246, 30);
381 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
382
383 ScenePresence npc = m_scene.GetScenePresence(npcId);
384 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
385
386 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
387 npc.Flying = true;
388
389 m_scene.Update(1);
390 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
391
392 Vector3 targetPos = startPos + new Vector3(0, 20, 0);
393 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false);
394
395 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
396 //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f)));
397 Assert.That(
398 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
399
400 m_scene.Update(1);
401
402 // We should really check the exact figure.
403 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
404 Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
405 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
406 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
407
408 for (int i = 0; i < 20; i++)
409 {
410 m_scene.Update(1);
411// Console.WriteLine("pos: {0}", npc.AbsolutePosition);
412 }
413
414 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
415 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
416 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
417 Assert.That(npc.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
418 }
419
420 [Test]
306 public void TestSitAndStandWithSitTarget() 421 public void TestSitAndStandWithSitTarget()
307 { 422 {
308 TestHelpers.InMethod(); 423 TestHelpers.InMethod();
309// log4net.Config.XmlConfigurator.Configure(); 424// log4net.Config.XmlConfigurator.Configure();
310 425
426 SetUpScene();
427
311 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 428 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
312 429
313 Vector3 startPos = new Vector3(128, 128, 30); 430 Vector3 startPos = new Vector3(128, 128, 30);
@@ -337,6 +454,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
337 TestHelpers.InMethod(); 454 TestHelpers.InMethod();
338// TestHelpers.EnableLogging(); 455// TestHelpers.EnableLogging();
339 456
457 SetUpScene();
458
340 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 459 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
341 460
342 // FIXME: To get this to work for now, we are going to place the npc right next to the target so that 461 // FIXME: To get this to work for now, we are going to place the npc right next to the target so that
diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs
index 6cbccc0..a26d145 100644
--- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs
+++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Reflection; 31using System.Reflection;
32using System.Text; 32using System.Text;
33using System.Threading;
33using log4net; 34using log4net;
34using Mono.Addins; 35using Mono.Addins;
35using Nini.Config; 36using Nini.Config;
@@ -93,28 +94,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
93 "Debug", this, "debug scene get", 94 "Debug", this, "debug scene get",
94 "debug scene get", 95 "debug scene get",
95 "List current scene options.", 96 "List current scene options.",
96 "If active is false then main scene update and maintenance loops are suspended.\n" 97 "active - if false then main scene update and maintenance loops are suspended.\n"
97 + "If animations is true then extra animations debug information is logged.\n" 98 + "animations - if true then extra animations debug information is logged.\n"
98 + "If collisions is false then collisions with other objects are turned off.\n" 99 + "appear-refresh - if true then appearance is resent to other avatars every 60 seconds.\n"
99 + "If pbackup is false then periodic scene backup is turned off.\n" 100 + "child-repri - how far an avatar must move in meters before we update the position of its child agents in neighbouring regions.\n"
100 + "If physics is false then all physics objects are non-physical.\n" 101 + "client-pos-upd - the tolerance before clients are updated with new rotation information for an avatar.\n"
101 + "If scripting is false then no scripting operations happen.\n" 102 + "client-rot-upd - the tolerance before clients are updated with new rotation information for an avatar.\n"
102 + "If teleport is true then some extra teleport debug information is logged.\n" 103 + "client-vel-upd - the tolerance before clients are updated with new velocity information for an avatar.\n"
103 + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", 104 + "root-upd-per - if greater than 1, terse updates are only sent to root agents other than the originator on every n updates.\n"
105 + "child-upd-per - if greater than 1, terse updates are only sent to child agents on every n updates.\n"
106 + "collisions - if false then collisions with other objects are turned off.\n"
107 + "pbackup - if false then periodic scene backup is turned off.\n"
108 + "physics - if false then all physics objects are non-physical.\n"
109 + "scripting - if false then no scripting operations happen.\n"
110 + "teleport - if true then some extra teleport debug information is logged.\n"
111 + "update-on-timer - If true then the scene is updated via a timer. If false then a thread with sleep is used.\n"
112 + "updates - if true then any frame which exceeds double the maximum desired frame time is logged.",
104 HandleDebugSceneGetCommand); 113 HandleDebugSceneGetCommand);
105 114
106 scene.AddCommand( 115 scene.AddCommand(
107 "Debug", this, "debug scene set", 116 "Debug", this, "debug scene set",
108 "debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false", 117 "debug scene set <param> <value>",
109 "Turn on scene debugging options.", 118 "Turn on scene debugging options.",
110 "If active is false then main scene update and maintenance loops are suspended.\n" 119 "active - if false then main scene update and maintenance loops are suspended.\n"
111 + "If animations is true then extra animations debug information is logged.\n" 120 + "animations - if true then extra animations debug information is logged.\n"
112 + "If collisions is false then collisions with other objects are turned off.\n" 121 + "appear-refresh - if true then appearance is resent to other avatars every 60 seconds.\n"
113 + "If pbackup is false then periodic scene backup is turned off.\n" 122 + "child-repri - how far an avatar must move in meters before we update the position of its child agents in neighbouring regions.\n"
114 + "If physics is false then all physics objects are non-physical.\n" 123 + "client-pos-upd - the tolerance before clients are updated with new rotation information for an avatar.\n"
115 + "If scripting is false then no scripting operations happen.\n" 124 + "client-rot-upd - the tolerance before clients are updated with new rotation information for an avatar.\n"
116 + "If teleport is true then some extra teleport debug information is logged.\n" 125 + "client-vel-upd - the tolerance before clients are updated with new velocity information for an avatar.\n"
117 + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", 126 + "root-upd-per - if greater than 1, terse updates are only sent to root agents other than the originator on every n updates.\n"
127 + "child-upd-per - if greater than 1, terse updates are only sent to child agents on every n updates.\n"
128 + "collisions - if false then collisions with other objects are turned off.\n"
129 + "pbackup - if false then periodic scene backup is turned off.\n"
130 + "physics - if false then all physics objects are non-physical.\n"
131 + "scripting - if false then no scripting operations happen.\n"
132 + "teleport - if true then some extra teleport debug information is logged.\n"
133 + "update-on-timer - If true then the scene is updated via a timer. If false then a thread with sleep is used.\n"
134 + "updates - if true then any frame which exceeds double the maximum desired frame time is logged.",
118 HandleDebugSceneSetCommand); 135 HandleDebugSceneSetCommand);
119 } 136 }
120 137
@@ -138,10 +155,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
138 ConsoleDisplayList cdl = new ConsoleDisplayList(); 155 ConsoleDisplayList cdl = new ConsoleDisplayList();
139 cdl.AddRow("active", m_scene.Active); 156 cdl.AddRow("active", m_scene.Active);
140 cdl.AddRow("animations", m_scene.DebugAnimations); 157 cdl.AddRow("animations", m_scene.DebugAnimations);
158 cdl.AddRow("appear-refresh", m_scene.SendPeriodicAppearanceUpdates);
159 cdl.AddRow("child-repri", m_scene.ChildReprioritizationDistance);
160 cdl.AddRow("client-pos-upd", m_scene.RootPositionUpdateTolerance);
161 cdl.AddRow("client-rot-upd", m_scene.RootRotationUpdateTolerance);
162 cdl.AddRow("client-vel-upd", m_scene.RootVelocityUpdateTolerance);
163 cdl.AddRow("root-upd-per", m_scene.RootTerseUpdatePeriod);
164 cdl.AddRow("child-upd-per", m_scene.ChildTerseUpdatePeriod);
141 cdl.AddRow("pbackup", m_scene.PeriodicBackup); 165 cdl.AddRow("pbackup", m_scene.PeriodicBackup);
142 cdl.AddRow("physics", m_scene.PhysicsEnabled); 166 cdl.AddRow("physics", m_scene.PhysicsEnabled);
143 cdl.AddRow("scripting", m_scene.ScriptsEnabled); 167 cdl.AddRow("scripting", m_scene.ScriptsEnabled);
144 cdl.AddRow("teleport", m_scene.DebugTeleporting); 168 cdl.AddRow("teleport", m_scene.DebugTeleporting);
169 cdl.AddRow("update-on-timer", m_scene.UpdateOnTimer);
145 cdl.AddRow("updates", m_scene.DebugUpdates); 170 cdl.AddRow("updates", m_scene.DebugUpdates);
146 171
147 MainConsole.Instance.OutputFormat("Scene {0} options:", m_scene.Name); 172 MainConsole.Instance.OutputFormat("Scene {0} options:", m_scene.Name);
@@ -163,8 +188,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
163 } 188 }
164 else 189 else
165 { 190 {
166 MainConsole.Instance.Output( 191 MainConsole.Instance.Output("Usage: debug scene set <param> <value>");
167 "Usage: debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false");
168 } 192 }
169 } 193 }
170 194
@@ -186,6 +210,69 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
186 m_scene.DebugAnimations = active; 210 m_scene.DebugAnimations = active;
187 } 211 }
188 212
213 if (options.ContainsKey("appear-refresh"))
214 {
215 bool newValue;
216
217 // FIXME: This can only come from the console at the moment but might not always be true.
218 if (ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, options["appear-refresh"], out newValue))
219 m_scene.SendPeriodicAppearanceUpdates = newValue;
220 }
221
222 if (options.ContainsKey("child-repri"))
223 {
224 double newValue;
225
226 // FIXME: This can only come from the console at the moment but might not always be true.
227 if (ConsoleUtil.TryParseConsoleDouble(MainConsole.Instance, options["child-repri"], out newValue))
228 m_scene.ChildReprioritizationDistance = newValue;
229 }
230
231 if (options.ContainsKey("client-pos-upd"))
232 {
233 float newValue;
234
235 // FIXME: This can only come from the console at the moment but might not always be true.
236 if (ConsoleUtil.TryParseConsoleFloat(MainConsole.Instance, options["client-pos-upd"], out newValue))
237 m_scene.RootPositionUpdateTolerance = newValue;
238 }
239
240 if (options.ContainsKey("client-rot-upd"))
241 {
242 float newValue;
243
244 // FIXME: This can only come from the console at the moment but might not always be true.
245 if (ConsoleUtil.TryParseConsoleFloat(MainConsole.Instance, options["client-rot-upd"], out newValue))
246 m_scene.RootRotationUpdateTolerance = newValue;
247 }
248
249 if (options.ContainsKey("client-vel-upd"))
250 {
251 float newValue;
252
253 // FIXME: This can only come from the console at the moment but might not always be true.
254 if (ConsoleUtil.TryParseConsoleFloat(MainConsole.Instance, options["client-vel-upd"], out newValue))
255 m_scene.RootVelocityUpdateTolerance = newValue;
256 }
257
258 if (options.ContainsKey("root-upd-per"))
259 {
260 int newValue;
261
262 // FIXME: This can only come from the console at the moment but might not always be true.
263 if (ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, options["root-upd-per"], out newValue))
264 m_scene.RootTerseUpdatePeriod = newValue;
265 }
266
267 if (options.ContainsKey("child-upd-per"))
268 {
269 int newValue;
270
271 // FIXME: This can only come from the console at the moment but might not always be true.
272 if (ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, options["child-upd-per"], out newValue))
273 m_scene.ChildTerseUpdatePeriod = newValue;
274 }
275
189 if (options.ContainsKey("pbackup")) 276 if (options.ContainsKey("pbackup"))
190 { 277 {
191 bool active; 278 bool active;
@@ -221,6 +308,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
221 m_scene.DebugTeleporting = enableTeleportDebugging; 308 m_scene.DebugTeleporting = enableTeleportDebugging;
222 } 309 }
223 310
311 if (options.ContainsKey("update-on-timer"))
312 {
313 bool enableUpdateOnTimer;
314 if (bool.TryParse(options["update-on-timer"], out enableUpdateOnTimer))
315 {
316 m_scene.UpdateOnTimer = enableUpdateOnTimer;
317 m_scene.Active = false;
318
319 while (m_scene.IsRunning)
320 Thread.Sleep(20);
321
322 m_scene.Active = true;
323 }
324 }
325
224 if (options.ContainsKey("updates")) 326 if (options.ContainsKey("updates"))
225 { 327 {
226 bool enableUpdateDebugging; 328 bool enableUpdateDebugging;