diff --git a/OpenSim/Framework/General/Interfaces/IClientAPI.cs b/OpenSim/Framework/General/Interfaces/IClientAPI.cs index bedea9e636..0dad91f4ae 100644 --- a/OpenSim/Framework/General/Interfaces/IClientAPI.cs +++ b/OpenSim/Framework/General/Interfaces/IClientAPI.cs @@ -34,8 +34,108 @@ using OpenSim.Framework.Types; namespace OpenSim.Framework.Interfaces { + // Base Args Interface + public interface IEventArgs + { + IScene Scene + { + get; + set; + } + + IClientAPI Sender + { + get; + set; + } + } + public delegate void ViewerEffectEventHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock); - public delegate void ChatFromViewer(byte[] message, byte type, int channel, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + + public delegate void ChatFromViewer(Object sender, ChatFromViewerArgs e); + + public enum ChatTypeEnum { Whisper = 0, Say = 1, Shout = 2, Broadcast = 0xFF }; + + /// + /// ChatFromViewer Arguments + /// + public class ChatFromViewerArgs : EventArgs, IEventArgs + { + protected string m_message; + protected ChatTypeEnum m_type; + protected int m_channel; + protected LLVector3 m_position; + protected string m_from; + + protected IClientAPI m_sender; + protected IScene m_scene; + + /// + /// The message sent by the user + /// + public string Message + { + get { return m_message; } + set { m_message = value; } + } + + /// + /// The type of message, eg say, shout, broadcast. + /// + public ChatTypeEnum Type + { + get { return m_type; } + set { m_type = value; } + } + + /// + /// Which channel was this message sent on? Different channels may have different listeners. Public chat is on channel zero. + /// + public int Channel + { + get { return m_channel; } + set { m_channel = value; } + } + + /// + /// The position of the sender at the time of the message broadcast. + /// + public LLVector3 Position + { + get { return m_position; } + set { m_position = value; } + } + + /// + /// The name of the sender (needed for scripts) + /// + public string From + { + get { return m_from; } + set { m_from = value; } + } + + /// + /// The client responsible for sending the message, or null. + /// + public IClientAPI Sender + { + get { return m_sender; } + set { m_sender = value; } + } + + public IScene Scene + { + get { return m_scene; } + set { m_scene = value; } + } + + public ChatFromViewerArgs() + { + m_position = new LLVector3(); + } + } + public delegate void ImprovedInstantMessage(LLUUID fromAgentID, LLUUID fromAgentSession, LLUUID toAgentID, LLUUID imSessionID, uint timestamp, string fromAgentName, string message, byte dialog); // Cut down from full list public delegate void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 pos); public delegate void ModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, IClientAPI remoteClient); diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs index d92127f326..05b11189ef 100644 --- a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs +++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs @@ -100,7 +100,17 @@ namespace OpenSim.Region.ClientStack if (OnChatFromViewer != null) { - this.OnChatFromViewer(message, type, channel, fromPos, fromName, fromAgentID); + ChatFromViewerArgs args = new ChatFromViewerArgs(); + args.Channel = channel; + args.From = fromName; + args.Message = Util.FieldToString(message); + args.Type = (ChatTypeEnum)type; + args.Position = fromPos; + + args.Scene = Scene; + args.Sender = this; + + this.OnChatFromViewer(this, args); } break; case PacketType.ImprovedInstantMessage: diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 24897394f8..cf4072cb52 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -68,7 +68,14 @@ namespace OpenSim.Region.ClientStack //private AgentAssetUpload UploadAssets; private LLUUID newAssetFolder = LLUUID.Zero; private int debug = 0; + protected IScene m_scene; + + public IScene Scene + { + get { return m_scene; } + } + private ClientManager m_clientManager; private AssetCache m_assetCache; // private InventoryCache m_inventoryCache; diff --git a/OpenSim/Region/Environment/Interfaces/ISimChat.cs b/OpenSim/Region/Environment/Interfaces/ISimChat.cs index 4ec55ffe21..583d8b20db 100644 --- a/OpenSim/Region/Environment/Interfaces/ISimChat.cs +++ b/OpenSim/Region/Environment/Interfaces/ISimChat.cs @@ -32,6 +32,6 @@ namespace OpenSim.Region.Environment.Interfaces { public interface ISimChat { - void SimChat(byte[] message, byte type, int channel, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + void SimChat(System.Object sender, OpenSim.Framework.Interfaces.ChatFromViewerArgs e); } } diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/ChatModule.cs index 7db4f4b3da..594d5b4eed 100644 --- a/OpenSim/Region/Environment/Modules/ChatModule.cs +++ b/OpenSim/Region/Environment/Modules/ChatModule.cs @@ -33,15 +33,16 @@ using System.Threading; using libsecondlife; using OpenSim.Framework.Interfaces; using OpenSim.Framework.Utilities; +using OpenSim.Framework.Console; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; -using Nini.Config; namespace OpenSim.Region.Environment.Modules { public class ChatModule : IRegionModule, ISimChat { - private Scene m_scene; + private Scene m_scene; + private LogBase m_log; private string m_server = null; private int m_port = 6668; @@ -65,10 +66,12 @@ namespace OpenSim.Region.Environment.Modules m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); m_irc = null; m_ircWriter = null; - m_ircReader = null; + m_ircReader = null; + + m_log = OpenSim.Framework.Console.MainLog.Instance; } - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(Scene scene, Nini.Config.IConfigSource config) { try { m_server = config.Configs["IRC"].GetString("server"); @@ -175,41 +178,80 @@ namespace OpenSim.Region.Environment.Modules } } - public void SimChat(byte[] message, byte type, int channel, LLVector3 fromPos, string fromName, - LLUUID fromAgentID) + public void SimChat(Object sender, ChatFromViewerArgs e) { ScenePresence avatar = null; - avatar = m_scene.GetScenePresence(fromAgentID); + + //TODO: Move ForEachScenePresence and others into IScene. + Scene scene = (Scene)e.Scene; + + //TODO: Remove the need for this check + if (scene == null) + scene = m_scene; + + // Filled in since it's easier than rewriting right now. + LLVector3 fromPos = e.Position; + string fromName = e.From; + string message = e.Message; + byte type = (byte)e.Type; + LLUUID fromAgentID = LLUUID.Zero; + + if (e.Sender != null) + avatar = scene.GetScenePresence(e.Sender.AgentId); + if (avatar != null) { fromPos = avatar.AbsolutePosition; fromName = avatar.Firstname + " " + avatar.Lastname; + fromAgentID = e.Sender.AgentId; avatar = null; - } + } + + string typeName; + switch (e.Type) + { + case ChatTypeEnum.Broadcast: + typeName = "broadcasts"; + break; + case ChatTypeEnum.Say: + typeName = "says"; + break; + case ChatTypeEnum.Shout: + typeName = "shouts"; + break; + case ChatTypeEnum.Whisper: + typeName = "whispers"; + break; + default: + typeName = "unknown"; + break; + } + + m_log.Verbose("CHAT", fromName + " (" + e.Channel + ") " + typeName + ": " + e.Message); if (connected) { m_ircWriter.WriteLine("PRIVMSG " + m_channel + " :" + "<" + fromName + ">: " + - Util.FieldToString(message)); + e.Message); m_ircWriter.Flush(); } - if (channel == 0) + if (e.Channel == 0) { - m_scene.ForEachScenePresence(delegate(ScenePresence presence) + scene.ForEachScenePresence(delegate(ScenePresence presence) { int dis = -1000; //err ??? the following code seems to be request a scenePresence when it already has a ref to it - avatar = m_scene.GetScenePresence(presence.ControllingClient.AgentId); + avatar = scene.GetScenePresence(presence.ControllingClient.AgentId); if (avatar != null) { dis = (int) avatar.AbsolutePosition.GetDistanceTo(fromPos); } - switch (type) + switch (e.Type) { - case 0: // Whisper + case ChatTypeEnum.Whisper: if ((dis < 10) && (dis > -10)) { //should change so the message is sent through the avatar rather than direct to the ClientView @@ -220,7 +262,7 @@ namespace OpenSim.Region.Environment.Modules fromAgentID); } break; - case 1: // Say + case ChatTypeEnum.Say: if ((dis < 30) && (dis > -30)) { //Console.WriteLine("sending chat"); @@ -231,7 +273,7 @@ namespace OpenSim.Region.Environment.Modules fromAgentID); } break; - case 2: // Shout + case ChatTypeEnum.Shout: if ((dis < 100) && (dis > -100)) { presence.ControllingClient.SendChatMessage(message, @@ -242,7 +284,7 @@ namespace OpenSim.Region.Environment.Modules } break; - case 0xff: // Broadcast + case ChatTypeEnum.Broadcast: presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, diff --git a/OpenSim/Region/Environment/Modules/WorldCommModule.cs b/OpenSim/Region/Environment/Modules/WorldCommModule.cs index 765f1b4c45..cf5bba3613 100644 --- a/OpenSim/Region/Environment/Modules/WorldCommModule.cs +++ b/OpenSim/Region/Environment/Modules/WorldCommModule.cs @@ -119,13 +119,12 @@ namespace OpenSim.Region.Environment.Modules client.OnChatFromViewer += DeliverClientMessage; } - private void DeliverClientMessage(byte[] message, byte type, int channel, LLVector3 fromPos, string fromName, - LLUUID fromAgentID) + private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) { - ASCIIEncoding ae = new ASCIIEncoding(); - - DeliverMessage(fromAgentID.ToString(), type, channel, fromName, ae.GetString(message)); - + DeliverMessage(e.Sender.AgentId.ToString(), + (int)e.Type, e.Channel, + e.Sender.FirstName + " " + e.Sender.LastName, + e.Message); } public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs index df8b19037c..71f8037589 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs @@ -70,7 +70,22 @@ namespace OpenSim.Region.Environment.Scenes { if (m_simChatModule != null) { - m_simChatModule.SimChat(message, type, channel, fromPos, fromName, fromAgentID); + ChatFromViewerArgs args = new ChatFromViewerArgs(); + + args.Message = OpenSim.Framework.Utilities.Util.FieldToString(message); + args.Channel = channel; + args.Type = (ChatTypeEnum)type; + args.Position = fromPos; + + ScenePresence user = this.GetScenePresence(fromAgentID); + if (user != null) + args.Sender = user.ControllingClient; + else + args.Sender = null; + + args.From = fromName; + + m_simChatModule.SimChat(this, args); } } diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs index c9c663eb80..1460b81bfb 100644 --- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs @@ -245,7 +245,15 @@ namespace SimpleApp { if (OnChatFromViewer != null) { - this.OnChatFromViewer(enc.GetBytes("Kind of quiet around here, isn't it! \0"), 2, 0, new LLVector3(128, 128, 26), this.FirstName + " " + this.LastName, this.AgentId); + ChatFromViewerArgs args = new ChatFromViewerArgs(); + args.Message = "Kinda quiet around here, isn't it?"; + args.Channel = 0; + args.From = this.FirstName + " " + this.LastName; + args.Position = new LLVector3(128, 128, 26); + args.Sender = this; + args.Type = ChatTypeEnum.Shout; + + this.OnChatFromViewer(this, args); } count = -1;