public static void Main(string[] args) { // Error handling AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); // Fix working directory string path = Assembly.GetExecutingAssembly().Location; if (path.LastIndexOf(Path.DirectorySeparatorChar) > 0) { path = path.Substring(0, path.LastIndexOf(Path.DirectorySeparatorChar)); Environment.CurrentDirectory = path; } Console.WriteLine("Path set to: " + Environment.CurrentDirectory); // Read configuration file string configurationFile = "config.xml"; if (args.Length > 0) { configurationFile = string.Join(" ", args); } Console.WriteLine("Loading configuration file: " + configurationFile); ConfigurationBase configuration = ConfigurationReader.Read(configurationFile); if (configuration == null || configuration.Core == null || configuration.Bots.Length < 1) { Environment.Exit(1); return; } ConfigurationBot configurationBot = configuration.Bots[0]; // Start bot try { Console.Title = "VhaBot " + BotShell.VERSION + " " + BotShell.EDITION + " Edition [" + configurationBot.GetID() + "]"; } catch { } Console.WriteLine("Starting " + configurationBot.GetID()); BotShell bot = new BotShell(configurationBot, configuration.Core, null); // Main loop, just keep it alive int collectTimeout = 1; while (true) { collectTimeout--; if (collectTimeout < 1) { bot.Clean(); collectTimeout = 600; } System.Threading.Thread.Sleep(100); } }
public override void OnCommand(BotShell bot, CommandArgs e) { // make !status display various stats of the bot and the current state of all slaves and their friendslists, also include links to relog etc switch (e.Command) { case "shutdown": bot.SendOrganizationMessage(bot.ColorHighlight + "System »» Shutting Down"); bot.SendPrivateMessage(e.SenderID, bot.ColorHighlight + "System »» Shutting Down", AoLib.Net.PacketQueue.Priority.Urgent, true); bot.SendPrivateChannelMessage(bot.ColorHighlight + "System »» Shutting Down"); System.Threading.Thread.Sleep(1000); bot.Shutdown(); break; case "restart": if (!bot.CoreConnected) { bot.SendReply(e, "Restart is not available"); return; } bot.SendOrganizationMessage(bot.ColorHighlight + "System »» Rebooting"); bot.SendPrivateMessage(e.SenderID, bot.ColorHighlight + "System »» Rebooting", AoLib.Net.PacketQueue.Priority.Urgent, true); bot.SendPrivateChannelMessage(bot.ColorHighlight + "System »» Rebooting"); System.Threading.Thread.Sleep(1000); bot.Restart(); break; case "core": this.OnCoreCommand(bot, e); break; case "core shutdown": case "core start": case "core restart": if (e.Args.Length < 1 || !e.Args[0].Contains("@")) { bot.SendReply(e, "Usage: " + e.Command + " [bot@dimension]"); return; } if (!bot.Master) { bot.SendReply(e, "This bot is not a master bot"); return; } CoreCommand command; if (e.Command == "core shutdown") { command = CoreCommand.Shutdown; } else if (e.Command == "core start") { command = CoreCommand.Start; } else { command = CoreCommand.Restart; } MessageResult result = bot.SendCoreMessage(this.InternalName, e.Args[0].ToLower(), command); switch (result) { case MessageResult.Success: bot.SendReply(e, "Your command has been relayed to the core and will be executed shortly"); break; case MessageResult.InvalidTarget: bot.SendReply(e, "The target you specified appeared to be invalid"); break; case MessageResult.NotConnected: bot.SendReply(e, "Unable to connect to the core in order to issue this command"); break; default: bot.SendReply(e, "An unknown error prevented your command from being executed"); break; } break; case "core clean": bot.Clean(); bot.SendReply(e, "Memory cleaning routines have been executed"); break; } }
static void Main(string[] args) { // Error handling AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); // Parse arguments Dictionary <string, string> arguments = new Dictionary <string, string>(); foreach (string arg in args) { if (!arg.Contains("=") || arg.IndexOf("=") + 1 == arg.Length) { Console.WriteLine("Invalid argument: " + arg); continue; } string argKey = arg.Substring(0, arg.IndexOf("=")); string argValue = arg.Substring(arg.IndexOf("=") + 1); arguments.Add(argKey, argValue); } // Verify arguments string channelName = ""; if (arguments.ContainsKey("channel")) { channelName = arguments["channel"]; } if (string.IsNullOrEmpty(channelName)) { Console.WriteLine("No valid remoting channel specified"); Environment.Exit(ExitCodes.INVALID_ARGUMENT); return; } string id = null; if (arguments.ContainsKey("id")) { id = arguments["id"]; } if (id == null || id == string.Empty) { Console.WriteLine("No valid id specified"); Environment.Exit(ExitCodes.INVALID_ARGUMENT); return; } string key = null; if (arguments.ContainsKey("key")) { key = arguments["key"]; } if (key == null || key == string.Empty) { Console.WriteLine("No valid key specified"); Environment.Exit(ExitCodes.INVALID_ARGUMENT); return; } int pid = -1; if (arguments.ContainsKey("pid")) { try { pid = Convert.ToInt32(arguments["pid"]); } catch { } } if (pid < 1) { Console.WriteLine("No valid core process id specified"); Environment.Exit(ExitCodes.INVALID_ARGUMENT); return; } // Be sure we know when the core goes down Process coreProcess = Process.GetProcessById(pid); if (coreProcess == null) { Console.WriteLine("Unable to access VhaBot.Core process"); Environment.Exit(ExitCodes.COMMUNICATION_LOST); return; } coreProcess.Exited += new EventHandler(OnCoreShutdown); // Fix working directory string path = Assembly.GetExecutingAssembly().Location; if (path.LastIndexOf(Path.DirectorySeparatorChar) > 0) { path = path.Substring(0, path.LastIndexOf(Path.DirectorySeparatorChar)); Environment.CurrentDirectory = path; } // Connect to core Console.WriteLine("Connecting to VhaBot.Core on channel " + channelName); ClientCommunication communication; try { ServerCommunication server = (ServerCommunication)Activator.GetObject(typeof(ServerCommunication), "ipc://" + channelName + "/ServerCommunication"); communication = server.AuthorizeClient(id, key); if (communication == null) { Console.WriteLine("Unable to authorize client on VhaBot.Core"); Environment.Exit(ExitCodes.REMOTING_FAILED); return; } } catch { Console.WriteLine("An error occurred while connecting to VhaBot.Core"); Environment.Exit(ExitCodes.REMOTING_FAILED); return; } Console.WriteLine("Connected to VhaBot.Core (" + communication.CoreID + ")"); ConfigurationBot configurationBot = communication.GetConfigurationBot(); ConfigurationCore configurationCore = communication.GetConfigurationCore(); if (configurationBot == null || configurationCore == null) { Console.WriteLine("An error occurred while fetching configuration from VhaBot.Core"); Environment.Exit(ExitCodes.NO_CONFIGURATION); return; } Console.WriteLine("Received bot configuration for " + configurationBot.ToString()); // Verify core PID if (pid != communication.CoreID) { Console.WriteLine("Core process id appeared to be invalid. " + pid + " was specified but the actual id is " + communication.CoreID); Environment.Exit(ExitCodes.INVALID_ARGUMENT); return; } // Initiate the bot Console.WriteLine("Starting BotShell"); BotShell bot = new BotShell(configurationBot, configurationCore, new SendMessageHandler(communication.SendMessage)); // Main loop, check for messages and relay int collectTimeout = 1; while (true) { coreProcess.Refresh(); if (coreProcess.HasExited) { Console.WriteLine("Core shutdown"); Environment.Exit(ExitCodes.SHUTDOWN); } try { communication.Ping(); } catch (Exception ex) { Console.WriteLine("Failed to ping core: " + ex.Message); Environment.Exit(ExitCodes.COMMUNICATION_LOST); return; } while (communication.QueueSize > 0) { MessageBase message = communication.Dequeue(); bot.RelayMessage(message); } // Cleanup duties every 60 seconds collectTimeout--; if (collectTimeout < 1) { bot.Clean(); collectTimeout = 600; } System.Threading.Thread.Sleep(100); } }