Пример #1
0
        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);
            }
        }