// TODO: rename this method, and rework it a bit private static bool Invoke( ref IRCMessage newMessage, IRCMessage message ) { if( IsAuthed( message.nickname, message.host ) ) { string[] cmdLine = message.chatMessage.Split( ' ' ); if( cmdLine.Length == 2 ) // Should cover most bans etc { // TODO: FIX THIS SHIT // It's bananas, it only handles players that are/have been online PlayerInfo OfflineOffender; Player Offender; bool pIsOnline = false; if( (Offender = Server.FindPlayer( cmdLine[1] )) != null ) { pIsOnline = true; HandlePlayer( ref newMessage, ref message, cmdLine[1] ); return true; } else if( pIsOnline == false ) { PlayerDB.FindPlayerInfo( cmdLine[1], out OfflineOffender ); if( OfflineOffender != null && message.cmd != IRCCommands.kick ) { HandlePlayer( ref newMessage, ref message, cmdLine[1] ); return true; } else { newMessage.chatMessage = "Sorry, no player by the name '" + cmdLine[1] + "' was found."; outMessages.Add( newMessage ); return false; } } } else { newMessage.chatMessage = "Incorrect Syntax for command '" + message.cmd.ToString() + ", try using !help."; } outMessages.Add( newMessage ); return true; } else { newMessage.chatMessage = "Sorry, you're not authorized to do that"; outMessages.Add( newMessage ); return false; } }
internal static void HandlePlayer( ref IRCMessage newMessage, ref IRCMessage message, string command ) { // Fix this with above switch( message.cmd ) { case (IRCCommands.kick): Commands.ParseCommand( fBot, "/kick " + command, true ); newMessage.chatMessage = " Kicked player: " + command + "!"; break; case (IRCCommands.ban): Commands.ParseCommand( fBot, "/ban " + command, true ); newMessage.chatMessage = " Banned(player): " + command + "!"; break; case (IRCCommands.banip): Commands.ParseCommand( fBot, "/banip " + command, true ); newMessage.chatMessage = "Banned(ip): " + command + "!"; break; case (IRCCommands.banall): Commands.ParseCommand( fBot, "/banall " + command, true ); newMessage.chatMessage = " Banned(all): " + command + "!"; break; case (IRCCommands.unban): Commands.ParseCommand( fBot, "/unban " + command, true ); newMessage.chatMessage = " Unbanned: " + command + "!"; break; case (IRCCommands.unbanip): Commands.ParseCommand( fBot, "/unbanip " + command, true ); newMessage.chatMessage = " Unbanned(ip): " + command + "!"; break; case (IRCCommands.unbanall): Commands.ParseCommand( fBot, "/unbanall " + command, true ); newMessage.chatMessage = " Unbanned(all): " + command + "!"; break; case (IRCCommands.slock): Commands.ParseCommand( fBot, "/lock " + command, true ); newMessage.chatMessage = " Initiated a Lockdown on the server!"; break; case (IRCCommands.unlock): Commands.ParseCommand( fBot, "/unlock " + command, true ); newMessage.chatMessage = " Revoked a Lockdown on the server!"; break; } Logger.Log( "(IRC)" + message.nickname + newMessage.chatMessage, LogType.IRC ); }
// TODO: Need a new way to detect command source private static bool CheckCommands( ref IRCMessage newMsg ) { string[] tmpMessage = newMsg.chatMessage.Split( ' ' ); if( tmpMessage.Length == 1 || tmpMessage.Length == 2 && newMsg.to == BOTNICK || tmpMessage.Length == 2 && newMsg.to == COMMA_PREFIX || tmpMessage.Length == 2 && newMsg.to == COLON_PREFIX ) { foreach( IRCCommands item in Enum.GetValues( typeof( IRCCommands ) ) ) { if( newMsg.chatMessage.Contains( "!" + item.ToString() ) ) { newMsg.cmd = item; return true; } } } return false; }
public static void RemoveOutgoingMessage( IRCMessage msg ) { outMessages.Remove( msg ); }
// Check for player joins and send a message to the channels to notify public static void SendPlayerJoinMsg( Session session, ref bool cancel ) { session.player.Message( "This server's IRC Bot is" + Color.Red + " Online." ); session.player.Message( "Use '#<message>' in chat to forward messages to the IRC Channel(s)." ); IRCMessage newMsg = new IRCMessage() { chatMessage = session.player.GetLogName() + " has joined " + Config.GetString( ConfigKey.ServerName ) + ".", destination = Destination.Channels }; outMessages.Add( newMsg ); IRCComm.Process(); }
public static bool SendMsgChannels( IRCMessage message ) { try { foreach( string channel in CHANNELS ) { #if DEBUG_IRC Console.WriteLine("*SENT-MESSAGE* :" + message.chatMessage + " | to: " + message.to); #endif if( message.colour != null && message.colour != "" ) writer.WriteLine( "PRIVMSG " + channel + " :" + message.colour + message.chatMessage + "\r\n" ); else writer.WriteLine( "PRIVMSG " + channel + " :" + message.chatMessage + "\r\n" ); writer.Flush(); } return true; } catch( Exception e ) { Console.WriteLine( e.ToString() ); return false; } }
// Parse IRC Message into a nice package for use public static void ParseMsg( ref IRCMessage newMsg, string input ) { // This code handles ping/pong to keep the irc bot alive and connected if( input.StartsWith( "PING :" ) ) { if( IRCComm.InitConnect() ) { string pongresp = input.Substring( 6, input.Length - 6 ); newMsg.type = "RAW"; newMsg.chatMessage = "PONG :" + pongresp; newMsg.destination = Destination.RAW; outMessages.Add( newMsg ); return; } else { SERVERHOST = input.Substring( 6, input.Length - 6 ); if( BOTHOST != "" ) { newMsg.type = "RAW"; newMsg.chatMessage = "PONG :" + BOTHOST + " " + SERVERHOST; newMsg.destination = Destination.RAW; outMessages.Add( newMsg ); return; } else Console.WriteLine( "*** ERROR: BOTHOST was empty, this means it couldn't parse a host! ***" ); } // Need this line to grab the bot's hostname to respond to pings } else if( input.Contains( "JOIN" ) ) { Regex exp = new Regex( @"^:([^!]+)!([^@]*)@([^ ]+) ([A-Z]+) :(#?[^ ]+)$" ); MatchCollection matches = exp.Matches( input ); foreach( Match match in matches ) { GroupCollection tmpGroup = match.Groups; BOTHOST = tmpGroup[3].ToString(); } } else { Regex exp = new Regex( @"^:([^!]+)!([^@]*)@([^ ]+) ([A-Z]+) (#?[^ ]+) :(.*)$" ); MatchCollection matches = exp.Matches( input ); foreach( Match match in matches ) { GroupCollection tmpGroup = match.Groups; // tmpGroup contains: // 0 is the raw IRC message itself, 1 Nickname, 2 Username, 3 Host, 4 Message type, 5 Channel/User the message was sent to, 6 Message content newMsg.nickname = tmpGroup[1].ToString().Trim(); newMsg.user = tmpGroup[2].ToString(); newMsg.host = tmpGroup[3].ToString(); newMsg.type = tmpGroup[4].ToString(); newMsg.to = tmpGroup[5].ToString(); newMsg.chatMessage = tmpGroup[6].ToString().Trim(); if( newMsg.type == "MODE" || newMsg.type == "NOTICE" ) { newMsg.chatMessage = null; return; } } if( CHANNELS.Contains( newMsg.to ) ) { // check for commands if( CheckCommands( ref newMsg ) ) { newMsg.to = BOTNICK; newMsg.destination = Destination.NOTICE; return; } if( FORWARD_IRC ) { newMsg.destination = Destination.Server; } else { if( newMsg.chatMessage != null && newMsg.chatMessage != "" ) { if( newMsg.chatMessage.IndexOf( COMMA_PREFIX ) != -1 ) { newMsg.chatMessage = newMsg.chatMessage.Substring( newMsg.chatMessage.IndexOf( COMMA_PREFIX ) + COMMA_PREFIX.Length ).Trim(); newMsg.destination = Destination.Server; } else if( newMsg.chatMessage.IndexOf( COLON_PREFIX ) != -1 ) { newMsg.chatMessage = newMsg.chatMessage.Substring( newMsg.chatMessage.IndexOf( COLON_PREFIX ) + COLON_PREFIX.Length ).Trim(); newMsg.destination = Destination.Server; } else if( newMsg.chatMessage.IndexOf( BOTNICK ) != -1 ) { newMsg.chatMessage = newMsg.chatMessage.Substring( newMsg.chatMessage.IndexOf( BOTNICK ) + BOTNICK.Length ).Trim(); newMsg.destination = Destination.Server; } } } } if( newMsg.to == BOTNICK ) // Catch chat messages to the bot itself { if( CheckCommands( ref newMsg ) ) return; // Find a command? Return! if( newMsg.chatMessage.Contains( "#" ) ) { newMsg.nickname = BOTNICK; newMsg.chatMessage = newMsg.chatMessage.Substring( newMsg.chatMessage.IndexOf( "#" ) + 1 ); newMsg.destination = Destination.Server; } } } }
void HandleMessage([NotNull] string message) { if (message == null) { throw new ArgumentNullException("message"); } IRCMessage msg = MessageParser(message, ActualBotNick); #if DEBUG_IRC Logger.Log(LogType.IRC, "[{0}]: {1}", msg.Type, msg.RawMessage); #endif switch (msg.Type) { case IRCMessageType.Login: if (ConfigKey.IRCRegisteredNick.Enabled()) { Send(IRCCommands.Privmsg(ConfigKey.IRCNickServ.GetString(), ConfigKey.IRCNickServMessage.GetString())); } foreach (string channel in channelNames) { if (ConfigKey.IRCChannelPassword.GetString() != "password") { Send(IRCCommands.Join(channel + " " + ConfigKey.IRCChannelPassword.GetString())); } else { Send(IRCCommands.Join(channel)); } } IsReady = true; AssignBotForInputParsing(); // bot should be ready to receive input after joining return; case IRCMessageType.Ping: // ping-pong Send(IRCCommands.Pong(msg.RawMessageArray[1].Substring(1))); return; case IRCMessageType.ChannelAction: case IRCMessageType.ChannelMessage: // channel chat if (!ResponsibleForInputParsing) { return; } if (!IsBotNick(msg.Nick)) { string processedMessage = msg.Message; if (msg.Type == IRCMessageType.ChannelAction) { if (processedMessage.StartsWith("\u0001ACTION")) { processedMessage = processedMessage.Substring(8); } else { return; } } processedMessage = NonPrintableChars.Replace(processedMessage, ""); if (processedMessage.Length > 0) { if (ConfigKey.IRCBotForwardFromIRC.Enabled()) { if (msg.Type == IRCMessageType.ChannelAction) { Server.Message("&i(IRC) * {0} {1}", msg.Nick, processedMessage); Logger.Log(LogType.IRC, "(IRC) * {0} {1}", msg.Nick, processedMessage); } else { Server.Message("&i(IRC) {0}{1}: {2}", msg.Nick, Color.White, processedMessage); Logger.Log(LogType.IRC, "(IRC) {0}: {1}", msg.Nick, processedMessage); } } else if (msg.Message.StartsWith("#")) { Server.Message("&i(IRC) {0}{1}: {2}", msg.Nick, Color.White, processedMessage.Substring(1)); Logger.Log(LogType.IRC, "(IRC) {0}: {1}", msg.Nick, processedMessage.Substring(1)); } } } return; case IRCMessageType.Join: if (!ResponsibleForInputParsing) { return; } if (ConfigKey.IRCBotAnnounceIRCJoins.Enabled()) { Server.Message("&i(IRC) {0} joined {1}", msg.Nick, msg.Channel); } return; case IRCMessageType.Kick: string kicked = msg.RawMessageArray[3]; if (kicked == ActualBotNick) { Logger.Log(LogType.IRC, "Bot was kicked from {0} by {1} ({2}), rejoining.", msg.Channel, msg.Nick, msg.Message); Thread.Sleep(ReconnectDelay); Send(IRCCommands.Join(msg.Channel)); } else { if (!ResponsibleForInputParsing) { return; } Server.Message("&i(IRC) {0} kicked {1} from {2} ({3})", msg.Nick, kicked, msg.Channel, msg.Message); } return; case IRCMessageType.Part: case IRCMessageType.Quit: if (!ResponsibleForInputParsing) { return; } if (ConfigKey.IRCBotAnnounceIRCJoins.Enabled()) { Server.Message("&i(IRC) {0} left {1}", msg.Nick, msg.Channel); } return; case IRCMessageType.NickChange: if (!ResponsibleForInputParsing) { return; } Server.Message("&i(IRC) {0} is now known as {1}", msg.Nick, msg.Message); return; case IRCMessageType.ErrorMessage: case IRCMessageType.Error: bool die = false; switch (msg.ReplyCode) { case IRCReplyCode.ErrorNicknameInUse: case IRCReplyCode.ErrorNicknameCollision: Logger.Log(LogType.IRC, "Error: Nickname \"{0}\" is already in use. Trying \"{0}_\"", ActualBotNick); ActualBotNick += "_"; Send(IRCCommands.Nick(ActualBotNick)); break; case IRCReplyCode.ErrorPasswordMismatch: if (triedPass) { Logger.Log(LogType.IRC, "Could not connect with irc server password. Please configure your correct irc server password in the ConfigGUI."); die = true; break; } if (ConfigKey.IRCBotNetworkPass.GetString() == "defaultPass") { Logger.Log(LogType.IRC, "Requested irc server is password-locked. Please set your irc server password in the ConfigGUI."); break; } Logger.Log(LogType.IRC, "Requested irc server is password-locked, attempting to connect with " + ConfigKey.IRCBotNetworkPass.GetString()); //give the irc client a second to prompt for password before sending Scheduler.NewTask(t => SendChannelMessage("/pass " + ConfigKey.IRCBotNetworkPass.GetString())).RunManual(TimeSpan.FromSeconds(2)); triedPass = true; break; case IRCReplyCode.ErrorBannedFromChannel: case IRCReplyCode.ErrorNoSuchChannel: Logger.Log(LogType.IRC, "Error: {0} ({1})", msg.ReplyCode, msg.Channel); die = true; break; default: Logger.Log(LogType.IRC, "Error ({0}): {1}", msg.ReplyCode, msg.RawMessage); break; } if (die) { Logger.Log(LogType.IRC, "Error: Disconnecting."); reconnect = false; DisconnectThread(); } return; case IRCMessageType.QueryAction: // TODO: PMs Logger.Log(LogType.IRC, "Query: {0}", msg.RawMessage); break; case IRCMessageType.Kill: Logger.Log(LogType.IRC, "Bot was killed from {0} by {1} ({2}), reconnecting.", hostName, msg.Nick, msg.Message); reconnect = true; isConnected = false; return; } }
public static void AddMessage( IRCMessage message ) { messageStack.Add( message ); }
private void HandleMessage([NotNull] string message) { if (message == null) { throw new ArgumentNullException("message"); } IRCMessage msg = MessageParser(message, ActualBotNick); #if DEBUG_IRC Logger.Log(LogType.IRC, "[{0}]: {1}", msg.Type, msg.RawMessage); #endif switch (msg.Type) { case IRCMessageType.Login: if (ConfigKey.IRCRegisteredNick.Enabled()) { Send(IRCCommands.Privmsg(ConfigKey.IRCNickServ.GetString(), ConfigKey.IRCNickServMessage.GetString())); } foreach (string channel in channelNames) { Send(IRCCommands.Join(channel)); } IsReady = true; AssignBotForInputParsing(); // bot should be ready to receive input after joining return; case IRCMessageType.Ping: // ping-pong Send(IRCCommands.Pong(msg.RawMessageArray[1].Substring(1))); return; case IRCMessageType.ChannelAction: case IRCMessageType.ChannelMessage: // channel chat if (!ResponsibleForInputParsing) { return; } if (!IsBotNick(msg.Nick)) { string processedMessage = msg.Message; if (msg.Type == IRCMessageType.ChannelAction) { if (processedMessage.StartsWith("\u0001ACTION")) { processedMessage = processedMessage.Substring(8); } else { return; } } processedMessage = NonPrintableChars.Replace(processedMessage, ""); if (processedMessage.Length > 0) { if (ConfigKey.IRCBotForwardFromIRC.Enabled()) { if (msg.Type == IRCMessageType.ChannelAction) { Server.Message("(IRC) * {0} {1}", msg.Nick, processedMessage); Logger.Log(LogType.IRC, " * {0} {1}", msg.Nick, processedMessage); } else { Server.Message("&i(IRC) {0}{1}: {2}", msg.Nick, Color.White, processedMessage); Logger.Log(LogType.IRC, "{0}: {1}", msg.Nick, processedMessage); } } else if (msg.Message.StartsWith("#")) { Server.Message("&i(IRC) {0}{1}: {2}", msg.Nick, Color.White, processedMessage.Substring(1)); Logger.Log(LogType.IRC, "{0}: {1}", msg.Nick, processedMessage.Substring(1)); } } } return; case IRCMessageType.Join: if (!ResponsibleForInputParsing) { return; } if (ConfigKey.IRCBotAnnounceIRCJoins.Enabled()) { Server.Message("&i(IRC) {0} joined {1}", msg.Nick, msg.Channel); } return; case IRCMessageType.Kick: string kicked = msg.RawMessageArray[3]; if (kicked == ActualBotNick) { Logger.Log(LogType.IRC, "Bot was kicked from {0} by {1} ({2}), rejoining.", msg.Channel, msg.Nick, msg.Message); Thread.Sleep(ReconnectDelay); Send(IRCCommands.Join(msg.Channel)); } else { if (!ResponsibleForInputParsing) { return; } Server.Message("&i(IRC) {0} kicked {1} from {2} ({3})", msg.Nick, kicked, msg.Channel, msg.Message); } return; case IRCMessageType.Part: case IRCMessageType.Quit: if (!ResponsibleForInputParsing) { return; } if (ConfigKey.IRCBotAnnounceIRCJoins.Enabled()) { Server.Message("&i(IRC) {0} left {1}", msg.Nick, msg.Channel); } return; case IRCMessageType.NickChange: if (!ResponsibleForInputParsing) { return; } Server.Message("&i(IRC) {0} is now known as {1}", msg.Nick, msg.Message); return; case IRCMessageType.ErrorMessage: case IRCMessageType.Error: bool die = false; switch (msg.ReplyCode) { case IRCReplyCode.ErrorNicknameInUse: case IRCReplyCode.ErrorNicknameCollision: Logger.Log(LogType.IRC, "Error: Nickname \"{0}\" is already in use. Trying \"{0}_\"", ActualBotNick); ActualBotNick += "_"; Send(IRCCommands.Nick(ActualBotNick)); break; case IRCReplyCode.ErrorBannedFromChannel: case IRCReplyCode.ErrorNoSuchChannel: Logger.Log(LogType.IRC, "Error: {0} ({1})", msg.ReplyCode, msg.Channel); die = true; break; case IRCReplyCode.ErrorBadChannelKey: Logger.Log(LogType.IRC, "Error: Channel password required for {0}. fCraft does not currently support passworded channels.", msg.Channel); die = true; break; default: Logger.Log(LogType.IRC, "Error ({0}): {1}", msg.ReplyCode, msg.RawMessage); break; } if (die) { Logger.Log(LogType.IRC, "Error: Disconnecting."); reconnect = false; DisconnectThread(); } return; case IRCMessageType.QueryAction: // TODO: PMs Logger.Log(LogType.IRC, "Query: {0}", msg.RawMessage); break; case IRCMessageType.Kill: Logger.Log(LogType.IRC, "Bot was killed from {0} by {1} ({2}), reconnecting.", hostName, msg.Nick, msg.Message); reconnect = true; isConnected = false; return; } }
void HandleMessage([NotNull] string message) { if (message == null) { throw new ArgumentNullException("message"); } IRCMessage msg = IRC.MessageParser(message, ActualBotNick); var SendList = Server.Players.Where(p => !p.IsDeaf && !p.GlobalChatIgnore); #if DEBUG_IRC Logger.Log(LogType.IRC, "[{0}]: {1}", msg.Type, msg.RawMessage); #endif switch (msg.Type) { case IRCMessageType.Login: foreach (string channel in channelNames) { Send(IRCCommands.Join(channel)); } IsReady = true; AssignBotForInputParsing(); // bot should be ready to receive input after joining return; case IRCMessageType.Ping: // ping-pong Send(IRCCommands.Pong(msg.RawMessageArray[1].Substring(1))); return; case IRCMessageType.ChannelAction: case IRCMessageType.ChannelMessage: // channel chat if (!ResponsibleForInputParsing) { return; } string processedMessage = msg.Message; if (msg.Type == IRCMessageType.ChannelAction) { if (processedMessage.StartsWith("\u0001ACTION")) { processedMessage = processedMessage.Substring(8); } else { return; } } processedMessage = IRC.NonPrintableChars.Replace(processedMessage, ""); if (processedMessage.Length > 0) { if (msg.Type == IRCMessageType.ChannelAction) { SendList.Message("&g[Global] * {1} {2}", ActualBotNick, msg.Nick, processedMessage); Logger.Log(LogType.GlobalChat, "[Global] * {1} {2}", ActualBotNick, msg.Nick, processedMessage); } else { SendList.Message("&g[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage); Logger.Log(LogType.GlobalChat, "[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage); } } else if (msg.Message.StartsWith("#")) { SendList.Message("&g[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage.Substring(1)); Logger.Log(LogType.GlobalChat, "[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage.Substring(1)); } return; case IRCMessageType.Join: if (!ResponsibleForInputParsing) { return; } if (msg.Nick.StartsWith("(")) { SendList.Message("&g[Global] Server {0} joined the LegendCraft Global Chat", msg.Nick); Logger.Log(LogType.GlobalChat, "[Global] Server {0} joined the LegendCraft Global Chat", msg.Nick); } else { SendList.Message("&g[Global] {0} joined the LegendCraft Global Chat", msg.Nick); Logger.Log(LogType.GlobalChat, "[Global] {0} joined the LegendCraft Global Chat", msg.Nick); } return; case IRCMessageType.Kick: string kicked = msg.RawMessageArray[3]; if (kicked == ActualBotNick) { Logger.Log(LogType.SystemActivity, "Bot was kicked from {0} by {1}({2}), rejoining.", msg.Channel, msg.Nick, msg.Message); Thread.Sleep(ReconnectDelay); Send(IRCCommands.Join(msg.Channel)); } else { if (!ResponsibleForInputParsing) { return; } SendList.Message("&g[Global] {0} kicked {1}({2})", msg.Nick, kicked, msg.Message); Logger.Log(LogType.GlobalChat, "[Global] {0} kicked {1}({2})", msg.Nick, kicked, msg.Message); } return; case IRCMessageType.Part: case IRCMessageType.Quit: if (!ResponsibleForInputParsing) { return; } SendList.Message("&g[Global] Server {0} left the LegendCraft Global Chat", msg.Nick); Logger.Log(LogType.GlobalChat, "[Global] Server {0} left the LegendCraft Global Chat", msg.Nick); return; case IRCMessageType.NickChange: if (!ResponsibleForInputParsing) { return; } SendList.Message("&g[Global] {0} is now known as {1}", msg.Nick, msg.Message); Logger.Log(LogType.GlobalChat, "[Global] {0} is now known as {1}", msg.Nick, msg.Message); return; case IRCMessageType.ErrorMessage: case IRCMessageType.Error: bool die = false; switch (msg.ReplyCode) { case IRCReplyCode.ErrorNicknameInUse: case IRCReplyCode.ErrorNicknameCollision: ActualBotNick = ActualBotNick.Remove(ActualBotNick.Length - 4) + "_"; Logger.Log(LogType.SystemActivity, "Error: Global Chat Nickname is already in use. Trying \"{0}\"", ActualBotNick); Send(IRCCommands.Nick(ActualBotNick)); break; case IRCReplyCode.ErrorBannedFromChannel: case IRCReplyCode.ErrorNoSuchChannel: Logger.Log(LogType.SystemActivity, "Error: {0}({1})", msg.ReplyCode, msg.Channel); GCReady = false; die = true; break; //wont happen case IRCReplyCode.ErrorBadChannelKey: Logger.Log(LogType.SystemActivity, "Error: Channel password required for {0}. LegendCraft does not currently support passworded channels.", msg.Channel); die = true; GCReady = false; break; default: Logger.Log(LogType.SystemActivity, "Error({0}): {1}", msg.ReplyCode, msg.RawMessage); GCReady = false; break; } if (die) { Logger.Log(LogType.SystemActivity, "Error: Disconnecting from Global Chat."); reconnect = false; DisconnectThread(); } return; case IRCMessageType.QueryAction: // TODO: PMs Logger.Log(LogType.SystemActivity, "Query: {0}", msg.RawMessage); break; case IRCMessageType.Kill: Logger.Log(LogType.SystemActivity, "Bot was killed from {0} by {1}({2}), reconnecting.", hostName, msg.Nick, msg.Message); reconnect = true; isConnected = false; return; } }
static void CommHandler() { try { #region Initialize connection and register // Initiate connection and bring the streams to life! connection = new TcpClient( IRCSERVER, PORT ); stream = connection.GetStream(); reader = new StreamReader( stream ); writer = new StreamWriter( stream ); // IRC Registration RFC demands you send your user credentials serverMsg.chatMessage = USER; SendRaw( ref serverMsg ); // Then send the nickname you will use serverMsg.chatMessage = "NICK " + BOTNICK + "\r\n"; SendRaw( ref serverMsg ); // After registration is done firstConnect = true; #endregion while( true ) { // Prevent exceptions being thrown on thread.abort() if( connection.Connected != true ) { online = false; throw new Exception( "Connection was severed somehow." ); } // If the server is going offline, return, else process messages if( doShutdown ) return; else { Process(); Thread.Sleep( 500 ); } #region Read stream and parse messages // get ready to read input String serverInput; byte[] myReadBuffer = new byte[2048]; String myCompleteMessage = ""; int numberOfBytesRead = 0; do // Read input while data is available { // Read from the stream and place the read buffer into serverInput numberOfBytesRead = stream.Read( myReadBuffer, 0, myReadBuffer.Length ); serverInput = String.Concat( myCompleteMessage, Encoding.ASCII.GetString( myReadBuffer, 0, numberOfBytesRead ) ); #if DEBUG_IRC_RAW Console.WriteLine("*BYTES* :" + numberOfBytesRead); #endif // Split each line in the buffer by \r\n String[] splitParam = new String[1]; splitParam[0] = "\r\n"; String[] tmpServerMsgs = serverInput.Split( splitParam, System.StringSplitOptions.RemoveEmptyEntries ); // Loop through each line we have and parse it foreach( String msg in tmpServerMsgs ) { #if DEBUG_IRC_RAW Console.WriteLine("*SERVERMSG* :" + msg); #endif // check each message for errors if( firstConnect ) Init( msg ); // If the server has just registered, join channels etc. else if( msg.StartsWith( "ERROR :Closing Link:" ) ) throw new Exception( "Connection was terminated by the server." ); else // If no errors are found, parse the message { IRCMessage message = new IRCMessage(); IRCBot.ParseMsg( ref message, msg ); // Parse the message for something useful (commands, etc) if( message.chatMessage != null && message.chatMessage != "" ) { IRCBot.AddMessage( message ); // TODO: Instead of only adding messages to a stack, throw an event too } } } Thread.Sleep( 100 ); } while( stream.DataAvailable ); #endregion } } catch( ThreadAbortException ex ) { Console.WriteLine( ex.ToString() ); thread.Abort(); } catch( Exception ex ) { if( doShutdown ) return; if( ex.Message.Contains( "(433)" ) ) { BOTNICK = BOTNICK + NICKVALUE; NICKVALUE++; } Logger.Log( "IRC Bot has been disconnected, trying to restart: " + ex.Message, LogType.Error ); #if DEBUG_IRC_RAW Console.WriteLine(ex.ToString()); #endif Thread.Sleep( 10000 ); firstConnect = true; CommHandler(); } }
internal static bool SendRaw( ref IRCMessage message ) { try { #if DEBUG_IRC Console.WriteLine("*SENT-RAW* :" + message.chatMessage ); #endif writer.WriteLine( message.chatMessage ); writer.Flush(); return true; } catch( Exception e ) { Console.WriteLine( e.ToString() ); return false; } }
public static bool SendPM( IRCMessage message ) { try { #if DEBUG_IRC Console.WriteLine("*SENT-PM* :" + message.chatMessage + " | to: " + message.to); #endif if( message.colour != null && message.colour != "" ) writer.WriteLine( "PRIVMSG " + message.to + " :" + message.colour + message.chatMessage + "\r\n" ); else writer.WriteLine( "PRIVMSG " + message.to + " :" + message.chatMessage + "\r\n" ); writer.Flush(); return true; } catch( Exception e ) { Console.WriteLine( e.ToString() ); return false; } }
static void MessageHandler() { try { // After the IRCComm is online, // start keeping an eye on the message stack while( true ) { // Always ALWAYS keep the bot's nickname straight, // if the server throws 433 the nick will have a number appended if( BOTNICK != IRCComm.GetBotNick() ) { BOTNICK = IRCComm.GetBotNick(); } List<IRCMessage> tempMsgStack = new List<IRCMessage>(); tempMsgStack.AddRange( messageStack ); if( tempMsgStack.Count > 0 ) { foreach( IRCMessage message in tempMsgStack ) { IRCMessage newMessage = new IRCMessage(); // If it's a private message to the bot, start handling IRCCommands if( message.to == BOTNICK ) { newMessage.to = message.nickname; newMessage.destination = message.destination; if( message.cmd == IRCCommands.status ) { #region StatusMessage // Put together all of the status variables from world and such newMessage.chatMessage = message.nickname + ", you have requested a status update."; outMessages.Add( newMessage ); newMessage.chatMessage = "Server Name: ** " + Config.GetString( ConfigKey.ServerName ) + " **"; outMessages.Add( newMessage ); newMessage.chatMessage = "MOTD: ** " + Config.GetString( ConfigKey.MOTD ) + " **"; outMessages.Add( newMessage ); newMessage.chatMessage = "Address: ** " + Config.ServerURL + " **"; outMessages.Add( newMessage ); newMessage.chatMessage = "Players online: ** " + Server.GetPlayerCount() + " **"; outMessages.Add( newMessage ); // This is broken for now string[] playerList = Server.PlayerListToString().Split( ',' ); //// List the players online if there are any if( playerList.Length > 0 ) { int count = 0; newMessage.chatMessage = "Players:"; outMessages.Add( newMessage ); foreach( string player in playerList ) { newMessage.chatMessage = " ** " + player + " ** "; outMessages.Add( newMessage ); ++count; } } #endregion } else if( message.cmd == IRCCommands.help ) { #region HelpMessage newMessage.chatMessage = "Hello, " + message.nickname + " , you have requested help!"; outMessages.Add( newMessage ); newMessage.chatMessage = "** Be patient the help line is long **"; outMessages.Add( newMessage ); newMessage.chatMessage = "***********************************************************"; outMessages.Add( newMessage ); newMessage.chatMessage = "Public IRCCommands:"; outMessages.Add( newMessage ); newMessage.chatMessage = " !status - Gives the status of the server itself."; outMessages.Add( newMessage ); newMessage.chatMessage = " !auth <password> - Authorize with the bot with the password you registered from inside the server."; outMessages.Add( newMessage ); newMessage.chatMessage = " !help - Displays this message."; outMessages.Add( newMessage ); newMessage.chatMessage = " Chat IRCCommands:"; outMessages.Add( newMessage ); newMessage.chatMessage = " # - initiates sending a chat message to the server from this PM."; outMessages.Add( newMessage ); newMessage.chatMessage = " <botname>: - initiates sending a chat message to the server from a channel."; outMessages.Add( newMessage ); if( IsAuthed( message.nickname, message.host ) ) { newMessage.chatMessage = "***********************************************************"; outMessages.Add( newMessage ); newMessage.chatMessage = "Authorized User IRCCommands:"; outMessages.Add( newMessage ); newMessage.chatMessage = " !kick <player> - initiates kicking a player from the server."; outMessages.Add( newMessage ); newMessage.chatMessage = " !ban <player> - initiates banning a player from the server by nickname."; outMessages.Add( newMessage ); newMessage.chatMessage = " !banip <ip address> - initiates banning a player from the server by IP."; outMessages.Add( newMessage ); newMessage.chatMessage = " !banall <player> - initiates banning a player from the server by Name, IP, and any players from the same IP."; outMessages.Add( newMessage ); newMessage.chatMessage = " !unban <player> - initiates banning a player from the server."; outMessages.Add( newMessage ); newMessage.chatMessage = " !unbanip <player> - initiates banning a player from the server."; outMessages.Add( newMessage ); newMessage.chatMessage = " !unbanip <player> - initiates banning a player from the server."; outMessages.Add( newMessage ); newMessage.chatMessage = " !slock - initiates Lockdown mode for the server."; outMessages.Add( newMessage ); newMessage.chatMessage = " !unlock - revokes Lockdown mode for the server."; outMessages.Add( newMessage ); } #endregion } else if( message.cmd == IRCCommands.auth ) { #region Authenticate string[] authLine = message.chatMessage.Split( ' ' ); if( authLine.Length == 2 ) { // Need an authorization workup here // registerdnicks.contains(message.nickname) // password matches registered users password if( authLine[1] == "auth0riz3m3" )// Bot auth password { string authResponse = message.nickname + " Authenticated to host " + message.host; newMessage.chatMessage = message.nickname + ", you have authenticated with the host " + message.host + "."; outMessages.Add( newMessage ); Logger.Log( message.nickname + " Authenticated to host " + message.host, LogType.IRC ); AuthPkg newAuth = new AuthPkg() { host = message.host, nickname = message.nickname }; authedHosts.Add( newAuth ); } else { newMessage.chatMessage = "Sorry, that was the wrong password associated with the nickname - " + message.nickname; outMessages.Add( newMessage ); } } else { newMessage.chatMessage = "Sorry, your auth request contained too many/few parameters. Try again or type !help for useage."; outMessages.Add( newMessage ); } } else if( message.cmd >= IRCCommands.kick ) { Invoke( ref newMessage, message ); } else if( message.chatMessage.Contains( "Hello" ) || message.chatMessage.Contains( "hello" ) ) { newMessage.chatMessage = "Hi there, " + message.nickname + "!"; newMessage.chatMessage = "You can access help by typing '!help'."; outMessages.Add( newMessage ); } else { newMessage.chatMessage = "Sorry, unreadable Command. Try typing '!help' for help."; outMessages.Add( newMessage ); } #endregion } if( message.destination == Destination.Server && message.chatMessage != null && message.chatMessage != "" ) { string stringToServer = "(IRC)" + message.nickname + ": " + message.chatMessage; Logger.Log( stringToServer, LogType.IRC ); Server.SendToAll( stringToServer ); } // Remove parsed messages from the message stack messageStack.Remove( message ); } // Clean the message stack that we copied tempMsgStack.Clear(); } else Thread.Sleep( 1 ); // No messages? Sleeeep if( doShutdown == true ) return; } } catch( ThreadAbortException tb ) { Console.WriteLine( tb.ToString() ); thread.Abort(); } catch( Exception e ) { Logger.Log( "IRC Message parser has crashed! It should recover now.", LogType.Error ); Console.WriteLine( e.ToString() ); messageStack.Clear(); Thread.Sleep( 10 ); MessageHandler(); } }
public static void AddOutgoingMessage( IRCMessage msg ) { outMessages.Add( msg ); }
// Parses message incoming from the player public void ParseMessage( string message, bool fromConsole ) { if( DateTime.Now < mutedUntil ) return; if( world != null && !world.FireSentMessageEvent( this, ref message ) ) return; switch( Commands.GetMessageType( message ) ) { case MessageType.Chat: if( CheckChatSpam() ) return; if (!Can(Permissions.Chat)) return; info.linesWritten++; string displayedName = nick; if( Config.GetBool( ConfigKey.ClassPrefixesInChat ) ) { displayedName = info.playerClass.prefix + displayedName; } if( Config.GetBool( ConfigKey.ClassColorsInChat ) && info.playerClass.color != "" && info.playerClass.color != Color.White ) { displayedName = info.playerClass.color + displayedName + Color.White; } Server.SendToAll( displayedName + ": " + message, null ); // IRC Bot code for sending messages if( IRCBot.IsOnline() ) { if( IRCComm.FORWARD_SERVER ) { IRCMessage newMsg = new IRCMessage(); newMsg.chatMessage = nick + ": " + message.Substring( message.IndexOf( "#" ) + 1 ); newMsg.destination = Destination.Channels; IRCBot.AddOutgoingMessage( newMsg ); IRCComm.Process(); } else { if( message.Contains( "#" ) ) { IRCMessage newMsg = new IRCMessage(); string tmpChat = message.Substring( message.IndexOf( "#" ) + 1 ); if( tmpChat != "" ) { newMsg.chatMessage = nick + ": " + tmpChat; newMsg.destination = Destination.Channels; IRCBot.AddOutgoingMessage( newMsg ); IRCComm.Process(); } } } } Logger.Log( "{0}: {1}", LogType.WorldChat, GetLogName(), message ); break; case MessageType.Command: Logger.Log( "{0}: {1}", LogType.UserCommand, GetLogName(), message ); Commands.ParseCommand( this, message, fromConsole ); break; case MessageType.PrivateChat: if( CheckChatSpam() ) return; if (!Can(Permissions.PrivateChat)) return; string otherPlayerName = message.Substring( 1, message.IndexOf( ' ' ) - 1 ); Player otherPlayer = Server.FindPlayer( otherPlayerName ); if( otherPlayer != null ) { Logger.Log( "{0} to {1}: {2}", LogType.PrivateChat, GetLogName(), otherPlayer.GetLogName(), message ); otherPlayer.Message( Color.Gray, "from " + name + ": " + message.Substring( message.IndexOf( ' ' ) + 1 ) ); Message( Color.Gray, "to " + otherPlayer.name + ": " + message.Substring( message.IndexOf( ' ' ) + 1 ) ); } else { NoPlayerMessage( otherPlayerName ); } break; case MessageType.ClassChat: if( CheckChatSpam() ) return; if (!Can(Permissions.Chat)) return; string className = message.Substring( 2, message.IndexOf( ' ' ) - 2 ); PlayerClass playerClass = ClassList.FindClass( className ); if( playerClass != null ) { Logger.Log( "{0} to class {1}: {2}", LogType.ClassChat, GetLogName(), playerClass.name, message ); Packet classMsg = PacketWriter.MakeMessage( Color.Gray + "[" + playerClass.color + playerClass.name + Color.Gray + "]" + nick + ": " + message.Substring( message.IndexOf( ' ' ) + 1 ) ); Server.SendToClass( classMsg, playerClass, this ); if( info.playerClass != playerClass ) { Send( classMsg ); } } else { Message( "No class found matching \"" + className + "\"" ); } break; } }
// Process messages that need to be sent to the IRC server public static void Process() { outMessages.AddRange( IRCBot.GetOutgoingMessages() ); // Process messages on the stack if( outMessages.Count > 0 ) { int count = 0; foreach( IRCMessage msg in outMessages ) { // Prevent spamming the entire stack at once and getting kicked for flooding if( count == 4 ) Thread.Sleep( 5000 ); if( msg.destination == Destination.PM ) SendPM( msg ); else if( msg.destination == Destination.Channels ) SendMsgChannels( msg ); else if( msg.destination == Destination.NOTICE ) SendNotice( msg ); else if( msg.destination == Destination.RAW ) { IRCMessage rawMsg = new IRCMessage(); rawMsg = msg; SendRaw( ref rawMsg ); } IRCBot.RemoveOutgoingMessage( msg ); } outMessages.Clear(); } }