public void AddRegion(Scene scene) { if (Enabled) { try { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); if (!String.IsNullOrEmpty(m_password)) { MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); } m_region = new RegionState(scene, m_config); lock (m_regions) m_regions.Add(m_region); m_region.Open(); } catch (Exception e) { m_log.WarnFormat("[IRC-Bridge] Region {0} not connected to IRC : {1}", scene.RegionInfo.RegionName, e.Message); m_log.Debug(e); } } else { //m_log.DebugFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName); } }
// This function implements the variable substitution mechanism // for the configuration values. Each string read from the // configuration file is scanned for '[...]' enclosures. Each // one that is found is replaced by either a runtime variable // (%xxx) or an existing configuration key. When no further // substitution is possible, the remaining string is returned // to the caller. This allows for arbitrarily nested // enclosures. private static string Substitute(RegionState rs, string instr) { string result = instr; if (result == null || result.Length == 0) { return(result); } // Repeatedly scan the string until all possible // substitutions have been performed. // m_log.DebugFormat("[IRC-Channel] Parse[1]: {0}", result); while (arg.IsMatch(result)) { string vvar = arg.Match(result).ToString(); string var = vvar.Substring(1, vvar.Length - 2).Trim(); switch (var.ToLower()) { case "%region": result = result.Replace(vvar, rs.Region); break; case "%host": result = result.Replace(vvar, rs.Host); break; case "%master1": result = result.Replace(vvar, rs.MA1); break; case "%master2": result = result.Replace(vvar, rs.MA2); break; case "%locx": result = result.Replace(vvar, rs.LocX); break; case "%locy": result = result.Replace(vvar, rs.LocY); break; case "%k": result = result.Replace(vvar, rs.IDK); break; default: result = result.Replace(vvar, rs.config.GetString(var, var)); break; } // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); } // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result); return(result); }
internal ChannelState UpdateChannel(RegionState rs, string channel) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.IrcChannel = channel; cs = Integrate(rs, cs); cs.AddRegion(rs); return(cs); }
internal ChannelState UpdatePort(RegionState rs, string port) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.Port = Convert.ToUInt32(port); cs = Integrate(rs, cs); cs.AddRegion(rs); return(cs); }
// These routines allow differentiating changes to // the underlying channel state. If necessary, a // new channel state will be created. internal ChannelState UpdateServer(RegionState rs, string server) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.Server = server; cs = Integrate(rs, cs); cs.AddRegion(rs); return(cs); }
internal ChannelState UpdateClientReporting(RegionState rs, string cr) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.ClientReporting = Convert.ToBoolean(cr); cs = Integrate(rs, cs); cs.AddRegion(rs); return(cs); }
internal ChannelState UpdateRelayOut(RegionState rs, string channel) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.RelayChannelOut = Convert.ToInt32(channel); cs = Integrate(rs, cs); cs.AddRegion(rs); return(cs); }
internal ChannelState UpdateNickname(RegionState rs, string nickname) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.BaseNickname = nickname; cs = Integrate(rs, cs); cs.AddRegion(rs); return(cs); }
// Add a client region to this channel if it is not already known public void AddRegion(RegionState rs) { m_log.InfoFormat("[IRC-Channel-{0}] Adding region {1} to channel <{2}> to server <{3}:{4}>", idn, rs.Region, IrcChannel, Server, Port); if (!clientregions.Contains(rs)) { clientregions.Add(rs); lock (irc) irc.depends++; } }
// This function implements the variable substitution mechanism // for the configuration values. Each string read from the // configuration file is scanned for '[...]' enclosures. Each // one that is found is replaced by either a runtime variable // (%xxx) or an existing configuration key. When no further // substitution is possible, the remaining string is returned // to the caller. This allows for arbitrarily nested // enclosures. private static string Substitute(RegionState rs, string instr) { string result = instr; if (string.IsNullOrEmpty(result)) { return(result); } // Repeatedly scan the string until all possible // substitutions have been performed. // m_log.DebugFormat("[IRC-Channel] Parse[1]: {0}", result); while (arg.IsMatch(result)) { string vvar = arg.Match(result).ToString(); string var = vvar.Substring(1, vvar.Length - 2).Trim(); switch (var.ToLower()) { case "%region": result = result.Replace(vvar, rs.Region); break; case "%host": result = result.Replace(vvar, rs.Host); break; case "%locx": result = result.Replace(vvar, rs.LocX); break; case "%locy": result = result.Replace(vvar, rs.LocY); break; case "%k": result = result.Replace(vvar, rs.IDK); break; default: result = result.Replace(vvar, rs.config.GetString(var, var)); break; } // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); } // Now we unescape the literal brackets result = result.Replace(@"\[", "[").Replace(@"\]", "]"); // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result); return(result); }
// Remove a client region from the channel. If this is the last // region, then clean up the channel. The connector will clean itself // up if it finds itself about to be GC'd. public void RemoveRegion(RegionState rs) { m_log.InfoFormat("[IRC-Channel-{0}] Removing region {1} from channel <{2} to server <{3}:{4}>", idn, rs.Region, IrcChannel, Server, Port); if (clientregions.Contains(rs)) { clientregions.Remove(rs); lock (irc) irc.depends--; } }
// Close is called to ensure that the IRC session is terminated if this is the // only client. public void Close(RegionState rs) { RemoveRegion(rs); if (clientregions.Count == 0) { Close(); IRCBridgeModule.m_channels.Remove(this); m_log.InfoFormat("[IRC-Channel-{0}] Region {1} is last user of channel <{2}> to server <{3}:{4}>", idn, rs.Region, IrcChannel, Server, Port); m_log.InfoFormat("[IRC-Channel-{0}] Removed", idn); } }
// This function implements the variable substitution mechanism // for the configuration values. Each string read from the // configuration file is scanned for '[...]' enclosures. Each // one that is found is replaced by either a runtime variable // (%xxx) or an existing configuration key. When no further // substitution is possible, the remaining string is returned // to the caller. This allows for arbitrarily nested // enclosures. private static string Substitute(RegionState rs, string instr) { string result = instr; if (result == null || result.Length == 0) return result; // Repeatedly scan the string until all possible // substitutions have been performed. // m_log.DebugFormat("[IRC-Channel] Parse[1]: {0}", result); while (arg.IsMatch(result)) { string vvar = arg.Match(result).ToString(); string var = vvar.Substring(1,vvar.Length-2).Trim(); switch (var.ToLower()) { case "%region" : result = result.Replace(vvar, rs.Region); break; case "%host" : result = result.Replace(vvar, rs.Host); break; case "%master1" : result = result.Replace(vvar, rs.MA1); break; case "%master2" : result = result.Replace(vvar, rs.MA2); break; case "%locx" : result = result.Replace(vvar, rs.LocX); break; case "%locy" : result = result.Replace(vvar, rs.LocY); break; case "%k" : result = result.Replace(vvar, rs.IDK); break; default : result = result.Replace(vvar, rs.config.GetString(var,var)); break; } // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); } // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result); return result; }
internal ChannelState UpdateClientReporting(RegionState rs, string cr) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.ClientReporting = Convert.ToBoolean(cr); cs = Integrate(rs, cs); cs.AddRegion(rs); return cs; }
internal ChannelState UpdateRelayOut(RegionState rs, string channel) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.RelayChannelOut = Convert.ToInt32(channel); cs = Integrate(rs, cs); cs.AddRegion(rs); return cs; }
internal ChannelState UpdateChannel(RegionState rs, string channel) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.IrcChannel = channel; cs = Integrate(rs, cs); cs.AddRegion(rs); return cs; }
internal ChannelState UpdateNickname(RegionState rs, string nickname) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.BaseNickname = nickname; cs = Integrate(rs, cs); cs.AddRegion(rs); return cs; }
// Read the configuration file, performing variable substitution and any // necessary aliasing. See accompanying documentation for how this works. // If you don't need variables, then this works exactly as before. // If either channel or server are not specified, the request fails. internal static void OpenChannel(RegionState rs, IConfig config) { // Create a new instance of a channel. This may not actually // get used if an equivalent channel already exists. ChannelState cs = new ChannelState(); // Read in the configuration file and filter everything for variable // subsititution. m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); cs.Server = Substitute(rs, config.GetString("server", null)); cs.fromwhere = Substitute(rs, config.GetString("fromwhere", null)); m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); cs.Password = Substitute(rs, config.GetString("password", null)); // probably not a good idea to put a password in the log file cs.User = Substitute(rs, config.GetString("user", null)); cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); cs.User = Substitute(rs, config.GetString("username", cs.User)); m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting ? "1" : "0"))) > 0; m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); string[] excludes = config.GetString("exclude_list", "").Trim().Split(new Char[] { ',' }); cs.ExcludeList = new List <string>(excludes.Length); foreach (string name in excludes) { cs.ExcludeList.Add(name.Trim().ToLower()); } // Fail if fundamental information is still missing if (cs.Server == null) { throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: server missing", cs.idn, rs.Region)); } else if (cs.IrcChannel == null) { throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: channel missing", cs.idn, rs.Region)); } else if (cs.BaseNickname == null) { throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: nick missing", cs.idn, rs.Region)); } else if (cs.User == null) { throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: user missing", cs.idn, rs.Region)); } m_log.InfoFormat("[IRC-Channel-{0}] Configuration for Region {1} is valid", cs.idn, rs.Region); m_log.InfoFormat("[IRC-Channel-{0}] Server = {1}", cs.idn, cs.Server); m_log.InfoFormat("[IRC-Channel-{0}] Channel = {1}", cs.idn, cs.IrcChannel); m_log.InfoFormat("[IRC-Channel-{0}] Port = {1}", cs.idn, cs.Port); m_log.InfoFormat("[IRC-Channel-{0}] Nickname = {1}", cs.idn, cs.BaseNickname); m_log.InfoFormat("[IRC-Channel-{0}] User = {1}", cs.idn, cs.User); // Set the channel state for this region if (cs.RelayChat) { cs.ValidInWorldChannels.Add(0); cs.ValidInWorldChannels.Add(DEBUG_CHANNEL); } if (cs.RelayPrivateChannels) { cs.ValidInWorldChannels.Add(cs.RelayChannelOut); } rs.cs = Integrate(rs, cs); }
// Read the configuration file, performing variable substitution and any // necessary aliasing. See accompanying documentation for how this works. // If you don't need variables, then this works exactly as before. // If either channel or server are not specified, the request fails. internal static void OpenChannel(RegionState rs, IConfig config) { // Create a new instance of a channel. This may not actually // get used if an equivalent channel already exists. ChannelState cs = new ChannelState(); // Read in the configuration file and filter everything for variable // subsititution. m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); cs.Server = Substitute(rs, config.GetString("server", null)); m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); cs.Password = Substitute(rs, config.GetString("password", null)); // probably not a good idea to put a password in the log file cs.User = Substitute(rs, config.GetString("user", null)); cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); cs.User = Substitute(rs, config.GetString("username", cs.User)); m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting?"1":"0"))) > 0; m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); string[] excludes = config.GetString("exclude_list", "").Trim().Split(new Char[] { ',' }); cs.ExcludeList = new List<string>(excludes.Length); foreach (string name in excludes) { cs.ExcludeList.Add(name.Trim().ToLower()); } // Fail if fundamental information is still missing if (cs.Server == null || cs.IrcChannel == null || cs.BaseNickname == null || cs.User == null) throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}", cs.idn, rs.Region)); m_log.InfoFormat("[IRC-Channel-{0}] Configuration for Region {1} is valid", cs.idn, rs.Region); m_log.InfoFormat("[IRC-Channel-{0}] Server = {1}", cs.idn, cs.Server); m_log.InfoFormat("[IRC-Channel-{0}] Channel = {1}", cs.idn, cs.IrcChannel); m_log.InfoFormat("[IRC-Channel-{0}] Port = {1}", cs.idn, cs.Port); m_log.InfoFormat("[IRC-Channel-{0}] Nickname = {1}", cs.idn, cs.BaseNickname); m_log.InfoFormat("[IRC-Channel-{0}] User = {1}", cs.idn, cs.User); // Set the channel state for this region if (cs.RelayChat) { cs.ValidInWorldChannels.Add(0); cs.ValidInWorldChannels.Add(DEBUG_CHANNEL); } if (cs.RelayPrivateChannels) cs.ValidInWorldChannels.Add(cs.RelayChannelOut); rs.cs = Integrate(rs, cs); }
// An initialized channel state instance is passed in. If an identical // channel state instance already exists, then the existing instance // is used to replace the supplied value. // If the instance matches with respect to IRC, then the underlying // IRCConnector is assigned to the supplied channel state and the // updated value is returned. // If there is no match, then the supplied instance is completed by // creating and assigning an instance of an IRC connector. private static ChannelState Integrate(RegionState rs, ChannelState p_cs) { ChannelState cs = p_cs; // Check to see if we have an existing server/channel setup that can be used // In the absence of variable substitution this will always resolve to the // same ChannelState instance, and the table will only contains a single // entry, so the performance considerations for the existing behavior are // zero. Only the IRC connector is shared, the ChannelState still contains // values that, while independent of the IRC connetion, do still distinguish // this region's behavior. lock (IRCBridgeModule.m_channels) { foreach (ChannelState xcs in IRCBridgeModule.m_channels) { if (cs.IsAPerfectMatchFor(xcs)) { m_log.DebugFormat("[IRC-Channel-{0}] Channel state matched", cs.idn); cs = xcs; break; } if (cs.IsAConnectionMatchFor(xcs)) { m_log.DebugFormat("[IRC-Channel-{0}] Channel matched", cs.idn); cs.irc = xcs.irc; break; } } } // No entry was found, so this is going to be a new entry. if (cs.irc == null) { m_log.DebugFormat("[IRC-Channel-{0}] New channel required", cs.idn); if ((cs.irc = new IRCConnector(cs)) != null) { IRCBridgeModule.m_channels.Add(cs); m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", cs.idn, rs.Region, cs.DefaultZone, cs.CommandsEnabled ? "enabled" : "not enabled", cs.RelayPrivateChannels ? "relayed" : "not relayed"); } else { string txt = String.Format("[IRC-Channel-{0}] Region {1} failed to connect to channel {2} on server {3}:{4}", cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); m_log.Error(txt); throw new Exception(txt); } } else { m_log.InfoFormat("[IRC-Channel-{0}] Region {1} reusing existing connection to channel {2} on server {3}:{4}", cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); } m_log.InfoFormat("[IRC-Channel-{0}] Region {1} associated with channel {2} on server {3}:{4}", cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); // We're finally ready to commit ourselves return cs; }
public static XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request) { m_log.Info("[IRC-Bridge]: XML RPC Admin Entry"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable responseData = new Hashtable(); try { Hashtable requestData = (Hashtable)request.Params[0]; bool found = false; string region = String.Empty; if (password != String.Empty) { if (!requestData.ContainsKey("password")) { throw new Exception("Invalid request"); } if ((string)requestData["password"] != password) { throw new Exception("Invalid request"); } } if (!requestData.ContainsKey("region")) { throw new Exception("No region name specified"); } region = (string)requestData["region"]; foreach (RegionState rs in m_regions) { if (rs.Region == region) { responseData["server"] = rs.cs.Server; responseData["port"] = (int)rs.cs.Port; responseData["user"] = rs.cs.User; responseData["channel"] = rs.cs.IrcChannel; responseData["enabled"] = rs.cs.irc.Enabled; responseData["connected"] = rs.cs.irc.Connected; responseData["nickname"] = rs.cs.irc.Nick; found = true; break; } } if (!found) { throw new Exception(String.Format("Region <{0}> not found", region)); } responseData["success"] = true; } catch (Exception e) { m_log.InfoFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); responseData["success"] = "false"; responseData["error"] = e.Message; } finally { response.Value = responseData; } m_log.Debug("[IRC-Bridge]: XML RPC Admin Exit"); return(response); }
// This function implements the variable substitution mechanism // for the configuration values. Each string read from the // configuration file is scanned for '[...]' enclosures. Each // one that is found is replaced by either a runtime variable // (%xxx) or an existing configuration key. When no further // substitution is possible, the remaining string is returned // to the caller. This allows for arbitrarily nested // enclosures. private static string Substitute(RegionState rs, string instr) { string result = instr; if (string.IsNullOrEmpty(result)) return result; // Repeatedly scan the string until all possible // substitutions have been performed. // m_log.DebugFormat("[IRC-Channel] Parse[1]: {0}", result); while (arg.IsMatch(result)) { string vvar = arg.Match(result).ToString(); string var = vvar.Substring(1, vvar.Length - 2).Trim(); switch (var.ToLower()) { case "%region": result = result.Replace(vvar, rs.Region); break; case "%host": result = result.Replace(vvar, rs.Host); break; case "%locx": result = result.Replace(vvar, rs.LocX); break; case "%locy": result = result.Replace(vvar, rs.LocY); break; case "%k": result = result.Replace(vvar, rs.IDK); break; default: result = result.Replace(vvar, rs.config.GetString(var, var)); break; } // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); } // Now we unescape the literal brackets result = result.Replace(@"\[","[").Replace(@"\]","]"); // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result); return result; }
public void Initialise(Scene scene, IConfigSource config) { // Do a once-only scan of the configuration file to make // sure it's basically intact. if (!configured) { configured = true; try { if ((m_config = config.Configs["IRC"]) == null) { m_log.InfoFormat("[IRC-Bridge] module not configured"); return; } if (!m_config.GetBoolean("enabled", false)) { m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); return; } } catch (Exception e) { m_log.ErrorFormat("[IRC-Bridge] configuration failed : {0}", e.Message); return; } enabled = true; if (config.Configs["RemoteAdmin"] != null) { password = config.Configs["RemoteAdmin"].GetString("access_password", password); scene.CommsManager.HttpServer.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); } } // Iff the IRC bridge is enabled, then each new region may be // connected to IRC. But it should NOT be obligatory (and it // is not). // We have to do ALL of the startup here because PostInitialize // is not called when a region gets created in-flight from the // command line. if (enabled) { try { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); region = new RegionState(scene, m_config); lock (m_regions) m_regions.Add(region); region.Open(); } catch (Exception e) { m_log.WarnFormat("[IRC-Bridge] Region {0} not connected to IRC : {1}", scene.RegionInfo.RegionName, e.Message); m_log.Debug(e); } } else { m_log.WarnFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName); } }
// These are called by each region that attaches to this channel. The call affects // only the relationship of the region with the channel. Not the channel to IRC // relationship (unless it is closed and we want it open). public void Open(RegionState rs) { AddRegion(rs); Open(); }
public void AddRegion(Scene scene) { if (m_pluginEnabled) { try { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); if (!String.IsNullOrEmpty(m_password)) MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); m_region = new RegionState(scene, m_config); lock (m_regions) m_regions.Add(m_region); m_region.Open(); } catch (Exception e) { m_log.WarnFormat("[IRC-Bridge] Region {0} not connected to IRC : {1}", scene.RegionInfo.RegionName, e.Message); m_log.Debug(e); } } else { m_log.WarnFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName); } }
// These routines allow differentiating changes to // the underlying channel state. If necessary, a // new channel state will be created. internal ChannelState UpdateServer(RegionState rs, string server) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.Server = server; cs = Integrate(rs, cs); cs.AddRegion(rs); return cs; }
// Close is called to ensure that the IRC session is terminated if this is the // only client. public void Close(RegionState rs) { RemoveRegion(rs); lock (IRCBridgeModule.m_channels) { if (clientregions.Count == 0) { Close(); IRCBridgeModule.m_channels.Remove(this); m_log.InfoFormat("[IRC-Channel-{0}] Region {1} is last user of channel <{2}> to server <{3}:{4}>", idn, rs.Region, IrcChannel, Server, Port); m_log.InfoFormat("[IRC-Channel-{0}] Removed", idn); } } }
internal ChannelState UpdatePort(RegionState rs, string port) { RemoveRegion(rs); ChannelState cs = new ChannelState(this); cs.Port = Convert.ToUInt32(port); cs = Integrate(rs, cs); cs.AddRegion(rs); return cs; }
// An initialized channel state instance is passed in. If an identical // channel state instance already exists, then the existing instance // is used to replace the supplied value. // If the instance matches with respect to IRC, then the underlying // IRCConnector is assigned to the supplied channel state and the // updated value is returned. // If there is no match, then the supplied instance is completed by // creating and assigning an instance of an IRC connector. private static ChannelState Integrate(RegionState rs, ChannelState p_cs) { ChannelState cs = p_cs; // Check to see if we have an existing server/channel setup that can be used // In the absence of variable substitution this will always resolve to the // same ChannelState instance, and the table will only contains a single // entry, so the performance considerations for the existing behavior are // zero. Only the IRC connector is shared, the ChannelState still contains // values that, while independent of the IRC connetion, do still distinguish // this region's behavior. lock (IRCBridgeModule.m_channels) { foreach (ChannelState xcs in IRCBridgeModule.m_channels) { if (cs.IsAPerfectMatchFor(xcs)) { m_log.DebugFormat("[IRC-Channel-{0}] Channel state matched", cs.idn); cs = xcs; break; } if (cs.IsAConnectionMatchFor(xcs)) { m_log.DebugFormat("[IRC-Channel-{0}] Channel matched", cs.idn); cs.irc = xcs.irc; break; } } } // No entry was found, so this is going to be a new entry. if (cs.irc == null) { m_log.DebugFormat("[IRC-Channel-{0}] New channel required", cs.idn); if ((cs.irc = new IRCConnector(cs)) != null) { IRCBridgeModule.m_channels.Add(cs); m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", cs.idn, rs.Region, cs.DefaultZone, cs.CommandsEnabled ? "enabled" : "not enabled", cs.RelayPrivateChannels ? "relayed" : "not relayed"); } else { string txt = String.Format("[IRC-Channel-{0}] Region {1} failed to connect to channel {2} on server {3}:{4}", cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); m_log.Error(txt); throw new Exception(txt); } } else { m_log.InfoFormat("[IRC-Channel-{0}] Region {1} reusing existing connection to channel {2} on server {3}:{4}", cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); } m_log.InfoFormat("[IRC-Channel-{0}] Region {1} associated with channel {2} on server {3}:{4}", cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); // We're finally ready to commit ourselves return(cs); }