Exemplo n.º 1
0
        public static void Main(string[] args)
        {
            exitHandler += new EventHandler(ExitHandler);
            SetConsoleCtrlHandler(exitHandler, true);

            long millis = (long)DateTime.Now.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;

            Dictionary <string, string> configParams = parseConfig("chessbridge.cfg");

            if (configParams.ContainsKey(LOGGING_KEY))
            {
                string str = configParams[LOGGING_KEY];
                if (str == null || !str.ToLower().Trim().Equals("true"))
                {
                    logToFile = false;
                }
                else
                {
                    logToFile = true;
                    str       = configParams[LOG_BASE_FILENAME_KEY];
                    if (str != null)
                    {
                        logBaseFilename = str;
                    }
                    chessLogWriter = new StreamWriter(logBaseFilename + "-" + millis + ".log");
                }
            }
            else
            {
                //assume logging to true if missing
                logToFile      = true;
                chessLogWriter = new StreamWriter(logBaseFilename + "-" + millis + ".log");
            }

            if (configParams.ContainsKey(CONSOLE_LOGGING_KEY))
            {
                string str = configParams[CONSOLE_LOGGING_KEY];
                if (str == null || !str.ToLower().Trim().Equals("true"))
                {
                    logToConsole = false;
                }
                else
                {
                    logToConsole = true;
                }
            }
            else
            {
                //NOTE: Logging to the console can interefere with engine communication, so only enable when there is a problem that for some reason isn't
                //making it to the log file
                logToConsole = false;
            }

            if (configParams.ContainsKey(GUI_KEY))
            {
                string tg = configParams[GUI_KEY];
                if (tg != null && tg.Trim().Length > 0)
                {
                    guiName = tg;
                }
            }

            guiName = guiName.ToLower().Trim();

            if (guiName.Equals(ChessMaster.Instance.getId()))
            {
                gui = ChessMaster.Instance;
            }

            if (configParams.ContainsKey(ENGINE_KEY))
            {
                engine = configParams[ENGINE_KEY];
            }

            if (engine == null || engine.Trim().Length == 0)
            {
                engine = DEFAULT_ENGINE;
            }

            string mode;

            if (configParams.ContainsKey(MODE_KEY))
            {
                mode = configParams[MODE_KEY];
                if (mode != null)
                {
                    mode = mode.ToLower();
                }
            }
            else
            {
                mode = "";
            }

            if (mode.Equals(PERSONALITY_DUMP))
            {
                string inputDir = configParams[PERSONALITY_INPUT_DIR_KEY];

                string outputDir = configParams[PERSONALITY_OUTPUT_DIR_KEY];
                if (outputDir != null && outputDir.Length != 0)
                {
                    Directory.CreateDirectory(outputDir);
                }

                gui.dumpPersonalities(engine, inputDir, outputDir);

                //we're done
                return;
            }

            if (mode == null || !mode.Equals(PERSONALITY_DUMP))
            {
                engine = configParams[ENGINE_KEY];
                if (engine == null || engine.Length == 0)
                {
                    Console.WriteLine("ERROR: Chess engine is null! Cannot proceed!");
                    return;
                }
            }

            //load OPK key if provided
            string opk = null;

            if (configParams.ContainsKey(OPK_KEY))
            {
                opk = configParams[OPK_KEY];
            }
            else
            {
                log("WARNING: No OPK key specified. If you're trying to use the chessmaster engine with a 3rd party application it will NOT" +
                    " operate at full strength.");
            }

            //load personality if provided
            string gamePersonality = null;

            /*if (configParams.ContainsKey(SHOW_PERSONALITY_DIALOG_KEY))
             * {
             * string showDialog = configParams[SHOW_PERSONALITY_DIALOG_KEY];
             *
             * if (!showDialog.ToLower().Trim().Equals("false"))
             * {
             * Personality p = showPersonalityGui();
             * gamePersonality = p.toIniString();
             * }
             * }
             * else*/if (configParams.ContainsKey(PERSONALITY_KEY) && gamePersonality == null)
            {
                //attempt to read in personality file
                string value = configParams[PERSONALITY_KEY];
                try
                {
                    string personalityName = Path.GetFileNameWithoutExtension(value);

                    if (!Path.GetExtension(value).ToLower().Equals(".ini"))
                    {
                        //parse binary file
                        gamePersonality = gui.parsePersonality(value);

                        //store for the future as an ini
                        StreamWriter personalityFile = new StreamWriter(personalityName + ".ini");
                        personalityFile.WriteLine(gamePersonality);
                        personalityFile.Flush();
                        personalityFile.Close();
                    }
                    else
                    {
                        gamePersonality = File.ReadAllText(value);
                    }
                }
                catch (Exception ex)
                {
                    log("An exception occurred trying to read Chessmaster personality file " + value + ". Will use defaults.");
                    log(ex.ToString());
                }
            }

            log("***PROGRAM ARGUMENTS***");
            foreach (string arg in args)
            {
                log(arg);
            }

            //Start the engine
            engineProcess = new Process();
            engineProcess.StartInfo.FileName = engine;
            //p.StartInfo.Arguments = "/c "+engineName;
            engineProcess.StartInfo.UseShellExecute        = false;
            engineProcess.StartInfo.CreateNoWindow         = true;
            engineProcess.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
            engineProcess.StartInfo.RedirectStandardInput  = true;
            engineProcess.StartInfo.RedirectStandardOutput = true;
            engineProcess.StartInfo.RedirectStandardError  = true;
            engineProcess.OutputDataReceived += new DataReceivedEventHandler(ChessEngineDataHandler);
            engineProcess.ErrorDataReceived  += new DataReceivedEventHandler(ChessEngineErrorDataHandler);

            try
            {
                engineProcess.Start();
                engineProcess.BeginOutputReadLine();
                engineProcess.BeginErrorReadLine();
            }
            catch (Exception ex)
            {
                log("Exception occurred trying to start engine " + engine + "!");
                log(ex.ToString());

                Console.WriteLine("Exception occurred trying to start engine " + engine + "!");
                Console.WriteLine(ex.ToString());
                Environment.Exit(-1);
            }

            //Now the bridge. Read in and record commands from GUI and pass them on to the engine.
            string line;

            log("***ENGINE COMS***");

            //if a personality was specified, use it first

            /*if (gamePersonality != null)
             * {
             *      log("IN: "+gamePersonality);
             *      //pass to engine
             *      engineProcess.StandardInput.WriteLine(gamePersonality);
             *      engineProcess.StandardInput.Flush();
             * }*/

            string[] nl     = new string[] { "\\n" };
            bool     loaded = false;

            while ((line = Console.ReadLine()) != null && line != "")
            {
                //if this parameter is found, we're running from the chessmaster gui and require
                //special handling of analysis output so the chessmaster mentor works
                line = gui.translateToEngine(line);

                //make sure there are no unparsed newlines
                string[] tokens = line.Split(nl, StringSplitOptions.None);

                //record
                foreach (string tok in tokens)
                {
                    if (tok.Trim().Length > 0)
                    {
                        if (tok.Equals("new") && !loaded)
                        {
                            log("IN: " + tok);

                            //pass to engine
                            engineProcess.StandardInput.WriteLine(tok);
                            engineProcess.StandardInput.Flush();

                            if (configParams.ContainsKey(SHOW_PERSONALITY_DIALOG_KEY))
                            {
                                string showDialog = configParams[SHOW_PERSONALITY_DIALOG_KEY];

                                if (!showDialog.ToLower().Trim().Equals("false"))
                                {
                                    Personality p = showPersonalityGui();
                                    gamePersonality = p.toIniString();
                                }
                            }

                            if (gamePersonality != null)
                            {
                                log("IN: " + gamePersonality);
                                engineProcess.StandardInput.WriteLine(gamePersonality);
                                engineProcess.StandardInput.Flush();
                            }

                            loaded = true;
                        }
                        else if (tok.Equals("xboard") && gamePersonality != null)
                        {
                            log("IN: " + tok);
                            //pass to engine
                            engineProcess.StandardInput.WriteLine(tok);
                            engineProcess.StandardInput.Flush();

                            log("IN: " + "cm_parm opk=" + opk);
                            engineProcess.StandardInput.WriteLine("cm_parm opk=" + opk);
                            engineProcess.StandardInput.Flush();
                        }
                        else if (tok.Equals("quit") || tok.Equals("exit"))
                        {
                            loaded = false;
                            log("IN: " + tok);
                            //pass to engine
                            engineProcess.StandardInput.WriteLine(tok);
                            engineProcess.StandardInput.Flush();
                        }
                        else
                        {
                            log("IN: " + tok);
                            //pass to engine
                            engineProcess.StandardInput.WriteLine(tok);
                            engineProcess.StandardInput.Flush();
                        }
                    }
                }
            }

            engineProcess.WaitForExit();
            return;
        }