// This handler detects chat events int he virtual world.
        public void OnSimChat(Object sender, OSChatMessage msg)
        {
            // early return if this comes from the IRC forwarder

            if (cs.irc.Equals(sender))
            {
                return;
            }

            // early return if nothing to forward

            if (msg.Message.Length == 0)
            {
                return;
            }

            // check for commands coming from avatars or in-world
            // object (if commands are enabled)

            if (cs.CommandsEnabled && msg.Channel == cs.CommandChannel)
            {
                m_log.DebugFormat("[IRC-Region {0}] command on channel {1}: {2}", Region, msg.Channel, msg.Message);

                string[] messages = msg.Message.Split(' ');
                string   command  = messages[0].ToLower();

                try
                {
                    switch (command)
                    {
                    // These commands potentially require a change in the
                    // underlying ChannelState.

                    case "server":
                        cs.Close(this);
                        cs = cs.UpdateServer(this, messages[1]);
                        cs.Open(this);
                        break;

                    case "port":
                        cs.Close(this);
                        cs = cs.UpdatePort(this, messages[1]);
                        cs.Open(this);
                        break;

                    case "channel":
                        cs.Close(this);
                        cs = cs.UpdateChannel(this, messages[1]);
                        cs.Open(this);
                        break;

                    case "nick":
                        cs.Close(this);
                        cs = cs.UpdateNickname(this, messages[1]);
                        cs.Open(this);
                        break;

                    // These may also (but are less likely) to require a
                    // change in ChannelState.

                    case "client-reporting":
                        cs = cs.UpdateClientReporting(this, messages[1]);
                        break;

                    case "in-channel":
                        cs = cs.UpdateRelayIn(this, messages[1]);
                        break;

                    case "out-channel":
                        cs = cs.UpdateRelayOut(this, messages[1]);
                        break;

                    // These are all taken to be temporary changes in state
                    // so the underlying connector remains intact. But note
                    // that with regions sharing a connector, there could
                    // be interference.

                    case "close":
                        enabled = false;
                        cs.Close(this);
                        break;

                    case "connect":
                        enabled = true;
                        cs.Open(this);
                        break;

                    case "reconnect":
                        enabled = true;
                        cs.Close(this);
                        cs.Open(this);
                        break;

                    // This one is harmless as far as we can judge from here.
                    // If it is not, then the complaints will eventually make
                    // that evident.

                    default:
                        m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}",
                                          Region, msg.Message);
                        cs.irc.Send(msg.Message);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}",
                                     Region, ex.Message);
                    m_log.Debug(ex);
                }

                return;
            }

            // The command channel remains enabled, even if we have otherwise disabled the IRC
            // interface.

            if (!enabled)
            {
                return;
            }

            // drop messages unless they are on a valid in-world
            // channel as configured in the ChannelState

            if (!cs.ValidInWorldChannels.Contains(msg.Channel))
            {
                m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel);
                return;
            }

            ScenePresence avatar   = null;
            string        fromName = msg.From;

            if (msg.Sender != null)
            {
                avatar = scene.GetScenePresence(msg.Sender.AgentId);
                if (avatar != null)
                {
                    fromName = avatar.Name;
                }
            }

            if (!cs.irc.Connected)
            {
                m_log.WarnFormat("[IRC-Region {0}] IRCConnector not connected: dropping message from {1}", Region, fromName);
                return;
            }

            m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message);

            if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL))
            {
                string txt = msg.Message;
                if (txt.StartsWith("/me "))
                {
                    txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4));
                }

                cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt);
                return;
            }

            if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword &&
                msg.Channel == cs.RelayChannelOut)
            {
                Match m = cs.AccessPasswordRegex.Match(msg.Message);
                if (null != m)
                {
                    m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(),
                                      m.Groups["message"].ToString());
                    cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(),
                                   scene.RegionInfo.RegionName, m.Groups["message"].ToString());
                }
            }
        }
Example #2
0
        // This handler detects chat events int he virtual world.

        public void OnSimChat(Object sender, OSChatMessage msg)
        {

            // early return if this comes from the IRC forwarder

            if (cs.irc.Equals(sender)) return;

            // early return if nothing to forward

            if (msg.Message.Length == 0) return;

            // check for commands coming from avatars or in-world
            // object (if commands are enabled)

            if (cs.CommandsEnabled && msg.Channel == cs.CommandChannel)
            {

                m_log.DebugFormat("[IRC-Region {0}] command on channel {1}: {2}", Region, msg.Channel, msg.Message);

                string[] messages = msg.Message.Split(' ');
                string command = messages[0].ToLower();

                try
                {
                    switch (command)
                    {

                        // These commands potentially require a change in the
                        // underlying ChannelState.

                        case "server":
                            cs.Close(this);
                            cs = cs.UpdateServer(this, messages[1]);
                            cs.Open(this);
                            break;
                        case "port":
                            cs.Close(this);
                            cs = cs.UpdatePort(this, messages[1]);
                            cs.Open(this);
                            break;
                        case "channel":
                            cs.Close(this);
                            cs = cs.UpdateChannel(this, messages[1]);
                            cs.Open(this);
                            break;
                        case "nick":
                            cs.Close(this);
                            cs = cs.UpdateNickname(this, messages[1]);
                            cs.Open(this);
                            break;

                        // These may also (but are less likely) to require a
                        // change in ChannelState.

                        case "client-reporting":
                            cs = cs.UpdateClientReporting(this, messages[1]);
                            break;
                        case "in-channel":
                            cs = cs.UpdateRelayIn(this, messages[1]);
                            break;
                        case "out-channel":
                            cs = cs.UpdateRelayOut(this, messages[1]);
                            break;

                        // These are all taken to be temporary changes in state
                        // so the underlying connector remains intact. But note
                        // that with regions sharing a connector, there could
                        // be interference.

                        case "close":
                            enabled = false;
                            cs.Close(this);
                            break;

                        case "connect":
                            enabled = true;
                            cs.Open(this);
                            break;

                        case "reconnect":
                            enabled = true;
                            cs.Close(this);
                            cs.Open(this);
                            break;

                        // This one is harmless as far as we can judge from here.
                        // If it is not, then the complaints will eventually make
                        // that evident.

                        default:
                            m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", 
                                            Region, msg.Message);
                            cs.irc.Send(msg.Message);
                            break;
                    }
                }
                catch (Exception ex)
                { 
                    m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}",
                                    Region, ex.Message);
                    m_log.Debug(ex);
                }

                return;

            }

            // The command channel remains enabled, even if we have otherwise disabled the IRC
            // interface.

            if (!enabled)
                return;

            // drop messages unless they are on a valid in-world
            // channel as configured in the ChannelState

            if (!cs.ValidInWorldChannels.Contains(msg.Channel))
            {
                m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel);
                return;
            }

            ScenePresence avatar = null;
            string fromName = msg.From;

            if (msg.Sender != null)
            {
                avatar = scene.GetScenePresence(msg.Sender.AgentId);
                if (avatar != null) fromName = avatar.Name;
            }

            if (!cs.irc.Connected)
            {
                m_log.WarnFormat("[IRC-Region {0}] IRCConnector not connected: dropping message from {1}", Region, fromName);
                return;
            }

            m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message);

            if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) 
            {
                string txt = msg.Message;
                if (txt.StartsWith("/me "))
                    txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4));

                cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt);
                return;
            }

            if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && 
                msg.Channel == cs.RelayChannelOut)
            {
                Match m = cs.AccessPasswordRegex.Match(msg.Message);
                if (null != m)
                {
                    m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), 
                                      m.Groups["message"].ToString());
                    cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(),
                                   scene.RegionInfo.RegionName, m.Groups["message"].ToString());
                }
            }
        }
        // Called by IRCBridgeModule.Close immediately prior to unload
        // of the module for this region. This happens when the region
        // is being removed or the server is terminating. The IRC
        // BridgeModule will remove the region from the region list
        // when control returns.

        public void Close()
        {
            enabled = false;
            cs.Close(this);
        }