From 69666be28c5700b94be54d6165c9f59d681a4f4f Mon Sep 17 00:00:00 2001
From: Melanie
Date: Thu, 13 Jan 2011 16:05:17 +0100
Subject: Implement kicking, freezing and unfreezing users in the same sim via
profile god buttons.
---
.../Region/CoreModules/Avatar/Gods/GodsModule.cs | 175 ++++++++++++++-------
1 file 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;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.IO;
+using System.Web;
+using System.Xml;
+using log4net;
+using Mono.Addins;
+using OpenMetaverse.Messages.Linden;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework.Capabilities;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Servers.HttpServer;
+using Caps = OpenSim.Framework.Capabilities.Caps;
+using OSDArray = OpenMetaverse.StructuredData.OSDArray;
+using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Avatar.Gods
{
public class GodsModule : IRegionModule, IGodsModule
{
+ private static readonly ILog m_log =
+ LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
/// Special UUID for actions that apply to all agents
private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
protected Scene m_scene;
protected IDialogModule m_dialogModule;
+
+ protected Dictionary m_capsDict =
+ new Dictionary();
public void Initialise(Scene scene, IConfigSource source)
{
@@ -48,6 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
m_dialogModule = m_scene.RequestModuleInterface();
m_scene.RegisterModuleInterface(this);
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
+ m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
+ m_scene.EventManager.OnClientClosed += OnClientClosed;
}
public void PostInitialise() {}
@@ -67,6 +93,50 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
client.OnRequestGodlikePowers -= RequestGodlikePowers;
}
+ private void OnClientClosed(UUID agentID, Scene scene)
+ {
+ m_capsDict.Remove(agentID);
+ }
+
+ private void OnRegisterCaps(UUID agentID, Caps caps)
+ {
+ string uri = "/CAPS/" + UUID.Random();
+ m_capsDict[agentID] = uri;
+
+ caps.RegisterHandler("UntrustedSimulatorMessage",
+ new RestStreamHandler("POST", uri,
+ HandleUntrustedSimulatorMessage));
+ }
+
+ private string HandleUntrustedSimulatorMessage(string request,
+ string path, string param, OSHttpRequest httpRequest,
+ OSHttpResponse httpResponse)
+ {
+ OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
+
+ string message = osd["message"].AsString();
+
+ if (message == "GodKickUser")
+ {
+ OSDMap body = (OSDMap)osd["body"];
+ OSDArray userInfo = (OSDArray)body["UserInfo"];
+ OSDMap userData = (OSDMap)userInfo[0];
+
+ UUID agentID = userData["AgentID"].AsUUID();
+ UUID godID = userData["GodID"].AsUUID();
+ UUID godSessionID = userData["GodSessionID"].AsUUID();
+ uint kickFlags = userData["KickFlags"].AsUInteger();
+ string reason = userData["Reason"].AsString();
+
+ KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
+ }
+ else
+ {
+ m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
+ }
+ return String.Empty;
+ }
+
public void RequestGodlikePowers(
UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
{
@@ -115,71 +185,60 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
/// The message to send to the user after it's been turned into a field
public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
{
- UUID kickUserID = ALL_AGENTS;
-
+ if (!m_scene.Permissions.IsGod(godID))
+ return;
+
+ ScenePresence god = m_scene.GetScenePresence(godID);
+ if (god == null || god.ControllingClient.SessionId != sessionID)
+ return;
+
ScenePresence sp = m_scene.GetScenePresence(agentID);
- if (sp != null || agentID == kickUserID)
+ switch (kickflags)
{
- if (m_scene.Permissions.IsGod(godID))
+ case 0:
+ if (sp != null)
{
- if (kickflags == 0)
- {
- if (agentID == kickUserID)
- {
- string reasonStr = Utils.BytesToString(reason);
-
- m_scene.ForEachClient(
- delegate(IClientAPI controller)
- {
- if (controller.AgentId != godID)
- controller.Kick(reasonStr);
- }
- );
-
- // This is a bit crude. It seems the client will be null before it actually stops the thread
- // The thread will kill itself eventually :/
- // Is there another way to make sure *all* clients get this 'inter region' message?
- m_scene.ForEachScenePresence(
- delegate(ScenePresence p)
- {
- if (p.UUID != godID && !p.IsChildAgent)
- {
- // Possibly this should really be p.Close() though that method doesn't send a close
- // to the client
- p.ControllingClient.Close();
- }
- }
- );
- }
- else
- {
- m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
-
- sp.ControllingClient.Kick(Utils.BytesToString(reason));
- sp.ControllingClient.Close();
- }
- }
-
- if (kickflags == 1)
- {
- sp.AllowMovement = false;
- m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
- m_dialogModule.SendAlertToUser(godID, "User Frozen");
- }
-
- if (kickflags == 2)
- {
- sp.AllowMovement = true;
- m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
- m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
- }
+ KickPresence(sp, Utils.BytesToString(reason));
}
- else
+ else if (agentID == ALL_AGENTS)
+ {
+ m_scene.ForEachScenePresence(
+ delegate(ScenePresence p)
+ {
+ if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
+ KickPresence(p, Utils.BytesToString(reason));
+ }
+ );
+ }
+ break;
+ case 1:
+ if (sp != null)
{
- m_dialogModule.SendAlertToUser(godID, "Kick request denied");
+ sp.AllowMovement = false;
+ m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
+ m_dialogModule.SendAlertToUser(godID, "User Frozen");
}
+ break;
+ case 2:
+ if (sp != null)
+ {
+ sp.AllowMovement = true;
+ m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
+ m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
+ }
+ break;
+ default:
+ break;
}
}
+
+ private void KickPresence(ScenePresence sp, string reason)
+ {
+ if (sp.IsChildAgent)
+ return;
+ sp.ControllingClient.Kick(reason);
+ sp.Scene.IncomingCloseAgent(sp.UUID);
+ }
}
-}
\ No newline at end of file
+}
--
cgit v1.1