aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs199
1 files changed, 137 insertions, 62 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 5a7446f..d9badcd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -32,14 +32,35 @@ using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using System;
36using System.Reflection;
37using System.Collections;
38using System.Collections.Specialized;
39using System.Reflection;
40using System.IO;
41using System.Web;
42using System.Xml;
43using log4net;
35 44
36using Mono.Addins; 45using Mono.Addins;
37 46
47using OpenMetaverse.Messages.Linden;
48using OpenMetaverse.StructuredData;
49using OpenSim.Framework.Capabilities;
50using OpenSim.Framework.Servers;
51using OpenSim.Framework.Servers.HttpServer;
52using Caps = OpenSim.Framework.Capabilities.Caps;
53using OSDArray = OpenMetaverse.StructuredData.OSDArray;
54using OSDMap = OpenMetaverse.StructuredData.OSDMap;
55
38namespace OpenSim.Region.CoreModules.Avatar.Gods 56namespace OpenSim.Region.CoreModules.Avatar.Gods
39{ 57{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")] 58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")]
41 public class GodsModule : INonSharedRegionModule, IGodsModule 59 public class GodsModule : INonSharedRegionModule, IGodsModule
42 { 60 {
61 private static readonly ILog m_log =
62 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63
43 /// <summary>Special UUID for actions that apply to all agents</summary> 64 /// <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"); 65 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
45 66
@@ -65,6 +86,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
65 m_scene = scene; 86 m_scene = scene;
66 m_scene.RegisterModuleInterface<IGodsModule>(this); 87 m_scene.RegisterModuleInterface<IGodsModule>(this);
67 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 88 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
89 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
90 scene.EventManager.OnIncomingInstantMessage +=
91 OnIncomingInstantMessage;
68 } 92 }
69 93
70 public void RemoveRegion(Scene scene) 94 public void RemoveRegion(Scene scene)
@@ -98,6 +122,47 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
98 client.OnRequestGodlikePowers -= RequestGodlikePowers; 122 client.OnRequestGodlikePowers -= RequestGodlikePowers;
99 } 123 }
100 124
125 private void OnRegisterCaps(UUID agentID, Caps caps)
126 {
127 string uri = "/CAPS/" + UUID.Random();
128
129 caps.RegisterHandler("UntrustedSimulatorMessage",
130 new RestStreamHandler("POST", uri,
131 HandleUntrustedSimulatorMessage));
132 }
133
134 private string HandleUntrustedSimulatorMessage(string request,
135 string path, string param, IOSHttpRequest httpRequest,
136 IOSHttpResponse httpResponse)
137 {
138 OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
139
140 string message = osd["message"].AsString();
141
142 if (message == "GodKickUser")
143 {
144 OSDMap body = (OSDMap)osd["body"];
145 OSDArray userInfo = (OSDArray)body["UserInfo"];
146 OSDMap userData = (OSDMap)userInfo[0];
147
148 UUID agentID = userData["AgentID"].AsUUID();
149 UUID godID = userData["GodID"].AsUUID();
150 UUID godSessionID = userData["GodSessionID"].AsUUID();
151 uint kickFlags = userData["KickFlags"].AsUInteger();
152 string reason = userData["Reason"].AsString();
153 ScenePresence god = m_scene.GetScenePresence(godID);
154 if (god == null || god.ControllingClient.SessionId != godSessionID)
155 return String.Empty;
156
157 KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
158 }
159 else
160 {
161 m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
162 }
163 return String.Empty;
164 }
165
101 public void RequestGodlikePowers( 166 public void RequestGodlikePowers(
102 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) 167 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
103 { 168 {
@@ -146,76 +211,86 @@ 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> 211 /// <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) 212 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
148 { 213 {
149 UUID kickUserID = ALL_AGENTS; 214 if (!m_scene.Permissions.IsGod(godID))
150 215 return;
216
151 ScenePresence sp = m_scene.GetScenePresence(agentID); 217 ScenePresence sp = m_scene.GetScenePresence(agentID);
152 218
153 if (sp != null || agentID == kickUserID) 219 if (sp == null && agentID != ALL_AGENTS)
154 { 220 {
155 if (m_scene.Permissions.IsGod(godID)) 221 IMessageTransferModule transferModule =
222 m_scene.RequestModuleInterface<IMessageTransferModule>();
223 if (transferModule != null)
156 { 224 {
157 if (kickflags == 0) 225 m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID);
158 { 226 transferModule.SendInstantMessage(new GridInstantMessage(
159 if (agentID == kickUserID) 227 m_scene, godID, "God", agentID, (byte)250, false,
160 { 228 Utils.BytesToString(reason), UUID.Zero, true,
161 string reasonStr = Utils.BytesToString(reason); 229 new Vector3(), new byte[] {(byte)kickflags}, true),
162 230 delegate(bool success) {} );
163 m_scene.ForEachClient( 231 }
164 delegate(IClientAPI controller) 232 return;
165 { 233 }
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 234
188 sp.ControllingClient.Kick(Utils.BytesToString(reason)); 235 switch (kickflags)
189 sp.ControllingClient.Close(); 236 {
190 } 237 case 0:
191 } 238 if (sp != null)
192 239 {
193 if (kickflags == 1) 240 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 } 241 }
213 else 242 else if (agentID == ALL_AGENTS)
214 { 243 {
215 if (DialogModule != null) 244 m_scene.ForEachRootScenePresence(
216 DialogModule.SendAlertToUser(godID, "Kick request denied"); 245 delegate(ScenePresence p)
246 {
247 if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
248 KickPresence(p, Utils.BytesToString(reason));
249 }
250 );
217 } 251 }
252 break;
253 case 1:
254 if (sp != null)
255 {
256 sp.AllowMovement = false;
257 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
258 m_dialogModule.SendAlertToUser(godID, "User Frozen");
259 }
260 break;
261 case 2:
262 if (sp != null)
263 {
264 sp.AllowMovement = true;
265 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
266 m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
267 }
268 break;
269 default:
270 break;
271 }
272 }
273
274 private void KickPresence(ScenePresence sp, string reason)
275 {
276 if (sp.IsChildAgent)
277 return;
278 sp.ControllingClient.Kick(reason);
279 sp.MakeChildAgent();
280 sp.ControllingClient.Close();
281 }
282
283 private void OnIncomingInstantMessage(GridInstantMessage msg)
284 {
285 if (msg.dialog == (uint)250) // Nonlocal kick
286 {
287 UUID agentID = new UUID(msg.toAgentID);
288 string reason = msg.message;
289 UUID godID = new UUID(msg.fromAgentID);
290 uint kickMode = (uint)msg.binaryBucket[0];
291
292 KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
218 } 293 }
219 } 294 }
220 } 295 }
221} \ No newline at end of file 296}