i've refactored the ChatModule into two modules: ChatModule and IRCBridgeModule.

ChatModule is now only doing in-world chat. IRCBridgeModule is only doing, well,
bridging chat to/from IRC. Both modules are now using a new OnChatFromWorld event
handler (which Scene.PacketHandler is feeding for chat from in-world instead of 
going via the Interface method). This refactoring will allow us to easily add
other bridge modules (e.g., an XMPP bridge module).

there is still a bug in IRCBridgeModule (inherited from the old ChatModule)
where FindClientRegion does not really find the client region...
0.6.0-stable
Dr Scofield 2008-05-23 10:24:26 +00:00
parent 066b350d20
commit bf23e5d66c
3 changed files with 70 additions and 727 deletions

View File

@ -43,23 +43,19 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
{ {
public class ChatModule : IRegionModule, ISimChat public class ChatModule : IRegionModule, ISimChat
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log =
private string m_defaultzone = null; LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IRCChatModule m_irc = null; private const int DEBUG_CHANNEL = 2147483647;
private Thread m_irc_connector = null;
private string m_last_leaving_user = null;
private string m_last_new_user = null;
private int m_saydistance = 30; private int m_saydistance = 30;
private List<Scene> m_scenes = new List<Scene>();
private int m_shoutdistance = 100; private int m_shoutdistance = 100;
internal object m_syncInit = new object();
internal object m_syncLogout = new object();
private int m_whisperdistance = 10; private int m_whisperdistance = 10;
private List<Scene> m_scenes = new List<Scene>();
internal object m_syncInit = new object();
#region IRegionModule Members #region IRegionModule Members
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
{ {
lock (m_syncInit) lock (m_syncInit)
@ -68,7 +64,8 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
{ {
m_scenes.Add(scene); m_scenes.Add(scene);
scene.EventManager.OnNewClient += NewClient; scene.EventManager.OnNewClient += NewClient;
scene.RegisterModuleInterface<ISimChat>(this); scene.EventManager.OnChatFromWorld += SimChat;
// scene.RegisterModuleInterface<ISimChat>(this);
} }
// wrap this in a try block so that defaults will work if // wrap this in a try block so that defaults will work if
@ -82,57 +79,17 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
catch (Exception) catch (Exception)
{ {
} }
m_log.InfoFormat("[CHAT] initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName,
try m_whisperdistance, m_saydistance, m_shoutdistance);
{
m_defaultzone = config.Configs["IRC"].GetString("nick", "Sim");
}
catch (Exception)
{
}
// setup IRC Relay
if (m_irc == null)
{
m_irc = new IRCChatModule(config);
}
if (m_irc_connector == null)
{
m_irc_connector = new Thread(IRCConnectRun);
m_irc_connector.Name = "IRCConnectorThread";
m_irc_connector.IsBackground = true;
}
} }
} }
public void PostInitialise() public void PostInitialise()
{ {
if (m_irc.Enabled)
{
try
{
//m_irc.Connect(m_scenes);
if (m_irc_connector == null)
{
m_irc_connector = new Thread(IRCConnectRun);
m_irc_connector.Name = "IRCConnectorThread";
m_irc_connector.IsBackground = true;
}
if (!m_irc_connector.IsAlive)
{
m_irc_connector.Start();
ThreadTracker.Add(m_irc_connector);
}
}
catch (Exception)
{
}
}
} }
public void Close() public void Close()
{ {
m_irc.Close();
} }
public string Name public string Name
@ -148,11 +105,8 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
#endregion #endregion
#region ISimChat Members #region ISimChat Members
public void SimChat(Object sender, ChatFromViewerArgs e) public void SimChat(Object sender, ChatFromViewerArgs e)
{ {
// FROM: Sim TO: IRC
ScenePresence avatar = null; ScenePresence avatar = null;
//TODO: Move ForEachScenePresence and others into IScene. //TODO: Move ForEachScenePresence and others into IScene.
@ -164,7 +118,8 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
// Filled in since it's easier than rewriting right now. // Filled in since it's easier than rewriting right now.
LLVector3 fromPos = e.Position; LLVector3 fromPos = e.Position;
LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
string fromName = e.From; string fromName = e.From;
string message = e.Message; string message = e.Message;
@ -178,66 +133,37 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
if (avatar != null) if (avatar != null)
{ {
fromPos = avatar.AbsolutePosition; fromPos = avatar.AbsolutePosition;
regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
fromName = avatar.Firstname + " " + avatar.Lastname; fromName = avatar.Firstname + " " + avatar.Lastname;
fromAgentID = e.Sender.AgentId; fromAgentID = e.Sender.AgentId;
} }
// Try to reconnect to server if not connected
if (m_irc.Enabled && !m_irc.Connected)
{
// In a non-blocking way. Eventually the connector will get it started
try
{
if (m_irc_connector == null)
{
m_irc_connector = new Thread(IRCConnectRun);
m_irc_connector.Name = "IRCConnectorThread";
m_irc_connector.IsBackground = true;
}
if (!m_irc_connector.IsAlive)
{
m_irc_connector.Start();
ThreadTracker.Add(m_irc_connector);
}
}
catch (Exception)
{
}
}
// We only want to relay stuff on channel 0 // We only want to relay stuff on channel 0
if (e.Channel == 0 || e.Channel == 2147483647) if (e.Channel == 0 || e.Channel == DEBUG_CHANNEL)
{ {
if (e.Channel == 2147483647) if (e.Channel == DEBUG_CHANNEL)
e.Type = ChatTypeEnum.DebugChannel; e.Type = ChatTypeEnum.DebugChannel;
// IRC stuff // chat works by redistributing every incoming chat
if (e.Message.Length > 0 && e.Channel == 0) // message to each avatar in the scene
{
if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC
{
m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
}
}
foreach (Scene s in m_scenes) foreach (Scene s in m_scenes)
{ {
s.ForEachScenePresence(delegate(ScenePresence presence) s.ForEachScenePresence(delegate(ScenePresence presence)
{
if (e.Channel == DEBUG_CHANNEL)
{ {
if (e.Channel == 2147483647) TrySendChatMessage(presence, fromPos, regionPos,
{ fromAgentID, fromName, e.Type,
TrySendChatMessage(presence, fromPos, regionPos, message, ChatSourceType.Object);
fromAgentID, fromName, e.Type, message, ChatSourceType.Object); }
} else
else {
{ TrySendChatMessage(presence, fromPos, regionPos,
TrySendChatMessage(presence, fromPos, regionPos, fromAgentID, fromName, e.Type,
fromAgentID, fromName, e.Type, message, ChatSourceType.Agent); message, ChatSourceType.Agent);
}
} });
});
} }
} }
} }
@ -249,67 +175,23 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
try try
{ {
client.OnChatFromViewer += SimChat; client.OnChatFromViewer += SimChat;
if ((m_irc.Enabled) && (m_irc.Connected))
{
string clientName = client.Name;
// handles simple case. May not work for hundred connecting in per second.
// and the NewClients calles getting interleved
// but filters out multiple reports
if (clientName != m_last_new_user)
{
m_last_new_user = clientName;
string clientRegion = FindClientRegion(client.FirstName, client.LastName);
m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in " + clientRegion);
}
}
client.OnLogout += ClientLoggedOut;
client.OnConnectionClosed += ClientLoggedOut;
client.OnLogout += ClientLoggedOut;
} }
catch (Exception ex) catch (Exception ex)
{ {
m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); m_log.Error("[CHAT]: NewClient exception trap:" + ex.ToString());
}
}
public void ClientLoggedOut(IClientAPI client)
{
lock (m_syncLogout)
{
try
{
if ((m_irc.Enabled) && (m_irc.Connected))
{
string clientName = client.FirstName + " " + client.LastName;
string clientRegion = FindClientRegion(client.FirstName, client.LastName);
// handles simple case. May not work for hundred connecting in per second.
// and the NewClients calles getting interleved
// but filters out multiple reports
if (clientName != m_last_leaving_user)
{
m_last_leaving_user = clientName;
m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion);
}
}
}
catch (Exception ex)
{
m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString());
}
} }
} }
private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message, ChatSourceType src) LLUUID fromAgentID, string fromName, ChatTypeEnum type,
string message, ChatSourceType src)
{ {
if (!presence.IsChildAgent) if (!presence.IsChildAgent)
{ {
LLVector3 fromRegionPos = fromPos + regionPos; LLVector3 fromRegionPos = fromPos + regionPos;
LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; LLVector3 toRegionPos = presence.AbsolutePosition + regionPos;
int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos));
if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
type == ChatTypeEnum.Say && dis > m_saydistance || type == ChatTypeEnum.Say && dis > m_saydistance ||
type == ChatTypeEnum.Shout && dis > m_shoutdistance) type == ChatTypeEnum.Shout && dis > m_shoutdistance)
@ -318,563 +200,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
} }
// TODO: should change so the message is sent through the avatar rather than direct to the ClientView // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID,(byte)src,(byte)ChatAudibleLevel.Fully); presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName,
fromAgentID,(byte)src,(byte)ChatAudibleLevel.Fully);
} }
} }
// if IRC is enabled then just keep trying using a monitor thread
public void IRCConnectRun()
{
while (true)
{
if ((m_irc.Enabled) && (!m_irc.Connected))
{
m_irc.Connect(m_scenes);
}
Thread.Sleep(15000);
}
}
public string FindClientRegion(string client_FirstName, string client_LastName)
{
string sourceRegion = null;
foreach (Scene s in m_scenes)
{
s.ForEachScenePresence(delegate(ScenePresence presence)
{
if ((presence.IsChildAgent == false)
&& (presence.Firstname == client_FirstName)
&& (presence.Lastname == client_LastName))
{
sourceRegion = presence.Scene.RegionInfo.RegionName;
//sourceRegion= s.RegionInfo.RegionName;
}
});
if (sourceRegion != null) return sourceRegion;
}
if (m_defaultzone == null)
{
m_defaultzone = "Sim";
}
return m_defaultzone;
}
}
internal class IRCChatModule
{
#region ErrorReplies enum
public enum ErrorReplies
{
NotRegistered = 451, // ":You have not registered"
NicknameInUse = 433 // "<nick> :Nickname is already in use"
}
#endregion
#region Replies enum
public enum Replies
{
MotdStart = 375, // ":- <server> Message of the day - "
Motd = 372, // ":- <text>"
EndOfMotd = 376 // ":End of /MOTD command"
}
#endregion
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Thread listener;
private string m_basenick = null;
private string m_channel = null;
private bool m_connected = false;
private bool m_enabled = false;
private List<Scene> m_last_scenes = null;
private string m_nick = null;
private uint m_port = 6668;
private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}";
private StreamReader m_reader;
private List<Scene> m_scenes = null;
private string m_server = null;
private NetworkStream m_stream;
internal object m_syncConnect = new object();
private TcpClient m_tcp;
private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
private StreamWriter m_writer;
private Thread pingSender;
public IRCChatModule(IConfigSource config)
{
m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
m_tcp = null;
m_writer = null;
m_reader = null;
// configuration in OpenSim.ini
// [IRC]
// server = chat.freenode.net
// nick = OSimBot_mysim
// ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot
// ; username is the IRC command line sent
// ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname>
// channel = #opensim-regions
// port = 6667
// ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message
// ;for <bot>:<user in region> :<message>
// ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"
// ;for <bot>:<message> - <user of region> :
// ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}"
// ;for <bot>:<message> - from <user> :
// ;msgformat = "PRIVMSG {0} : {3} - from {1}"
// Traps I/O disconnects so it does not crash the sim
// Trys to reconnect if disconnected and someone says something
// Tells IRC server "QUIT" when doing a close (just to be nice)
// Default port back to 6667
try
{
m_server = config.Configs["IRC"].GetString("server");
m_nick = config.Configs["IRC"].GetString("nick");
m_basenick = m_nick;
m_channel = config.Configs["IRC"].GetString("channel");
m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port);
m_user = config.Configs["IRC"].GetString("username", m_user);
m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat);
if (m_server != null && m_nick != null && m_channel != null)
{
m_nick = m_nick + Util.RandomClass.Next(1, 99);
m_enabled = true;
}
}
catch (Exception)
{
m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration");
}
}
public bool Enabled
{
get { return m_enabled; }
}
public bool Connected
{
get { return m_connected; }
}
public string Nick
{
get { return m_nick; }
}
public bool Connect(List<Scene> scenes)
{
lock (m_syncConnect)
{
try
{
if (m_connected) return true;
m_scenes = scenes;
if (m_last_scenes == null)
{
m_last_scenes = scenes;
}
m_tcp = new TcpClient(m_server, (int) m_port);
m_log.Info("[IRC]: Connecting...");
m_stream = m_tcp.GetStream();
m_log.Info("[IRC]: Connected to " + m_server);
m_reader = new StreamReader(m_stream);
m_writer = new StreamWriter(m_stream);
pingSender = new Thread(new ThreadStart(PingRun));
pingSender.Name = "PingSenderThread";
pingSender.IsBackground = true;
pingSender.Start();
ThreadTracker.Add(pingSender);
listener = new Thread(new ThreadStart(ListenerRun));
listener.Name = "IRCChatModuleListenerThread";
listener.IsBackground = true;
listener.Start();
ThreadTracker.Add(listener);
m_writer.WriteLine(m_user);
m_writer.Flush();
m_writer.WriteLine("NICK " + m_nick);
m_writer.Flush();
m_writer.WriteLine("JOIN " + m_channel);
m_writer.Flush();
m_log.Info("[IRC]: Connection fully established");
m_connected = true;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return m_connected;
}
}
public void Reconnect()
{
m_connected = false;
listener.Abort();
pingSender.Abort();
m_writer.Close();
m_reader.Close();
m_tcp.Close();
if (m_enabled)
{
Connect(m_last_scenes);
}
}
public void PrivMsg(string from, string region, string msg)
{
// One message to the IRC server
try
{
if (m_privmsgformat == null)
{
m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
}
else
{
m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg);
}
m_writer.Flush();
m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg);
}
catch (IOException)
{
m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)");
Reconnect();
}
catch (Exception ex)
{
m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString());
}
}
private Dictionary<string, string> ExtractMsg(string input)
{
//examines IRC commands and extracts any private messages
// which will then be reboadcast in the Sim
m_log.Info("[IRC]: ExtractMsg: " + input);
Dictionary<string, string> result = null;
//string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
Regex RE = new Regex(regex, RegexOptions.Multiline);
MatchCollection matches = RE.Matches(input);
// Get some direct matches $1 $4 is a
if ((matches.Count == 1) && (matches[0].Groups.Count == 5))
{
result = new Dictionary<string, string>();
result.Add("nick", matches[0].Groups[1].Value);
result.Add("user", matches[0].Groups[2].Value);
result.Add("channel", matches[0].Groups[3].Value);
result.Add("msg", matches[0].Groups[4].Value);
}
else
{
m_log.Info("[IRC]: Number of matches: " + matches.Count);
if (matches.Count > 0)
{
m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count);
}
}
return result;
}
public void PingRun()
{
// IRC keep alive thread
// send PING ever 15 seconds
while (true)
{
try
{
if (m_connected == true)
{
m_writer.WriteLine("PING :" + m_server);
m_writer.Flush();
Thread.Sleep(15000);
}
}
catch (IOException)
{
m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)");
Reconnect();
}
catch (Exception ex)
{
m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
}
}
}
public void ListenerRun()
{
string inputLine;
LLVector3 pos = new LLVector3(128, 128, 20);
while (true)
{
try
{
while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null))
{
// Console.WriteLine(inputLine);
if (inputLine.Contains(m_channel))
{
Dictionary<string, string> data = ExtractMsg(inputLine);
// Any chat ???
if (data != null)
{
foreach (Scene m_scene in m_scenes)
{
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
if (!avatar.IsChildAgent)
{
avatar.ControllingClient.SendChatMessage(
Helpers.StringToField(data["msg"]), 255,
pos, data["nick"],
LLUUID.Zero,(byte)ChatSourceType.Agent,(byte)ChatAudibleLevel.Fully);
}
});
}
}
else
{
// Was an command from the IRC server
ProcessIRCCommand(inputLine);
}
}
else
{
// Was an command from the IRC server
ProcessIRCCommand(inputLine);
}
Thread.Sleep(150);
}
}
catch (IOException)
{
m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)");
Reconnect();
}
catch (Exception ex)
{
m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
}
}
}
public void BroadcastSim(string message, string sender)
{
LLVector3 pos = new LLVector3(128, 128, 20);
try
{
foreach (Scene m_scene in m_scenes)
{
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
if (!avatar.IsChildAgent)
{
avatar.ControllingClient.SendChatMessage(
Helpers.StringToField(message), 255,
pos, sender,
LLUUID.Zero,(byte)ChatSourceType.Object,(byte)ChatAudibleLevel.Fully);
}
});
}
}
catch (Exception ex) // IRC gate should not crash Sim
{
m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace);
}
}
public void ProcessIRCCommand(string command)
{
//m_log.Info("[IRC]: ProcessIRCCommand:" + command);
string[] commArgs = new string[command.Split(' ').Length];
string c_server = m_server;
commArgs = command.Split(' ');
if (commArgs[0].Substring(0, 1) == ":")
{
commArgs[0] = commArgs[0].Remove(0, 1);
}
if (commArgs[1] == "002")
{
// fetch the correct servername
// ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/...
// irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch
c_server = (commArgs[6].Split('['))[0];
m_server = c_server;
}
if (commArgs[0] == "ERROR")
{
m_log.Error("[IRC]: IRC SERVER ERROR:" + command);
}
if (commArgs[0] == "PING")
{
string p_reply = "";
for (int i = 1; i < commArgs.Length; i++)
{
p_reply += commArgs[i] + " ";
}
m_writer.WriteLine("PONG " + p_reply);
m_writer.Flush();
}
else if (commArgs[0] == c_server)
{
// server message
try
{
Int32 commandCode = Int32.Parse(commArgs[1]);
switch (commandCode)
{
case (int) ErrorReplies.NicknameInUse:
// Gen a new name
m_nick = m_basenick + Util.RandomClass.Next(1, 99);
m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick);
// Retry
m_writer.WriteLine("NICK " + m_nick);
m_writer.Flush();
m_writer.WriteLine("JOIN " + m_channel);
m_writer.Flush();
break;
case (int) ErrorReplies.NotRegistered:
break;
case (int) Replies.EndOfMotd:
break;
}
}
catch (Exception)
{
}
}
else
{
// Normal message
string commAct = commArgs[1];
switch (commAct)
{
case "JOIN":
eventIrcJoin(commArgs);
break;
case "PART":
eventIrcPart(commArgs);
break;
case "MODE":
eventIrcMode(commArgs);
break;
case "NICK":
eventIrcNickChange(commArgs);
break;
case "KICK":
eventIrcKick(commArgs);
break;
case "QUIT":
eventIrcQuit(commArgs);
break;
case "PONG":
break; // that's nice
}
}
}
public void eventIrcJoin(string[] commArgs)
{
string IrcChannel = commArgs[2];
string IrcUser = commArgs[0].Split('!')[0];
BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick);
}
public void eventIrcPart(string[] commArgs)
{
string IrcChannel = commArgs[2];
string IrcUser = commArgs[0].Split('!')[0];
BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick);
}
public void eventIrcMode(string[] commArgs)
{
//string IrcChannel = commArgs[2];
//string IrcUser = commArgs[0].Split('!')[0];
string UserMode = "";
for (int i = 3; i < commArgs.Length; i++)
{
UserMode += commArgs[i] + " ";
}
if (UserMode.Substring(0, 1) == ":")
{
UserMode = UserMode.Remove(0, 1);
}
}
public void eventIrcNickChange(string[] commArgs)
{
string UserOldNick = commArgs[0].Split('!')[0];
string UserNewNick = commArgs[2].Remove(0, 1);
BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick);
}
public void eventIrcKick(string[] commArgs)
{
string UserKicker = commArgs[0].Split('!')[0];
string UserKicked = commArgs[3];
string IrcChannel = commArgs[2];
string KickMessage = "";
for (int i = 4; i < commArgs.Length; i++)
{
KickMessage += commArgs[i] + " ";
}
BroadcastSim(UserKicker + " kicked " + UserKicked + " on " + IrcChannel + " saying " + KickMessage, m_nick);
if (UserKicked == m_nick)
{
BroadcastSim("Hey, that was me!!!", m_nick);
}
}
public void eventIrcQuit(string[] commArgs)
{
string IrcUser = commArgs[0].Split('!')[0];
string QuitMessage = "";
for (int i = 2; i < commArgs.Length; i++)
{
QuitMessage += commArgs[i] + " ";
}
BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick);
}
public void Close()
{
m_connected = false;
m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing");
m_writer.Flush();
listener.Abort();
pingSender.Abort();
m_writer.Close();
m_reader.Close();
m_tcp.Close();
}
} }
} }

View File

@ -182,6 +182,13 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary> /// </summary>
public delegate void DeregisterCapsEvent(LLUUID agentID, Caps caps); public delegate void DeregisterCapsEvent(LLUUID agentID, Caps caps);
public event DeregisterCapsEvent OnDeregisterCaps; public event DeregisterCapsEvent OnDeregisterCaps;
/// <summary>
/// ChatFromWorldEvent is called via Scene when a chat message
/// from world comes in (chat from viewer is available via
/// client.OnChatFromViewer).
/// </summary>
public delegate void ChatFromWorldEvent(Object sender, ChatFromViewerArgs chat);
public event ChatFromWorldEvent OnChatFromWorld;
public class MoneyTransferArgs : EventArgs public class MoneyTransferArgs : EventArgs
{ {
@ -283,6 +290,7 @@ namespace OpenSim.Region.Environment.Scenes
private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
private DeregisterCapsEvent handlerDeregisterCaps = null; // OnDeregisterCaps; private DeregisterCapsEvent handlerDeregisterCaps = null; // OnDeregisterCaps;
private ChatFromWorldEvent handlerChatFromWorld = null; // OnChatFromWorld;
private NewInventoryItemUploadComplete handlerNewInventoryItemUpdateComplete = null; private NewInventoryItemUploadComplete handlerNewInventoryItemUpdateComplete = null;
private RequestChangeWaterHeight handlerRequestChangeWaterHeight = null; //OnRequestChangeWaterHeight private RequestChangeWaterHeight handlerRequestChangeWaterHeight = null; //OnRequestChangeWaterHeight
private ScriptControlEvent handlerScriptControlEvent = null; private ScriptControlEvent handlerScriptControlEvent = null;
@ -625,6 +633,16 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
public void TriggerOnChatFromWorld(Object sender, ChatFromViewerArgs chat)
{
handlerChatFromWorld = OnChatFromWorld;
if (handlerChatFromWorld != null)
{
handlerChatFromWorld(sender, chat);
}
}
internal void TriggerControlEvent(uint p, LLUUID scriptUUID, LLUUID avatarID, uint held, uint _changed) internal void TriggerControlEvent(uint p, LLUUID scriptUUID, LLUUID avatarID, uint held, uint _changed)
{ {
handlerScriptControlEvent = OnScriptControlEvent; handlerScriptControlEvent = OnScriptControlEvent;

View File

@ -45,28 +45,25 @@ namespace OpenSim.Region.Environment.Scenes
public void SimChat(byte[] message, ChatTypeEnum type, int channel, LLVector3 fromPos, string fromName, public void SimChat(byte[] message, ChatTypeEnum type, int channel, LLVector3 fromPos, string fromName,
LLUUID fromAgentID) LLUUID fromAgentID)
{ {
if (m_simChatModule != null) ChatFromViewerArgs args = new ChatFromViewerArgs();
{
ChatFromViewerArgs args = new ChatFromViewerArgs();
args.Message = Helpers.FieldToUTF8String(message); args.Message = Helpers.FieldToUTF8String(message);
args.Channel = channel; args.Channel = channel;
args.Type = type; args.Type = type;
args.Position = fromPos; args.Position = fromPos;
args.SenderUUID = fromAgentID; args.SenderUUID = fromAgentID;
args.Scene = this;
ScenePresence user = GetScenePresence(fromAgentID);
if (user != null)
args.Sender = user.ControllingClient;
else
args.Sender = null;
ScenePresence user = GetScenePresence(fromAgentID); args.From = fromName;
if (user != null) //args.
args.Sender = user.ControllingClient;
else
args.Sender = null;
args.From = fromName; EventManager.TriggerOnChatFromWorld(this, args);
//args.
m_simChatModule.SimChat(this, args);
}
} }
/// <summary> /// <summary>