diff options
author | David Walter Seikel | 2016-11-03 21:44:39 +1000 |
---|---|---|
committer | David Walter Seikel | 2016-11-03 21:44:39 +1000 |
commit | 134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch) | |
tree | 216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/OptionalModules | |
parent | More changing to production grid. Double oops. (diff) | |
download | opensim-SC-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip opensim-SC-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz opensim-SC-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2 opensim-SC-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz |
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to '')
78 files changed, 6723 insertions, 1404 deletions
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 781539a..6fe86b2 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -71,7 +71,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
71 | m_client = client; | 71 | m_client = client; |
72 | m_scene = scene; | 72 | m_scene = scene; |
73 | 73 | ||
74 | Watchdog.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); | 74 | WorkManager.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); |
75 | } | 75 | } |
76 | 76 | ||
77 | private void SendServerCommand(string command) | 77 | private void SendServerCommand(string command) |
@@ -516,7 +516,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
516 | 516 | ||
517 | public Vector3 StartPos | 517 | public Vector3 StartPos |
518 | { | 518 | { |
519 | get { return new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 50); } | 519 | get { return new Vector3(m_scene.RegionInfo.RegionSizeX * 0.5f, m_scene.RegionInfo.RegionSizeY * 0.5f, 50f); } |
520 | set { } | 520 | set { } |
521 | } | 521 | } |
522 | 522 | ||
@@ -660,6 +660,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
660 | public event BakeTerrain OnBakeTerrain; | 660 | public event BakeTerrain OnBakeTerrain; |
661 | public event EstateChangeInfo OnEstateChangeInfo; | 661 | public event EstateChangeInfo OnEstateChangeInfo; |
662 | public event EstateManageTelehub OnEstateManageTelehub; | 662 | public event EstateManageTelehub OnEstateManageTelehub; |
663 | public event CachedTextureRequest OnCachedTextureRequest; | ||
663 | public event SetAppearance OnSetAppearance; | 664 | public event SetAppearance OnSetAppearance; |
664 | public event AvatarNowWearing OnAvatarNowWearing; | 665 | public event AvatarNowWearing OnAvatarNowWearing; |
665 | public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; | 666 | public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; |
@@ -686,6 +687,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
686 | public event Action<IClientAPI, bool> OnCompleteMovementToRegion; | 687 | public event Action<IClientAPI, bool> OnCompleteMovementToRegion; |
687 | public event UpdateAgent OnPreAgentUpdate; | 688 | public event UpdateAgent OnPreAgentUpdate; |
688 | public event UpdateAgent OnAgentUpdate; | 689 | public event UpdateAgent OnAgentUpdate; |
690 | public event UpdateAgent OnAgentCameraUpdate; | ||
689 | public event AgentRequestSit OnAgentRequestSit; | 691 | public event AgentRequestSit OnAgentRequestSit; |
690 | public event AgentSit OnAgentSit; | 692 | public event AgentSit OnAgentSit; |
691 | public event AvatarPickerRequest OnAvatarPickerRequest; | 693 | public event AvatarPickerRequest OnAvatarPickerRequest; |
@@ -901,12 +903,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
901 | 903 | ||
902 | public void Start() | 904 | public void Start() |
903 | { | 905 | { |
904 | m_scene.AddNewClient(this, PresenceType.User); | 906 | m_scene.AddNewAgent(this, PresenceType.User); |
905 | 907 | ||
906 | // Mimicking LLClientView which gets always set appearance from client. | 908 | // Mimicking LLClientView which gets always set appearance from client. |
907 | AvatarAppearance appearance; | 909 | AvatarAppearance appearance; |
908 | m_scene.GetAvatarAppearance(this, out appearance); | 910 | m_scene.GetAvatarAppearance(this, out appearance); |
909 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); | 911 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]); |
910 | } | 912 | } |
911 | 913 | ||
912 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) | 914 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) |
@@ -938,13 +940,18 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
938 | { | 940 | { |
939 | 941 | ||
940 | } | 942 | } |
943 | |||
944 | public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures) | ||
945 | { | ||
941 | 946 | ||
947 | } | ||
948 | |||
942 | public void SendStartPingCheck(byte seq) | 949 | public void SendStartPingCheck(byte seq) |
943 | { | 950 | { |
944 | 951 | ||
945 | } | 952 | } |
946 | 953 | ||
947 | public void SendKillObject(ulong regionHandle, List<uint> localID) | 954 | public void SendKillObject(List<uint> localID) |
948 | { | 955 | { |
949 | 956 | ||
950 | } | 957 | } |
@@ -971,12 +978,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
971 | // TODO | 978 | // TODO |
972 | } | 979 | } |
973 | 980 | ||
974 | public void SendGenericMessage(string method, List<string> message) | 981 | public void SendGenericMessage(string method, UUID invoice, List<string> message) |
975 | { | 982 | { |
976 | 983 | ||
977 | } | 984 | } |
978 | 985 | ||
979 | public void SendGenericMessage(string method, List<byte[]> message) | 986 | public void SendGenericMessage(string method, UUID invoice, List<byte[]> message) |
980 | { | 987 | { |
981 | 988 | ||
982 | } | 989 | } |
@@ -1050,7 +1057,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1050 | { | 1057 | { |
1051 | } | 1058 | } |
1052 | 1059 | ||
1053 | public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance) | 1060 | public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item) |
1054 | { | 1061 | { |
1055 | 1062 | ||
1056 | } | 1063 | } |
@@ -1190,11 +1197,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1190 | 1197 | ||
1191 | } | 1198 | } |
1192 | 1199 | ||
1193 | public bool AddMoney(int debit) | ||
1194 | { | ||
1195 | return true; | ||
1196 | } | ||
1197 | |||
1198 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition) | 1200 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition) |
1199 | { | 1201 | { |
1200 | 1202 | ||
@@ -1424,9 +1426,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1424 | return new byte[0]; | 1426 | return new byte[0]; |
1425 | } | 1427 | } |
1426 | 1428 | ||
1429 | #pragma warning disable 0067 | ||
1427 | public event ViewerEffectEventHandler OnViewerEffect; | 1430 | public event ViewerEffectEventHandler OnViewerEffect; |
1428 | public event Action<IClientAPI> OnLogout; | 1431 | public event Action<IClientAPI> OnLogout; |
1429 | public event Action<IClientAPI> OnConnectionClosed; | 1432 | public event Action<IClientAPI> OnConnectionClosed; |
1433 | #pragma warning restore 0067 | ||
1430 | 1434 | ||
1431 | public void SendBlueBoxMessage(UUID FromAvatarID, string FromAvatarName, string Message) | 1435 | public void SendBlueBoxMessage(UUID FromAvatarID, string FromAvatarName, string Message) |
1432 | { | 1436 | { |
@@ -1671,12 +1675,17 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1671 | { | 1675 | { |
1672 | } | 1676 | } |
1673 | 1677 | ||
1674 | public void StopFlying(ISceneEntity presence) | 1678 | public void SendAgentTerseUpdate(ISceneEntity presence) |
1675 | { | 1679 | { |
1676 | } | 1680 | } |
1677 | 1681 | ||
1678 | public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data) | 1682 | public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data) |
1679 | { | 1683 | { |
1680 | } | 1684 | } |
1685 | |||
1686 | public void SendPartPhysicsProprieties(ISceneEntity entity) | ||
1687 | { | ||
1688 | } | ||
1689 | |||
1681 | } | 1690 | } |
1682 | } | 1691 | } |
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 992f38e..08d0fbf 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
30 | using System.Reflection; | 31 | using System.Reflection; |
31 | using System.Text; | 32 | using System.Text; |
32 | using log4net; | 33 | using log4net; |
@@ -51,7 +52,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
51 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")] | 52 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")] |
52 | public class LindenUDPInfoModule : ISharedRegionModule | 53 | public class LindenUDPInfoModule : ISharedRegionModule |
53 | { | 54 | { |
54 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | 56 | ||
56 | protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | 57 | protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); |
57 | 58 | ||
@@ -130,6 +131,15 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
130 | "Go on/off emergency monitoring mode", | 131 | "Go on/off emergency monitoring mode", |
131 | "Go on/off emergency monitoring mode", | 132 | "Go on/off emergency monitoring mode", |
132 | HandleEmergencyMonitoring); | 133 | HandleEmergencyMonitoring); |
134 | |||
135 | scene.AddCommand( | ||
136 | "Comms", this, "show client stats", | ||
137 | "show client stats [first_name last_name]", | ||
138 | "Show client request stats", | ||
139 | "Without the 'first_name last_name' option, all clients are shown." | ||
140 | + " With the 'first_name last_name' option only a specific client is shown.", | ||
141 | (mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd))); | ||
142 | |||
133 | } | 143 | } |
134 | 144 | ||
135 | public void RemoveRegion(Scene scene) | 145 | public void RemoveRegion(Scene scene) |
@@ -294,7 +304,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
294 | private string GetImageQueuesReport(string[] showParams) | 304 | private string GetImageQueuesReport(string[] showParams) |
295 | { | 305 | { |
296 | if (showParams.Length < 5 || showParams.Length > 6) | 306 | if (showParams.Length < 5 || showParams.Length > 6) |
297 | return "Usage: image queues show <first-name> <last-name> [full]"; | 307 | return "Usage: show image queues <first-name> <last-name> [full]"; |
298 | 308 | ||
299 | string firstName = showParams[3]; | 309 | string firstName = showParams[3]; |
300 | string lastName = showParams[4]; | 310 | string lastName = showParams[4]; |
@@ -385,7 +395,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
385 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); | 395 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); |
386 | 396 | ||
387 | report.AppendFormat( | 397 | report.AppendFormat( |
388 | "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7} {12,7}\n", | 398 | "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7}\n", |
389 | "Since", | 399 | "Since", |
390 | "Pkts", | 400 | "Pkts", |
391 | "Pkts", | 401 | "Pkts", |
@@ -397,12 +407,11 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
397 | "Q Pkts", | 407 | "Q Pkts", |
398 | "Q Pkts", | 408 | "Q Pkts", |
399 | "Q Pkts", | 409 | "Q Pkts", |
400 | "Q Pkts", | ||
401 | "Q Pkts"); | 410 | "Q Pkts"); |
402 | 411 | ||
403 | report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); | 412 | report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); |
404 | report.AppendFormat( | 413 | report.AppendFormat( |
405 | "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7} {12,7}\n", | 414 | "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7}\n", |
406 | "Last In", | 415 | "Last In", |
407 | "In", | 416 | "In", |
408 | "Out", | 417 | "Out", |
@@ -414,8 +423,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
414 | "Cloud", | 423 | "Cloud", |
415 | "Task", | 424 | "Task", |
416 | "Texture", | 425 | "Texture", |
417 | "Asset", | 426 | "Asset"); |
418 | "State"); | ||
419 | 427 | ||
420 | lock (m_scenes) | 428 | lock (m_scenes) |
421 | { | 429 | { |
@@ -424,24 +432,24 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
424 | scene.ForEachClient( | 432 | scene.ForEachClient( |
425 | delegate(IClientAPI client) | 433 | delegate(IClientAPI client) |
426 | { | 434 | { |
427 | bool isChild = client.SceneAgent.IsChildAgent; | ||
428 | if (isChild && !showChildren) | ||
429 | return; | ||
430 | |||
431 | string name = client.Name; | ||
432 | if (pname != "" && name != pname) | ||
433 | return; | ||
434 | |||
435 | string regionName = scene.RegionInfo.RegionName; | ||
436 | |||
437 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | ||
438 | report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding)); | ||
439 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); | ||
440 | |||
441 | if (client is IStatsCollector) | 435 | if (client is IStatsCollector) |
442 | { | 436 | { |
443 | IStatsCollector stats = (IStatsCollector)client; | 437 | |
438 | bool isChild = client.SceneAgent.IsChildAgent; | ||
439 | if (isChild && !showChildren) | ||
440 | return; | ||
444 | 441 | ||
442 | string name = client.Name; | ||
443 | if (pname != "" && name != pname) | ||
444 | return; | ||
445 | |||
446 | string regionName = scene.RegionInfo.RegionName; | ||
447 | |||
448 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | ||
449 | report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding)); | ||
450 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); | ||
451 | |||
452 | IStatsCollector stats = (IStatsCollector)client; | ||
445 | report.AppendLine(stats.Report()); | 453 | report.AppendLine(stats.Report()); |
446 | } | 454 | } |
447 | }); | 455 | }); |
@@ -479,8 +487,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
479 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); | 487 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); |
480 | 488 | ||
481 | report.AppendFormat( | 489 | report.AppendFormat( |
482 | "{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", |
483 | "Total", | 491 | "Max", |
492 | "Target", | ||
493 | "Actual", | ||
484 | "Resend", | 494 | "Resend", |
485 | "Land", | 495 | "Land", |
486 | "Wind", | 496 | "Wind", |
@@ -491,7 +501,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
491 | 501 | ||
492 | report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); | 502 | report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); |
493 | report.AppendFormat( | 503 | report.AppendFormat( |
494 | "{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", | ||
495 | "kb/s", | 507 | "kb/s", |
496 | "kb/s", | 508 | "kb/s", |
497 | "kb/s", | 509 | "kb/s", |
@@ -503,8 +515,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
503 | 515 | ||
504 | report.AppendLine(); | 516 | report.AppendLine(); |
505 | 517 | ||
506 | bool firstClient = true; | ||
507 | |||
508 | lock (m_scenes) | 518 | lock (m_scenes) |
509 | { | 519 | { |
510 | foreach (Scene scene in m_scenes.Values) | 520 | foreach (Scene scene in m_scenes.Values) |
@@ -516,12 +526,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
516 | { | 526 | { |
517 | LLClientView llClient = client as LLClientView; | 527 | LLClientView llClient = client as LLClientView; |
518 | 528 | ||
519 | if (firstClient) | ||
520 | { | ||
521 | report.AppendLine(GetServerThrottlesReport(llClient.UDPServer)); | ||
522 | firstClient = false; | ||
523 | } | ||
524 | |||
525 | bool isChild = client.SceneAgent.IsChildAgent; | 529 | bool isChild = client.SceneAgent.IsChildAgent; |
526 | if (isChild && !showChildren) | 530 | if (isChild && !showChildren) |
527 | return; | 531 | return; |
@@ -540,7 +544,11 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
540 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); | 544 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); |
541 | 545 | ||
542 | report.AppendFormat( | 546 | report.AppendFormat( |
543 | "{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(), | ||
544 | (ci.totalThrottle * 8) / 1000, | 552 | (ci.totalThrottle * 8) / 1000, |
545 | (ci.resendThrottle * 8) / 1000, | 553 | (ci.resendThrottle * 8) / 1000, |
546 | (ci.landThrottle * 8) / 1000, | 554 | (ci.landThrottle * 8) / 1000, |
@@ -548,9 +556,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
548 | (ci.cloudThrottle * 8) / 1000, | 556 | (ci.cloudThrottle * 8) / 1000, |
549 | (ci.taskThrottle * 8) / 1000, | 557 | (ci.taskThrottle * 8) / 1000, |
550 | (ci.textureThrottle * 8) / 1000, | 558 | (ci.textureThrottle * 8) / 1000, |
551 | (ci.assetThrottle * 8) / 1000); | 559 | (ci.assetThrottle * 8) / 1000); |
552 | |||
553 | report.AppendLine(); | ||
554 | } | 560 | } |
555 | }); | 561 | }); |
556 | } | 562 | } |
@@ -558,35 +564,116 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
558 | 564 | ||
559 | return report.ToString(); | 565 | return report.ToString(); |
560 | } | 566 | } |
561 | 567 | ||
562 | protected string GetServerThrottlesReport(LLUDPServer udpServer) | 568 | /// <summary> |
569 | /// Show client stats data | ||
570 | /// </summary> | ||
571 | /// <param name="showParams"></param> | ||
572 | /// <returns></returns> | ||
573 | protected string HandleClientStatsReport(string[] showParams) | ||
563 | { | 574 | { |
564 | StringBuilder report = new StringBuilder(); | 575 | // NOTE: This writes to m_log on purpose. We want to store this information |
565 | 576 | // in case we need to analyze it later. | |
566 | int columnPadding = 2; | 577 | // |
567 | int maxNameLength = 18; | 578 | if (showParams.Length <= 4) |
568 | int maxRegionNameLength = 14; | 579 | { |
569 | int maxTypeLength = 4; | 580 | m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates"); |
570 | 581 | foreach (Scene scene in m_scenes.Values) | |
571 | string name = "SERVER AGENT RATES"; | 582 | { |
572 | 583 | scene.ForEachClient( | |
573 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | 584 | delegate(IClientAPI client) |
574 | report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding)); | 585 | { |
575 | report.Append(GetColumnEntry("-", maxTypeLength, columnPadding)); | 586 | if (client is LLClientView) |
576 | 587 | { | |
577 | ThrottleRates throttleRates = udpServer.ThrottleRates; | 588 | LLClientView llClient = client as LLClientView; |
578 | report.AppendFormat( | 589 | ClientInfo cinfo = llClient.UDPClient.GetClientInfo(); |
579 | "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", | 590 | int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); |
580 | (throttleRates.Total * 8) / 1000, | 591 | avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); |
581 | (throttleRates.Resend * 8) / 1000, | 592 | |
582 | (throttleRates.Land * 8) / 1000, | 593 | string childAgentStatus; |
583 | (throttleRates.Wind * 8) / 1000, | 594 | |
584 | (throttleRates.Cloud * 8) / 1000, | 595 | if (llClient.SceneAgent != null) |
585 | (throttleRates.Task * 8) / 1000, | 596 | childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y"; |
586 | (throttleRates.Texture * 8) / 1000, | 597 | else |
587 | (throttleRates.Asset * 8) / 1000); | 598 | childAgentStatus = "Off!"; |
599 | |||
600 | m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", | ||
601 | scene.RegionInfo.RegionName, llClient.Name, | ||
602 | childAgentStatus, | ||
603 | (DateTime.Now - cinfo.StartedTime).Minutes, | ||
604 | avg_reqs, | ||
605 | string.Format( | ||
606 | "{0} ({1:0.00}%)", | ||
607 | llClient.TotalAgentUpdates, | ||
608 | cinfo.SyncRequests.ContainsKey("AgentUpdate") | ||
609 | ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100 | ||
610 | : 0)); | ||
611 | } | ||
612 | }); | ||
613 | } | ||
614 | return string.Empty; | ||
615 | } | ||
588 | 616 | ||
589 | return report.ToString(); | 617 | string fname = "", lname = ""; |
590 | } | 618 | |
619 | if (showParams.Length > 3) | ||
620 | fname = showParams[3]; | ||
621 | if (showParams.Length > 4) | ||
622 | lname = showParams[4]; | ||
623 | |||
624 | foreach (Scene scene in m_scenes.Values) | ||
625 | { | ||
626 | scene.ForEachClient( | ||
627 | delegate(IClientAPI client) | ||
628 | { | ||
629 | if (client is LLClientView) | ||
630 | { | ||
631 | LLClientView llClient = client as LLClientView; | ||
632 | |||
633 | if (llClient.Name == fname + " " + lname) | ||
634 | { | ||
635 | |||
636 | ClientInfo cinfo = llClient.GetClientInfo(); | ||
637 | AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode); | ||
638 | if (aCircuit == null) // create a dummy one | ||
639 | aCircuit = new AgentCircuitData(); | ||
640 | |||
641 | if (!llClient.SceneAgent.IsChildAgent) | ||
642 | m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0); | ||
643 | |||
644 | int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); | ||
645 | avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); | ||
646 | |||
647 | m_log.InfoFormat("[INFO]:"); | ||
648 | m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName, | ||
649 | (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs); | ||
650 | |||
651 | Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry) | ||
652 | .ToDictionary(pair => pair.Key, pair => pair.Value); | ||
653 | PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum()); | ||
654 | |||
655 | sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry) | ||
656 | .ToDictionary(pair => pair.Key, pair => pair.Value); | ||
657 | PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum()); | ||
658 | |||
659 | sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry) | ||
660 | .ToDictionary(pair => pair.Key, pair => pair.Value); | ||
661 | PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum()); | ||
662 | } | ||
663 | } | ||
664 | }); | ||
665 | } | ||
666 | return string.Empty; | ||
667 | } | ||
668 | |||
669 | private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum) | ||
670 | { | ||
671 | m_log.InfoFormat("[INFO]:"); | ||
672 | m_log.InfoFormat("[INFO]: {0,25}", type); | ||
673 | foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12)) | ||
674 | m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); | ||
675 | m_log.InfoFormat("[INFO]: {0,25}", "..."); | ||
676 | m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum); | ||
677 | } | ||
591 | } | 678 | } |
592 | } \ 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 d718a2f..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 | { |
@@ -222,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
222 | { | 238 | { |
223 | bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); | 239 | bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); |
224 | MainConsole.Instance.OutputFormat( | 240 | MainConsole.Instance.OutputFormat( |
225 | "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); | 241 | "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete"); |
226 | } | 242 | } |
227 | ); | 243 | ); |
228 | } | 244 | } |
@@ -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/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index d97e3b3..0333747 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs | |||
@@ -176,16 +176,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
176 | // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", | 176 | // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", |
177 | // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, | 177 | // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, |
178 | // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); | 178 | // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); |
179 | ct.Rows.Add( | 179 | |
180 | new ConsoleDisplayTableRow( | 180 | ct.AddRow( |
181 | new List<string>() | 181 | attachmentObject.Name, |
182 | { | 182 | attachmentObject.LocalId, |
183 | attachmentObject.Name, | 183 | attachmentObject.FromItemID, |
184 | attachmentObject.LocalId.ToString(), | 184 | ((AttachmentPoint)attachmentObject.AttachmentPoint), |
185 | attachmentObject.FromItemID.ToString(), | 185 | attachmentObject.RootPart.AttachedPos); |
186 | ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), | ||
187 | attachmentObject.RootPart.AttachedPos.ToString() | ||
188 | })); | ||
189 | // } | 186 | // } |
190 | } | 187 | } |
191 | 188 | ||
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index d7fb272..535bf67 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | |||
@@ -40,6 +40,7 @@ using OpenSim.Framework.Monitoring; | |||
40 | using OpenSim.Region.ClientStack.LindenUDP; | 40 | using OpenSim.Region.ClientStack.LindenUDP; |
41 | using OpenSim.Region.Framework.Interfaces; | 41 | using OpenSim.Region.Framework.Interfaces; |
42 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
43 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
43 | 44 | ||
44 | namespace OpenSim.Region.OptionalModules.Avatar.Attachments | 45 | namespace OpenSim.Region.OptionalModules.Avatar.Attachments |
45 | { | 46 | { |
@@ -76,7 +77,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
76 | 77 | ||
77 | if (m_console != null) | 78 | if (m_console != null) |
78 | { | 79 | { |
79 | m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); | 80 | m_console.AddCommand("TempAttachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner or estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); |
80 | } | 81 | } |
81 | } | 82 | } |
82 | else | 83 | else |
@@ -183,7 +184,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
183 | hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); | 184 | hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); |
184 | } | 185 | } |
185 | 186 | ||
186 | return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true) ? 1 : 0; | 187 | return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true) ? 1 : 0; |
187 | } | 188 | } |
188 | } | 189 | } |
189 | } | 190 | } |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 66265d8..b5d9fda 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | |||
@@ -55,42 +55,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
55 | // These are the IRC Connector configurable parameters with hard-wired | 55 | // These are the IRC Connector configurable parameters with hard-wired |
56 | // default values (retained for compatability). | 56 | // default values (retained for compatability). |
57 | 57 | ||
58 | internal string Server = null; | 58 | internal string Server = null; |
59 | internal string Password = null; | 59 | internal string Password = null; |
60 | internal string IrcChannel = null; | 60 | internal string IrcChannel = null; |
61 | internal string BaseNickname = "OSimBot"; | 61 | internal string BaseNickname = "OSimBot"; |
62 | internal uint Port = 6667; | 62 | internal uint Port = 6667; |
63 | internal string User = null; | 63 | internal string User = null; |
64 | 64 | ||
65 | internal bool ClientReporting = true; | 65 | internal bool ClientReporting = true; |
66 | internal bool RelayChat = true; | 66 | internal bool RelayChat = true; |
67 | internal bool RelayPrivateChannels = false; | 67 | internal bool RelayPrivateChannels = false; |
68 | internal int RelayChannel = 1; | 68 | internal int RelayChannel = 1; |
69 | internal List<int> ValidInWorldChannels = new List<int>(); | 69 | internal List<int> ValidInWorldChannels = new List<int>(); |
70 | 70 | ||
71 | // Connector agnostic parameters. These values are NOT shared with the | 71 | // Connector agnostic parameters. These values are NOT shared with the |
72 | // connector and do not differentiate at an IRC level | 72 | // connector and do not differentiate at an IRC level |
73 | 73 | ||
74 | internal string PrivateMessageFormat = "PRIVMSG {0} :<{2}> {1} {3}"; | 74 | internal string PrivateMessageFormat = "PRIVMSG {0} :<{2}> {1} {3}"; |
75 | internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; | 75 | internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; |
76 | internal int RelayChannelOut = -1; | 76 | internal int RelayChannelOut = -1; |
77 | internal bool RandomizeNickname = true; | 77 | internal bool RandomizeNickname = true; |
78 | internal bool CommandsEnabled = false; | 78 | internal bool CommandsEnabled = false; |
79 | internal int CommandChannel = -1; | 79 | internal int CommandChannel = -1; |
80 | internal int ConnectDelay = 10; | 80 | internal int ConnectDelay = 10; |
81 | internal int PingDelay = 15; | 81 | internal int PingDelay = 15; |
82 | internal string DefaultZone = "Sim"; | 82 | internal string DefaultZone = "Sim"; |
83 | 83 | ||
84 | internal string _accessPassword = String.Empty; | 84 | internal string _accessPassword = String.Empty; |
85 | internal Regex AccessPasswordRegex = null; | 85 | internal Regex AccessPasswordRegex = null; |
86 | internal List<string> ExcludeList = new List<string>(); | 86 | internal List<string> ExcludeList = new List<string>(); |
87 | internal string AccessPassword | 87 | internal string AccessPassword |
88 | { | 88 | { |
89 | get { return _accessPassword; } | 89 | get { return _accessPassword; } |
90 | set | 90 | set |
91 | { | 91 | { |
92 | _accessPassword = value; | 92 | _accessPassword = value; |
93 | AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?<avatar>[^,]+),\s*(?<message>.+)$", _accessPassword), | 93 | AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?<avatar>[^,]+),\s*(?<message>.+)$", _accessPassword), |
94 | RegexOptions.Compiled); | 94 | RegexOptions.Compiled); |
95 | } | 95 | } |
96 | } | 96 | } |
@@ -99,9 +99,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
99 | 99 | ||
100 | // IRC connector reference | 100 | // IRC connector reference |
101 | 101 | ||
102 | internal IRCConnector irc = null; | 102 | internal IRCConnector irc = null; |
103 | 103 | ||
104 | internal int idn = _idk_++; | 104 | internal int idn = _idk_++; |
105 | 105 | ||
106 | // List of regions dependent upon this connection | 106 | // List of regions dependent upon this connection |
107 | 107 | ||
@@ -119,29 +119,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
119 | 119 | ||
120 | internal ChannelState(ChannelState model) | 120 | internal ChannelState(ChannelState model) |
121 | { | 121 | { |
122 | Server = model.Server; | 122 | Server = model.Server; |
123 | Password = model.Password; | 123 | Password = model.Password; |
124 | IrcChannel = model.IrcChannel; | 124 | IrcChannel = model.IrcChannel; |
125 | Port = model.Port; | 125 | Port = model.Port; |
126 | BaseNickname = model.BaseNickname; | 126 | BaseNickname = model.BaseNickname; |
127 | RandomizeNickname = model.RandomizeNickname; | 127 | RandomizeNickname = model.RandomizeNickname; |
128 | User = model.User; | 128 | User = model.User; |
129 | CommandsEnabled = model.CommandsEnabled; | 129 | CommandsEnabled = model.CommandsEnabled; |
130 | CommandChannel = model.CommandChannel; | 130 | CommandChannel = model.CommandChannel; |
131 | RelayChat = model.RelayChat; | 131 | RelayChat = model.RelayChat; |
132 | RelayPrivateChannels = model.RelayPrivateChannels; | 132 | RelayPrivateChannels = model.RelayPrivateChannels; |
133 | RelayChannelOut = model.RelayChannelOut; | 133 | RelayChannelOut = model.RelayChannelOut; |
134 | RelayChannel = model.RelayChannel; | 134 | RelayChannel = model.RelayChannel; |
135 | ValidInWorldChannels = model.ValidInWorldChannels; | 135 | ValidInWorldChannels = model.ValidInWorldChannels; |
136 | PrivateMessageFormat = model.PrivateMessageFormat; | 136 | PrivateMessageFormat = model.PrivateMessageFormat; |
137 | NoticeMessageFormat = model.NoticeMessageFormat; | 137 | NoticeMessageFormat = model.NoticeMessageFormat; |
138 | ClientReporting = model.ClientReporting; | 138 | ClientReporting = model.ClientReporting; |
139 | AccessPassword = model.AccessPassword; | 139 | AccessPassword = model.AccessPassword; |
140 | DefaultZone = model.DefaultZone; | 140 | DefaultZone = model.DefaultZone; |
141 | ConnectDelay = model.ConnectDelay; | 141 | ConnectDelay = model.ConnectDelay; |
142 | PingDelay = model.PingDelay; | 142 | PingDelay = model.PingDelay; |
143 | } | 143 | } |
144 | 144 | ||
145 | // Read the configuration file, performing variable substitution and any | 145 | // Read the configuration file, performing variable substitution and any |
146 | // necessary aliasing. See accompanying documentation for how this works. | 146 | // necessary aliasing. See accompanying documentation for how this works. |
147 | // If you don't need variables, then this works exactly as before. | 147 | // If you don't need variables, then this works exactly as before. |
@@ -160,54 +160,54 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
160 | 160 | ||
161 | m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); | 161 | m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); |
162 | 162 | ||
163 | cs.Server = Substitute(rs, config.GetString("server", null)); | 163 | cs.Server = Substitute(rs, config.GetString("server", null)); |
164 | m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); | 164 | m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); |
165 | cs.Password = Substitute(rs, config.GetString("password", null)); | 165 | cs.Password = Substitute(rs, config.GetString("password", null)); |
166 | // probably not a good idea to put a password in the log file | 166 | // probably not a good idea to put a password in the log file |
167 | cs.User = Substitute(rs, config.GetString("user", null)); | 167 | cs.User = Substitute(rs, config.GetString("user", null)); |
168 | cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); | 168 | cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); |
169 | m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); | 169 | m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); |
170 | cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); | 170 | cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); |
171 | m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); | 171 | m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); |
172 | cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); | 172 | cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); |
173 | m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); | 173 | m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); |
174 | cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); | 174 | cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); |
175 | m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); | 175 | m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); |
176 | cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); | 176 | cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); |
177 | m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); | 177 | m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); |
178 | cs.User = Substitute(rs, config.GetString("username", cs.User)); | 178 | cs.User = Substitute(rs, config.GetString("username", cs.User)); |
179 | m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); | 179 | m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); |
180 | cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); | 180 | cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); |
181 | m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); | 181 | m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); |
182 | cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); | 182 | cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); |
183 | m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); | 183 | m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); |
184 | cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); | 184 | cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); |
185 | m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); | 185 | m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); |
186 | cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); | 186 | cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); |
187 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); | 187 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); |
188 | cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); | 188 | cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); |
189 | m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); | 189 | m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); |
190 | cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); | 190 | cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); |
191 | m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); | 191 | m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); |
192 | cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); | 192 | cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); |
193 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); | 193 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); |
194 | cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); | 194 | cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); |
195 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); | 195 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); |
196 | cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); | 196 | cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); |
197 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); | 197 | m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); |
198 | cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); | 198 | cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); |
199 | m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); | 199 | m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); |
200 | cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); | 200 | cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); |
201 | m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); | 201 | m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); |
202 | cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting?"1":"0"))) > 0; | 202 | cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting ? "1" : "0"))) > 0; |
203 | m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); | 203 | m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); |
204 | cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); | 204 | cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); |
205 | m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); | 205 | m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); |
206 | cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); | 206 | cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); |
207 | m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); | 207 | m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); |
208 | cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); | 208 | cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); |
209 | m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); | 209 | m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); |
210 | cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); | 210 | cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); |
211 | m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); | 211 | m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); |
212 | cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); | 212 | cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); |
213 | m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); | 213 | m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); |
@@ -217,7 +217,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
217 | { | 217 | { |
218 | cs.ExcludeList.Add(name.Trim().ToLower()); | 218 | cs.ExcludeList.Add(name.Trim().ToLower()); |
219 | } | 219 | } |
220 | 220 | ||
221 | // Fail if fundamental information is still missing | 221 | // Fail if fundamental information is still missing |
222 | 222 | ||
223 | if (cs.Server == null) | 223 | if (cs.Server == null) |
@@ -306,8 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
306 | 306 | ||
307 | IRCBridgeModule.m_channels.Add(cs); | 307 | IRCBridgeModule.m_channels.Add(cs); |
308 | 308 | ||
309 | m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", | 309 | m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", |
310 | cs.idn, rs.Region, cs.DefaultZone, | 310 | cs.idn, rs.Region, cs.DefaultZone, |
311 | cs.CommandsEnabled ? "enabled" : "not enabled", | 311 | cs.CommandsEnabled ? "enabled" : "not enabled", |
312 | cs.RelayPrivateChannels ? "relayed" : "not relayed"); | 312 | cs.RelayPrivateChannels ? "relayed" : "not relayed"); |
313 | } | 313 | } |
@@ -417,7 +417,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
417 | private bool IsAConnectionMatchFor(ChannelState cs) | 417 | private bool IsAConnectionMatchFor(ChannelState cs) |
418 | { | 418 | { |
419 | return ( | 419 | return ( |
420 | Server == cs.Server && | 420 | Server == cs.Server && |
421 | IrcChannel == cs.IrcChannel && | 421 | IrcChannel == cs.IrcChannel && |
422 | Port == cs.Port && | 422 | Port == cs.Port && |
423 | BaseNickname == cs.BaseNickname && | 423 | BaseNickname == cs.BaseNickname && |
@@ -461,7 +461,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
461 | 461 | ||
462 | string result = instr; | 462 | string result = instr; |
463 | 463 | ||
464 | if (result == null || result.Length == 0) | 464 | if (string.IsNullOrEmpty(result)) |
465 | return result; | 465 | return result; |
466 | 466 | ||
467 | // Repeatedly scan the string until all possible | 467 | // Repeatedly scan the string until all possible |
@@ -473,27 +473,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
473 | { | 473 | { |
474 | 474 | ||
475 | string vvar = arg.Match(result).ToString(); | 475 | string vvar = arg.Match(result).ToString(); |
476 | string var = vvar.Substring(1,vvar.Length-2).Trim(); | 476 | string var = vvar.Substring(1, vvar.Length - 2).Trim(); |
477 | 477 | ||
478 | switch (var.ToLower()) | 478 | switch (var.ToLower()) |
479 | { | 479 | { |
480 | case "%region" : | 480 | case "%region": |
481 | result = result.Replace(vvar, rs.Region); | 481 | result = result.Replace(vvar, rs.Region); |
482 | break; | 482 | break; |
483 | case "%host" : | 483 | case "%host": |
484 | result = result.Replace(vvar, rs.Host); | 484 | result = result.Replace(vvar, rs.Host); |
485 | break; | 485 | break; |
486 | case "%locx" : | 486 | case "%locx": |
487 | result = result.Replace(vvar, rs.LocX); | 487 | result = result.Replace(vvar, rs.LocX); |
488 | break; | 488 | break; |
489 | case "%locy" : | 489 | case "%locy": |
490 | result = result.Replace(vvar, rs.LocY); | 490 | result = result.Replace(vvar, rs.LocY); |
491 | break; | 491 | break; |
492 | case "%k" : | 492 | case "%k": |
493 | result = result.Replace(vvar, rs.IDK); | 493 | result = result.Replace(vvar, rs.IDK); |
494 | break; | 494 | break; |
495 | default : | 495 | default: |
496 | result = result.Replace(vvar, rs.config.GetString(var,var)); | 496 | result = result.Replace(vvar, rs.config.GetString(var, var)); |
497 | break; | 497 | break; |
498 | } | 498 | } |
499 | // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); | 499 | // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 2e1d03d..351dbfe 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | |||
@@ -46,18 +46,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | internal static bool m_pluginEnabled = false; | 49 | internal static bool Enabled = false; |
50 | internal static IConfig m_config = null; | 50 | internal static IConfig m_config = null; |
51 | 51 | ||
52 | internal static List<ChannelState> m_channels = new List<ChannelState>(); | 52 | internal static List<ChannelState> m_channels = new List<ChannelState>(); |
53 | internal static List<RegionState> m_regions = new List<RegionState>(); | 53 | internal static List<RegionState> m_regions = new List<RegionState>(); |
54 | 54 | ||
55 | internal static string m_password = String.Empty; | 55 | internal static string m_password = String.Empty; |
56 | internal RegionState m_region = null; | 56 | internal RegionState m_region = null; |
57 | 57 | ||
58 | #region INonSharedRegionModule Members | 58 | #region INonSharedRegionModule Members |
59 | 59 | ||
60 | public Type ReplaceableInterface | 60 | public Type ReplaceableInterface |
61 | { | 61 | { |
62 | get { return null; } | 62 | get { return null; } |
63 | } | 63 | } |
@@ -72,13 +72,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
72 | m_config = config.Configs["IRC"]; | 72 | m_config = config.Configs["IRC"]; |
73 | if (m_config == null) | 73 | if (m_config == null) |
74 | { | 74 | { |
75 | // m_log.InfoFormat("[IRC-Bridge] module not configured"); | 75 | // m_log.InfoFormat("[IRC-Bridge] module not configured"); |
76 | return; | 76 | return; |
77 | } | 77 | } |
78 | 78 | ||
79 | if (!m_config.GetBoolean("enabled", false)) | 79 | if (!m_config.GetBoolean("enabled", false)) |
80 | { | 80 | { |
81 | // m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); | 81 | // m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); |
82 | return; | 82 | return; |
83 | } | 83 | } |
84 | 84 | ||
@@ -87,19 +87,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
87 | m_password = config.Configs["RemoteAdmin"].GetString("access_password", m_password); | 87 | m_password = config.Configs["RemoteAdmin"].GetString("access_password", m_password); |
88 | } | 88 | } |
89 | 89 | ||
90 | m_pluginEnabled = true; | 90 | Enabled = true; |
91 | m_log.InfoFormat("[IRC-Bridge]: Module enabled"); | 91 | |
92 | m_log.InfoFormat("[IRC-Bridge]: Module is enabled"); | ||
92 | } | 93 | } |
93 | 94 | ||
94 | public void AddRegion(Scene scene) | 95 | public void AddRegion(Scene scene) |
95 | { | 96 | { |
96 | if (m_pluginEnabled) | 97 | if (Enabled) |
97 | { | 98 | { |
98 | try | 99 | try |
99 | { | 100 | { |
100 | m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); | 101 | m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); |
102 | |||
101 | if (!String.IsNullOrEmpty(m_password)) | 103 | if (!String.IsNullOrEmpty(m_password)) |
102 | MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); | 104 | MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); |
105 | |||
103 | m_region = new RegionState(scene, m_config); | 106 | m_region = new RegionState(scene, m_config); |
104 | lock (m_regions) m_regions.Add(m_region); | 107 | lock (m_regions) m_regions.Add(m_region); |
105 | m_region.Open(); | 108 | m_region.Open(); |
@@ -123,7 +126,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
123 | 126 | ||
124 | public void RemoveRegion(Scene scene) | 127 | public void RemoveRegion(Scene scene) |
125 | { | 128 | { |
126 | if (!m_pluginEnabled) | 129 | if (!Enabled) |
127 | return; | 130 | return; |
128 | 131 | ||
129 | if (m_region == null) | 132 | if (m_region == null) |
@@ -150,12 +153,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
150 | m_log.Debug("[IRC-Bridge]: XML RPC Admin Entry"); | 153 | m_log.Debug("[IRC-Bridge]: XML RPC Admin Entry"); |
151 | 154 | ||
152 | XmlRpcResponse response = new XmlRpcResponse(); | 155 | XmlRpcResponse response = new XmlRpcResponse(); |
153 | Hashtable responseData = new Hashtable(); | 156 | Hashtable responseData = new Hashtable(); |
154 | 157 | ||
155 | try | 158 | try |
156 | { | 159 | { |
157 | Hashtable requestData = (Hashtable)request.Params[0]; | 160 | Hashtable requestData = (Hashtable)request.Params[0]; |
158 | bool found = false; | 161 | bool found = false; |
159 | string region = String.Empty; | 162 | string region = String.Empty; |
160 | 163 | ||
161 | if (m_password != String.Empty) | 164 | if (m_password != String.Empty) |
@@ -169,18 +172,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
169 | if (!requestData.ContainsKey("region")) | 172 | if (!requestData.ContainsKey("region")) |
170 | throw new Exception("No region name specified"); | 173 | throw new Exception("No region name specified"); |
171 | region = (string)requestData["region"]; | 174 | region = (string)requestData["region"]; |
172 | 175 | ||
173 | foreach (RegionState rs in m_regions) | 176 | foreach (RegionState rs in m_regions) |
174 | { | 177 | { |
175 | if (rs.Region == region) | 178 | if (rs.Region == region) |
176 | { | 179 | { |
177 | responseData["server"] = rs.cs.Server; | 180 | responseData["server"] = rs.cs.Server; |
178 | responseData["port"] = (int)rs.cs.Port; | 181 | responseData["port"] = (int)rs.cs.Port; |
179 | responseData["user"] = rs.cs.User; | 182 | responseData["user"] = rs.cs.User; |
180 | responseData["channel"] = rs.cs.IrcChannel; | 183 | responseData["channel"] = rs.cs.IrcChannel; |
181 | responseData["enabled"] = rs.cs.irc.Enabled; | 184 | responseData["enabled"] = rs.cs.irc.Enabled; |
182 | responseData["connected"] = rs.cs.irc.Connected; | 185 | responseData["connected"] = rs.cs.irc.Connected; |
183 | responseData["nickname"] = rs.cs.irc.Nick; | 186 | responseData["nickname"] = rs.cs.irc.Nick; |
184 | found = true; | 187 | found = true; |
185 | break; | 188 | break; |
186 | } | 189 | } |
@@ -195,7 +198,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
195 | m_log.ErrorFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); | 198 | m_log.ErrorFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); |
196 | 199 | ||
197 | responseData["success"] = "false"; | 200 | responseData["success"] = "false"; |
198 | responseData["error"] = e.Message; | 201 | responseData["error"] = e.Message; |
199 | } | 202 | } |
200 | finally | 203 | finally |
201 | { | 204 | { |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index a014798..6985371 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | |||
@@ -52,17 +52,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
52 | 52 | ||
53 | // Local constants | 53 | // Local constants |
54 | 54 | ||
55 | // This computation is not the real region center if the region is larger than 256. | ||
56 | // This computation isn't fixed because there is not a handle back to the region. | ||
55 | private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); | 57 | private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); |
56 | private static readonly char[] CS_SPACE = { ' ' }; | 58 | private static readonly char[] CS_SPACE = { ' ' }; |
57 | 59 | ||
58 | private const int WD_INTERVAL = 1000; // base watchdog interval | 60 | private const int WD_INTERVAL = 1000; // base watchdog interval |
59 | private static int PING_PERIOD = 15; // WD intervals per PING | 61 | private static int PING_PERIOD = 15; // WD intervals per PING |
60 | private static int ICCD_PERIOD = 10; // WD intervals between Connects | 62 | private static int ICCD_PERIOD = 10; // WD intervals between Connects |
61 | private static int L_TIMEOUT = 25; // Login time out interval | 63 | private static int L_TIMEOUT = 25; // Login time out interval |
62 | 64 | ||
63 | private static int _idk_ = 0; // core connector identifier | 65 | private static int _idk_ = 0; // core connector identifier |
64 | private static int _pdk_ = 0; // ping interval counter | 66 | private static int _pdk_ = 0; // ping interval counter |
65 | private static int _icc_ = ICCD_PERIOD; // IRC connect counter | 67 | private static int _icc_ = ICCD_PERIOD; // IRC connect counter |
66 | 68 | ||
67 | // List of configured connectors | 69 | // List of configured connectors |
68 | 70 | ||
@@ -107,13 +109,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
107 | 109 | ||
108 | internal int m_resetk = 0; | 110 | internal int m_resetk = 0; |
109 | 111 | ||
110 | // Working threads | ||
111 | |||
112 | private Thread m_listener = null; | ||
113 | |||
114 | private Object msyncConnect = new Object(); | 112 | private Object msyncConnect = new Object(); |
115 | 113 | ||
116 | internal bool m_randomizeNick = true; // add random suffix | 114 | internal bool m_randomizeNick = true; // add random suffix |
117 | internal string m_baseNick = null; // base name for randomizing | 115 | internal string m_baseNick = null; // base name for randomizing |
118 | internal string m_nick = null; // effective nickname | 116 | internal string m_nick = null; // effective nickname |
119 | 117 | ||
@@ -122,7 +120,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
122 | get { return m_nick; } | 120 | get { return m_nick; } |
123 | set { m_nick = value; } | 121 | set { m_nick = value; } |
124 | } | 122 | } |
125 | 123 | ||
126 | private bool m_enabled = false; // connector enablement | 124 | private bool m_enabled = false; // connector enablement |
127 | public bool Enabled | 125 | public bool Enabled |
128 | { | 126 | { |
@@ -130,8 +128,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
130 | } | 128 | } |
131 | 129 | ||
132 | private bool m_connected = false; // connection status | 130 | private bool m_connected = false; // connection status |
133 | private bool m_pending = false; // login disposition | 131 | private bool m_pending = false; // login disposition |
134 | private int m_timeout = L_TIMEOUT; // login timeout counter | 132 | private int m_timeout = L_TIMEOUT; // login timeout counter |
135 | public bool Connected | 133 | public bool Connected |
136 | { | 134 | { |
137 | get { return m_connected; } | 135 | get { return m_connected; } |
@@ -143,9 +141,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
143 | get { return m_ircChannel; } | 141 | get { return m_ircChannel; } |
144 | set { m_ircChannel = value; } | 142 | set { m_ircChannel = value; } |
145 | } | 143 | } |
146 | 144 | ||
147 | private uint m_port = 6667; // session port | 145 | private uint m_port = 6667; // session port |
148 | public uint Port | 146 | public uint Port |
149 | { | 147 | { |
150 | get { return m_port; } | 148 | get { return m_port; } |
151 | set { m_port = value; } | 149 | set { m_port = value; } |
@@ -172,10 +170,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
172 | 170 | ||
173 | // Network interface | 171 | // Network interface |
174 | 172 | ||
175 | private TcpClient m_tcp; | 173 | private TcpClient m_tcp; |
176 | private NetworkStream m_stream = null; | 174 | private NetworkStream m_stream = null; |
177 | private StreamReader m_reader; | 175 | private StreamReader m_reader; |
178 | private StreamWriter m_writer; | 176 | private StreamWriter m_writer; |
179 | 177 | ||
180 | // Channel characteristic info (if available) | 178 | // Channel characteristic info (if available) |
181 | 179 | ||
@@ -193,26 +191,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
193 | 191 | ||
194 | // Prepare network interface | 192 | // Prepare network interface |
195 | 193 | ||
196 | m_tcp = null; | 194 | m_tcp = null; |
197 | m_writer = null; | 195 | m_writer = null; |
198 | m_reader = null; | 196 | m_reader = null; |
199 | 197 | ||
200 | // Setup IRC session parameters | 198 | // Setup IRC session parameters |
201 | 199 | ||
202 | m_server = cs.Server; | 200 | m_server = cs.Server; |
203 | m_password = cs.Password; | 201 | m_password = cs.Password; |
204 | m_baseNick = cs.BaseNickname; | 202 | m_baseNick = cs.BaseNickname; |
205 | m_randomizeNick = cs.RandomizeNickname; | 203 | m_randomizeNick = cs.RandomizeNickname; |
206 | m_ircChannel = cs.IrcChannel; | 204 | m_ircChannel = cs.IrcChannel; |
207 | m_port = cs.Port; | 205 | m_port = cs.Port; |
208 | m_user = cs.User; | 206 | m_user = cs.User; |
209 | 207 | ||
210 | if (m_watchdog == null) | 208 | if (m_watchdog == null) |
211 | { | 209 | { |
212 | // Non-differentiating | 210 | // Non-differentiating |
213 | 211 | ||
214 | ICCD_PERIOD = cs.ConnectDelay; | 212 | ICCD_PERIOD = cs.ConnectDelay; |
215 | PING_PERIOD = cs.PingDelay; | 213 | PING_PERIOD = cs.PingDelay; |
216 | 214 | ||
217 | // Smaller values are not reasonable | 215 | // Smaller values are not reasonable |
218 | 216 | ||
@@ -235,7 +233,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
235 | 233 | ||
236 | if (m_randomizeNick) | 234 | if (m_randomizeNick) |
237 | m_nick = m_baseNick + Util.RandomClass.Next(1, 99); | 235 | m_nick = m_baseNick + Util.RandomClass.Next(1, 99); |
238 | else | 236 | else |
239 | m_nick = m_baseNick; | 237 | m_nick = m_baseNick; |
240 | 238 | ||
241 | m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); | 239 | m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); |
@@ -295,18 +293,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
295 | m_nick, m_ircChannel, m_server)); | 293 | m_nick, m_ircChannel, m_server)); |
296 | m_writer.Flush(); | 294 | m_writer.Flush(); |
297 | } | 295 | } |
298 | catch (Exception) {} | 296 | catch (Exception) { } |
299 | 297 | ||
300 | 298 | ||
301 | m_connected = false; | 299 | m_connected = false; |
302 | 300 | ||
303 | try { m_writer.Close(); } catch (Exception) {} | 301 | try { m_writer.Close(); } |
304 | try { m_reader.Close(); } catch (Exception) {} | 302 | catch (Exception) { } |
305 | try { m_stream.Close(); } catch (Exception) {} | 303 | try { m_reader.Close(); } |
306 | try { m_tcp.Close(); } catch (Exception) {} | 304 | catch (Exception) { } |
305 | try { m_stream.Close(); } | ||
306 | catch (Exception) { } | ||
307 | try { m_tcp.Close(); } | ||
308 | catch (Exception) { } | ||
307 | 309 | ||
308 | } | 310 | } |
309 | 311 | ||
310 | lock (m_connectors) | 312 | lock (m_connectors) |
311 | m_connectors.Remove(this); | 313 | m_connectors.Remove(this); |
312 | 314 | ||
@@ -347,20 +349,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
347 | if (m_connected) return; | 349 | if (m_connected) return; |
348 | 350 | ||
349 | m_connected = true; | 351 | m_connected = true; |
350 | m_pending = true; | 352 | m_pending = true; |
351 | m_timeout = L_TIMEOUT; | 353 | m_timeout = L_TIMEOUT; |
352 | 354 | ||
353 | m_tcp = new TcpClient(m_server, (int)m_port); | 355 | m_tcp = new TcpClient(m_server, (int)m_port); |
354 | m_stream = m_tcp.GetStream(); | 356 | m_stream = m_tcp.GetStream(); |
355 | m_reader = new StreamReader(m_stream); | 357 | m_reader = new StreamReader(m_stream); |
356 | m_writer = new StreamWriter(m_stream); | 358 | m_writer = new StreamWriter(m_stream); |
357 | 359 | ||
358 | 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); |
359 | 361 | ||
360 | m_listener = new Thread(new ThreadStart(ListenerRun)); | 362 | WorkManager.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); |
361 | m_listener.Name = "IRCConnectorListenerThread"; | ||
362 | m_listener.IsBackground = true; | ||
363 | m_listener.Start(); | ||
364 | 363 | ||
365 | // This is the message order recommended by RFC 2812 | 364 | // This is the message order recommended by RFC 2812 |
366 | if (m_password != null) | 365 | if (m_password != null) |
@@ -418,12 +417,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
418 | // the socket and it will disappear of its own accord, once this | 417 | // the socket and it will disappear of its own accord, once this |
419 | // processing is completed. | 418 | // processing is completed. |
420 | 419 | ||
421 | try { m_writer.Close(); } catch (Exception) {} | 420 | try { m_writer.Close(); } |
422 | try { m_reader.Close(); } catch (Exception) {} | 421 | catch (Exception) { } |
423 | try { m_tcp.Close(); } catch (Exception) {} | 422 | try { m_reader.Close(); } |
423 | catch (Exception) { } | ||
424 | try { m_tcp.Close(); } | ||
425 | catch (Exception) { } | ||
424 | 426 | ||
425 | m_connected = false; | 427 | m_connected = false; |
426 | m_pending = false; | 428 | m_pending = false; |
427 | m_resetk++; | 429 | m_resetk++; |
428 | 430 | ||
429 | } | 431 | } |
@@ -495,27 +497,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
495 | { | 497 | { |
496 | 498 | ||
497 | string inputLine; | 499 | string inputLine; |
498 | int resetk = m_resetk; | 500 | int resetk = m_resetk; |
499 | 501 | ||
500 | try | 502 | try |
501 | { | 503 | { |
502 | while (m_enabled && m_connected) | 504 | while (m_enabled && m_connected) |
503 | { | 505 | { |
504 | |||
505 | if ((inputLine = m_reader.ReadLine()) == null) | 506 | if ((inputLine = m_reader.ReadLine()) == null) |
506 | throw new Exception("Listener input socket closed"); | 507 | throw new Exception("Listener input socket closed"); |
507 | 508 | ||
509 | Watchdog.UpdateThread(); | ||
510 | |||
508 | // m_log.Info("[IRCConnector]: " + inputLine); | 511 | // m_log.Info("[IRCConnector]: " + inputLine); |
509 | 512 | ||
510 | if (inputLine.Contains("PRIVMSG")) | 513 | if (inputLine.Contains("PRIVMSG")) |
511 | { | 514 | { |
512 | |||
513 | Dictionary<string, string> data = ExtractMsg(inputLine); | 515 | Dictionary<string, string> data = ExtractMsg(inputLine); |
514 | 516 | ||
515 | // Any chat ??? | 517 | // Any chat ??? |
516 | if (data != null) | 518 | if (data != null) |
517 | { | 519 | { |
518 | |||
519 | OSChatMessage c = new OSChatMessage(); | 520 | OSChatMessage c = new OSChatMessage(); |
520 | c.Message = data["msg"]; | 521 | c.Message = data["msg"]; |
521 | c.Type = ChatTypeEnum.Region; | 522 | c.Type = ChatTypeEnum.Region; |
@@ -531,9 +532,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
531 | 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)); |
532 | 533 | ||
533 | ChannelState.OSChat(this, c, false); | 534 | ChannelState.OSChat(this, c, false); |
534 | |||
535 | } | 535 | } |
536 | |||
537 | } | 536 | } |
538 | else | 537 | else |
539 | { | 538 | { |
@@ -553,9 +552,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
553 | 552 | ||
554 | if (m_enabled && (m_resetk == resetk)) | 553 | if (m_enabled && (m_resetk == resetk)) |
555 | Reconnect(); | 554 | Reconnect(); |
555 | |||
556 | Watchdog.RemoveThread(); | ||
556 | } | 557 | } |
557 | 558 | ||
558 | 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>.*)", |
559 | RegexOptions.Multiline); | 560 | RegexOptions.Multiline); |
560 | 561 | ||
561 | private Dictionary<string, string> ExtractMsg(string input) | 562 | private Dictionary<string, string> ExtractMsg(string input) |
@@ -617,8 +618,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
617 | string[] commArgs; | 618 | string[] commArgs; |
618 | string c_server = m_server; | 619 | string c_server = m_server; |
619 | 620 | ||
620 | string pfx = String.Empty; | 621 | string pfx = String.Empty; |
621 | string cmd = String.Empty; | 622 | string cmd = String.Empty; |
622 | string parms = String.Empty; | 623 | string parms = String.Empty; |
623 | 624 | ||
624 | // ":" indicates that a prefix is present | 625 | // ":" indicates that a prefix is present |
@@ -627,15 +628,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
627 | // ":" indicates that the remainder of the | 628 | // ":" indicates that the remainder of the |
628 | // line is a single parameter value. | 629 | // line is a single parameter value. |
629 | 630 | ||
630 | commArgs = command.Split(CS_SPACE,2); | 631 | commArgs = command.Split(CS_SPACE, 2); |
631 | 632 | ||
632 | if (commArgs[0].StartsWith(":")) | 633 | if (commArgs[0].StartsWith(":")) |
633 | { | 634 | { |
634 | pfx = commArgs[0].Substring(1); | 635 | pfx = commArgs[0].Substring(1); |
635 | commArgs = commArgs[1].Split(CS_SPACE,2); | 636 | commArgs = commArgs[1].Split(CS_SPACE, 2); |
636 | } | 637 | } |
637 | 638 | ||
638 | cmd = commArgs[0]; | 639 | cmd = commArgs[0]; |
639 | parms = commArgs[1]; | 640 | parms = commArgs[1]; |
640 | 641 | ||
641 | // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd); | 642 | // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd); |
@@ -646,44 +647,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
646 | // Messages 001-004 are always sent | 647 | // Messages 001-004 are always sent |
647 | // following signon. | 648 | // following signon. |
648 | 649 | ||
649 | case "001" : // Welcome ... | 650 | case "001": // Welcome ... |
650 | case "002" : // Server information | 651 | case "002": // Server information |
651 | case "003" : // Welcome ... | 652 | case "003": // Welcome ... |
652 | break; | 653 | break; |
653 | case "004" : // Server information | 654 | case "004": // Server information |
654 | m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); | 655 | m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); |
655 | commArgs = parms.Split(CS_SPACE); | 656 | commArgs = parms.Split(CS_SPACE); |
656 | c_server = commArgs[1]; | 657 | c_server = commArgs[1]; |
657 | m_server = c_server; | 658 | m_server = c_server; |
658 | version = commArgs[2]; | 659 | version = commArgs[2]; |
659 | usermod = commArgs[3]; | 660 | usermod = commArgs[3]; |
660 | chanmod = commArgs[4]; | 661 | chanmod = commArgs[4]; |
661 | break; | 662 | break; |
662 | case "005" : // Server information | 663 | case "005": // Server information |
663 | break; | 664 | break; |
664 | case "042" : | 665 | case "042": |
665 | case "250" : | 666 | case "250": |
666 | case "251" : | 667 | case "251": |
667 | case "252" : | 668 | case "252": |
668 | case "254" : | 669 | case "254": |
669 | case "255" : | 670 | case "255": |
670 | case "265" : | 671 | case "265": |
671 | case "266" : | 672 | case "266": |
672 | case "332" : // Subject | 673 | case "332": // Subject |
673 | case "333" : // Subject owner (?) | 674 | case "333": // Subject owner (?) |
674 | case "353" : // Name list | 675 | case "353": // Name list |
675 | case "366" : // End-of-Name list marker | 676 | case "366": // End-of-Name list marker |
676 | case "372" : // MOTD body | 677 | case "372": // MOTD body |
677 | case "375" : // MOTD start | 678 | case "375": // MOTD start |
678 | // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); | 679 | // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); |
679 | break; | 680 | break; |
680 | case "376" : // MOTD end | 681 | case "376": // MOTD end |
681 | // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); | 682 | // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); |
682 | motd = true; | 683 | motd = true; |
683 | break; | 684 | break; |
684 | case "451" : // Not registered | 685 | case "451": // Not registered |
685 | break; | 686 | break; |
686 | case "433" : // Nickname in use | 687 | case "433": // Nickname in use |
687 | // Gen a new name | 688 | // Gen a new name |
688 | m_nick = m_baseNick + Util.RandomClass.Next(1, 99); | 689 | m_nick = m_baseNick + Util.RandomClass.Next(1, 99); |
689 | m_log.ErrorFormat("[IRC-Connector-{0}]: [{1}] IRC SERVER reports NicknameInUse, trying {2}", idn, cmd, m_nick); | 690 | m_log.ErrorFormat("[IRC-Connector-{0}]: [{1}] IRC SERVER reports NicknameInUse, trying {2}", idn, cmd, m_nick); |
@@ -695,29 +696,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
695 | m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); | 696 | m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); |
696 | m_writer.Flush(); | 697 | m_writer.Flush(); |
697 | break; | 698 | break; |
698 | case "479" : // Bad channel name, etc. This will never work, so disable the connection | 699 | case "479": // Bad channel name, etc. This will never work, so disable the connection |
699 | m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); | 700 | m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]); |
700 | m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] Connector disabled", idn, cmd); | 701 | m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] Connector disabled", idn, cmd); |
701 | m_enabled = false; | 702 | m_enabled = false; |
702 | m_connected = false; | 703 | m_connected = false; |
703 | m_pending = false; | 704 | m_pending = false; |
704 | break; | 705 | break; |
705 | case "NOTICE" : | 706 | case "NOTICE": |
706 | // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); | 707 | // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); |
707 | break; | 708 | break; |
708 | case "ERROR" : | 709 | case "ERROR": |
709 | m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); | 710 | m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]); |
710 | if (parms.Contains("reconnect too fast")) | 711 | if (parms.Contains("reconnect too fast")) |
711 | ICCD_PERIOD++; | 712 | ICCD_PERIOD++; |
712 | m_pending = false; | 713 | m_pending = false; |
713 | Reconnect(); | 714 | Reconnect(); |
714 | break; | 715 | break; |
715 | case "PING" : | 716 | case "PING": |
716 | m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); | 717 | m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); |
717 | m_writer.WriteLine(String.Format("PONG {0}", parms)); | 718 | m_writer.WriteLine(String.Format("PONG {0}", parms)); |
718 | m_writer.Flush(); | 719 | m_writer.Flush(); |
719 | break; | 720 | break; |
720 | case "PONG" : | 721 | case "PONG": |
721 | break; | 722 | break; |
722 | case "JOIN": | 723 | case "JOIN": |
723 | if (m_pending) | 724 | if (m_pending) |
@@ -748,19 +749,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
748 | m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); | 749 | m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); |
749 | eventIrcQuit(pfx, cmd, parms); | 750 | eventIrcQuit(pfx, cmd, parms); |
750 | break; | 751 | break; |
751 | default : | 752 | default: |
752 | m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms); | 753 | m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms); |
753 | break; | 754 | break; |
754 | } | 755 | } |
755 | 756 | ||
756 | // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd); | 757 | // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd); |
757 | 758 | ||
758 | } | 759 | } |
759 | 760 | ||
760 | public void eventIrcJoin(string prefix, string command, string parms) | 761 | public void eventIrcJoin(string prefix, string command, string parms) |
761 | { | 762 | { |
762 | string[] args = parms.Split(CS_SPACE,2); | 763 | string[] args = parms.Split(CS_SPACE, 2); |
763 | string IrcUser = prefix.Split('!')[0]; | 764 | string IrcUser = prefix.Split('!')[0]; |
764 | string IrcChannel = args[0]; | 765 | string IrcChannel = args[0]; |
765 | 766 | ||
766 | if (IrcChannel.StartsWith(":")) | 767 | if (IrcChannel.StartsWith(":")) |
@@ -772,8 +773,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
772 | 773 | ||
773 | public void eventIrcPart(string prefix, string command, string parms) | 774 | public void eventIrcPart(string prefix, string command, string parms) |
774 | { | 775 | { |
775 | string[] args = parms.Split(CS_SPACE,2); | 776 | string[] args = parms.Split(CS_SPACE, 2); |
776 | string IrcUser = prefix.Split('!')[0]; | 777 | string IrcUser = prefix.Split('!')[0]; |
777 | string IrcChannel = args[0]; | 778 | string IrcChannel = args[0]; |
778 | 779 | ||
779 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel); | 780 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel); |
@@ -782,7 +783,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
782 | 783 | ||
783 | public void eventIrcMode(string prefix, string command, string parms) | 784 | public void eventIrcMode(string prefix, string command, string parms) |
784 | { | 785 | { |
785 | string[] args = parms.Split(CS_SPACE,2); | 786 | string[] args = parms.Split(CS_SPACE, 2); |
786 | string UserMode = args[1]; | 787 | string UserMode = args[1]; |
787 | 788 | ||
788 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel); | 789 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel); |
@@ -794,7 +795,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
794 | 795 | ||
795 | public void eventIrcNickChange(string prefix, string command, string parms) | 796 | public void eventIrcNickChange(string prefix, string command, string parms) |
796 | { | 797 | { |
797 | string[] args = parms.Split(CS_SPACE,2); | 798 | string[] args = parms.Split(CS_SPACE, 2); |
798 | string UserOldNick = prefix.Split('!')[0]; | 799 | string UserOldNick = prefix.Split('!')[0]; |
799 | string UserNewNick = args[0].Remove(0, 1); | 800 | string UserNewNick = args[0].Remove(0, 1); |
800 | 801 | ||
@@ -804,11 +805,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
804 | 805 | ||
805 | public void eventIrcKick(string prefix, string command, string parms) | 806 | public void eventIrcKick(string prefix, string command, string parms) |
806 | { | 807 | { |
807 | string[] args = parms.Split(CS_SPACE,3); | 808 | string[] args = parms.Split(CS_SPACE, 3); |
808 | string UserKicker = prefix.Split('!')[0]; | 809 | string UserKicker = prefix.Split('!')[0]; |
809 | string IrcChannel = args[0]; | 810 | string IrcChannel = args[0]; |
810 | string UserKicked = args[1]; | 811 | string UserKicked = args[1]; |
811 | string KickMessage = args[2]; | 812 | string KickMessage = args[2]; |
812 | 813 | ||
813 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel); | 814 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel); |
814 | BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage); | 815 | BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage); |
@@ -822,7 +823,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
822 | 823 | ||
823 | public void eventIrcQuit(string prefix, string command, string parms) | 824 | public void eventIrcQuit(string prefix, string command, string parms) |
824 | { | 825 | { |
825 | string IrcUser = prefix.Split('!')[0]; | 826 | string IrcUser = prefix.Split('!')[0]; |
826 | string QuitMessage = parms; | 827 | string QuitMessage = parms; |
827 | 828 | ||
828 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel); | 829 | m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel); |
@@ -842,65 +843,65 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
842 | 843 | ||
843 | // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_); | 844 | // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_); |
844 | 845 | ||
845 | _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger | 846 | _pdk_ = (_pdk_ + 1) % PING_PERIOD; // cycle the ping trigger |
846 | _icc_++; // increment the inter-consecutive-connect-delay counter | 847 | _icc_++; // increment the inter-consecutive-connect-delay counter |
847 | 848 | ||
848 | lock (m_connectors) | 849 | lock (m_connectors) |
849 | foreach (IRCConnector connector in m_connectors) | 850 | foreach (IRCConnector connector in m_connectors) |
850 | { | 851 | { |
851 | 852 | ||
852 | // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); | 853 | // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); |
853 | 854 | ||
854 | if (connector.Enabled) | 855 | if (connector.Enabled) |
855 | { | ||
856 | if (!connector.Connected) | ||
857 | { | 856 | { |
858 | try | 857 | if (!connector.Connected) |
859 | { | 858 | { |
860 | // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); | 859 | try |
861 | connector.Connect(); | 860 | { |
861 | // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); | ||
862 | connector.Connect(); | ||
863 | } | ||
864 | catch (Exception e) | ||
865 | { | ||
866 | m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); | ||
867 | } | ||
862 | } | 868 | } |
863 | catch (Exception e) | 869 | else |
864 | { | 870 | { |
865 | m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); | ||
866 | } | ||
867 | } | ||
868 | else | ||
869 | { | ||
870 | 871 | ||
871 | if (connector.m_pending) | 872 | if (connector.m_pending) |
872 | { | ||
873 | if (connector.m_timeout == 0) | ||
874 | { | 873 | { |
875 | m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); | 874 | if (connector.m_timeout == 0) |
876 | connector.Reconnect(); | 875 | { |
876 | m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); | ||
877 | connector.Reconnect(); | ||
878 | } | ||
879 | else | ||
880 | connector.m_timeout--; | ||
877 | } | 881 | } |
878 | else | ||
879 | connector.m_timeout--; | ||
880 | } | ||
881 | 882 | ||
882 | // Being marked connected is not enough to ping. Socket establishment can sometimes take a long | 883 | // Being marked connected is not enough to ping. Socket establishment can sometimes take a long |
883 | // time, in which case the watch dog might try to ping the server before the socket has been | 884 | // time, in which case the watch dog might try to ping the server before the socket has been |
884 | // set up, with nasty side-effects. | 885 | // set up, with nasty side-effects. |
885 | 886 | ||
886 | else if (_pdk_ == 0) | 887 | else if (_pdk_ == 0) |
887 | { | ||
888 | try | ||
889 | { | ||
890 | connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); | ||
891 | connector.m_writer.Flush(); | ||
892 | } | ||
893 | catch (Exception e) | ||
894 | { | 888 | { |
895 | m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); | 889 | try |
896 | m_log.Debug(e); | 890 | { |
897 | connector.Reconnect(); | 891 | connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); |
892 | connector.m_writer.Flush(); | ||
893 | } | ||
894 | catch (Exception e) | ||
895 | { | ||
896 | m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); | ||
897 | m_log.Debug(e); | ||
898 | connector.Reconnect(); | ||
899 | } | ||
898 | } | 900 | } |
899 | } | ||
900 | 901 | ||
902 | } | ||
901 | } | 903 | } |
902 | } | 904 | } |
903 | } | ||
904 | 905 | ||
905 | // m_log.InfoFormat("[IRC-Watchdog] Status scan completed"); | 906 | // m_log.InfoFormat("[IRC-Watchdog] Status scan completed"); |
906 | 907 | ||
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index 53b103e..5505001 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs | |||
@@ -41,49 +41,73 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
41 | 41 | ||
42 | internal class RegionState | 42 | internal class RegionState |
43 | { | 43 | { |
44 | |||
45 | private static readonly ILog m_log = | 44 | private static readonly ILog m_log = |
46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 46 | ||
47 | // This computation is not the real region center if the region is larger than 256. | ||
48 | // This computation isn't fixed because there is not a handle back to the region. | ||
48 | private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); | 49 | private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); |
49 | private const int DEBUG_CHANNEL = 2147483647; | 50 | private const int DEBUG_CHANNEL = 2147483647; |
50 | 51 | ||
51 | private static int _idk_ = 0; | 52 | private static int _idk_ = 0; |
52 | 53 | ||
53 | // Runtime variables; these values are assigned when the | 54 | // Runtime variables; these values are assigned when the |
54 | // IrcState is created and remain constant thereafter. | 55 | // IrcState is created and remain constant thereafter. |
55 | 56 | ||
56 | internal string Region = String.Empty; | 57 | internal string Region = String.Empty; |
57 | internal string Host = String.Empty; | 58 | internal string Host = String.Empty; |
58 | internal string LocX = String.Empty; | 59 | internal string LocX = String.Empty; |
59 | internal string LocY = String.Empty; | 60 | internal string LocY = String.Empty; |
60 | internal string IDK = String.Empty; | 61 | internal string IDK = String.Empty; |
61 | 62 | ||
62 | // System values - used only be the IRC classes themselves | 63 | // System values - used only be the IRC classes themselves |
63 | 64 | ||
64 | internal ChannelState cs = null; // associated IRC configuration | 65 | internal ChannelState cs = null; // associated IRC configuration |
65 | internal Scene scene = null; // associated scene | 66 | internal Scene scene = null; // associated scene |
66 | internal IConfig config = null; // configuration file reference | 67 | internal IConfig config = null; // configuration file reference |
67 | internal bool enabled = true; | 68 | internal bool enabled = true; |
68 | 69 | ||
70 | //AgentAlert | ||
71 | internal bool showAlert = false; | ||
72 | internal string alertMessage = String.Empty; | ||
73 | internal IDialogModule dialogModule = null; | ||
74 | |||
69 | // This list is used to keep track of who is here, and by | 75 | // This list is used to keep track of who is here, and by |
70 | // implication, who is not. | 76 | // implication, who is not. |
71 | 77 | ||
72 | internal List<IClientAPI> clients = new List<IClientAPI>(); | 78 | internal List<IClientAPI> clients = new List<IClientAPI>(); |
73 | 79 | ||
74 | // Setup runtime variable values | 80 | // Setup runtime variable values |
75 | 81 | ||
76 | public RegionState(Scene p_scene, IConfig p_config) | 82 | public RegionState(Scene p_scene, IConfig p_config) |
77 | { | 83 | { |
78 | 84 | scene = p_scene; | |
79 | scene = p_scene; | ||
80 | config = p_config; | 85 | config = p_config; |
81 | 86 | ||
82 | Region = scene.RegionInfo.RegionName; | 87 | Region = scene.RegionInfo.RegionName; |
83 | Host = scene.RegionInfo.ExternalHostName; | 88 | Host = scene.RegionInfo.ExternalHostName; |
84 | LocX = Convert.ToString(scene.RegionInfo.RegionLocX); | 89 | LocX = Convert.ToString(scene.RegionInfo.RegionLocX); |
85 | LocY = Convert.ToString(scene.RegionInfo.RegionLocY); | 90 | LocY = Convert.ToString(scene.RegionInfo.RegionLocY); |
86 | IDK = Convert.ToString(_idk_++); | 91 | IDK = Convert.ToString(_idk_++); |
92 | |||
93 | showAlert = config.GetBoolean("alert_show", false); | ||
94 | string alertServerInfo = String.Empty; | ||
95 | |||
96 | if (showAlert) | ||
97 | { | ||
98 | bool showAlertServerInfo = config.GetBoolean("alert_show_serverinfo", true); | ||
99 | |||
100 | if (showAlertServerInfo) | ||
101 | alertServerInfo = String.Format("\nServer: {0}\nPort: {1}\nChannel: {2}\n\n", | ||
102 | config.GetString("server", ""), config.GetString("port", ""), config.GetString("channel", "")); | ||
103 | |||
104 | string alertPreMessage = config.GetString("alert_msg_pre", "This region is linked to Irc."); | ||
105 | string alertPostMessage = config.GetString("alert_msg_post", "Everything you say in public chat can be listened."); | ||
106 | |||
107 | alertMessage = String.Format("{0}\n{1}{2}", alertPreMessage, alertServerInfo, alertPostMessage); | ||
108 | |||
109 | dialogModule = scene.RequestModuleInterface<IDialogModule>(); | ||
110 | } | ||
87 | 111 | ||
88 | // OpenChannel conditionally establishes a connection to the | 112 | // OpenChannel conditionally establishes a connection to the |
89 | // IRC server. The request will either succeed, or it will | 113 | // IRC server. The request will either succeed, or it will |
@@ -93,9 +117,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
93 | 117 | ||
94 | // Connect channel to world events | 118 | // Connect channel to world events |
95 | 119 | ||
96 | scene.EventManager.OnChatFromWorld += OnSimChat; | 120 | scene.EventManager.OnChatFromWorld += OnSimChat; |
97 | scene.EventManager.OnChatFromClient += OnSimChat; | 121 | scene.EventManager.OnChatFromClient += OnSimChat; |
98 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; | 122 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; |
99 | scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; | 123 | scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; |
100 | 124 | ||
101 | m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region); | 125 | m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region); |
@@ -106,8 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
106 | 130 | ||
107 | ~RegionState() | 131 | ~RegionState() |
108 | { | 132 | { |
109 | if (cs != null) | 133 | if (cs != null) |
110 | cs.RemoveRegion(this); | 134 | cs.RemoveRegion(this); |
111 | } | 135 | } |
112 | 136 | ||
113 | // Called by PostInitialize after all regions have been created | 137 | // Called by PostInitialize after all regions have been created |
@@ -138,7 +162,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
138 | { | 162 | { |
139 | if (clients.Contains(client)) | 163 | if (clients.Contains(client)) |
140 | { | 164 | { |
141 | if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) | 165 | if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) |
142 | { | 166 | { |
143 | m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); | 167 | m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); |
144 | //Check if this person is excluded from IRC | 168 | //Check if this person is excluded from IRC |
@@ -147,7 +171,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
147 | cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); | 171 | cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); |
148 | } | 172 | } |
149 | } | 173 | } |
150 | client.OnLogout -= OnClientLoggedOut; | 174 | client.OnLogout -= OnClientLoggedOut; |
151 | client.OnConnectionClosed -= OnClientLoggedOut; | 175 | client.OnConnectionClosed -= OnClientLoggedOut; |
152 | clients.Remove(client); | 176 | clients.Remove(client); |
153 | } | 177 | } |
@@ -171,13 +195,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
171 | { | 195 | { |
172 | if (clients.Contains(client)) | 196 | if (clients.Contains(client)) |
173 | { | 197 | { |
174 | if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) | 198 | if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) |
175 | { | 199 | { |
176 | string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); | 200 | string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); |
177 | m_log.DebugFormat("[IRC-Region {0}] {1} has left", Region, clientName); | 201 | m_log.DebugFormat("[IRC-Region {0}] {1} has left", Region, clientName); |
178 | cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", clientName)); | 202 | cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", clientName)); |
179 | } | 203 | } |
180 | client.OnLogout -= OnClientLoggedOut; | 204 | client.OnLogout -= OnClientLoggedOut; |
181 | client.OnConnectionClosed -= OnClientLoggedOut; | 205 | client.OnConnectionClosed -= OnClientLoggedOut; |
182 | clients.Remove(client); | 206 | clients.Remove(client); |
183 | } | 207 | } |
@@ -195,14 +219,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
195 | 219 | ||
196 | private void OnMakeRootAgent(ScenePresence presence) | 220 | private void OnMakeRootAgent(ScenePresence presence) |
197 | { | 221 | { |
198 | |||
199 | IClientAPI client = presence.ControllingClient; | 222 | IClientAPI client = presence.ControllingClient; |
200 | 223 | ||
201 | try | 224 | try |
202 | { | 225 | { |
203 | if (!clients.Contains(client)) | 226 | if (!clients.Contains(client)) |
204 | { | 227 | { |
205 | client.OnLogout += OnClientLoggedOut; | 228 | client.OnLogout += OnClientLoggedOut; |
206 | client.OnConnectionClosed += OnClientLoggedOut; | 229 | client.OnConnectionClosed += OnClientLoggedOut; |
207 | clients.Add(client); | 230 | clients.Add(client); |
208 | if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) | 231 | if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) |
@@ -216,17 +239,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
216 | } | 239 | } |
217 | } | 240 | } |
218 | } | 241 | } |
242 | |||
243 | if (dialogModule != null && showAlert) | ||
244 | dialogModule.SendAlertToUser(client, alertMessage, true); | ||
219 | } | 245 | } |
220 | catch (Exception ex) | 246 | catch (Exception ex) |
221 | { | 247 | { |
222 | m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message); | 248 | m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message); |
223 | m_log.Debug(ex); | 249 | m_log.Debug(ex); |
224 | } | 250 | } |
225 | |||
226 | } | 251 | } |
227 | 252 | ||
228 | // This handler detects chat events int he virtual world. | 253 | // This handler detects chat events int he virtual world. |
229 | |||
230 | public void OnSimChat(Object sender, OSChatMessage msg) | 254 | public void OnSimChat(Object sender, OSChatMessage msg) |
231 | { | 255 | { |
232 | 256 | ||
@@ -317,14 +341,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
317 | // that evident. | 341 | // that evident. |
318 | 342 | ||
319 | default: | 343 | default: |
320 | m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", | 344 | m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", |
321 | Region, msg.Message); | 345 | Region, msg.Message); |
322 | cs.irc.Send(msg.Message); | 346 | cs.irc.Send(msg.Message); |
323 | break; | 347 | break; |
324 | } | 348 | } |
325 | } | 349 | } |
326 | catch (Exception ex) | 350 | catch (Exception ex) |
327 | { | 351 | { |
328 | m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", | 352 | m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", |
329 | Region, ex.Message); | 353 | Region, ex.Message); |
330 | m_log.Debug(ex); | 354 | m_log.Debug(ex); |
@@ -366,7 +390,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
366 | 390 | ||
367 | m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); | 391 | m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); |
368 | 392 | ||
369 | if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) | 393 | if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) |
370 | { | 394 | { |
371 | string txt = msg.Message; | 395 | string txt = msg.Message; |
372 | if (txt.StartsWith("/me ")) | 396 | if (txt.StartsWith("/me ")) |
@@ -376,13 +400,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
376 | return; | 400 | return; |
377 | } | 401 | } |
378 | 402 | ||
379 | if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && | 403 | if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && |
380 | msg.Channel == cs.RelayChannelOut) | 404 | msg.Channel == cs.RelayChannelOut) |
381 | { | 405 | { |
382 | Match m = cs.AccessPasswordRegex.Match(msg.Message); | 406 | Match m = cs.AccessPasswordRegex.Match(msg.Message); |
383 | if (null != m) | 407 | if (null != m) |
384 | { | 408 | { |
385 | m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), | 409 | m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), |
386 | m.Groups["message"].ToString()); | 410 | m.Groups["message"].ToString()); |
387 | cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), | 411 | cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), |
388 | scene.RegionInfo.RegionName, m.Groups["message"].ToString()); | 412 | scene.RegionInfo.RegionName, m.Groups["message"].ToString()); |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 018357a..c48e585 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | |||
@@ -375,11 +375,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge | |||
375 | scene.GetRootAgentCount(), scene.RegionInfo.RegionName, | 375 | scene.GetRootAgentCount(), scene.RegionInfo.RegionName, |
376 | scene.RegionInfo.RegionID, | 376 | scene.RegionInfo.RegionID, |
377 | DateTime.UtcNow.ToString("s"))); | 377 | DateTime.UtcNow.ToString("s"))); |
378 | |||
378 | scene.ForEachRootScenePresence(delegate(ScenePresence sp) | 379 | scene.ForEachRootScenePresence(delegate(ScenePresence sp) |
379 | { | 380 | { |
380 | list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID)); | 381 | list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID)); |
381 | list.Append("</avatars>"); | ||
382 | }); | 382 | }); |
383 | |||
384 | list.Append("</avatars>"); | ||
383 | string payload = list.ToString(); | 385 | string payload = list.ToString(); |
384 | 386 | ||
385 | // post via REST to broker | 387 | // post via REST to broker |
diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs new file mode 100644 index 0000000..5a6b284 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs | |||
@@ -0,0 +1,220 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using log4net; | ||
35 | using Mono.Addins; | ||
36 | using NDesk.Options; | ||
37 | using Nini.Config; | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Framework.Console; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | |||
44 | namespace OpenSim.Region.OptionalModules.Avatar.SitStand | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// A module that just holds commands for changing avatar sitting and standing states. | ||
48 | /// </summary> | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")] | ||
50 | public class SitStandCommandModule : INonSharedRegionModule | ||
51 | { | ||
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | private Scene m_scene; | ||
55 | |||
56 | public string Name { get { return "SitStand Command Module"; } } | ||
57 | |||
58 | public Type ReplaceableInterface { get { return null; } } | ||
59 | |||
60 | public void Initialise(IConfigSource source) | ||
61 | { | ||
62 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); | ||
63 | } | ||
64 | |||
65 | public void PostInitialise() | ||
66 | { | ||
67 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); | ||
68 | } | ||
69 | |||
70 | public void Close() | ||
71 | { | ||
72 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); | ||
73 | } | ||
74 | |||
75 | public void AddRegion(Scene scene) | ||
76 | { | ||
77 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
78 | } | ||
79 | |||
80 | public void RemoveRegion(Scene scene) | ||
81 | { | ||
82 | // m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
83 | } | ||
84 | |||
85 | public void RegionLoaded(Scene scene) | ||
86 | { | ||
87 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
88 | |||
89 | m_scene = scene; | ||
90 | |||
91 | scene.AddCommand( | ||
92 | "Users", this, "sit user name", | ||
93 | "sit user name [--regex] <first-name> <last-name>", | ||
94 | "Sit the named user on an unoccupied object with a sit target.", | ||
95 | "If there are no such objects then nothing happens.\n" | ||
96 | + "If --regex is specified then the names are treated as regular expressions.", | ||
97 | HandleSitUserNameCommand); | ||
98 | |||
99 | scene.AddCommand( | ||
100 | "Users", this, "stand user name", | ||
101 | "stand user name [--regex] <first-name> <last-name>", | ||
102 | "Stand the named user.", | ||
103 | "If --regex is specified then the names are treated as regular expressions.", | ||
104 | HandleStandUserNameCommand); | ||
105 | } | ||
106 | |||
107 | private void HandleSitUserNameCommand(string module, string[] cmd) | ||
108 | { | ||
109 | if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) | ||
110 | return; | ||
111 | |||
112 | if (cmd.Length < 5) | ||
113 | { | ||
114 | MainConsole.Instance.Output("Usage: sit user name [--regex] <first-name> <last-name>"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | List<ScenePresence> scenePresences = GetScenePresences(cmd); | ||
119 | |||
120 | foreach (ScenePresence sp in scenePresences) | ||
121 | { | ||
122 | if (sp.SitGround || sp.IsSatOnObject) | ||
123 | continue; | ||
124 | |||
125 | SceneObjectPart sitPart = null; | ||
126 | List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups(); | ||
127 | |||
128 | foreach (SceneObjectGroup sceneObject in sceneObjects) | ||
129 | { | ||
130 | if (sceneObject.IsAttachment) | ||
131 | continue; | ||
132 | |||
133 | foreach (SceneObjectPart part in sceneObject.Parts) | ||
134 | { | ||
135 | if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) | ||
136 | { | ||
137 | sitPart = part; | ||
138 | break; | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | if (sitPart != null) | ||
144 | { | ||
145 | MainConsole.Instance.OutputFormat( | ||
146 | "Sitting {0} on {1} {2} in {3}", | ||
147 | sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name); | ||
148 | |||
149 | sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero); | ||
150 | sp.HandleAgentSit(sp.ControllingClient, sp.UUID); | ||
151 | } | ||
152 | else | ||
153 | { | ||
154 | MainConsole.Instance.OutputFormat( | ||
155 | "Could not find any unoccupied set seat on which to sit {0} in {1}. Aborting", | ||
156 | sp.Name, m_scene.Name); | ||
157 | |||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | private void HandleStandUserNameCommand(string module, string[] cmd) | ||
164 | { | ||
165 | if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) | ||
166 | return; | ||
167 | |||
168 | if (cmd.Length < 5) | ||
169 | { | ||
170 | MainConsole.Instance.Output("Usage: stand user name [--regex] <first-name> <last-name>"); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | List<ScenePresence> scenePresences = GetScenePresences(cmd); | ||
175 | |||
176 | foreach (ScenePresence sp in scenePresences) | ||
177 | { | ||
178 | if (sp.SitGround || sp.IsSatOnObject) | ||
179 | { | ||
180 | MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name); | ||
181 | sp.StandUp(); | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | private List<ScenePresence> GetScenePresences(string[] cmdParams) | ||
187 | { | ||
188 | bool useRegex = false; | ||
189 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
190 | |||
191 | List<string> mainParams = options.Parse(cmdParams); | ||
192 | |||
193 | string firstName = mainParams[3]; | ||
194 | string lastName = mainParams[4]; | ||
195 | |||
196 | List<ScenePresence> scenePresencesMatched = new List<ScenePresence>(); | ||
197 | |||
198 | if (useRegex) | ||
199 | { | ||
200 | Regex nameRegex = new Regex(string.Format("{0} {1}", firstName, lastName)); | ||
201 | List<ScenePresence> scenePresences = m_scene.GetScenePresences(); | ||
202 | |||
203 | foreach (ScenePresence sp in scenePresences) | ||
204 | { | ||
205 | if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name)) | ||
206 | scenePresencesMatched.Add(sp); | ||
207 | } | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); | ||
212 | |||
213 | if (sp != null && !sp.IsChildAgent) | ||
214 | scenePresencesMatched.Add(sp); | ||
215 | } | ||
216 | |||
217 | return scenePresencesMatched; | ||
218 | } | ||
219 | } | ||
220 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 37ab35a..45af212 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; |
@@ -326,15 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
326 | "ParcelVoiceInfoRequest", | 326 | "ParcelVoiceInfoRequest", |
327 | agentID.ToString())); | 327 | agentID.ToString())); |
328 | 328 | ||
329 | caps.RegisterHandler( | 329 | //caps.RegisterHandler( |
330 | "ChatSessionRequest", | 330 | // "ChatSessionRequest", |
331 | new RestStreamHandler( | 331 | // new RestStreamHandler( |
332 | "POST", | 332 | // "POST", |
333 | capsBase + m_chatSessionRequestPath, | 333 | // capsBase + m_chatSessionRequestPath, |
334 | (request, path, param, httpRequest, httpResponse) | 334 | // (request, path, param, httpRequest, httpResponse) |
335 | => ChatSessionRequest(scene, request, path, param, agentID, caps), | 335 | // => ChatSessionRequest(scene, request, path, param, agentID, caps), |
336 | "ChatSessionRequest", | 336 | // "ChatSessionRequest", |
337 | agentID.ToString())); | 337 | // agentID.ToString())); |
338 | } | 338 | } |
339 | 339 | ||
340 | /// <summary> | 340 | /// <summary> |
@@ -551,13 +551,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
551 | reqStream.Close(); | 551 | reqStream.Close(); |
552 | } | 552 | } |
553 | 553 | ||
554 | HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); | 554 | using (HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse()) |
555 | Encoding encoding = Util.UTF8; | 555 | { |
556 | StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); | 556 | Encoding encoding = Util.UTF8; |
557 | fwdresponsestr = fwdresponsestream.ReadToEnd(); | 557 | |
558 | fwdresponsecontenttype = fwdrsp.ContentType; | 558 | using (Stream s = fwdrsp.GetResponseStream()) |
559 | fwdresponsecode = (int)fwdrsp.StatusCode; | 559 | { |
560 | fwdresponsestream.Close(); | 560 | using (StreamReader fwdresponsestream = new StreamReader(s)) |
561 | { | ||
562 | fwdresponsestr = fwdresponsestream.ReadToEnd(); | ||
563 | fwdresponsecontenttype = fwdrsp.ContentType; | ||
564 | fwdresponsecode = (int)fwdrsp.StatusCode; | ||
565 | } | ||
566 | } | ||
567 | } | ||
561 | 568 | ||
562 | response["content_type"] = fwdresponsecontenttype; | 569 | response["content_type"] = fwdresponsecontenttype; |
563 | response["str_response_string"] = fwdresponsestr; | 570 | response["str_response_string"] = fwdresponsestr; |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 881807a..dd44564 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; |
@@ -117,6 +117,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
117 | 117 | ||
118 | private IConfig m_config; | 118 | private IConfig m_config; |
119 | 119 | ||
120 | private object m_Lock; | ||
121 | |||
120 | public void Initialise(IConfigSource config) | 122 | public void Initialise(IConfigSource config) |
121 | { | 123 | { |
122 | 124 | ||
@@ -128,6 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
128 | if (!m_config.GetBoolean("enabled", false)) | 130 | if (!m_config.GetBoolean("enabled", false)) |
129 | return; | 131 | return; |
130 | 132 | ||
133 | m_Lock = new object(); | ||
134 | |||
131 | try | 135 | try |
132 | { | 136 | { |
133 | // retrieve configuration variables | 137 | // retrieve configuration variables |
@@ -429,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
429 | "ParcelVoiceInfoRequest", | 433 | "ParcelVoiceInfoRequest", |
430 | agentID.ToString())); | 434 | agentID.ToString())); |
431 | 435 | ||
432 | caps.RegisterHandler( | 436 | //caps.RegisterHandler( |
433 | "ChatSessionRequest", | 437 | // "ChatSessionRequest", |
434 | new RestStreamHandler( | 438 | // new RestStreamHandler( |
435 | "POST", | 439 | // "POST", |
436 | capsBase + m_chatSessionRequestPath, | 440 | // capsBase + m_chatSessionRequestPath, |
437 | (request, path, param, httpRequest, httpResponse) | 441 | // (request, path, param, httpRequest, httpResponse) |
438 | => ChatSessionRequest(scene, request, path, param, agentID, caps), | 442 | // => ChatSessionRequest(scene, request, path, param, agentID, caps), |
439 | "ChatSessionRequest", | 443 | // "ChatSessionRequest", |
440 | agentID.ToString())); | 444 | // agentID.ToString())); |
441 | } | 445 | } |
442 | 446 | ||
443 | /// <summary> | 447 | /// <summary> |
@@ -818,11 +822,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
818 | { | 822 | { |
819 | string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken); | 823 | string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken); |
820 | 824 | ||
821 | if (parent != null && parent != String.Empty) | 825 | if (!string.IsNullOrEmpty(parent)) |
822 | { | 826 | { |
823 | requrl = String.Format("{0}&chan_parent={1}", requrl, parent); | 827 | requrl = String.Format("{0}&chan_parent={1}", requrl, parent); |
824 | } | 828 | } |
825 | if (description != null && description != String.Empty) | 829 | if (!string.IsNullOrEmpty(description)) |
826 | { | 830 | { |
827 | requrl = String.Format("{0}&chan_desc={1}", requrl, description); | 831 | requrl = String.Format("{0}&chan_desc={1}", requrl, description); |
828 | } | 832 | } |
@@ -832,7 +836,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
832 | requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff); | 836 | requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff); |
833 | requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); | 837 | requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); |
834 | requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); | 838 | requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); |
835 | requrl = String.Format("{0}&chan_ckamping_distance={1}", requrl, m_vivoxChannelClampingDistance); | 839 | requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance); |
836 | 840 | ||
837 | XmlElement resp = VivoxCall(requrl, true); | 841 | XmlElement resp = VivoxCall(requrl, true); |
838 | if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) | 842 | if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) |
@@ -858,7 +862,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
858 | // requrl = String.Format("{0}&chan_parent={1}", requrl, parent); | 862 | // requrl = String.Format("{0}&chan_parent={1}", requrl, parent); |
859 | // } | 863 | // } |
860 | 864 | ||
861 | if (description != null && description != String.Empty) | 865 | if (!string.IsNullOrEmpty(description)) |
862 | { | 866 | { |
863 | requrl = String.Format("{0}&chan_desc={1}", requrl, description); | 867 | requrl = String.Format("{0}&chan_desc={1}", requrl, description); |
864 | } | 868 | } |
@@ -1043,7 +1047,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
1043 | private XmlElement VivoxDeleteChannel(string parent, string channelid) | 1047 | private XmlElement VivoxDeleteChannel(string parent, string channelid) |
1044 | { | 1048 | { |
1045 | string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); | 1049 | string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); |
1046 | if (parent != null && parent != String.Empty) | 1050 | if (!string.IsNullOrEmpty(parent)) |
1047 | { | 1051 | { |
1048 | requrl = String.Format("{0}&chan_parent={1}", requrl, parent); | 1052 | requrl = String.Format("{0}&chan_parent={1}", requrl, parent); |
1049 | } | 1053 | } |
@@ -1111,27 +1115,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
1111 | 1115 | ||
1112 | doc = new XmlDocument(); | 1116 | doc = new XmlDocument(); |
1113 | 1117 | ||
1114 | try | 1118 | // Let's serialize all calls to Vivox. Most of these are driven by |
1119 | // the clients (CAPs), when the user arrives at the region. We don't | ||
1120 | // want to issue many simultaneous http requests to Vivox, because mono | ||
1121 | // doesn't like that | ||
1122 | lock (m_Lock) | ||
1115 | { | 1123 | { |
1116 | // Otherwise prepare the request | 1124 | try |
1117 | m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); | 1125 | { |
1118 | 1126 | // Otherwise prepare the request | |
1119 | HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); | 1127 | m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); |
1120 | HttpWebResponse rsp = null; | ||
1121 | 1128 | ||
1122 | // We are sending just parameters, no content | 1129 | HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); |
1123 | req.ContentLength = 0; | ||
1124 | 1130 | ||
1125 | // Send request and retrieve the response | 1131 | // We are sending just parameters, no content |
1126 | rsp = (HttpWebResponse)req.GetResponse(); | 1132 | req.ContentLength = 0; |
1127 | 1133 | ||
1128 | XmlTextReader rdr = new XmlTextReader(rsp.GetResponseStream()); | 1134 | // Send request and retrieve the response |
1129 | doc.Load(rdr); | 1135 | using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) |
1130 | rdr.Close(); | 1136 | using (Stream s = rsp.GetResponseStream()) |
1131 | } | 1137 | using (XmlTextReader rdr = new XmlTextReader(s)) |
1132 | catch (Exception e) | 1138 | doc.Load(rdr); |
1133 | { | 1139 | } |
1134 | m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); | 1140 | catch (Exception e) |
1141 | { | ||
1142 | m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); | ||
1143 | } | ||
1135 | } | 1144 | } |
1136 | 1145 | ||
1137 | // If we're debugging server responses, dump the whole | 1146 | // If we're debugging server responses, dump the whole |
@@ -1316,4 +1325,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | |||
1316 | return false; | 1325 | return false; |
1317 | } | 1326 | } |
1318 | } | 1327 | } |
1319 | } \ No newline at end of file | 1328 | } |
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 29f9591..1565da9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | |||
@@ -35,10 +35,10 @@ using Nini.Config; | |||
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenMetaverse.StructuredData; | 36 | using OpenMetaverse.StructuredData; |
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Communications; | ||
39 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
40 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | using System.Text; | ||
42 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; | 42 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; |
43 | 43 | ||
44 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | 44 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups |
@@ -76,9 +76,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
76 | 76 | ||
77 | private List<Scene> m_sceneList = new List<Scene>(); | 77 | private List<Scene> m_sceneList = new List<Scene>(); |
78 | 78 | ||
79 | private IMessageTransferModule m_msgTransferModule = null; | 79 | private IMessageTransferModule m_msgTransferModule; |
80 | |||
81 | private IGroupsMessagingModule m_groupsMessagingModule; | ||
80 | 82 | ||
81 | private IGroupsServicesConnector m_groupData = null; | 83 | private IGroupsServicesConnector m_groupData; |
82 | 84 | ||
83 | // Configuration settings | 85 | // Configuration settings |
84 | private bool m_groupsEnabled = false; | 86 | private bool m_groupsEnabled = false; |
@@ -184,10 +186,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
184 | if (m_msgTransferModule == null) | 186 | if (m_msgTransferModule == null) |
185 | { | 187 | { |
186 | m_groupsEnabled = false; | 188 | m_groupsEnabled = false; |
187 | m_log.Warn("[GROUPS]: Could not get MessageTransferModule"); | 189 | m_log.Warn("[GROUPS]: Could not get IMessageTransferModule"); |
188 | } | 190 | } |
189 | } | 191 | } |
190 | 192 | ||
193 | if (m_groupsMessagingModule == null) | ||
194 | { | ||
195 | m_groupsMessagingModule = scene.RequestModuleInterface<IGroupsMessagingModule>(); | ||
196 | |||
197 | // No message transfer module, no notices, group invites, rejects, ejects, etc | ||
198 | if (m_groupsMessagingModule == null) | ||
199 | m_log.Warn("[GROUPS]: Could not get IGroupsMessagingModule"); | ||
200 | } | ||
201 | |||
191 | lock (m_sceneList) | 202 | lock (m_sceneList) |
192 | { | 203 | { |
193 | m_sceneList.Add(scene); | 204 | m_sceneList.Add(scene); |
@@ -250,7 +261,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
250 | 261 | ||
251 | client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; | 262 | client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; |
252 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; | 263 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; |
253 | client.OnDirFindQuery += OnDirFindQuery; | ||
254 | client.OnRequestAvatarProperties += OnRequestAvatarProperties; | 264 | client.OnRequestAvatarProperties += OnRequestAvatarProperties; |
255 | 265 | ||
256 | // Used for Notices and Group Invites/Accept/Reject | 266 | // Used for Notices and Group Invites/Accept/Reject |
@@ -303,21 +313,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
303 | } | 313 | } |
304 | */ | 314 | */ |
305 | 315 | ||
306 | void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) | ||
307 | { | ||
308 | if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) | ||
309 | { | ||
310 | if (m_debugEnabled) | ||
311 | m_log.DebugFormat( | ||
312 | "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", | ||
313 | System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); | ||
314 | |||
315 | // TODO: This currently ignores pretty much all the query flags including Mature and sort order | ||
316 | remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); | ||
317 | } | ||
318 | |||
319 | } | ||
320 | |||
321 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) | 316 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) |
322 | { | 317 | { |
323 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 318 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
@@ -361,7 +356,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
361 | 356 | ||
362 | private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) | 357 | private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) |
363 | { | 358 | { |
364 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 359 | if (m_debugEnabled) |
360 | m_log.DebugFormat( | ||
361 | "[GROUPS]: {0} called for {1}, message type {2}", | ||
362 | System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog); | ||
365 | 363 | ||
366 | // Group invitations | 364 | // Group invitations |
367 | if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) | 365 | if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) |
@@ -437,81 +435,160 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
437 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); | 435 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); |
438 | string Message = im.message.Substring(Subject.Length + 1); | 436 | string Message = im.message.Substring(Subject.Length + 1); |
439 | 437 | ||
438 | InventoryItemBase item = null; | ||
439 | bool hasAttachment = false; | ||
440 | UUID itemID = UUID.Zero; //Assignment to quiet compiler | ||
441 | UUID ownerID = UUID.Zero; //Assignment to quiet compiler | ||
440 | byte[] bucket; | 442 | byte[] bucket; |
441 | 443 | ||
442 | if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) | 444 | if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) |
443 | { | ||
444 | bucket = new byte[19]; | ||
445 | bucket[0] = 0; //dunno | ||
446 | bucket[1] = 0; //dunno | ||
447 | GroupID.ToBytes(bucket, 2); | ||
448 | bucket[18] = 0; //dunno | ||
449 | } | ||
450 | else | ||
451 | { | 445 | { |
452 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); | 446 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); |
453 | binBucket = binBucket.Remove(0, 14).Trim(); | 447 | binBucket = binBucket.Remove(0, 14).Trim(); |
454 | if (m_debugEnabled) | 448 | |
449 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | ||
450 | if (binBucketOSD is OSD) | ||
455 | { | 451 | { |
456 | m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); | 452 | OSDMap binBucketMap = (OSDMap)binBucketOSD; |
453 | |||
454 | itemID = binBucketMap["item_id"].AsUUID(); | ||
455 | ownerID = binBucketMap["owner_id"].AsUUID(); | ||
456 | |||
457 | //Attempt to get the details of the attached item. | ||
458 | //If sender doesn't own the attachment, the item | ||
459 | //variable will be set to null and attachment will | ||
460 | //not be included with the group notice. | ||
461 | Scene scene = (Scene)remoteClient.Scene; | ||
462 | item = new InventoryItemBase(itemID, ownerID); | ||
463 | item = scene.InventoryService.GetItem(item); | ||
457 | 464 | ||
458 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | 465 | if (item != null) |
459 | |||
460 | foreach (string key in binBucketOSD.Keys) | ||
461 | { | 466 | { |
462 | if (binBucketOSD.ContainsKey(key)) | 467 | //Got item details so include the attachment. |
463 | { | 468 | hasAttachment = true; |
464 | m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); | ||
465 | } | ||
466 | } | 469 | } |
467 | } | 470 | } |
468 | 471 | else | |
469 | // treat as if no attachment | 472 | { |
473 | m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | if (hasAttachment) | ||
478 | { | ||
479 | //Bucket contains information about attachment. | ||
480 | // | ||
481 | //Byte offset and description of bucket data: | ||
482 | //0: 1 byte indicating if attachment is present | ||
483 | //1: 1 byte indicating the type of attachment | ||
484 | //2: 16 bytes - Group UUID | ||
485 | //18: 16 bytes - UUID of the attachment owner | ||
486 | //34: 16 bytes - UUID of the attachment | ||
487 | //50: variable - Name of the attachment | ||
488 | //??: NUL byte to terminate the attachment name | ||
489 | byte[] name = Encoding.UTF8.GetBytes(item.Name); | ||
490 | bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name | ||
491 | bucket[0] = 1; //Has attachment flag | ||
492 | bucket[1] = (byte)item.InvType; //Type of Attachment | ||
493 | GroupID.ToBytes(bucket, 2); | ||
494 | ownerID.ToBytes(bucket, 18); | ||
495 | itemID.ToBytes(bucket, 34); | ||
496 | name.CopyTo(bucket, 50); | ||
497 | } | ||
498 | else | ||
499 | { | ||
470 | bucket = new byte[19]; | 500 | bucket = new byte[19]; |
471 | bucket[0] = 0; //dunno | 501 | bucket[0] = 0; //Has attachment flag |
472 | bucket[1] = 0; //dunno | 502 | bucket[1] = 0; //Type of attachment |
473 | GroupID.ToBytes(bucket, 2); | 503 | GroupID.ToBytes(bucket, 2); |
474 | bucket[18] = 0; //dunno | 504 | bucket[18] = 0; //NUL terminate name of attachment |
475 | } | 505 | } |
476 | 506 | ||
477 | |||
478 | m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); | 507 | m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); |
479 | if (OnNewGroupNotice != null) | 508 | if (OnNewGroupNotice != null) |
480 | { | 509 | { |
481 | OnNewGroupNotice(GroupID, NoticeID); | 510 | OnNewGroupNotice(GroupID, NoticeID); |
482 | } | 511 | } |
483 | 512 | ||
484 | // Send notice out to everyone that wants notices | 513 | if (m_debugEnabled) |
485 | foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) | ||
486 | { | 514 | { |
487 | if (m_debugEnabled) | 515 | foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) |
488 | { | 516 | { |
489 | UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); | 517 | if (m_debugEnabled) |
490 | if (targetUser != null) | ||
491 | { | 518 | { |
492 | m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); | 519 | UserAccount targetUser |
493 | } | 520 | = m_sceneList[0].UserAccountService.GetUserAccount( |
494 | else | 521 | remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); |
495 | { | 522 | |
496 | m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); | 523 | if (targetUser != null) |
524 | { | ||
525 | m_log.DebugFormat( | ||
526 | "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", | ||
527 | NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); | ||
528 | } | ||
529 | else | ||
530 | { | ||
531 | m_log.DebugFormat( | ||
532 | "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", | ||
533 | NoticeID, member.AgentID, member.AcceptNotices); | ||
534 | } | ||
497 | } | 535 | } |
498 | } | 536 | } |
537 | } | ||
499 | 538 | ||
500 | if (member.AcceptNotices) | 539 | GridInstantMessage msg |
501 | { | 540 | = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); |
502 | // Build notice IIM | ||
503 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); | ||
504 | 541 | ||
505 | msg.toAgentID = member.AgentID.Guid; | 542 | if (m_groupsMessagingModule != null) |
506 | OutgoingInstantMessage(msg, member.AgentID); | 543 | m_groupsMessagingModule.SendMessageToGroup( |
507 | } | 544 | msg, GroupID, remoteClient.AgentId, gmd => gmd.AcceptNotices); |
545 | } | ||
546 | } | ||
547 | |||
548 | if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) | ||
549 | { | ||
550 | //Is bucket large enough to hold UUID of the attachment? | ||
551 | if (im.binaryBucket.Length < 16) | ||
552 | return; | ||
553 | |||
554 | UUID noticeID = new UUID(im.imSessionID); | ||
555 | |||
556 | if (m_debugEnabled) | ||
557 | m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId); | ||
558 | |||
559 | GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); | ||
560 | if (notice != null) | ||
561 | { | ||
562 | UUID giver = new UUID(notice.BinaryBucket, 18); | ||
563 | UUID attachmentUUID = new UUID(notice.BinaryBucket, 34); | ||
564 | |||
565 | if (m_debugEnabled) | ||
566 | m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); | ||
567 | |||
568 | string message; | ||
569 | InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, | ||
570 | giver, attachmentUUID, out message); | ||
571 | |||
572 | if (itemCopy == null) | ||
573 | { | ||
574 | remoteClient.SendAgentAlertMessage(message, false); | ||
575 | return; | ||
508 | } | 576 | } |
577 | |||
578 | remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); | ||
579 | } | ||
580 | else | ||
581 | { | ||
582 | if (m_debugEnabled) | ||
583 | m_log.DebugFormat( | ||
584 | "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", | ||
585 | noticeID, remoteClient.AgentId); | ||
509 | } | 586 | } |
510 | } | 587 | } |
511 | 588 | ||
512 | // Interop, received special 210 code for ejecting a group member | 589 | // Interop, received special 210 code for ejecting a group member |
513 | // this only works within the comms servers domain, and won't work hypergrid | 590 | // this only works within the comms servers domain, and won't work hypergrid |
514 | // TODO:FIXME: Use a presense server of some kind to find out where the | 591 | // TODO:FIXME: Use a presence server of some kind to find out where the |
515 | // client actually is, and try contacting that region directly to notify them, | 592 | // client actually is, and try contacting that region directly to notify them, |
516 | // or provide the notification via xmlrpc update queue | 593 | // or provide the notification via xmlrpc update queue |
517 | if ((im.dialog == 210)) | 594 | if ((im.dialog == 210)) |
@@ -764,7 +841,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
764 | remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); | 841 | remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); |
765 | return UUID.Zero; | 842 | return UUID.Zero; |
766 | } | 843 | } |
767 | money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); | 844 | money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate); |
768 | } | 845 | } |
769 | UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); | 846 | UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); |
770 | 847 | ||
@@ -889,26 +966,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
889 | 966 | ||
890 | if (data != null) | 967 | if (data != null) |
891 | { | 968 | { |
892 | GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); | 969 | GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); |
893 | |||
894 | GridInstantMessage msg = new GridInstantMessage(); | ||
895 | msg.imSessionID = UUID.Zero.Guid; | ||
896 | msg.fromAgentID = data.GroupID.Guid; | ||
897 | msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; | ||
898 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
899 | msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; | ||
900 | msg.message = data.noticeData.Subject + "|" + data.Message; | ||
901 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; | ||
902 | msg.fromGroup = true; | ||
903 | msg.offline = (byte)0; | ||
904 | msg.ParentEstateID = 0; | ||
905 | msg.Position = Vector3.Zero; | ||
906 | msg.RegionID = UUID.Zero.Guid; | ||
907 | msg.binaryBucket = data.BinaryBucket; | ||
908 | 970 | ||
909 | OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); | 971 | OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); |
910 | } | 972 | } |
911 | |||
912 | } | 973 | } |
913 | 974 | ||
914 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) | 975 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) |
@@ -916,10 +977,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
916 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 977 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
917 | 978 | ||
918 | GridInstantMessage msg = new GridInstantMessage(); | 979 | GridInstantMessage msg = new GridInstantMessage(); |
919 | msg.imSessionID = UUID.Zero.Guid; | 980 | byte[] bucket; |
981 | |||
982 | msg.imSessionID = groupNoticeID.Guid; | ||
920 | msg.toAgentID = agentID.Guid; | 983 | msg.toAgentID = agentID.Guid; |
921 | msg.dialog = dialog; | 984 | msg.dialog = dialog; |
922 | // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; | ||
923 | msg.fromGroup = true; | 985 | msg.fromGroup = true; |
924 | msg.offline = (byte)0; | 986 | msg.offline = (byte)0; |
925 | msg.ParentEstateID = 0; | 987 | msg.ParentEstateID = 0; |
@@ -933,13 +995,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
933 | msg.timestamp = info.noticeData.Timestamp; | 995 | msg.timestamp = info.noticeData.Timestamp; |
934 | msg.fromAgentName = info.noticeData.FromName; | 996 | msg.fromAgentName = info.noticeData.FromName; |
935 | msg.message = info.noticeData.Subject + "|" + info.Message; | 997 | msg.message = info.noticeData.Subject + "|" + info.Message; |
936 | msg.binaryBucket = info.BinaryBucket; | 998 | |
999 | if (info.BinaryBucket[0] > 0) | ||
1000 | { | ||
1001 | //32 is due to not needing space for two of the UUIDs. | ||
1002 | //(Don't need UUID of attachment or its owner in IM) | ||
1003 | //50 offset gets us to start of attachment name. | ||
1004 | //We are skipping the attachment flag, type, and | ||
1005 | //the three UUID fields at the start of the bucket. | ||
1006 | bucket = new byte[info.BinaryBucket.Length-32]; | ||
1007 | bucket[0] = 1; //Has attachment | ||
1008 | bucket[1] = info.BinaryBucket[1]; | ||
1009 | Array.Copy(info.BinaryBucket, 50, | ||
1010 | bucket, 18, info.BinaryBucket.Length-50); | ||
1011 | } | ||
1012 | else | ||
1013 | { | ||
1014 | bucket = new byte[19]; | ||
1015 | bucket[0] = 0; //No attachment | ||
1016 | bucket[1] = 0; //Attachment type | ||
1017 | bucket[18] = 0; //NUL terminate name | ||
1018 | } | ||
1019 | |||
1020 | info.GroupID.ToBytes(bucket, 2); | ||
1021 | msg.binaryBucket = bucket; | ||
937 | } | 1022 | } |
938 | else | 1023 | else |
939 | { | 1024 | { |
940 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); | 1025 | if (m_debugEnabled) |
1026 | m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); | ||
1027 | |||
941 | msg.fromAgentID = UUID.Zero.Guid; | 1028 | msg.fromAgentID = UUID.Zero.Guid; |
942 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; | 1029 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
943 | msg.fromAgentName = string.Empty; | 1030 | msg.fromAgentName = string.Empty; |
944 | msg.message = string.Empty; | 1031 | msg.message = string.Empty; |
945 | msg.binaryBucket = new byte[0]; | 1032 | msg.binaryBucket = new byte[0]; |
@@ -1063,7 +1150,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1063 | // Message to ejector | 1150 | // Message to ejector |
1064 | // Interop, received special 210 code for ejecting a group member | 1151 | // Interop, received special 210 code for ejecting a group member |
1065 | // this only works within the comms servers domain, and won't work hypergrid | 1152 | // this only works within the comms servers domain, and won't work hypergrid |
1066 | // TODO:FIXME: Use a presense server of some kind to find out where the | 1153 | // TODO:FIXME: Use a presence server of some kind to find out where the |
1067 | // client actually is, and try contacting that region directly to notify them, | 1154 | // client actually is, and try contacting that region directly to notify them, |
1068 | // or provide the notification via xmlrpc update queue | 1155 | // or provide the notification via xmlrpc update queue |
1069 | 1156 | ||
@@ -1178,6 +1265,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1178 | } | 1265 | } |
1179 | } | 1266 | } |
1180 | 1267 | ||
1268 | public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query) | ||
1269 | { | ||
1270 | return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query); | ||
1271 | } | ||
1272 | |||
1273 | |||
1181 | #endregion | 1274 | #endregion |
1182 | 1275 | ||
1183 | #region Client/Update Tools | 1276 | #region Client/Update Tools |
@@ -1222,7 +1315,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1222 | AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); | 1315 | AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); |
1223 | AgentData.Add(AgentDataMap); | 1316 | AgentData.Add(AgentDataMap); |
1224 | 1317 | ||
1225 | |||
1226 | OSDArray GroupData = new OSDArray(data.Length); | 1318 | OSDArray GroupData = new OSDArray(data.Length); |
1227 | OSDArray NewGroupData = new OSDArray(data.Length); | 1319 | OSDArray NewGroupData = new OSDArray(data.Length); |
1228 | 1320 | ||
@@ -1288,7 +1380,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1288 | presence.Grouptitle = Title; | 1380 | presence.Grouptitle = Title; |
1289 | 1381 | ||
1290 | if (! presence.IsChildAgent) | 1382 | if (! presence.IsChildAgent) |
1291 | presence.SendAvatarDataToAllAgents(); | 1383 | presence.SendAvatarDataToAllClients(); |
1292 | } | 1384 | } |
1293 | } | 1385 | } |
1294 | } | 1386 | } |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 7bae8f7..1cb4747 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | |||
@@ -42,7 +42,6 @@ using OpenMetaverse; | |||
42 | using OpenMetaverse.StructuredData; | 42 | using OpenMetaverse.StructuredData; |
43 | 43 | ||
44 | using OpenSim.Framework; | 44 | using OpenSim.Framework; |
45 | using OpenSim.Framework.Communications; | ||
46 | using OpenSim.Region.Framework.Interfaces; | 45 | using OpenSim.Region.Framework.Interfaces; |
47 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
48 | 47 | ||
@@ -212,8 +211,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
212 | m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); | 211 | m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); |
213 | 212 | ||
214 | m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); | 213 | m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); |
215 | if ((m_groupsServerURI == null) || | 214 | if (string.IsNullOrEmpty(m_groupsServerURI)) |
216 | (m_groupsServerURI == string.Empty)) | ||
217 | { | 215 | { |
218 | m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); | 216 | m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); |
219 | m_connectorEnabled = false; | 217 | m_connectorEnabled = false; |
@@ -438,7 +436,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
438 | return null; | 436 | return null; |
439 | } | 437 | } |
440 | } | 438 | } |
441 | else if ((groupName != null) && (groupName != string.Empty)) | 439 | else if (!string.IsNullOrEmpty(groupName)) |
442 | { | 440 | { |
443 | if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) | 441 | if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) |
444 | { | 442 | { |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index c1bdacb..9a42bac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | |||
@@ -26,15 +26,25 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Net; | ||
29 | using System.Reflection; | 32 | using System.Reflection; |
30 | using Nini.Config; | 33 | using Nini.Config; |
31 | using NUnit.Framework; | 34 | using NUnit.Framework; |
32 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenMetaverse.Messages.Linden; | ||
37 | using OpenMetaverse.Packets; | ||
38 | using OpenMetaverse.StructuredData; | ||
33 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Communications; | 40 | using OpenSim.Framework.Servers; |
41 | using OpenSim.Framework.Servers.HttpServer; | ||
42 | using OpenSim.Region.ClientStack.Linden; | ||
43 | using OpenSim.Region.CoreModules.Avatar.InstantMessage; | ||
44 | using OpenSim.Region.CoreModules.Framework; | ||
35 | using OpenSim.Region.Framework.Scenes; | 45 | using OpenSim.Region.Framework.Scenes; |
46 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; | ||
36 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 48 | ||
39 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests | 49 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests |
40 | { | 50 | { |
@@ -44,11 +54,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests | |||
44 | [TestFixture] | 54 | [TestFixture] |
45 | public class GroupsModuleTests : OpenSimTestCase | 55 | public class GroupsModuleTests : OpenSimTestCase |
46 | { | 56 | { |
57 | [SetUp] | ||
58 | public override void SetUp() | ||
59 | { | ||
60 | base.SetUp(); | ||
61 | |||
62 | uint port = 9999; | ||
63 | uint sslPort = 9998; | ||
64 | |||
65 | // This is an unfortunate bit of clean up we have to do because MainServer manages things through static | ||
66 | // variables and the VM is not restarted between tests. | ||
67 | MainServer.RemoveHttpServer(port); | ||
68 | |||
69 | BaseHttpServer server = new BaseHttpServer(port, false, sslPort, ""); | ||
70 | MainServer.AddHttpServer(server); | ||
71 | MainServer.Instance = server; | ||
72 | } | ||
73 | |||
47 | [Test] | 74 | [Test] |
48 | public void TestBasic() | 75 | public void TestSendAgentGroupDataUpdate() |
49 | { | 76 | { |
50 | TestHelpers.InMethod(); | 77 | TestHelpers.InMethod(); |
51 | // log4net.Config.XmlConfigurator.Configure(); | 78 | // TestHelpers.EnableLogging(); |
52 | 79 | ||
53 | TestScene scene = new SceneHelpers().SetupScene(); | 80 | TestScene scene = new SceneHelpers().SetupScene(); |
54 | IConfigSource configSource = new IniConfigSource(); | 81 | IConfigSource configSource = new IniConfigSource(); |
@@ -56,8 +83,185 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests | |||
56 | config.Set("Enabled", true); | 83 | config.Set("Enabled", true); |
57 | config.Set("Module", "GroupsModule"); | 84 | config.Set("Module", "GroupsModule"); |
58 | config.Set("DebugEnabled", true); | 85 | config.Set("DebugEnabled", true); |
86 | |||
87 | GroupsModule gm = new GroupsModule(); | ||
88 | EventQueueGetModule eqgm = new EventQueueGetModule(); | ||
89 | |||
90 | // We need a capabilities module active so that adding the scene presence creates an event queue in the | ||
91 | // EventQueueGetModule | ||
59 | SceneHelpers.SetupSceneModules( | 92 | SceneHelpers.SetupSceneModules( |
60 | scene, configSource, new object[] { new MockGroupsServicesConnector() }); | 93 | scene, configSource, gm, new MockGroupsServicesConnector(), new CapabilitiesModule(), eqgm); |
94 | |||
95 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseStem("1")); | ||
96 | |||
97 | gm.SendAgentGroupDataUpdate(sp.ControllingClient); | ||
98 | |||
99 | Hashtable eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID); | ||
100 | |||
101 | Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); | ||
102 | |||
103 | // Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); | ||
104 | |||
105 | OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]); | ||
106 | OSDArray eventsOsd = (OSDArray)rawOsd["events"]; | ||
107 | |||
108 | bool foundUpdate = false; | ||
109 | foreach (OSD osd in eventsOsd) | ||
110 | { | ||
111 | OSDMap eventOsd = (OSDMap)osd; | ||
112 | |||
113 | if (eventOsd["message"] == "AgentGroupDataUpdate") | ||
114 | foundUpdate = true; | ||
115 | } | ||
116 | |||
117 | Assert.That(foundUpdate, Is.True, "Did not find AgentGroupDataUpdate in response"); | ||
118 | |||
119 | // TODO: More checking of more actual event data. | ||
120 | } | ||
121 | |||
122 | [Test] | ||
123 | public void TestSendGroupNotice() | ||
124 | { | ||
125 | TestHelpers.InMethod(); | ||
126 | // TestHelpers.EnableLogging(); | ||
127 | |||
128 | TestScene scene = new SceneHelpers().SetupScene(); | ||
129 | |||
130 | MessageTransferModule mtm = new MessageTransferModule(); | ||
131 | GroupsModule gm = new GroupsModule(); | ||
132 | GroupsMessagingModule gmm = new GroupsMessagingModule(); | ||
133 | MockGroupsServicesConnector mgsc = new MockGroupsServicesConnector(); | ||
134 | |||
135 | IConfigSource configSource = new IniConfigSource(); | ||
136 | |||
137 | { | ||
138 | IConfig config = configSource.AddConfig("Messaging"); | ||
139 | config.Set("MessageTransferModule", mtm.Name); | ||
140 | } | ||
141 | |||
142 | { | ||
143 | IConfig config = configSource.AddConfig("Groups"); | ||
144 | config.Set("Enabled", true); | ||
145 | config.Set("Module", gm.Name); | ||
146 | config.Set("DebugEnabled", true); | ||
147 | config.Set("MessagingModule", gmm.Name); | ||
148 | config.Set("MessagingEnabled", true); | ||
149 | } | ||
150 | |||
151 | SceneHelpers.SetupSceneModules(scene, configSource, mgsc, mtm, gm, gmm); | ||
152 | |||
153 | UUID userId = TestHelpers.ParseTail(0x1); | ||
154 | string subjectText = "newman"; | ||
155 | string messageText = "Hello"; | ||
156 | string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText); | ||
157 | |||
158 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); | ||
159 | TestClient tc = (TestClient)sp.ControllingClient; | ||
160 | |||
161 | UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true); | ||
162 | gm.JoinGroupRequest(tc, groupID); | ||
163 | |||
164 | // Create a second user who doesn't want to receive notices | ||
165 | ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2)); | ||
166 | TestClient tc2 = (TestClient)sp2.ControllingClient; | ||
167 | gm.JoinGroupRequest(tc2, groupID); | ||
168 | gm.SetGroupAcceptNotices(tc2, groupID, false, true); | ||
169 | |||
170 | List<GridInstantMessage> spReceivedMessages = new List<GridInstantMessage>(); | ||
171 | tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im); | ||
172 | |||
173 | List<GridInstantMessage> sp2ReceivedMessages = new List<GridInstantMessage>(); | ||
174 | tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im); | ||
175 | |||
176 | GridInstantMessage noticeIm = new GridInstantMessage(); | ||
177 | noticeIm.fromAgentID = userId.Guid; | ||
178 | noticeIm.toAgentID = groupID.Guid; | ||
179 | noticeIm.message = combinedSubjectMessage; | ||
180 | noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice; | ||
181 | |||
182 | tc.HandleImprovedInstantMessage(noticeIm); | ||
183 | |||
184 | Assert.That(spReceivedMessages.Count, Is.EqualTo(1)); | ||
185 | Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage)); | ||
186 | |||
187 | List<GroupNoticeData> notices = mgsc.GetGroupNotices(UUID.Zero, groupID); | ||
188 | Assert.AreEqual(1, notices.Count); | ||
189 | |||
190 | // OpenSimulator (possibly also SL) transport the notice ID as the session ID! | ||
191 | Assert.AreEqual(notices[0].NoticeID.Guid, spReceivedMessages[0].imSessionID); | ||
192 | |||
193 | Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0)); | ||
194 | } | ||
195 | |||
196 | /// <summary> | ||
197 | /// Run test with the MessageOnlineUsersOnly flag set. | ||
198 | /// </summary> | ||
199 | [Test] | ||
200 | public void TestSendGroupNoticeOnlineOnly() | ||
201 | { | ||
202 | TestHelpers.InMethod(); | ||
203 | // TestHelpers.EnableLogging(); | ||
204 | |||
205 | TestScene scene = new SceneHelpers().SetupScene(); | ||
206 | |||
207 | MessageTransferModule mtm = new MessageTransferModule(); | ||
208 | GroupsModule gm = new GroupsModule(); | ||
209 | GroupsMessagingModule gmm = new GroupsMessagingModule(); | ||
210 | |||
211 | IConfigSource configSource = new IniConfigSource(); | ||
212 | |||
213 | { | ||
214 | IConfig config = configSource.AddConfig("Messaging"); | ||
215 | config.Set("MessageTransferModule", mtm.Name); | ||
216 | } | ||
217 | |||
218 | { | ||
219 | IConfig config = configSource.AddConfig("Groups"); | ||
220 | config.Set("Enabled", true); | ||
221 | config.Set("Module", gm.Name); | ||
222 | config.Set("DebugEnabled", true); | ||
223 | config.Set("MessagingModule", gmm.Name); | ||
224 | config.Set("MessagingEnabled", true); | ||
225 | config.Set("MessageOnlineUsersOnly", true); | ||
226 | } | ||
227 | |||
228 | SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm); | ||
229 | |||
230 | UUID userId = TestHelpers.ParseTail(0x1); | ||
231 | string subjectText = "newman"; | ||
232 | string messageText = "Hello"; | ||
233 | string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText); | ||
234 | |||
235 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); | ||
236 | TestClient tc = (TestClient)sp.ControllingClient; | ||
237 | |||
238 | UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true); | ||
239 | gm.JoinGroupRequest(tc, groupID); | ||
240 | |||
241 | // Create a second user who doesn't want to receive notices | ||
242 | ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2)); | ||
243 | TestClient tc2 = (TestClient)sp2.ControllingClient; | ||
244 | gm.JoinGroupRequest(tc2, groupID); | ||
245 | gm.SetGroupAcceptNotices(tc2, groupID, false, true); | ||
246 | |||
247 | List<GridInstantMessage> spReceivedMessages = new List<GridInstantMessage>(); | ||
248 | tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im); | ||
249 | |||
250 | List<GridInstantMessage> sp2ReceivedMessages = new List<GridInstantMessage>(); | ||
251 | tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im); | ||
252 | |||
253 | GridInstantMessage noticeIm = new GridInstantMessage(); | ||
254 | noticeIm.fromAgentID = userId.Guid; | ||
255 | noticeIm.toAgentID = groupID.Guid; | ||
256 | noticeIm.message = combinedSubjectMessage; | ||
257 | noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice; | ||
258 | |||
259 | tc.HandleImprovedInstantMessage(noticeIm); | ||
260 | |||
261 | Assert.That(spReceivedMessages.Count, Is.EqualTo(1)); | ||
262 | Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage)); | ||
263 | |||
264 | Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0)); | ||
61 | } | 265 | } |
62 | } | 266 | } |
63 | } \ No newline at end of file | 267 | } \ 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 1101851..20555e4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | |||
@@ -41,7 +41,6 @@ using OpenMetaverse; | |||
41 | using OpenMetaverse.StructuredData; | 41 | using OpenMetaverse.StructuredData; |
42 | 42 | ||
43 | using OpenSim.Framework; | 43 | using OpenSim.Framework; |
44 | using OpenSim.Framework.Communications; | ||
45 | using OpenSim.Region.Framework.Interfaces; | 44 | using OpenSim.Region.Framework.Interfaces; |
46 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
47 | 46 | ||
@@ -168,8 +167,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
168 | m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); | 167 | m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); |
169 | 168 | ||
170 | m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); | 169 | m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); |
171 | if ((m_groupsServerURI == null) || | 170 | if (string.IsNullOrEmpty(m_groupsServerURI)) |
172 | (m_groupsServerURI == string.Empty)) | ||
173 | { | 171 | { |
174 | m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); | 172 | m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); |
175 | m_connectorEnabled = false; | 173 | m_connectorEnabled = false; |
@@ -354,7 +352,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
354 | { | 352 | { |
355 | param["GroupID"] = GroupID.ToString(); | 353 | param["GroupID"] = GroupID.ToString(); |
356 | } | 354 | } |
357 | if ((GroupName != null) && (GroupName != string.Empty)) | 355 | if (!string.IsNullOrEmpty(GroupName)) |
358 | { | 356 | { |
359 | param["Name"] = GroupName.ToString(); | 357 | param["Name"] = GroupName.ToString(); |
360 | } | 358 | } |
@@ -1013,7 +1011,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1013 | Hashtable respData = (Hashtable)resp.Value; | 1011 | Hashtable respData = (Hashtable)resp.Value; |
1014 | if (respData.Contains("error") && !respData.Contains("succeed")) | 1012 | if (respData.Contains("error") && !respData.Contains("succeed")) |
1015 | { | 1013 | { |
1016 | LogRespDataToConsoleError(respData); | 1014 | LogRespDataToConsoleError(requestingAgentID, function, param, respData); |
1017 | } | 1015 | } |
1018 | 1016 | ||
1019 | return respData; | 1017 | return respData; |
@@ -1041,20 +1039,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1041 | return error; | 1039 | return error; |
1042 | } | 1040 | } |
1043 | 1041 | ||
1044 | private void LogRespDataToConsoleError(Hashtable respData) | 1042 | private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData) |
1045 | { | 1043 | { |
1046 | m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); | 1044 | m_log.ErrorFormat( |
1047 | 1045 | "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}", | |
1048 | foreach (string key in respData.Keys) | 1046 | function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData)); |
1049 | { | ||
1050 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); | ||
1051 | |||
1052 | string[] lines = respData[key].ToString().Split(new char[] { '\n' }); | ||
1053 | foreach (string line in lines) | ||
1054 | { | ||
1055 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); | ||
1056 | } | ||
1057 | } | ||
1058 | } | 1047 | } |
1059 | 1048 | ||
1060 | /// <summary> | 1049 | /// <summary> |
@@ -1146,28 +1135,38 @@ namespace Nwc.XmlRpc | |||
1146 | request.AllowWriteStreamBuffering = true; | 1135 | request.AllowWriteStreamBuffering = true; |
1147 | request.KeepAlive = !_disableKeepAlive; | 1136 | request.KeepAlive = !_disableKeepAlive; |
1148 | 1137 | ||
1149 | Stream stream = request.GetRequestStream(); | 1138 | using (Stream stream = request.GetRequestStream()) |
1150 | XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); | ||
1151 | _serializer.Serialize(xml, this); | ||
1152 | xml.Flush(); | ||
1153 | xml.Close(); | ||
1154 | |||
1155 | HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | ||
1156 | StreamReader input = new StreamReader(response.GetResponseStream()); | ||
1157 | |||
1158 | string inputXml = input.ReadToEnd(); | ||
1159 | XmlRpcResponse resp; | ||
1160 | try | ||
1161 | { | 1139 | { |
1162 | resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); | 1140 | using (XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII)) |
1141 | { | ||
1142 | _serializer.Serialize(xml, this); | ||
1143 | xml.Flush(); | ||
1144 | } | ||
1163 | } | 1145 | } |
1164 | catch (Exception e) | 1146 | |
1147 | XmlRpcResponse resp; | ||
1148 | |||
1149 | using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) | ||
1165 | { | 1150 | { |
1166 | RequestResponse = inputXml; | 1151 | using (Stream s = response.GetResponseStream()) |
1167 | throw e; | 1152 | { |
1153 | using (StreamReader input = new StreamReader(s)) | ||
1154 | { | ||
1155 | string inputXml = input.ReadToEnd(); | ||
1156 | |||
1157 | try | ||
1158 | { | ||
1159 | resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); | ||
1160 | } | ||
1161 | catch (Exception e) | ||
1162 | { | ||
1163 | RequestResponse = inputXml; | ||
1164 | throw e; | ||
1165 | } | ||
1166 | } | ||
1167 | } | ||
1168 | } | 1168 | } |
1169 | input.Close(); | 1169 | |
1170 | response.Close(); | ||
1171 | return resp; | 1170 | return resp; |
1172 | } | 1171 | } |
1173 | } | 1172 | } |
diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs index 32e93b4..50276ae 100644 --- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs | |||
@@ -63,7 +63,7 @@ namespace OpenSim.Region.DataSnapshot | |||
63 | 63 | ||
64 | public Hashtable OnGetSnapshot(Hashtable keysvals) | 64 | public Hashtable OnGetSnapshot(Hashtable keysvals) |
65 | { | 65 | { |
66 | m_log.Info("[DATASNAPSHOT] Received collection request"); | 66 | m_log.Debug("[DATASNAPSHOT] Received collection request"); |
67 | Hashtable reply = new Hashtable(); | 67 | Hashtable reply = new Hashtable(); |
68 | int statuscode = 200; | 68 | int statuscode = 200; |
69 | 69 | ||
@@ -80,7 +80,7 @@ namespace OpenSim.Region.DataSnapshot | |||
80 | 80 | ||
81 | public Hashtable OnValidate(Hashtable keysvals) | 81 | public Hashtable OnValidate(Hashtable keysvals) |
82 | { | 82 | { |
83 | m_log.Info("[DATASNAPSHOT] Received validation request"); | 83 | m_log.Debug("[DATASNAPSHOT] Received validation request"); |
84 | Hashtable reply = new Hashtable(); | 84 | Hashtable reply = new Hashtable(); |
85 | int statuscode = 200; | 85 | int statuscode = 200; |
86 | 86 | ||
diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/OptionalModules/DataSnapshot/DataSnapshotManager.cs index 5e62f23..0c3446d 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/DataSnapshotManager.cs | |||
@@ -29,22 +29,20 @@ | |||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.IO; | 31 | using System.IO; |
32 | using System.Linq; | ||
32 | using System.Net; | 33 | using System.Net; |
33 | using System.Reflection; | 34 | using System.Reflection; |
35 | using System.Text; | ||
34 | using System.Xml; | 36 | using System.Xml; |
35 | using log4net; | 37 | using log4net; |
36 | using Nini.Config; | 38 | using Nini.Config; |
37 | using OpenMetaverse; | 39 | using OpenMetaverse; |
38 | using Mono.Addins; | 40 | using Mono.Addins; |
39 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
40 | using OpenSim.Framework.Communications; | ||
41 | using OpenSim.Region.DataSnapshot.Interfaces; | 42 | using OpenSim.Region.DataSnapshot.Interfaces; |
42 | using OpenSim.Region.Framework.Interfaces; | 43 | using OpenSim.Region.Framework.Interfaces; |
43 | using OpenSim.Region.Framework.Scenes; | 44 | using OpenSim.Region.Framework.Scenes; |
44 | 45 | ||
45 | [assembly: Addin("DataSnapshot", "0.1")] | ||
46 | [assembly: AddinDependency("OpenSim", "0.5")] | ||
47 | |||
48 | namespace OpenSim.Region.DataSnapshot | 46 | namespace OpenSim.Region.DataSnapshot |
49 | { | 47 | { |
50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DataSnapshotManager")] | 48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DataSnapshotManager")] |
@@ -113,9 +111,17 @@ namespace OpenSim.Region.DataSnapshot | |||
113 | try | 111 | try |
114 | { | 112 | { |
115 | m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); | 113 | m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); |
116 | IConfig conf = config.Configs["GridService"]; | 114 | string gatekeeper = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI", |
117 | if (conf != null) | 115 | new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty); |
118 | m_gridinfo.Add("gatekeeperURL", conf.GetString("Gatekeeper", String.Empty)); | 116 | // Legacy. Remove soon! |
117 | if (string.IsNullOrEmpty(gatekeeper)) | ||
118 | { | ||
119 | IConfig conf = config.Configs["GridService"]; | ||
120 | if (conf != null) | ||
121 | gatekeeper = conf.GetString("Gatekeeper", gatekeeper); | ||
122 | } | ||
123 | if (!string.IsNullOrEmpty(gatekeeper)) | ||
124 | m_gridinfo.Add("gatekeeperURL", gatekeeper); | ||
119 | 125 | ||
120 | m_gridinfo.Add( | 126 | m_gridinfo.Add( |
121 | "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); | 127 | "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); |
@@ -123,9 +129,12 @@ namespace OpenSim.Region.DataSnapshot | |||
123 | m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); | 129 | m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); |
124 | m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); | 130 | m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); |
125 | m_snapsDir = config.Configs["DataSnapshot"].GetString("snapshot_cache_directory", m_snapsDir); | 131 | m_snapsDir = config.Configs["DataSnapshot"].GetString("snapshot_cache_directory", m_snapsDir); |
126 | m_dataServices = config.Configs["DataSnapshot"].GetString("data_services", m_dataServices); | ||
127 | m_listener_port = config.Configs["Network"].GetString("http_listener_port", m_listener_port); | 132 | m_listener_port = config.Configs["Network"].GetString("http_listener_port", m_listener_port); |
128 | 133 | ||
134 | m_dataServices = config.Configs["DataSnapshot"].GetString("data_services", m_dataServices); | ||
135 | // New way of spec'ing data services, one per line | ||
136 | AddDataServicesVars(config.Configs["DataSnapshot"]); | ||
137 | |||
129 | String[] annoying_string_array = config.Configs["DataSnapshot"].GetString("disable_modules", "").Split(".".ToCharArray()); | 138 | String[] annoying_string_array = config.Configs["DataSnapshot"].GetString("disable_modules", "").Split(".".ToCharArray()); |
130 | foreach (String bloody_wanker in annoying_string_array) | 139 | foreach (String bloody_wanker in annoying_string_array) |
131 | { | 140 | { |
@@ -140,8 +149,6 @@ namespace OpenSim.Region.DataSnapshot | |||
140 | return; | 149 | return; |
141 | } | 150 | } |
142 | 151 | ||
143 | if (m_enabled) | ||
144 | m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); | ||
145 | } | 152 | } |
146 | 153 | ||
147 | } | 154 | } |
@@ -155,8 +162,22 @@ namespace OpenSim.Region.DataSnapshot | |||
155 | 162 | ||
156 | m_log.DebugFormat("[DATASNAPSHOT]: Module added to Scene {0}.", scene.RegionInfo.RegionName); | 163 | m_log.DebugFormat("[DATASNAPSHOT]: Module added to Scene {0}.", scene.RegionInfo.RegionName); |
157 | 164 | ||
158 | m_snapStore.AddScene(scene); | 165 | if (!m_servicesNotified) |
166 | { | ||
167 | m_hostname = scene.RegionInfo.ExternalHostName; | ||
168 | m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); | ||
169 | |||
170 | //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer | ||
171 | new DataRequestHandler(scene, this); | ||
172 | |||
173 | if (m_dataServices != "" && m_dataServices != "noservices") | ||
174 | NotifyDataServices(m_dataServices, "online"); | ||
175 | |||
176 | m_servicesNotified = true; | ||
177 | } | ||
178 | |||
159 | m_scenes.Add(scene); | 179 | m_scenes.Add(scene); |
180 | m_snapStore.AddScene(scene); | ||
160 | 181 | ||
161 | Assembly currentasm = Assembly.GetExecutingAssembly(); | 182 | Assembly currentasm = Assembly.GetExecutingAssembly(); |
162 | 183 | ||
@@ -181,22 +202,6 @@ namespace OpenSim.Region.DataSnapshot | |||
181 | } | 202 | } |
182 | } | 203 | } |
183 | 204 | ||
184 | // Must be done here because on shared modules, PostInitialise() will run | ||
185 | // BEFORE any scenes are registered. There is no "all scenes have been loaded" | ||
186 | // kind of callback because scenes may be created dynamically, so we cannot | ||
187 | // have that info, ever. | ||
188 | if (!m_servicesNotified) | ||
189 | { | ||
190 | //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer | ||
191 | new DataRequestHandler(m_scenes[0], this); | ||
192 | |||
193 | m_hostname = m_scenes[0].RegionInfo.ExternalHostName; | ||
194 | |||
195 | if (m_dataServices != "" && m_dataServices != "noservices") | ||
196 | NotifyDataServices(m_dataServices, "online"); | ||
197 | |||
198 | m_servicesNotified = true; | ||
199 | } | ||
200 | } | 205 | } |
201 | 206 | ||
202 | public void RemoveRegion(Scene scene) | 207 | public void RemoveRegion(Scene scene) |
@@ -285,6 +290,28 @@ namespace OpenSim.Region.DataSnapshot | |||
285 | return null; | 290 | return null; |
286 | } | 291 | } |
287 | 292 | ||
293 | private void AddDataServicesVars(IConfig config) | ||
294 | { | ||
295 | // Make sure the services given this way aren't in m_dataServices already | ||
296 | List<string> servs = new List<string>(m_dataServices.Split(new char[] { ';' })); | ||
297 | |||
298 | StringBuilder sb = new StringBuilder(); | ||
299 | string[] keys = config.GetKeys(); | ||
300 | |||
301 | if (keys.Length > 0) | ||
302 | { | ||
303 | IEnumerable<string> serviceKeys = keys.Where(value => value.StartsWith("DATA_SRV_")); | ||
304 | foreach (string serviceKey in serviceKeys) | ||
305 | { | ||
306 | string keyValue = config.GetString(serviceKey, string.Empty).Trim(); | ||
307 | if (!servs.Contains(keyValue)) | ||
308 | sb.Append(keyValue).Append(";"); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | m_dataServices = (m_dataServices == "noservices") ? sb.ToString() : sb.Append(m_dataServices).ToString(); | ||
313 | } | ||
314 | |||
288 | #endregion | 315 | #endregion |
289 | 316 | ||
290 | #region [Public] Snapshot storage functions | 317 | #region [Public] Snapshot storage functions |
@@ -303,7 +330,7 @@ namespace OpenSim.Region.DataSnapshot | |||
303 | XmlNode regiondata = requestedSnap.CreateNode(XmlNodeType.Element, "regiondata", ""); | 330 | XmlNode regiondata = requestedSnap.CreateNode(XmlNodeType.Element, "regiondata", ""); |
304 | try | 331 | try |
305 | { | 332 | { |
306 | if (regionName == null || regionName == "") | 333 | if (string.IsNullOrEmpty(regionName)) |
307 | { | 334 | { |
308 | XmlNode timerblock = requestedSnap.CreateNode(XmlNodeType.Element, "expire", ""); | 335 | XmlNode timerblock = requestedSnap.CreateNode(XmlNodeType.Element, "expire", ""); |
309 | timerblock.InnerText = m_period.ToString(); | 336 | timerblock.InnerText = m_period.ToString(); |
@@ -364,43 +391,46 @@ namespace OpenSim.Region.DataSnapshot | |||
364 | string delimStr = ";"; | 391 | string delimStr = ";"; |
365 | char [] delimiter = delimStr.ToCharArray(); | 392 | char [] delimiter = delimStr.ToCharArray(); |
366 | 393 | ||
367 | string[] services = servicesStr.Split(delimiter); | 394 | string[] services = servicesStr.Split(delimiter, StringSplitOptions.RemoveEmptyEntries); |
368 | 395 | ||
369 | for (int i = 0; i < services.Length; i++) | 396 | for (int i = 0; i < services.Length; i++) |
370 | { | 397 | { |
371 | string url = services[i].Trim(); | 398 | string url = services[i].Trim(); |
372 | RestClient cli = new RestClient(url); | 399 | using (RestClient cli = new RestClient(url)) |
373 | cli.AddQueryParameter("service", serviceName); | ||
374 | cli.AddQueryParameter("host", m_hostname); | ||
375 | cli.AddQueryParameter("port", m_listener_port); | ||
376 | cli.AddQueryParameter("secret", m_Secret.ToString()); | ||
377 | cli.RequestMethod = "GET"; | ||
378 | try | ||
379 | { | ||
380 | reply = cli.Request(); | ||
381 | } | ||
382 | catch (WebException) | ||
383 | { | ||
384 | m_log.Warn("[DATASNAPSHOT]: Unable to notify " + url); | ||
385 | } | ||
386 | catch (Exception e) | ||
387 | { | ||
388 | m_log.Warn("[DATASNAPSHOT]: Ignoring unknown exception " + e.ToString()); | ||
389 | } | ||
390 | byte[] response = new byte[1024]; | ||
391 | // int n = 0; | ||
392 | try | ||
393 | { | 400 | { |
394 | // n = reply.Read(response, 0, 1024); | 401 | cli.AddQueryParameter("service", serviceName); |
395 | reply.Read(response, 0, 1024); | 402 | cli.AddQueryParameter("host", m_hostname); |
396 | } | 403 | cli.AddQueryParameter("port", m_listener_port); |
397 | catch (Exception e) | 404 | cli.AddQueryParameter("secret", m_Secret.ToString()); |
398 | { | 405 | cli.RequestMethod = "GET"; |
399 | m_log.WarnFormat("[DATASNAPSHOT]: Unable to decode reply from data service. Ignoring. {0}", e.StackTrace); | 406 | try |
407 | { | ||
408 | reply = cli.Request(null); | ||
409 | } | ||
410 | catch (WebException) | ||
411 | { | ||
412 | m_log.Warn("[DATASNAPSHOT]: Unable to notify " + url); | ||
413 | } | ||
414 | catch (Exception e) | ||
415 | { | ||
416 | m_log.Warn("[DATASNAPSHOT]: Ignoring unknown exception " + e.ToString()); | ||
417 | } | ||
418 | |||
419 | byte[] response = new byte[1024]; | ||
420 | // int n = 0; | ||
421 | try | ||
422 | { | ||
423 | // n = reply.Read(response, 0, 1024); | ||
424 | reply.Read(response, 0, 1024); | ||
425 | } | ||
426 | catch (Exception e) | ||
427 | { | ||
428 | m_log.WarnFormat("[DATASNAPSHOT]: Unable to decode reply from data service. Ignoring. {0}", e.StackTrace); | ||
429 | } | ||
430 | // This is not quite working, so... | ||
431 | // string responseStr = Util.UTF8.GetString(response); | ||
432 | m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret); | ||
400 | } | 433 | } |
401 | // This is not quite working, so... | ||
402 | // string responseStr = Util.UTF8.GetString(response); | ||
403 | m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret); | ||
404 | } | 434 | } |
405 | 435 | ||
406 | } | 436 | } |
diff --git a/OpenSim/Region/DataSnapshot/EstateSnapshot.cs b/OpenSim/Region/OptionalModules/DataSnapshot/EstateSnapshot.cs index 8da9e8c..8da9e8c 100644 --- a/OpenSim/Region/DataSnapshot/EstateSnapshot.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/EstateSnapshot.cs | |||
diff --git a/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshot.cs b/OpenSim/Region/OptionalModules/DataSnapshot/Interfaces/IDataSnapshot.cs index 3b3db65..3b3db65 100644 --- a/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshot.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/Interfaces/IDataSnapshot.cs | |||
diff --git a/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshotProvider.cs b/OpenSim/Region/OptionalModules/DataSnapshot/Interfaces/IDataSnapshotProvider.cs index daea373..daea373 100644 --- a/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshotProvider.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/Interfaces/IDataSnapshotProvider.cs | |||
diff --git a/OpenSim/Region/DataSnapshot/LLSDDiscovery.cs b/OpenSim/Region/OptionalModules/DataSnapshot/LLSDDiscovery.cs index 54a87f9..54a87f9 100644 --- a/OpenSim/Region/DataSnapshot/LLSDDiscovery.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/LLSDDiscovery.cs | |||
diff --git a/OpenSim/Region/DataSnapshot/LandSnapshot.cs b/OpenSim/Region/OptionalModules/DataSnapshot/LandSnapshot.cs index b8c90cd..b8c90cd 100644 --- a/OpenSim/Region/DataSnapshot/LandSnapshot.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/LandSnapshot.cs | |||
diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/OptionalModules/DataSnapshot/ObjectSnapshot.cs index 0bb4044..0bb4044 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/ObjectSnapshot.cs | |||
diff --git a/OpenSim/Region/DataSnapshot/SnapshotStore.cs b/OpenSim/Region/OptionalModules/DataSnapshot/SnapshotStore.cs index aa3d2ff..480aaaf 100644 --- a/OpenSim/Region/DataSnapshot/SnapshotStore.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/SnapshotStore.cs | |||
@@ -120,7 +120,7 @@ namespace OpenSim.Region.DataSnapshot | |||
120 | provider.Stale = false; | 120 | provider.Stale = false; |
121 | m_scenes[provider.GetParentScene] = true; | 121 | m_scenes[provider.GetParentScene] = true; |
122 | 122 | ||
123 | m_log.Info("[DATASNAPSHOT]: Generated fragment response for provider type " + provider.Name); | 123 | m_log.Debug("[DATASNAPSHOT]: Generated fragment response for provider type " + provider.Name); |
124 | } | 124 | } |
125 | else | 125 | else |
126 | { | 126 | { |
@@ -134,7 +134,7 @@ namespace OpenSim.Region.DataSnapshot | |||
134 | data = factory.ImportNode(node, true); | 134 | data = factory.ImportNode(node, true); |
135 | } | 135 | } |
136 | 136 | ||
137 | m_log.Info("[DATASNAPSHOT]: Retrieved fragment response for provider type " + provider.Name); | 137 | m_log.Debug("[DATASNAPSHOT]: Retrieved fragment response for provider type " + provider.Name); |
138 | } | 138 | } |
139 | 139 | ||
140 | return data; | 140 | return data; |
@@ -154,7 +154,7 @@ namespace OpenSim.Region.DataSnapshot | |||
154 | 154 | ||
155 | if (!m_scenes[scene]) | 155 | if (!m_scenes[scene]) |
156 | { | 156 | { |
157 | m_log.Info("[DATASNAPSHOT]: Attempting to retrieve snapshot from cache."); | 157 | m_log.Debug("[DATASNAPSHOT]: Attempting to retrieve snapshot from cache."); |
158 | //get snapshot from cache | 158 | //get snapshot from cache |
159 | String path = DataFileNameScene(scene); | 159 | String path = DataFileNameScene(scene); |
160 | 160 | ||
@@ -168,11 +168,11 @@ namespace OpenSim.Region.DataSnapshot | |||
168 | regionElement = factory.ImportNode(node, true); | 168 | regionElement = factory.ImportNode(node, true); |
169 | } | 169 | } |
170 | 170 | ||
171 | m_log.Info("[DATASNAPSHOT]: Obtained snapshot from cache for " + scene.RegionInfo.RegionName); | 171 | m_log.Debug("[DATASNAPSHOT]: Obtained snapshot from cache for " + scene.RegionInfo.RegionName); |
172 | } | 172 | } |
173 | else | 173 | else |
174 | { | 174 | { |
175 | m_log.Info("[DATASNAPSHOT]: Attempting to generate snapshot."); | 175 | m_log.Debug("[DATASNAPSHOT]: Attempting to generate snapshot."); |
176 | //make snapshot | 176 | //make snapshot |
177 | regionElement = MakeRegionNode(scene, factory); | 177 | regionElement = MakeRegionNode(scene, factory); |
178 | 178 | ||
@@ -211,7 +211,7 @@ namespace OpenSim.Region.DataSnapshot | |||
211 | 211 | ||
212 | m_scenes[scene] = false; | 212 | m_scenes[scene] = false; |
213 | 213 | ||
214 | m_log.Info("[DATASNAPSHOT]: Generated new snapshot for " + scene.RegionInfo.RegionName); | 214 | m_log.Debug("[DATASNAPSHOT]: Generated new snapshot for " + scene.RegionInfo.RegionName); |
215 | } | 215 | } |
216 | 216 | ||
217 | return regionElement; | 217 | return regionElement; |
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs index 7d37135..bbf7168 100644 --- a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs +++ b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs | |||
@@ -33,6 +33,12 @@ using Nini.Config; | |||
33 | using OpenSim.Region.Framework.Interfaces; | 33 | using OpenSim.Region.Framework.Interfaces; |
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | 35 | ||
36 | // You will need to uncomment these lines if you are adding a region module to some other assembly which does not already | ||
37 | // specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans | ||
38 | // the available DLLs | ||
39 | //[assembly: Addin("MyModule", "1.0")] | ||
40 | //[assembly: AddinDependency("OpenSim", "0.8.1")] | ||
41 | |||
36 | namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared | 42 | namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared |
37 | { | 43 | { |
38 | /// <summary> | 44 | /// <summary> |
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs index 781fe95..46fea3e 100644 --- a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs +++ b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs | |||
@@ -33,6 +33,12 @@ using Nini.Config; | |||
33 | using OpenSim.Region.Framework.Interfaces; | 33 | using OpenSim.Region.Framework.Interfaces; |
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | 35 | ||
36 | // You will need to uncomment these lines if you are adding a region module to some other assembly which does not already | ||
37 | // specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans | ||
38 | // the available DLLs | ||
39 | //[assembly: Addin("MyModule", "1.0")] | ||
40 | //[assembly: AddinDependency("OpenSim", "0.8.1")] | ||
41 | |||
36 | namespace OpenSim.Region.OptionalModules.Example.BareBonesShared | 42 | namespace OpenSim.Region.OptionalModules.Example.BareBonesShared |
37 | { | 43 | { |
38 | /// <summary> | 44 | /// <summary> |
diff --git a/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs new file mode 100644 index 0000000..5bf0ed4 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs | |||
@@ -0,0 +1,175 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using OpenSim.Framework.Servers; | ||
32 | using Mono.Addins; | ||
33 | using log4net; | ||
34 | using Nini.Config; | ||
35 | using OpenSim.Region.Framework.Interfaces; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | |||
38 | using OpenSim.Framework.Servers.HttpServer; | ||
39 | |||
40 | |||
41 | namespace OpenSim.Region.OptionalModules.WebSocketEchoModule | ||
42 | { | ||
43 | |||
44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebSocketEchoModule")] | ||
45 | public class WebSocketEchoModule : ISharedRegionModule | ||
46 | { | ||
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | private bool enabled; | ||
50 | public string Name { get { return "WebSocketEchoModule"; } } | ||
51 | |||
52 | public Type ReplaceableInterface { get { return null; } } | ||
53 | |||
54 | |||
55 | private HashSet<WebSocketHttpServerHandler> _activeHandlers = new HashSet<WebSocketHttpServerHandler>(); | ||
56 | |||
57 | public void Initialise(IConfigSource pConfig) | ||
58 | { | ||
59 | enabled = (pConfig.Configs["WebSocketEcho"] != null); | ||
60 | // if (enabled) | ||
61 | // m_log.DebugFormat("[WebSocketEchoModule]: INITIALIZED MODULE"); | ||
62 | } | ||
63 | |||
64 | /// <summary> | ||
65 | /// This method sets up the callback to WebSocketHandlerCallback below when a HTTPRequest comes in for /echo | ||
66 | /// </summary> | ||
67 | public void PostInitialise() | ||
68 | { | ||
69 | if (enabled) | ||
70 | MainServer.Instance.AddWebSocketHandler("/echo", WebSocketHandlerCallback); | ||
71 | } | ||
72 | |||
73 | // This gets called by BaseHttpServer and gives us an opportunity to set things on the WebSocket handler before we turn it on | ||
74 | public void WebSocketHandlerCallback(string path, WebSocketHttpServerHandler handler) | ||
75 | { | ||
76 | SubscribeToEvents(handler); | ||
77 | handler.SetChunksize(8192); | ||
78 | handler.NoDelay_TCP_Nagle = true; | ||
79 | handler.HandshakeAndUpgrade(); | ||
80 | } | ||
81 | |||
82 | //These are our normal events | ||
83 | public void SubscribeToEvents(WebSocketHttpServerHandler handler) | ||
84 | { | ||
85 | handler.OnClose += HandlerOnOnClose; | ||
86 | handler.OnText += HandlerOnOnText; | ||
87 | handler.OnUpgradeCompleted += HandlerOnOnUpgradeCompleted; | ||
88 | handler.OnData += HandlerOnOnData; | ||
89 | handler.OnPong += HandlerOnOnPong; | ||
90 | } | ||
91 | |||
92 | public void UnSubscribeToEvents(WebSocketHttpServerHandler handler) | ||
93 | { | ||
94 | handler.OnClose -= HandlerOnOnClose; | ||
95 | handler.OnText -= HandlerOnOnText; | ||
96 | handler.OnUpgradeCompleted -= HandlerOnOnUpgradeCompleted; | ||
97 | handler.OnData -= HandlerOnOnData; | ||
98 | handler.OnPong -= HandlerOnOnPong; | ||
99 | } | ||
100 | |||
101 | private void HandlerOnOnPong(object sender, PongEventArgs pongdata) | ||
102 | { | ||
103 | m_log.Info("[WebSocketEchoModule]: Got a pong.. ping time: " + pongdata.PingResponseMS); | ||
104 | } | ||
105 | |||
106 | private void HandlerOnOnData(object sender, WebsocketDataEventArgs data) | ||
107 | { | ||
108 | WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; | ||
109 | obj.SendData(data.Data); | ||
110 | m_log.Info("[WebSocketEchoModule]: We received a bunch of ugly non-printable bytes"); | ||
111 | obj.SendPingCheck(); | ||
112 | } | ||
113 | |||
114 | |||
115 | private void HandlerOnOnUpgradeCompleted(object sender, UpgradeCompletedEventArgs completeddata) | ||
116 | { | ||
117 | WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; | ||
118 | _activeHandlers.Add(obj); | ||
119 | } | ||
120 | |||
121 | private void HandlerOnOnText(object sender, WebsocketTextEventArgs text) | ||
122 | { | ||
123 | WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; | ||
124 | obj.SendMessage(text.Data); | ||
125 | m_log.Info("[WebSocketEchoModule]: We received this: " + text.Data); | ||
126 | } | ||
127 | |||
128 | // Remove the references to our handler | ||
129 | private void HandlerOnOnClose(object sender, CloseEventArgs closedata) | ||
130 | { | ||
131 | WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; | ||
132 | UnSubscribeToEvents(obj); | ||
133 | |||
134 | lock (_activeHandlers) | ||
135 | _activeHandlers.Remove(obj); | ||
136 | obj.Dispose(); | ||
137 | } | ||
138 | |||
139 | // Shutting down.. so shut down all sockets. | ||
140 | // Note.. this should be done outside of an ienumerable if you're also hook to the close event. | ||
141 | public void Close() | ||
142 | { | ||
143 | if (!enabled) | ||
144 | return; | ||
145 | |||
146 | // We convert this to a for loop so we're not in in an IEnumerable when the close | ||
147 | //call triggers an event which then removes item from _activeHandlers that we're enumerating | ||
148 | WebSocketHttpServerHandler[] items = new WebSocketHttpServerHandler[_activeHandlers.Count]; | ||
149 | _activeHandlers.CopyTo(items); | ||
150 | |||
151 | for (int i = 0; i < items.Length; i++) | ||
152 | { | ||
153 | items[i].Close(string.Empty); | ||
154 | items[i].Dispose(); | ||
155 | } | ||
156 | _activeHandlers.Clear(); | ||
157 | MainServer.Instance.RemoveWebSocketHandler("/echo"); | ||
158 | } | ||
159 | |||
160 | public void AddRegion(Scene scene) | ||
161 | { | ||
162 | // m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
163 | } | ||
164 | |||
165 | public void RemoveRegion(Scene scene) | ||
166 | { | ||
167 | // m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
168 | } | ||
169 | |||
170 | public void RegionLoaded(Scene scene) | ||
171 | { | ||
172 | // m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
173 | } | ||
174 | } | ||
175 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs new file mode 100644 index 0000000..e95889d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs | |||
@@ -0,0 +1,608 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Security.Cryptography; // for computing md5 hash | ||
33 | using log4net; | ||
34 | using Mono.Addins; | ||
35 | using Nini.Config; | ||
36 | |||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | |||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Framework.Servers; | ||
42 | using OpenSim.Framework.Servers.HttpServer; | ||
43 | using OpenSim.Region.Framework.Interfaces; | ||
44 | using OpenSim.Region.Framework.Scenes; | ||
45 | using OpenSimAssetType = OpenSim.Framework.SLUtil.OpenSimAssetType; | ||
46 | |||
47 | using Ionic.Zlib; | ||
48 | |||
49 | // You will need to uncomment these lines if you are adding a region module to some other assembly which does not already | ||
50 | // specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans | ||
51 | // the available DLLs | ||
52 | //[assembly: Addin("MaterialsModule", "1.0")] | ||
53 | //[assembly: AddinDependency("OpenSim", "0.8.1")] | ||
54 | |||
55 | namespace OpenSim.Region.OptionalModules.Materials | ||
56 | { | ||
57 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MaterialsModule")] | ||
58 | public class MaterialsModule : INonSharedRegionModule | ||
59 | { | ||
60 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
61 | |||
62 | public string Name { get { return "MaterialsModule"; } } | ||
63 | |||
64 | public Type ReplaceableInterface { get { return null; } } | ||
65 | |||
66 | private Scene m_scene = null; | ||
67 | private bool m_enabled = false; | ||
68 | private int m_maxMaterialsPerTransaction = 50; | ||
69 | |||
70 | public Dictionary<UUID, OSDMap> m_regionMaterials = new Dictionary<UUID, OSDMap>(); | ||
71 | |||
72 | public void Initialise(IConfigSource source) | ||
73 | { | ||
74 | m_enabled = true; // default is enabled | ||
75 | |||
76 | IConfig config = source.Configs["Materials"]; | ||
77 | if (config != null) | ||
78 | { | ||
79 | m_enabled = config.GetBoolean("enable_materials", m_enabled); | ||
80 | m_maxMaterialsPerTransaction = config.GetInt("MaxMaterialsPerTransaction", m_maxMaterialsPerTransaction); | ||
81 | } | ||
82 | |||
83 | if (m_enabled) | ||
84 | m_log.DebugFormat("[Materials]: Initialized"); | ||
85 | } | ||
86 | |||
87 | public void Close() | ||
88 | { | ||
89 | if (!m_enabled) | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | public void AddRegion(Scene scene) | ||
94 | { | ||
95 | if (!m_enabled) | ||
96 | return; | ||
97 | |||
98 | m_scene = scene; | ||
99 | m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; | ||
100 | m_scene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; | ||
101 | } | ||
102 | |||
103 | private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) | ||
104 | { | ||
105 | foreach (var part in obj.Parts) | ||
106 | if (part != null) | ||
107 | GetStoredMaterialsInPart(part); | ||
108 | } | ||
109 | |||
110 | private void OnRegisterCaps(OpenMetaverse.UUID agentID, OpenSim.Framework.Capabilities.Caps caps) | ||
111 | { | ||
112 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | ||
113 | |||
114 | IRequestHandler renderMaterialsPostHandler | ||
115 | = new RestStreamHandler("POST", capsBase + "/", | ||
116 | (request, path, param, httpRequest, httpResponse) | ||
117 | => RenderMaterialsPostCap(request, agentID), | ||
118 | "RenderMaterials", null); | ||
119 | caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler); | ||
120 | |||
121 | // OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET | ||
122 | // and POST handlers, (at least at the time this was originally written), so we first set up a POST | ||
123 | // handler normally and then add a GET handler via MainServer | ||
124 | |||
125 | IRequestHandler renderMaterialsGetHandler | ||
126 | = new RestStreamHandler("GET", capsBase + "/", | ||
127 | (request, path, param, httpRequest, httpResponse) | ||
128 | => RenderMaterialsGetCap(request), | ||
129 | "RenderMaterials", null); | ||
130 | MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler); | ||
131 | |||
132 | // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well | ||
133 | IRequestHandler renderMaterialsPutHandler | ||
134 | = new RestStreamHandler("PUT", capsBase + "/", | ||
135 | (request, path, param, httpRequest, httpResponse) | ||
136 | => RenderMaterialsPostCap(request, agentID), | ||
137 | "RenderMaterials", null); | ||
138 | MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); | ||
139 | } | ||
140 | |||
141 | public void RemoveRegion(Scene scene) | ||
142 | { | ||
143 | if (!m_enabled) | ||
144 | return; | ||
145 | |||
146 | m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps; | ||
147 | m_scene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene; | ||
148 | } | ||
149 | |||
150 | public void RegionLoaded(Scene scene) | ||
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; | ||
162 | } | ||
163 | |||
164 | /// <summary> | ||
165 | /// Finds any legacy materials stored in DynAttrs that may exist for this part and add them to 'm_regionMaterials'. | ||
166 | /// </summary> | ||
167 | /// <param name="part"></param> | ||
168 | private void GetLegacyStoredMaterialsInPart(SceneObjectPart part) | ||
169 | { | ||
170 | if (part.DynAttrs == null) | ||
171 | return; | ||
172 | |||
173 | OSD OSMaterials = null; | ||
174 | OSDArray matsArr = null; | ||
175 | |||
176 | lock (part.DynAttrs) | ||
177 | { | ||
178 | if (part.DynAttrs.ContainsStore("OpenSim", "Materials")) | ||
179 | { | ||
180 | OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials"); | ||
181 | |||
182 | if (materialsStore == null) | ||
183 | return; | ||
184 | |||
185 | materialsStore.TryGetValue("Materials", out OSMaterials); | ||
186 | } | ||
187 | |||
188 | if (OSMaterials != null && OSMaterials is OSDArray) | ||
189 | matsArr = OSMaterials as OSDArray; | ||
190 | else | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | if (matsArr == null) | ||
195 | return; | ||
196 | |||
197 | foreach (OSD elemOsd in matsArr) | ||
198 | { | ||
199 | if (elemOsd != null && elemOsd is OSDMap) | ||
200 | { | ||
201 | OSDMap matMap = elemOsd as OSDMap; | ||
202 | if (matMap.ContainsKey("ID") && matMap.ContainsKey("Material")) | ||
203 | { | ||
204 | try | ||
205 | { | ||
206 | lock (m_regionMaterials) | ||
207 | m_regionMaterials[matMap["ID"].AsUUID()] = (OSDMap)matMap["Material"]; | ||
208 | } | ||
209 | catch (Exception e) | ||
210 | { | ||
211 | m_log.Warn("[Materials]: exception decoding persisted legacy material: " + e.ToString()); | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | /// <summary> | ||
219 | /// Find the materials used in the SOP, and add them to 'm_regionMaterials'. | ||
220 | /// </summary> | ||
221 | private void GetStoredMaterialsInPart(SceneObjectPart part) | ||
222 | { | ||
223 | if (part.Shape == null) | ||
224 | return; | ||
225 | |||
226 | var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length); | ||
227 | if (te == null) | ||
228 | return; | ||
229 | |||
230 | GetLegacyStoredMaterialsInPart(part); | ||
231 | |||
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); | ||
238 | |||
239 | foreach (Primitive.TextureEntryFace face in te.FaceTextures) | ||
240 | { | ||
241 | if (face != null) | ||
242 | GetStoredMaterialInFace(part, face); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /// <summary> | ||
247 | /// Find the materials used in one Face, and add them to 'm_regionMaterials'. | ||
248 | /// </summary> | ||
249 | private void GetStoredMaterialInFace(SceneObjectPart part, Primitive.TextureEntryFace face) | ||
250 | { | ||
251 | UUID id = face.MaterialID; | ||
252 | if (id == UUID.Zero) | ||
253 | return; | ||
254 | |||
255 | lock (m_regionMaterials) | ||
256 | { | ||
257 | if (m_regionMaterials.ContainsKey(id)) | ||
258 | return; | ||
259 | |||
260 | byte[] data = m_scene.AssetService.GetData(id.ToString()); | ||
261 | if (data == null) | ||
262 | { | ||
263 | m_log.WarnFormat("[Materials]: Prim \"{0}\" ({1}) contains unknown material ID {2}", part.Name, part.UUID, id); | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | OSDMap mat; | ||
268 | try | ||
269 | { | ||
270 | mat = (OSDMap)OSDParser.DeserializeLLSDXml(data); | ||
271 | } | ||
272 | catch (Exception e) | ||
273 | { | ||
274 | m_log.WarnFormat("[Materials]: cannot decode material asset {0}: {1}", id, e.Message); | ||
275 | return; | ||
276 | } | ||
277 | |||
278 | m_regionMaterials[id] = mat; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | public string RenderMaterialsPostCap(string request, UUID agentID) | ||
283 | { | ||
284 | OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); | ||
285 | OSDMap resp = new OSDMap(); | ||
286 | |||
287 | OSDMap materialsFromViewer = null; | ||
288 | |||
289 | OSDArray respArr = new OSDArray(); | ||
290 | |||
291 | if (req.ContainsKey("Zipped")) | ||
292 | { | ||
293 | OSD osd = null; | ||
294 | |||
295 | byte[] inBytes = req["Zipped"].AsBinary(); | ||
296 | |||
297 | try | ||
298 | { | ||
299 | osd = ZDecompressBytesToOsd(inBytes); | ||
300 | |||
301 | if (osd != null) | ||
302 | { | ||
303 | if (osd is OSDArray) // assume array of MaterialIDs designating requested material entries | ||
304 | { | ||
305 | foreach (OSD elem in (OSDArray)osd) | ||
306 | { | ||
307 | try | ||
308 | { | ||
309 | UUID id = new UUID(elem.AsBinary(), 0); | ||
310 | |||
311 | lock (m_regionMaterials) | ||
312 | { | ||
313 | if (m_regionMaterials.ContainsKey(id)) | ||
314 | { | ||
315 | OSDMap matMap = new OSDMap(); | ||
316 | matMap["ID"] = OSD.FromBinary(id.GetBytes()); | ||
317 | matMap["Material"] = m_regionMaterials[id]; | ||
318 | respArr.Add(matMap); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | m_log.Warn("[Materials]: request for unknown material ID: " + id.ToString()); | ||
323 | |||
324 | // Theoretically we could try to load the material from the assets service, | ||
325 | // but that shouldn't be necessary because the viewer should only request | ||
326 | // materials that exist in a prim on the region, and all of these materials | ||
327 | // are already stored in m_regionMaterials. | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | catch (Exception e) | ||
332 | { | ||
333 | m_log.Error("Error getting materials in response to viewer request", e); | ||
334 | continue; | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | else if (osd is OSDMap) // request to assign a material | ||
339 | { | ||
340 | materialsFromViewer = osd as OSDMap; | ||
341 | |||
342 | if (materialsFromViewer.ContainsKey("FullMaterialsPerFace")) | ||
343 | { | ||
344 | OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"]; | ||
345 | if (matsOsd is OSDArray) | ||
346 | { | ||
347 | OSDArray matsArr = matsOsd as OSDArray; | ||
348 | |||
349 | try | ||
350 | { | ||
351 | foreach (OSDMap matsMap in matsArr) | ||
352 | { | ||
353 | uint primLocalID = 0; | ||
354 | try { | ||
355 | primLocalID = matsMap["ID"].AsUInteger(); | ||
356 | } | ||
357 | catch (Exception e) { | ||
358 | m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message); | ||
359 | continue; | ||
360 | } | ||
361 | |||
362 | OSDMap mat = null; | ||
363 | try | ||
364 | { | ||
365 | mat = matsMap["Material"] as OSDMap; | ||
366 | } | ||
367 | catch (Exception e) | ||
368 | { | ||
369 | m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message); | ||
370 | continue; | ||
371 | } | ||
372 | |||
373 | SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID); | ||
374 | if (sop == null) | ||
375 | { | ||
376 | m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString()); | ||
377 | continue; | ||
378 | } | ||
379 | |||
380 | if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID)) | ||
381 | { | ||
382 | m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID); | ||
383 | continue; | ||
384 | } | ||
385 | |||
386 | Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); | ||
387 | if (te == null) | ||
388 | { | ||
389 | m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID); | ||
390 | continue; | ||
391 | } | ||
392 | |||
393 | |||
394 | UUID id; | ||
395 | if (mat == null) | ||
396 | { | ||
397 | // This happens then the user removes a material from a prim | ||
398 | id = UUID.Zero; | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | id = StoreMaterialAsAsset(agentID, mat, sop); | ||
403 | } | ||
404 | |||
405 | |||
406 | int face = -1; | ||
407 | |||
408 | if (matsMap.ContainsKey("Face")) | ||
409 | { | ||
410 | face = matsMap["Face"].AsInteger(); | ||
411 | Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face); | ||
412 | faceEntry.MaterialID = id; | ||
413 | } | ||
414 | else | ||
415 | { | ||
416 | if (te.DefaultTexture == null) | ||
417 | m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID); | ||
418 | else | ||
419 | te.DefaultTexture.MaterialID = id; | ||
420 | } | ||
421 | |||
422 | //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); | ||
423 | |||
424 | // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually | ||
425 | sop.Shape.TextureEntry = te.GetBytes(); | ||
426 | |||
427 | if (sop.ParentGroup != null) | ||
428 | { | ||
429 | sop.TriggerScriptChangedEvent(Changed.TEXTURE); | ||
430 | sop.UpdateFlag = UpdateRequired.FULL; | ||
431 | sop.ParentGroup.HasGroupChanged = true; | ||
432 | sop.ScheduleFullUpdate(); | ||
433 | } | ||
434 | } | ||
435 | } | ||
436 | catch (Exception e) | ||
437 | { | ||
438 | m_log.Warn("[Materials]: exception processing received material ", e); | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | } | ||
446 | catch (Exception e) | ||
447 | { | ||
448 | m_log.Warn("[Materials]: exception decoding zipped CAP payload ", e); | ||
449 | //return ""; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | |||
454 | resp["Zipped"] = ZCompressOSD(respArr, false); | ||
455 | string response = OSDParser.SerializeLLSDXmlString(resp); | ||
456 | |||
457 | //m_log.Debug("[Materials]: cap request: " + request); | ||
458 | //m_log.Debug("[Materials]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary())); | ||
459 | //m_log.Debug("[Materials]: cap response: " + response); | ||
460 | return response; | ||
461 | } | ||
462 | |||
463 | private UUID StoreMaterialAsAsset(UUID agentID, OSDMap mat, SceneObjectPart sop) | ||
464 | { | ||
465 | UUID id; | ||
466 | // Material UUID = hash of the material's data. | ||
467 | // This makes materials deduplicate across the entire grid (but isn't otherwise required). | ||
468 | byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat)); | ||
469 | using (var md5 = MD5.Create()) | ||
470 | id = new UUID(md5.ComputeHash(data), 0); | ||
471 | |||
472 | lock (m_regionMaterials) | ||
473 | { | ||
474 | if (!m_regionMaterials.ContainsKey(id)) | ||
475 | { | ||
476 | m_regionMaterials[id] = mat; | ||
477 | |||
478 | // This asset might exist already, but it's ok to try to store it again | ||
479 | string name = "Material " + ChooseMaterialName(mat, sop); | ||
480 | name = name.Substring(0, Math.Min(64, name.Length)).Trim(); | ||
481 | AssetBase asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString()); | ||
482 | asset.Data = data; | ||
483 | m_scene.AssetService.Store(asset); | ||
484 | } | ||
485 | } | ||
486 | return id; | ||
487 | } | ||
488 | |||
489 | /// <summary> | ||
490 | /// Use heuristics to choose a good name for the material. | ||
491 | /// </summary> | ||
492 | private string ChooseMaterialName(OSDMap mat, SceneObjectPart sop) | ||
493 | { | ||
494 | UUID normMap = mat["NormMap"].AsUUID(); | ||
495 | if (normMap != UUID.Zero) | ||
496 | { | ||
497 | AssetBase asset = m_scene.AssetService.GetCached(normMap.ToString()); | ||
498 | if ((asset != null) && (asset.Name.Length > 0) && !asset.Name.Equals("From IAR")) | ||
499 | return asset.Name; | ||
500 | } | ||
501 | |||
502 | UUID specMap = mat["SpecMap"].AsUUID(); | ||
503 | if (specMap != UUID.Zero) | ||
504 | { | ||
505 | AssetBase asset = m_scene.AssetService.GetCached(specMap.ToString()); | ||
506 | if ((asset != null) && (asset.Name.Length > 0) && !asset.Name.Equals("From IAR")) | ||
507 | return asset.Name; | ||
508 | } | ||
509 | |||
510 | if (sop.Name != "Primitive") | ||
511 | return sop.Name; | ||
512 | |||
513 | if ((sop.ParentGroup != null) && (sop.ParentGroup.Name != "Primitive")) | ||
514 | return sop.ParentGroup.Name; | ||
515 | |||
516 | return ""; | ||
517 | } | ||
518 | |||
519 | |||
520 | public string RenderMaterialsGetCap(string request) | ||
521 | { | ||
522 | OSDMap resp = new OSDMap(); | ||
523 | int matsCount = 0; | ||
524 | OSDArray allOsd = new OSDArray(); | ||
525 | |||
526 | lock (m_regionMaterials) | ||
527 | { | ||
528 | foreach (KeyValuePair<UUID, OSDMap> kvp in m_regionMaterials) | ||
529 | { | ||
530 | OSDMap matMap = new OSDMap(); | ||
531 | |||
532 | matMap["ID"] = OSD.FromBinary(kvp.Key.GetBytes()); | ||
533 | matMap["Material"] = kvp.Value; | ||
534 | allOsd.Add(matMap); | ||
535 | matsCount++; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | resp["Zipped"] = ZCompressOSD(allOsd, false); | ||
540 | |||
541 | return OSDParser.SerializeLLSDXmlString(resp); | ||
542 | } | ||
543 | |||
544 | private static string ZippedOsdBytesToString(byte[] bytes) | ||
545 | { | ||
546 | try | ||
547 | { | ||
548 | return OSDParser.SerializeJsonString(ZDecompressBytesToOsd(bytes)); | ||
549 | } | ||
550 | catch (Exception e) | ||
551 | { | ||
552 | return "ZippedOsdBytesToString caught an exception: " + e.ToString(); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | /// <summary> | ||
557 | /// computes a UUID by hashing a OSD object | ||
558 | /// </summary> | ||
559 | /// <param name="osd"></param> | ||
560 | /// <returns></returns> | ||
561 | private static UUID HashOsd(OSD osd) | ||
562 | { | ||
563 | byte[] data = OSDParser.SerializeLLSDBinary(osd, false); | ||
564 | using (var md5 = MD5.Create()) | ||
565 | return new UUID(md5.ComputeHash(data), 0); | ||
566 | } | ||
567 | |||
568 | public static OSD ZCompressOSD(OSD inOsd, bool useHeader) | ||
569 | { | ||
570 | OSD osd = null; | ||
571 | |||
572 | byte[] data = OSDParser.SerializeLLSDBinary(inOsd, useHeader); | ||
573 | |||
574 | using (MemoryStream msSinkCompressed = new MemoryStream()) | ||
575 | { | ||
576 | using (Ionic.Zlib.ZlibStream zOut = new Ionic.Zlib.ZlibStream(msSinkCompressed, | ||
577 | Ionic.Zlib.CompressionMode.Compress, CompressionLevel.BestCompression, true)) | ||
578 | { | ||
579 | zOut.Write(data, 0, data.Length); | ||
580 | } | ||
581 | |||
582 | msSinkCompressed.Seek(0L, SeekOrigin.Begin); | ||
583 | osd = OSD.FromBinary(msSinkCompressed.ToArray()); | ||
584 | } | ||
585 | |||
586 | return osd; | ||
587 | } | ||
588 | |||
589 | |||
590 | public static OSD ZDecompressBytesToOsd(byte[] input) | ||
591 | { | ||
592 | OSD osd = null; | ||
593 | |||
594 | using (MemoryStream msSinkUnCompressed = new MemoryStream()) | ||
595 | { | ||
596 | using (Ionic.Zlib.ZlibStream zOut = new Ionic.Zlib.ZlibStream(msSinkUnCompressed, CompressionMode.Decompress, true)) | ||
597 | { | ||
598 | zOut.Write(input, 0, input.Length); | ||
599 | } | ||
600 | |||
601 | msSinkUnCompressed.Seek(0L, SeekOrigin.Begin); | ||
602 | osd = OSDParser.DeserializeLLSDBinary(msSinkUnCompressed.ToArray()); | ||
603 | } | ||
604 | |||
605 | return osd; | ||
606 | } | ||
607 | } | ||
608 | } | ||
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs index 40f7fbc..1d9179c 100755 --- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs | |||
@@ -36,7 +36,7 @@ using OpenSim.Framework.Console; | |||
36 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | 36 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; |
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using OpenSim.Region.Physics.Manager; | 39 | using OpenSim.Region.PhysicsModules.SharedBase; |
40 | 40 | ||
41 | namespace OpenSim.Region.OptionalModules.PhysicsParameters | 41 | namespace OpenSim.Region.OptionalModules.PhysicsParameters |
42 | { | 42 | { |
@@ -146,7 +146,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters | |||
146 | { | 146 | { |
147 | foreach (PhysParameterEntry ppe in physScene.GetParameterList()) | 147 | foreach (PhysParameterEntry ppe in physScene.GetParameterList()) |
148 | { | 148 | { |
149 | float val = 0.0f; | 149 | string val = string.Empty; |
150 | if (physScene.GetPhysicsParameter(ppe.name, out val)) | 150 | if (physScene.GetPhysicsParameter(ppe.name, out val)) |
151 | { | 151 | { |
152 | WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val); | 152 | WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val); |
@@ -159,7 +159,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters | |||
159 | } | 159 | } |
160 | else | 160 | else |
161 | { | 161 | { |
162 | float val = 0.0f; | 162 | string val = string.Empty; |
163 | if (physScene.GetPhysicsParameter(parm, out val)) | 163 | if (physScene.GetPhysicsParameter(parm, out val)) |
164 | { | 164 | { |
165 | WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val); | 165 | WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val); |
@@ -185,21 +185,12 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters | |||
185 | return; | 185 | return; |
186 | } | 186 | } |
187 | string parm = "xxx"; | 187 | string parm = "xxx"; |
188 | float val = 0f; | 188 | string valparm = String.Empty; |
189 | uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value | 189 | uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value |
190 | try | 190 | try |
191 | { | 191 | { |
192 | parm = cmdparms[2]; | 192 | parm = cmdparms[2]; |
193 | string valparm = cmdparms[3].ToLower(); | 193 | valparm = cmdparms[3].ToLower(); |
194 | if (valparm == "true") | ||
195 | val = PhysParameterEntry.NUMERIC_TRUE; | ||
196 | else | ||
197 | { | ||
198 | if (valparm == "false") | ||
199 | val = PhysParameterEntry.NUMERIC_FALSE; | ||
200 | else | ||
201 | val = float.Parse(valparm, Culture.NumberFormatInfo); | ||
202 | } | ||
203 | if (cmdparms.Length > 4) | 194 | if (cmdparms.Length > 4) |
204 | { | 195 | { |
205 | if (cmdparms[4].ToLower() == "all") | 196 | if (cmdparms[4].ToLower() == "all") |
@@ -224,7 +215,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters | |||
224 | IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; | 215 | IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; |
225 | if (physScene != null) | 216 | if (physScene != null) |
226 | { | 217 | { |
227 | if (!physScene.SetPhysicsParameter(parm, val, localID)) | 218 | if (!physScene.SetPhysicsParameter(parm, valparm, localID)) |
228 | { | 219 | { |
229 | WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName); | 220 | WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName); |
230 | } | 221 | } |
diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index c1957e2..395bbf1 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs | |||
@@ -26,8 +26,9 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | ||
30 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
31 | using System.Reflection; | ||
31 | using log4net; | 32 | using log4net; |
32 | using Mono.Addins; | 33 | using Mono.Addins; |
33 | using Nini.Config; | 34 | using Nini.Config; |
@@ -57,11 +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 | string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules", |
62 | new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); | ||
61 | 63 | ||
62 | string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); | 64 | List<string> modules = new List<string>(permissionModules.Split(',').Select(m => m.Trim())); |
63 | |||
64 | List<string> modules=new List<string>(permissionModules.Split(',')); | ||
65 | 65 | ||
66 | if(!modules.Contains("PrimLimitsModule")) | 66 | if(!modules.Contains("PrimLimitsModule")) |
67 | return; | 67 | return; |
@@ -102,20 +102,34 @@ namespace OpenSim.Region.OptionalModules | |||
102 | public void RegionLoaded(Scene scene) | 102 | public void RegionLoaded(Scene scene) |
103 | { | 103 | { |
104 | m_dialogModule = scene.RequestModuleInterface<IDialogModule>(); | 104 | m_dialogModule = scene.RequestModuleInterface<IDialogModule>(); |
105 | } | 105 | } |
106 | 106 | ||
107 | private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) | 107 | private bool CanRezObject(int objectCount, UUID ownerID, Vector3 objectPosition, Scene scene) |
108 | { | 108 | { |
109 | ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); | 109 | ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); |
110 | int usedPrims = lo.PrimCounts.Total; | ||
111 | int simulatorCapacity = lo.GetSimulatorMaxPrimCount(); | ||
112 | 110 | ||
113 | if (objectCount + usedPrims > simulatorCapacity) | 111 | string response = DoCommonChecks(objectCount, ownerID, lo, scene); |
112 | |||
113 | if (response != null) | ||
114 | { | 114 | { |
115 | m_dialogModule.SendAlertToUser(owner, "Unable to rez object because the parcel is too full"); | 115 | m_dialogModule.SendAlertToUser(ownerID, response); |
116 | return false; | 116 | return false; |
117 | } | 117 | } |
118 | return true; | ||
119 | } | ||
118 | 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 | } | ||
119 | return true; | 133 | return true; |
120 | } | 134 | } |
121 | 135 | ||
@@ -127,10 +141,12 @@ namespace OpenSim.Region.OptionalModules | |||
127 | ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); | 141 | ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); |
128 | ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); | 142 | ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); |
129 | 143 | ||
130 | int usedPrims = newParcel.PrimCounts.Total; | 144 | // newParcel will be null only if it outside of our current region. If this is the case, then the |
131 | int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); | 145 | // receiving permissions will perform the check. |
132 | 146 | if (newParcel == null) | |
133 | // The prim hasn't crossed a region boundry so we don't need to worry | 147 | return true; |
148 | |||
149 | // The prim hasn't crossed a region boundary so we don't need to worry | ||
134 | // about prim counts here | 150 | // about prim counts here |
135 | if(oldParcel.Equals(newParcel)) | 151 | if(oldParcel.Equals(newParcel)) |
136 | { | 152 | { |
@@ -145,30 +161,53 @@ namespace OpenSim.Region.OptionalModules | |||
145 | } | 161 | } |
146 | 162 | ||
147 | // TODO: Add Special Case here for temporary prims | 163 | // TODO: Add Special Case here for temporary prims |
148 | 164 | ||
149 | if(objectCount + usedPrims > simulatorCapacity) | 165 | string response = DoCommonChecks(objectCount, obj.OwnerID, newParcel, scene); |
166 | |||
167 | if (response != null) | ||
150 | { | 168 | { |
151 | m_dialogModule.SendAlertToUser(obj.OwnerID, "Unable to move object because the destination parcel is too full"); | 169 | m_dialogModule.SendAlertToUser(obj.OwnerID, response); |
152 | return false; | 170 | return false; |
153 | } | 171 | } |
154 | |||
155 | return true; | 172 | return true; |
156 | } | 173 | } |
157 | 174 | ||
158 | //OnDuplicateObject | 175 | private string DoCommonChecks(int objectCount, UUID ownerID, ILandObject lo, Scene scene) |
159 | private bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition) | ||
160 | { | 176 | { |
161 | ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); | 177 | string response = null; |
162 | int usedPrims = lo.PrimCounts.Total; | ||
163 | int simulatorCapacity = lo.GetSimulatorMaxPrimCount(); | ||
164 | 178 | ||
165 | if(objectCount + usedPrims > simulatorCapacity) | 179 | int simulatorCapacity = lo.GetSimulatorMaxPrimCount(); |
180 | if ((objectCount + lo.PrimCounts.Total) > simulatorCapacity) | ||
166 | { | 181 | { |
167 | m_dialogModule.SendAlertToUser(owner, "Unable to duplicate object because the parcel is too full"); | 182 | response = "Unable to rez object because the parcel is too full"; |
168 | return false; | ||
169 | } | 183 | } |
170 | 184 | else | |
171 | return true; | 185 | { |
186 | int maxPrimsPerUser = scene.RegionInfo.MaxPrimsPerUser; | ||
187 | if (maxPrimsPerUser >= 0) | ||
188 | { | ||
189 | // per-user prim limit is set | ||
190 | if (ownerID != lo.LandData.OwnerID || lo.LandData.IsGroupOwned) | ||
191 | { | ||
192 | // caller is not the sole Parcel owner | ||
193 | EstateSettings estateSettings = scene.RegionInfo.EstateSettings; | ||
194 | if (ownerID != estateSettings.EstateOwner) | ||
195 | { | ||
196 | // caller is NOT the Estate owner | ||
197 | List<UUID> mgrs = new List<UUID>(estateSettings.EstateManagers); | ||
198 | if (!mgrs.Contains(ownerID)) | ||
199 | { | ||
200 | // caller is not an Estate Manager | ||
201 | if ((lo.PrimCounts.Users[ownerID] + objectCount) > maxPrimsPerUser) | ||
202 | { | ||
203 | response = "Unable to rez object because you have reached your limit"; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | return response; | ||
172 | } | 211 | } |
173 | } | 212 | } |
174 | } \ No newline at end of file | 213 | } |
diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs index 217b2d5..dc6ca6f 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.7.5.*")] | 33 | [assembly: AssemblyVersion("0.8.3.*")] |
34 | [assembly: AssemblyFileVersion("1.0.0.0")] | ||
35 | 34 | ||
36 | [assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] | 35 | |
37 | [assembly: AddinDependency("OpenSim", "0.5")] | 36 | [assembly: Addin("OpenSim.Region.OptionalModules", OpenSim.VersionInfo.VersionNumber)] |
37 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | ||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerClientEventForwarder.cs index 721d396..721d396 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerClientEventForwarder.cs | |||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs index f424e7f..83732e2 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs | |||
@@ -51,7 +51,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
51 | m_virtScene.UnSubscribeToClientPrimEvents(client); | 51 | m_virtScene.UnSubscribeToClientPrimEvents(client); |
52 | m_virtScene.UnSubscribeToClientPrimRezEvents(client); | 52 | m_virtScene.UnSubscribeToClientPrimRezEvents(client); |
53 | m_virtScene.UnSubscribeToClientInventoryEvents(client); | 53 | m_virtScene.UnSubscribeToClientInventoryEvents(client); |
54 | ((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client); | 54 | if(m_virtScene.AttachmentsModule != null) |
55 | ((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client); | ||
55 | //m_virtScene.UnSubscribeToClientTeleportEvents(client); | 56 | //m_virtScene.UnSubscribeToClientTeleportEvents(client); |
56 | m_virtScene.UnSubscribeToClientScriptEvents(client); | 57 | m_virtScene.UnSubscribeToClientScriptEvents(client); |
57 | 58 | ||
@@ -66,7 +67,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
66 | client.OnRezObject += LocalRezObject; | 67 | client.OnRezObject += LocalRezObject; |
67 | 68 | ||
68 | m_rootScene.SubscribeToClientInventoryEvents(client); | 69 | m_rootScene.SubscribeToClientInventoryEvents(client); |
69 | ((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client); | 70 | if (m_rootScene.AttachmentsModule != null) |
71 | ((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client); | ||
70 | //m_rootScene.SubscribeToClientTeleportEvents(client); | 72 | //m_rootScene.SubscribeToClientTeleportEvents(client); |
71 | m_rootScene.SubscribeToClientScriptEvents(client); | 73 | m_rootScene.SubscribeToClientScriptEvents(client); |
72 | 74 | ||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerLargeLandChannel.cs index a133e51..4bf2a82 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerLargeLandChannel.cs | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | ||
31 | using log4net; | ||
30 | using OpenMetaverse; | 32 | using OpenMetaverse; |
31 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
32 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
@@ -34,10 +36,10 @@ using OpenSim.Region.CoreModules.World.Land; | |||
34 | 36 | ||
35 | namespace OpenSim.Region.RegionCombinerModule | 37 | namespace OpenSim.Region.RegionCombinerModule |
36 | { | 38 | { |
37 | public class RegionCombinerLargeLandChannel : ILandChannel | 39 | public class RegionCombinerLargeLandChannel : ILandChannel |
38 | { | 40 | { |
39 | // private static readonly ILog m_log = | 41 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
40 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | |
41 | private RegionData RegData; | 43 | private RegionData RegData; |
42 | private ILandChannel RootRegionLandChannel; | 44 | private ILandChannel RootRegionLandChannel; |
43 | private readonly List<RegionData> RegionConnections; | 45 | private readonly List<RegionData> RegionConnections; |
@@ -68,42 +70,58 @@ public class RegionCombinerLargeLandChannel : ILandChannel | |||
68 | RootRegionLandChannel.Clear(setupDefaultParcel); | 70 | RootRegionLandChannel.Clear(setupDefaultParcel); |
69 | } | 71 | } |
70 | 72 | ||
71 | public ILandObject GetLandObject(int x, int y) | 73 | public ILandObject GetLandObject(Vector3 position) |
72 | { | 74 | { |
73 | //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y); | 75 | return GetLandObject(position.X, position.Y); |
74 | 76 | } | |
75 | if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize) | ||
76 | { | ||
77 | return RootRegionLandChannel.GetLandObject(x, y); | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | int offsetX = (x / (int)Constants.RegionSize); | ||
82 | int offsetY = (y / (int)Constants.RegionSize); | ||
83 | offsetX *= (int)Constants.RegionSize; | ||
84 | offsetY *= (int)Constants.RegionSize; | ||
85 | 77 | ||
86 | foreach (RegionData regionData in RegionConnections) | 78 | public ILandObject GetLandObject(int x, int y) |
87 | { | 79 | { |
88 | if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY) | 80 | return GetLandObject((float)x, (float)y); |
89 | { | 81 | |
90 | return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY); | 82 | // m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y); |
91 | } | 83 | // |
92 | } | 84 | // if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize) |
93 | ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene); | 85 | // { |
94 | obj.LandData.Name = "NO LAND"; | 86 | // return RootRegionLandChannel.GetLandObject(x, y); |
95 | return obj; | 87 | // } |
96 | } | 88 | // else |
89 | // { | ||
90 | // int offsetX = (x / (int)Constants.RegionSize); | ||
91 | // int offsetY = (y / (int)Constants.RegionSize); | ||
92 | // offsetX *= (int)Constants.RegionSize; | ||
93 | // offsetY *= (int)Constants.RegionSize; | ||
94 | // | ||
95 | // foreach (RegionData regionData in RegionConnections) | ||
96 | // { | ||
97 | // if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY) | ||
98 | // { | ||
99 | // m_log.DebugFormat( | ||
100 | // "[REGION COMBINER LARGE LAND CHANNEL]: Found region {0} at offset {1},{2}", | ||
101 | // regionData.RegionScene.Name, offsetX, offsetY); | ||
102 | // | ||
103 | // return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY); | ||
104 | // } | ||
105 | // } | ||
106 | // //ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene); | ||
107 | // //obj.LandData.Name = "NO LAND"; | ||
108 | // //return obj; | ||
109 | // } | ||
110 | // | ||
111 | // m_log.DebugFormat("[REGION COMBINER LARGE LAND CHANNEL]: No region found at {0},{1}, returning null", x, y); | ||
112 | // | ||
113 | // return null; | ||
97 | } | 114 | } |
98 | 115 | ||
99 | public ILandObject GetLandObject(int localID) | 116 | public ILandObject GetLandObject(int localID) |
100 | { | 117 | { |
118 | // XXX: Possibly should be looking in every land channel, not just the root. | ||
101 | return RootRegionLandChannel.GetLandObject(localID); | 119 | return RootRegionLandChannel.GetLandObject(localID); |
102 | } | 120 | } |
103 | 121 | ||
104 | public ILandObject GetLandObject(float x, float y) | 122 | public ILandObject GetLandObject(float x, float y) |
105 | { | 123 | { |
106 | //m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y); | 124 | // m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y); |
107 | 125 | ||
108 | if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize) | 126 | if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize) |
109 | { | 127 | { |
@@ -120,14 +138,22 @@ public class RegionCombinerLargeLandChannel : ILandChannel | |||
120 | { | 138 | { |
121 | if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY) | 139 | if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY) |
122 | { | 140 | { |
141 | // m_log.DebugFormat( | ||
142 | // "[REGION COMBINER LARGE LAND CHANNEL]: Found region {0} at offset {1},{2}", | ||
143 | // regionData.RegionScene.Name, offsetX, offsetY); | ||
144 | |||
123 | return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY); | 145 | return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY); |
124 | } | 146 | } |
125 | } | 147 | } |
126 | 148 | ||
127 | ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene); | 149 | // ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene); |
128 | obj.LandData.Name = "NO LAND"; | 150 | // obj.LandData.Name = "NO LAND"; |
129 | return obj; | 151 | // return obj; |
130 | } | 152 | } |
153 | |||
154 | // m_log.DebugFormat("[REGION COMBINER LARGE LAND CHANNEL]: No region found at {0},{1}, returning null", x, y); | ||
155 | |||
156 | return null; | ||
131 | } | 157 | } |
132 | 158 | ||
133 | public bool IsForcefulBansAllowed() | 159 | public bool IsForcefulBansAllowed() |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerModule.cs index 905540d..32eead0 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerModule.cs | |||
@@ -36,14 +36,16 @@ using OpenSim.Framework.Client; | |||
36 | using OpenSim.Region.Framework.Interfaces; | 36 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Framework.Console; | 38 | using OpenSim.Framework.Console; |
39 | using OpenSim.Region.Physics.Manager; | 39 | using OpenSim.Region.PhysicsModules.SharedBase; |
40 | using Mono.Addins; | 40 | using Mono.Addins; |
41 | 41 | ||
42 | namespace OpenSim.Region.RegionCombinerModule | 42 | namespace OpenSim.Region.RegionCombinerModule |
43 | { | 43 | { |
44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionCombinerModule")] | ||
44 | public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule | 45 | public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule |
45 | { | 46 | { |
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | // private static string LogHeader = "[REGION COMBINER MODULE]"; | ||
47 | 49 | ||
48 | public string Name | 50 | public string Name |
49 | { | 51 | { |
@@ -77,6 +79,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
77 | { | 79 | { |
78 | IConfig myConfig = source.Configs["Startup"]; | 80 | IConfig myConfig = source.Configs["Startup"]; |
79 | m_combineContiguousRegions = myConfig.GetBoolean("CombineContiguousRegions", false); | 81 | m_combineContiguousRegions = myConfig.GetBoolean("CombineContiguousRegions", false); |
82 | if (m_combineContiguousRegions) | ||
83 | m_log.ErrorFormat("[REGION COMBINER MODULE]: THIS MODULE IS BEING MARKED OBSOLETE AND MAY SOON BE REMOVED. PLEASE USE VARREGIONS INSTEAD."); | ||
80 | 84 | ||
81 | MainConsole.Instance.Commands.AddCommand( | 85 | MainConsole.Instance.Commands.AddCommand( |
82 | "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", | 86 | "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", |
@@ -134,6 +138,49 @@ namespace OpenSim.Region.RegionCombinerModule | |||
134 | throw new Exception(string.Format("Region with id {0} not found", regionId)); | 138 | throw new Exception(string.Format("Region with id {0} not found", regionId)); |
135 | } | 139 | } |
136 | 140 | ||
141 | // Test to see if this postiion (relative to the region) is within the area covered | ||
142 | // by this megaregion. | ||
143 | public bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy) | ||
144 | { | ||
145 | bool ret = false; | ||
146 | if (xx < 0 || yy < 0) | ||
147 | return ret; | ||
148 | |||
149 | foreach (RegionConnections rootRegion in m_regions.Values) | ||
150 | { | ||
151 | if (currentRegion == rootRegion.RegionId) | ||
152 | { | ||
153 | // The caller is in the root region so this is an easy test | ||
154 | if (xx < rootRegion.XEnd && yy < rootRegion.YEnd) | ||
155 | { | ||
156 | ret = true; | ||
157 | } | ||
158 | break; | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | // Maybe the caller is in one of the sub-regions | ||
163 | foreach (RegionData childRegion in rootRegion.ConnectedRegions) | ||
164 | { | ||
165 | if (currentRegion == childRegion.RegionId) | ||
166 | { | ||
167 | // This is a child. Diddle the offsets and check if in | ||
168 | Vector3 positionInMegaregion = childRegion.Offset; | ||
169 | positionInMegaregion.X += xx; | ||
170 | positionInMegaregion.Y += yy; | ||
171 | if (positionInMegaregion.X < rootRegion.XEnd && positionInMegaregion.Y < rootRegion.YEnd) | ||
172 | { | ||
173 | ret = true; | ||
174 | } | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | |||
181 | return ret; | ||
182 | } | ||
183 | |||
137 | private void NewPresence(ScenePresence presence) | 184 | private void NewPresence(ScenePresence presence) |
138 | { | 185 | { |
139 | if (presence.IsChildAgent) | 186 | if (presence.IsChildAgent) |
@@ -220,27 +267,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
220 | // | 267 | // |
221 | */ | 268 | */ |
222 | 269 | ||
223 | // Give each region a standard set of non-infinite borders | ||
224 | Border northBorder = new Border(); | ||
225 | northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- | ||
226 | northBorder.CrossDirection = Cardinals.N; | ||
227 | scene.NorthBorders[0] = northBorder; | ||
228 | |||
229 | Border southBorder = new Border(); | ||
230 | southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> | ||
231 | southBorder.CrossDirection = Cardinals.S; | ||
232 | scene.SouthBorders[0] = southBorder; | ||
233 | |||
234 | Border eastBorder = new Border(); | ||
235 | eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- | ||
236 | eastBorder.CrossDirection = Cardinals.E; | ||
237 | scene.EastBorders[0] = eastBorder; | ||
238 | |||
239 | Border westBorder = new Border(); | ||
240 | westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> | ||
241 | westBorder.CrossDirection = Cardinals.W; | ||
242 | scene.WestBorders[0] = westBorder; | ||
243 | |||
244 | RegionConnections newConn = new RegionConnections(); | 270 | RegionConnections newConn = new RegionConnections(); |
245 | newConn.ConnectedRegions = new List<RegionData>(); | 271 | newConn.ConnectedRegions = new List<RegionData>(); |
246 | newConn.RegionScene = scene; | 272 | newConn.RegionScene = scene; |
@@ -248,8 +274,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
248 | newConn.RegionId = scene.RegionInfo.originRegionID; | 274 | newConn.RegionId = scene.RegionInfo.originRegionID; |
249 | newConn.X = scene.RegionInfo.RegionLocX; | 275 | newConn.X = scene.RegionInfo.RegionLocX; |
250 | newConn.Y = scene.RegionInfo.RegionLocY; | 276 | newConn.Y = scene.RegionInfo.RegionLocY; |
251 | newConn.XEnd = (int)Constants.RegionSize; | 277 | newConn.XEnd = scene.RegionInfo.RegionSizeX; |
252 | newConn.YEnd = (int)Constants.RegionSize; | 278 | newConn.YEnd = scene.RegionInfo.RegionSizeX; |
253 | 279 | ||
254 | lock (m_regions) | 280 | lock (m_regions) |
255 | { | 281 | { |
@@ -415,36 +441,39 @@ namespace OpenSim.Region.RegionCombinerModule | |||
415 | */ | 441 | */ |
416 | #endregion | 442 | #endregion |
417 | 443 | ||
418 | // If we're one region over +x y | 444 | |
445 | // Check to see if this new region is adjacent to the root region. | ||
446 | // Note that we expect the regions to be combined from the root region outward | ||
447 | // thus the requirement for the ordering in the configuration files. | ||
448 | |||
449 | // If we're one region over +x y (i.e. root region is to the west) | ||
419 | //xxx | 450 | //xxx |
420 | //xxy | 451 | //xxy |
421 | //xxx | 452 | //xxx |
422 | |||
423 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) | 453 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) |
424 | { | 454 | { |
425 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); | 455 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); |
426 | break; | 456 | break; |
427 | } | 457 | } |
428 | 458 | ||
429 | // If we're one region over x +y | 459 | // If we're one region over x +y (i.e. root region is to the south) |
430 | //xyx | 460 | //xyx |
431 | //xxx | 461 | //xxx |
432 | //xxx | 462 | //xxx |
433 | if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) | 463 | if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) |
434 | { | 464 | { |
435 | connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); | 465 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); |
436 | break; | 466 | break; |
437 | } | 467 | } |
438 | 468 | ||
439 | // If we're one region over +x +y | 469 | // If we're one region over +x +y (i.e. root region is to the south-west) |
440 | //xxy | 470 | //xxy |
441 | //xxx | 471 | //xxx |
442 | //xxx | 472 | //xxx |
443 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) | 473 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) |
444 | { | 474 | { |
445 | connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); | 475 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); |
446 | break; | 476 | break; |
447 | |||
448 | } | 477 | } |
449 | } | 478 | } |
450 | 479 | ||
@@ -454,20 +483,20 @@ namespace OpenSim.Region.RegionCombinerModule | |||
454 | DoWorkForRootRegion(newConn, scene); | 483 | DoWorkForRootRegion(newConn, scene); |
455 | } | 484 | } |
456 | } | 485 | } |
457 | |||
458 | // Set up infinite borders around the entire AABB of the combined ConnectedRegions | ||
459 | AdjustLargeRegionBounds(); | ||
460 | } | 486 | } |
461 | 487 | ||
462 | private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) | 488 | private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) |
463 | { | 489 | { |
490 | // Offset (in meters) from the base of this region to the base of the root region. | ||
464 | Vector3 offset = Vector3.Zero; | 491 | Vector3 offset = Vector3.Zero; |
465 | offset.X = newConn.PosX - rootConn.PosX; | 492 | offset.X = newConn.PosX - rootConn.PosX; |
466 | offset.Y = newConn.PosY - rootConn.PosY; | 493 | offset.Y = newConn.PosY - rootConn.PosY; |
467 | 494 | ||
495 | // The new total size of the region (in meters) | ||
496 | // We just extend the X and Y dimensions so the extent might temporarily include areas without regions. | ||
468 | Vector3 extents = Vector3.Zero; | 497 | Vector3 extents = Vector3.Zero; |
469 | extents.Y = rootConn.YEnd; | 498 | extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX); |
470 | extents.X = rootConn.XEnd + newConn.XEnd; | 499 | extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY); |
471 | 500 | ||
472 | rootConn.UpdateExtents(extents); | 501 | rootConn.UpdateExtents(extents); |
473 | 502 | ||
@@ -476,9 +505,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
476 | rootConn.RegionScene.RegionInfo.RegionName, | 505 | rootConn.RegionScene.RegionInfo.RegionName, |
477 | newConn.RegionScene.RegionInfo.RegionName, offset, extents); | 506 | newConn.RegionScene.RegionInfo.RegionName, offset, extents); |
478 | 507 | ||
479 | scene.BordersLocked = true; | ||
480 | rootConn.RegionScene.BordersLocked = true; | ||
481 | |||
482 | RegionData ConnectedRegion = new RegionData(); | 508 | RegionData ConnectedRegion = new RegionData(); |
483 | ConnectedRegion.Offset = offset; | 509 | ConnectedRegion.Offset = offset; |
484 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; | 510 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; |
@@ -491,34 +517,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
491 | // Inform Child region that it needs to forward it's terrain to the root region | 517 | // Inform Child region that it needs to forward it's terrain to the root region |
492 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 518 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
493 | 519 | ||
494 | // Extend the borders as appropriate | ||
495 | lock (rootConn.RegionScene.EastBorders) | ||
496 | rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
497 | |||
498 | lock (rootConn.RegionScene.NorthBorders) | ||
499 | rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
500 | |||
501 | lock (rootConn.RegionScene.SouthBorders) | ||
502 | rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
503 | |||
504 | lock (scene.WestBorders) | ||
505 | { | ||
506 | scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West | ||
507 | |||
508 | // Trigger auto teleport to root region | ||
509 | scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
510 | scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
511 | } | ||
512 | |||
513 | // Reset Terrain.. since terrain loads before we get here, we need to load | 520 | // Reset Terrain.. since terrain loads before we get here, we need to load |
514 | // it again so it loads in the root region | 521 | // it again so it loads in the root region |
515 | |||
516 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); | 522 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); |
517 | 523 | ||
518 | // Unlock borders | ||
519 | rootConn.RegionScene.BordersLocked = false; | ||
520 | scene.BordersLocked = false; | ||
521 | |||
522 | // Create a client event forwarder and add this region's events to the root region. | 524 | // Create a client event forwarder and add this region's events to the root region. |
523 | if (rootConn.ClientEventForwarder != null) | 525 | if (rootConn.ClientEventForwarder != null) |
524 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); | 526 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); |
@@ -526,6 +528,9 @@ namespace OpenSim.Region.RegionCombinerModule | |||
526 | return true; | 528 | return true; |
527 | } | 529 | } |
528 | 530 | ||
531 | /* | ||
532 | * 20140215 radams1: The border stuff was removed and the addition of regions to the mega-regions | ||
533 | * was generalized. These functions are not needed for the generalized solution but left for reference. | ||
529 | private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) | 534 | private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) |
530 | { | 535 | { |
531 | Vector3 offset = Vector3.Zero; | 536 | Vector3 offset = Vector3.Zero; |
@@ -537,9 +542,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
537 | extents.X = rootConn.XEnd; | 542 | extents.X = rootConn.XEnd; |
538 | rootConn.UpdateExtents(extents); | 543 | rootConn.UpdateExtents(extents); |
539 | 544 | ||
540 | scene.BordersLocked = true; | ||
541 | rootConn.RegionScene.BordersLocked = true; | ||
542 | |||
543 | RegionData ConnectedRegion = new RegionData(); | 545 | RegionData ConnectedRegion = new RegionData(); |
544 | ConnectedRegion.Offset = offset; | 546 | ConnectedRegion.Offset = offset; |
545 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; | 547 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; |
@@ -554,30 +556,11 @@ namespace OpenSim.Region.RegionCombinerModule | |||
554 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); | 556 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); |
555 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 557 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
556 | 558 | ||
557 | lock (rootConn.RegionScene.NorthBorders) | ||
558 | rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
559 | |||
560 | lock (rootConn.RegionScene.EastBorders) | ||
561 | rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
562 | |||
563 | lock (rootConn.RegionScene.WestBorders) | ||
564 | rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
565 | |||
566 | lock (scene.SouthBorders) | ||
567 | { | ||
568 | scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south | ||
569 | scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
570 | scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
571 | } | ||
572 | |||
573 | // Reset Terrain.. since terrain normally loads first. | 559 | // Reset Terrain.. since terrain normally loads first. |
574 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 560 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
575 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); | 561 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); |
576 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 562 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
577 | 563 | ||
578 | scene.BordersLocked = false; | ||
579 | rootConn.RegionScene.BordersLocked = false; | ||
580 | |||
581 | if (rootConn.ClientEventForwarder != null) | 564 | if (rootConn.ClientEventForwarder != null) |
582 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); | 565 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); |
583 | 566 | ||
@@ -601,9 +584,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
601 | extents.Y = rootConn.YEnd; | 584 | extents.Y = rootConn.YEnd; |
602 | extents.X = rootConn.XEnd; | 585 | extents.X = rootConn.XEnd; |
603 | 586 | ||
604 | scene.BordersLocked = true; | ||
605 | rootConn.RegionScene.BordersLocked = true; | ||
606 | |||
607 | RegionData ConnectedRegion = new RegionData(); | 587 | RegionData ConnectedRegion = new RegionData(); |
608 | ConnectedRegion.Offset = offset; | 588 | ConnectedRegion.Offset = offset; |
609 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; | 589 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; |
@@ -619,68 +599,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
619 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); | 599 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); |
620 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 600 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
621 | 601 | ||
622 | lock (rootConn.RegionScene.NorthBorders) | ||
623 | { | ||
624 | if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) | ||
625 | { | ||
626 | //compound border | ||
627 | // already locked above | ||
628 | rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
629 | |||
630 | lock (rootConn.RegionScene.EastBorders) | ||
631 | rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
632 | |||
633 | lock (rootConn.RegionScene.WestBorders) | ||
634 | rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | lock (scene.SouthBorders) | ||
639 | { | ||
640 | scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south | ||
641 | scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
642 | scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
643 | } | ||
644 | |||
645 | lock (rootConn.RegionScene.EastBorders) | ||
646 | { | ||
647 | if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) | ||
648 | { | ||
649 | |||
650 | rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
651 | |||
652 | lock (rootConn.RegionScene.NorthBorders) | ||
653 | rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
654 | |||
655 | lock (rootConn.RegionScene.SouthBorders) | ||
656 | rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
657 | } | ||
658 | } | ||
659 | |||
660 | lock (scene.WestBorders) | ||
661 | { | ||
662 | scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West | ||
663 | scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
664 | scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | else | ||
669 | { | ||
670 | conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
671 | conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
672 | conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
673 | scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south | ||
674 | } | ||
675 | */ | ||
676 | |||
677 | |||
678 | // Reset Terrain.. since terrain normally loads first. | 602 | // Reset Terrain.. since terrain normally loads first. |
679 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 603 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
680 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); | 604 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); |
681 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 605 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
682 | scene.BordersLocked = false; | ||
683 | rootConn.RegionScene.BordersLocked = false; | ||
684 | 606 | ||
685 | if (rootConn.ClientEventForwarder != null) | 607 | if (rootConn.ClientEventForwarder != null) |
686 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); | 608 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); |
@@ -689,6 +611,7 @@ namespace OpenSim.Region.RegionCombinerModule | |||
689 | 611 | ||
690 | //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); | 612 | //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); |
691 | } | 613 | } |
614 | */ | ||
692 | 615 | ||
693 | private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) | 616 | private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) |
694 | { | 617 | { |
@@ -887,125 +810,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
887 | // } | 810 | // } |
888 | // } | 811 | // } |
889 | 812 | ||
890 | // Create a set of infinite borders around the whole aabb of the combined island. | ||
891 | private void AdjustLargeRegionBounds() | ||
892 | { | ||
893 | lock (m_regions) | ||
894 | { | ||
895 | foreach (RegionConnections rconn in m_regions.Values) | ||
896 | { | ||
897 | Vector3 offset = Vector3.Zero; | ||
898 | rconn.RegionScene.BordersLocked = true; | ||
899 | foreach (RegionData rdata in rconn.ConnectedRegions) | ||
900 | { | ||
901 | if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X; | ||
902 | if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y; | ||
903 | } | ||
904 | |||
905 | lock (rconn.RegionScene.NorthBorders) | ||
906 | { | ||
907 | Border northBorder = null; | ||
908 | // If we don't already have an infinite border, create one. | ||
909 | if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder)) | ||
910 | { | ||
911 | northBorder = new Border(); | ||
912 | rconn.RegionScene.NorthBorders.Add(northBorder); | ||
913 | } | ||
914 | |||
915 | northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, | ||
916 | offset.Y + (int) Constants.RegionSize); //<--- | ||
917 | northBorder.CrossDirection = Cardinals.N; | ||
918 | } | ||
919 | |||
920 | lock (rconn.RegionScene.SouthBorders) | ||
921 | { | ||
922 | Border southBorder = null; | ||
923 | // If we don't already have an infinite border, create one. | ||
924 | if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder)) | ||
925 | { | ||
926 | southBorder = new Border(); | ||
927 | rconn.RegionScene.SouthBorders.Add(southBorder); | ||
928 | } | ||
929 | southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> | ||
930 | southBorder.CrossDirection = Cardinals.S; | ||
931 | } | ||
932 | |||
933 | lock (rconn.RegionScene.EastBorders) | ||
934 | { | ||
935 | Border eastBorder = null; | ||
936 | // If we don't already have an infinite border, create one. | ||
937 | if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder)) | ||
938 | { | ||
939 | eastBorder = new Border(); | ||
940 | rconn.RegionScene.EastBorders.Add(eastBorder); | ||
941 | } | ||
942 | eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize); | ||
943 | //<--- | ||
944 | eastBorder.CrossDirection = Cardinals.E; | ||
945 | } | ||
946 | |||
947 | lock (rconn.RegionScene.WestBorders) | ||
948 | { | ||
949 | Border westBorder = null; | ||
950 | // If we don't already have an infinite border, create one. | ||
951 | if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder)) | ||
952 | { | ||
953 | westBorder = new Border(); | ||
954 | rconn.RegionScene.WestBorders.Add(westBorder); | ||
955 | |||
956 | } | ||
957 | westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> | ||
958 | westBorder.CrossDirection = Cardinals.W; | ||
959 | } | ||
960 | |||
961 | rconn.RegionScene.BordersLocked = false; | ||
962 | } | ||
963 | } | ||
964 | } | ||
965 | |||
966 | /// <summary> | ||
967 | /// Try and get an Infinite border out of a listT of borders | ||
968 | /// </summary> | ||
969 | /// <param name="borders"></param> | ||
970 | /// <param name="oborder"></param> | ||
971 | /// <returns></returns> | ||
972 | public static bool TryGetInfiniteBorder(List<Border> borders, out Border oborder) | ||
973 | { | ||
974 | // Warning! Should be locked before getting here! | ||
975 | foreach (Border b in borders) | ||
976 | { | ||
977 | if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue) | ||
978 | { | ||
979 | oborder = b; | ||
980 | return true; | ||
981 | } | ||
982 | } | ||
983 | |||
984 | oborder = null; | ||
985 | return false; | ||
986 | } | ||
987 | |||
988 | public RegionData GetRegionFromPosition(Vector3 pPosition) | ||
989 | { | ||
990 | pPosition = pPosition/(int) Constants.RegionSize; | ||
991 | int OffsetX = (int) pPosition.X; | ||
992 | int OffsetY = (int) pPosition.Y; | ||
993 | |||
994 | lock (m_regions) | ||
995 | { | ||
996 | foreach (RegionConnections regConn in m_regions.Values) | ||
997 | { | ||
998 | foreach (RegionData reg in regConn.ConnectedRegions) | ||
999 | { | ||
1000 | if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) | ||
1001 | return reg; | ||
1002 | } | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | return new RegionData(); | ||
1007 | } | ||
1008 | |||
1009 | public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) | 813 | public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) |
1010 | { | 814 | { |
1011 | if (BigRegion.PermissionModule == null) | 815 | if (BigRegion.PermissionModule == null) |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerPermissionModule.cs index 7c662c9..07dd68b 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCombinerPermissionModule.cs | |||
@@ -34,7 +34,7 @@ using OpenSim.Region.Framework.Scenes; | |||
34 | 34 | ||
35 | namespace OpenSim.Region.RegionCombinerModule | 35 | namespace OpenSim.Region.RegionCombinerModule |
36 | { | 36 | { |
37 | public class RegionCombinerPermissionModule | 37 | public class RegionCombinerPermissionModule |
38 | { | 38 | { |
39 | private Scene m_rootScene; | 39 | private Scene m_rootScene; |
40 | 40 | ||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionConnections.cs index fba51d2..62a3a91 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionConnections.cs | |||
@@ -64,12 +64,12 @@ namespace OpenSim.Region.RegionCombinerModule | |||
64 | /// <summary> | 64 | /// <summary> |
65 | /// The X meters position of this connection. | 65 | /// The X meters position of this connection. |
66 | /// </summary> | 66 | /// </summary> |
67 | public uint PosX { get { return X * Constants.RegionSize; } } | 67 | public uint PosX { get { return Util.RegionToWorldLoc(X); } } |
68 | 68 | ||
69 | /// <summary> | 69 | /// <summary> |
70 | /// The Y meters co-ordinate of this connection. | 70 | /// The Y meters co-ordinate of this connection. |
71 | /// </summary> | 71 | /// </summary> |
72 | public uint PosY { get { return Y * Constants.RegionSize; } } | 72 | public uint PosY { get { return Util.RegionToWorldLoc(Y); } } |
73 | 73 | ||
74 | /// <summary> | 74 | /// <summary> |
75 | /// The size of the megaregion in meters. | 75 | /// The size of the megaregion in meters. |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCourseLocation.cs index 224ac99..224ac99 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionCourseLocation.cs | |||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionData.cs b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionData.cs index bd0e398..42fca9f 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionData.cs +++ b/OpenSim/Region/OptionalModules/RegionCombinerModule/RegionData.cs | |||
@@ -34,6 +34,7 @@ namespace OpenSim.Region.RegionCombinerModule | |||
34 | { | 34 | { |
35 | public UUID RegionId; | 35 | public UUID RegionId; |
36 | public Scene RegionScene; | 36 | public Scene RegionScene; |
37 | // Offset of this region from the base of the root region. | ||
37 | public Vector3 Offset; | 38 | public Vector3 Offset; |
38 | } | 39 | } |
39 | } \ No newline at end of file | 40 | } \ No newline at end of file |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 34894ba..c38bb3e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs | |||
@@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
49 | private static readonly ILog m_log = | 49 | private static readonly ILog m_log = |
50 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 51 | ||
52 | private OSD m_ValueStore; | 52 | protected virtual OSD ValueStore { get; set; } |
53 | 53 | ||
54 | protected class TakeValueCallbackClass | 54 | protected class TakeValueCallbackClass |
55 | { | 55 | { |
@@ -68,42 +68,141 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
68 | protected List<TakeValueCallbackClass> m_TakeStore; | 68 | protected List<TakeValueCallbackClass> m_TakeStore; |
69 | protected List<TakeValueCallbackClass> m_ReadStore; | 69 | protected List<TakeValueCallbackClass> m_ReadStore; |
70 | 70 | ||
71 | // add separators for quoted paths and array references | ||
72 | protected static Regex m_ParsePassOne = new Regex("({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); | ||
71 | 73 | ||
74 | // add quotes to bare identifiers which are limited to alphabetic characters | ||
75 | protected static Regex m_ParsePassThree = new Regex("(?<!{[^}]*)\\.([a-zA-Z]+)(?=\\.)"); | ||
76 | |||
77 | // remove extra separator characters | ||
78 | protected static Regex m_ParsePassFour = new Regex("\\.+"); | ||
79 | |||
80 | // expression used to validate the full path, this is canonical representation | ||
81 | protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$"); | ||
82 | |||
83 | // expression used to match path components | ||
84 | protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); | ||
85 | |||
86 | // extract the internals of an array reference | ||
87 | protected static Regex m_SimpleArrayPattern = new Regex("^\\[([0-9]+)\\]$"); | ||
88 | protected static Regex m_ArrayPattern = new Regex("^\\[([0-9]+|\\+)\\]$"); | ||
89 | |||
90 | // extract the internals of a has reference | ||
91 | protected static Regex m_HashPattern = new Regex("^{([^}]+)}$"); | ||
92 | |||
93 | // ----------------------------------------------------------------- | ||
94 | /// <summary> | ||
95 | /// This is a simple estimator for the size of the stored data, it | ||
96 | /// is not precise, but should be close enough to implement reasonable | ||
97 | /// limits on the storage space used | ||
98 | /// </summary> | ||
99 | // ----------------------------------------------------------------- | ||
100 | public int StringSpace { get; set; } | ||
101 | |||
72 | // ----------------------------------------------------------------- | 102 | // ----------------------------------------------------------------- |
73 | /// <summary> | 103 | /// <summary> |
74 | /// | 104 | /// |
75 | /// </summary> | 105 | /// </summary> |
76 | // ----------------------------------------------------------------- | 106 | // ----------------------------------------------------------------- |
77 | public JsonStore() : this("") {} | 107 | public static bool CanonicalPathExpression(string ipath, out string opath) |
108 | { | ||
109 | Stack<string> path; | ||
110 | if (! ParsePathExpression(ipath,out path)) | ||
111 | { | ||
112 | opath = ""; | ||
113 | return false; | ||
114 | } | ||
115 | |||
116 | opath = PathExpressionToKey(path); | ||
117 | return true; | ||
118 | } | ||
78 | 119 | ||
79 | public JsonStore(string value) | 120 | // ----------------------------------------------------------------- |
121 | /// <summary> | ||
122 | /// | ||
123 | /// </summary> | ||
124 | // ----------------------------------------------------------------- | ||
125 | public JsonStore() | ||
80 | { | 126 | { |
127 | StringSpace = 0; | ||
81 | m_TakeStore = new List<TakeValueCallbackClass>(); | 128 | m_TakeStore = new List<TakeValueCallbackClass>(); |
82 | m_ReadStore = new List<TakeValueCallbackClass>(); | 129 | m_ReadStore = new List<TakeValueCallbackClass>(); |
83 | 130 | } | |
131 | |||
132 | public JsonStore(string value) : this() | ||
133 | { | ||
134 | // This is going to throw an exception if the value is not | ||
135 | // a valid JSON chunk. Calling routines should catch the | ||
136 | // exception and handle it appropriately | ||
84 | if (String.IsNullOrEmpty(value)) | 137 | if (String.IsNullOrEmpty(value)) |
85 | m_ValueStore = new OSDMap(); | 138 | ValueStore = new OSDMap(); |
86 | else | 139 | else |
87 | m_ValueStore = OSDParser.DeserializeJson(value); | 140 | ValueStore = OSDParser.DeserializeJson(value); |
88 | } | 141 | } |
142 | |||
143 | // ----------------------------------------------------------------- | ||
144 | /// <summary> | ||
145 | /// | ||
146 | /// </summary> | ||
147 | // ----------------------------------------------------------------- | ||
148 | public JsonStoreNodeType GetNodeType(string expr) | ||
149 | { | ||
150 | Stack<string> path; | ||
151 | if (! ParsePathExpression(expr,out path)) | ||
152 | return JsonStoreNodeType.Undefined; | ||
153 | |||
154 | OSD result = ProcessPathExpression(ValueStore,path); | ||
89 | 155 | ||
156 | if (result == null) | ||
157 | return JsonStoreNodeType.Undefined; | ||
158 | |||
159 | if (result is OSDMap) | ||
160 | return JsonStoreNodeType.Object; | ||
161 | |||
162 | if (result is OSDArray) | ||
163 | return JsonStoreNodeType.Array; | ||
164 | |||
165 | if (OSDBaseType(result.Type)) | ||
166 | return JsonStoreNodeType.Value; | ||
167 | |||
168 | return JsonStoreNodeType.Undefined; | ||
169 | } | ||
170 | |||
90 | // ----------------------------------------------------------------- | 171 | // ----------------------------------------------------------------- |
91 | /// <summary> | 172 | /// <summary> |
92 | /// | 173 | /// |
93 | /// </summary> | 174 | /// </summary> |
94 | // ----------------------------------------------------------------- | 175 | // ----------------------------------------------------------------- |
95 | public bool TestPath(string expr, bool useJson) | 176 | public JsonStoreValueType GetValueType(string expr) |
96 | { | 177 | { |
97 | Stack<string> path = ParsePathExpression(expr); | 178 | Stack<string> path; |
98 | OSD result = ProcessPathExpression(m_ValueStore,path); | 179 | if (! ParsePathExpression(expr,out path)) |
180 | return JsonStoreValueType.Undefined; | ||
181 | |||
182 | OSD result = ProcessPathExpression(ValueStore,path); | ||
99 | 183 | ||
100 | if (result == null) | 184 | if (result == null) |
101 | return false; | 185 | return JsonStoreValueType.Undefined; |
102 | 186 | ||
103 | if (useJson || result.Type == OSDType.String) | 187 | if (result is OSDMap) |
104 | return true; | 188 | return JsonStoreValueType.Undefined; |
105 | 189 | ||
106 | return false; | 190 | if (result is OSDArray) |
191 | return JsonStoreValueType.Undefined; | ||
192 | |||
193 | if (result is OSDBoolean) | ||
194 | return JsonStoreValueType.Boolean; | ||
195 | |||
196 | if (result is OSDInteger) | ||
197 | return JsonStoreValueType.Integer; | ||
198 | |||
199 | if (result is OSDReal) | ||
200 | return JsonStoreValueType.Float; | ||
201 | |||
202 | if (result is OSDString) | ||
203 | return JsonStoreValueType.String; | ||
204 | |||
205 | return JsonStoreValueType.Undefined; | ||
107 | } | 206 | } |
108 | 207 | ||
109 | // ----------------------------------------------------------------- | 208 | // ----------------------------------------------------------------- |
@@ -111,10 +210,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
111 | /// | 210 | /// |
112 | /// </summary> | 211 | /// </summary> |
113 | // ----------------------------------------------------------------- | 212 | // ----------------------------------------------------------------- |
213 | public int ArrayLength(string expr) | ||
214 | { | ||
215 | Stack<string> path; | ||
216 | if (! ParsePathExpression(expr,out path)) | ||
217 | return -1; | ||
218 | |||
219 | OSD result = ProcessPathExpression(ValueStore,path); | ||
220 | if (result != null && result.Type == OSDType.Array) | ||
221 | { | ||
222 | OSDArray arr = result as OSDArray; | ||
223 | return arr.Count; | ||
224 | } | ||
225 | |||
226 | return -1; | ||
227 | } | ||
228 | |||
229 | // ----------------------------------------------------------------- | ||
230 | /// <summary> | ||
231 | /// | ||
232 | /// </summary> | ||
233 | // ----------------------------------------------------------------- | ||
114 | public bool GetValue(string expr, out string value, bool useJson) | 234 | public bool GetValue(string expr, out string value, bool useJson) |
115 | { | 235 | { |
116 | Stack<string> path = ParsePathExpression(expr); | 236 | Stack<string> path; |
117 | OSD result = ProcessPathExpression(m_ValueStore,path); | 237 | if (! ParsePathExpression(expr,out path)) |
238 | { | ||
239 | value = ""; | ||
240 | return false; | ||
241 | } | ||
242 | |||
243 | OSD result = ProcessPathExpression(ValueStore,path); | ||
118 | return ConvertOutputValue(result,out value,useJson); | 244 | return ConvertOutputValue(result,out value,useJson); |
119 | } | 245 | } |
120 | 246 | ||
@@ -136,7 +262,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
136 | // ----------------------------------------------------------------- | 262 | // ----------------------------------------------------------------- |
137 | public bool SetValue(string expr, string value, bool useJson) | 263 | public bool SetValue(string expr, string value, bool useJson) |
138 | { | 264 | { |
139 | OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value); | 265 | OSD ovalue; |
266 | |||
267 | // One note of caution... if you use an empty string in the | ||
268 | // structure it will be assumed to be a default value and will | ||
269 | // not be seialized in the json | ||
270 | |||
271 | if (useJson) | ||
272 | { | ||
273 | // There doesn't appear to be a good way to determine if the | ||
274 | // value is valid Json other than to let the parser crash | ||
275 | try | ||
276 | { | ||
277 | ovalue = OSDParser.DeserializeJson(value); | ||
278 | } | ||
279 | catch (Exception) | ||
280 | { | ||
281 | if (value.StartsWith("'") && value.EndsWith("'")) | ||
282 | { | ||
283 | ovalue = new OSDString(value.Substring(1,value.Length - 2)); | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | return false; | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | ovalue = new OSDString(value); | ||
294 | } | ||
295 | |||
140 | return SetValueFromExpression(expr,ovalue); | 296 | return SetValueFromExpression(expr,ovalue); |
141 | } | 297 | } |
142 | 298 | ||
@@ -147,10 +303,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
147 | // ----------------------------------------------------------------- | 303 | // ----------------------------------------------------------------- |
148 | public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) | 304 | public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) |
149 | { | 305 | { |
150 | Stack<string> path = ParsePathExpression(expr); | 306 | Stack<string> path; |
307 | if (! ParsePathExpression(expr,out path)) | ||
308 | return false; | ||
309 | |||
151 | string pexpr = PathExpressionToKey(path); | 310 | string pexpr = PathExpressionToKey(path); |
152 | 311 | ||
153 | OSD result = ProcessPathExpression(m_ValueStore,path); | 312 | OSD result = ProcessPathExpression(ValueStore,path); |
154 | if (result == null) | 313 | if (result == null) |
155 | { | 314 | { |
156 | m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); | 315 | m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); |
@@ -178,10 +337,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
178 | // ----------------------------------------------------------------- | 337 | // ----------------------------------------------------------------- |
179 | public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) | 338 | public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) |
180 | { | 339 | { |
181 | Stack<string> path = ParsePathExpression(expr); | 340 | Stack<string> path; |
341 | if (! ParsePathExpression(expr,out path)) | ||
342 | return false; | ||
343 | |||
182 | string pexpr = PathExpressionToKey(path); | 344 | string pexpr = PathExpressionToKey(path); |
183 | 345 | ||
184 | OSD result = ProcessPathExpression(m_ValueStore,path); | 346 | OSD result = ProcessPathExpression(ValueStore,path); |
185 | if (result == null) | 347 | if (result == null) |
186 | { | 348 | { |
187 | m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); | 349 | m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); |
@@ -208,25 +370,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
208 | // ----------------------------------------------------------------- | 370 | // ----------------------------------------------------------------- |
209 | protected bool SetValueFromExpression(string expr, OSD ovalue) | 371 | protected bool SetValueFromExpression(string expr, OSD ovalue) |
210 | { | 372 | { |
211 | Stack<string> path = ParsePathExpression(expr); | 373 | Stack<string> path; |
374 | if (! ParsePathExpression(expr,out path)) | ||
375 | return false; | ||
376 | |||
212 | if (path.Count == 0) | 377 | if (path.Count == 0) |
213 | { | 378 | { |
214 | m_ValueStore = ovalue; | 379 | ValueStore = ovalue; |
380 | StringSpace = 0; | ||
215 | return true; | 381 | return true; |
216 | } | 382 | } |
217 | 383 | ||
384 | // pkey will be the final element in the path, we pull it out here to make sure | ||
385 | // that the assignment works correctly | ||
218 | string pkey = path.Pop(); | 386 | string pkey = path.Pop(); |
219 | string pexpr = PathExpressionToKey(path); | 387 | string pexpr = PathExpressionToKey(path); |
220 | if (pexpr != "") | 388 | if (pexpr != "") |
221 | pexpr += "."; | 389 | pexpr += "."; |
222 | 390 | ||
223 | OSD result = ProcessPathExpression(m_ValueStore,path); | 391 | OSD result = ProcessPathExpression(ValueStore,path); |
224 | if (result == null) | 392 | if (result == null) |
225 | return false; | 393 | return false; |
226 | 394 | ||
227 | Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]"); | 395 | // Check pkey, the last element in the path, for and extract array references |
228 | MatchCollection amatches = aPattern.Matches(pkey,0); | 396 | MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); |
229 | |||
230 | if (amatches.Count > 0) | 397 | if (amatches.Count > 0) |
231 | { | 398 | { |
232 | if (result.Type != OSDType.Array) | 399 | if (result.Type != OSDType.Array) |
@@ -242,8 +409,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
242 | { | 409 | { |
243 | string npkey = String.Format("[{0}]",amap.Count); | 410 | string npkey = String.Format("[{0}]",amap.Count); |
244 | 411 | ||
245 | amap.Add(ovalue); | 412 | if (ovalue != null) |
246 | InvokeNextCallback(pexpr + npkey); | 413 | { |
414 | StringSpace += ComputeSizeOf(ovalue); | ||
415 | |||
416 | amap.Add(ovalue); | ||
417 | InvokeNextCallback(pexpr + npkey); | ||
418 | } | ||
247 | return true; | 419 | return true; |
248 | } | 420 | } |
249 | 421 | ||
@@ -251,9 +423,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
251 | if (0 <= aval && aval < amap.Count) | 423 | if (0 <= aval && aval < amap.Count) |
252 | { | 424 | { |
253 | if (ovalue == null) | 425 | if (ovalue == null) |
426 | { | ||
427 | StringSpace -= ComputeSizeOf(amap[aval]); | ||
254 | amap.RemoveAt(aval); | 428 | amap.RemoveAt(aval); |
429 | } | ||
255 | else | 430 | else |
256 | { | 431 | { |
432 | StringSpace -= ComputeSizeOf(amap[aval]); | ||
433 | StringSpace += ComputeSizeOf(ovalue); | ||
257 | amap[aval] = ovalue; | 434 | amap[aval] = ovalue; |
258 | InvokeNextCallback(pexpr + pkey); | 435 | InvokeNextCallback(pexpr + pkey); |
259 | } | 436 | } |
@@ -263,9 +440,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
263 | return false; | 440 | return false; |
264 | } | 441 | } |
265 | 442 | ||
266 | Regex hPattern = new Regex("{([^}]+)}"); | 443 | // Check for and extract hash references |
267 | MatchCollection hmatches = hPattern.Matches(pkey,0); | 444 | MatchCollection hmatches = m_HashPattern.Matches(pkey,0); |
268 | |||
269 | if (hmatches.Count > 0) | 445 | if (hmatches.Count > 0) |
270 | { | 446 | { |
271 | Match match = hmatches[0]; | 447 | Match match = hmatches[0]; |
@@ -274,16 +450,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
274 | 450 | ||
275 | if (result is OSDMap) | 451 | if (result is OSDMap) |
276 | { | 452 | { |
453 | // this is the assignment case | ||
277 | OSDMap hmap = result as OSDMap; | 454 | OSDMap hmap = result as OSDMap; |
278 | if (ovalue != null) | 455 | if (ovalue != null) |
279 | { | 456 | { |
457 | StringSpace -= ComputeSizeOf(hmap[hkey]); | ||
458 | StringSpace += ComputeSizeOf(ovalue); | ||
459 | |||
280 | hmap[hkey] = ovalue; | 460 | hmap[hkey] = ovalue; |
281 | InvokeNextCallback(pexpr + pkey); | 461 | InvokeNextCallback(pexpr + pkey); |
462 | return true; | ||
282 | } | 463 | } |
283 | else if (hmap.ContainsKey(hkey)) | 464 | |
465 | // this is the remove case | ||
466 | if (hmap.ContainsKey(hkey)) | ||
467 | { | ||
468 | StringSpace -= ComputeSizeOf(hmap[hkey]); | ||
284 | hmap.Remove(hkey); | 469 | hmap.Remove(hkey); |
285 | 470 | return true; | |
286 | return true; | 471 | } |
472 | |||
473 | return false; | ||
287 | } | 474 | } |
288 | 475 | ||
289 | return false; | 476 | return false; |
@@ -332,39 +519,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
332 | /// use a stack because we process the path in inverse order later | 519 | /// use a stack because we process the path in inverse order later |
333 | /// </summary> | 520 | /// </summary> |
334 | // ----------------------------------------------------------------- | 521 | // ----------------------------------------------------------------- |
335 | protected static Stack<string> ParsePathExpression(string path) | 522 | protected static bool ParsePathExpression(string expr, out Stack<string> path) |
336 | { | 523 | { |
337 | Stack<string> m_path = new Stack<string>(); | 524 | path = new Stack<string>(); |
338 | 525 | ||
339 | // add front and rear separators | 526 | // add front and rear separators |
340 | path = "." + path + "."; | 527 | expr = "." + expr + "."; |
341 | 528 | ||
342 | // add separators for quoted paths | 529 | // add separators for quoted exprs and array references |
343 | Regex pass1 = new Regex("{[^}]+}"); | 530 | expr = m_ParsePassOne.Replace(expr,".$1.",-1,0); |
344 | path = pass1.Replace(path,".$0.",-1,0); | ||
345 | |||
346 | // add separators for array references | ||
347 | Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])"); | ||
348 | path = pass2.Replace(path,".$0.",-1,0); | ||
349 | 531 | ||
350 | // add quotes to bare identifier | 532 | // add quotes to bare identifier |
351 | Regex pass3 = new Regex("\\.([a-zA-Z]+)"); | 533 | expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0); |
352 | path = pass3.Replace(path,".{$1}",-1,0); | ||
353 | 534 | ||
354 | // remove extra separators | 535 | // remove extra separators |
355 | Regex pass4 = new Regex("\\.+"); | 536 | expr = m_ParsePassFour.Replace(expr,".",-1,0); |
356 | path = pass4.Replace(path,".",-1,0); | ||
357 | 537 | ||
358 | Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); | 538 | // validate the results (catches extra quote characters for example) |
359 | if (validate.IsMatch(path)) | 539 | if (m_ValidatePath.IsMatch(expr)) |
360 | { | 540 | { |
361 | Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); | 541 | MatchCollection matches = m_PathComponent.Matches(expr,0); |
362 | MatchCollection matches = parser.Matches(path,0); | ||
363 | foreach (Match match in matches) | 542 | foreach (Match match in matches) |
364 | m_path.Push(match.Groups[1].Value); | 543 | path.Push(match.Groups[1].Value); |
544 | |||
545 | return true; | ||
365 | } | 546 | } |
366 | 547 | ||
367 | return m_path; | 548 | return false; |
368 | } | 549 | } |
369 | 550 | ||
370 | // ----------------------------------------------------------------- | 551 | // ----------------------------------------------------------------- |
@@ -385,9 +566,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
385 | return null; | 566 | return null; |
386 | 567 | ||
387 | // ---------- Check for an array index ---------- | 568 | // ---------- Check for an array index ---------- |
388 | Regex aPattern = new Regex("\\[([0-9]+)\\]"); | 569 | MatchCollection amatches = m_SimpleArrayPattern.Matches(pkey,0); |
389 | MatchCollection amatches = aPattern.Matches(pkey,0); | 570 | |
390 | |||
391 | if (amatches.Count > 0) | 571 | if (amatches.Count > 0) |
392 | { | 572 | { |
393 | if (rmap.Type != OSDType.Array) | 573 | if (rmap.Type != OSDType.Array) |
@@ -410,9 +590,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
410 | } | 590 | } |
411 | 591 | ||
412 | // ---------- Check for a hash index ---------- | 592 | // ---------- Check for a hash index ---------- |
413 | Regex hPattern = new Regex("{([^}]+)}"); | 593 | MatchCollection hmatches = m_HashPattern.Matches(pkey,0); |
414 | MatchCollection hmatches = hPattern.Matches(pkey,0); | 594 | |
415 | |||
416 | if (hmatches.Count > 0) | 595 | if (hmatches.Count > 0) |
417 | { | 596 | { |
418 | if (rmap.Type != OSDType.Map) | 597 | if (rmap.Type != OSDType.Map) |
@@ -456,14 +635,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
456 | // The path pointed to an intermediate hash structure | 635 | // The path pointed to an intermediate hash structure |
457 | if (result.Type == OSDType.Map) | 636 | if (result.Type == OSDType.Map) |
458 | { | 637 | { |
459 | value = OSDParser.SerializeJsonString(result as OSDMap); | 638 | value = OSDParser.SerializeJsonString(result as OSDMap,true); |
460 | return true; | 639 | return true; |
461 | } | 640 | } |
462 | 641 | ||
463 | // The path pointed to an intermediate hash structure | 642 | // The path pointed to an intermediate hash structure |
464 | if (result.Type == OSDType.Array) | 643 | if (result.Type == OSDType.Array) |
465 | { | 644 | { |
466 | value = OSDParser.SerializeJsonString(result as OSDArray); | 645 | value = OSDParser.SerializeJsonString(result as OSDArray,true); |
467 | return true; | 646 | return true; |
468 | } | 647 | } |
469 | 648 | ||
@@ -471,7 +650,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
471 | return true; | 650 | return true; |
472 | } | 651 | } |
473 | 652 | ||
474 | if (result.Type == OSDType.String) | 653 | if (OSDBaseType(result.Type)) |
475 | { | 654 | { |
476 | value = result.AsString(); | 655 | value = result.AsString(); |
477 | return true; | 656 | return true; |
@@ -496,5 +675,91 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
496 | 675 | ||
497 | return pkey; | 676 | return pkey; |
498 | } | 677 | } |
678 | |||
679 | // ----------------------------------------------------------------- | ||
680 | /// <summary> | ||
681 | /// | ||
682 | /// </summary> | ||
683 | // ----------------------------------------------------------------- | ||
684 | protected static bool OSDBaseType(OSDType type) | ||
685 | { | ||
686 | // Should be the list of base types for which AsString() returns | ||
687 | // something useful | ||
688 | if (type == OSDType.Boolean) | ||
689 | return true; | ||
690 | if (type == OSDType.Integer) | ||
691 | return true; | ||
692 | if (type == OSDType.Real) | ||
693 | return true; | ||
694 | if (type == OSDType.String) | ||
695 | return true; | ||
696 | if (type == OSDType.UUID) | ||
697 | return true; | ||
698 | if (type == OSDType.Date) | ||
699 | return true; | ||
700 | if (type == OSDType.URI) | ||
701 | return true; | ||
702 | |||
703 | return false; | ||
704 | } | ||
705 | |||
706 | // ----------------------------------------------------------------- | ||
707 | /// <summary> | ||
708 | /// | ||
709 | /// </summary> | ||
710 | // ----------------------------------------------------------------- | ||
711 | protected static int ComputeSizeOf(OSD value) | ||
712 | { | ||
713 | string sval; | ||
714 | |||
715 | if (ConvertOutputValue(value,out sval,true)) | ||
716 | return sval.Length; | ||
717 | |||
718 | return 0; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | // ----------------------------------------------------------------- | ||
723 | /// <summary> | ||
724 | /// </summary> | ||
725 | // ----------------------------------------------------------------- | ||
726 | public class JsonObjectStore : JsonStore | ||
727 | { | ||
728 | private static readonly ILog m_log = | ||
729 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
730 | |||
731 | private Scene m_scene; | ||
732 | private UUID m_objectID; | ||
733 | |||
734 | protected override OSD ValueStore | ||
735 | { | ||
736 | get | ||
737 | { | ||
738 | SceneObjectPart sop = m_scene.GetSceneObjectPart(m_objectID); | ||
739 | if (sop == null) | ||
740 | { | ||
741 | // This is bad | ||
742 | return null; | ||
743 | } | ||
744 | |||
745 | return sop.DynAttrs.TopLevelMap; | ||
746 | } | ||
747 | |||
748 | // cannot set the top level | ||
749 | set | ||
750 | { | ||
751 | m_log.InfoFormat("[JsonStore] cannot set top level value in object store"); | ||
752 | } | ||
753 | } | ||
754 | |||
755 | public JsonObjectStore(Scene scene, UUID oid) : base() | ||
756 | { | ||
757 | m_scene = scene; | ||
758 | m_objectID = oid; | ||
759 | |||
760 | // the size limit is imposed on whatever is already in the store | ||
761 | StringSpace = ComputeSizeOf(ValueStore); | ||
762 | } | ||
499 | } | 763 | } |
764 | |||
500 | } | 765 | } |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs new file mode 100644 index 0000000..d4b19dd --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors | ||
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 OpenSim 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 | using Mono.Addins; | ||
28 | |||
29 | using System; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using System.Text; | ||
33 | using System.Net; | ||
34 | using System.Net.Sockets; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using System.Collections.Generic; | ||
43 | using System.Text.RegularExpressions; | ||
44 | |||
45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | ||
46 | { | ||
47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreCommandsModule")] | ||
48 | |||
49 | public class JsonStoreCommandsModule : INonSharedRegionModule | ||
50 | { | ||
51 | private static readonly ILog m_log = | ||
52 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | private IConfig m_config = null; | ||
55 | private bool m_enabled = false; | ||
56 | |||
57 | private Scene m_scene = null; | ||
58 | //private IJsonStoreModule m_store; | ||
59 | private JsonStoreModule m_store; | ||
60 | |||
61 | #region Region Module interface | ||
62 | |||
63 | // ----------------------------------------------------------------- | ||
64 | /// <summary> | ||
65 | /// Name of this shared module is it's class name | ||
66 | /// </summary> | ||
67 | // ----------------------------------------------------------------- | ||
68 | public string Name | ||
69 | { | ||
70 | get { return this.GetType().Name; } | ||
71 | } | ||
72 | |||
73 | // ----------------------------------------------------------------- | ||
74 | /// <summary> | ||
75 | /// Initialise this shared module | ||
76 | /// </summary> | ||
77 | /// <param name="scene">this region is getting initialised</param> | ||
78 | /// <param name="source">nini config, we are not using this</param> | ||
79 | // ----------------------------------------------------------------- | ||
80 | public void Initialise(IConfigSource config) | ||
81 | { | ||
82 | try | ||
83 | { | ||
84 | if ((m_config = config.Configs["JsonStore"]) == null) | ||
85 | { | ||
86 | // There is no configuration, the module is disabled | ||
87 | // m_log.InfoFormat("[JsonStore] no configuration info"); | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); | ||
92 | } | ||
93 | catch (Exception e) | ||
94 | { | ||
95 | m_log.Error("[JsonStore]: initialization error: {0}", e); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | if (m_enabled) | ||
100 | m_log.DebugFormat("[JsonStore]: module is enabled"); | ||
101 | } | ||
102 | |||
103 | // ----------------------------------------------------------------- | ||
104 | /// <summary> | ||
105 | /// everything is loaded, perform post load configuration | ||
106 | /// </summary> | ||
107 | // ----------------------------------------------------------------- | ||
108 | public void PostInitialise() | ||
109 | { | ||
110 | } | ||
111 | |||
112 | // ----------------------------------------------------------------- | ||
113 | /// <summary> | ||
114 | /// Nothing to do on close | ||
115 | /// </summary> | ||
116 | // ----------------------------------------------------------------- | ||
117 | public void Close() | ||
118 | { | ||
119 | } | ||
120 | |||
121 | // ----------------------------------------------------------------- | ||
122 | /// <summary> | ||
123 | /// </summary> | ||
124 | // ----------------------------------------------------------------- | ||
125 | public void AddRegion(Scene scene) | ||
126 | { | ||
127 | if (m_enabled) | ||
128 | { | ||
129 | m_scene = scene; | ||
130 | |||
131 | } | ||
132 | } | ||
133 | |||
134 | // ----------------------------------------------------------------- | ||
135 | /// <summary> | ||
136 | /// </summary> | ||
137 | // ----------------------------------------------------------------- | ||
138 | public void RemoveRegion(Scene scene) | ||
139 | { | ||
140 | // need to remove all references to the scene in the subscription | ||
141 | // list to enable full garbage collection of the scene object | ||
142 | } | ||
143 | |||
144 | // ----------------------------------------------------------------- | ||
145 | /// <summary> | ||
146 | /// Called when all modules have been added for a region. This is | ||
147 | /// where we hook up events | ||
148 | /// </summary> | ||
149 | // ----------------------------------------------------------------- | ||
150 | public void RegionLoaded(Scene scene) | ||
151 | { | ||
152 | if (m_enabled) | ||
153 | { | ||
154 | m_scene = scene; | ||
155 | |||
156 | m_store = (JsonStoreModule) m_scene.RequestModuleInterface<IJsonStoreModule>(); | ||
157 | if (m_store == null) | ||
158 | { | ||
159 | m_log.ErrorFormat("[JsonStoreCommands]: JsonModule interface not defined"); | ||
160 | m_enabled = false; | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | scene.AddCommand("JsonStore", this, "jsonstore stats", "jsonstore stats", | ||
165 | "Display statistics about the state of the JsonStore module", "", | ||
166 | CmdStats); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /// ----------------------------------------------------------------- | ||
171 | /// <summary> | ||
172 | /// </summary> | ||
173 | // ----------------------------------------------------------------- | ||
174 | public Type ReplaceableInterface | ||
175 | { | ||
176 | get { return null; } | ||
177 | } | ||
178 | |||
179 | #endregion | ||
180 | |||
181 | #region Commands | ||
182 | |||
183 | private void CmdStats(string module, string[] cmd) | ||
184 | { | ||
185 | if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) | ||
186 | return; | ||
187 | |||
188 | JsonStoreStats stats = m_store.GetStoreStats(); | ||
189 | MainConsole.Instance.OutputFormat("{0}\t{1}",m_scene.RegionInfo.RegionName,stats.StoreCount); | ||
190 | } | ||
191 | |||
192 | #endregion | ||
193 | |||
194 | } | ||
195 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index e68764a..26044f0 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | |||
@@ -42,7 +42,6 @@ using OpenSim.Region.Framework.Scenes; | |||
42 | using System.Collections.Generic; | 42 | using System.Collections.Generic; |
43 | using System.Text.RegularExpressions; | 43 | using System.Text.RegularExpressions; |
44 | 44 | ||
45 | |||
46 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | 45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore |
47 | { | 46 | { |
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")] | 47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")] |
@@ -54,9 +53,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
54 | 53 | ||
55 | private IConfig m_config = null; | 54 | private IConfig m_config = null; |
56 | private bool m_enabled = false; | 55 | private bool m_enabled = false; |
56 | private bool m_enableObjectStore = false; | ||
57 | private int m_maxStringSpace = Int32.MaxValue; | ||
58 | |||
57 | private Scene m_scene = null; | 59 | private Scene m_scene = null; |
58 | 60 | ||
59 | private Dictionary<UUID,JsonStore> m_JsonValueStore; | 61 | private Dictionary<UUID,JsonStore> m_JsonValueStore; |
62 | |||
60 | private UUID m_sharedStore; | 63 | private UUID m_sharedStore; |
61 | 64 | ||
62 | #region Region Module interface | 65 | #region Region Module interface |
@@ -90,15 +93,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
90 | } | 93 | } |
91 | 94 | ||
92 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); | 95 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); |
96 | m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore); | ||
97 | m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace); | ||
98 | if (m_maxStringSpace == 0) | ||
99 | m_maxStringSpace = Int32.MaxValue; | ||
93 | } | 100 | } |
94 | catch (Exception e) | 101 | catch (Exception e) |
95 | { | 102 | { |
96 | m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message); | 103 | m_log.Error("[JsonStore]: initialization error: {0}", e); |
97 | return; | 104 | return; |
98 | } | 105 | } |
99 | 106 | ||
100 | if (m_enabled) | 107 | if (m_enabled) |
101 | m_log.DebugFormat("[JsonStore] module is enabled"); | 108 | m_log.DebugFormat("[JsonStore]: module is enabled"); |
102 | } | 109 | } |
103 | 110 | ||
104 | // ----------------------------------------------------------------- | 111 | // ----------------------------------------------------------------- |
@@ -133,6 +140,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
133 | m_sharedStore = UUID.Zero; | 140 | m_sharedStore = UUID.Zero; |
134 | m_JsonValueStore = new Dictionary<UUID,JsonStore>(); | 141 | m_JsonValueStore = new Dictionary<UUID,JsonStore>(); |
135 | m_JsonValueStore.Add(m_sharedStore,new JsonStore("")); | 142 | m_JsonValueStore.Add(m_sharedStore,new JsonStore("")); |
143 | |||
144 | scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene; | ||
136 | } | 145 | } |
137 | } | 146 | } |
138 | 147 | ||
@@ -142,6 +151,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
142 | // ----------------------------------------------------------------- | 151 | // ----------------------------------------------------------------- |
143 | public void RemoveRegion(Scene scene) | 152 | public void RemoveRegion(Scene scene) |
144 | { | 153 | { |
154 | scene.EventManager.OnObjectBeingRemovedFromScene -= EventManagerOnObjectBeingRemovedFromScene; | ||
155 | |||
145 | // need to remove all references to the scene in the subscription | 156 | // need to remove all references to the scene in the subscription |
146 | // list to enable full garbage collection of the scene object | 157 | // list to enable full garbage collection of the scene object |
147 | } | 158 | } |
@@ -154,7 +165,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
154 | // ----------------------------------------------------------------- | 165 | // ----------------------------------------------------------------- |
155 | public void RegionLoaded(Scene scene) | 166 | public void RegionLoaded(Scene scene) |
156 | { | 167 | { |
157 | if (m_enabled) {} | 168 | if (m_enabled) |
169 | { | ||
170 | } | ||
158 | } | 171 | } |
159 | 172 | ||
160 | /// ----------------------------------------------------------------- | 173 | /// ----------------------------------------------------------------- |
@@ -168,8 +181,68 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
168 | 181 | ||
169 | #endregion | 182 | #endregion |
170 | 183 | ||
184 | #region SceneEvents | ||
185 | // ----------------------------------------------------------------- | ||
186 | /// <summary> | ||
187 | /// | ||
188 | /// </summary> | ||
189 | // ----------------------------------------------------------------- | ||
190 | public void EventManagerOnObjectBeingRemovedFromScene(SceneObjectGroup obj) | ||
191 | { | ||
192 | obj.ForEachPart(delegate(SceneObjectPart sop) { DestroyStore(sop.UUID); } ); | ||
193 | } | ||
194 | |||
195 | #endregion | ||
196 | |||
171 | #region ScriptInvocationInteface | 197 | #region ScriptInvocationInteface |
172 | 198 | ||
199 | |||
200 | // ----------------------------------------------------------------- | ||
201 | /// <summary> | ||
202 | /// | ||
203 | /// </summary> | ||
204 | // ----------------------------------------------------------------- | ||
205 | public JsonStoreStats GetStoreStats() | ||
206 | { | ||
207 | JsonStoreStats stats; | ||
208 | |||
209 | lock (m_JsonValueStore) | ||
210 | { | ||
211 | stats.StoreCount = m_JsonValueStore.Count; | ||
212 | } | ||
213 | |||
214 | return stats; | ||
215 | } | ||
216 | |||
217 | // ----------------------------------------------------------------- | ||
218 | /// <summary> | ||
219 | /// | ||
220 | /// </summary> | ||
221 | // ----------------------------------------------------------------- | ||
222 | public bool AttachObjectStore(UUID objectID) | ||
223 | { | ||
224 | if (! m_enabled) return false; | ||
225 | if (! m_enableObjectStore) return false; | ||
226 | |||
227 | SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); | ||
228 | if (sop == null) | ||
229 | { | ||
230 | m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID); | ||
231 | return false; | ||
232 | } | ||
233 | |||
234 | lock (m_JsonValueStore) | ||
235 | { | ||
236 | if (m_JsonValueStore.ContainsKey(objectID)) | ||
237 | return true; | ||
238 | |||
239 | JsonStore map = new JsonObjectStore(m_scene,objectID); | ||
240 | m_JsonValueStore.Add(objectID,map); | ||
241 | } | ||
242 | |||
243 | return true; | ||
244 | } | ||
245 | |||
173 | // ----------------------------------------------------------------- | 246 | // ----------------------------------------------------------------- |
174 | /// <summary> | 247 | /// <summary> |
175 | /// | 248 | /// |
@@ -189,9 +262,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
189 | { | 262 | { |
190 | map = new JsonStore(value); | 263 | map = new JsonStore(value); |
191 | } | 264 | } |
192 | catch (Exception e) | 265 | catch (Exception) |
193 | { | 266 | { |
194 | m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message); | 267 | m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value); |
195 | return false; | 268 | return false; |
196 | } | 269 | } |
197 | 270 | ||
@@ -211,9 +284,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
211 | if (! m_enabled) return false; | 284 | if (! m_enabled) return false; |
212 | 285 | ||
213 | lock (m_JsonValueStore) | 286 | lock (m_JsonValueStore) |
214 | m_JsonValueStore.Remove(storeID); | 287 | return m_JsonValueStore.Remove(storeID); |
215 | |||
216 | return true; | ||
217 | } | 288 | } |
218 | 289 | ||
219 | // ----------------------------------------------------------------- | 290 | // ----------------------------------------------------------------- |
@@ -221,31 +292,76 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
221 | /// | 292 | /// |
222 | /// </summary> | 293 | /// </summary> |
223 | // ----------------------------------------------------------------- | 294 | // ----------------------------------------------------------------- |
224 | public bool TestPath(UUID storeID, string path, bool useJson) | 295 | public bool TestStore(UUID storeID) |
225 | { | 296 | { |
226 | if (! m_enabled) return false; | 297 | if (! m_enabled) return false; |
227 | 298 | ||
299 | lock (m_JsonValueStore) | ||
300 | return m_JsonValueStore.ContainsKey(storeID); | ||
301 | } | ||
302 | |||
303 | // ----------------------------------------------------------------- | ||
304 | /// <summary> | ||
305 | /// | ||
306 | /// </summary> | ||
307 | // ----------------------------------------------------------------- | ||
308 | public JsonStoreNodeType GetNodeType(UUID storeID, string path) | ||
309 | { | ||
310 | if (! m_enabled) return JsonStoreNodeType.Undefined; | ||
311 | |||
228 | JsonStore map = null; | 312 | JsonStore map = null; |
229 | lock (m_JsonValueStore) | 313 | lock (m_JsonValueStore) |
230 | { | 314 | { |
231 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | 315 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) |
232 | { | 316 | { |
233 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); | 317 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); |
234 | return false; | 318 | return JsonStoreNodeType.Undefined; |
235 | } | 319 | } |
236 | } | 320 | } |
237 | 321 | ||
238 | try | 322 | try |
239 | { | 323 | { |
240 | lock (map) | 324 | lock (map) |
241 | return map.TestPath(path,useJson); | 325 | return map.GetNodeType(path); |
242 | } | 326 | } |
243 | catch (Exception e) | 327 | catch (Exception e) |
244 | { | 328 | { |
245 | m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); | 329 | m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); |
246 | } | 330 | } |
247 | 331 | ||
248 | return false; | 332 | return JsonStoreNodeType.Undefined; |
333 | } | ||
334 | |||
335 | // ----------------------------------------------------------------- | ||
336 | /// <summary> | ||
337 | /// | ||
338 | /// </summary> | ||
339 | // ----------------------------------------------------------------- | ||
340 | public JsonStoreValueType GetValueType(UUID storeID, string path) | ||
341 | { | ||
342 | if (! m_enabled) return JsonStoreValueType.Undefined; | ||
343 | |||
344 | JsonStore map = null; | ||
345 | lock (m_JsonValueStore) | ||
346 | { | ||
347 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
348 | { | ||
349 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); | ||
350 | return JsonStoreValueType.Undefined; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | try | ||
355 | { | ||
356 | lock (map) | ||
357 | return map.GetValueType(path); | ||
358 | } | ||
359 | catch (Exception e) | ||
360 | { | ||
361 | m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); | ||
362 | } | ||
363 | |||
364 | return JsonStoreValueType.Undefined; | ||
249 | } | 365 | } |
250 | 366 | ||
251 | // ----------------------------------------------------------------- | 367 | // ----------------------------------------------------------------- |
@@ -270,12 +386,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
270 | try | 386 | try |
271 | { | 387 | { |
272 | lock (map) | 388 | lock (map) |
273 | if (map.SetValue(path,value,useJson)) | 389 | { |
274 | return true; | 390 | if (map.StringSpace > m_maxStringSpace) |
391 | { | ||
392 | m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit", | ||
393 | storeID,map.StringSpace,m_maxStringSpace); | ||
394 | return false; | ||
395 | } | ||
396 | |||
397 | return map.SetValue(path,value,useJson); | ||
398 | } | ||
275 | } | 399 | } |
276 | catch (Exception e) | 400 | catch (Exception e) |
277 | { | 401 | { |
278 | m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message); | 402 | m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e); |
279 | } | 403 | } |
280 | 404 | ||
281 | return false; | 405 | return false; |
@@ -303,12 +427,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
303 | try | 427 | try |
304 | { | 428 | { |
305 | lock (map) | 429 | lock (map) |
306 | if (map.RemoveValue(path)) | 430 | return map.RemoveValue(path); |
307 | return true; | ||
308 | } | 431 | } |
309 | catch (Exception e) | 432 | catch (Exception e) |
310 | { | 433 | { |
311 | m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message); | 434 | m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e); |
312 | } | 435 | } |
313 | 436 | ||
314 | return false; | 437 | return false; |
@@ -319,6 +442,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
319 | /// | 442 | /// |
320 | /// </summary> | 443 | /// </summary> |
321 | // ----------------------------------------------------------------- | 444 | // ----------------------------------------------------------------- |
445 | public int GetArrayLength(UUID storeID, string path) | ||
446 | { | ||
447 | if (! m_enabled) return -1; | ||
448 | |||
449 | JsonStore map = null; | ||
450 | lock (m_JsonValueStore) | ||
451 | { | ||
452 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
453 | return -1; | ||
454 | } | ||
455 | |||
456 | try | ||
457 | { | ||
458 | lock (map) | ||
459 | { | ||
460 | return map.ArrayLength(path); | ||
461 | } | ||
462 | } | ||
463 | catch (Exception e) | ||
464 | { | ||
465 | m_log.Error("[JsonStore]: unable to retrieve value", e); | ||
466 | } | ||
467 | |||
468 | return -1; | ||
469 | } | ||
470 | |||
471 | // ----------------------------------------------------------------- | ||
472 | /// <summary> | ||
473 | /// | ||
474 | /// </summary> | ||
475 | // ----------------------------------------------------------------- | ||
322 | public bool GetValue(UUID storeID, string path, bool useJson, out string value) | 476 | public bool GetValue(UUID storeID, string path, bool useJson, out string value) |
323 | { | 477 | { |
324 | value = String.Empty; | 478 | value = String.Empty; |
@@ -341,7 +495,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
341 | } | 495 | } |
342 | catch (Exception e) | 496 | catch (Exception e) |
343 | { | 497 | { |
344 | m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message); | 498 | m_log.Error("[JsonStore]: unable to retrieve value", e); |
345 | } | 499 | } |
346 | 500 | ||
347 | return false; | 501 | return false; |
@@ -380,7 +534,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
380 | } | 534 | } |
381 | catch (Exception e) | 535 | catch (Exception e) |
382 | { | 536 | { |
383 | m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); | 537 | m_log.Error("[JsonStore] unable to retrieve value", e); |
384 | } | 538 | } |
385 | 539 | ||
386 | cback(String.Empty); | 540 | cback(String.Empty); |
@@ -419,7 +573,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
419 | } | 573 | } |
420 | catch (Exception e) | 574 | catch (Exception e) |
421 | { | 575 | { |
422 | m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); | 576 | m_log.Error("[JsonStore]: unable to retrieve value", e); |
423 | } | 577 | } |
424 | 578 | ||
425 | cback(String.Empty); | 579 | cback(String.Empty); |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 0c175ca..edf51a2 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | |||
@@ -39,8 +39,10 @@ using OpenMetaverse.StructuredData; | |||
39 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Region.Framework.Interfaces; | 40 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.Framework.Scenes.Scripting; | ||
42 | using System.Collections.Generic; | 43 | using System.Collections.Generic; |
43 | using System.Text.RegularExpressions; | 44 | using System.Text.RegularExpressions; |
45 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
44 | 46 | ||
45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | 47 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore |
46 | { | 48 | { |
@@ -57,7 +59,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
57 | 59 | ||
58 | private IScriptModuleComms m_comms; | 60 | private IScriptModuleComms m_comms; |
59 | private IJsonStoreModule m_store; | 61 | private IJsonStoreModule m_store; |
60 | 62 | ||
63 | private Dictionary<UUID,HashSet<UUID>> m_scriptStores = new Dictionary<UUID,HashSet<UUID>>(); | ||
64 | |||
61 | #region Region Module interface | 65 | #region Region Module interface |
62 | 66 | ||
63 | // ----------------------------------------------------------------- | 67 | // ----------------------------------------------------------------- |
@@ -92,12 +96,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
92 | } | 96 | } |
93 | catch (Exception e) | 97 | catch (Exception e) |
94 | { | 98 | { |
95 | m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); | 99 | m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message); |
96 | return; | 100 | return; |
97 | } | 101 | } |
98 | 102 | ||
99 | if (m_enabled) | 103 | if (m_enabled) |
100 | m_log.DebugFormat("[JsonStoreScripts] module is enabled"); | 104 | m_log.DebugFormat("[JsonStoreScripts]: module is enabled"); |
101 | } | 105 | } |
102 | 106 | ||
103 | // ----------------------------------------------------------------- | 107 | // ----------------------------------------------------------------- |
@@ -124,6 +128,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
124 | // ----------------------------------------------------------------- | 128 | // ----------------------------------------------------------------- |
125 | public void AddRegion(Scene scene) | 129 | public void AddRegion(Scene scene) |
126 | { | 130 | { |
131 | scene.EventManager.OnScriptReset += HandleScriptReset; | ||
132 | scene.EventManager.OnRemoveScript += HandleScriptReset; | ||
127 | } | 133 | } |
128 | 134 | ||
129 | // ----------------------------------------------------------------- | 135 | // ----------------------------------------------------------------- |
@@ -132,12 +138,34 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
132 | // ----------------------------------------------------------------- | 138 | // ----------------------------------------------------------------- |
133 | public void RemoveRegion(Scene scene) | 139 | public void RemoveRegion(Scene scene) |
134 | { | 140 | { |
141 | scene.EventManager.OnScriptReset -= HandleScriptReset; | ||
142 | scene.EventManager.OnRemoveScript -= HandleScriptReset; | ||
143 | |||
135 | // need to remove all references to the scene in the subscription | 144 | // need to remove all references to the scene in the subscription |
136 | // list to enable full garbage collection of the scene object | 145 | // list to enable full garbage collection of the scene object |
137 | } | 146 | } |
138 | 147 | ||
139 | // ----------------------------------------------------------------- | 148 | // ----------------------------------------------------------------- |
140 | /// <summary> | 149 | /// <summary> |
150 | /// </summary> | ||
151 | // ----------------------------------------------------------------- | ||
152 | private void HandleScriptReset(uint localID, UUID itemID) | ||
153 | { | ||
154 | HashSet<UUID> stores; | ||
155 | |||
156 | lock (m_scriptStores) | ||
157 | { | ||
158 | if (! m_scriptStores.TryGetValue(itemID, out stores)) | ||
159 | return; | ||
160 | m_scriptStores.Remove(itemID); | ||
161 | } | ||
162 | |||
163 | foreach (UUID id in stores) | ||
164 | m_store.DestroyStore(id); | ||
165 | } | ||
166 | |||
167 | // ----------------------------------------------------------------- | ||
168 | /// <summary> | ||
141 | /// Called when all modules have been added for a region. This is | 169 | /// Called when all modules have been added for a region. This is |
142 | /// where we hook up events | 170 | /// where we hook up events |
143 | /// </summary> | 171 | /// </summary> |
@@ -150,7 +178,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
150 | m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>(); | 178 | m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>(); |
151 | if (m_comms == null) | 179 | if (m_comms == null) |
152 | { | 180 | { |
153 | m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); | 181 | m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined"); |
154 | m_enabled = false; | 182 | m_enabled = false; |
155 | return; | 183 | return; |
156 | } | 184 | } |
@@ -158,40 +186,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
158 | m_store = m_scene.RequestModuleInterface<IJsonStoreModule>(); | 186 | m_store = m_scene.RequestModuleInterface<IJsonStoreModule>(); |
159 | if (m_store == null) | 187 | if (m_store == null) |
160 | { | 188 | { |
161 | m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); | 189 | m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined"); |
162 | m_enabled = false; | 190 | m_enabled = false; |
163 | return; | 191 | return; |
164 | } | 192 | } |
165 | 193 | ||
166 | try | 194 | try |
167 | { | 195 | { |
168 | m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); | 196 | m_comms.RegisterScriptInvocations(this); |
169 | m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); | 197 | m_comms.RegisterConstants(this); |
170 | |||
171 | m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); | ||
172 | m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); | ||
173 | |||
174 | m_comms.RegisterScriptInvocation(this,"JsonTestPath"); | ||
175 | m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); | ||
176 | |||
177 | m_comms.RegisterScriptInvocation(this,"JsonGetValue"); | ||
178 | m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); | ||
179 | |||
180 | m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); | ||
181 | m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); | ||
182 | |||
183 | m_comms.RegisterScriptInvocation(this,"JsonReadValue"); | ||
184 | m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); | ||
185 | |||
186 | m_comms.RegisterScriptInvocation(this,"JsonSetValue"); | ||
187 | m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); | ||
188 | |||
189 | m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); | ||
190 | } | 198 | } |
191 | catch (Exception e) | 199 | catch (Exception e) |
192 | { | 200 | { |
193 | // See http://opensimulator.org/mantis/view.php?id=5971 for more information | 201 | // See http://opensimulator.org/mantis/view.php?id=5971 for more information |
194 | m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); | 202 | m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message); |
195 | m_enabled = false; | 203 | m_enabled = false; |
196 | } | 204 | } |
197 | } | 205 | } |
@@ -208,28 +216,73 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
208 | 216 | ||
209 | #endregion | 217 | #endregion |
210 | 218 | ||
219 | #region ScriptConstantsInterface | ||
220 | |||
221 | [ScriptConstant] | ||
222 | public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined; | ||
223 | |||
224 | [ScriptConstant] | ||
225 | public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object; | ||
226 | |||
227 | [ScriptConstant] | ||
228 | public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array; | ||
229 | |||
230 | [ScriptConstant] | ||
231 | public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value; | ||
232 | |||
233 | [ScriptConstant] | ||
234 | public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined; | ||
235 | |||
236 | [ScriptConstant] | ||
237 | public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean; | ||
238 | |||
239 | [ScriptConstant] | ||
240 | public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer; | ||
241 | |||
242 | [ScriptConstant] | ||
243 | public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float; | ||
244 | |||
245 | [ScriptConstant] | ||
246 | public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String; | ||
247 | |||
248 | |||
249 | #endregion | ||
250 | |||
211 | #region ScriptInvocationInteface | 251 | #region ScriptInvocationInteface |
212 | // ----------------------------------------------------------------- | 252 | // ----------------------------------------------------------------- |
213 | /// <summary> | 253 | /// <summary> |
214 | /// | 254 | /// |
215 | /// </summary> | 255 | /// </summary> |
216 | // ----------------------------------------------------------------- | 256 | // ----------------------------------------------------------------- |
217 | protected void GenerateRuntimeError(string msg) | 257 | [ScriptInvocation] |
258 | public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID) | ||
218 | { | 259 | { |
219 | throw new Exception("JsonStore Runtime Error: " + msg); | 260 | UUID uuid = UUID.Zero; |
261 | if (! m_store.AttachObjectStore(hostID)) | ||
262 | GenerateRuntimeError("Failed to create Json store"); | ||
263 | |||
264 | return hostID; | ||
220 | } | 265 | } |
221 | 266 | ||
222 | // ----------------------------------------------------------------- | 267 | // ----------------------------------------------------------------- |
223 | /// <summary> | 268 | /// <summary> |
224 | /// | 269 | /// |
225 | /// </summary> | 270 | /// </summary> |
226 | // ----------------------------------------------------------------- | 271 | // ----------------------------------------------------------------- |
227 | protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) | 272 | [ScriptInvocation] |
273 | public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) | ||
228 | { | 274 | { |
229 | UUID uuid = UUID.Zero; | 275 | UUID uuid = UUID.Zero; |
230 | if (! m_store.CreateStore(value, ref uuid)) | 276 | if (! m_store.CreateStore(value, ref uuid)) |
231 | GenerateRuntimeError("Failed to create Json store"); | 277 | GenerateRuntimeError("Failed to create Json store"); |
232 | 278 | ||
279 | lock (m_scriptStores) | ||
280 | { | ||
281 | if (! m_scriptStores.ContainsKey(scriptID)) | ||
282 | m_scriptStores[scriptID] = new HashSet<UUID>(); | ||
283 | |||
284 | m_scriptStores[scriptID].Add(uuid); | ||
285 | } | ||
233 | return uuid; | 286 | return uuid; |
234 | } | 287 | } |
235 | 288 | ||
@@ -238,8 +291,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
238 | /// | 291 | /// |
239 | /// </summary> | 292 | /// </summary> |
240 | // ----------------------------------------------------------------- | 293 | // ----------------------------------------------------------------- |
241 | protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) | 294 | [ScriptInvocation] |
295 | public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) | ||
242 | { | 296 | { |
297 | lock(m_scriptStores) | ||
298 | { | ||
299 | if (m_scriptStores.ContainsKey(scriptID)) | ||
300 | m_scriptStores[scriptID].Remove(storeID); | ||
301 | } | ||
302 | |||
243 | return m_store.DestroyStore(storeID) ? 1 : 0; | 303 | return m_store.DestroyStore(storeID) ? 1 : 0; |
244 | } | 304 | } |
245 | 305 | ||
@@ -248,10 +308,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
248 | /// | 308 | /// |
249 | /// </summary> | 309 | /// </summary> |
250 | // ----------------------------------------------------------------- | 310 | // ----------------------------------------------------------------- |
251 | protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) | 311 | [ScriptInvocation] |
312 | public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID) | ||
313 | { | ||
314 | return m_store.TestStore(storeID) ? 1 : 0; | ||
315 | } | ||
316 | |||
317 | // ----------------------------------------------------------------- | ||
318 | /// <summary> | ||
319 | /// | ||
320 | /// </summary> | ||
321 | // ----------------------------------------------------------------- | ||
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] | ||
337 | public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) | ||
252 | { | 338 | { |
253 | UUID reqID = UUID.Random(); | 339 | UUID reqID = UUID.Random(); |
254 | Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); | 340 | Util.FireAndForget( |
341 | o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier), null, "JsonStoreScriptModule.JsonReadNotecard"); | ||
255 | return reqID; | 342 | return reqID; |
256 | } | 343 | } |
257 | 344 | ||
@@ -260,10 +347,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
260 | /// | 347 | /// |
261 | /// </summary> | 348 | /// </summary> |
262 | // ----------------------------------------------------------------- | 349 | // ----------------------------------------------------------------- |
263 | protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) | 350 | [ScriptInvocation] |
351 | public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) | ||
264 | { | 352 | { |
265 | UUID reqID = UUID.Random(); | 353 | UUID reqID = UUID.Random(); |
266 | 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"); | ||
267 | return reqID; | 356 | return reqID; |
268 | } | 357 | } |
269 | 358 | ||
@@ -272,14 +361,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
272 | /// | 361 | /// |
273 | /// </summary> | 362 | /// </summary> |
274 | // ----------------------------------------------------------------- | 363 | // ----------------------------------------------------------------- |
275 | protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) | 364 | [ScriptInvocation] |
365 | public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) | ||
366 | { | ||
367 | string ipath = ConvertList2Path(pathlist); | ||
368 | string opath; | ||
369 | |||
370 | if (JsonStore.CanonicalPathExpression(ipath,out opath)) | ||
371 | return opath; | ||
372 | |||
373 | // This won't parse if passed to the other routines as opposed to | ||
374 | // returning an empty string which is a valid path and would overwrite | ||
375 | // the entire store | ||
376 | return "**INVALID**"; | ||
377 | } | ||
378 | |||
379 | // ----------------------------------------------------------------- | ||
380 | /// <summary> | ||
381 | /// | ||
382 | /// </summary> | ||
383 | // ----------------------------------------------------------------- | ||
384 | [ScriptInvocation] | ||
385 | public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
276 | { | 386 | { |
277 | return m_store.TestPath(storeID,path,false) ? 1 : 0; | 387 | return (int)m_store.GetNodeType(storeID,path); |
278 | } | 388 | } |
279 | 389 | ||
280 | protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) | 390 | // ----------------------------------------------------------------- |
391 | /// <summary> | ||
392 | /// | ||
393 | /// </summary> | ||
394 | // ----------------------------------------------------------------- | ||
395 | [ScriptInvocation] | ||
396 | public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
281 | { | 397 | { |
282 | return m_store.TestPath(storeID,path,true) ? 1 : 0; | 398 | return (int)m_store.GetValueType(storeID,path); |
283 | } | 399 | } |
284 | 400 | ||
285 | // ----------------------------------------------------------------- | 401 | // ----------------------------------------------------------------- |
@@ -287,12 +403,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
287 | /// | 403 | /// |
288 | /// </summary> | 404 | /// </summary> |
289 | // ----------------------------------------------------------------- | 405 | // ----------------------------------------------------------------- |
290 | protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) | 406 | [ScriptInvocation] |
407 | public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) | ||
291 | { | 408 | { |
292 | return m_store.SetValue(storeID,path,value,false) ? 1 : 0; | 409 | return m_store.SetValue(storeID,path,value,false) ? 1 : 0; |
293 | } | 410 | } |
294 | 411 | ||
295 | protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) | 412 | [ScriptInvocation] |
413 | public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) | ||
296 | { | 414 | { |
297 | return m_store.SetValue(storeID,path,value,true) ? 1 : 0; | 415 | return m_store.SetValue(storeID,path,value,true) ? 1 : 0; |
298 | } | 416 | } |
@@ -302,7 +420,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
302 | /// | 420 | /// |
303 | /// </summary> | 421 | /// </summary> |
304 | // ----------------------------------------------------------------- | 422 | // ----------------------------------------------------------------- |
305 | protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) | 423 | [ScriptInvocation] |
424 | public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
306 | { | 425 | { |
307 | return m_store.RemoveValue(storeID,path) ? 1 : 0; | 426 | return m_store.RemoveValue(storeID,path) ? 1 : 0; |
308 | } | 427 | } |
@@ -312,14 +431,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
312 | /// | 431 | /// |
313 | /// </summary> | 432 | /// </summary> |
314 | // ----------------------------------------------------------------- | 433 | // ----------------------------------------------------------------- |
315 | protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) | 434 | [ScriptInvocation] |
435 | public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
436 | { | ||
437 | return m_store.GetArrayLength(storeID,path); | ||
438 | } | ||
439 | |||
440 | // ----------------------------------------------------------------- | ||
441 | /// <summary> | ||
442 | /// | ||
443 | /// </summary> | ||
444 | // ----------------------------------------------------------------- | ||
445 | [ScriptInvocation] | ||
446 | public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
316 | { | 447 | { |
317 | string value = String.Empty; | 448 | string value = String.Empty; |
318 | m_store.GetValue(storeID,path,false,out value); | 449 | m_store.GetValue(storeID,path,false,out value); |
319 | return value; | 450 | return value; |
320 | } | 451 | } |
321 | 452 | ||
322 | protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | 453 | [ScriptInvocation] |
454 | public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
323 | { | 455 | { |
324 | string value = String.Empty; | 456 | string value = String.Empty; |
325 | m_store.GetValue(storeID,path,true, out value); | 457 | m_store.GetValue(storeID,path,true, out value); |
@@ -331,80 +463,109 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
331 | /// | 463 | /// |
332 | /// </summary> | 464 | /// </summary> |
333 | // ----------------------------------------------------------------- | 465 | // ----------------------------------------------------------------- |
334 | protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) | 466 | [ScriptInvocation] |
467 | public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
335 | { | 468 | { |
336 | UUID reqID = UUID.Random(); | 469 | UUID reqID = UUID.Random(); |
337 | 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"); | ||
338 | return reqID; | 472 | return reqID; |
339 | } | 473 | } |
340 | 474 | ||
341 | protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | 475 | [ScriptInvocation] |
476 | public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
342 | { | 477 | { |
343 | UUID reqID = UUID.Random(); | 478 | UUID reqID = UUID.Random(); |
344 | 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"); | ||
345 | return reqID; | 481 | return reqID; |
346 | } | 482 | } |
347 | 483 | ||
348 | private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) | ||
349 | { | ||
350 | try | ||
351 | { | ||
352 | m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); | ||
353 | return; | ||
354 | } | ||
355 | catch (Exception e) | ||
356 | { | ||
357 | m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); | ||
358 | } | ||
359 | |||
360 | DispatchValue(scriptID,reqID,String.Empty); | ||
361 | } | ||
362 | |||
363 | |||
364 | // ----------------------------------------------------------------- | 484 | // ----------------------------------------------------------------- |
365 | /// <summary> | 485 | /// <summary> |
366 | /// | 486 | /// |
367 | /// </summary> | 487 | /// </summary> |
368 | // ----------------------------------------------------------------- | 488 | // ----------------------------------------------------------------- |
369 | protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) | 489 | [ScriptInvocation] |
490 | public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
370 | { | 491 | { |
371 | UUID reqID = UUID.Random(); | 492 | UUID reqID = UUID.Random(); |
372 | 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"); | ||
373 | return reqID; | 495 | return reqID; |
374 | } | 496 | } |
375 | 497 | ||
376 | protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | 498 | [ScriptInvocation] |
499 | public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
377 | { | 500 | { |
378 | UUID reqID = UUID.Random(); | 501 | UUID reqID = UUID.Random(); |
379 | 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"); | ||
380 | return reqID; | 504 | return reqID; |
381 | } | 505 | } |
382 | 506 | ||
383 | private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) | 507 | #endregion |
508 | |||
509 | // ----------------------------------------------------------------- | ||
510 | /// <summary> | ||
511 | /// | ||
512 | /// </summary> | ||
513 | // ----------------------------------------------------------------- | ||
514 | protected void GenerateRuntimeError(string msg) | ||
515 | { | ||
516 | m_log.InfoFormat("[JsonStore] runtime error: {0}",msg); | ||
517 | throw new Exception("JsonStore Runtime Error: " + msg); | ||
518 | } | ||
519 | |||
520 | // ----------------------------------------------------------------- | ||
521 | /// <summary> | ||
522 | /// | ||
523 | /// </summary> | ||
524 | // ----------------------------------------------------------------- | ||
525 | protected void DispatchValue(UUID scriptID, UUID reqID, string value) | ||
526 | { | ||
527 | m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); | ||
528 | } | ||
529 | |||
530 | // ----------------------------------------------------------------- | ||
531 | /// <summary> | ||
532 | /// | ||
533 | /// </summary> | ||
534 | // ----------------------------------------------------------------- | ||
535 | private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) | ||
384 | { | 536 | { |
385 | try | 537 | try |
386 | { | 538 | { |
387 | m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); | 539 | m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); |
388 | return; | 540 | return; |
389 | } | 541 | } |
390 | catch (Exception e) | 542 | catch (Exception e) |
391 | { | 543 | { |
392 | m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); | 544 | m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); |
393 | } | 545 | } |
394 | 546 | ||
395 | DispatchValue(scriptID,reqID,String.Empty); | 547 | DispatchValue(scriptID,reqID,String.Empty); |
396 | } | 548 | } |
397 | 549 | ||
398 | #endregion | ||
399 | 550 | ||
400 | // ----------------------------------------------------------------- | 551 | // ----------------------------------------------------------------- |
401 | /// <summary> | 552 | /// <summary> |
402 | /// | 553 | /// |
403 | /// </summary> | 554 | /// </summary> |
404 | // ----------------------------------------------------------------- | 555 | // ----------------------------------------------------------------- |
405 | protected void DispatchValue(UUID scriptID, UUID reqID, string value) | 556 | private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) |
406 | { | 557 | { |
407 | m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); | 558 | try |
559 | { | ||
560 | m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); | ||
561 | return; | ||
562 | } | ||
563 | catch (Exception e) | ||
564 | { | ||
565 | m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); | ||
566 | } | ||
567 | |||
568 | DispatchValue(scriptID,reqID,String.Empty); | ||
408 | } | 569 | } |
409 | 570 | ||
410 | // ----------------------------------------------------------------- | 571 | // ----------------------------------------------------------------- |
@@ -412,31 +573,44 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
412 | /// | 573 | /// |
413 | /// </summary> | 574 | /// </summary> |
414 | // ----------------------------------------------------------------- | 575 | // ----------------------------------------------------------------- |
415 | private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) | 576 | private void DoJsonReadNotecard( |
577 | UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) | ||
416 | { | 578 | { |
579 | UUID assetID; | ||
580 | |||
581 | if (!UUID.TryParse(notecardIdentifier, out assetID)) | ||
582 | { | ||
583 | SceneObjectPart part = m_scene.GetSceneObjectPart(hostID); | ||
584 | assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard); | ||
585 | } | ||
586 | |||
417 | AssetBase a = m_scene.AssetService.Get(assetID.ToString()); | 587 | AssetBase a = m_scene.AssetService.Get(assetID.ToString()); |
418 | if (a == null) | 588 | if (a == null) |
419 | GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); | 589 | GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID)); |
420 | 590 | ||
421 | if (a.Type != (sbyte)AssetType.Notecard) | 591 | if (a.Type != (sbyte)AssetType.Notecard) |
422 | GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); | 592 | GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID)); |
423 | 593 | ||
424 | m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); | 594 | m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID); |
425 | 595 | ||
426 | try | 596 | try |
427 | { | 597 | { |
428 | string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); | 598 | string jsondata = SLUtil.ParseNotecardToString(a.Data); |
429 | int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; | 599 | int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; |
430 | m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); | 600 | m_comms.DispatchReply(scriptID, result, "", reqID.ToString()); |
431 | return; | 601 | return; |
432 | } | 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 | } | ||
433 | catch (Exception e) | 607 | catch (Exception e) |
434 | { | 608 | { |
435 | m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); | 609 | m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message); |
436 | } | 610 | } |
437 | 611 | ||
438 | GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); | 612 | GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID)); |
439 | m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); | 613 | m_comms.DispatchReply(scriptID, 0, "", reqID.ToString()); |
440 | } | 614 | } |
441 | 615 | ||
442 | // ----------------------------------------------------------------- | 616 | // ----------------------------------------------------------------- |
@@ -494,5 +668,141 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
494 | 668 | ||
495 | m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); | 669 | m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); |
496 | } | 670 | } |
671 | |||
672 | // ----------------------------------------------------------------- | ||
673 | /// <summary> | ||
674 | /// Convert a list of values that are path components to a single string path | ||
675 | /// </summary> | ||
676 | // ----------------------------------------------------------------- | ||
677 | protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$"); | ||
678 | private string ConvertList2Path(object[] pathlist) | ||
679 | { | ||
680 | string path = ""; | ||
681 | for (int i = 0; i < pathlist.Length; i++) | ||
682 | { | ||
683 | string token = ""; | ||
684 | |||
685 | if (pathlist[i] is string) | ||
686 | { | ||
687 | token = pathlist[i].ToString(); | ||
688 | |||
689 | // Check to see if this is a bare number which would not be a valid | ||
690 | // identifier otherwise | ||
691 | if (m_ArrayPattern.IsMatch(token)) | ||
692 | token = '[' + token + ']'; | ||
693 | } | ||
694 | else if (pathlist[i] is int) | ||
695 | { | ||
696 | token = "[" + pathlist[i].ToString() + "]"; | ||
697 | } | ||
698 | else | ||
699 | { | ||
700 | token = "." + pathlist[i].ToString() + "."; | ||
701 | } | ||
702 | |||
703 | path += token + "."; | ||
704 | } | ||
705 | |||
706 | return path; | ||
707 | } | ||
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 | } | ||
497 | } | 807 | } |
498 | } | 808 | } |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs new file mode 100644 index 0000000..99a7076 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | |||
@@ -0,0 +1,900 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using NUnit.Framework; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.CoreModules.Scripting.ScriptModuleComms; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Region.ScriptEngine.Shared; | ||
40 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
41 | using OpenSim.Services.Interfaces; | ||
42 | using OpenSim.Tests.Common; | ||
43 | |||
44 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// Tests for inventory functions in LSL | ||
48 | /// </summary> | ||
49 | [TestFixture] | ||
50 | public class JsonStoreScriptModuleTests : OpenSimTestCase | ||
51 | { | ||
52 | private Scene m_scene; | ||
53 | private MockScriptEngine m_engine; | ||
54 | private ScriptModuleCommsModule m_smcm; | ||
55 | private JsonStoreScriptModule m_jssm; | ||
56 | |||
57 | [TestFixtureSetUp] | ||
58 | public void FixtureInit() | ||
59 | { | ||
60 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. | ||
61 | Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; | ||
62 | } | ||
63 | |||
64 | [TestFixtureTearDown] | ||
65 | public void TearDown() | ||
66 | { | ||
67 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
68 | // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression | ||
69 | // tests really shouldn't). | ||
70 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
71 | } | ||
72 | |||
73 | [SetUp] | ||
74 | public override void SetUp() | ||
75 | { | ||
76 | base.SetUp(); | ||
77 | |||
78 | IConfigSource configSource = new IniConfigSource(); | ||
79 | IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); | ||
80 | jsonStoreConfig.Set("Enabled", "true"); | ||
81 | |||
82 | m_engine = new MockScriptEngine(); | ||
83 | m_smcm = new ScriptModuleCommsModule(); | ||
84 | JsonStoreModule jsm = new JsonStoreModule(); | ||
85 | m_jssm = new JsonStoreScriptModule(); | ||
86 | |||
87 | m_scene = new SceneHelpers().SetupScene(); | ||
88 | SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm); | ||
89 | |||
90 | try | ||
91 | { | ||
92 | m_smcm.RegisterScriptInvocation(this, "DummyTestMethod"); | ||
93 | } | ||
94 | catch (ArgumentException) | ||
95 | { | ||
96 | Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier."); | ||
97 | } | ||
98 | |||
99 | // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods. | ||
100 | } | ||
101 | |||
102 | private object InvokeOp(string name, params object[] args) | ||
103 | { | ||
104 | return InvokeOpOnHost(name, UUID.Zero, args); | ||
105 | } | ||
106 | |||
107 | private object InvokeOpOnHost(string name, UUID hostId, params object[] args) | ||
108 | { | ||
109 | return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args); | ||
110 | } | ||
111 | |||
112 | [Test] | ||
113 | public void TestJsonCreateStore() | ||
114 | { | ||
115 | TestHelpers.InMethod(); | ||
116 | // TestHelpers.EnableLogging(); | ||
117 | |||
118 | // Test blank store | ||
119 | { | ||
120 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
121 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
122 | } | ||
123 | |||
124 | // Test single element store | ||
125 | { | ||
126 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
127 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
128 | } | ||
129 | |||
130 | // Test with an integer value | ||
131 | { | ||
132 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }"); | ||
133 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
134 | |||
135 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | ||
136 | Assert.That(value, Is.EqualTo("42.15")); | ||
137 | } | ||
138 | |||
139 | // Test with an array as the root node | ||
140 | { | ||
141 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]"); | ||
142 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
143 | |||
144 | string value = (string)InvokeOp("JsonGetValue", storeId, "[1]"); | ||
145 | Assert.That(value, Is.EqualTo("two")); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | [Test] | ||
150 | public void TestJsonDestroyStore() | ||
151 | { | ||
152 | TestHelpers.InMethod(); | ||
153 | // TestHelpers.EnableLogging(); | ||
154 | |||
155 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
156 | int dsrv = (int)InvokeOp("JsonDestroyStore", storeId); | ||
157 | |||
158 | Assert.That(dsrv, Is.EqualTo(1)); | ||
159 | |||
160 | int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
161 | Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
162 | } | ||
163 | |||
164 | [Test] | ||
165 | public void TestJsonDestroyStoreNotExists() | ||
166 | { | ||
167 | TestHelpers.InMethod(); | ||
168 | // TestHelpers.EnableLogging(); | ||
169 | |||
170 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
171 | |||
172 | int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId); | ||
173 | |||
174 | Assert.That(dsrv, Is.EqualTo(0)); | ||
175 | } | ||
176 | |||
177 | [Test] | ||
178 | public void TestJsonGetValue() | ||
179 | { | ||
180 | TestHelpers.InMethod(); | ||
181 | // TestHelpers.EnableLogging(); | ||
182 | |||
183 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); | ||
184 | |||
185 | { | ||
186 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World"); | ||
187 | Assert.That(value, Is.EqualTo("Two")); | ||
188 | } | ||
189 | |||
190 | // Test get of path section instead of leaf | ||
191 | { | ||
192 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | ||
193 | Assert.That(value, Is.EqualTo("")); | ||
194 | } | ||
195 | |||
196 | // Test get of non-existing value | ||
197 | { | ||
198 | string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo"); | ||
199 | Assert.That(fakeValueGet, Is.EqualTo("")); | ||
200 | } | ||
201 | |||
202 | // Test get from non-existing store | ||
203 | { | ||
204 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
205 | string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); | ||
206 | Assert.That(fakeStoreValueGet, Is.EqualTo("")); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | [Test] | ||
211 | public void TestJsonGetJson() | ||
212 | { | ||
213 | TestHelpers.InMethod(); | ||
214 | // TestHelpers.EnableLogging(); | ||
215 | |||
216 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); | ||
217 | |||
218 | { | ||
219 | string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World"); | ||
220 | Assert.That(value, Is.EqualTo("'Two'")); | ||
221 | } | ||
222 | |||
223 | // Test get of path section instead of leaf | ||
224 | { | ||
225 | string value = (string)InvokeOp("JsonGetJson", storeId, "Hello"); | ||
226 | Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}")); | ||
227 | } | ||
228 | |||
229 | // Test get of non-existing value | ||
230 | { | ||
231 | string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo"); | ||
232 | Assert.That(fakeValueGet, Is.EqualTo("")); | ||
233 | } | ||
234 | |||
235 | // Test get from non-existing store | ||
236 | { | ||
237 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
238 | string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello"); | ||
239 | Assert.That(fakeStoreValueGet, Is.EqualTo("")); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | // [Test] | ||
244 | // public void TestJsonTakeValue() | ||
245 | // { | ||
246 | // TestHelpers.InMethod(); | ||
247 | //// TestHelpers.EnableLogging(); | ||
248 | // | ||
249 | // UUID storeId | ||
250 | // = (UUID)m_smcm.InvokeOperation( | ||
251 | // UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); | ||
252 | // | ||
253 | // string value | ||
254 | // = (string)m_smcm.InvokeOperation( | ||
255 | // UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" }); | ||
256 | // | ||
257 | // Assert.That(value, Is.EqualTo("World")); | ||
258 | // | ||
259 | // string value2 | ||
260 | // = (string)m_smcm.InvokeOperation( | ||
261 | // UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); | ||
262 | // | ||
263 | // Assert.That(value, Is.Null); | ||
264 | // } | ||
265 | |||
266 | [Test] | ||
267 | public void TestJsonRemoveValue() | ||
268 | { | ||
269 | TestHelpers.InMethod(); | ||
270 | // TestHelpers.EnableLogging(); | ||
271 | |||
272 | // Test remove of node in object pointing to a string | ||
273 | { | ||
274 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
275 | |||
276 | int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); | ||
277 | Assert.That(returnValue, Is.EqualTo(1)); | ||
278 | |||
279 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
280 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
281 | |||
282 | string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | ||
283 | Assert.That(returnValue2, Is.EqualTo("")); | ||
284 | } | ||
285 | |||
286 | // Test remove of node in object pointing to another object | ||
287 | { | ||
288 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }"); | ||
289 | |||
290 | int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); | ||
291 | Assert.That(returnValue, Is.EqualTo(1)); | ||
292 | |||
293 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
294 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
295 | |||
296 | string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); | ||
297 | Assert.That(returnValue2, Is.EqualTo("")); | ||
298 | } | ||
299 | |||
300 | // Test remove of node in an array | ||
301 | { | ||
302 | UUID storeId | ||
303 | = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }"); | ||
304 | |||
305 | int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); | ||
306 | Assert.That(returnValue, Is.EqualTo(1)); | ||
307 | |||
308 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]"); | ||
309 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); | ||
310 | |||
311 | result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]"); | ||
312 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
313 | |||
314 | string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); | ||
315 | Assert.That(stringReturnValue, Is.EqualTo("value2")); | ||
316 | |||
317 | stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]"); | ||
318 | Assert.That(stringReturnValue, Is.EqualTo("")); | ||
319 | } | ||
320 | |||
321 | // Test remove of non-existing value | ||
322 | { | ||
323 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
324 | |||
325 | int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese"); | ||
326 | Assert.That(fakeValueRemove, Is.EqualTo(0)); | ||
327 | } | ||
328 | |||
329 | { | ||
330 | // Test get from non-existing store | ||
331 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
332 | int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello"); | ||
333 | Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | // [Test] | ||
338 | // public void TestJsonTestPath() | ||
339 | // { | ||
340 | // TestHelpers.InMethod(); | ||
341 | //// TestHelpers.EnableLogging(); | ||
342 | // | ||
343 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); | ||
344 | // | ||
345 | // { | ||
346 | // int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World"); | ||
347 | // Assert.That(result, Is.EqualTo(1)); | ||
348 | // } | ||
349 | // | ||
350 | // // Test for path which does not resolve to a value. | ||
351 | // { | ||
352 | // int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); | ||
353 | // Assert.That(result, Is.EqualTo(0)); | ||
354 | // } | ||
355 | // | ||
356 | // { | ||
357 | // int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); | ||
358 | // Assert.That(result2, Is.EqualTo(0)); | ||
359 | // } | ||
360 | // | ||
361 | // // Test with fake store | ||
362 | // { | ||
363 | // UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
364 | // int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); | ||
365 | // Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); | ||
366 | // } | ||
367 | // } | ||
368 | |||
369 | // [Test] | ||
370 | // public void TestJsonTestPathJson() | ||
371 | // { | ||
372 | // TestHelpers.InMethod(); | ||
373 | //// TestHelpers.EnableLogging(); | ||
374 | // | ||
375 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); | ||
376 | // | ||
377 | // { | ||
378 | // int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World"); | ||
379 | // Assert.That(result, Is.EqualTo(1)); | ||
380 | // } | ||
381 | // | ||
382 | // // Test for path which does not resolve to a value. | ||
383 | // { | ||
384 | // int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello"); | ||
385 | // Assert.That(result, Is.EqualTo(1)); | ||
386 | // } | ||
387 | // | ||
388 | // { | ||
389 | // int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo"); | ||
390 | // Assert.That(result2, Is.EqualTo(0)); | ||
391 | // } | ||
392 | // | ||
393 | // // Test with fake store | ||
394 | // { | ||
395 | // UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
396 | // int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello"); | ||
397 | // Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); | ||
398 | // } | ||
399 | // } | ||
400 | |||
401 | [Test] | ||
402 | public void TestJsonGetArrayLength() | ||
403 | { | ||
404 | TestHelpers.InMethod(); | ||
405 | // TestHelpers.EnableLogging(); | ||
406 | |||
407 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); | ||
408 | |||
409 | { | ||
410 | int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World"); | ||
411 | Assert.That(result, Is.EqualTo(2)); | ||
412 | } | ||
413 | |||
414 | // Test path which is not an array | ||
415 | { | ||
416 | int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello"); | ||
417 | Assert.That(result, Is.EqualTo(-1)); | ||
418 | } | ||
419 | |||
420 | // Test fake path | ||
421 | { | ||
422 | int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo"); | ||
423 | Assert.That(result, Is.EqualTo(-1)); | ||
424 | } | ||
425 | |||
426 | // Test fake store | ||
427 | { | ||
428 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
429 | int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World"); | ||
430 | Assert.That(result, Is.EqualTo(-1)); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | [Test] | ||
435 | public void TestJsonGetNodeType() | ||
436 | { | ||
437 | TestHelpers.InMethod(); | ||
438 | // TestHelpers.EnableLogging(); | ||
439 | |||
440 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); | ||
441 | |||
442 | { | ||
443 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "."); | ||
444 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); | ||
445 | } | ||
446 | |||
447 | { | ||
448 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
449 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); | ||
450 | } | ||
451 | |||
452 | { | ||
453 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World"); | ||
454 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY)); | ||
455 | } | ||
456 | |||
457 | { | ||
458 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]"); | ||
459 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); | ||
460 | } | ||
461 | |||
462 | { | ||
463 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]"); | ||
464 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); | ||
465 | } | ||
466 | |||
467 | // Test for non-existent path | ||
468 | { | ||
469 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo"); | ||
470 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
471 | } | ||
472 | |||
473 | // Test for non-existent store | ||
474 | { | ||
475 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
476 | int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, "."); | ||
477 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
478 | } | ||
479 | } | ||
480 | |||
481 | [Test] | ||
482 | public void TestJsonList2Path() | ||
483 | { | ||
484 | TestHelpers.InMethod(); | ||
485 | // TestHelpers.EnableLogging(); | ||
486 | |||
487 | // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason | ||
488 | // - some confusion with the methods that take a params object[] invocation. | ||
489 | { | ||
490 | string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" }); | ||
491 | Assert.That(result, Is.EqualTo("{foo}")); | ||
492 | } | ||
493 | |||
494 | { | ||
495 | string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" }); | ||
496 | Assert.That(result, Is.EqualTo("{foo}.{bar}")); | ||
497 | } | ||
498 | |||
499 | { | ||
500 | string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" }); | ||
501 | Assert.That(result, Is.EqualTo("{foo}.[1].{bar}")); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | [Test] | ||
506 | public void TestJsonSetValue() | ||
507 | { | ||
508 | TestHelpers.InMethod(); | ||
509 | // TestHelpers.EnableLogging(); | ||
510 | |||
511 | { | ||
512 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
513 | |||
514 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); | ||
515 | Assert.That(result, Is.EqualTo(1)); | ||
516 | |||
517 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); | ||
518 | Assert.That(value, Is.EqualTo("Times")); | ||
519 | } | ||
520 | |||
521 | // Test setting a key containing periods with delineation | ||
522 | { | ||
523 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
524 | |||
525 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times"); | ||
526 | Assert.That(result, Is.EqualTo(1)); | ||
527 | |||
528 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}"); | ||
529 | Assert.That(value, Is.EqualTo("Times")); | ||
530 | } | ||
531 | |||
532 | // *** Test [] *** | ||
533 | |||
534 | // Test setting a key containing unbalanced ] without delineation. Expecting failure | ||
535 | { | ||
536 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
537 | |||
538 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times"); | ||
539 | Assert.That(result, Is.EqualTo(0)); | ||
540 | |||
541 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus"); | ||
542 | Assert.That(value, Is.EqualTo("")); | ||
543 | } | ||
544 | |||
545 | // Test setting a key containing unbalanced [ without delineation. Expecting failure | ||
546 | { | ||
547 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
548 | |||
549 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times"); | ||
550 | Assert.That(result, Is.EqualTo(0)); | ||
551 | |||
552 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus"); | ||
553 | Assert.That(value, Is.EqualTo("")); | ||
554 | } | ||
555 | |||
556 | // Test setting a key containing unbalanced [] without delineation. Expecting failure | ||
557 | { | ||
558 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
559 | |||
560 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times"); | ||
561 | Assert.That(result, Is.EqualTo(0)); | ||
562 | |||
563 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus"); | ||
564 | Assert.That(value, Is.EqualTo("")); | ||
565 | } | ||
566 | |||
567 | // Test setting a key containing unbalanced ] with delineation | ||
568 | { | ||
569 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
570 | |||
571 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times"); | ||
572 | Assert.That(result, Is.EqualTo(1)); | ||
573 | |||
574 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}"); | ||
575 | Assert.That(value, Is.EqualTo("Times")); | ||
576 | } | ||
577 | |||
578 | // Test setting a key containing unbalanced [ with delineation | ||
579 | { | ||
580 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
581 | |||
582 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times"); | ||
583 | Assert.That(result, Is.EqualTo(1)); | ||
584 | |||
585 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}"); | ||
586 | Assert.That(value, Is.EqualTo("Times")); | ||
587 | } | ||
588 | |||
589 | // Test setting a key containing empty balanced [] with delineation | ||
590 | { | ||
591 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
592 | |||
593 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times"); | ||
594 | Assert.That(result, Is.EqualTo(1)); | ||
595 | |||
596 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}"); | ||
597 | Assert.That(value, Is.EqualTo("Times")); | ||
598 | } | ||
599 | |||
600 | // // Commented out as this currently unexpectedly fails. | ||
601 | // // Test setting a key containing brackets around an integer with delineation | ||
602 | // { | ||
603 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
604 | // | ||
605 | // int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times"); | ||
606 | // Assert.That(result, Is.EqualTo(1)); | ||
607 | // | ||
608 | // string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}"); | ||
609 | // Assert.That(value, Is.EqualTo("Times")); | ||
610 | // } | ||
611 | |||
612 | // *** Test {} *** | ||
613 | |||
614 | // Test setting a key containing unbalanced } without delineation. Expecting failure (?) | ||
615 | { | ||
616 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
617 | |||
618 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times"); | ||
619 | Assert.That(result, Is.EqualTo(0)); | ||
620 | |||
621 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); | ||
622 | Assert.That(value, Is.EqualTo("")); | ||
623 | } | ||
624 | |||
625 | // Test setting a key containing unbalanced { without delineation. Expecting failure (?) | ||
626 | { | ||
627 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
628 | |||
629 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times"); | ||
630 | Assert.That(result, Is.EqualTo(0)); | ||
631 | |||
632 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); | ||
633 | Assert.That(value, Is.EqualTo("")); | ||
634 | } | ||
635 | |||
636 | // // Commented out as this currently unexpectedly fails. | ||
637 | // // Test setting a key containing unbalanced } | ||
638 | // { | ||
639 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
640 | // | ||
641 | // int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times"); | ||
642 | // Assert.That(result, Is.EqualTo(0)); | ||
643 | // } | ||
644 | |||
645 | // Test setting a key containing unbalanced { with delineation | ||
646 | { | ||
647 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
648 | |||
649 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times"); | ||
650 | Assert.That(result, Is.EqualTo(1)); | ||
651 | |||
652 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}"); | ||
653 | Assert.That(value, Is.EqualTo("Times")); | ||
654 | } | ||
655 | |||
656 | // Test setting a key containing balanced {} with delineation. This should fail. | ||
657 | { | ||
658 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
659 | |||
660 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times"); | ||
661 | Assert.That(result, Is.EqualTo(0)); | ||
662 | |||
663 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}"); | ||
664 | Assert.That(value, Is.EqualTo("")); | ||
665 | } | ||
666 | |||
667 | // Test setting to location that does not exist. This should fail. | ||
668 | { | ||
669 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
670 | |||
671 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times"); | ||
672 | Assert.That(result, Is.EqualTo(0)); | ||
673 | |||
674 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); | ||
675 | Assert.That(value, Is.EqualTo("")); | ||
676 | } | ||
677 | |||
678 | // Test with fake store | ||
679 | { | ||
680 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
681 | int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World"); | ||
682 | Assert.That(fakeStoreValueSet, Is.EqualTo(0)); | ||
683 | } | ||
684 | } | ||
685 | |||
686 | [Test] | ||
687 | public void TestJsonSetJson() | ||
688 | { | ||
689 | TestHelpers.InMethod(); | ||
690 | // TestHelpers.EnableLogging(); | ||
691 | |||
692 | // Single quoted token case | ||
693 | { | ||
694 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
695 | |||
696 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'"); | ||
697 | Assert.That(result, Is.EqualTo(1)); | ||
698 | |||
699 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); | ||
700 | Assert.That(value, Is.EqualTo("Times")); | ||
701 | } | ||
702 | |||
703 | // Sub-tree case | ||
704 | { | ||
705 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
706 | |||
707 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }"); | ||
708 | Assert.That(result, Is.EqualTo(1)); | ||
709 | |||
710 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled"); | ||
711 | Assert.That(value, Is.EqualTo("Times")); | ||
712 | } | ||
713 | |||
714 | // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings. | ||
715 | { | ||
716 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
717 | |||
718 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times"); | ||
719 | Assert.That(result, Is.EqualTo(0)); | ||
720 | |||
721 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); | ||
722 | Assert.That(value, Is.EqualTo("")); | ||
723 | } | ||
724 | |||
725 | // Test setting to location that does not exist. This should fail. | ||
726 | { | ||
727 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
728 | |||
729 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'"); | ||
730 | Assert.That(result, Is.EqualTo(0)); | ||
731 | |||
732 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); | ||
733 | Assert.That(value, Is.EqualTo("")); | ||
734 | } | ||
735 | |||
736 | // Test with fake store | ||
737 | { | ||
738 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
739 | int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'"); | ||
740 | Assert.That(fakeStoreValueSet, Is.EqualTo(0)); | ||
741 | } | ||
742 | } | ||
743 | |||
744 | /// <summary> | ||
745 | /// Test for writing json to a notecard | ||
746 | /// </summary> | ||
747 | /// <remarks> | ||
748 | /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching | ||
749 | /// it via the MockScriptEngine or perhaps by a dummy script instance. | ||
750 | /// </remarks> | ||
751 | [Test] | ||
752 | public void TestJsonWriteNotecard() | ||
753 | { | ||
754 | TestHelpers.InMethod(); | ||
755 | // TestHelpers.EnableLogging(); | ||
756 | |||
757 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); | ||
758 | m_scene.AddSceneObject(so); | ||
759 | |||
760 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); | ||
761 | |||
762 | { | ||
763 | string notecardName = "nc1"; | ||
764 | |||
765 | // Write notecard | ||
766 | UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName); | ||
767 | Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
768 | |||
769 | TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); | ||
770 | Assert.That(nc1Item, Is.Not.Null); | ||
771 | |||
772 | // TODO: Should independently check the contents. | ||
773 | } | ||
774 | |||
775 | // TODO: Write partial test | ||
776 | |||
777 | { | ||
778 | // Try to write notecard for a bad path | ||
779 | // In this case we do get a request id but no notecard is written. | ||
780 | string badPathNotecardName = "badPathNotecardName"; | ||
781 | |||
782 | UUID writeNotecardBadPathRequestId | ||
783 | = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName); | ||
784 | Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
785 | |||
786 | TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName); | ||
787 | Assert.That(badPathItem, Is.Null); | ||
788 | } | ||
789 | |||
790 | { | ||
791 | // Test with fake store | ||
792 | // In this case we do get a request id but no notecard is written. | ||
793 | string fakeStoreNotecardName = "fakeStoreNotecardName"; | ||
794 | |||
795 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
796 | UUID fakeStoreWriteNotecardValue | ||
797 | = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName); | ||
798 | Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); | ||
799 | |||
800 | TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); | ||
801 | Assert.That(fakeStoreItem, Is.Null); | ||
802 | } | ||
803 | } | ||
804 | |||
805 | /// <summary> | ||
806 | /// Test for reading json from a notecard | ||
807 | /// </summary> | ||
808 | /// <remarks> | ||
809 | /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching | ||
810 | /// it via the MockScriptEngine or perhaps by a dummy script instance. | ||
811 | /// </remarks> | ||
812 | [Test] | ||
813 | public void TestJsonReadNotecard() | ||
814 | { | ||
815 | TestHelpers.InMethod(); | ||
816 | // TestHelpers.EnableLogging(); | ||
817 | |||
818 | string notecardName = "nc1"; | ||
819 | |||
820 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); | ||
821 | m_scene.AddSceneObject(so); | ||
822 | |||
823 | UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); | ||
824 | |||
825 | // Write notecard | ||
826 | InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName); | ||
827 | |||
828 | { | ||
829 | // Read notecard | ||
830 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
831 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName); | ||
832 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
833 | |||
834 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
835 | Assert.That(value, Is.EqualTo("World")); | ||
836 | } | ||
837 | |||
838 | { | ||
839 | // Read notecard to new single component path | ||
840 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
841 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName); | ||
842 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
843 | |||
844 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
845 | Assert.That(value, Is.EqualTo("")); | ||
846 | |||
847 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello"); | ||
848 | Assert.That(value, Is.EqualTo("World")); | ||
849 | } | ||
850 | |||
851 | { | ||
852 | // Read notecard to new multi-component path. This should not work. | ||
853 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
854 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); | ||
855 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
856 | |||
857 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
858 | Assert.That(value, Is.EqualTo("")); | ||
859 | |||
860 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); | ||
861 | Assert.That(value, Is.EqualTo("")); | ||
862 | } | ||
863 | |||
864 | { | ||
865 | // Read notecard to existing multi-component path. This should work | ||
866 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); | ||
867 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); | ||
868 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
869 | |||
870 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
871 | Assert.That(value, Is.EqualTo("")); | ||
872 | |||
873 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); | ||
874 | Assert.That(value, Is.EqualTo("World")); | ||
875 | } | ||
876 | |||
877 | { | ||
878 | // Read notecard to invalid path. This should not work. | ||
879 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); | ||
880 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); | ||
881 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
882 | |||
883 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
884 | Assert.That(value, Is.EqualTo("")); | ||
885 | } | ||
886 | |||
887 | { | ||
888 | // Try read notecard to fake store. | ||
889 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
890 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); | ||
891 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
892 | |||
893 | string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); | ||
894 | Assert.That(value, Is.EqualTo("")); | ||
895 | } | ||
896 | } | ||
897 | |||
898 | public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } | ||
899 | } | ||
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/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 5ed1514..47b9c09 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs | |||
@@ -34,7 +34,7 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object; | 36 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object; |
37 | using OpenSim.Region.Physics.Manager; | 37 | using OpenSim.Region.PhysicsModules.SharedBase; |
38 | using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType; | 38 | using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType; |
39 | using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType; | 39 | using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType; |
40 | 40 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c550c44..870c0bb 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | |||
@@ -105,7 +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 | m_log.InfoFormat("[RegionReady]: Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name); | 108 | // This should always show up to the user but should not trigger warn/errors as these messages are |
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); | ||
109 | 112 | ||
110 | if (m_uri != string.Empty) | 113 | if (m_uri != string.Empty) |
111 | { | 114 | { |
@@ -169,7 +172,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
169 | c.Channel = m_channelNotify; | 172 | c.Channel = m_channelNotify; |
170 | c.Message += numScriptsFailed.ToString() + "," + message; | 173 | c.Message += numScriptsFailed.ToString() + "," + message; |
171 | c.Type = ChatTypeEnum.Region; | 174 | c.Type = ChatTypeEnum.Region; |
172 | c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); | 175 | if (m_scene != null) |
176 | c.Position = new Vector3((m_scene.RegionInfo.RegionSizeX * 0.5f), (m_scene.RegionInfo.RegionSizeY * 0.5f), 30); | ||
177 | else | ||
178 | c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); | ||
173 | c.Sender = null; | 179 | c.Sender = null; |
174 | c.SenderUUID = UUID.Zero; | 180 | c.SenderUUID = UUID.Zero; |
175 | c.Scene = m_scene; | 181 | c.Scene = m_scene; |
@@ -215,8 +221,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
215 | // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", | 221 | // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", |
216 | // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); | 222 | // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); |
217 | 223 | ||
218 | m_log.InfoFormat( | 224 | // Putting this out to console to make it eye-catching for people who are running OpenSimulator |
219 | "[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); | 225 | // without info log messages enabled. Making this a warning is arguably misleading since it isn't a |
226 | // warning, and monitor scripts looking for warn/error/fatal messages will received false positives. | ||
227 | // Arguably, log4net needs a status log level (like Apache). | ||
228 | MainConsole.Instance.OutputFormat("INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); | ||
220 | } | 229 | } |
221 | 230 | ||
222 | m_scene.SceneGridService.InformNeighborsThatRegionisUp( | 231 | m_scene.SceneGridService.InformNeighborsThatRegionisUp( |
@@ -297,7 +306,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
297 | finally | 306 | finally |
298 | { | 307 | { |
299 | if (os != null) | 308 | if (os != null) |
300 | os.Close(); | 309 | os.Dispose(); |
301 | } | 310 | } |
302 | } | 311 | } |
303 | } | 312 | } |
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index 709d389..744d1e3 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs | |||
@@ -35,7 +35,6 @@ using OpenMetaverse; | |||
35 | using Mono.Addins; | 35 | using Mono.Addins; |
36 | 36 | ||
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Communications; | ||
39 | using OpenSim.Framework.Servers; | 38 | using OpenSim.Framework.Servers; |
40 | using OpenSim.Framework.Servers.HttpServer; | 39 | using OpenSim.Framework.Servers.HttpServer; |
41 | using OpenSim.Framework.Client; | 40 | using OpenSim.Framework.Client; |
diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/OptionalModules/UserStatistics/ActiveConnectionsAJAX.cs index 3243a9a..6a1112c 100644 --- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/ActiveConnectionsAJAX.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using Mono.Data.SqliteClient; | 33 | using Mono.Data.SqliteClient; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
36 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Framework.Monitoring; | 38 | using OpenSim.Framework.Monitoring; |
@@ -51,7 +52,6 @@ namespace OpenSim.Region.UserStatistics | |||
51 | 52 | ||
52 | public Hashtable ProcessModel(Hashtable pParams) | 53 | public Hashtable ProcessModel(Hashtable pParams) |
53 | { | 54 | { |
54 | |||
55 | List<Scene> m_scene = (List<Scene>)pParams["Scenes"]; | 55 | List<Scene> m_scene = (List<Scene>)pParams["Scenes"]; |
56 | 56 | ||
57 | Hashtable nh = new Hashtable(); | 57 | Hashtable nh = new Hashtable(); |
@@ -129,6 +129,86 @@ namespace OpenSim.Region.UserStatistics | |||
129 | return output.ToString(); | 129 | return output.ToString(); |
130 | } | 130 | } |
131 | 131 | ||
132 | /// <summary> | ||
133 | /// Convert active connections information to JSON string. Returns a structure: | ||
134 | /// <pre> | ||
135 | /// {"regionName": { | ||
136 | /// "presenceName": { | ||
137 | /// "name": "presenceName", | ||
138 | /// "position": "<x,y,z>", | ||
139 | /// "isRoot": "false", | ||
140 | /// "throttle": { | ||
141 | /// }, | ||
142 | /// "queue": { | ||
143 | /// } | ||
144 | /// }, | ||
145 | /// ... // multiple presences in the scene | ||
146 | /// }, | ||
147 | /// ... // multiple regions in the sim | ||
148 | /// } | ||
149 | /// | ||
150 | /// </pre> | ||
151 | /// </summary> | ||
152 | /// <param name="pModelResult"></param> | ||
153 | /// <returns></returns> | ||
154 | public string RenderJson(Hashtable pModelResult) | ||
155 | { | ||
156 | List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"]; | ||
157 | |||
158 | OSDMap regionInfo = new OSDMap(); | ||
159 | foreach (Scene scene in all_scenes) | ||
160 | { | ||
161 | OSDMap sceneInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
162 | List<ScenePresence> avatarInScene = scene.GetScenePresences(); | ||
163 | foreach (ScenePresence av in avatarInScene) | ||
164 | { | ||
165 | OSDMap presenceInfo = new OSDMap(); | ||
166 | presenceInfo.Add("Name", new OSDString(av.Name)); | ||
167 | |||
168 | Dictionary<string,string> queues = new Dictionary<string, string>(); | ||
169 | if (av.ControllingClient is IStatsCollector) | ||
170 | { | ||
171 | IStatsCollector isClient = (IStatsCollector) av.ControllingClient; | ||
172 | queues = decodeQueueReport(isClient.Report()); | ||
173 | } | ||
174 | OSDMap queueInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
175 | foreach (KeyValuePair<string, string> kvp in queues) { | ||
176 | queueInfo.Add(kvp.Key, new OSDString(kvp.Value)); | ||
177 | } | ||
178 | sceneInfo.Add("queues", queueInfo); | ||
179 | |||
180 | if (av.IsChildAgent) | ||
181 | presenceInfo.Add("isRoot", new OSDString("false")); | ||
182 | else | ||
183 | presenceInfo.Add("isRoot", new OSDString("true")); | ||
184 | |||
185 | if (av.AbsolutePosition == DefaultNeighborPosition) | ||
186 | { | ||
187 | presenceInfo.Add("position", new OSDString("<0, 0, 0>")); | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | presenceInfo.Add("position", new OSDString(string.Format("<{0},{1},{2}>", | ||
192 | (int)av.AbsolutePosition.X, | ||
193 | (int) av.AbsolutePosition.Y, | ||
194 | (int) av.AbsolutePosition.Z)) ); | ||
195 | } | ||
196 | |||
197 | Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); | ||
198 | OSDMap throttleInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
199 | foreach (string throttlename in throttles.Keys) | ||
200 | { | ||
201 | throttleInfo.Add(throttlename, new OSDString(throttles[throttlename].ToString())); | ||
202 | } | ||
203 | presenceInfo.Add("throttle", throttleInfo); | ||
204 | |||
205 | sceneInfo.Add(av.Name, presenceInfo); | ||
206 | } | ||
207 | regionInfo.Add(scene.RegionInfo.RegionName, sceneInfo); | ||
208 | } | ||
209 | return regionInfo.ToString(); | ||
210 | } | ||
211 | |||
132 | public Dictionary<string, int> DecodeClientThrottles(byte[] throttle) | 212 | public Dictionary<string, int> DecodeClientThrottles(byte[] throttle) |
133 | { | 213 | { |
134 | Dictionary<string, int> returndict = new Dictionary<string, int>(); | 214 | Dictionary<string, int> returndict = new Dictionary<string, int>(); |
@@ -203,7 +283,7 @@ namespace OpenSim.Region.UserStatistics | |||
203 | returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; | 283 | returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; |
204 | returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; | 284 | returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; |
205 | returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; | 285 | returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; |
206 | returndic.Add("Asset", rep.Substring((7 * pos), 8)); | 286 | returndic.Add("Asset", rep.Substring((7 * pos), 8)); |
207 | /* | 287 | /* |
208 | * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", | 288 | * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", |
209 | SendQueue.Count(), | 289 | SendQueue.Count(), |
diff --git a/OpenSim/Region/UserStatistics/Clients_report.cs b/OpenSim/Region/OptionalModules/UserStatistics/Clients_report.cs index b2bb33b..4a6f7be 100644 --- a/OpenSim/Region/UserStatistics/Clients_report.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/Clients_report.cs | |||
@@ -31,6 +31,7 @@ using System.Collections.Generic; | |||
31 | using System.Text; | 31 | using System.Text; |
32 | using Mono.Data.SqliteClient; | 32 | using Mono.Data.SqliteClient; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.StructuredData; | ||
34 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
35 | 36 | ||
36 | namespace OpenSim.Region.UserStatistics | 37 | namespace OpenSim.Region.UserStatistics |
@@ -44,6 +45,32 @@ namespace OpenSim.Region.UserStatistics | |||
44 | get { return "Client"; } | 45 | get { return "Client"; } |
45 | } | 46 | } |
46 | 47 | ||
48 | /// <summary> | ||
49 | /// Return summar information in the form: | ||
50 | /// <pre> | ||
51 | /// {"totalUsers": "34", | ||
52 | /// "totalSessions": "233", | ||
53 | /// ... | ||
54 | /// } | ||
55 | /// </pre> | ||
56 | /// </summary> | ||
57 | /// <param name="pModelResult"></param> | ||
58 | /// <returns></returns> | ||
59 | public string RenderJson(Hashtable pModelResult) { | ||
60 | stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; | ||
61 | |||
62 | OSDMap summaryInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
63 | summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); | ||
64 | summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); | ||
65 | summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); | ||
66 | summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); | ||
67 | summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); | ||
68 | summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); | ||
69 | summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); | ||
70 | summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); | ||
71 | return summaryInfo.ToString(); | ||
72 | } | ||
73 | |||
47 | public Hashtable ProcessModel(Hashtable pParams) | 74 | public Hashtable ProcessModel(Hashtable pParams) |
48 | { | 75 | { |
49 | SqliteConnection dbConn = (SqliteConnection)pParams["DatabaseConnection"]; | 76 | SqliteConnection dbConn = (SqliteConnection)pParams["DatabaseConnection"]; |
diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/OptionalModules/UserStatistics/Default_Report.cs index cdc615c..fabe3d4 100644 --- a/OpenSim/Region/UserStatistics/Default_Report.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/Default_Report.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using Mono.Data.SqliteClient; | 33 | using Mono.Data.SqliteClient; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Framework.Monitoring; | 37 | using OpenSim.Framework.Monitoring; |
37 | 38 | ||
@@ -230,6 +231,31 @@ TD.align_top { vertical-align: top; } | |||
230 | return returnstruct; | 231 | return returnstruct; |
231 | } | 232 | } |
232 | 233 | ||
234 | /// <summary> | ||
235 | /// Return summar information in the form: | ||
236 | /// <pre> | ||
237 | /// {"totalUsers": "34", | ||
238 | /// "totalSessions": "233", | ||
239 | /// ... | ||
240 | /// } | ||
241 | /// </pre> | ||
242 | /// </summary> | ||
243 | /// <param name="pModelResult"></param> | ||
244 | /// <returns></returns> | ||
245 | public string RenderJson(Hashtable pModelResult) { | ||
246 | stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; | ||
247 | |||
248 | OSDMap summaryInfo = new OSDMap(); | ||
249 | summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); | ||
250 | summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); | ||
251 | summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); | ||
252 | summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); | ||
253 | summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); | ||
254 | summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); | ||
255 | summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); | ||
256 | summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); | ||
257 | return summaryInfo.ToString(); | ||
258 | } | ||
233 | } | 259 | } |
234 | 260 | ||
235 | public struct stats_default_page_values | 261 | public struct stats_default_page_values |
@@ -247,4 +273,5 @@ TD.align_top { vertical-align: top; } | |||
247 | public Dictionary<UUID, USimStatsData> sim_stat_data; | 273 | public Dictionary<UUID, USimStatsData> sim_stat_data; |
248 | public Dictionary<string, IStatsController> stats_reports; | 274 | public Dictionary<string, IStatsController> stats_reports; |
249 | } | 275 | } |
276 | |||
250 | } | 277 | } |
diff --git a/OpenSim/Region/UserStatistics/HTMLUtil.cs b/OpenSim/Region/OptionalModules/UserStatistics/HTMLUtil.cs index c07619f..c07619f 100644 --- a/OpenSim/Region/UserStatistics/HTMLUtil.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/HTMLUtil.cs | |||
diff --git a/OpenSim/Region/UserStatistics/IStatsReport.cs b/OpenSim/Region/OptionalModules/UserStatistics/IStatsReport.cs index e0ecce4..80c4487 100644 --- a/OpenSim/Region/UserStatistics/IStatsReport.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/IStatsReport.cs | |||
@@ -34,5 +34,6 @@ namespace OpenSim.Region.UserStatistics | |||
34 | string ReportName { get; } | 34 | string ReportName { get; } |
35 | Hashtable ProcessModel(Hashtable pParams); | 35 | Hashtable ProcessModel(Hashtable pParams); |
36 | string RenderView(Hashtable pModelResult); | 36 | string RenderView(Hashtable pModelResult); |
37 | string RenderJson(Hashtable pModelResult); | ||
37 | } | 38 | } |
38 | } | 39 | } |
diff --git a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs b/OpenSim/Region/OptionalModules/UserStatistics/LogLinesAJAX.cs index 74de46b..4d45b80 100644 --- a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/LogLinesAJAX.cs | |||
@@ -33,6 +33,7 @@ using System.Text; | |||
33 | using System.Text.RegularExpressions; | 33 | using System.Text.RegularExpressions; |
34 | using Mono.Data.SqliteClient; | 34 | using Mono.Data.SqliteClient; |
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenMetaverse.StructuredData; | ||
36 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Framework.Monitoring; | 38 | using OpenSim.Framework.Monitoring; |
38 | 39 | ||
@@ -125,6 +126,34 @@ namespace OpenSim.Region.UserStatistics | |||
125 | return output.ToString(); | 126 | return output.ToString(); |
126 | } | 127 | } |
127 | 128 | ||
129 | /// <summary> | ||
130 | /// Return the last log lines. Output in the format: | ||
131 | /// <pre> | ||
132 | /// {"logLines": [ | ||
133 | /// "line1", | ||
134 | /// "line2", | ||
135 | /// ... | ||
136 | /// ] | ||
137 | /// } | ||
138 | /// </pre> | ||
139 | /// </summary> | ||
140 | /// <param name="pModelResult"></param> | ||
141 | /// <returns></returns> | ||
142 | public string RenderJson(Hashtable pModelResult) | ||
143 | { | ||
144 | OSDMap logInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
145 | |||
146 | OSDArray logLines = new OpenMetaverse.StructuredData.OSDArray(); | ||
147 | string tmp = normalizeEndLines.Replace(pModelResult["loglines"].ToString(), "\n"); | ||
148 | string[] result = Regex.Split(tmp, "\n"); | ||
149 | for (int i = 0; i < result.Length; i++) | ||
150 | { | ||
151 | logLines.Add(new OSDString(result[i])); | ||
152 | } | ||
153 | logInfo.Add("logLines", logLines); | ||
154 | return logInfo.ToString(); | ||
155 | } | ||
156 | |||
128 | #endregion | 157 | #endregion |
129 | } | 158 | } |
130 | } | 159 | } |
diff --git a/OpenSim/Region/UserStatistics/Prototype_distributor.cs b/OpenSim/Region/OptionalModules/UserStatistics/Prototype_distributor.cs index 53ae557..6f8b2aa 100644 --- a/OpenSim/Region/UserStatistics/Prototype_distributor.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/Prototype_distributor.cs | |||
@@ -36,7 +36,18 @@ namespace OpenSim.Region.UserStatistics | |||
36 | { | 36 | { |
37 | public class Prototype_distributor : IStatsController | 37 | public class Prototype_distributor : IStatsController |
38 | { | 38 | { |
39 | private string prototypejs=string.Empty; | 39 | private string jsFileName = "prototype.js"; |
40 | private string prototypejs = string.Empty; | ||
41 | |||
42 | public Prototype_distributor() | ||
43 | { | ||
44 | jsFileName = "prototype.js"; | ||
45 | } | ||
46 | |||
47 | public Prototype_distributor(string jsName) | ||
48 | { | ||
49 | jsFileName = jsName; | ||
50 | } | ||
40 | 51 | ||
41 | public string ReportName | 52 | public string ReportName |
42 | { | 53 | { |
@@ -45,20 +56,24 @@ namespace OpenSim.Region.UserStatistics | |||
45 | public Hashtable ProcessModel(Hashtable pParams) | 56 | public Hashtable ProcessModel(Hashtable pParams) |
46 | { | 57 | { |
47 | Hashtable pResult = new Hashtable(); | 58 | Hashtable pResult = new Hashtable(); |
48 | if (prototypejs.Length == 0) | 59 | pResult["js"] = jsFileName; |
60 | return pResult; | ||
61 | } | ||
62 | |||
63 | public string RenderView(Hashtable pModelResult) | ||
64 | { | ||
65 | string fileName = (string)pModelResult["js"]; | ||
66 | using (StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/" + fileName, FileMode.Open))) | ||
49 | { | 67 | { |
50 | StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open)); | ||
51 | prototypejs = fs.ReadToEnd(); | 68 | prototypejs = fs.ReadToEnd(); |
52 | fs.Close(); | 69 | fs.Close(); |
53 | fs.Dispose(); | ||
54 | } | 70 | } |
55 | pResult["js"] = prototypejs; | 71 | return prototypejs; |
56 | return pResult; | ||
57 | } | 72 | } |
58 | 73 | ||
59 | public string RenderView(Hashtable pModelResult) | 74 | public string RenderJson(Hashtable pModelResult) |
60 | { | 75 | { |
61 | return pModelResult["js"].ToString(); | 76 | return "{}"; |
62 | } | 77 | } |
63 | 78 | ||
64 | } | 79 | } |
diff --git a/OpenSim/Region/UserStatistics/Sessions_Report.cs b/OpenSim/Region/OptionalModules/UserStatistics/Sessions_Report.cs index 1a2d460..0e94912 100644 --- a/OpenSim/Region/UserStatistics/Sessions_Report.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/Sessions_Report.cs | |||
@@ -278,6 +278,11 @@ TD.align_top { vertical-align: top; } | |||
278 | public DateTime start_time; | 278 | public DateTime start_time; |
279 | } | 279 | } |
280 | 280 | ||
281 | public string RenderJson(Hashtable pModelResult) | ||
282 | { | ||
283 | return "{}"; | ||
284 | } | ||
281 | #endregion | 285 | #endregion |
282 | } | 286 | } |
287 | |||
283 | } | 288 | } |
diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/OptionalModules/UserStatistics/SimStatsAJAX.cs index 28051fb..06d9e91 100644 --- a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/SimStatsAJAX.cs | |||
@@ -32,6 +32,7 @@ using System.Reflection; | |||
32 | using System.Text; | 32 | using System.Text; |
33 | using Mono.Data.SqliteClient; | 33 | using Mono.Data.SqliteClient; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Framework.Monitoring; | 37 | using OpenSim.Framework.Monitoring; |
37 | 38 | ||
@@ -161,9 +162,6 @@ namespace OpenSim.Region.UserStatistics | |||
161 | output.Append("OthrMS"); | 162 | output.Append("OthrMS"); |
162 | HTMLUtil.TD_C(ref output); | 163 | HTMLUtil.TD_C(ref output); |
163 | HTMLUtil.TD_O(ref output, TDHeaderClass); | 164 | HTMLUtil.TD_O(ref output, TDHeaderClass); |
164 | output.Append("ScrLPS"); | ||
165 | HTMLUtil.TD_C(ref output); | ||
166 | HTMLUtil.TD_O(ref output, TDHeaderClass); | ||
167 | output.Append("OutPPS"); | 165 | output.Append("OutPPS"); |
168 | HTMLUtil.TD_C(ref output); | 166 | HTMLUtil.TD_C(ref output); |
169 | HTMLUtil.TD_O(ref output, TDHeaderClass); | 167 | HTMLUtil.TD_O(ref output, TDHeaderClass); |
@@ -193,9 +191,6 @@ namespace OpenSim.Region.UserStatistics | |||
193 | output.Append(sdata.OtherFrameTime); | 191 | output.Append(sdata.OtherFrameTime); |
194 | HTMLUtil.TD_C(ref output); | 192 | HTMLUtil.TD_C(ref output); |
195 | HTMLUtil.TD_O(ref output, TDDataClassCenter); | 193 | HTMLUtil.TD_O(ref output, TDDataClassCenter); |
196 | output.Append(sdata.ScriptLinesPerSecond); | ||
197 | HTMLUtil.TD_C(ref output); | ||
198 | HTMLUtil.TD_O(ref output, TDDataClassCenter); | ||
199 | output.Append(sdata.OutPacketsPerSecond); | 194 | output.Append(sdata.OutPacketsPerSecond); |
200 | HTMLUtil.TD_C(ref output); | 195 | HTMLUtil.TD_C(ref output); |
201 | HTMLUtil.TD_O(ref output, TDDataClassCenter); | 196 | HTMLUtil.TD_O(ref output, TDDataClassCenter); |
@@ -218,6 +213,64 @@ namespace OpenSim.Region.UserStatistics | |||
218 | return output.ToString(); | 213 | return output.ToString(); |
219 | } | 214 | } |
220 | 215 | ||
216 | /// <summary> | ||
217 | /// Return stat information for all regions in the sim. Returns data of the form: | ||
218 | /// <pre> | ||
219 | /// {"REGIONNAME": { | ||
220 | /// "region": "REGIONNAME", | ||
221 | /// "timeDilation": "101", | ||
222 | /// ... // the rest of the stat info | ||
223 | /// }, | ||
224 | /// ... // entries for each region | ||
225 | /// } | ||
226 | /// </pre> | ||
227 | /// </summary> | ||
228 | /// <param name="pModelResult"></param> | ||
229 | /// <returns></returns> | ||
230 | public string RenderJson(Hashtable pModelResult) | ||
231 | { | ||
232 | List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"]; | ||
233 | Dictionary<UUID, USimStatsData> sdatadic = (Dictionary<UUID,USimStatsData>)pModelResult["simstats"]; | ||
234 | |||
235 | OSDMap allStatsInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
236 | foreach (USimStatsData sdata in sdatadic.Values) | ||
237 | { | ||
238 | OSDMap statsInfo = new OpenMetaverse.StructuredData.OSDMap(); | ||
239 | string regionName = "unknown"; | ||
240 | foreach (Scene sn in all_scenes) | ||
241 | { | ||
242 | if (sn.RegionInfo.RegionID == sdata.RegionId) | ||
243 | { | ||
244 | regionName = sn.RegionInfo.RegionName; | ||
245 | break; | ||
246 | } | ||
247 | } | ||
248 | statsInfo.Add("region", new OSDString(regionName)); | ||
249 | statsInfo.Add("timeDilation", new OSDString(sdata.TimeDilation.ToString())); | ||
250 | statsInfo.Add("simFPS", new OSDString(sdata.SimFps.ToString())); | ||
251 | statsInfo.Add("physicsFPS", new OSDString(sdata.PhysicsFps.ToString())); | ||
252 | statsInfo.Add("agentUpdates", new OSDString(sdata.AgentUpdates.ToString())); | ||
253 | statsInfo.Add("rootAgents", new OSDString(sdata.RootAgents.ToString())); | ||
254 | statsInfo.Add("childAgents", new OSDString(sdata.ChildAgents.ToString())); | ||
255 | statsInfo.Add("totalPrims", new OSDString(sdata.TotalPrims.ToString())); | ||
256 | statsInfo.Add("activePrims", new OSDString(sdata.ActivePrims.ToString())); | ||
257 | statsInfo.Add("activeScripts", new OSDString(sdata.ActiveScripts.ToString())); | ||
258 | statsInfo.Add("scriptLinesPerSec", new OSDString(sdata.ScriptLinesPerSecond.ToString())); | ||
259 | statsInfo.Add("totalFrameTime", new OSDString(sdata.TotalFrameTime.ToString())); | ||
260 | statsInfo.Add("agentFrameTime", new OSDString(sdata.AgentFrameTime.ToString())); | ||
261 | statsInfo.Add("physicsFrameTime", new OSDString(sdata.PhysicsFrameTime.ToString())); | ||
262 | statsInfo.Add("otherFrameTime", new OSDString(sdata.OtherFrameTime.ToString())); | ||
263 | statsInfo.Add("outPacketsPerSec", new OSDString(sdata.OutPacketsPerSecond.ToString())); | ||
264 | statsInfo.Add("inPacketsPerSec", new OSDString(sdata.InPacketsPerSecond.ToString())); | ||
265 | statsInfo.Add("unackedByptes", new OSDString(sdata.UnackedBytes.ToString())); | ||
266 | statsInfo.Add("pendingDownloads", new OSDString(sdata.PendingDownloads.ToString())); | ||
267 | statsInfo.Add("pendingUploads", new OSDString(sdata.PendingUploads.ToString())); | ||
268 | |||
269 | allStatsInfo.Add(regionName, statsInfo); | ||
270 | } | ||
271 | return allStatsInfo.ToString(); | ||
272 | } | ||
273 | |||
221 | #endregion | 274 | #endregion |
222 | } | 275 | } |
223 | } | 276 | } |
diff --git a/OpenSim/Region/UserStatistics/Updater_distributor.cs b/OpenSim/Region/OptionalModules/UserStatistics/Updater_distributor.cs index 9593cc9..601e06b 100644 --- a/OpenSim/Region/UserStatistics/Updater_distributor.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/Updater_distributor.cs | |||
@@ -62,5 +62,9 @@ namespace OpenSim.Region.UserStatistics | |||
62 | return pModelResult["js"].ToString(); | 62 | return pModelResult["js"].ToString(); |
63 | } | 63 | } |
64 | 64 | ||
65 | public string RenderJson(Hashtable pModelResult) { | ||
66 | return "{}"; | ||
67 | } | ||
68 | |||
65 | } | 69 | } |
66 | } \ No newline at end of file | 70 | } \ No newline at end of file |
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/OptionalModules/UserStatistics/WebStatsModule.cs index 64cb577..bcb6361 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/OptionalModules/UserStatistics/WebStatsModule.cs | |||
@@ -50,9 +50,6 @@ using Caps = OpenSim.Framework.Capabilities.Caps; | |||
50 | using OSD = OpenMetaverse.StructuredData.OSD; | 50 | using OSD = OpenMetaverse.StructuredData.OSD; |
51 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | 51 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; |
52 | 52 | ||
53 | [assembly: Addin("WebStats", "1.0")] | ||
54 | [assembly: AddinDependency("OpenSim", "0.5")] | ||
55 | |||
56 | namespace OpenSim.Region.UserStatistics | 53 | namespace OpenSim.Region.UserStatistics |
57 | { | 54 | { |
58 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebStatsModule")] | 55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebStatsModule")] |
@@ -121,6 +118,10 @@ namespace OpenSim.Region.UserStatistics | |||
121 | reports.Add("clients.report", clientReport); | 118 | reports.Add("clients.report", clientReport); |
122 | reports.Add("sessions.report", sessionsReport); | 119 | reports.Add("sessions.report", sessionsReport); |
123 | 120 | ||
121 | reports.Add("sim.css", new Prototype_distributor("sim.css")); | ||
122 | reports.Add("sim.html", new Prototype_distributor("sim.html")); | ||
123 | reports.Add("jquery.js", new Prototype_distributor("jquery.js")); | ||
124 | |||
124 | //// | 125 | //// |
125 | // Add Your own Reports here (Do Not Modify Lines here Devs!) | 126 | // Add Your own Reports here (Do Not Modify Lines here Devs!) |
126 | //// | 127 | //// |
@@ -255,9 +256,12 @@ namespace OpenSim.Region.UserStatistics | |||
255 | string regpath = request["uri"].ToString(); | 256 | string regpath = request["uri"].ToString(); |
256 | int response_code = 404; | 257 | int response_code = 404; |
257 | string contenttype = "text/html"; | 258 | string contenttype = "text/html"; |
259 | bool jsonFormatOutput = false; | ||
258 | 260 | ||
259 | string strOut = string.Empty; | 261 | string strOut = string.Empty; |
260 | 262 | ||
263 | // The request patch should be "/SStats/reportName" where 'reportName' | ||
264 | // is one of the names added to the 'reports' hashmap. | ||
261 | regpath = regpath.Remove(0, 8); | 265 | regpath = regpath.Remove(0, 8); |
262 | if (regpath.Length == 0) regpath = "default.report"; | 266 | if (regpath.Length == 0) regpath = "default.report"; |
263 | if (reports.ContainsKey(regpath)) | 267 | if (reports.ContainsKey(regpath)) |
@@ -265,6 +269,9 @@ namespace OpenSim.Region.UserStatistics | |||
265 | IStatsController rep = reports[regpath]; | 269 | IStatsController rep = reports[regpath]; |
266 | Hashtable repParams = new Hashtable(); | 270 | Hashtable repParams = new Hashtable(); |
267 | 271 | ||
272 | if (request.ContainsKey("json")) | ||
273 | jsonFormatOutput = true; | ||
274 | |||
268 | if (request.ContainsKey("requestvars")) | 275 | if (request.ContainsKey("requestvars")) |
269 | repParams["RequestVars"] = request["requestvars"]; | 276 | repParams["RequestVars"] = request["requestvars"]; |
270 | else | 277 | else |
@@ -284,13 +291,26 @@ namespace OpenSim.Region.UserStatistics | |||
284 | 291 | ||
285 | concurrencyCounter++; | 292 | concurrencyCounter++; |
286 | 293 | ||
287 | strOut = rep.RenderView(rep.ProcessModel(repParams)); | 294 | if (jsonFormatOutput) |
295 | { | ||
296 | strOut = rep.RenderJson(rep.ProcessModel(repParams)); | ||
297 | contenttype = "text/json"; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | strOut = rep.RenderView(rep.ProcessModel(repParams)); | ||
302 | } | ||
288 | 303 | ||
289 | if (regpath.EndsWith("js")) | 304 | if (regpath.EndsWith("js")) |
290 | { | 305 | { |
291 | contenttype = "text/javascript"; | 306 | contenttype = "text/javascript"; |
292 | } | 307 | } |
293 | 308 | ||
309 | if (regpath.EndsWith("css")) | ||
310 | { | ||
311 | contenttype = "text/css"; | ||
312 | } | ||
313 | |||
294 | concurrencyCounter--; | 314 | concurrencyCounter--; |
295 | 315 | ||
296 | response_code = 200; | 316 | response_code = 200; |
@@ -397,7 +417,7 @@ namespace OpenSim.Region.UserStatistics | |||
397 | Encoding encoding = Encoding.ASCII; | 417 | Encoding encoding = Encoding.ASCII; |
398 | int sizeOfChar = encoding.GetByteCount("\n"); | 418 | int sizeOfChar = encoding.GetByteCount("\n"); |
399 | byte[] buffer = encoding.GetBytes("\n"); | 419 | byte[] buffer = encoding.GetBytes("\n"); |
400 | string logfile = Util.logDir() + "/" + "OpenSim.log"; | 420 | string logfile = Util.logFile(); |
401 | FileStream fs = new FileStream(logfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); | 421 | FileStream fs = new FileStream(logfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); |
402 | Int64 tokenCount = 0; | 422 | Int64 tokenCount = 0; |
403 | Int64 endPosition = fs.Length / sizeOfChar; | 423 | Int64 endPosition = fs.Length / sizeOfChar; |
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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Threading; | ||
34 | |||
35 | using OpenMetaverse; | ||
36 | using OpenMetaverse.StructuredData; | ||
37 | using OpenSim; | ||
38 | using OpenSim.Region; | ||
39 | using OpenSim.Region.Framework; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Framework; | ||
43 | //using OpenSim.Framework.Capabilities; | ||
44 | using OpenSim.Framework.Servers; | ||
45 | using OpenSim.Framework.Servers.HttpServer; | ||
46 | using Nini.Config; | ||
47 | using log4net; | ||
48 | using Mono.Addins; | ||
49 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
50 | using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags; | ||
51 | |||
52 | namespace 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/DynamicFloaterModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs new file mode 100644 index 0000000..e76e8f2 --- /dev/null +++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs | |||
@@ -0,0 +1,238 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Collections.Generic; | ||
33 | using OpenMetaverse; | ||
34 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim; | ||
36 | using OpenSim.Region; | ||
37 | using OpenSim.Region.Framework; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Framework.Servers; | ||
42 | using OpenSim.Framework.Servers.HttpServer; | ||
43 | using Nini.Config; | ||
44 | using log4net; | ||
45 | using Mono.Addins; | ||
46 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
47 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
48 | |||
49 | namespace OpenSim.Region.OptionalModules.ViewerSupport | ||
50 | { | ||
51 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicFloater")] | ||
52 | public class DynamicFloaterModule : INonSharedRegionModule, IDynamicFloaterModule | ||
53 | { | ||
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
55 | |||
56 | private Scene m_scene; | ||
57 | |||
58 | private Dictionary<UUID, Dictionary<int, FloaterData>> m_floaters = new Dictionary<UUID, Dictionary<int, FloaterData>>(); | ||
59 | |||
60 | public string Name | ||
61 | { | ||
62 | get { return "DynamicFloaterModule"; } | ||
63 | } | ||
64 | |||
65 | public Type ReplaceableInterface | ||
66 | { | ||
67 | get { return null; } | ||
68 | } | ||
69 | |||
70 | public void Initialise(IConfigSource config) | ||
71 | { | ||
72 | } | ||
73 | |||
74 | public void Close() | ||
75 | { | ||
76 | } | ||
77 | |||
78 | public void AddRegion(Scene scene) | ||
79 | { | ||
80 | m_scene = scene; | ||
81 | scene.EventManager.OnNewClient += OnNewClient; | ||
82 | scene.EventManager.OnClientClosed += OnClientClosed; | ||
83 | m_scene.RegisterModuleInterface<IDynamicFloaterModule>(this); | ||
84 | } | ||
85 | |||
86 | public void RegionLoaded(Scene scene) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | public void RemoveRegion(Scene scene) | ||
91 | { | ||
92 | } | ||
93 | |||
94 | private void OnNewClient(IClientAPI client) | ||
95 | { | ||
96 | client.OnChatFromClient += OnChatFromClient; | ||
97 | } | ||
98 | |||
99 | private void OnClientClosed(UUID agentID, Scene scene) | ||
100 | { | ||
101 | m_floaters.Remove(agentID); | ||
102 | } | ||
103 | |||
104 | private void SendToClient(ScenePresence sp, string msg) | ||
105 | { | ||
106 | sp.ControllingClient.SendChatMessage(msg, | ||
107 | (byte)ChatTypeEnum.Owner, | ||
108 | sp.AbsolutePosition, | ||
109 | "Server", | ||
110 | UUID.Zero, | ||
111 | UUID.Zero, | ||
112 | (byte)ChatSourceType.Object, | ||
113 | (byte)ChatAudibleLevel.Fully); | ||
114 | } | ||
115 | |||
116 | public void DoUserFloater(UUID agentID, FloaterData dialogData, string configuration) | ||
117 | { | ||
118 | ScenePresence sp = m_scene.GetScenePresence(agentID); | ||
119 | if (sp == null || sp.IsChildAgent) | ||
120 | return; | ||
121 | |||
122 | if (!m_floaters.ContainsKey(agentID)) | ||
123 | m_floaters[agentID] = new Dictionary<int, FloaterData>(); | ||
124 | |||
125 | if (m_floaters[agentID].ContainsKey(dialogData.Channel)) | ||
126 | return; | ||
127 | |||
128 | m_floaters[agentID].Add(dialogData.Channel, dialogData); | ||
129 | |||
130 | string xml; | ||
131 | if (dialogData.XmlText != null && dialogData.XmlText != String.Empty) | ||
132 | { | ||
133 | xml = dialogData.XmlText; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | using (FileStream fs = File.Open(dialogData.XmlName + ".xml", FileMode.Open)) | ||
138 | { | ||
139 | using (StreamReader sr = new StreamReader(fs)) | ||
140 | xml = sr.ReadToEnd().Replace("\n", ""); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | List<string> xparts = new List<string>(); | ||
145 | |||
146 | while (xml.Length > 0) | ||
147 | { | ||
148 | string x = xml; | ||
149 | if (x.Length > 600) | ||
150 | { | ||
151 | x = x.Substring(0, 600); | ||
152 | xml = xml.Substring(600); | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | xml = String.Empty; | ||
157 | } | ||
158 | |||
159 | xparts.Add(x); | ||
160 | } | ||
161 | |||
162 | for (int i = 0 ; i < xparts.Count ; i++) | ||
163 | SendToClient(sp, String.Format("># floater {2} create {0}/{1} " + xparts[i], i + 1, xparts.Count, dialogData.FloaterName)); | ||
164 | |||
165 | SendToClient(sp, String.Format("># floater {0} {{notify:1}} {{channel: {1}}} {{node:cancel {{notify:1}}}} {{node:ok {{notify:1}}}} {2}", dialogData.FloaterName, (uint)dialogData.Channel, configuration)); | ||
166 | } | ||
167 | |||
168 | private void OnChatFromClient(object sender, OSChatMessage msg) | ||
169 | { | ||
170 | if (msg.Sender == null) | ||
171 | return; | ||
172 | |||
173 | //m_log.DebugFormat("chan {0} msg {1}", msg.Channel, msg.Message); | ||
174 | |||
175 | IClientAPI client = msg.Sender; | ||
176 | |||
177 | if (!m_floaters.ContainsKey(client.AgentId)) | ||
178 | return; | ||
179 | |||
180 | string[] parts = msg.Message.Split(new char[] {':'}); | ||
181 | if (parts.Length == 0) | ||
182 | return; | ||
183 | |||
184 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | ||
185 | if (sp == null || sp.IsChildAgent) | ||
186 | return; | ||
187 | |||
188 | Dictionary<int, FloaterData> d = m_floaters[client.AgentId]; | ||
189 | |||
190 | // Work around a viewer bug - VALUE from any | ||
191 | // dialog can appear on this channel and needs to | ||
192 | // be dispatched to ALL open dialogs for the user | ||
193 | if (msg.Channel == 427169570) | ||
194 | { | ||
195 | if (parts[0] == "VALUE") | ||
196 | { | ||
197 | foreach (FloaterData dd in d.Values) | ||
198 | { | ||
199 | if(dd.Handler(client, dd, parts)) | ||
200 | { | ||
201 | m_floaters[client.AgentId].Remove(dd.Channel); | ||
202 | SendToClient(sp, String.Format("># floater {0} destroy", dd.FloaterName)); | ||
203 | break; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | if (!d.ContainsKey(msg.Channel)) | ||
211 | return; | ||
212 | |||
213 | FloaterData data = d[msg.Channel]; | ||
214 | |||
215 | if (parts[0] == "NOTIFY") | ||
216 | { | ||
217 | if (parts[1] == "cancel" || parts[1] == data.FloaterName) | ||
218 | { | ||
219 | m_floaters[client.AgentId].Remove(data.Channel); | ||
220 | SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName)); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | if (data.Handler != null && data.Handler(client, data, parts)) | ||
225 | { | ||
226 | m_floaters[client.AgentId].Remove(data.Channel); | ||
227 | SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName)); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | public void FloaterControl(ScenePresence sp, FloaterData d, string msg) | ||
232 | { | ||
233 | string sendData = String.Format("># floater {0} {1}", d.FloaterName, msg); | ||
234 | SendToClient(sp, sendData); | ||
235 | |||
236 | } | ||
237 | } | ||
238 | } | ||
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs new file mode 100644 index 0000000..d37369c --- /dev/null +++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs | |||
@@ -0,0 +1,304 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Collections.Generic; | ||
33 | using OpenMetaverse; | ||
34 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim; | ||
36 | using OpenSim.Region; | ||
37 | using OpenSim.Region.Framework; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Framework; | ||
41 | //using OpenSim.Framework.Capabilities; | ||
42 | using OpenSim.Framework.Servers; | ||
43 | using OpenSim.Framework.Servers.HttpServer; | ||
44 | using Nini.Config; | ||
45 | using log4net; | ||
46 | using Mono.Addins; | ||
47 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
48 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
49 | |||
50 | namespace OpenSim.Region.OptionalModules.ViewerSupport | ||
51 | { | ||
52 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicMenu")] | ||
53 | public class DynamicMenuModule : INonSharedRegionModule, IDynamicMenuModule | ||
54 | { | ||
55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
56 | |||
57 | private class MenuItemData | ||
58 | { | ||
59 | public string Title; | ||
60 | public UUID AgentID; | ||
61 | public InsertLocation Location; | ||
62 | public UserMode Mode; | ||
63 | public CustomMenuHandler Handler; | ||
64 | } | ||
65 | |||
66 | private Dictionary<UUID, List<MenuItemData>> m_menuItems = | ||
67 | new Dictionary<UUID, List<MenuItemData>>(); | ||
68 | |||
69 | private Scene m_scene; | ||
70 | |||
71 | public string Name | ||
72 | { | ||
73 | get { return "DynamicMenuModule"; } | ||
74 | } | ||
75 | |||
76 | public Type ReplaceableInterface | ||
77 | { | ||
78 | get { return null; } | ||
79 | } | ||
80 | |||
81 | public void Initialise(IConfigSource config) | ||
82 | { | ||
83 | } | ||
84 | |||
85 | public void Close() | ||
86 | { | ||
87 | } | ||
88 | |||
89 | public void AddRegion(Scene scene) | ||
90 | { | ||
91 | m_scene = scene; | ||
92 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | ||
93 | m_scene.RegisterModuleInterface<IDynamicMenuModule>(this); | ||
94 | } | ||
95 | |||
96 | public void RegionLoaded(Scene scene) | ||
97 | { | ||
98 | ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface<ISimulatorFeaturesModule>(); | ||
99 | |||
100 | if (featuresModule != null) | ||
101 | featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; | ||
102 | } | ||
103 | |||
104 | public void RemoveRegion(Scene scene) | ||
105 | { | ||
106 | } | ||
107 | |||
108 | private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) | ||
109 | { | ||
110 | OSD menus = new OSDMap(); | ||
111 | if (features.ContainsKey("menus")) | ||
112 | menus = features["menus"]; | ||
113 | |||
114 | OSDMap agent = new OSDMap(); | ||
115 | OSDMap world = new OSDMap(); | ||
116 | OSDMap tools = new OSDMap(); | ||
117 | OSDMap advanced = new OSDMap(); | ||
118 | OSDMap admin = new OSDMap(); | ||
119 | if (((OSDMap)menus).ContainsKey("agent")) | ||
120 | agent = (OSDMap)((OSDMap)menus)["agent"]; | ||
121 | if (((OSDMap)menus).ContainsKey("world")) | ||
122 | world = (OSDMap)((OSDMap)menus)["world"]; | ||
123 | if (((OSDMap)menus).ContainsKey("tools")) | ||
124 | tools = (OSDMap)((OSDMap)menus)["tools"]; | ||
125 | if (((OSDMap)menus).ContainsKey("advanced")) | ||
126 | advanced = (OSDMap)((OSDMap)menus)["advanced"]; | ||
127 | if (((OSDMap)menus).ContainsKey("admin")) | ||
128 | admin = (OSDMap)((OSDMap)menus)["admin"]; | ||
129 | |||
130 | if (m_menuItems.ContainsKey(UUID.Zero)) | ||
131 | { | ||
132 | foreach (MenuItemData d in m_menuItems[UUID.Zero]) | ||
133 | { | ||
134 | if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID))) | ||
135 | continue; | ||
136 | |||
137 | OSDMap loc = null; | ||
138 | switch (d.Location) | ||
139 | { | ||
140 | case InsertLocation.Agent: | ||
141 | loc = agent; | ||
142 | break; | ||
143 | case InsertLocation.World: | ||
144 | loc = world; | ||
145 | break; | ||
146 | case InsertLocation.Tools: | ||
147 | loc = tools; | ||
148 | break; | ||
149 | case InsertLocation.Advanced: | ||
150 | loc = advanced; | ||
151 | break; | ||
152 | case InsertLocation.Admin: | ||
153 | loc = admin; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | if (loc == null) | ||
158 | continue; | ||
159 | |||
160 | loc[d.Title] = OSD.FromString(d.Title); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | if (m_menuItems.ContainsKey(agentID)) | ||
165 | { | ||
166 | foreach (MenuItemData d in m_menuItems[agentID]) | ||
167 | { | ||
168 | if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID))) | ||
169 | continue; | ||
170 | |||
171 | OSDMap loc = null; | ||
172 | switch (d.Location) | ||
173 | { | ||
174 | case InsertLocation.Agent: | ||
175 | loc = agent; | ||
176 | break; | ||
177 | case InsertLocation.World: | ||
178 | loc = world; | ||
179 | break; | ||
180 | case InsertLocation.Tools: | ||
181 | loc = tools; | ||
182 | break; | ||
183 | case InsertLocation.Advanced: | ||
184 | loc = advanced; | ||
185 | break; | ||
186 | case InsertLocation.Admin: | ||
187 | loc = admin; | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | if (loc == null) | ||
192 | continue; | ||
193 | |||
194 | loc[d.Title] = OSD.FromString(d.Title); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | |||
199 | ((OSDMap)menus)["agent"] = agent; | ||
200 | ((OSDMap)menus)["world"] = world; | ||
201 | ((OSDMap)menus)["tools"] = tools; | ||
202 | ((OSDMap)menus)["advanced"] = advanced; | ||
203 | ((OSDMap)menus)["admin"] = admin; | ||
204 | |||
205 | features["menus"] = menus; | ||
206 | } | ||
207 | |||
208 | private void OnRegisterCaps(UUID agentID, Caps caps) | ||
209 | { | ||
210 | string capUrl = "/CAPS/" + UUID.Random() + "/"; | ||
211 | |||
212 | capUrl = "/CAPS/" + UUID.Random() + "/"; | ||
213 | caps.RegisterHandler("CustomMenuAction", new MenuActionHandler(capUrl, "CustomMenuAction", agentID, this, m_scene)); | ||
214 | } | ||
215 | |||
216 | internal void HandleMenuSelection(string action, UUID agentID, List<uint> selection) | ||
217 | { | ||
218 | if (m_menuItems.ContainsKey(agentID)) | ||
219 | { | ||
220 | foreach (MenuItemData d in m_menuItems[agentID]) | ||
221 | { | ||
222 | if (d.Title == action) | ||
223 | d.Handler(action, agentID, selection); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | if (m_menuItems.ContainsKey(UUID.Zero)) | ||
228 | { | ||
229 | foreach (MenuItemData d in m_menuItems[UUID.Zero]) | ||
230 | { | ||
231 | if (d.Title == action) | ||
232 | d.Handler(action, agentID, selection); | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | public void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler) | ||
238 | { | ||
239 | AddMenuItem(UUID.Zero, title, location, mode, handler); | ||
240 | } | ||
241 | |||
242 | public void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler) | ||
243 | { | ||
244 | if (!m_menuItems.ContainsKey(agentID)) | ||
245 | m_menuItems[agentID] = new List<MenuItemData>(); | ||
246 | |||
247 | m_menuItems[agentID].Add(new MenuItemData() { Title = title, AgentID = agentID, Location = location, Mode = mode, Handler = handler }); | ||
248 | } | ||
249 | |||
250 | public void RemoveMenuItem(string action) | ||
251 | { | ||
252 | foreach (KeyValuePair<UUID,List< MenuItemData>> kvp in m_menuItems) | ||
253 | { | ||
254 | List<MenuItemData> pendingDeletes = new List<MenuItemData>(); | ||
255 | foreach (MenuItemData d in kvp.Value) | ||
256 | { | ||
257 | if (d.Title == action) | ||
258 | pendingDeletes.Add(d); | ||
259 | } | ||
260 | |||
261 | foreach (MenuItemData d in pendingDeletes) | ||
262 | kvp.Value.Remove(d); | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | public class MenuActionHandler : BaseStreamHandler | ||
268 | { | ||
269 | private static readonly ILog m_log = | ||
270 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
271 | |||
272 | private UUID m_agentID; | ||
273 | private Scene m_scene; | ||
274 | private DynamicMenuModule m_module; | ||
275 | |||
276 | public MenuActionHandler(string path, string name, UUID agentID, DynamicMenuModule module, Scene scene) | ||
277 | :base("POST", path, name, agentID.ToString()) | ||
278 | { | ||
279 | m_agentID = agentID; | ||
280 | m_scene = scene; | ||
281 | m_module = module; | ||
282 | } | ||
283 | |||
284 | protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
285 | { | ||
286 | StreamReader reader = new StreamReader(request); | ||
287 | string requestBody = reader.ReadToEnd(); | ||
288 | |||
289 | OSD osd = OSDParser.DeserializeLLSDXml(requestBody); | ||
290 | |||
291 | string action = ((OSDMap)osd)["action"].AsString(); | ||
292 | OSDArray selection = (OSDArray)((OSDMap)osd)["selection"]; | ||
293 | List<uint> sel = new List<uint>(); | ||
294 | for (int i = 0 ; i < selection.Count ; i++) | ||
295 | sel.Add(selection[i].AsUInteger()); | ||
296 | |||
297 | Util.FireAndForget( | ||
298 | x => { m_module.HandleMenuSelection(action, m_agentID, sel); }, null, "DynamicMenuModule.HandleMenuSelection"); | ||
299 | |||
300 | Encoding encoding = Encoding.UTF8; | ||
301 | return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); | ||
302 | } | ||
303 | } | ||
304 | } | ||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using Mono.Addins; | ||
33 | using Nini.Config; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.StructuredData; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | |||
40 | namespace 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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Threading; | ||
34 | |||
35 | using OpenMetaverse; | ||
36 | using OpenMetaverse.StructuredData; | ||
37 | using OpenSim; | ||
38 | using OpenSim.Region; | ||
39 | using OpenSim.Region.Framework; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Framework; | ||
43 | using OpenSim.Services.Interfaces; | ||
44 | //using OpenSim.Framework.Capabilities; | ||
45 | using Nini.Config; | ||
46 | using log4net; | ||
47 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
48 | using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags; | ||
49 | |||
50 | namespace 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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Threading; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.StructuredData; | ||
36 | using OpenSim; | ||
37 | using OpenSim.Region; | ||
38 | using OpenSim.Region.Framework; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Framework; | ||
42 | //using OpenSim.Framework.Capabilities; | ||
43 | using OpenSim.Framework.Servers; | ||
44 | using OpenSim.Framework.Servers.HttpServer; | ||
45 | using Nini.Config; | ||
46 | using log4net; | ||
47 | using Mono.Addins; | ||
48 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
49 | using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags; | ||
50 | |||
51 | namespace 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 a999b7f..4cd5676 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 | { |
@@ -191,9 +193,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
191 | // Please do not refactor these to be just one method | 193 | // Please do not refactor these to be just one method |
192 | // Existing implementations need the distinction | 194 | // Existing implementations need the distinction |
193 | // | 195 | // |
194 | public void ApplyCharge(UUID agentID, int amount, string text) | 196 | public void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData) |
195 | { | 197 | { |
196 | } | 198 | } |
199 | |||
200 | public void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type) | ||
201 | { | ||
202 | } | ||
203 | |||
197 | public void ApplyUploadCharge(UUID agentID, int amount, string text) | 204 | public void ApplyUploadCharge(UUID agentID, int amount, string text) |
198 | { | 205 | { |
199 | } | 206 | } |
@@ -322,7 +329,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
322 | client.SendAlertMessage(e.Message + " "); | 329 | client.SendAlertMessage(e.Message + " "); |
323 | } | 330 | } |
324 | 331 | ||
325 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); | 332 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds, 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty); |
326 | } | 333 | } |
327 | else | 334 | else |
328 | { | 335 | { |
@@ -385,12 +392,12 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
385 | { | 392 | { |
386 | if (sender != null) | 393 | if (sender != null) |
387 | { | 394 | { |
388 | sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID)); | 395 | sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty); |
389 | } | 396 | } |
390 | 397 | ||
391 | if (receiver != null) | 398 | if (receiver != null) |
392 | { | 399 | { |
393 | receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID)); | 400 | receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty); |
394 | } | 401 | } |
395 | } | 402 | } |
396 | } | 403 | } |
@@ -555,7 +562,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
555 | /// <returns></returns> | 562 | /// <returns></returns> |
556 | private int GetFundsForAgentID(UUID AgentID) | 563 | private int GetFundsForAgentID(UUID AgentID) |
557 | { | 564 | { |
558 | int returnfunds = 75004; // Set it to the OpenSim version, plus the IG build number. Muahahaha; | 565 | int returnfunds = 0; |
559 | 566 | ||
560 | return returnfunds; | 567 | return returnfunds; |
561 | } | 568 | } |
@@ -688,19 +695,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
688 | /// Event called Economy Data Request handler. | 695 | /// Event called Economy Data Request handler. |
689 | /// </summary> | 696 | /// </summary> |
690 | /// <param name="agentId"></param> | 697 | /// <param name="agentId"></param> |
691 | public void EconomyDataRequestHandler(UUID agentId) | 698 | public void EconomyDataRequestHandler(IClientAPI user) |
692 | { | 699 | { |
693 | IClientAPI user = LocateClientObject(agentId); | 700 | Scene s = (Scene)user.Scene; |
694 | 701 | ||
695 | if (user != null) | 702 | user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, |
696 | { | 703 | PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, |
697 | Scene s = LocateSceneClientIn(user.AgentId); | 704 | PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, |
698 | 705 | TeleportMinPrice, TeleportPriceExponent); | |
699 | user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, | ||
700 | PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, | ||
701 | PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, | ||
702 | TeleportMinPrice, TeleportPriceExponent); | ||
703 | } | ||
704 | } | 706 | } |
705 | 707 | ||
706 | private void ValidateLandBuy(Object osender, EventManager.LandBuyArgs e) | 708 | private void ValidateLandBuy(Object osender, EventManager.LandBuyArgs e) |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 5ea2bcd..fb644b7 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -44,10 +44,24 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
44 | { | 44 | { |
45 | public bool SenseAsAgent { get; set; } | 45 | public bool SenseAsAgent { get; set; } |
46 | 46 | ||
47 | public delegate void ChatToNPC( | ||
48 | string message, byte type, Vector3 fromPos, string fromName, | ||
49 | UUID fromAgentID, UUID ownerID, byte source, byte audible); | ||
50 | |||
51 | /// <summary> | ||
52 | /// Fired when the NPC receives a chat message. | ||
53 | /// </summary> | ||
54 | public event ChatToNPC OnChatToNPC; | ||
55 | |||
56 | /// <summary> | ||
57 | /// Fired when the NPC receives an instant message. | ||
58 | /// </summary> | ||
59 | public event Action<GridInstantMessage> OnInstantMessageToNPC; | ||
60 | |||
47 | private readonly string m_firstname; | 61 | private readonly string m_firstname; |
48 | private readonly string m_lastname; | 62 | private readonly string m_lastname; |
49 | private readonly Vector3 m_startPos; | 63 | private readonly Vector3 m_startPos; |
50 | private readonly UUID m_uuid = UUID.Random(); | 64 | private readonly UUID m_uuid; |
51 | private readonly Scene m_scene; | 65 | private readonly Scene m_scene; |
52 | private readonly UUID m_ownerID; | 66 | private readonly UUID m_ownerID; |
53 | 67 | ||
@@ -57,6 +71,19 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
57 | m_firstname = firstname; | 71 | m_firstname = firstname; |
58 | m_lastname = lastname; | 72 | m_lastname = lastname; |
59 | m_startPos = position; | 73 | m_startPos = position; |
74 | m_uuid = UUID.Random(); | ||
75 | m_scene = scene; | ||
76 | m_ownerID = ownerID; | ||
77 | SenseAsAgent = senseAsAgent; | ||
78 | } | ||
79 | |||
80 | public NPCAvatar( | ||
81 | string firstname, string lastname, UUID agentID, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene) | ||
82 | { | ||
83 | m_firstname = firstname; | ||
84 | m_lastname = lastname; | ||
85 | m_startPos = position; | ||
86 | m_uuid = agentID; | ||
60 | m_scene = scene; | 87 | m_scene = scene; |
61 | m_ownerID = ownerID; | 88 | m_ownerID = ownerID; |
62 | SenseAsAgent = senseAsAgent; | 89 | SenseAsAgent = senseAsAgent; |
@@ -258,6 +285,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
258 | public event Action<IClientAPI, bool> OnCompleteMovementToRegion; | 285 | public event Action<IClientAPI, bool> OnCompleteMovementToRegion; |
259 | public event UpdateAgent OnPreAgentUpdate; | 286 | public event UpdateAgent OnPreAgentUpdate; |
260 | public event UpdateAgent OnAgentUpdate; | 287 | public event UpdateAgent OnAgentUpdate; |
288 | public event UpdateAgent OnAgentCameraUpdate; | ||
261 | public event AgentRequestSit OnAgentRequestSit; | 289 | public event AgentRequestSit OnAgentRequestSit; |
262 | public event AgentSit OnAgentSit; | 290 | public event AgentSit OnAgentSit; |
263 | public event AvatarPickerRequest OnAvatarPickerRequest; | 291 | public event AvatarPickerRequest OnAvatarPickerRequest; |
@@ -391,6 +419,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
391 | public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest; | 419 | public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest; |
392 | public event EstateChangeInfo OnEstateChangeInfo; | 420 | public event EstateChangeInfo OnEstateChangeInfo; |
393 | public event EstateManageTelehub OnEstateManageTelehub; | 421 | public event EstateManageTelehub OnEstateManageTelehub; |
422 | public event CachedTextureRequest OnCachedTextureRequest; | ||
394 | public event ScriptReset OnScriptReset; | 423 | public event ScriptReset OnScriptReset; |
395 | public event GetScriptRunning OnGetScriptRunning; | 424 | public event GetScriptRunning OnGetScriptRunning; |
396 | public event SetScriptRunning OnSetScriptRunning; | 425 | public event SetScriptRunning OnSetScriptRunning; |
@@ -569,6 +598,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
569 | { | 598 | { |
570 | } | 599 | } |
571 | 600 | ||
601 | public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures) | ||
602 | { | ||
603 | |||
604 | } | ||
605 | |||
572 | public virtual void Kick(string message) | 606 | public virtual void Kick(string message) |
573 | { | 607 | { |
574 | } | 608 | } |
@@ -586,7 +620,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
586 | 620 | ||
587 | } | 621 | } |
588 | 622 | ||
589 | public virtual void SendKillObject(ulong regionHandle, List<uint> localID) | 623 | public virtual void SendKillObject(List<uint> localID) |
590 | { | 624 | { |
591 | } | 625 | } |
592 | 626 | ||
@@ -607,25 +641,26 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
607 | string message, byte type, Vector3 fromPos, string fromName, | 641 | string message, byte type, Vector3 fromPos, string fromName, |
608 | UUID fromAgentID, UUID ownerID, byte source, byte audible) | 642 | UUID fromAgentID, UUID ownerID, byte source, byte audible) |
609 | { | 643 | { |
610 | } | 644 | ChatToNPC ctn = OnChatToNPC; |
611 | 645 | ||
612 | public virtual void SendChatMessage( | 646 | if (ctn != null) |
613 | byte[] message, byte type, Vector3 fromPos, string fromName, | 647 | ctn(message, type, fromPos, fromName, fromAgentID, ownerID, source, audible); |
614 | UUID fromAgentID, UUID ownerID, byte source, byte audible) | ||
615 | { | ||
616 | } | 648 | } |
617 | 649 | ||
618 | public void SendInstantMessage(GridInstantMessage im) | 650 | public void SendInstantMessage(GridInstantMessage im) |
619 | { | 651 | { |
620 | 652 | Action<GridInstantMessage> oimtn = OnInstantMessageToNPC; | |
653 | |||
654 | if (oimtn != null) | ||
655 | oimtn(im); | ||
621 | } | 656 | } |
622 | 657 | ||
623 | public void SendGenericMessage(string method, List<string> message) | 658 | public void SendGenericMessage(string method, UUID invoice, List<string> message) |
624 | { | 659 | { |
625 | 660 | ||
626 | } | 661 | } |
627 | 662 | ||
628 | public void SendGenericMessage(string method, List<byte[]> message) | 663 | public void SendGenericMessage(string method, UUID invoice, List<byte[]> message) |
629 | { | 664 | { |
630 | 665 | ||
631 | } | 666 | } |
@@ -688,7 +723,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
688 | { | 723 | { |
689 | } | 724 | } |
690 | 725 | ||
691 | public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance) | 726 | public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item) |
692 | { | 727 | { |
693 | } | 728 | } |
694 | 729 | ||
@@ -860,11 +895,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
860 | { | 895 | { |
861 | } | 896 | } |
862 | 897 | ||
863 | public bool AddMoney(int debit) | ||
864 | { | ||
865 | return false; | ||
866 | } | ||
867 | |||
868 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase) | 898 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase) |
869 | { | 899 | { |
870 | } | 900 | } |
@@ -1227,12 +1257,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
1227 | { | 1257 | { |
1228 | } | 1258 | } |
1229 | 1259 | ||
1230 | public void StopFlying(ISceneEntity presence) | 1260 | public void SendAgentTerseUpdate(ISceneEntity presence) |
1231 | { | 1261 | { |
1232 | } | 1262 | } |
1233 | 1263 | ||
1234 | public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data) | 1264 | public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data) |
1235 | { | 1265 | { |
1236 | } | 1266 | } |
1267 | |||
1268 | public void SendPartPhysicsProprieties(ISceneEntity entity) | ||
1269 | { | ||
1270 | } | ||
1271 | |||
1237 | } | 1272 | } |
1238 | } | 1273 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index d6cf1ab..9232db9 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -116,7 +116,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
116 | return false; | 116 | return false; |
117 | 117 | ||
118 | // Delete existing npc attachments | 118 | // Delete existing npc attachments |
119 | scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false); | 119 | if(scene.AttachmentsModule != null) |
120 | scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false); | ||
120 | 121 | ||
121 | // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet | 122 | // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet |
122 | // since it doesn't transfer attachments | 123 | // since it doesn't transfer attachments |
@@ -125,7 +126,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
125 | npc.Appearance = npcAppearance; | 126 | npc.Appearance = npcAppearance; |
126 | 127 | ||
127 | // Rez needed npc attachments | 128 | // Rez needed npc attachments |
128 | scene.AttachmentsModule.RezAttachments(npc); | 129 | if (scene.AttachmentsModule != null) |
130 | scene.AttachmentsModule.RezAttachments(npc); | ||
129 | 131 | ||
130 | IAvatarFactoryModule module = | 132 | IAvatarFactoryModule module = |
131 | scene.RequestModuleInterface<IAvatarFactoryModule>(); | 133 | scene.RequestModuleInterface<IAvatarFactoryModule>(); |
@@ -138,15 +140,37 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
138 | Vector3 position, UUID owner, bool senseAsAgent, Scene scene, | 140 | Vector3 position, UUID owner, bool senseAsAgent, Scene scene, |
139 | AvatarAppearance appearance) | 141 | AvatarAppearance appearance) |
140 | { | 142 | { |
141 | NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, | 143 | return CreateNPC(firstname, lastname, position, UUID.Zero, owner, senseAsAgent, scene, appearance); |
142 | 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 | |||
143 | npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, | 167 | npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, |
144 | int.MaxValue); | 168 | int.MaxValue); |
145 | 169 | ||
146 | m_log.DebugFormat( | 170 | m_log.DebugFormat( |
147 | "[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}", | 171 | "[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}", |
148 | firstname, lastname, npcAvatar.AgentId, owner, | 172 | firstname, lastname, npcAvatar.AgentId, owner, |
149 | senseAsAgent, position, scene.RegionInfo.RegionName); | 173 | senseAsAgent, position, scene.RegionInfo.RegionName); |
150 | 174 | ||
151 | AgentCircuitData acd = new AgentCircuitData(); | 175 | AgentCircuitData acd = new AgentCircuitData(); |
152 | acd.AgentID = npcAvatar.AgentId; | 176 | acd.AgentID = npcAvatar.AgentId; |
@@ -154,8 +178,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
154 | acd.lastname = lastname; | 178 | acd.lastname = lastname; |
155 | acd.ServiceURLs = new Dictionary<string, object>(); | 179 | acd.ServiceURLs = new Dictionary<string, object>(); |
156 | 180 | ||
157 | AvatarAppearance npcAppearance = new AvatarAppearance(appearance, | 181 | AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); |
158 | true); | ||
159 | acd.Appearance = npcAppearance; | 182 | acd.Appearance = npcAppearance; |
160 | 183 | ||
161 | /* | 184 | /* |
@@ -173,7 +196,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
173 | { | 196 | { |
174 | scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, | 197 | scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, |
175 | acd); | 198 | acd); |
176 | scene.AddNewClient(npcAvatar, PresenceType.Npc); | 199 | scene.AddNewAgent(npcAvatar, PresenceType.Npc); |
177 | 200 | ||
178 | ScenePresence sp; | 201 | ScenePresence sp; |
179 | if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) | 202 | if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) |
@@ -186,16 +209,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
186 | 209 | ||
187 | sp.CompleteMovement(npcAvatar, false); | 210 | sp.CompleteMovement(npcAvatar, false); |
188 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); | 211 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); |
189 | m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", | 212 | m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", npcAvatar.AgentId, sp.Name); |
190 | npcAvatar.AgentId, sp.Name); | ||
191 | 213 | ||
192 | return npcAvatar.AgentId; | 214 | return npcAvatar.AgentId; |
193 | } | 215 | } |
194 | else | 216 | else |
195 | { | 217 | { |
196 | m_log.WarnFormat( | 218 | m_log.WarnFormat( |
197 | "[NPC MODULE]: Could not find scene presence for NPC {0} {1}", | 219 | "[NPC MODULE]: Could not find scene presence for NPC {0} {1}", |
198 | sp.Name, sp.UUID); | 220 | sp.Name, sp.UUID); |
221 | |||
199 | return UUID.Zero; | 222 | return UUID.Zero; |
200 | } | 223 | } |
201 | } | 224 | } |
@@ -211,12 +234,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
211 | ScenePresence sp; | 234 | ScenePresence sp; |
212 | if (scene.TryGetScenePresence(agentID, out sp)) | 235 | if (scene.TryGetScenePresence(agentID, out sp)) |
213 | { | 236 | { |
214 | /* | 237 | if (sp.IsSatOnObject || sp.SitGround) |
215 | m_log.DebugFormat( | 238 | return false; |
216 | "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", | 239 | |
217 | sp.Name, pos, scene.RegionInfo.RegionName, | 240 | // m_log.DebugFormat( |
218 | noFly, landAtTarget); | 241 | // "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", |
219 | */ | 242 | // sp.Name, pos, scene.RegionInfo.RegionName, |
243 | // noFly, landAtTarget); | ||
220 | 244 | ||
221 | sp.MoveToTarget(pos, noFly, landAtTarget); | 245 | sp.MoveToTarget(pos, noFly, landAtTarget); |
222 | sp.SetAlwaysRun = running; | 246 | sp.SetAlwaysRun = running; |
@@ -293,9 +317,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
293 | ScenePresence sp; | 317 | ScenePresence sp; |
294 | if (scene.TryGetScenePresence(agentID, out sp)) | 318 | if (scene.TryGetScenePresence(agentID, out sp)) |
295 | { | 319 | { |
296 | sp.HandleAgentRequestSit(m_avatars[agentID], agentID, | 320 | sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero); |
297 | partID, Vector3.Zero); | ||
298 | //sp.HandleAgentSit(m_avatars[agentID], agentID); | ||
299 | 321 | ||
300 | return true; | 322 | return true; |
301 | } | 323 | } |
@@ -376,23 +398,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
376 | 398 | ||
377 | public bool DeleteNPC(UUID agentID, Scene scene) | 399 | public bool DeleteNPC(UUID agentID, Scene scene) |
378 | { | 400 | { |
401 | bool doRemove = false; | ||
402 | NPCAvatar av; | ||
379 | lock (m_avatars) | 403 | lock (m_avatars) |
380 | { | 404 | { |
381 | NPCAvatar av; | ||
382 | if (m_avatars.TryGetValue(agentID, out av)) | 405 | if (m_avatars.TryGetValue(agentID, out av)) |
383 | { | 406 | { |
384 | /* | 407 | /* |
385 | m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", | 408 | m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", |
386 | agentID, av.Name); | 409 | agentID, av.Name); |
387 | */ | 410 | */ |
388 | scene.RemoveClient(agentID, false); | 411 | doRemove = true; |
412 | } | ||
413 | } | ||
414 | |||
415 | if (doRemove) | ||
416 | { | ||
417 | scene.CloseAgent(agentID, false); | ||
418 | lock (m_avatars) | ||
419 | { | ||
389 | m_avatars.Remove(agentID); | 420 | m_avatars.Remove(agentID); |
390 | /* | ||
391 | m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", | ||
392 | agentID, av.Name); | ||
393 | */ | ||
394 | return true; | ||
395 | } | 421 | } |
422 | m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", | ||
423 | agentID, av.Name); | ||
424 | return true; | ||
396 | } | 425 | } |
397 | /* | 426 | /* |
398 | m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", | 427 | m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", |
@@ -416,13 +445,20 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
416 | /// <summary> | 445 | /// <summary> |
417 | /// Check if the caller has permission to manipulate the given NPC. | 446 | /// Check if the caller has permission to manipulate the given NPC. |
418 | /// </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> | ||
419 | /// <param name="av"></param> | 455 | /// <param name="av"></param> |
420 | /// <param name="callerID"></param> | 456 | /// <param name="callerID"></param> |
421 | /// <returns>true if they do, false if they don't.</returns> | 457 | /// <returns>true if they do, false if they don't.</returns> |
422 | private bool CheckPermissions(NPCAvatar av, UUID callerID) | 458 | private bool CheckPermissions(NPCAvatar av, UUID callerID) |
423 | { | 459 | { |
424 | return callerID == UUID.Zero || av.OwnerID == UUID.Zero || | 460 | return callerID == UUID.Zero || av.OwnerID == UUID.Zero || |
425 | av.OwnerID == callerID; | 461 | av.OwnerID == callerID || av.AgentId == callerID; |
426 | } | 462 | } |
427 | } | 463 | } |
428 | } | 464 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index bf23040..77dfd40 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -33,7 +33,6 @@ using Nini.Config; | |||
33 | using NUnit.Framework; | 33 | using NUnit.Framework; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Communications; | ||
37 | using OpenSim.Region.CoreModules.Avatar.Attachments; | 36 | using OpenSim.Region.CoreModules.Avatar.Attachments; |
38 | using OpenSim.Region.CoreModules.Avatar.AvatarFactory; | 37 | using OpenSim.Region.CoreModules.Avatar.AvatarFactory; |
39 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | 38 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; |
@@ -43,7 +42,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
43 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Services.AvatarService; | 43 | using OpenSim.Services.AvatarService; |
45 | using OpenSim.Tests.Common; | 44 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 45 | ||
48 | namespace OpenSim.Region.OptionalModules.World.NPC.Tests | 46 | namespace OpenSim.Region.OptionalModules.World.NPC.Tests |
49 | { | 47 | { |
@@ -71,11 +69,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
71 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | 69 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; |
72 | } | 70 | } |
73 | 71 | ||
74 | [SetUp] | 72 | public void SetUpScene() |
75 | public void Init() | ||
76 | { | 73 | { |
77 | base.SetUp(); | 74 | SetUpScene(256, 256); |
75 | } | ||
78 | 76 | ||
77 | public void SetUpScene(uint sizeX, uint sizeY) | ||
78 | { | ||
79 | IConfigSource config = new IniConfigSource(); | 79 | IConfigSource config = new IniConfigSource(); |
80 | config.AddConfig("NPC"); | 80 | config.AddConfig("NPC"); |
81 | config.Configs["NPC"].Set("Enabled", "true"); | 81 | config.Configs["NPC"].Set("Enabled", "true"); |
@@ -87,7 +87,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
87 | m_attMod = new AttachmentsModule(); | 87 | m_attMod = new AttachmentsModule(); |
88 | m_npcMod = new NPCModule(); | 88 | m_npcMod = new NPCModule(); |
89 | 89 | ||
90 | m_scene = new SceneHelpers().SetupScene(); | 90 | 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()); | 91 | SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule()); |
92 | } | 92 | } |
93 | 93 | ||
@@ -97,6 +97,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
97 | TestHelpers.InMethod(); | 97 | TestHelpers.InMethod(); |
98 | // log4net.Config.XmlConfigurator.Configure(); | 98 | // log4net.Config.XmlConfigurator.Configure(); |
99 | 99 | ||
100 | SetUpScene(); | ||
101 | |||
100 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); | 102 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); |
101 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); | 103 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); |
102 | 104 | ||
@@ -110,7 +112,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
110 | // ScenePresence.SendInitialData() to reset our entire appearance. | 112 | // ScenePresence.SendInitialData() to reset our entire appearance. |
111 | m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); | 113 | m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); |
112 | 114 | ||
113 | m_afMod.SetAppearance(sp, originalTe, null); | 115 | m_afMod.SetAppearance(sp, originalTe, null, null); |
114 | 116 | ||
115 | UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); | 117 | UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); |
116 | 118 | ||
@@ -133,6 +135,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
133 | TestHelpers.InMethod(); | 135 | TestHelpers.InMethod(); |
134 | // log4net.Config.XmlConfigurator.Configure(); | 136 | // log4net.Config.XmlConfigurator.Configure(); |
135 | 137 | ||
138 | SetUpScene(); | ||
139 | |||
136 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); | 140 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); |
137 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); | 141 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); |
138 | 142 | ||
@@ -155,7 +159,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
155 | public void TestCreateWithAttachments() | 159 | public void TestCreateWithAttachments() |
156 | { | 160 | { |
157 | TestHelpers.InMethod(); | 161 | TestHelpers.InMethod(); |
158 | // log4net.Config.XmlConfigurator.Configure(); | 162 | // TestHelpers.EnableLogging(); |
163 | |||
164 | SetUpScene(); | ||
159 | 165 | ||
160 | UUID userId = TestHelpers.ParseTail(0x1); | 166 | UUID userId = TestHelpers.ParseTail(0x1); |
161 | UserAccountHelpers.CreateUserWithInventory(m_scene, userId); | 167 | UserAccountHelpers.CreateUserWithInventory(m_scene, userId); |
@@ -191,11 +197,66 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
191 | } | 197 | } |
192 | 198 | ||
193 | [Test] | 199 | [Test] |
200 | public void TestCreateWithMultiAttachments() | ||
201 | { | ||
202 | TestHelpers.InMethod(); | ||
203 | // TestHelpers.EnableLogging(); | ||
204 | |||
205 | SetUpScene(); | ||
206 | // m_attMod.DebugLevel = 1; | ||
207 | |||
208 | UUID userId = TestHelpers.ParseTail(0x1); | ||
209 | UserAccountHelpers.CreateUserWithInventory(m_scene, userId); | ||
210 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); | ||
211 | |||
212 | InventoryItemBase att1Item | ||
213 | = UserInventoryHelpers.CreateInventoryItem( | ||
214 | m_scene, "att1", TestHelpers.ParseTail(0x2), TestHelpers.ParseTail(0x3), sp.UUID, InventoryType.Object); | ||
215 | InventoryItemBase att2Item | ||
216 | = UserInventoryHelpers.CreateInventoryItem( | ||
217 | m_scene, "att2", TestHelpers.ParseTail(0x12), TestHelpers.ParseTail(0x13), sp.UUID, InventoryType.Object); | ||
218 | |||
219 | m_attMod.RezSingleAttachmentFromInventory(sp, att1Item.ID, (uint)AttachmentPoint.Chest); | ||
220 | m_attMod.RezSingleAttachmentFromInventory(sp, att2Item.ID, (uint)AttachmentPoint.Chest | 0x80); | ||
221 | |||
222 | UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); | ||
223 | |||
224 | ScenePresence npc = m_scene.GetScenePresence(npcId); | ||
225 | |||
226 | // Check scene presence status | ||
227 | Assert.That(npc.HasAttachments(), Is.True); | ||
228 | List<SceneObjectGroup> attachments = npc.GetAttachments(); | ||
229 | Assert.That(attachments.Count, Is.EqualTo(2)); | ||
230 | |||
231 | // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item | ||
232 | // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC. | ||
233 | // Assert.That(attSo.Name, Is.EqualTo(attName)); | ||
234 | |||
235 | TestAttachedObject(attachments[0], AttachmentPoint.Chest, npc.UUID); | ||
236 | TestAttachedObject(attachments[1], AttachmentPoint.Chest, npc.UUID); | ||
237 | |||
238 | // Attached objects on the same point must have different FromItemIDs to be shown to other avatars, at least | ||
239 | // on Singularity 1.8.5. Otherwise, only one (the first ObjectUpdate sent) appears. | ||
240 | Assert.AreNotEqual(attachments[0].FromItemID, attachments[1].FromItemID); | ||
241 | } | ||
242 | |||
243 | private void TestAttachedObject(SceneObjectGroup attSo, AttachmentPoint attPoint, UUID ownerId) | ||
244 | { | ||
245 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)attPoint)); | ||
246 | Assert.That(attSo.IsAttachment); | ||
247 | Assert.That(attSo.UsesPhysics, Is.False); | ||
248 | Assert.That(attSo.IsTemporary, Is.False); | ||
249 | Assert.That(attSo.OwnerID, Is.EqualTo(ownerId)); | ||
250 | } | ||
251 | |||
252 | [Test] | ||
194 | public void TestLoadAppearance() | 253 | public void TestLoadAppearance() |
195 | { | 254 | { |
196 | TestHelpers.InMethod(); | 255 | TestHelpers.InMethod(); |
197 | // log4net.Config.XmlConfigurator.Configure(); | 256 | // log4net.Config.XmlConfigurator.Configure(); |
198 | 257 | ||
258 | SetUpScene(); | ||
259 | |||
199 | UUID userId = TestHelpers.ParseTail(0x1); | 260 | UUID userId = TestHelpers.ParseTail(0x1); |
200 | UserAccountHelpers.CreateUserWithInventory(m_scene, userId); | 261 | UserAccountHelpers.CreateUserWithInventory(m_scene, userId); |
201 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); | 262 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); |
@@ -237,7 +298,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
237 | public void TestMove() | 298 | public void TestMove() |
238 | { | 299 | { |
239 | TestHelpers.InMethod(); | 300 | TestHelpers.InMethod(); |
240 | // log4net.Config.XmlConfigurator.Configure(); | 301 | // TestHelpers.EnableLogging(); |
302 | |||
303 | SetUpScene(); | ||
241 | 304 | ||
242 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); | 305 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); |
243 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); | 306 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); |
@@ -303,11 +366,64 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
303 | } | 366 | } |
304 | 367 | ||
305 | [Test] | 368 | [Test] |
369 | public void TestMoveInVarRegion() | ||
370 | { | ||
371 | TestHelpers.InMethod(); | ||
372 | // TestHelpers.EnableLogging(); | ||
373 | |||
374 | SetUpScene(512, 512); | ||
375 | |||
376 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); | ||
377 | // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); | ||
378 | |||
379 | Vector3 startPos = new Vector3(128, 246, 30); | ||
380 | UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance); | ||
381 | |||
382 | ScenePresence npc = m_scene.GetScenePresence(npcId); | ||
383 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | ||
384 | |||
385 | // For now, we'll make the scene presence fly to simplify this test, but this needs to change. | ||
386 | npc.Flying = true; | ||
387 | |||
388 | m_scene.Update(1); | ||
389 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | ||
390 | |||
391 | Vector3 targetPos = startPos + new Vector3(0, 20, 0); | ||
392 | m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false); | ||
393 | |||
394 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | ||
395 | //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f))); | ||
396 | Assert.That( | ||
397 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); | ||
398 | |||
399 | m_scene.Update(1); | ||
400 | |||
401 | // We should really check the exact figure. | ||
402 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); | ||
403 | Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y)); | ||
404 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); | ||
405 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); | ||
406 | |||
407 | for (int i = 0; i < 20; i++) | ||
408 | { | ||
409 | m_scene.Update(1); | ||
410 | // Console.WriteLine("pos: {0}", npc.AbsolutePosition); | ||
411 | } | ||
412 | |||
413 | double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); | ||
414 | Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); | ||
415 | Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos)); | ||
416 | Assert.That(npc.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE)); | ||
417 | } | ||
418 | |||
419 | [Test] | ||
306 | public void TestSitAndStandWithSitTarget() | 420 | public void TestSitAndStandWithSitTarget() |
307 | { | 421 | { |
308 | TestHelpers.InMethod(); | 422 | TestHelpers.InMethod(); |
309 | // log4net.Config.XmlConfigurator.Configure(); | 423 | // log4net.Config.XmlConfigurator.Configure(); |
310 | 424 | ||
425 | SetUpScene(); | ||
426 | |||
311 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); | 427 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); |
312 | 428 | ||
313 | Vector3 startPos = new Vector3(128, 128, 30); | 429 | Vector3 startPos = new Vector3(128, 128, 30); |
@@ -321,9 +437,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
321 | 437 | ||
322 | Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId)); | 438 | Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId)); |
323 | Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); | 439 | Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); |
324 | Assert.That( | 440 | // Assert.That( |
325 | npc.AbsolutePosition, | 441 | // npc.AbsolutePosition, |
326 | Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); | 442 | // Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); |
327 | 443 | ||
328 | m_npcMod.Stand(npc.UUID, m_scene); | 444 | m_npcMod.Stand(npc.UUID, m_scene); |
329 | 445 | ||
@@ -335,7 +451,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
335 | public void TestSitAndStandWithNoSitTarget() | 451 | public void TestSitAndStandWithNoSitTarget() |
336 | { | 452 | { |
337 | TestHelpers.InMethod(); | 453 | TestHelpers.InMethod(); |
338 | // log4net.Config.XmlConfigurator.Configure(); | 454 | // TestHelpers.EnableLogging(); |
455 | |||
456 | SetUpScene(); | ||
339 | 457 | ||
340 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); | 458 | ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); |
341 | 459 | ||
@@ -353,13 +471,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
353 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | 471 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); |
354 | Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); | 472 | Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); |
355 | 473 | ||
356 | // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the | 474 | // We should really be using the NPC size but this would mean preserving the physics actor since it is |
357 | // default avatar. | 475 | // removed on sit. |
358 | // Curiously, Vector3.ToString() will not display the last two places of the float. For example, | ||
359 | // printing out npc.AbsolutePosition will give <0, 0, 0.8454993> not <0, 0, 0.845499337> | ||
360 | Assert.That( | 476 | Assert.That( |
361 | npc.AbsolutePosition, | 477 | npc.AbsolutePosition, |
362 | Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f))); | 478 | Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, sp.PhysicsActor.Size.Z / 2))); |
363 | 479 | ||
364 | m_npcMod.Stand(npc.UUID, m_scene); | 480 | m_npcMod.Stand(npc.UUID, m_scene); |
365 | 481 | ||
@@ -367,4 +483,4 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
367 | Assert.That(npc.ParentID, Is.EqualTo(0)); | 483 | Assert.That(npc.ParentID, Is.EqualTo(0)); |
368 | } | 484 | } |
369 | } | 485 | } |
370 | } | 486 | } \ No newline at end of file |
diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 12169ab..0927c4f 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; | |||
30 | using System.Linq; | 30 | using System.Linq; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Threading; | ||
33 | using log4net; | 34 | using log4net; |
34 | using Mono.Addins; | 35 | using Mono.Addins; |
35 | using Nini.Config; | 36 | using Nini.Config; |
@@ -48,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SceneCommandsModule")] | 49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SceneCommandsModule")] |
49 | public class SceneCommandsModule : ISceneCommandsModule, INonSharedRegionModule | 50 | public class SceneCommandsModule : ISceneCommandsModule, INonSharedRegionModule |
50 | { | 51 | { |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 53 | ||
53 | private Scene m_scene; | 54 | private Scene m_scene; |
54 | 55 | ||
@@ -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; |
diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index 8144870..e4a3382 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs | |||
@@ -748,8 +748,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator | |||
748 | position.X = s_tree.AbsolutePosition.X + (float)randX; | 748 | position.X = s_tree.AbsolutePosition.X + (float)randX; |
749 | position.Y = s_tree.AbsolutePosition.Y + (float)randY; | 749 | position.Y = s_tree.AbsolutePosition.Y + (float)randY; |
750 | 750 | ||
751 | if (position.X <= ((int)Constants.RegionSize - 1) && position.X >= 0 && | 751 | if (position.X <= (m_scene.RegionInfo.RegionSizeX - 1) && position.X >= 0 && |
752 | position.Y <= ((int)Constants.RegionSize - 1) && position.Y >= 0 && | 752 | position.Y <= (m_scene.RegionInfo.RegionSizeY - 1) && position.Y >= 0 && |
753 | Util.GetDistanceTo(position, copse.m_seed_point) <= copse.m_range) | 753 | Util.GetDistanceTo(position, copse.m_seed_point) <= copse.m_range) |
754 | { | 754 | { |
755 | UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner; | 755 | UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner; |
diff --git a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs index 550b5d4..8720cc7 100644 --- a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs +++ b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs | |||
@@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.World.WorldView | |||
55 | m_WorldViewModule = fmodule; | 55 | m_WorldViewModule = fmodule; |
56 | } | 56 | } |
57 | 57 | ||
58 | public override byte[] Handle(string path, Stream requestData, | 58 | protected override byte[] ProcessRequest(string path, Stream requestData, |
59 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 59 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) |
60 | { | 60 | { |
61 | httpResponse.ContentType = "image/jpeg"; | 61 | httpResponse.ContentType = "image/jpeg"; |