diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 198 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Collections.Specialized; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | ||
34 | using System.Web; | ||
35 | using System.Xml; | ||
36 | using log4net; | ||
37 | using Mono.Addins; | ||
30 | using Nini.Config; | 38 | using Nini.Config; |
31 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | using OpenMetaverse.Messages.Linden; | ||
41 | using OpenMetaverse.StructuredData; | ||
32 | using OpenSim.Framework; | 42 | using OpenSim.Framework; |
43 | using OpenSim.Framework.Capabilities; | ||
44 | using OpenSim.Framework.Servers; | ||
45 | using OpenSim.Framework.Servers.HttpServer; | ||
33 | using OpenSim.Region.Framework.Scenes; | 46 | using OpenSim.Region.Framework.Scenes; |
34 | using OpenSim.Region.Framework.Interfaces; | 47 | using OpenSim.Region.Framework.Interfaces; |
35 | 48 | using Caps = OpenSim.Framework.Capabilities.Caps; | |
36 | using Mono.Addins; | 49 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; |
50 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
37 | 51 | ||
38 | namespace OpenSim.Region.CoreModules.Avatar.Gods | 52 | namespace 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 | } |