diff options
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 175 |
1 files changed, 117 insertions, 58 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 5ec64d5..9fd3318 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | |||
@@ -31,16 +31,40 @@ using OpenMetaverse; | |||
31 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
32 | using OpenSim.Region.Framework.Scenes; | 32 | using OpenSim.Region.Framework.Scenes; |
33 | using OpenSim.Region.Framework.Interfaces; | 33 | using OpenSim.Region.Framework.Interfaces; |
34 | using System; | ||
35 | using System.Reflection; | ||
36 | using System.Collections; | ||
37 | using System.Collections.Specialized; | ||
38 | using System.Reflection; | ||
39 | using System.IO; | ||
40 | using System.Web; | ||
41 | using System.Xml; | ||
42 | using log4net; | ||
43 | using Mono.Addins; | ||
44 | using OpenMetaverse.Messages.Linden; | ||
45 | using OpenMetaverse.StructuredData; | ||
46 | using OpenSim.Framework.Capabilities; | ||
47 | using OpenSim.Framework.Servers; | ||
48 | using OpenSim.Framework.Servers.HttpServer; | ||
49 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
50 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; | ||
51 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
34 | 52 | ||
35 | namespace OpenSim.Region.CoreModules.Avatar.Gods | 53 | namespace OpenSim.Region.CoreModules.Avatar.Gods |
36 | { | 54 | { |
37 | public class GodsModule : IRegionModule, IGodsModule | 55 | public class GodsModule : IRegionModule, IGodsModule |
38 | { | 56 | { |
57 | private static readonly ILog m_log = | ||
58 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
59 | |||
39 | /// <summary>Special UUID for actions that apply to all agents</summary> | 60 | /// <summary>Special UUID for actions that apply to all agents</summary> |
40 | 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"); |
41 | 62 | ||
42 | protected Scene m_scene; | 63 | protected Scene m_scene; |
43 | protected IDialogModule m_dialogModule; | 64 | protected IDialogModule m_dialogModule; |
65 | |||
66 | protected Dictionary<UUID, string> m_capsDict = | ||
67 | new Dictionary<UUID, string>(); | ||
44 | 68 | ||
45 | public void Initialise(Scene scene, IConfigSource source) | 69 | public void Initialise(Scene scene, IConfigSource source) |
46 | { | 70 | { |
@@ -48,6 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
48 | m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); | 72 | m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); |
49 | m_scene.RegisterModuleInterface<IGodsModule>(this); | 73 | m_scene.RegisterModuleInterface<IGodsModule>(this); |
50 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 74 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
75 | m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; | ||
76 | m_scene.EventManager.OnClientClosed += OnClientClosed; | ||
51 | } | 77 | } |
52 | 78 | ||
53 | public void PostInitialise() {} | 79 | public void PostInitialise() {} |
@@ -67,6 +93,50 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
67 | client.OnRequestGodlikePowers -= RequestGodlikePowers; | 93 | client.OnRequestGodlikePowers -= RequestGodlikePowers; |
68 | } | 94 | } |
69 | 95 | ||
96 | private void OnClientClosed(UUID agentID, Scene scene) | ||
97 | { | ||
98 | m_capsDict.Remove(agentID); | ||
99 | } | ||
100 | |||
101 | private void OnRegisterCaps(UUID agentID, Caps caps) | ||
102 | { | ||
103 | string uri = "/CAPS/" + UUID.Random(); | ||
104 | m_capsDict[agentID] = uri; | ||
105 | |||
106 | caps.RegisterHandler("UntrustedSimulatorMessage", | ||
107 | new RestStreamHandler("POST", uri, | ||
108 | HandleUntrustedSimulatorMessage)); | ||
109 | } | ||
110 | |||
111 | private string HandleUntrustedSimulatorMessage(string request, | ||
112 | string path, string param, OSHttpRequest httpRequest, | ||
113 | OSHttpResponse httpResponse) | ||
114 | { | ||
115 | OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request); | ||
116 | |||
117 | string message = osd["message"].AsString(); | ||
118 | |||
119 | if (message == "GodKickUser") | ||
120 | { | ||
121 | OSDMap body = (OSDMap)osd["body"]; | ||
122 | OSDArray userInfo = (OSDArray)body["UserInfo"]; | ||
123 | OSDMap userData = (OSDMap)userInfo[0]; | ||
124 | |||
125 | UUID agentID = userData["AgentID"].AsUUID(); | ||
126 | UUID godID = userData["GodID"].AsUUID(); | ||
127 | UUID godSessionID = userData["GodSessionID"].AsUUID(); | ||
128 | uint kickFlags = userData["KickFlags"].AsUInteger(); | ||
129 | string reason = userData["Reason"].AsString(); | ||
130 | |||
131 | KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason)); | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message); | ||
136 | } | ||
137 | return String.Empty; | ||
138 | } | ||
139 | |||
70 | public void RequestGodlikePowers( | 140 | public void RequestGodlikePowers( |
71 | UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) | 141 | UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) |
72 | { | 142 | { |
@@ -115,71 +185,60 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
115 | /// <param name="reason">The message to send to the user after it's been turned into a field</param> | 185 | /// <param name="reason">The message to send to the user after it's been turned into a field</param> |
116 | public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason) | 186 | public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason) |
117 | { | 187 | { |
118 | UUID kickUserID = ALL_AGENTS; | 188 | if (!m_scene.Permissions.IsGod(godID)) |
119 | 189 | return; | |
190 | |||
191 | ScenePresence god = m_scene.GetScenePresence(godID); | ||
192 | if (god == null || god.ControllingClient.SessionId != sessionID) | ||
193 | return; | ||
194 | |||
120 | ScenePresence sp = m_scene.GetScenePresence(agentID); | 195 | ScenePresence sp = m_scene.GetScenePresence(agentID); |
121 | 196 | ||
122 | if (sp != null || agentID == kickUserID) | 197 | switch (kickflags) |
123 | { | 198 | { |
124 | if (m_scene.Permissions.IsGod(godID)) | 199 | case 0: |
200 | if (sp != null) | ||
125 | { | 201 | { |
126 | if (kickflags == 0) | 202 | KickPresence(sp, Utils.BytesToString(reason)); |
127 | { | ||
128 | if (agentID == kickUserID) | ||
129 | { | ||
130 | string reasonStr = Utils.BytesToString(reason); | ||
131 | |||
132 | m_scene.ForEachClient( | ||
133 | delegate(IClientAPI controller) | ||
134 | { | ||
135 | if (controller.AgentId != godID) | ||
136 | controller.Kick(reasonStr); | ||
137 | } | ||
138 | ); | ||
139 | |||
140 | // This is a bit crude. It seems the client will be null before it actually stops the thread | ||
141 | // The thread will kill itself eventually :/ | ||
142 | // Is there another way to make sure *all* clients get this 'inter region' message? | ||
143 | m_scene.ForEachScenePresence( | ||
144 | delegate(ScenePresence p) | ||
145 | { | ||
146 | if (p.UUID != godID && !p.IsChildAgent) | ||
147 | { | ||
148 | // Possibly this should really be p.Close() though that method doesn't send a close | ||
149 | // to the client | ||
150 | p.ControllingClient.Close(); | ||
151 | } | ||
152 | } | ||
153 | ); | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent); | ||
158 | |||
159 | sp.ControllingClient.Kick(Utils.BytesToString(reason)); | ||
160 | sp.ControllingClient.Close(); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | if (kickflags == 1) | ||
165 | { | ||
166 | sp.AllowMovement = false; | ||
167 | m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason)); | ||
168 | m_dialogModule.SendAlertToUser(godID, "User Frozen"); | ||
169 | } | ||
170 | |||
171 | if (kickflags == 2) | ||
172 | { | ||
173 | sp.AllowMovement = true; | ||
174 | m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason)); | ||
175 | m_dialogModule.SendAlertToUser(godID, "User Unfrozen"); | ||
176 | } | ||
177 | } | 203 | } |
178 | else | 204 | else if (agentID == ALL_AGENTS) |
205 | { | ||
206 | m_scene.ForEachScenePresence( | ||
207 | delegate(ScenePresence p) | ||
208 | { | ||
209 | if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID))) | ||
210 | KickPresence(p, Utils.BytesToString(reason)); | ||
211 | } | ||
212 | ); | ||
213 | } | ||
214 | break; | ||
215 | case 1: | ||
216 | if (sp != null) | ||
179 | { | 217 | { |
180 | m_dialogModule.SendAlertToUser(godID, "Kick request denied"); | 218 | sp.AllowMovement = false; |
219 | m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason)); | ||
220 | m_dialogModule.SendAlertToUser(godID, "User Frozen"); | ||
181 | } | 221 | } |
222 | break; | ||
223 | case 2: | ||
224 | if (sp != null) | ||
225 | { | ||
226 | sp.AllowMovement = true; | ||
227 | m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason)); | ||
228 | m_dialogModule.SendAlertToUser(godID, "User Unfrozen"); | ||
229 | } | ||
230 | break; | ||
231 | default: | ||
232 | break; | ||
182 | } | 233 | } |
183 | } | 234 | } |
235 | |||
236 | private void KickPresence(ScenePresence sp, string reason) | ||
237 | { | ||
238 | if (sp.IsChildAgent) | ||
239 | return; | ||
240 | sp.ControllingClient.Kick(reason); | ||
241 | sp.Scene.IncomingCloseAgent(sp.UUID); | ||
242 | } | ||
184 | } | 243 | } |
185 | } \ No newline at end of file | 244 | } |