aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules')
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs200
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs158
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs41
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs283
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs96
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs21
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs12
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs15
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs173
-rw-r--r--OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs175
-rw-r--r--OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs339
-rwxr-xr-xOpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs19
-rw-r--r--OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs4
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs171
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs391
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs155
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs307
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs901
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs82
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs6
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs228
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs282
-rw-r--r--OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs31
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs266
35 files changed, 3809 insertions, 605 deletions
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 5ac4e27..686c605 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -976,12 +976,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
976 // TODO 976 // TODO
977 } 977 }
978 978
979 public void SendGenericMessage(string method, List<string> message) 979 public void SendGenericMessage(string method, UUID invoice, List<string> message)
980 { 980 {
981 981
982 } 982 }
983 983
984 public void SendGenericMessage(string method, List<byte[]> message) 984 public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
985 { 985 {
986 986
987 } 987 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs
new file mode 100644
index 0000000..84211a9
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs
@@ -0,0 +1,200 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Region.ClientStack.LindenUDP;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Animation;
44using OpenSim.Services.Interfaces;
45
46namespace OpenSim.Region.OptionalModules.Avatar.Animations
47{
48 /// <summary>
49 /// A module that just holds commands for inspecting avatar animations.
50 /// </summary>
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")]
52 public class AnimationsCommandModule : ISharedRegionModule
53 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private List<Scene> m_scenes = new List<Scene>();
57
58 public string Name { get { return "Animations Command Module"; } }
59
60 public Type ReplaceableInterface { get { return null; } }
61
62 public void Initialise(IConfigSource source)
63 {
64// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE");
65 }
66
67 public void PostInitialise()
68 {
69// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE");
70 }
71
72 public void Close()
73 {
74// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE");
75 }
76
77 public void AddRegion(Scene scene)
78 {
79// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 }
81
82 public void RemoveRegion(Scene scene)
83 {
84// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
85
86 lock (m_scenes)
87 m_scenes.Remove(scene);
88 }
89
90 public void RegionLoaded(Scene scene)
91 {
92// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
93
94 lock (m_scenes)
95 m_scenes.Add(scene);
96
97 scene.AddCommand(
98 "Users", this, "show animations",
99 "show animations [<first-name> <last-name>]",
100 "Show animation information for avatars in this simulator.",
101 "If no name is supplied then information for all avatars is shown.\n"
102 + "Please note that for inventory animations, the animation name is the name under which the animation was originally uploaded\n"
103 + ", which is not necessarily the current inventory name.",
104 HandleShowAnimationsCommand);
105 }
106
107 protected void HandleShowAnimationsCommand(string module, string[] cmd)
108 {
109 if (cmd.Length != 2 && cmd.Length < 4)
110 {
111 MainConsole.Instance.OutputFormat("Usage: show animations [<first-name> <last-name>]");
112 return;
113 }
114
115 bool targetNameSupplied = false;
116 string optionalTargetFirstName = null;
117 string optionalTargetLastName = null;
118
119 if (cmd.Length >= 4)
120 {
121 targetNameSupplied = true;
122 optionalTargetFirstName = cmd[2];
123 optionalTargetLastName = cmd[3];
124 }
125
126 StringBuilder sb = new StringBuilder();
127
128 lock (m_scenes)
129 {
130 foreach (Scene scene in m_scenes)
131 {
132 if (targetNameSupplied)
133 {
134 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
135 if (sp != null && !sp.IsChildAgent)
136 GetAttachmentsReport(sp, sb);
137 }
138 else
139 {
140 scene.ForEachRootScenePresence(sp => GetAttachmentsReport(sp, sb));
141 }
142 }
143 }
144
145 MainConsole.Instance.Output(sb.ToString());
146 }
147
148 private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb)
149 {
150 sb.AppendFormat("Animations for {0}\n", sp.Name);
151
152 ConsoleDisplayList cdl = new ConsoleDisplayList() { Indent = 2 };
153 ScenePresenceAnimator spa = sp.Animator;
154 AnimationSet anims = sp.Animator.Animations;
155
156 string cma = spa.CurrentMovementAnimation;
157 cdl.AddRow(
158 "Current movement anim",
159 string.Format("{0}, {1}", DefaultAvatarAnimations.GetDefaultAnimation(cma), cma));
160
161 UUID defaultAnimId = anims.DefaultAnimation.AnimID;
162 cdl.AddRow(
163 "Default anim",
164 string.Format("{0}, {1}", defaultAnimId, sp.Animator.GetAnimName(defaultAnimId)));
165
166 UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID;
167 cdl.AddRow(
168 "Implicit default anim",
169 string.Format("{0}, {1}",
170 implicitDefaultAnimId, sp.Animator.GetAnimName(implicitDefaultAnimId)));
171
172 cdl.AddToStringBuilder(sb);
173
174 ConsoleDisplayTable cdt = new ConsoleDisplayTable() { Indent = 2 };
175 cdt.AddColumn("Animation ID", 36);
176 cdt.AddColumn("Name", 20);
177 cdt.AddColumn("Seq", 3);
178 cdt.AddColumn("Object ID", 36);
179
180 UUID[] animIds;
181 int[] sequenceNumbers;
182 UUID[] objectIds;
183
184 sp.Animator.Animations.GetArrays(out animIds, out sequenceNumbers, out objectIds);
185
186 for (int i = 0; i < animIds.Length; i++)
187 {
188 UUID animId = animIds[i];
189 string animName = sp.Animator.GetAnimName(animId);
190 int seq = sequenceNumbers[i];
191 UUID objectId = objectIds[i];
192
193 cdt.AddRow(animId, animName, seq, objectId);
194 }
195
196 cdt.AddToStringBuilder(sb);
197 sb.Append("\n");
198 }
199 }
200} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index d718a2f..fa35f0f 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
222 { 222 {
223 bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); 223 bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp);
224 MainConsole.Instance.OutputFormat( 224 MainConsole.Instance.OutputFormat(
225 "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); 225 "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete");
226 } 226 }
227 ); 227 );
228 } 228 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
index 68bcb4a..0333747 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
@@ -97,6 +97,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
97 "Users", this, "attachments show", 97 "Users", this, "attachments show",
98 "attachments show [<first-name> <last-name>]", 98 "attachments show [<first-name> <last-name>]",
99 "Show attachment information for avatars in this simulator.", 99 "Show attachment information for avatars in this simulator.",
100 "If no name is supplied then information for all avatars is shown.",
100 HandleShowAttachmentsCommand); 101 HandleShowAttachmentsCommand);
101 } 102 }
102 103
@@ -175,16 +176,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
175// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", 176// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n",
176// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, 177// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID,
177// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); 178// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos);
178 ct.Rows.Add( 179
179 new ConsoleDisplayTableRow( 180 ct.AddRow(
180 new List<string>() 181 attachmentObject.Name,
181 { 182 attachmentObject.LocalId,
182 attachmentObject.Name, 183 attachmentObject.FromItemID,
183 attachmentObject.LocalId.ToString(), 184 ((AttachmentPoint)attachmentObject.AttachmentPoint),
184 attachmentObject.FromItemID.ToString(), 185 attachmentObject.RootPart.AttachedPos);
185 ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(),
186 attachmentObject.RootPart.AttachedPos.ToString()
187 }));
188// } 186// }
189 } 187 }
190 188
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
index 17971e3..d56e39d 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;
40using OpenSim.Region.ClientStack.LindenUDP; 40using OpenSim.Region.ClientStack.LindenUDP;
41using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using PermissionMask = OpenSim.Framework.PermissionMask;
43 44
44namespace OpenSim.Region.OptionalModules.Avatar.Attachments 45namespace 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, true) ? 1 : 0; 187 return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true, 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..5a37fad 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 &&
@@ -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..c5cba8e 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
@@ -53,16 +53,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
53 // Local constants 53 // Local constants
54 54
55 private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); 55 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 = { ' ' }; 56 private static readonly char[] CS_SPACE = { ' ' };
57 57
58 private const int WD_INTERVAL = 1000; // base watchdog interval 58 private const int WD_INTERVAL = 1000; // base watchdog interval
59 private static int PING_PERIOD = 15; // WD intervals per PING 59 private static int PING_PERIOD = 15; // WD intervals per PING
60 private static int ICCD_PERIOD = 10; // WD intervals between Connects 60 private static int ICCD_PERIOD = 10; // WD intervals between Connects
61 private static int L_TIMEOUT = 25; // Login time out interval 61 private static int L_TIMEOUT = 25; // Login time out interval
62 62
63 private static int _idk_ = 0; // core connector identifier 63 private static int _idk_ = 0; // core connector identifier
64 private static int _pdk_ = 0; // ping interval counter 64 private static int _pdk_ = 0; // ping interval counter
65 private static int _icc_ = ICCD_PERIOD; // IRC connect counter 65 private static int _icc_ = ICCD_PERIOD; // IRC connect counter
66 66
67 // List of configured connectors 67 // List of configured connectors
68 68
@@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
113 113
114 private Object msyncConnect = new Object(); 114 private Object msyncConnect = new Object();
115 115
116 internal bool m_randomizeNick = true; // add random suffix 116 internal bool m_randomizeNick = true; // add random suffix
117 internal string m_baseNick = null; // base name for randomizing 117 internal string m_baseNick = null; // base name for randomizing
118 internal string m_nick = null; // effective nickname 118 internal string m_nick = null; // effective nickname
119 119
@@ -122,7 +122,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
122 get { return m_nick; } 122 get { return m_nick; }
123 set { m_nick = value; } 123 set { m_nick = value; }
124 } 124 }
125 125
126 private bool m_enabled = false; // connector enablement 126 private bool m_enabled = false; // connector enablement
127 public bool Enabled 127 public bool Enabled
128 { 128 {
@@ -130,8 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
130 } 130 }
131 131
132 private bool m_connected = false; // connection status 132 private bool m_connected = false; // connection status
133 private bool m_pending = false; // login disposition 133 private bool m_pending = false; // login disposition
134 private int m_timeout = L_TIMEOUT; // login timeout counter 134 private int m_timeout = L_TIMEOUT; // login timeout counter
135 public bool Connected 135 public bool Connected
136 { 136 {
137 get { return m_connected; } 137 get { return m_connected; }
@@ -143,9 +143,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
143 get { return m_ircChannel; } 143 get { return m_ircChannel; }
144 set { m_ircChannel = value; } 144 set { m_ircChannel = value; }
145 } 145 }
146 146
147 private uint m_port = 6667; // session port 147 private uint m_port = 6667; // session port
148 public uint Port 148 public uint Port
149 { 149 {
150 get { return m_port; } 150 get { return m_port; }
151 set { m_port = value; } 151 set { m_port = value; }
@@ -172,10 +172,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
172 172
173 // Network interface 173 // Network interface
174 174
175 private TcpClient m_tcp; 175 private TcpClient m_tcp;
176 private NetworkStream m_stream = null; 176 private NetworkStream m_stream = null;
177 private StreamReader m_reader; 177 private StreamReader m_reader;
178 private StreamWriter m_writer; 178 private StreamWriter m_writer;
179 179
180 // Channel characteristic info (if available) 180 // Channel characteristic info (if available)
181 181
@@ -193,26 +193,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
193 193
194 // Prepare network interface 194 // Prepare network interface
195 195
196 m_tcp = null; 196 m_tcp = null;
197 m_writer = null; 197 m_writer = null;
198 m_reader = null; 198 m_reader = null;
199 199
200 // Setup IRC session parameters 200 // Setup IRC session parameters
201 201
202 m_server = cs.Server; 202 m_server = cs.Server;
203 m_password = cs.Password; 203 m_password = cs.Password;
204 m_baseNick = cs.BaseNickname; 204 m_baseNick = cs.BaseNickname;
205 m_randomizeNick = cs.RandomizeNickname; 205 m_randomizeNick = cs.RandomizeNickname;
206 m_ircChannel = cs.IrcChannel; 206 m_ircChannel = cs.IrcChannel;
207 m_port = cs.Port; 207 m_port = cs.Port;
208 m_user = cs.User; 208 m_user = cs.User;
209 209
210 if (m_watchdog == null) 210 if (m_watchdog == null)
211 { 211 {
212 // Non-differentiating 212 // Non-differentiating
213 213
214 ICCD_PERIOD = cs.ConnectDelay; 214 ICCD_PERIOD = cs.ConnectDelay;
215 PING_PERIOD = cs.PingDelay; 215 PING_PERIOD = cs.PingDelay;
216 216
217 // Smaller values are not reasonable 217 // Smaller values are not reasonable
218 218
@@ -235,7 +235,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
235 235
236 if (m_randomizeNick) 236 if (m_randomizeNick)
237 m_nick = m_baseNick + Util.RandomClass.Next(1, 99); 237 m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
238 else 238 else
239 m_nick = m_baseNick; 239 m_nick = m_baseNick;
240 240
241 m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); 241 m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn);
@@ -295,18 +295,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
295 m_nick, m_ircChannel, m_server)); 295 m_nick, m_ircChannel, m_server));
296 m_writer.Flush(); 296 m_writer.Flush();
297 } 297 }
298 catch (Exception) {} 298 catch (Exception) { }
299 299
300 300
301 m_connected = false; 301 m_connected = false;
302 302
303 try { m_writer.Close(); } catch (Exception) {} 303 try { m_writer.Close(); }
304 try { m_reader.Close(); } catch (Exception) {} 304 catch (Exception) { }
305 try { m_stream.Close(); } catch (Exception) {} 305 try { m_reader.Close(); }
306 try { m_tcp.Close(); } catch (Exception) {} 306 catch (Exception) { }
307 try { m_stream.Close(); }
308 catch (Exception) { }
309 try { m_tcp.Close(); }
310 catch (Exception) { }
307 311
308 } 312 }
309 313
310 lock (m_connectors) 314 lock (m_connectors)
311 m_connectors.Remove(this); 315 m_connectors.Remove(this);
312 316
@@ -347,15 +351,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
347 if (m_connected) return; 351 if (m_connected) return;
348 352
349 m_connected = true; 353 m_connected = true;
350 m_pending = true; 354 m_pending = true;
351 m_timeout = L_TIMEOUT; 355 m_timeout = L_TIMEOUT;
352 356
353 m_tcp = new TcpClient(m_server, (int)m_port); 357 m_tcp = new TcpClient(m_server, (int)m_port);
354 m_stream = m_tcp.GetStream(); 358 m_stream = m_tcp.GetStream();
355 m_reader = new StreamReader(m_stream); 359 m_reader = new StreamReader(m_stream);
356 m_writer = new StreamWriter(m_stream); 360 m_writer = new StreamWriter(m_stream);
357 361
358 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); 362 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port);
359 363
360 m_listener = new Thread(new ThreadStart(ListenerRun)); 364 m_listener = new Thread(new ThreadStart(ListenerRun));
361 m_listener.Name = "IRCConnectorListenerThread"; 365 m_listener.Name = "IRCConnectorListenerThread";
@@ -418,12 +422,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
418 // the socket and it will disappear of its own accord, once this 422 // the socket and it will disappear of its own accord, once this
419 // processing is completed. 423 // processing is completed.
420 424
421 try { m_writer.Close(); } catch (Exception) {} 425 try { m_writer.Close(); }
422 try { m_reader.Close(); } catch (Exception) {} 426 catch (Exception) { }
423 try { m_tcp.Close(); } catch (Exception) {} 427 try { m_reader.Close(); }
428 catch (Exception) { }
429 try { m_tcp.Close(); }
430 catch (Exception) { }
424 431
425 m_connected = false; 432 m_connected = false;
426 m_pending = false; 433 m_pending = false;
427 m_resetk++; 434 m_resetk++;
428 435
429 } 436 }
@@ -495,7 +502,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
495 { 502 {
496 503
497 string inputLine; 504 string inputLine;
498 int resetk = m_resetk; 505 int resetk = m_resetk;
499 506
500 try 507 try
501 { 508 {
@@ -555,7 +562,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
555 Reconnect(); 562 Reconnect();
556 } 563 }
557 564
558 private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)", 565 private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)",
559 RegexOptions.Multiline); 566 RegexOptions.Multiline);
560 567
561 private Dictionary<string, string> ExtractMsg(string input) 568 private Dictionary<string, string> ExtractMsg(string input)
@@ -617,8 +624,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
617 string[] commArgs; 624 string[] commArgs;
618 string c_server = m_server; 625 string c_server = m_server;
619 626
620 string pfx = String.Empty; 627 string pfx = String.Empty;
621 string cmd = String.Empty; 628 string cmd = String.Empty;
622 string parms = String.Empty; 629 string parms = String.Empty;
623 630
624 // ":" indicates that a prefix is present 631 // ":" indicates that a prefix is present
@@ -627,15 +634,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
627 // ":" indicates that the remainder of the 634 // ":" indicates that the remainder of the
628 // line is a single parameter value. 635 // line is a single parameter value.
629 636
630 commArgs = command.Split(CS_SPACE,2); 637 commArgs = command.Split(CS_SPACE, 2);
631 638
632 if (commArgs[0].StartsWith(":")) 639 if (commArgs[0].StartsWith(":"))
633 { 640 {
634 pfx = commArgs[0].Substring(1); 641 pfx = commArgs[0].Substring(1);
635 commArgs = commArgs[1].Split(CS_SPACE,2); 642 commArgs = commArgs[1].Split(CS_SPACE, 2);
636 } 643 }
637 644
638 cmd = commArgs[0]; 645 cmd = commArgs[0];
639 parms = commArgs[1]; 646 parms = commArgs[1];
640 647
641 // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd); 648 // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd);
@@ -646,44 +653,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
646 // Messages 001-004 are always sent 653 // Messages 001-004 are always sent
647 // following signon. 654 // following signon.
648 655
649 case "001" : // Welcome ... 656 case "001": // Welcome ...
650 case "002" : // Server information 657 case "002": // Server information
651 case "003" : // Welcome ... 658 case "003": // Welcome ...
652 break; 659 break;
653 case "004" : // Server information 660 case "004": // Server information
654 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); 661 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms);
655 commArgs = parms.Split(CS_SPACE); 662 commArgs = parms.Split(CS_SPACE);
656 c_server = commArgs[1]; 663 c_server = commArgs[1];
657 m_server = c_server; 664 m_server = c_server;
658 version = commArgs[2]; 665 version = commArgs[2];
659 usermod = commArgs[3]; 666 usermod = commArgs[3];
660 chanmod = commArgs[4]; 667 chanmod = commArgs[4];
661 break; 668 break;
662 case "005" : // Server information 669 case "005": // Server information
663 break; 670 break;
664 case "042" : 671 case "042":
665 case "250" : 672 case "250":
666 case "251" : 673 case "251":
667 case "252" : 674 case "252":
668 case "254" : 675 case "254":
669 case "255" : 676 case "255":
670 case "265" : 677 case "265":
671 case "266" : 678 case "266":
672 case "332" : // Subject 679 case "332": // Subject
673 case "333" : // Subject owner (?) 680 case "333": // Subject owner (?)
674 case "353" : // Name list 681 case "353": // Name list
675 case "366" : // End-of-Name list marker 682 case "366": // End-of-Name list marker
676 case "372" : // MOTD body 683 case "372": // MOTD body
677 case "375" : // MOTD start 684 case "375": // MOTD start
678 // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); 685 // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]);
679 break; 686 break;
680 case "376" : // MOTD end 687 case "376": // MOTD end
681 // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); 688 // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]);
682 motd = true; 689 motd = true;
683 break; 690 break;
684 case "451" : // Not registered 691 case "451": // Not registered
685 break; 692 break;
686 case "433" : // Nickname in use 693 case "433": // Nickname in use
687 // Gen a new name 694 // Gen a new name
688 m_nick = m_baseNick + Util.RandomClass.Next(1, 99); 695 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); 696 m_log.ErrorFormat("[IRC-Connector-{0}]: [{1}] IRC SERVER reports NicknameInUse, trying {2}", idn, cmd, m_nick);
@@ -695,29 +702,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
695 m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); 702 m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
696 m_writer.Flush(); 703 m_writer.Flush();
697 break; 704 break;
698 case "479" : // Bad channel name, etc. This will never work, so disable the connection 705 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]); 706 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); 707 m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] Connector disabled", idn, cmd);
701 m_enabled = false; 708 m_enabled = false;
702 m_connected = false; 709 m_connected = false;
703 m_pending = false; 710 m_pending = false;
704 break; 711 break;
705 case "NOTICE" : 712 case "NOTICE":
706 // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); 713 // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]);
707 break; 714 break;
708 case "ERROR" : 715 case "ERROR":
709 m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); 716 m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]);
710 if (parms.Contains("reconnect too fast")) 717 if (parms.Contains("reconnect too fast"))
711 ICCD_PERIOD++; 718 ICCD_PERIOD++;
712 m_pending = false; 719 m_pending = false;
713 Reconnect(); 720 Reconnect();
714 break; 721 break;
715 case "PING" : 722 case "PING":
716 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); 723 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms);
717 m_writer.WriteLine(String.Format("PONG {0}", parms)); 724 m_writer.WriteLine(String.Format("PONG {0}", parms));
718 m_writer.Flush(); 725 m_writer.Flush();
719 break; 726 break;
720 case "PONG" : 727 case "PONG":
721 break; 728 break;
722 case "JOIN": 729 case "JOIN":
723 if (m_pending) 730 if (m_pending)
@@ -748,19 +755,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
748 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); 755 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms);
749 eventIrcQuit(pfx, cmd, parms); 756 eventIrcQuit(pfx, cmd, parms);
750 break; 757 break;
751 default : 758 default:
752 m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms); 759 m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms);
753 break; 760 break;
754 } 761 }
755 762
756 // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd); 763 // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd);
757 764
758 } 765 }
759 766
760 public void eventIrcJoin(string prefix, string command, string parms) 767 public void eventIrcJoin(string prefix, string command, string parms)
761 { 768 {
762 string[] args = parms.Split(CS_SPACE,2); 769 string[] args = parms.Split(CS_SPACE, 2);
763 string IrcUser = prefix.Split('!')[0]; 770 string IrcUser = prefix.Split('!')[0];
764 string IrcChannel = args[0]; 771 string IrcChannel = args[0];
765 772
766 if (IrcChannel.StartsWith(":")) 773 if (IrcChannel.StartsWith(":"))
@@ -772,8 +779,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
772 779
773 public void eventIrcPart(string prefix, string command, string parms) 780 public void eventIrcPart(string prefix, string command, string parms)
774 { 781 {
775 string[] args = parms.Split(CS_SPACE,2); 782 string[] args = parms.Split(CS_SPACE, 2);
776 string IrcUser = prefix.Split('!')[0]; 783 string IrcUser = prefix.Split('!')[0];
777 string IrcChannel = args[0]; 784 string IrcChannel = args[0];
778 785
779 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel); 786 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel);
@@ -782,7 +789,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
782 789
783 public void eventIrcMode(string prefix, string command, string parms) 790 public void eventIrcMode(string prefix, string command, string parms)
784 { 791 {
785 string[] args = parms.Split(CS_SPACE,2); 792 string[] args = parms.Split(CS_SPACE, 2);
786 string UserMode = args[1]; 793 string UserMode = args[1];
787 794
788 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel); 795 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel);
@@ -794,7 +801,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
794 801
795 public void eventIrcNickChange(string prefix, string command, string parms) 802 public void eventIrcNickChange(string prefix, string command, string parms)
796 { 803 {
797 string[] args = parms.Split(CS_SPACE,2); 804 string[] args = parms.Split(CS_SPACE, 2);
798 string UserOldNick = prefix.Split('!')[0]; 805 string UserOldNick = prefix.Split('!')[0];
799 string UserNewNick = args[0].Remove(0, 1); 806 string UserNewNick = args[0].Remove(0, 1);
800 807
@@ -804,11 +811,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
804 811
805 public void eventIrcKick(string prefix, string command, string parms) 812 public void eventIrcKick(string prefix, string command, string parms)
806 { 813 {
807 string[] args = parms.Split(CS_SPACE,3); 814 string[] args = parms.Split(CS_SPACE, 3);
808 string UserKicker = prefix.Split('!')[0]; 815 string UserKicker = prefix.Split('!')[0];
809 string IrcChannel = args[0]; 816 string IrcChannel = args[0];
810 string UserKicked = args[1]; 817 string UserKicked = args[1];
811 string KickMessage = args[2]; 818 string KickMessage = args[2];
812 819
813 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel); 820 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); 821 BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage);
@@ -822,7 +829,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
822 829
823 public void eventIrcQuit(string prefix, string command, string parms) 830 public void eventIrcQuit(string prefix, string command, string parms)
824 { 831 {
825 string IrcUser = prefix.Split('!')[0]; 832 string IrcUser = prefix.Split('!')[0];
826 string QuitMessage = parms; 833 string QuitMessage = parms;
827 834
828 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel); 835 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel);
@@ -842,65 +849,65 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
842 849
843 // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_); 850 // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_);
844 851
845 _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger 852 _pdk_ = (_pdk_ + 1) % PING_PERIOD; // cycle the ping trigger
846 _icc_++; // increment the inter-consecutive-connect-delay counter 853 _icc_++; // increment the inter-consecutive-connect-delay counter
847 854
848 lock (m_connectors) 855 lock (m_connectors)
849 foreach (IRCConnector connector in m_connectors) 856 foreach (IRCConnector connector in m_connectors)
850 { 857 {
851 858
852 // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); 859 // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector);
853 860
854 if (connector.Enabled) 861 if (connector.Enabled)
855 {
856 if (!connector.Connected)
857 { 862 {
858 try 863 if (!connector.Connected)
859 { 864 {
860 // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); 865 try
861 connector.Connect(); 866 {
867 // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel);
868 connector.Connect();
869 }
870 catch (Exception e)
871 {
872 m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message);
873 }
862 } 874 }
863 catch (Exception e) 875 else
864 { 876 {
865 m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message);
866 }
867 }
868 else
869 {
870 877
871 if (connector.m_pending) 878 if (connector.m_pending)
872 {
873 if (connector.m_timeout == 0)
874 { 879 {
875 m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); 880 if (connector.m_timeout == 0)
876 connector.Reconnect(); 881 {
882 m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn);
883 connector.Reconnect();
884 }
885 else
886 connector.m_timeout--;
877 } 887 }
878 else
879 connector.m_timeout--;
880 }
881 888
882 // Being marked connected is not enough to ping. Socket establishment can sometimes take a long 889 // 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 890 // 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. 891 // set up, with nasty side-effects.
885 892
886 else if (_pdk_ == 0) 893 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 { 894 {
895 m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); 895 try
896 m_log.Debug(e); 896 {
897 connector.Reconnect(); 897 connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server));
898 connector.m_writer.Flush();
899 }
900 catch (Exception e)
901 {
902 m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message);
903 m_log.Debug(e);
904 connector.Reconnect();
905 }
898 } 906 }
899 }
900 907
908 }
901 } 909 }
902 } 910 }
903 }
904 911
905 // m_log.InfoFormat("[IRC-Watchdog] Status scan completed"); 912 // m_log.InfoFormat("[IRC-Watchdog] Status scan completed");
906 913
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
index 53b103e..d4fe5e0 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
@@ -41,49 +41,71 @@ 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
48 private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); 47 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; 48 private const int DEBUG_CHANNEL = 2147483647;
50 49
51 private static int _idk_ = 0; 50 private static int _idk_ = 0;
52 51
53 // Runtime variables; these values are assigned when the 52 // Runtime variables; these values are assigned when the
54 // IrcState is created and remain constant thereafter. 53 // IrcState is created and remain constant thereafter.
55 54
56 internal string Region = String.Empty; 55 internal string Region = String.Empty;
57 internal string Host = String.Empty; 56 internal string Host = String.Empty;
58 internal string LocX = String.Empty; 57 internal string LocX = String.Empty;
59 internal string LocY = String.Empty; 58 internal string LocY = String.Empty;
60 internal string IDK = String.Empty; 59 internal string IDK = String.Empty;
61 60
62 // System values - used only be the IRC classes themselves 61 // System values - used only be the IRC classes themselves
63 62
64 internal ChannelState cs = null; // associated IRC configuration 63 internal ChannelState cs = null; // associated IRC configuration
65 internal Scene scene = null; // associated scene 64 internal Scene scene = null; // associated scene
66 internal IConfig config = null; // configuration file reference 65 internal IConfig config = null; // configuration file reference
67 internal bool enabled = true; 66 internal bool enabled = true;
68 67
68 //AgentAlert
69 internal bool showAlert = false;
70 internal string alertMessage = String.Empty;
71 internal IDialogModule dialogModule = null;
72
69 // This list is used to keep track of who is here, and by 73 // This list is used to keep track of who is here, and by
70 // implication, who is not. 74 // implication, who is not.
71 75
72 internal List<IClientAPI> clients = new List<IClientAPI>(); 76 internal List<IClientAPI> clients = new List<IClientAPI>();
73 77
74 // Setup runtime variable values 78 // Setup runtime variable values
75 79
76 public RegionState(Scene p_scene, IConfig p_config) 80 public RegionState(Scene p_scene, IConfig p_config)
77 { 81 {
78 82 scene = p_scene;
79 scene = p_scene;
80 config = p_config; 83 config = p_config;
81 84
82 Region = scene.RegionInfo.RegionName; 85 Region = scene.RegionInfo.RegionName;
83 Host = scene.RegionInfo.ExternalHostName; 86 Host = scene.RegionInfo.ExternalHostName;
84 LocX = Convert.ToString(scene.RegionInfo.RegionLocX); 87 LocX = Convert.ToString(scene.RegionInfo.RegionLocX);
85 LocY = Convert.ToString(scene.RegionInfo.RegionLocY); 88 LocY = Convert.ToString(scene.RegionInfo.RegionLocY);
86 IDK = Convert.ToString(_idk_++); 89 IDK = Convert.ToString(_idk_++);
90
91 showAlert = config.GetBoolean("alert_show", false);
92 string alertServerInfo = String.Empty;
93
94 if (showAlert)
95 {
96 bool showAlertServerInfo = config.GetBoolean("alert_show_serverinfo", true);
97
98 if (showAlertServerInfo)
99 alertServerInfo = String.Format("\nServer: {0}\nPort: {1}\nChannel: {2}\n\n",
100 config.GetString("server", ""), config.GetString("port", ""), config.GetString("channel", ""));
101
102 string alertPreMessage = config.GetString("alert_msg_pre", "This region is linked to Irc.");
103 string alertPostMessage = config.GetString("alert_msg_post", "Everything you say in public chat can be listened.");
104
105 alertMessage = String.Format("{0}\n{1}{2}", alertPreMessage, alertServerInfo, alertPostMessage);
106
107 dialogModule = scene.RequestModuleInterface<IDialogModule>();
108 }
87 109
88 // OpenChannel conditionally establishes a connection to the 110 // OpenChannel conditionally establishes a connection to the
89 // IRC server. The request will either succeed, or it will 111 // IRC server. The request will either succeed, or it will
@@ -93,9 +115,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
93 115
94 // Connect channel to world events 116 // Connect channel to world events
95 117
96 scene.EventManager.OnChatFromWorld += OnSimChat; 118 scene.EventManager.OnChatFromWorld += OnSimChat;
97 scene.EventManager.OnChatFromClient += OnSimChat; 119 scene.EventManager.OnChatFromClient += OnSimChat;
98 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; 120 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
99 scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; 121 scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
100 122
101 m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region); 123 m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region);
@@ -106,8 +128,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
106 128
107 ~RegionState() 129 ~RegionState()
108 { 130 {
109 if (cs != null) 131 if (cs != null)
110 cs.RemoveRegion(this); 132 cs.RemoveRegion(this);
111 } 133 }
112 134
113 // Called by PostInitialize after all regions have been created 135 // Called by PostInitialize after all regions have been created
@@ -138,7 +160,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
138 { 160 {
139 if (clients.Contains(client)) 161 if (clients.Contains(client))
140 { 162 {
141 if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) 163 if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting))
142 { 164 {
143 m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); 165 m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name);
144 //Check if this person is excluded from IRC 166 //Check if this person is excluded from IRC
@@ -147,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
147 cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); 169 cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name));
148 } 170 }
149 } 171 }
150 client.OnLogout -= OnClientLoggedOut; 172 client.OnLogout -= OnClientLoggedOut;
151 client.OnConnectionClosed -= OnClientLoggedOut; 173 client.OnConnectionClosed -= OnClientLoggedOut;
152 clients.Remove(client); 174 clients.Remove(client);
153 } 175 }
@@ -171,13 +193,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
171 { 193 {
172 if (clients.Contains(client)) 194 if (clients.Contains(client))
173 { 195 {
174 if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) 196 if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting))
175 { 197 {
176 string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); 198 string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname);
177 m_log.DebugFormat("[IRC-Region {0}] {1} has left", Region, clientName); 199 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)); 200 cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", clientName));
179 } 201 }
180 client.OnLogout -= OnClientLoggedOut; 202 client.OnLogout -= OnClientLoggedOut;
181 client.OnConnectionClosed -= OnClientLoggedOut; 203 client.OnConnectionClosed -= OnClientLoggedOut;
182 clients.Remove(client); 204 clients.Remove(client);
183 } 205 }
@@ -195,14 +217,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
195 217
196 private void OnMakeRootAgent(ScenePresence presence) 218 private void OnMakeRootAgent(ScenePresence presence)
197 { 219 {
198
199 IClientAPI client = presence.ControllingClient; 220 IClientAPI client = presence.ControllingClient;
200 221
201 try 222 try
202 { 223 {
203 if (!clients.Contains(client)) 224 if (!clients.Contains(client))
204 { 225 {
205 client.OnLogout += OnClientLoggedOut; 226 client.OnLogout += OnClientLoggedOut;
206 client.OnConnectionClosed += OnClientLoggedOut; 227 client.OnConnectionClosed += OnClientLoggedOut;
207 clients.Add(client); 228 clients.Add(client);
208 if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) 229 if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting))
@@ -216,17 +237,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
216 } 237 }
217 } 238 }
218 } 239 }
240
241 if (dialogModule != null && showAlert)
242 dialogModule.SendAlertToUser(client, alertMessage, true);
219 } 243 }
220 catch (Exception ex) 244 catch (Exception ex)
221 { 245 {
222 m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message); 246 m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message);
223 m_log.Debug(ex); 247 m_log.Debug(ex);
224 } 248 }
225
226 } 249 }
227 250
228 // This handler detects chat events int he virtual world. 251 // This handler detects chat events int he virtual world.
229
230 public void OnSimChat(Object sender, OSChatMessage msg) 252 public void OnSimChat(Object sender, OSChatMessage msg)
231 { 253 {
232 254
@@ -317,14 +339,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
317 // that evident. 339 // that evident.
318 340
319 default: 341 default:
320 m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", 342 m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}",
321 Region, msg.Message); 343 Region, msg.Message);
322 cs.irc.Send(msg.Message); 344 cs.irc.Send(msg.Message);
323 break; 345 break;
324 } 346 }
325 } 347 }
326 catch (Exception ex) 348 catch (Exception ex)
327 { 349 {
328 m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", 350 m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}",
329 Region, ex.Message); 351 Region, ex.Message);
330 m_log.Debug(ex); 352 m_log.Debug(ex);
@@ -366,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
366 388
367 m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); 389 m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message);
368 390
369 if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) 391 if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL))
370 { 392 {
371 string txt = msg.Message; 393 string txt = msg.Message;
372 if (txt.StartsWith("/me ")) 394 if (txt.StartsWith("/me "))
@@ -376,13 +398,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
376 return; 398 return;
377 } 399 }
378 400
379 if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && 401 if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword &&
380 msg.Channel == cs.RelayChannelOut) 402 msg.Channel == cs.RelayChannelOut)
381 { 403 {
382 Match m = cs.AccessPasswordRegex.Match(msg.Message); 404 Match m = cs.AccessPasswordRegex.Match(msg.Message);
383 if (null != m) 405 if (null != m)
384 { 406 {
385 m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), 407 m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(),
386 m.Groups["message"].ToString()); 408 m.Groups["message"].ToString());
387 cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), 409 cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(),
388 scene.RegionInfo.RegionName, m.Groups["message"].ToString()); 410 scene.RegionInfo.RegionName, m.Groups["message"].ToString());
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index f292a75..0cec959 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -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 7da1de6..e756c70 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -1123,18 +1123,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1123 // Otherwise prepare the request 1123 // Otherwise prepare the request
1124// m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); 1124// m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl);
1125 1125
1126 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); 1126 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl);
1127 HttpWebResponse rsp = null;
1128 1127
1129 // We are sending just parameters, no content 1128 // We are sending just parameters, no content
1130 req.ContentLength = 0; 1129 req.ContentLength = 0;
1131 1130
1132 // Send request and retrieve the response 1131 // Send request and retrieve the response
1133 rsp = (HttpWebResponse)req.GetResponse(); 1132 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse())
1134 1133 using (Stream s = rsp.GetResponseStream())
1135 XmlTextReader rdr = new XmlTextReader(rsp.GetResponseStream()); 1134 using (XmlTextReader rdr = new XmlTextReader(s))
1136 doc.Load(rdr); 1135 doc.Load(rdr);
1137 rdr.Close();
1138 } 1136 }
1139 catch (Exception e) 1137 catch (Exception e)
1140 { 1138 {
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index ae0ad02..d764936 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
126 { 126 {
127 scene.RegisterModuleInterface<IGroupsModule>(this); 127 scene.RegisterModuleInterface<IGroupsModule>(this);
128 scene.AddCommand( 128 scene.AddCommand(
129 "debug", 129 "Debug",
130 this, 130 this,
131 "debug groups verbose", 131 "debug groups verbose",
132 "debug groups verbose <true|false>", 132 "debug groups verbose <true|false>",
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs
index 6d26075..6b5b40a 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs
@@ -36,7 +36,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
36 { 36 {
37 UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); 37 UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID);
38 void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); 38 void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish);
39
40 /// <summary>
41 /// Get the group record.
42 /// </summary>
43 /// <returns></returns>
44 /// <param name='RequestingAgentID'>The UUID of the user making the request.</param>
45 /// <param name='GroupID'>
46 /// The ID of the record to retrieve.
47 /// GroupName may be specified instead, in which case this parameter will be UUID.Zero
48 /// </param>
49 /// <param name='GroupName'>
50 /// The name of the group to retrieve.
51 /// GroupID may be specified instead, in which case this parmeter will be null.
52 /// </param>
39 GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); 53 GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName);
54
40 List<DirGroupsReplyData> FindGroups(UUID RequestingAgentID, string search); 55 List<DirGroupsReplyData> FindGroups(UUID RequestingAgentID, string search);
41 List<GroupMembersData> GetGroupMembers(UUID RequestingAgentID, UUID GroupID); 56 List<GroupMembersData> GetGroupMembers(UUID RequestingAgentID, UUID GroupID);
42 57
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index ac638f1..c1bdacb 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
42 /// Basic groups module tests 42 /// Basic groups module tests
43 /// </summary> 43 /// </summary>
44 [TestFixture] 44 [TestFixture]
45 public class GroupsModuleTests 45 public class GroupsModuleTests : OpenSimTestCase
46 { 46 {
47 [Test] 47 [Test]
48 public void TestBasic() 48 public void TestBasic()
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index d0c3ea5..71b24ac 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -54,13 +54,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
54 54
55 private bool m_debugEnabled = false; 55 private bool m_debugEnabled = false;
56 56
57 public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | 57 public const GroupPowers DefaultEveryonePowers
58 GroupPowers.Accountable | 58 = GroupPowers.AllowSetHome
59 GroupPowers.JoinChat | 59 | GroupPowers.Accountable
60 GroupPowers.AllowVoiceChat | 60 | GroupPowers.JoinChat
61 GroupPowers.ReceiveNotices | 61 | GroupPowers.AllowVoiceChat
62 GroupPowers.StartProposal | 62 | GroupPowers.ReceiveNotices
63 GroupPowers.VoteOnProposal; 63 | GroupPowers.StartProposal
64 | GroupPowers.VoteOnProposal;
65
66 // Would this be cleaner as (GroupPowers)ulong.MaxValue?
67 public const GroupPowers DefaultOwnerPowers
68 = GroupPowers.Accountable
69 | GroupPowers.AllowEditLand
70 | GroupPowers.AllowFly
71 | GroupPowers.AllowLandmark
72 | GroupPowers.AllowRez
73 | GroupPowers.AllowSetHome
74 | GroupPowers.AllowVoiceChat
75 | GroupPowers.AssignMember
76 | GroupPowers.AssignMemberLimited
77 | GroupPowers.ChangeActions
78 | GroupPowers.ChangeIdentity
79 | GroupPowers.ChangeMedia
80 | GroupPowers.ChangeOptions
81 | GroupPowers.CreateRole
82 | GroupPowers.DeedObject
83 | GroupPowers.DeleteRole
84 | GroupPowers.Eject
85 | GroupPowers.FindPlaces
86 | GroupPowers.Invite
87 | GroupPowers.JoinChat
88 | GroupPowers.LandChangeIdentity
89 | GroupPowers.LandDeed
90 | GroupPowers.LandDivideJoin
91 | GroupPowers.LandEdit
92 | GroupPowers.LandEjectAndFreeze
93 | GroupPowers.LandGardening
94 | GroupPowers.LandManageAllowed
95 | GroupPowers.LandManageBanned
96 | GroupPowers.LandManagePasses
97 | GroupPowers.LandOptions
98 | GroupPowers.LandRelease
99 | GroupPowers.LandSetSale
100 | GroupPowers.ModerateChat
101 | GroupPowers.ObjectManipulate
102 | GroupPowers.ObjectSetForSale
103 | GroupPowers.ReceiveNotices
104 | GroupPowers.RemoveMember
105 | GroupPowers.ReturnGroupOwned
106 | GroupPowers.ReturnGroupSet
107 | GroupPowers.ReturnNonGroup
108 | GroupPowers.RoleProperties
109 | GroupPowers.SendNotices
110 | GroupPowers.SetLandingPoint
111 | GroupPowers.StartProposal
112 | GroupPowers.VoteOnProposal;
64 113
65 private bool m_connectorEnabled = false; 114 private bool m_connectorEnabled = false;
66 115
@@ -219,59 +268,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
219 param["AllowPublish"] = allowPublish == true ? 1 : 0; 268 param["AllowPublish"] = allowPublish == true ? 1 : 0;
220 param["MaturePublish"] = maturePublish == true ? 1 : 0; 269 param["MaturePublish"] = maturePublish == true ? 1 : 0;
221 param["FounderID"] = founderID.ToString(); 270 param["FounderID"] = founderID.ToString();
222 param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); 271 param["EveryonePowers"] = ((ulong)DefaultEveryonePowers).ToString();
223 param["OwnerRoleID"] = OwnerRoleID.ToString(); 272 param["OwnerRoleID"] = OwnerRoleID.ToString();
224 273 param["OwnersPowers"] = ((ulong)DefaultOwnerPowers).ToString();
225 // Would this be cleaner as (GroupPowers)ulong.MaxValue;
226 GroupPowers OwnerPowers = GroupPowers.Accountable
227 | GroupPowers.AllowEditLand
228 | GroupPowers.AllowFly
229 | GroupPowers.AllowLandmark
230 | GroupPowers.AllowRez
231 | GroupPowers.AllowSetHome
232 | GroupPowers.AllowVoiceChat
233 | GroupPowers.AssignMember
234 | GroupPowers.AssignMemberLimited
235 | GroupPowers.ChangeActions
236 | GroupPowers.ChangeIdentity
237 | GroupPowers.ChangeMedia
238 | GroupPowers.ChangeOptions
239 | GroupPowers.CreateRole
240 | GroupPowers.DeedObject
241 | GroupPowers.DeleteRole
242 | GroupPowers.Eject
243 | GroupPowers.FindPlaces
244 | GroupPowers.Invite
245 | GroupPowers.JoinChat
246 | GroupPowers.LandChangeIdentity
247 | GroupPowers.LandDeed
248 | GroupPowers.LandDivideJoin
249 | GroupPowers.LandEdit
250 | GroupPowers.LandEjectAndFreeze
251 | GroupPowers.LandGardening
252 | GroupPowers.LandManageAllowed
253 | GroupPowers.LandManageBanned
254 | GroupPowers.LandManagePasses
255 | GroupPowers.LandOptions
256 | GroupPowers.LandRelease
257 | GroupPowers.LandSetSale
258 | GroupPowers.ModerateChat
259 | GroupPowers.ObjectManipulate
260 | GroupPowers.ObjectSetForSale
261 | GroupPowers.ReceiveNotices
262 | GroupPowers.RemoveMember
263 | GroupPowers.ReturnGroupOwned
264 | GroupPowers.ReturnGroupSet
265 | GroupPowers.ReturnNonGroup
266 | GroupPowers.RoleProperties
267 | GroupPowers.SendNotices
268 | GroupPowers.SetLandingPoint
269 | GroupPowers.StartProposal
270 | GroupPowers.VoteOnProposal;
271 param["OwnersPowers"] = ((ulong)OwnerPowers).ToString();
272
273
274
275 274
276 Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); 275 Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param);
277 276
@@ -612,8 +611,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
612 } 611 }
613 612
614 return Roles; 613 return Roles;
615
616
617 } 614 }
618 615
619 public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID GroupID) 616 public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID GroupID)
@@ -676,7 +673,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
676 } 673 }
677 674
678 return members; 675 return members;
679
680 } 676 }
681 677
682 public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) 678 public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID)
@@ -727,9 +723,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
727 values.Add(data); 723 values.Add(data);
728 } 724 }
729 } 725 }
730 return values;
731 726
727 return values;
732 } 728 }
729
733 public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) 730 public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
734 { 731 {
735 Hashtable param = new Hashtable(); 732 Hashtable param = new Hashtable();
@@ -737,7 +734,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
737 734
738 Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); 735 Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param);
739 736
740
741 if (respData.Contains("error")) 737 if (respData.Contains("error"))
742 { 738 {
743 return null; 739 return null;
@@ -761,6 +757,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
761 757
762 return data; 758 return data;
763 } 759 }
760
764 public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) 761 public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
765 { 762 {
766 string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); 763 string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, "");
@@ -777,8 +774,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
777 XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); 774 XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param);
778 } 775 }
779 776
780
781
782 #endregion 777 #endregion
783 778
784 #region GroupSessionTracking 779 #region GroupSessionTracking
@@ -1151,28 +1146,38 @@ namespace Nwc.XmlRpc
1151 request.AllowWriteStreamBuffering = true; 1146 request.AllowWriteStreamBuffering = true;
1152 request.KeepAlive = !_disableKeepAlive; 1147 request.KeepAlive = !_disableKeepAlive;
1153 1148
1154 Stream stream = request.GetRequestStream(); 1149 using (Stream stream = request.GetRequestStream())
1155 XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII);
1156 _serializer.Serialize(xml, this);
1157 xml.Flush();
1158 xml.Close();
1159
1160 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
1161 StreamReader input = new StreamReader(response.GetResponseStream());
1162
1163 string inputXml = input.ReadToEnd();
1164 XmlRpcResponse resp;
1165 try
1166 { 1150 {
1167 resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); 1151 using (XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII))
1152 {
1153 _serializer.Serialize(xml, this);
1154 xml.Flush();
1155 }
1168 } 1156 }
1169 catch (Exception e) 1157
1158 XmlRpcResponse resp;
1159
1160 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
1170 { 1161 {
1171 RequestResponse = inputXml; 1162 using (Stream s = response.GetResponseStream())
1172 throw e; 1163 {
1164 using (StreamReader input = new StreamReader(s))
1165 {
1166 string inputXml = input.ReadToEnd();
1167
1168 try
1169 {
1170 resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml);
1171 }
1172 catch (Exception e)
1173 {
1174 RequestResponse = inputXml;
1175 throw e;
1176 }
1177 }
1178 }
1173 } 1179 }
1174 input.Close(); 1180
1175 response.Close();
1176 return resp; 1181 return resp;
1177 } 1182 }
1178 } 1183 }
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
index 7d37135..0615036 100644
--- a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
+++ b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
@@ -33,6 +33,12 @@ using Nini.Config;
33using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 34using 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.5")]
41
36namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared 42namespace 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..811a263 100644
--- a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
+++ b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
@@ -33,6 +33,12 @@ using Nini.Config;
33using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 34using 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.5")]
41
36namespace OpenSim.Region.OptionalModules.Example.BareBonesShared 42namespace 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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using OpenSim.Framework.Servers;
32using Mono.Addins;
33using log4net;
34using Nini.Config;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37
38using OpenSim.Framework.Servers.HttpServer;
39
40
41namespace 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/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
new file mode 100644
index 0000000..6e74ce0
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
@@ -0,0 +1,339 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31using System.Linq;
32using System.Net.NetworkInformation;
33using System.Text;
34using System.Threading;
35
36using log4net;
37using Mono.Addins;
38using Nini.Config;
39
40using OpenSim.Framework;
41using OpenSim.Framework.Console;
42using OpenSim.Framework.Monitoring;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45
46using OpenMetaverse.StructuredData;
47
48namespace OpenSim.Region.OptionalModules.Framework.Monitoring
49{
50[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ServerStatistics")]
51public class ServerStats : ISharedRegionModule
52{
53 private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
54 private readonly string LogHeader = "[SERVER STATS]";
55
56 public bool Enabled = false;
57 private static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>();
58
59 public readonly string CategoryServer = "server";
60
61 public readonly string ContainerProcessor = "processor";
62 public readonly string ContainerMemory = "memory";
63 public readonly string ContainerNetwork = "network";
64 public readonly string ContainerProcess = "process";
65
66 public string NetworkInterfaceTypes = "Ethernet";
67
68 readonly int performanceCounterSampleInterval = 500;
69 int lastperformanceCounterSampleTime = 0;
70
71 private class PerfCounterControl
72 {
73 public PerformanceCounter perfCounter;
74 public int lastFetch;
75 public string name;
76 public PerfCounterControl(PerformanceCounter pPc)
77 : this(pPc, String.Empty)
78 {
79 }
80 public PerfCounterControl(PerformanceCounter pPc, string pName)
81 {
82 perfCounter = pPc;
83 lastFetch = 0;
84 name = pName;
85 }
86 }
87
88 PerfCounterControl processorPercentPerfCounter = null;
89
90 #region ISharedRegionModule
91 // IRegionModuleBase.Name
92 public string Name { get { return "Server Stats"; } }
93 // IRegionModuleBase.ReplaceableInterface
94 public Type ReplaceableInterface { get { return null; } }
95 // IRegionModuleBase.Initialize
96 public void Initialise(IConfigSource source)
97 {
98 IConfig cfg = source.Configs["Monitoring"];
99
100 if (cfg != null)
101 Enabled = cfg.GetBoolean("ServerStatsEnabled", true);
102
103 if (Enabled)
104 {
105 NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet");
106 }
107 }
108 // IRegionModuleBase.Close
109 public void Close()
110 {
111 if (RegisteredStats.Count > 0)
112 {
113 foreach (Stat stat in RegisteredStats.Values)
114 {
115 StatsManager.DeregisterStat(stat);
116 stat.Dispose();
117 }
118 RegisteredStats.Clear();
119 }
120 }
121 // IRegionModuleBase.AddRegion
122 public void AddRegion(Scene scene)
123 {
124 }
125 // IRegionModuleBase.RemoveRegion
126 public void RemoveRegion(Scene scene)
127 {
128 }
129 // IRegionModuleBase.RegionLoaded
130 public void RegionLoaded(Scene scene)
131 {
132 }
133 // ISharedRegionModule.PostInitialize
134 public void PostInitialise()
135 {
136 if (RegisteredStats.Count == 0)
137 {
138 RegisterServerStats();
139 }
140 }
141 #endregion ISharedRegionModule
142
143 private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act)
144 {
145 string desc = pDesc;
146 if (desc == null)
147 desc = pName;
148 Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info);
149 StatsManager.RegisterStat(stat);
150 RegisteredStats.Add(pName, stat);
151 }
152
153 public void RegisterServerStats()
154 {
155 lastperformanceCounterSampleTime = Util.EnvironmentTickCount();
156 PerformanceCounter tempPC;
157 Stat tempStat;
158 string tempName;
159
160 try
161 {
162 tempName = "CPUPercent";
163 tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total");
164 processorPercentPerfCounter = new PerfCounterControl(tempPC);
165 // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
166 tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor,
167 StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); },
168 StatVerbosity.Info);
169 StatsManager.RegisterStat(tempStat);
170 RegisteredStats.Add(tempName, tempStat);
171
172 MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
173 (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
174
175 MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
176 (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
177
178 MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
179 (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
180
181 MakeStat("Threads", null, "threads", ContainerProcessor,
182 (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
183 }
184 catch (Exception e)
185 {
186 m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e);
187 }
188
189 try
190 {
191 List<string> okInterfaceTypes = new List<string>(NetworkInterfaceTypes.Split(','));
192
193 IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces();
194 foreach (NetworkInterface nic in nics)
195 {
196 if (nic.OperationalStatus != OperationalStatus.Up)
197 continue;
198
199 string nicInterfaceType = nic.NetworkInterfaceType.ToString();
200 if (!okInterfaceTypes.Contains(nicInterfaceType))
201 {
202 m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.",
203 LogHeader, nic.Name, nicInterfaceType);
204 m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}",
205 LogHeader, NetworkInterfaceTypes);
206 continue;
207 }
208
209 if (nic.Supports(NetworkInterfaceComponent.IPv4))
210 {
211 IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
212 if (nicStats != null)
213 {
214 MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork,
215 (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
216 MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork,
217 (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
218 MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork,
219 (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
220 }
221 }
222 // TODO: add IPv6 (it may actually happen someday)
223 }
224 }
225 catch (Exception e)
226 {
227 m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
228 }
229
230 MakeStat("ProcessMemory", null, "MB", ContainerMemory,
231 (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; });
232 MakeStat("ObjectMemory", null, "MB", ContainerMemory,
233 (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; });
234 MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory,
235 (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); });
236 MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory,
237 (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); });
238 }
239
240 // Notes on performance counters:
241 // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx
242 // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c
243 // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
244 private delegate double PerfCounterNextValue();
245 private void GetNextValue(Stat stat, PerfCounterControl perfControl)
246 {
247 GetNextValue(stat, perfControl, 1.0);
248 }
249 private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor)
250 {
251 if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval)
252 {
253 if (perfControl != null && perfControl.perfCounter != null)
254 {
255 try
256 {
257 // Kludge for factor to run double duty. If -1, subtract the value from one
258 if (factor == -1)
259 stat.Value = 1 - perfControl.perfCounter.NextValue();
260 else
261 stat.Value = perfControl.perfCounter.NextValue() / factor;
262 }
263 catch (Exception e)
264 {
265 m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
266 }
267 perfControl.lastFetch = Util.EnvironmentTickCount();
268 }
269 }
270 }
271
272 // Lookup the nic that goes with this stat and set the value by using a fetch action.
273 // Not sure about closure with delegates inside delegates.
274 private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat);
275 private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor)
276 {
277 // Get the one nic that has the name of this stat
278 IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where(
279 (network) => network.Name == stat.Description);
280 try
281 {
282 foreach (NetworkInterface nic in nics)
283 {
284 IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics();
285 if (intrStats != null)
286 {
287 double newVal = Math.Round(getter(intrStats) / factor, 3);
288 stat.Value = newVal;
289 }
290 break;
291 }
292 }
293 catch
294 {
295 // There are times interfaces go away so we just won't update the stat for this
296 m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description);
297 }
298 }
299}
300
301public class ServerStatsAggregator : Stat
302{
303 public ServerStatsAggregator(
304 string shortName,
305 string name,
306 string description,
307 string unitName,
308 string category,
309 string container
310 )
311 : base(
312 shortName,
313 name,
314 description,
315 unitName,
316 category,
317 container,
318 StatType.Push,
319 MeasuresOfInterest.None,
320 null,
321 StatVerbosity.Info)
322 {
323 }
324 public override string ToConsoleString()
325 {
326 StringBuilder sb = new StringBuilder();
327
328 return sb.ToString();
329 }
330
331 public override OSDMap ToOSDMap()
332 {
333 OSDMap ret = new OSDMap();
334
335 return ret;
336 }
337}
338
339}
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
index 40f7fbc..3083a33 100755
--- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
+++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
@@ -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 39cabb5..a375da9 100644
--- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
+++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
@@ -57,9 +57,10 @@ namespace OpenSim.Region.OptionalModules
57 57
58 public void Initialise(IConfigSource config) 58 public void Initialise(IConfigSource config)
59 { 59 {
60 IConfig myConfig = config.Configs["Startup"]; 60 //IConfig myConfig = config.Configs["Startup"];
61 61
62 string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); 62 string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules",
63 new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
63 64
64 List<string> modules=new List<string>(permissionModules.Split(',')); 65 List<string> modules=new List<string>(permissionModules.Split(','));
65 66
diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs
index 217b2d5..70bda72 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.7.6.*")]
34[assembly: AssemblyFileVersion("1.0.0.0")] 34
35 35
36[assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] 36[assembly: Addin("OpenSim.Region.OptionalModules", "0.1")]
37[assembly: AddinDependency("OpenSim", "0.5")] 37[assembly: AddinDependency("OpenSim", "0.5")]
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
new file mode 100755
index 0000000..6009dc5
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Linq;
30using System.Reflection;
31using System.Text;
32
33using OpenSim.Framework;
34using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.CoreModules;
38
39using Mono.Addins;
40using Nini.Config;
41using log4net;
42using OpenMetaverse;
43
44namespace OpenSim.Region.OptionalModules.Scripting
45{
46[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47public class ExtendedPhysics : INonSharedRegionModule
48{
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 private static string LogHeader = "[EXTENDED PHYSICS]";
51
52 private IConfig Configuration { get; set; }
53 private bool Enabled { get; set; }
54 private Scene BaseScene { get; set; }
55 private IScriptModuleComms Comms { get; set; }
56
57 #region INonSharedRegionModule
58
59 public string Name { get { return this.GetType().Name; } }
60
61 public void Initialise(IConfigSource config)
62 {
63 BaseScene = null;
64 Enabled = false;
65 Configuration = null;
66 Comms = null;
67
68 try
69 {
70 if ((Configuration = config.Configs["ExtendedPhysics"]) != null)
71 {
72 Enabled = Configuration.GetBoolean("Enabled", Enabled);
73 }
74 }
75 catch (Exception e)
76 {
77 m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e);
78 }
79
80 m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not"));
81 }
82
83 public void Close()
84 {
85 if (BaseScene != null)
86 {
87 BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
88 BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated;
89 BaseScene = null;
90 }
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 }
96
97 public void RemoveRegion(Scene scene)
98 {
99 if (BaseScene != null && BaseScene == scene)
100 {
101 Close();
102 }
103 }
104
105 public void RegionLoaded(Scene scene)
106 {
107 if (!Enabled) return;
108
109 BaseScene = scene;
110
111 Comms = BaseScene.RequestModuleInterface<IScriptModuleComms>();
112 if (Comms == null)
113 {
114 m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader);
115 Enabled = false;
116
117 return;
118 }
119
120 // Register as LSL functions all the [ScriptInvocation] marked methods.
121 Comms.RegisterScriptInvocations(this);
122
123 // When an object is modified, we might need to update its extended physics parameters
124 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
125 BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated;
126
127 }
128
129 public Type ReplaceableInterface { get { return null; } }
130
131 #endregion // INonSharedRegionModule
132
133 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
134 {
135 throw new NotImplementedException();
136 }
137
138 // Event generated when some property of a prim changes.
139 private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate)
140 {
141 }
142
143 [ScriptConstant]
144 public static int PHYS_CENTER_OF_MASS = 1 << 0;
145
146 [ScriptConstant]
147 public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1;
148 [ScriptConstant]
149 public static int PHYS_LINKSET_TYPE_COMPOUND = 2;
150 [ScriptConstant]
151 public static int PHYS_LINKSET_TYPE_MANUAL = 3;
152
153 [ScriptInvocation]
154 public string physGetEngineType(UUID hostID, UUID scriptID)
155 {
156 string ret = string.Empty;
157
158 if (BaseScene.PhysicsScene != null)
159 {
160 ret = BaseScene.PhysicsScene.EngineType;
161 }
162
163 return ret;
164 }
165
166 [ScriptInvocation]
167 public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
168 {
169 }
170}
171}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
index 34894ba..e498c6a 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 e)
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/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index e68764a..5fbfcc5 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
54 54
55 private IConfig m_config = null; 55 private IConfig m_config = null;
56 private bool m_enabled = false; 56 private bool m_enabled = false;
57 private bool m_enableObjectStore = false;
58 private int m_maxStringSpace = Int32.MaxValue;
59
57 private Scene m_scene = null; 60 private Scene m_scene = null;
58 61
59 private Dictionary<UUID,JsonStore> m_JsonValueStore; 62 private Dictionary<UUID,JsonStore> m_JsonValueStore;
@@ -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 // -----------------------------------------------------------------
@@ -175,6 +182,35 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
175 /// 182 ///
176 /// </summary> 183 /// </summary>
177 // ----------------------------------------------------------------- 184 // -----------------------------------------------------------------
185 public bool AttachObjectStore(UUID objectID)
186 {
187 if (! m_enabled) return false;
188 if (! m_enableObjectStore) return false;
189
190 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
191 if (sop == null)
192 {
193 m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID);
194 return false;
195 }
196
197 lock (m_JsonValueStore)
198 {
199 if (m_JsonValueStore.ContainsKey(objectID))
200 return true;
201
202 JsonStore map = new JsonObjectStore(m_scene,objectID);
203 m_JsonValueStore.Add(objectID,map);
204 }
205
206 return true;
207 }
208
209 // -----------------------------------------------------------------
210 /// <summary>
211 ///
212 /// </summary>
213 // -----------------------------------------------------------------
178 public bool CreateStore(string value, ref UUID result) 214 public bool CreateStore(string value, ref UUID result)
179 { 215 {
180 if (result == UUID.Zero) 216 if (result == UUID.Zero)
@@ -191,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
191 } 227 }
192 catch (Exception e) 228 catch (Exception e)
193 { 229 {
194 m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message); 230 m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value);
195 return false; 231 return false;
196 } 232 }
197 233
@@ -211,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
211 if (! m_enabled) return false; 247 if (! m_enabled) return false;
212 248
213 lock (m_JsonValueStore) 249 lock (m_JsonValueStore)
214 m_JsonValueStore.Remove(storeID); 250 return m_JsonValueStore.Remove(storeID);
215 251
216 return true; 252 return true;
217 } 253 }
@@ -221,31 +257,76 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
221 /// 257 ///
222 /// </summary> 258 /// </summary>
223 // ----------------------------------------------------------------- 259 // -----------------------------------------------------------------
224 public bool TestPath(UUID storeID, string path, bool useJson) 260 public bool TestStore(UUID storeID)
225 { 261 {
226 if (! m_enabled) return false; 262 if (! m_enabled) return false;
227 263
264 lock (m_JsonValueStore)
265 return m_JsonValueStore.ContainsKey(storeID);
266 }
267
268 // -----------------------------------------------------------------
269 /// <summary>
270 ///
271 /// </summary>
272 // -----------------------------------------------------------------
273 public JsonStoreNodeType GetNodeType(UUID storeID, string path)
274 {
275 if (! m_enabled) return JsonStoreNodeType.Undefined;
276
228 JsonStore map = null; 277 JsonStore map = null;
229 lock (m_JsonValueStore) 278 lock (m_JsonValueStore)
230 { 279 {
231 if (! m_JsonValueStore.TryGetValue(storeID,out map)) 280 if (! m_JsonValueStore.TryGetValue(storeID,out map))
232 { 281 {
233 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); 282 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
234 return false; 283 return JsonStoreNodeType.Undefined;
235 } 284 }
236 } 285 }
237 286
238 try 287 try
239 { 288 {
240 lock (map) 289 lock (map)
241 return map.TestPath(path,useJson); 290 return map.GetNodeType(path);
242 } 291 }
243 catch (Exception e) 292 catch (Exception e)
244 { 293 {
245 m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); 294 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
246 } 295 }
247 296
248 return false; 297 return JsonStoreNodeType.Undefined;
298 }
299
300 // -----------------------------------------------------------------
301 /// <summary>
302 ///
303 /// </summary>
304 // -----------------------------------------------------------------
305 public JsonStoreValueType GetValueType(UUID storeID, string path)
306 {
307 if (! m_enabled) return JsonStoreValueType.Undefined;
308
309 JsonStore map = null;
310 lock (m_JsonValueStore)
311 {
312 if (! m_JsonValueStore.TryGetValue(storeID,out map))
313 {
314 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
315 return JsonStoreValueType.Undefined;
316 }
317 }
318
319 try
320 {
321 lock (map)
322 return map.GetValueType(path);
323 }
324 catch (Exception e)
325 {
326 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
327 }
328
329 return JsonStoreValueType.Undefined;
249 } 330 }
250 331
251 // ----------------------------------------------------------------- 332 // -----------------------------------------------------------------
@@ -270,12 +351,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
270 try 351 try
271 { 352 {
272 lock (map) 353 lock (map)
273 if (map.SetValue(path,value,useJson)) 354 {
274 return true; 355 if (map.StringSpace > m_maxStringSpace)
356 {
357 m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
358 storeID,map.StringSpace,m_maxStringSpace);
359 return false;
360 }
361
362 return map.SetValue(path,value,useJson);
363 }
275 } 364 }
276 catch (Exception e) 365 catch (Exception e)
277 { 366 {
278 m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message); 367 m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e);
279 } 368 }
280 369
281 return false; 370 return false;
@@ -303,12 +392,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
303 try 392 try
304 { 393 {
305 lock (map) 394 lock (map)
306 if (map.RemoveValue(path)) 395 return map.RemoveValue(path);
307 return true;
308 } 396 }
309 catch (Exception e) 397 catch (Exception e)
310 { 398 {
311 m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message); 399 m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e);
312 } 400 }
313 401
314 return false; 402 return false;
@@ -319,6 +407,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
319 /// 407 ///
320 /// </summary> 408 /// </summary>
321 // ----------------------------------------------------------------- 409 // -----------------------------------------------------------------
410 public int GetArrayLength(UUID storeID, string path)
411 {
412 if (! m_enabled) return -1;
413
414 JsonStore map = null;
415 lock (m_JsonValueStore)
416 {
417 if (! m_JsonValueStore.TryGetValue(storeID,out map))
418 return -1;
419 }
420
421 try
422 {
423 lock (map)
424 {
425 return map.ArrayLength(path);
426 }
427 }
428 catch (Exception e)
429 {
430 m_log.Error("[JsonStore]: unable to retrieve value", e);
431 }
432
433 return -1;
434 }
435
436 // -----------------------------------------------------------------
437 /// <summary>
438 ///
439 /// </summary>
440 // -----------------------------------------------------------------
322 public bool GetValue(UUID storeID, string path, bool useJson, out string value) 441 public bool GetValue(UUID storeID, string path, bool useJson, out string value)
323 { 442 {
324 value = String.Empty; 443 value = String.Empty;
@@ -341,7 +460,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
341 } 460 }
342 catch (Exception e) 461 catch (Exception e)
343 { 462 {
344 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message); 463 m_log.Error("[JsonStore]: unable to retrieve value", e);
345 } 464 }
346 465
347 return false; 466 return false;
@@ -380,7 +499,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
380 } 499 }
381 catch (Exception e) 500 catch (Exception e)
382 { 501 {
383 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); 502 m_log.Error("[JsonStore] unable to retrieve value", e);
384 } 503 }
385 504
386 cback(String.Empty); 505 cback(String.Empty);
@@ -419,7 +538,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
419 } 538 }
420 catch (Exception e) 539 catch (Exception e)
421 { 540 {
422 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); 541 m_log.Error("[JsonStore]: unable to retrieve value", e);
423 } 542 }
424 543
425 cback(String.Empty); 544 cback(String.Empty);
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 0c175ca..1bb5aee 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -39,8 +39,10 @@ using OpenMetaverse.StructuredData;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Scripting;
42using System.Collections.Generic; 43using System.Collections.Generic;
43using System.Text.RegularExpressions; 44using System.Text.RegularExpressions;
45using PermissionMask = OpenSim.Framework.PermissionMask;
44 46
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore 47namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
46{ 48{
@@ -92,12 +94,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
92 } 94 }
93 catch (Exception e) 95 catch (Exception e)
94 { 96 {
95 m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); 97 m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message);
96 return; 98 return;
97 } 99 }
98 100
99 if (m_enabled) 101 if (m_enabled)
100 m_log.DebugFormat("[JsonStoreScripts] module is enabled"); 102 m_log.DebugFormat("[JsonStoreScripts]: module is enabled");
101 } 103 }
102 104
103 // ----------------------------------------------------------------- 105 // -----------------------------------------------------------------
@@ -150,7 +152,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
150 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>(); 152 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>();
151 if (m_comms == null) 153 if (m_comms == null)
152 { 154 {
153 m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); 155 m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined");
154 m_enabled = false; 156 m_enabled = false;
155 return; 157 return;
156 } 158 }
@@ -158,40 +160,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
158 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>(); 160 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>();
159 if (m_store == null) 161 if (m_store == null)
160 { 162 {
161 m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); 163 m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined");
162 m_enabled = false; 164 m_enabled = false;
163 return; 165 return;
164 } 166 }
165 167
166 try 168 try
167 { 169 {
168 m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); 170 m_comms.RegisterScriptInvocations(this);
169 m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); 171 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 } 172 }
191 catch (Exception e) 173 catch (Exception e)
192 { 174 {
193 // See http://opensimulator.org/mantis/view.php?id=5971 for more information 175 // See http://opensimulator.org/mantis/view.php?id=5971 for more information
194 m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); 176 m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message);
195 m_enabled = false; 177 m_enabled = false;
196 } 178 }
197 } 179 }
@@ -208,23 +190,61 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
208 190
209#endregion 191#endregion
210 192
193#region ScriptConstantsInterface
194
195 [ScriptConstant]
196 public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined;
197
198 [ScriptConstant]
199 public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object;
200
201 [ScriptConstant]
202 public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array;
203
204 [ScriptConstant]
205 public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value;
206
207 [ScriptConstant]
208 public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined;
209
210 [ScriptConstant]
211 public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean;
212
213 [ScriptConstant]
214 public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer;
215
216 [ScriptConstant]
217 public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float;
218
219 [ScriptConstant]
220 public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String;
221
222
223#endregion
224
211#region ScriptInvocationInteface 225#region ScriptInvocationInteface
212 // ----------------------------------------------------------------- 226 // -----------------------------------------------------------------
213 /// <summary> 227 /// <summary>
214 /// 228 ///
215 /// </summary> 229 /// </summary>
216 // ----------------------------------------------------------------- 230 // -----------------------------------------------------------------
217 protected void GenerateRuntimeError(string msg) 231 [ScriptInvocation]
232 public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID)
218 { 233 {
219 throw new Exception("JsonStore Runtime Error: " + msg); 234 UUID uuid = UUID.Zero;
235 if (! m_store.AttachObjectStore(hostID))
236 GenerateRuntimeError("Failed to create Json store");
237
238 return hostID;
220 } 239 }
221 240
222 // ----------------------------------------------------------------- 241 // -----------------------------------------------------------------
223 /// <summary> 242 /// <summary>
224 /// 243 ///
225 /// </summary> 244 /// </summary>
226 // ----------------------------------------------------------------- 245 // -----------------------------------------------------------------
227 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) 246 [ScriptInvocation]
247 public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
228 { 248 {
229 UUID uuid = UUID.Zero; 249 UUID uuid = UUID.Zero;
230 if (! m_store.CreateStore(value, ref uuid)) 250 if (! m_store.CreateStore(value, ref uuid))
@@ -238,7 +258,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
238 /// 258 ///
239 /// </summary> 259 /// </summary>
240 // ----------------------------------------------------------------- 260 // -----------------------------------------------------------------
241 protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) 261 [ScriptInvocation]
262 public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID)
242 { 263 {
243 return m_store.DestroyStore(storeID) ? 1 : 0; 264 return m_store.DestroyStore(storeID) ? 1 : 0;
244 } 265 }
@@ -248,10 +269,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
248 /// 269 ///
249 /// </summary> 270 /// </summary>
250 // ----------------------------------------------------------------- 271 // -----------------------------------------------------------------
251 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 272 [ScriptInvocation]
273 public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID)
274 {
275 return m_store.TestStore(storeID) ? 1 : 0;
276 }
277
278 // -----------------------------------------------------------------
279 /// <summary>
280 ///
281 /// </summary>
282 // -----------------------------------------------------------------
283 [ScriptInvocation]
284 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
252 { 285 {
253 UUID reqID = UUID.Random(); 286 UUID reqID = UUID.Random();
254 Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); 287 Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier));
255 return reqID; 288 return reqID;
256 } 289 }
257 290
@@ -260,7 +293,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
260 /// 293 ///
261 /// </summary> 294 /// </summary>
262 // ----------------------------------------------------------------- 295 // -----------------------------------------------------------------
263 protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) 296 [ScriptInvocation]
297 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
264 { 298 {
265 UUID reqID = UUID.Random(); 299 UUID reqID = UUID.Random();
266 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); 300 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); });
@@ -272,14 +306,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
272 /// 306 ///
273 /// </summary> 307 /// </summary>
274 // ----------------------------------------------------------------- 308 // -----------------------------------------------------------------
275 protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) 309 [ScriptInvocation]
310 public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist)
276 { 311 {
277 return m_store.TestPath(storeID,path,false) ? 1 : 0; 312 string ipath = ConvertList2Path(pathlist);
313 string opath;
314
315 if (JsonStore.CanonicalPathExpression(ipath,out opath))
316 return opath;
317
318 // This won't parse if passed to the other routines as opposed to
319 // returning an empty string which is a valid path and would overwrite
320 // the entire store
321 return "**INVALID**";
322 }
323
324 // -----------------------------------------------------------------
325 /// <summary>
326 ///
327 /// </summary>
328 // -----------------------------------------------------------------
329 [ScriptInvocation]
330 public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path)
331 {
332 return (int)m_store.GetNodeType(storeID,path);
278 } 333 }
279 334
280 protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) 335 // -----------------------------------------------------------------
336 /// <summary>
337 ///
338 /// </summary>
339 // -----------------------------------------------------------------
340 [ScriptInvocation]
341 public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path)
281 { 342 {
282 return m_store.TestPath(storeID,path,true) ? 1 : 0; 343 return (int)m_store.GetValueType(storeID,path);
283 } 344 }
284 345
285 // ----------------------------------------------------------------- 346 // -----------------------------------------------------------------
@@ -287,12 +348,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
287 /// 348 ///
288 /// </summary> 349 /// </summary>
289 // ----------------------------------------------------------------- 350 // -----------------------------------------------------------------
290 protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) 351 [ScriptInvocation]
352 public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
291 { 353 {
292 return m_store.SetValue(storeID,path,value,false) ? 1 : 0; 354 return m_store.SetValue(storeID,path,value,false) ? 1 : 0;
293 } 355 }
294 356
295 protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) 357 [ScriptInvocation]
358 public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
296 { 359 {
297 return m_store.SetValue(storeID,path,value,true) ? 1 : 0; 360 return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
298 } 361 }
@@ -302,7 +365,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
302 /// 365 ///
303 /// </summary> 366 /// </summary>
304 // ----------------------------------------------------------------- 367 // -----------------------------------------------------------------
305 protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) 368 [ScriptInvocation]
369 public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
306 { 370 {
307 return m_store.RemoveValue(storeID,path) ? 1 : 0; 371 return m_store.RemoveValue(storeID,path) ? 1 : 0;
308 } 372 }
@@ -312,14 +376,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
312 /// 376 ///
313 /// </summary> 377 /// </summary>
314 // ----------------------------------------------------------------- 378 // -----------------------------------------------------------------
315 protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) 379 [ScriptInvocation]
380 public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
381 {
382 return m_store.GetArrayLength(storeID,path);
383 }
384
385 // -----------------------------------------------------------------
386 /// <summary>
387 ///
388 /// </summary>
389 // -----------------------------------------------------------------
390 [ScriptInvocation]
391 public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path)
316 { 392 {
317 string value = String.Empty; 393 string value = String.Empty;
318 m_store.GetValue(storeID,path,false,out value); 394 m_store.GetValue(storeID,path,false,out value);
319 return value; 395 return value;
320 } 396 }
321 397
322 protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 398 [ScriptInvocation]
399 public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path)
323 { 400 {
324 string value = String.Empty; 401 string value = String.Empty;
325 m_store.GetValue(storeID,path,true, out value); 402 m_store.GetValue(storeID,path,true, out value);
@@ -331,80 +408,105 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
331 /// 408 ///
332 /// </summary> 409 /// </summary>
333 // ----------------------------------------------------------------- 410 // -----------------------------------------------------------------
334 protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) 411 [ScriptInvocation]
412 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
335 { 413 {
336 UUID reqID = UUID.Random(); 414 UUID reqID = UUID.Random();
337 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); 415 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); });
338 return reqID; 416 return reqID;
339 } 417 }
340 418
341 protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 419 [ScriptInvocation]
420 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
342 { 421 {
343 UUID reqID = UUID.Random(); 422 UUID reqID = UUID.Random();
344 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); 423 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); });
345 return reqID; 424 return reqID;
346 } 425 }
347 426
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 // ----------------------------------------------------------------- 427 // -----------------------------------------------------------------
365 /// <summary> 428 /// <summary>
366 /// 429 ///
367 /// </summary> 430 /// </summary>
368 // ----------------------------------------------------------------- 431 // -----------------------------------------------------------------
369 protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) 432 [ScriptInvocation]
433 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
370 { 434 {
371 UUID reqID = UUID.Random(); 435 UUID reqID = UUID.Random();
372 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); 436 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); });
373 return reqID; 437 return reqID;
374 } 438 }
375 439
376 protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 440 [ScriptInvocation]
441 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
377 { 442 {
378 UUID reqID = UUID.Random(); 443 UUID reqID = UUID.Random();
379 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); 444 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); });
380 return reqID; 445 return reqID;
381 } 446 }
382 447
383 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) 448#endregion
449
450 // -----------------------------------------------------------------
451 /// <summary>
452 ///
453 /// </summary>
454 // -----------------------------------------------------------------
455 protected void GenerateRuntimeError(string msg)
456 {
457 m_log.InfoFormat("[JsonStore] runtime error: {0}",msg);
458 throw new Exception("JsonStore Runtime Error: " + msg);
459 }
460
461 // -----------------------------------------------------------------
462 /// <summary>
463 ///
464 /// </summary>
465 // -----------------------------------------------------------------
466 protected void DispatchValue(UUID scriptID, UUID reqID, string value)
467 {
468 m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
469 }
470
471 // -----------------------------------------------------------------
472 /// <summary>
473 ///
474 /// </summary>
475 // -----------------------------------------------------------------
476 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
384 { 477 {
385 try 478 try
386 { 479 {
387 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); 480 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
388 return; 481 return;
389 } 482 }
390 catch (Exception e) 483 catch (Exception e)
391 { 484 {
392 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); 485 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
393 } 486 }
394 487
395 DispatchValue(scriptID,reqID,String.Empty); 488 DispatchValue(scriptID,reqID,String.Empty);
396 } 489 }
397 490
398#endregion
399 491
400 // ----------------------------------------------------------------- 492 // -----------------------------------------------------------------
401 /// <summary> 493 /// <summary>
402 /// 494 ///
403 /// </summary> 495 /// </summary>
404 // ----------------------------------------------------------------- 496 // -----------------------------------------------------------------
405 protected void DispatchValue(UUID scriptID, UUID reqID, string value) 497 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
406 { 498 {
407 m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); 499 try
500 {
501 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
502 return;
503 }
504 catch (Exception e)
505 {
506 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
507 }
508
509 DispatchValue(scriptID,reqID,String.Empty);
408 } 510 }
409 511
410 // ----------------------------------------------------------------- 512 // -----------------------------------------------------------------
@@ -412,31 +514,40 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
412 /// 514 ///
413 /// </summary> 515 /// </summary>
414 // ----------------------------------------------------------------- 516 // -----------------------------------------------------------------
415 private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) 517 private void DoJsonReadNotecard(
518 UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
416 { 519 {
520 UUID assetID;
521
522 if (!UUID.TryParse(notecardIdentifier, out assetID))
523 {
524 SceneObjectPart part = m_scene.GetSceneObjectPart(hostID);
525 assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard);
526 }
527
417 AssetBase a = m_scene.AssetService.Get(assetID.ToString()); 528 AssetBase a = m_scene.AssetService.Get(assetID.ToString());
418 if (a == null) 529 if (a == null)
419 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); 530 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID));
420 531
421 if (a.Type != (sbyte)AssetType.Notecard) 532 if (a.Type != (sbyte)AssetType.Notecard)
422 GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); 533 GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID));
423 534
424 m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); 535 m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID);
425 536
426 try 537 try
427 { 538 {
428 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 539 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
429 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; 540 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
430 m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); 541 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
431 return; 542 return;
432 } 543 }
433 catch (Exception e) 544 catch (Exception e)
434 { 545 {
435 m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); 546 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
436 } 547 }
437 548
438 GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); 549 GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID));
439 m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); 550 m_comms.DispatchReply(scriptID, 0, "", reqID.ToString());
440 } 551 }
441 552
442 // ----------------------------------------------------------------- 553 // -----------------------------------------------------------------
@@ -494,5 +605,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
494 605
495 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); 606 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
496 } 607 }
608
609 // -----------------------------------------------------------------
610 /// <summary>
611 /// Convert a list of values that are path components to a single string path
612 /// </summary>
613 // -----------------------------------------------------------------
614 protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$");
615 private string ConvertList2Path(object[] pathlist)
616 {
617 string path = "";
618 for (int i = 0; i < pathlist.Length; i++)
619 {
620 string token = "";
621
622 if (pathlist[i] is string)
623 {
624 token = pathlist[i].ToString();
625
626 // Check to see if this is a bare number which would not be a valid
627 // identifier otherwise
628 if (m_ArrayPattern.IsMatch(token))
629 token = '[' + token + ']';
630 }
631 else if (pathlist[i] is int)
632 {
633 token = "[" + pathlist[i].ToString() + "]";
634 }
635 else
636 {
637 token = "." + pathlist[i].ToString() + ".";
638 }
639
640 path += token + ".";
641 }
642
643 return path;
644 }
645
497 } 646 }
498} 647}
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..bfa9937
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -0,0 +1,901 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.Scripting.ScriptModuleComms;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api;
41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
46{
47 /// <summary>
48 /// Tests for inventory functions in LSL
49 /// </summary>
50 [TestFixture]
51 public class JsonStoreScriptModuleTests : OpenSimTestCase
52 {
53 private Scene m_scene;
54 private MockScriptEngine m_engine;
55 private ScriptModuleCommsModule m_smcm;
56 private JsonStoreScriptModule m_jssm;
57
58 [TestFixtureSetUp]
59 public void FixtureInit()
60 {
61 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
62 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
63 }
64
65 [TestFixtureTearDown]
66 public void TearDown()
67 {
68 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
69 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
70 // tests really shouldn't).
71 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
72 }
73
74 [SetUp]
75 public override void SetUp()
76 {
77 base.SetUp();
78
79 IConfigSource configSource = new IniConfigSource();
80 IConfig jsonStoreConfig = configSource.AddConfig("JsonStore");
81 jsonStoreConfig.Set("Enabled", "true");
82
83 m_engine = new MockScriptEngine();
84 m_smcm = new ScriptModuleCommsModule();
85 JsonStoreModule jsm = new JsonStoreModule();
86 m_jssm = new JsonStoreScriptModule();
87
88 m_scene = new SceneHelpers().SetupScene();
89 SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm);
90
91 try
92 {
93 m_smcm.RegisterScriptInvocation(this, "DummyTestMethod");
94 }
95 catch (ArgumentException)
96 {
97 Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier.");
98 }
99
100 // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods.
101 }
102
103 private object InvokeOp(string name, params object[] args)
104 {
105 return InvokeOpOnHost(name, UUID.Zero, args);
106 }
107
108 private object InvokeOpOnHost(string name, UUID hostId, params object[] args)
109 {
110 return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args);
111 }
112
113 [Test]
114 public void TestJsonCreateStore()
115 {
116 TestHelpers.InMethod();
117// TestHelpers.EnableLogging();
118
119 // Test blank store
120 {
121 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
122 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
123 }
124
125 // Test single element store
126 {
127 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
128 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
129 }
130
131 // Test with an integer value
132 {
133 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }");
134 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
135
136 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
137 Assert.That(value, Is.EqualTo("42.15"));
138 }
139
140 // Test with an array as the root node
141 {
142 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]");
143 Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
144
145 string value = (string)InvokeOp("JsonGetValue", storeId, "[1]");
146 Assert.That(value, Is.EqualTo("two"));
147 }
148 }
149
150 [Test]
151 public void TestJsonDestroyStore()
152 {
153 TestHelpers.InMethod();
154// TestHelpers.EnableLogging();
155
156 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
157 int dsrv = (int)InvokeOp("JsonDestroyStore", storeId);
158
159 Assert.That(dsrv, Is.EqualTo(1));
160
161 int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
162 Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
163 }
164
165 [Test]
166 public void TestJsonDestroyStoreNotExists()
167 {
168 TestHelpers.InMethod();
169// TestHelpers.EnableLogging();
170
171 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
172
173 int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId);
174
175 Assert.That(dsrv, Is.EqualTo(0));
176 }
177
178 [Test]
179 public void TestJsonGetValue()
180 {
181 TestHelpers.InMethod();
182// TestHelpers.EnableLogging();
183
184 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
185
186 {
187 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World");
188 Assert.That(value, Is.EqualTo("Two"));
189 }
190
191 // Test get of path section instead of leaf
192 {
193 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
194 Assert.That(value, Is.EqualTo(""));
195 }
196
197 // Test get of non-existing value
198 {
199 string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo");
200 Assert.That(fakeValueGet, Is.EqualTo(""));
201 }
202
203 // Test get from non-existing store
204 {
205 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
206 string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
207 Assert.That(fakeStoreValueGet, Is.EqualTo(""));
208 }
209 }
210
211 [Test]
212 public void TestJsonGetJson()
213 {
214 TestHelpers.InMethod();
215// TestHelpers.EnableLogging();
216
217 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }");
218
219 {
220 string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World");
221 Assert.That(value, Is.EqualTo("'Two'"));
222 }
223
224 // Test get of path section instead of leaf
225 {
226 string value = (string)InvokeOp("JsonGetJson", storeId, "Hello");
227 Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}"));
228 }
229
230 // Test get of non-existing value
231 {
232 string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo");
233 Assert.That(fakeValueGet, Is.EqualTo(""));
234 }
235
236 // Test get from non-existing store
237 {
238 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
239 string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello");
240 Assert.That(fakeStoreValueGet, Is.EqualTo(""));
241 }
242 }
243
244// [Test]
245// public void TestJsonTakeValue()
246// {
247// TestHelpers.InMethod();
248//// TestHelpers.EnableLogging();
249//
250// UUID storeId
251// = (UUID)m_smcm.InvokeOperation(
252// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
253//
254// string value
255// = (string)m_smcm.InvokeOperation(
256// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" });
257//
258// Assert.That(value, Is.EqualTo("World"));
259//
260// string value2
261// = (string)m_smcm.InvokeOperation(
262// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
263//
264// Assert.That(value, Is.Null);
265// }
266
267 [Test]
268 public void TestJsonRemoveValue()
269 {
270 TestHelpers.InMethod();
271// TestHelpers.EnableLogging();
272
273 // Test remove of node in object pointing to a string
274 {
275 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
276
277 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
278 Assert.That(returnValue, Is.EqualTo(1));
279
280 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
281 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
282
283 string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
284 Assert.That(returnValue2, Is.EqualTo(""));
285 }
286
287 // Test remove of node in object pointing to another object
288 {
289 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }");
290
291 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
292 Assert.That(returnValue, Is.EqualTo(1));
293
294 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
295 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
296
297 string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello");
298 Assert.That(returnValue2, Is.EqualTo(""));
299 }
300
301 // Test remove of node in an array
302 {
303 UUID storeId
304 = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }");
305
306 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]");
307 Assert.That(returnValue, Is.EqualTo(1));
308
309 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]");
310 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
311
312 result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]");
313 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
314
315 string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]");
316 Assert.That(stringReturnValue, Is.EqualTo("value2"));
317
318 stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]");
319 Assert.That(stringReturnValue, Is.EqualTo(""));
320 }
321
322 // Test remove of non-existing value
323 {
324 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
325
326 int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese");
327 Assert.That(fakeValueRemove, Is.EqualTo(0));
328 }
329
330 {
331 // Test get from non-existing store
332 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
333 int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello");
334 Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
335 }
336 }
337
338// [Test]
339// public void TestJsonTestPath()
340// {
341// TestHelpers.InMethod();
342//// TestHelpers.EnableLogging();
343//
344// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
345//
346// {
347// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
348// Assert.That(result, Is.EqualTo(1));
349// }
350//
351// // Test for path which does not resolve to a value.
352// {
353// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
354// Assert.That(result, Is.EqualTo(0));
355// }
356//
357// {
358// int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
359// Assert.That(result2, Is.EqualTo(0));
360// }
361//
362// // Test with fake store
363// {
364// UUID fakeStoreId = TestHelpers.ParseTail(0x500);
365// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
366// Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
367// }
368// }
369
370// [Test]
371// public void TestJsonTestPathJson()
372// {
373// TestHelpers.InMethod();
374//// TestHelpers.EnableLogging();
375//
376// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }");
377//
378// {
379// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
380// Assert.That(result, Is.EqualTo(1));
381// }
382//
383// // Test for path which does not resolve to a value.
384// {
385// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
386// Assert.That(result, Is.EqualTo(1));
387// }
388//
389// {
390// int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
391// Assert.That(result2, Is.EqualTo(0));
392// }
393//
394// // Test with fake store
395// {
396// UUID fakeStoreId = TestHelpers.ParseTail(0x500);
397// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
398// Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
399// }
400// }
401
402 [Test]
403 public void TestJsonGetArrayLength()
404 {
405 TestHelpers.InMethod();
406// TestHelpers.EnableLogging();
407
408 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
409
410 {
411 int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World");
412 Assert.That(result, Is.EqualTo(2));
413 }
414
415 // Test path which is not an array
416 {
417 int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello");
418 Assert.That(result, Is.EqualTo(-1));
419 }
420
421 // Test fake path
422 {
423 int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo");
424 Assert.That(result, Is.EqualTo(-1));
425 }
426
427 // Test fake store
428 {
429 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
430 int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World");
431 Assert.That(result, Is.EqualTo(-1));
432 }
433 }
434
435 [Test]
436 public void TestJsonGetNodeType()
437 {
438 TestHelpers.InMethod();
439// TestHelpers.EnableLogging();
440
441 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
442
443 {
444 int result = (int)InvokeOp("JsonGetNodeType", storeId, ".");
445 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT));
446 }
447
448 {
449 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
450 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT));
451 }
452
453 {
454 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World");
455 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY));
456 }
457
458 {
459 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]");
460 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
461 }
462
463 {
464 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]");
465 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
466 }
467
468 // Test for non-existant path
469 {
470 int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo");
471 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
472 }
473
474 // Test for non-existant store
475 {
476 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
477 int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, ".");
478 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
479 }
480 }
481
482 [Test]
483 public void TestJsonList2Path()
484 {
485 TestHelpers.InMethod();
486// TestHelpers.EnableLogging();
487
488 // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason
489 // - some confusion with the methods that take a params object[] invocation.
490 {
491 string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" });
492 Assert.That(result, Is.EqualTo("{foo}"));
493 }
494
495 {
496 string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" });
497 Assert.That(result, Is.EqualTo("{foo}.{bar}"));
498 }
499
500 {
501 string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" });
502 Assert.That(result, Is.EqualTo("{foo}.[1].{bar}"));
503 }
504 }
505
506 [Test]
507 public void TestJsonSetValue()
508 {
509 TestHelpers.InMethod();
510// TestHelpers.EnableLogging();
511
512 {
513 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
514
515 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times");
516 Assert.That(result, Is.EqualTo(1));
517
518 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
519 Assert.That(value, Is.EqualTo("Times"));
520 }
521
522 // Test setting a key containing periods with delineation
523 {
524 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
525
526 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times");
527 Assert.That(result, Is.EqualTo(1));
528
529 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}");
530 Assert.That(value, Is.EqualTo("Times"));
531 }
532
533 // *** Test [] ***
534
535 // Test setting a key containing unbalanced ] without delineation. Expecting failure
536 {
537 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
538
539 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times");
540 Assert.That(result, Is.EqualTo(0));
541
542 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus");
543 Assert.That(value, Is.EqualTo(""));
544 }
545
546 // Test setting a key containing unbalanced [ without delineation. Expecting failure
547 {
548 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
549
550 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times");
551 Assert.That(result, Is.EqualTo(0));
552
553 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus");
554 Assert.That(value, Is.EqualTo(""));
555 }
556
557 // Test setting a key containing unbalanced [] without delineation. Expecting failure
558 {
559 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
560
561 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times");
562 Assert.That(result, Is.EqualTo(0));
563
564 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus");
565 Assert.That(value, Is.EqualTo(""));
566 }
567
568 // Test setting a key containing unbalanced ] with delineation
569 {
570 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
571
572 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times");
573 Assert.That(result, Is.EqualTo(1));
574
575 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}");
576 Assert.That(value, Is.EqualTo("Times"));
577 }
578
579 // Test setting a key containing unbalanced [ with delineation
580 {
581 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
582
583 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times");
584 Assert.That(result, Is.EqualTo(1));
585
586 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}");
587 Assert.That(value, Is.EqualTo("Times"));
588 }
589
590 // Test setting a key containing empty balanced [] with delineation
591 {
592 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
593
594 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times");
595 Assert.That(result, Is.EqualTo(1));
596
597 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}");
598 Assert.That(value, Is.EqualTo("Times"));
599 }
600
601// // Commented out as this currently unexpectedly fails.
602// // Test setting a key containing brackets around an integer with delineation
603// {
604// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
605//
606// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times");
607// Assert.That(result, Is.EqualTo(1));
608//
609// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}");
610// Assert.That(value, Is.EqualTo("Times"));
611// }
612
613 // *** Test {} ***
614
615 // Test setting a key containing unbalanced } without delineation. Expecting failure (?)
616 {
617 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
618
619 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times");
620 Assert.That(result, Is.EqualTo(0));
621
622 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
623 Assert.That(value, Is.EqualTo(""));
624 }
625
626 // Test setting a key containing unbalanced { without delineation. Expecting failure (?)
627 {
628 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
629
630 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times");
631 Assert.That(result, Is.EqualTo(0));
632
633 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
634 Assert.That(value, Is.EqualTo(""));
635 }
636
637// // Commented out as this currently unexpectedly fails.
638// // Test setting a key containing unbalanced }
639// {
640// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
641//
642// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times");
643// Assert.That(result, Is.EqualTo(0));
644// }
645
646 // Test setting a key containing unbalanced { with delineation
647 {
648 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
649
650 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times");
651 Assert.That(result, Is.EqualTo(1));
652
653 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}");
654 Assert.That(value, Is.EqualTo("Times"));
655 }
656
657 // Test setting a key containing balanced {} with delineation. This should fail.
658 {
659 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
660
661 int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times");
662 Assert.That(result, Is.EqualTo(0));
663
664 string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}");
665 Assert.That(value, Is.EqualTo(""));
666 }
667
668 // Test setting to location that does not exist. This should fail.
669 {
670 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
671
672 int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times");
673 Assert.That(result, Is.EqualTo(0));
674
675 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
676 Assert.That(value, Is.EqualTo(""));
677 }
678
679 // Test with fake store
680 {
681 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
682 int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World");
683 Assert.That(fakeStoreValueSet, Is.EqualTo(0));
684 }
685 }
686
687 [Test]
688 public void TestJsonSetJson()
689 {
690 TestHelpers.InMethod();
691// TestHelpers.EnableLogging();
692
693 // Single quoted token case
694 {
695 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
696
697 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'");
698 Assert.That(result, Is.EqualTo(1));
699
700 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
701 Assert.That(value, Is.EqualTo("Times"));
702 }
703
704 // Sub-tree case
705 {
706 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
707
708 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
709 Assert.That(result, Is.EqualTo(1));
710
711 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled");
712 Assert.That(value, Is.EqualTo("Times"));
713 }
714
715 // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings.
716 {
717 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
718
719 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times");
720 Assert.That(result, Is.EqualTo(0));
721
722 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
723 Assert.That(value, Is.EqualTo(""));
724 }
725
726 // Test setting to location that does not exist. This should fail.
727 {
728 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }");
729
730 int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'");
731 Assert.That(result, Is.EqualTo(0));
732
733 string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
734 Assert.That(value, Is.EqualTo(""));
735 }
736
737 // Test with fake store
738 {
739 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
740 int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'");
741 Assert.That(fakeStoreValueSet, Is.EqualTo(0));
742 }
743 }
744
745 /// <summary>
746 /// Test for writing json to a notecard
747 /// </summary>
748 /// <remarks>
749 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
750 /// it via the MockScriptEngine or perhaps by a dummy script instance.
751 /// </remarks>
752 [Test]
753 public void TestJsonWriteNotecard()
754 {
755 TestHelpers.InMethod();
756// TestHelpers.EnableLogging();
757
758 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
759 m_scene.AddSceneObject(so);
760
761 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
762
763 {
764 string notecardName = "nc1";
765
766 // Write notecard
767 UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName);
768 Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
769
770 TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
771 Assert.That(nc1Item, Is.Not.Null);
772
773 // TODO: Should independently check the contents.
774 }
775
776 // TODO: Write partial test
777
778 {
779 // Try to write notecard for a bad path
780 // In this case we do get a request id but no notecard is written.
781 string badPathNotecardName = "badPathNotecardName";
782
783 UUID writeNotecardBadPathRequestId
784 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName);
785 Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero));
786
787 TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName);
788 Assert.That(badPathItem, Is.Null);
789 }
790
791 {
792 // Test with fake store
793 // In this case we do get a request id but no notecard is written.
794 string fakeStoreNotecardName = "fakeStoreNotecardName";
795
796 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
797 UUID fakeStoreWriteNotecardValue
798 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName);
799 Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
800
801 TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
802 Assert.That(fakeStoreItem, Is.Null);
803 }
804 }
805
806 /// <summary>
807 /// Test for reading json from a notecard
808 /// </summary>
809 /// <remarks>
810 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
811 /// it via the MockScriptEngine or perhaps by a dummy script instance.
812 /// </remarks>
813 [Test]
814 public void TestJsonReadNotecard()
815 {
816 TestHelpers.InMethod();
817// TestHelpers.EnableLogging();
818
819 string notecardName = "nc1";
820
821 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
822 m_scene.AddSceneObject(so);
823
824 UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
825
826 // Write notecard
827 InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName);
828
829 {
830 // Read notecard
831 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
832 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName);
833 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
834
835 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
836 Assert.That(value, Is.EqualTo("World"));
837 }
838
839 {
840 // Read notecard to new single component path
841 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
842 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName);
843 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
844
845 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
846 Assert.That(value, Is.EqualTo(""));
847
848 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello");
849 Assert.That(value, Is.EqualTo("World"));
850 }
851
852 {
853 // Read notecard to new multi-component path. This should not work.
854 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
855 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
856 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
857
858 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
859 Assert.That(value, Is.EqualTo(""));
860
861 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
862 Assert.That(value, Is.EqualTo(""));
863 }
864
865 {
866 // Read notecard to existing multi-component path. This should work
867 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
868 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
869 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
870
871 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
872 Assert.That(value, Is.EqualTo(""));
873
874 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
875 Assert.That(value, Is.EqualTo("World"));
876 }
877
878 {
879 // Read notecard to invalid path. This should not work.
880 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
881 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName);
882 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
883
884 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
885 Assert.That(value, Is.EqualTo(""));
886 }
887
888 {
889 // Try read notecard to fake store.
890 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
891 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName);
892 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
893
894 string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
895 Assert.That(value, Is.EqualTo(""));
896 }
897 }
898
899 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
900 }
901} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
index 6120a81..709d389 100644
--- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
46{ 46{
47 public class XmlRpcInfo 47 public class XmlRpcInfo
48 { 48 {
49 public UUID item;
49 public UUID channel; 50 public UUID channel;
50 public string uri; 51 public string uri;
51 } 52 }
@@ -88,6 +89,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
88 return; 89 return;
89 90
90 scene.RegisterModuleInterface<IXmlRpcRouter>(this); 91 scene.RegisterModuleInterface<IXmlRpcRouter>(this);
92
93 IScriptModule scriptEngine = scene.RequestModuleInterface<IScriptModule>();
94 if ( scriptEngine != null )
95 {
96 scriptEngine.OnScriptRemoved += this.ScriptRemoved;
97 scriptEngine.OnObjectRemoved += this.ObjectRemoved;
98
99 }
91 } 100 }
92 101
93 public void RegionLoaded(Scene scene) 102 public void RegionLoaded(Scene scene)
@@ -120,22 +129,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
120 129
121 public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) 130 public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri)
122 { 131 {
123 if (!m_Channels.ContainsKey(itemID)) 132 if (!m_Enabled)
124 { 133 return;
125 XmlRpcInfo info = new XmlRpcInfo();
126 info.channel = channel;
127 info.uri = uri;
128 134
129 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>( 135 m_log.InfoFormat("[XMLRPC GRID ROUTER]: New receiver Obj: {0} Ch: {1} ID: {2} URI: {3}",
130 "POST", m_ServerURI+"/RegisterChannel/", info); 136 objectID.ToString(), channel.ToString(), itemID.ToString(), uri);
131 137
132 if (!success) 138 XmlRpcInfo info = new XmlRpcInfo();
133 { 139 info.channel = channel;
134 m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); 140 info.uri = uri;
135 } 141 info.item = itemID;
142
143 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>(
144 "POST", m_ServerURI+"/RegisterChannel/", info);
136 145
137 m_Channels[itemID] = channel; 146 if (!success)
147 {
148 m_log.Error("[XMLRPC GRID ROUTER] Error contacting server");
138 } 149 }
150
151 m_Channels[itemID] = channel;
152
153 }
154
155 public void UnRegisterReceiver(string channelID, UUID itemID)
156 {
157 if (!m_Enabled)
158 return;
159
160 RemoveChannel(itemID);
161
139 } 162 }
140 163
141 public void ScriptRemoved(UUID itemID) 164 public void ScriptRemoved(UUID itemID)
@@ -143,10 +166,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
143 if (!m_Enabled) 166 if (!m_Enabled)
144 return; 167 return;
145 168
146 if (m_Channels.ContainsKey(itemID)) 169 RemoveChannel(itemID);
170
171 }
172
173 public void ObjectRemoved(UUID objectID)
174 {
175 // m_log.InfoFormat("[XMLRPC GRID ROUTER]: Object Removed {0}",objectID.ToString());
176 }
177
178 private bool RemoveChannel(UUID itemID)
179 {
180 if(!m_Channels.ContainsKey(itemID))
181 {
182 m_log.InfoFormat("[XMLRPC GRID ROUTER]: Attempted to unregister non-existing Item: {0}", itemID.ToString());
183 return false;
184 }
185
186 XmlRpcInfo info = new XmlRpcInfo();
187
188 info.channel = m_Channels[itemID];
189 info.item = itemID;
190 info.uri = "http://0.0.0.0:00";
191
192 if (info != null)
147 { 193 {
148 bool success = SynchronousRestObjectRequester.MakeRequest<UUID, bool>( 194 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>(
149 "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]); 195 "POST", m_ServerURI+"/RemoveChannel/", info);
150 196
151 if (!success) 197 if (!success)
152 { 198 {
@@ -154,11 +200,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
154 } 200 }
155 201
156 m_Channels.Remove(itemID); 202 m_Channels.Remove(itemID);
203 return true;
157 } 204 }
158 } 205 return false;
159
160 public void ObjectRemoved(UUID objectID)
161 {
162 } 206 }
163 } 207 }
164} 208}
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs
index 4bde52a..32549d6 100644
--- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs
@@ -104,12 +104,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule
104 } 104 }
105 } 105 }
106 106
107 public void UnRegisterReceiver(string channelID, UUID itemID)
108 {
109 }
110
107 public void ScriptRemoved(UUID itemID) 111 public void ScriptRemoved(UUID itemID)
108 { 112 {
113 // System.Console.WriteLine("TEST Script Removed!");
109 } 114 }
110 115
111 public void ObjectRemoved(UUID objectID) 116 public void ObjectRemoved(UUID objectID)
112 { 117 {
118 // System.Console.WriteLine("TEST Obj Removed!");
113 } 119 }
114 } 120 }
115} 121}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs
new file mode 100644
index 0000000..7919fef
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs
@@ -0,0 +1,228 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Reflection;
31using System.Text;
32using System.Collections.Generic;
33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35using OpenSim;
36using OpenSim.Region;
37using OpenSim.Region.Framework;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using Nini.Config;
44using log4net;
45using Mono.Addins;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47using OSDMap = OpenMetaverse.StructuredData.OSDMap;
48
49namespace 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 m_floaters[agentID].Add(dialogData.Channel, dialogData);
126
127 string xml;
128 using (FileStream fs = File.Open(dialogData.XmlName + ".xml", FileMode.Open))
129 {
130 using (StreamReader sr = new StreamReader(fs))
131 xml = sr.ReadToEnd().Replace("\n", "");
132 }
133
134 List<string> xparts = new List<string>();
135
136 while (xml.Length > 0)
137 {
138 string x = xml;
139 if (x.Length > 600)
140 {
141 x = x.Substring(0, 600);
142 xml = xml.Substring(600);
143 }
144 else
145 {
146 xml = String.Empty;
147 }
148
149 xparts.Add(x);
150 }
151
152 for (int i = 0 ; i < xparts.Count ; i++)
153 SendToClient(sp, String.Format("># floater {2} create {0}/{1} " + xparts[i], i + 1, xparts.Count, dialogData.FloaterName));
154
155 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));
156 }
157
158 private void OnChatFromClient(object sender, OSChatMessage msg)
159 {
160 if (msg.Sender == null)
161 return;
162
163 //m_log.DebugFormat("chan {0} msg {1}", msg.Channel, msg.Message);
164
165 IClientAPI client = msg.Sender;
166
167 if (!m_floaters.ContainsKey(client.AgentId))
168 return;
169
170 string[] parts = msg.Message.Split(new char[] {':'});
171 if (parts.Length == 0)
172 return;
173
174 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
175 if (sp == null || sp.IsChildAgent)
176 return;
177
178 Dictionary<int, FloaterData> d = m_floaters[client.AgentId];
179
180 // Work around a viewer bug - VALUE from any
181 // dialog can appear on this channel and needs to
182 // be dispatched to ALL open dialogs for the user
183 if (msg.Channel == 427169570)
184 {
185 if (parts[0] == "VALUE")
186 {
187 foreach (FloaterData dd in d.Values)
188 {
189 if(dd.Handler(client, dd, parts))
190 {
191 m_floaters[client.AgentId].Remove(dd.Channel);
192 SendToClient(sp, String.Format("># floater {0} destroy", dd.FloaterName));
193 break;
194 }
195 }
196 }
197 return;
198 }
199
200 if (!d.ContainsKey(msg.Channel))
201 return;
202
203 FloaterData data = d[msg.Channel];
204
205 if (parts[0] == "NOTIFY")
206 {
207 if (parts[1] == "cancel" || parts[1] == data.FloaterName)
208 {
209 m_floaters[client.AgentId].Remove(data.Channel);
210 SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName));
211 }
212 }
213
214 if (data.Handler(client, data, parts))
215 {
216 m_floaters[client.AgentId].Remove(data.Channel);
217 SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName));
218 }
219 }
220
221 public void FloaterControl(ScenePresence sp, FloaterData d, string msg)
222 {
223 string sendData = String.Format("># floater {0} {1}", d.FloaterName, msg);
224 SendToClient(sp, sendData);
225
226 }
227 }
228}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
new file mode 100644
index 0000000..917911f
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
@@ -0,0 +1,282 @@
1// ******************************************************************
2// Copyright (c) 2008, 2009 Melanie Thielker
3//
4// All rights reserved
5//
6
7using System;
8using System.IO;
9using System.Reflection;
10using System.Text;
11using System.Collections.Generic;
12using OpenMetaverse;
13using OpenMetaverse.StructuredData;
14using OpenSim;
15using OpenSim.Region;
16using OpenSim.Region.Framework;
17using OpenSim.Region.Framework.Scenes;
18using OpenSim.Region.Framework.Interfaces;
19using OpenSim.Framework;
20//using OpenSim.Framework.Capabilities;
21using OpenSim.Framework.Servers;
22using OpenSim.Framework.Servers.HttpServer;
23using Nini.Config;
24using log4net;
25using Mono.Addins;
26using Caps = OpenSim.Framework.Capabilities.Caps;
27using OSDMap = OpenMetaverse.StructuredData.OSDMap;
28
29namespace OpenSim.Region.OptionalModules.ViewerSupport
30{
31 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicMenu")]
32 public class DynamicMenuModule : INonSharedRegionModule, IDynamicMenuModule
33 {
34 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
35
36 private class MenuItemData
37 {
38 public string Title;
39 public UUID AgentID;
40 public InsertLocation Location;
41 public UserMode Mode;
42 public CustomMenuHandler Handler;
43 }
44
45 private Dictionary<UUID, List<MenuItemData>> m_menuItems =
46 new Dictionary<UUID, List<MenuItemData>>();
47
48 private Scene m_scene;
49
50 public string Name
51 {
52 get { return "DynamicMenuModule"; }
53 }
54
55 public Type ReplaceableInterface
56 {
57 get { return null; }
58 }
59
60 public void Initialise(IConfigSource config)
61 {
62 }
63
64 public void Close()
65 {
66 }
67
68 public void AddRegion(Scene scene)
69 {
70 m_scene = scene;
71 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
72 m_scene.RegisterModuleInterface<IDynamicMenuModule>(this);
73 }
74
75 public void RegionLoaded(Scene scene)
76 {
77 ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface<ISimulatorFeaturesModule>();
78
79 if (featuresModule != null)
80 featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
81 }
82
83 public void RemoveRegion(Scene scene)
84 {
85 }
86
87 private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
88 {
89 OSD menus = new OSDMap();
90 if (features.ContainsKey("menus"))
91 menus = features["menus"];
92
93 OSDMap agent = new OSDMap();
94 OSDMap world = new OSDMap();
95 OSDMap tools = new OSDMap();
96 OSDMap advanced = new OSDMap();
97 OSDMap admin = new OSDMap();
98 if (((OSDMap)menus).ContainsKey("agent"))
99 agent = (OSDMap)((OSDMap)menus)["agent"];
100 if (((OSDMap)menus).ContainsKey("world"))
101 world = (OSDMap)((OSDMap)menus)["world"];
102 if (((OSDMap)menus).ContainsKey("tools"))
103 tools = (OSDMap)((OSDMap)menus)["tools"];
104 if (((OSDMap)menus).ContainsKey("advanced"))
105 advanced = (OSDMap)((OSDMap)menus)["advanced"];
106 if (((OSDMap)menus).ContainsKey("admin"))
107 admin = (OSDMap)((OSDMap)menus)["admin"];
108
109 if (m_menuItems.ContainsKey(UUID.Zero))
110 {
111 foreach (MenuItemData d in m_menuItems[UUID.Zero])
112 {
113 if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID)))
114 continue;
115
116 OSDMap loc = null;
117 switch (d.Location)
118 {
119 case InsertLocation.Agent:
120 loc = agent;
121 break;
122 case InsertLocation.World:
123 loc = world;
124 break;
125 case InsertLocation.Tools:
126 loc = tools;
127 break;
128 case InsertLocation.Advanced:
129 loc = advanced;
130 break;
131 case InsertLocation.Admin:
132 loc = admin;
133 break;
134 }
135
136 if (loc == null)
137 continue;
138
139 loc[d.Title] = OSD.FromString(d.Title);
140 }
141 }
142
143 if (m_menuItems.ContainsKey(agentID))
144 {
145 foreach (MenuItemData d in m_menuItems[agentID])
146 {
147 if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID)))
148 continue;
149
150 OSDMap loc = null;
151 switch (d.Location)
152 {
153 case InsertLocation.Agent:
154 loc = agent;
155 break;
156 case InsertLocation.World:
157 loc = world;
158 break;
159 case InsertLocation.Tools:
160 loc = tools;
161 break;
162 case InsertLocation.Advanced:
163 loc = advanced;
164 break;
165 case InsertLocation.Admin:
166 loc = admin;
167 break;
168 }
169
170 if (loc == null)
171 continue;
172
173 loc[d.Title] = OSD.FromString(d.Title);
174 }
175 }
176
177
178 ((OSDMap)menus)["agent"] = agent;
179 ((OSDMap)menus)["world"] = world;
180 ((OSDMap)menus)["tools"] = tools;
181 ((OSDMap)menus)["advanced"] = advanced;
182 ((OSDMap)menus)["admin"] = admin;
183
184 features["menus"] = menus;
185 }
186
187 private void OnRegisterCaps(UUID agentID, Caps caps)
188 {
189 string capUrl = "/CAPS/" + UUID.Random() + "/";
190
191 capUrl = "/CAPS/" + UUID.Random() + "/";
192 caps.RegisterHandler("CustomMenuAction", new MenuActionHandler(capUrl, "CustomMenuAction", agentID, this, m_scene));
193 }
194
195 internal void HandleMenuSelection(string action, UUID agentID, List<uint> selection)
196 {
197 if (m_menuItems.ContainsKey(agentID))
198 {
199 foreach (MenuItemData d in m_menuItems[agentID])
200 {
201 if (d.Title == action)
202 d.Handler(action, agentID, selection);
203 }
204 }
205
206 if (m_menuItems.ContainsKey(UUID.Zero))
207 {
208 foreach (MenuItemData d in m_menuItems[UUID.Zero])
209 {
210 if (d.Title == action)
211 d.Handler(action, agentID, selection);
212 }
213 }
214 }
215
216 public void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
217 {
218 AddMenuItem(UUID.Zero, title, location, mode, handler);
219 }
220
221 public void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
222 {
223 if (!m_menuItems.ContainsKey(agentID))
224 m_menuItems[agentID] = new List<MenuItemData>();
225
226 m_menuItems[agentID].Add(new MenuItemData() { Title = title, AgentID = agentID, Location = location, Mode = mode, Handler = handler });
227 }
228
229 public void RemoveMenuItem(string action)
230 {
231 foreach (KeyValuePair<UUID,List< MenuItemData>> kvp in m_menuItems)
232 {
233 List<MenuItemData> pendingDeletes = new List<MenuItemData>();
234 foreach (MenuItemData d in kvp.Value)
235 {
236 if (d.Title == action)
237 pendingDeletes.Add(d);
238 }
239
240 foreach (MenuItemData d in pendingDeletes)
241 kvp.Value.Remove(d);
242 }
243 }
244 }
245
246 public class MenuActionHandler : BaseStreamHandler
247 {
248 private static readonly ILog m_log =
249 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
250
251 private UUID m_agentID;
252 private Scene m_scene;
253 private DynamicMenuModule m_module;
254
255 public MenuActionHandler(string path, string name, UUID agentID, DynamicMenuModule module, Scene scene)
256 :base("POST", path, name, agentID.ToString())
257 {
258 m_agentID = agentID;
259 m_scene = scene;
260 m_module = module;
261 }
262
263 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
264 {
265 StreamReader reader = new StreamReader(request);
266 string requestBody = reader.ReadToEnd();
267
268 OSD osd = OSDParser.DeserializeLLSDXml(requestBody);
269
270 string action = ((OSDMap)osd)["action"].AsString();
271 OSDArray selection = (OSDArray)((OSDMap)osd)["selection"];
272 List<uint> sel = new List<uint>();
273 for (int i = 0 ; i < selection.Count ; i++)
274 sel.Add(selection[i].AsUInteger());
275
276 Util.FireAndForget(x => { m_module.HandleMenuSelection(action, m_agentID, sel); });
277
278 Encoding encoding = Encoding.UTF8;
279 return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD()));
280 }
281 }
282}
diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
index c7e3a7a..be020e4 100644
--- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
+++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
49 /// (such as land transfers). There is no money code here! Use FORGE as an example for money code. 49 /// (such as land transfers). There is no money code here! Use FORGE as an example for money code.
50 /// Demo Economy/Money Module. This is a purposely crippled module! 50 /// Demo Economy/Money Module. This is a purposely crippled module!
51 /// // To land transfer you need to add: 51 /// // To land transfer you need to add:
52 /// -helperuri <ADDRESS TO THIS SERVER> 52 /// -helperuri http://serveraddress:port/
53 /// to the command line parameters you use to start up your client 53 /// to the command line parameters you use to start up your client
54 /// This commonly looks like -helperuri http://127.0.0.1:9000/ 54 /// This commonly looks like -helperuri http://127.0.0.1:9000/
55 /// 55 ///
@@ -116,10 +116,9 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
116 } 116 }
117 117
118 /// <summary> 118 /// <summary>
119 /// Startup 119 /// Called on startup so the module can be configured.
120 /// </summary> 120 /// </summary>
121 /// <param name="scene"></param> 121 /// <param name="config">Configuration source.</param>
122 /// <param name="config"></param>
123 public void Initialise(IConfigSource config) 122 public void Initialise(IConfigSource config)
124 { 123 {
125 m_gConfig = config; 124 m_gConfig = config;
@@ -674,9 +673,12 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
674 } 673 }
675 674
676 /// <summary> 675 /// <summary>
677 /// When the client closes the connection we remove their accounting info from memory to free up resources. 676 /// When the client closes the connection we remove their accounting
677 /// info from memory to free up resources.
678 /// </summary> 678 /// </summary>
679 /// <param name="AgentID"></param> 679 /// <param name="AgentID">UUID of agent</param>
680 /// <param name="scene">Scene the agent was connected to.</param>
681 /// <see cref="OpenSim.Region.Framework.Scenes.EventManager.ClientClosed"/>
680 public void ClientClosed(UUID AgentID, Scene scene) 682 public void ClientClosed(UUID AgentID, Scene scene)
681 { 683 {
682 684
@@ -686,19 +688,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
686 /// Event called Economy Data Request handler. 688 /// Event called Economy Data Request handler.
687 /// </summary> 689 /// </summary>
688 /// <param name="agentId"></param> 690 /// <param name="agentId"></param>
689 public void EconomyDataRequestHandler(UUID agentId) 691 public void EconomyDataRequestHandler(IClientAPI user)
690 { 692 {
691 IClientAPI user = LocateClientObject(agentId); 693 Scene s = LocateSceneClientIn(user.AgentId);
692 694
693 if (user != null) 695 user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate,
694 { 696 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor,
695 Scene s = LocateSceneClientIn(user.AgentId); 697 PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload,
696 698 TeleportMinPrice, TeleportPriceExponent);
697 user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate,
698 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor,
699 PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload,
700 TeleportMinPrice, TeleportPriceExponent);
701 }
702 } 699 }
703 700
704 private void ValidateLandBuy(Object osender, EventManager.LandBuyArgs e) 701 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 d665126..7918c22 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -630,12 +630,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC
630 630
631 } 631 }
632 632
633 public void SendGenericMessage(string method, List<string> message) 633 public void SendGenericMessage(string method, UUID invoice, List<string> message)
634 { 634 {
635 635
636 } 636 }
637 637
638 public void SendGenericMessage(string method, List<byte[]> message) 638 public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
639 { 639 {
640 640
641 } 641 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index ef4005b..34362af 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock;
48namespace OpenSim.Region.OptionalModules.World.NPC.Tests 48namespace OpenSim.Region.OptionalModules.World.NPC.Tests
49{ 49{
50 [TestFixture] 50 [TestFixture]
51 public class NPCModuleTests 51 public class NPCModuleTests : OpenSimTestCase
52 { 52 {
53 private TestScene m_scene; 53 private TestScene m_scene;
54 private AvatarFactoryModule m_afMod; 54 private AvatarFactoryModule m_afMod;
@@ -74,6 +74,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
74 [SetUp] 74 [SetUp]
75 public void Init() 75 public void Init()
76 { 76 {
77 base.SetUp();
78
77 IConfigSource config = new IniConfigSource(); 79 IConfigSource config = new IniConfigSource();
78 config.AddConfig("NPC"); 80 config.AddConfig("NPC");
79 config.Configs["NPC"].Set("Enabled", "true"); 81 config.Configs["NPC"].Set("Enabled", "true");
diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs
new file mode 100644
index 0000000..29b39e0
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs
@@ -0,0 +1,266 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.OptionalModules.Avatar.Attachments
44{
45 /// <summary>
46 /// A module that just holds commands for inspecting avatar appearance.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SceneCommandsModule")]
49 public class SceneCommandsModule : ISceneCommandsModule, INonSharedRegionModule
50 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private Scene m_scene;
54
55 public string Name { get { return "Scene Commands Module"; } }
56
57 public Type ReplaceableInterface { get { return null; } }
58
59 public void Initialise(IConfigSource source)
60 {
61// m_log.DebugFormat("[SCENE COMMANDS MODULE]: INITIALIZED MODULE");
62 }
63
64 public void PostInitialise()
65 {
66// m_log.DebugFormat("[SCENE COMMANDS MODULE]: POST INITIALIZED MODULE");
67 }
68
69 public void Close()
70 {
71// m_log.DebugFormat("[SCENE COMMANDS MODULE]: CLOSED MODULE");
72 }
73
74 public void AddRegion(Scene scene)
75 {
76// m_log.DebugFormat("[SCENE COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
77
78 m_scene = scene;
79
80 m_scene.RegisterModuleInterface<ISceneCommandsModule>(this);
81 }
82
83 public void RemoveRegion(Scene scene)
84 {
85// m_log.DebugFormat("[SCENE COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
86 }
87
88 public void RegionLoaded(Scene scene)
89 {
90// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
91
92 scene.AddCommand(
93 "Debug", this, "debug scene get",
94 "debug scene get",
95 "List current scene options.",
96 "If active is 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 + "If collisions is false then collisions with other objects are turned off.\n"
99 + "If pbackup is false then periodic scene backup is turned off.\n"
100 + "If physics is false then all physics objects are non-physical.\n"
101 + "If scripting is false then no scripting operations happen.\n"
102 + "If teleport is true then some extra teleport debug information is logged.\n"
103 + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.",
104 HandleDebugSceneGetCommand);
105
106 scene.AddCommand(
107 "Debug", this, "debug scene set",
108 "debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false",
109 "Turn on scene debugging options.",
110 "If active is false then main scene update and maintenance loops are suspended.\n"
111 + "If animations is true then extra animations debug information is logged.\n"
112 + "If collisions is false then collisions with other objects are turned off.\n"
113 + "If pbackup is false then periodic scene backup is turned off.\n"
114 + "If physics is false then all physics objects are non-physical.\n"
115 + "If scripting is false then no scripting operations happen.\n"
116 + "If teleport is true then some extra teleport debug information is logged.\n"
117 + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.",
118 HandleDebugSceneSetCommand);
119
120 scene.AddCommand(
121 "Regions",
122 this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand);
123 }
124
125 private void HandleShowBordersCommand(string module, string[] args)
126 {
127 StringBuilder sb = new StringBuilder();
128 sb.AppendFormat("Borders for {0}:\n", m_scene.Name);
129
130 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
131 cdt.AddColumn("Cross Direction", 15);
132 cdt.AddColumn("Line", 34);
133 cdt.AddColumn("Trigger Region", 14);
134
135 foreach (Border b in m_scene.NorthBorders)
136 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
137
138 foreach (Border b in m_scene.EastBorders)
139 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
140
141 foreach (Border b in m_scene.SouthBorders)
142 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
143
144 foreach (Border b in m_scene.WestBorders)
145 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
146
147 cdt.AddToStringBuilder(sb);
148
149 MainConsole.Instance.Output(sb.ToString());
150 }
151
152 private void HandleDebugSceneGetCommand(string module, string[] args)
153 {
154 if (args.Length == 3)
155 {
156 if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
157 return;
158
159 OutputSceneDebugOptions();
160 }
161 else
162 {
163 MainConsole.Instance.Output("Usage: debug scene get");
164 }
165 }
166
167 private void OutputSceneDebugOptions()
168 {
169 ConsoleDisplayList cdl = new ConsoleDisplayList();
170 cdl.AddRow("active", m_scene.Active);
171 cdl.AddRow("animations", m_scene.DebugAnimations);
172 cdl.AddRow("pbackup", m_scene.PeriodicBackup);
173 cdl.AddRow("physics", m_scene.PhysicsEnabled);
174 cdl.AddRow("scripting", m_scene.ScriptsEnabled);
175 cdl.AddRow("teleport", m_scene.DebugTeleporting);
176 cdl.AddRow("updates", m_scene.DebugUpdates);
177
178 MainConsole.Instance.OutputFormat("Scene {0} options:", m_scene.Name);
179 MainConsole.Instance.Output(cdl.ToString());
180 }
181
182 private void HandleDebugSceneSetCommand(string module, string[] args)
183 {
184 if (args.Length == 5)
185 {
186 if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
187 return;
188
189 string key = args[3];
190 string value = args[4];
191 SetSceneDebugOptions(new Dictionary<string, string>() { { key, value } });
192
193 MainConsole.Instance.OutputFormat("Set {0} debug scene {1} = {2}", m_scene.Name, key, value);
194 }
195 else
196 {
197 MainConsole.Instance.Output(
198 "Usage: debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false");
199 }
200 }
201
202 public void SetSceneDebugOptions(Dictionary<string, string> options)
203 {
204 if (options.ContainsKey("active"))
205 {
206 bool active;
207
208 if (bool.TryParse(options["active"], out active))
209 m_scene.Active = active;
210 }
211
212 if (options.ContainsKey("animations"))
213 {
214 bool active;
215
216 if (bool.TryParse(options["animations"], out active))
217 m_scene.DebugAnimations = active;
218 }
219
220 if (options.ContainsKey("pbackup"))
221 {
222 bool active;
223
224 if (bool.TryParse(options["pbackup"], out active))
225 m_scene.PeriodicBackup = active;
226 }
227
228 if (options.ContainsKey("scripting"))
229 {
230 bool enableScripts = true;
231 if (bool.TryParse(options["scripting"], out enableScripts))
232 m_scene.ScriptsEnabled = enableScripts;
233 }
234
235 if (options.ContainsKey("physics"))
236 {
237 bool enablePhysics;
238 if (bool.TryParse(options["physics"], out enablePhysics))
239 m_scene.PhysicsEnabled = enablePhysics;
240 }
241
242// if (options.ContainsKey("collisions"))
243// {
244// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow
245// // the avatar themselves to collide with the ground.
246// }
247
248 if (options.ContainsKey("teleport"))
249 {
250 bool enableTeleportDebugging;
251 if (bool.TryParse(options["teleport"], out enableTeleportDebugging))
252 m_scene.DebugTeleporting = enableTeleportDebugging;
253 }
254
255 if (options.ContainsKey("updates"))
256 {
257 bool enableUpdateDebugging;
258 if (bool.TryParse(options["updates"], out enableUpdateDebugging))
259 {
260 m_scene.DebugUpdates = enableUpdateDebugging;
261 GcNotify.Enabled = enableUpdateDebugging;
262 }
263 }
264 }
265 }
266} \ No newline at end of file