aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs198
1 files changed, 134 insertions, 64 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 5a7446f..3b6d970 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -26,20 +26,37 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized;
32using System.IO;
33using System.Reflection;
34using System.Web;
35using System.Xml;
36using log4net;
37using Mono.Addins;
30using Nini.Config; 38using Nini.Config;
31using OpenMetaverse; 39using OpenMetaverse;
40using OpenMetaverse.Messages.Linden;
41using OpenMetaverse.StructuredData;
32using OpenSim.Framework; 42using OpenSim.Framework;
43using OpenSim.Framework.Capabilities;
44using OpenSim.Framework.Servers;
45using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Region.Framework.Scenes; 46using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
35 48using Caps = OpenSim.Framework.Capabilities.Caps;
36using Mono.Addins; 49using OSDArray = OpenMetaverse.StructuredData.OSDArray;
50using OSDMap = OpenMetaverse.StructuredData.OSDMap;
37 51
38namespace OpenSim.Region.CoreModules.Avatar.Gods 52namespace OpenSim.Region.CoreModules.Avatar.Gods
39{ 53{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")] 54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")]
41 public class GodsModule : INonSharedRegionModule, IGodsModule 55 public class GodsModule : INonSharedRegionModule, IGodsModule
42 { 56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
43 /// <summary>Special UUID for actions that apply to all agents</summary> 60 /// <summary>Special UUID for actions that apply to all agents</summary>
44 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb"); 61 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
45 62
@@ -65,6 +82,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
65 m_scene = scene; 82 m_scene = scene;
66 m_scene.RegisterModuleInterface<IGodsModule>(this); 83 m_scene.RegisterModuleInterface<IGodsModule>(this);
67 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 84 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
85 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
86 scene.EventManager.OnIncomingInstantMessage +=
87 OnIncomingInstantMessage;
68 } 88 }
69 89
70 public void RemoveRegion(Scene scene) 90 public void RemoveRegion(Scene scene)
@@ -98,6 +118,47 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
98 client.OnRequestGodlikePowers -= RequestGodlikePowers; 118 client.OnRequestGodlikePowers -= RequestGodlikePowers;
99 } 119 }
100 120
121 private void OnRegisterCaps(UUID agentID, Caps caps)
122 {
123 string uri = "/CAPS/" + UUID.Random();
124
125 caps.RegisterHandler(
126 "UntrustedSimulatorMessage",
127 new RestStreamHandler("POST", uri, HandleUntrustedSimulatorMessage, "UntrustedSimulatorMessage", null));
128 }
129
130 private string HandleUntrustedSimulatorMessage(string request,
131 string path, string param, IOSHttpRequest httpRequest,
132 IOSHttpResponse httpResponse)
133 {
134 OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
135
136 string message = osd["message"].AsString();
137
138 if (message == "GodKickUser")
139 {
140 OSDMap body = (OSDMap)osd["body"];
141 OSDArray userInfo = (OSDArray)body["UserInfo"];
142 OSDMap userData = (OSDMap)userInfo[0];
143
144 UUID agentID = userData["AgentID"].AsUUID();
145 UUID godID = userData["GodID"].AsUUID();
146 UUID godSessionID = userData["GodSessionID"].AsUUID();
147 uint kickFlags = userData["KickFlags"].AsUInteger();
148 string reason = userData["Reason"].AsString();
149 ScenePresence god = m_scene.GetScenePresence(godID);
150 if (god == null || god.ControllingClient.SessionId != godSessionID)
151 return String.Empty;
152
153 KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
154 }
155 else
156 {
157 m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
158 }
159 return String.Empty;
160 }
161
101 public void RequestGodlikePowers( 162 public void RequestGodlikePowers(
102 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) 163 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
103 { 164 {
@@ -146,76 +207,85 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
146 /// <param name="reason">The message to send to the user after it's been turned into a field</param> 207 /// <param name="reason">The message to send to the user after it's been turned into a field</param>
147 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason) 208 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
148 { 209 {
149 UUID kickUserID = ALL_AGENTS; 210 if (!m_scene.Permissions.IsGod(godID))
150 211 return;
212
151 ScenePresence sp = m_scene.GetScenePresence(agentID); 213 ScenePresence sp = m_scene.GetScenePresence(agentID);
152 214
153 if (sp != null || agentID == kickUserID) 215 if (sp == null && agentID != ALL_AGENTS)
154 { 216 {
155 if (m_scene.Permissions.IsGod(godID)) 217 IMessageTransferModule transferModule =
218 m_scene.RequestModuleInterface<IMessageTransferModule>();
219 if (transferModule != null)
156 { 220 {
157 if (kickflags == 0) 221 m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID);
158 { 222 transferModule.SendInstantMessage(new GridInstantMessage(
159 if (agentID == kickUserID) 223 m_scene, godID, "God", agentID, (byte)250, false,
160 { 224 Utils.BytesToString(reason), UUID.Zero, true,
161 string reasonStr = Utils.BytesToString(reason); 225 new Vector3(), new byte[] {(byte)kickflags}, true),
162 226 delegate(bool success) {} );
163 m_scene.ForEachClient( 227 }
164 delegate(IClientAPI controller) 228 return;
165 { 229 }
166 if (controller.AgentId != godID)
167 controller.Kick(reasonStr);
168 }
169 );
170
171 // This is a bit crude. It seems the client will be null before it actually stops the thread
172 // The thread will kill itself eventually :/
173 // Is there another way to make sure *all* clients get this 'inter region' message?
174 m_scene.ForEachRootClient(
175 delegate(IClientAPI client)
176 {
177 if (client.AgentId != godID)
178 {
179 client.Close();
180 }
181 }
182 );
183 }
184 else
185 {
186 m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
187 230
188 sp.ControllingClient.Kick(Utils.BytesToString(reason)); 231 switch (kickflags)
189 sp.ControllingClient.Close(); 232 {
190 } 233 case 0:
191 } 234 if (sp != null)
192 235 {
193 if (kickflags == 1) 236 KickPresence(sp, Utils.BytesToString(reason));
194 {
195 sp.AllowMovement = false;
196 if (DialogModule != null)
197 {
198 DialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
199 DialogModule.SendAlertToUser(godID, "User Frozen");
200 }
201 }
202
203 if (kickflags == 2)
204 {
205 sp.AllowMovement = true;
206 if (DialogModule != null)
207 {
208 DialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
209 DialogModule.SendAlertToUser(godID, "User Unfrozen");
210 }
211 }
212 } 237 }
213 else 238 else if (agentID == ALL_AGENTS)
214 { 239 {
215 if (DialogModule != null) 240 m_scene.ForEachRootScenePresence(
216 DialogModule.SendAlertToUser(godID, "Kick request denied"); 241 delegate(ScenePresence p)
242 {
243 if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
244 KickPresence(p, Utils.BytesToString(reason));
245 }
246 );
217 } 247 }
248 break;
249 case 1:
250 if (sp != null)
251 {
252 sp.AllowMovement = false;
253 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
254 m_dialogModule.SendAlertToUser(godID, "User Frozen");
255 }
256 break;
257 case 2:
258 if (sp != null)
259 {
260 sp.AllowMovement = true;
261 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
262 m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
263 }
264 break;
265 default:
266 break;
267 }
268 }
269
270 private void KickPresence(ScenePresence sp, string reason)
271 {
272 if (sp.IsChildAgent)
273 return;
274 sp.ControllingClient.Kick(reason);
275 sp.Scene.CloseAgent(sp.UUID, true);
276 }
277
278 private void OnIncomingInstantMessage(GridInstantMessage msg)
279 {
280 if (msg.dialog == (uint)250) // Nonlocal kick
281 {
282 UUID agentID = new UUID(msg.toAgentID);
283 string reason = msg.message;
284 UUID godID = new UUID(msg.fromAgentID);
285 uint kickMode = (uint)msg.binaryBucket[0];
286
287 KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
218 } 288 }
219 } 289 }
220 } 290 }
221} \ No newline at end of file 291}