using System.Diagnostics; using System.IO; using System.Security.Cryptography; using System.Windows; using Zerolauncher.Defender; namespace Zerolauncher.Manager { internal class EngineManager { private static Dictionary mGame = new Dictionary(); //运行时才能决定是否执行内联 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] private static string AccToKey(Account account) { return string.Format("{0}{1}{2}", account.providerId, account.serverId, account.userName); } public static bool CreateGame(Account account) { if (UpDateData.is_check == false) { MessageBox.Show("正在更新游戏数据,请等待1-3秒。\n 请检查网络", "错误", MessageBoxButton.OK, MessageBoxImage.Warning); return true; } //if (UpDateManager.state) //{ // UpDateManager.DoUpdate(); // return true; //} var key = AccToKey(account); if (mGame.ContainsKey(key)) { return false; } if (CacheSha.errorCode != 0) { switch (CacheSha.errorCode) { case 1: MessageBox.Show("发生网络错误==EMS。\n 请检查网络", "错误", MessageBoxButton.OK, MessageBoxImage.Error); break; case 2: MessageBox.Show("发生游戏服务错误==EMS。\n 请联系管理员", "错误", MessageBoxButton.OK, MessageBoxImage.Error); break; default: MessageBox.Show("发生未知错误==EMS。\n 请联系管理员", "错误", MessageBoxButton.OK, MessageBoxImage.Error); break; } return true; } try { mGame[key] = new SingleGame(account); }catch (Exception _ex) { Trace.WriteLine("lalalala3"); UpDateManager.DoUpdate(); } return true; } public static bool CreateGame(int memberId) { return CreateGame(AccountManager.accountsList[memberId]); } public static int CheckGameState(Account account) { var key = AccToKey(account); if (mGame.ContainsKey(key)) { return mGame[key].mHandle; } return -1; } public static short TurnGameSizeMini(Account account) { var key = AccToKey(account); if (mGame.ContainsKey(key)) { var game = mGame[key]; if (game.mHandle != 0) { game.Send(StaticHandleS.MiniSize); return 2; } return 1; } return 0; } public static short TurnGameSizeNormal(Account account) { var key = AccToKey(account); if (mGame.ContainsKey(key)) { var game = mGame[key]; if (game.mHandle != 0) { game.Send(StaticHandleS.NormalSize); return 2; } return 1; } return 0; } public static bool ExitGame(Account account) { var key = AccToKey(account); if (!mGame.ContainsKey(key)) { return false; } mGame[key].Send(StaticHandleS.CloseGame); return true; } public static void OnGameExit(Account account) { mGame.Remove(AccToKey(account)); } public static bool CheckEmpy() { return mGame.Count == 0; } } class SingleGame { Process process; string? restartUrl; public int mHandle; public Account? account; string gameMode; public SingleGame(Account? acc, string mod = StaticHandleA.GameMode) { restartUrl = null; account = acc; gameMode = mod; mHandle = 0; process = EngineShell.CheckEngineSafe(gameMode); process.OutputDataReceived += Handle; process.ErrorDataReceived += Handle; process.Exited += Process_Exited; process.Start(); process.BeginOutputReadLine(); // 开始异步读取 } private void CreateProcess() { process = EngineShell.CheckEngineSafe(gameMode); process.OutputDataReceived += Handle; process.Exited += Process_Exited; process.Start(); process.BeginOutputReadLine(); // 开始异步读取 } private void Process_Exited(object? sender, EventArgs e) { Trace.WriteLine( $"Exit time : {process.ExitTime}\n" + $"Exit code : {process.ExitCode}\n" + $"Elapsed time : {Math.Round((process.ExitTime - process.StartTime).TotalMilliseconds)}"); Trace.WriteLine($"进程已退出:{account.nickName}"); if (gameMode != StaticHandleA.GameMode) return; if ( restartUrl == null) { EngineManager.OnGameExit(account); return; } CreateProcess(); } private void Handle(object sender, DataReceivedEventArgs e) { var lines = e.Data == null? [""] : e.Data.Split(" ", 2); // 切成两半 switch (lines[0]) { case StaticHandleC.LoadDone: if (gameMode == StaticHandleA.UpdateMode) { UpDateManager.DoUpdate1(); return; } Send($"{StaticHandleS.ShowWindow} {ServicesStaticInfo.ServicesName[account.providerId]}-{account.nickName}"); break; case StaticHandleC.StartDone: if (gameMode == StaticHandleA.UpdateMode) { UpDateManager.DoUpdate2(); return; } if (restartUrl == null) { Task.Run(async delegate { if (lines[1] == "True") await Task.Delay(5000); LoginManager.DoLogin(this); }); } else { Send($"{StaticHandleS.GameSa} {restartUrl}"); restartUrl = null; } break; case StaticHandleC.GameDone: mHandle = int.Parse(lines[1]); break; case StaticHandleC.BrowserDone: Trace.WriteLine($"尝试让游戏退出:{account.nickName}"); restartUrl = lines[1]; Send(StaticHandleS.CloseGame); break; case StaticHandleC.Version: mHandle = int.Parse(lines[1]); break; case StaticHandleC.DownloadDone: UpDateManager.OnDownLoadDone(lines[1]); break; case StaticHandleC.TakeVerify: var args = lines[1].Split(' '); _ = LoginManager.DoVerify(this, args[0], args[1]); break; default: Trace.WriteLine($"from client:{e.Data}"); break; } } public bool Send(string msg) { if(process.HasExited) { return false; } process.StandardInput.WriteLine(msg); return true; } } public class FileReadException : Exception { public FileReadException(string message) : base(message) { } } class EngineShell { static bool needShowTis = true; static bool is_check = false; const string engine_file = @"ZeroEngine.exe"; public static Process CheckEngineSafe(string mod) { bool is_first_luancher = EngineManager.CheckEmpy(); #region 检测代码 //if (mod == StaticHandleA.UpdateMode) //{ // if (DataStream.dataStream.ecs.Length > 10) // { // string? now_bit; // using (SHA256 sha256 = SHA256.Create()) // { // using (FileStream fileStream = File.OpenRead(engine_file)) // { // byte[] hashBytes = sha256.ComputeHash(fileStream); // now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty); // } // } // if (DataStream.dataStream.ecs != now_bit) // { // Trace.WriteLine("lalalala" + DataStream.dataStream.ecs); // throw new FileReadException("error esu1!"); // } // } //} //else if (!is_check && is_first_luancher) //{ // string? now_bit; // using (SHA256 sha256 = SHA256.Create()) // { // using (FileStream fileStream = File.OpenRead(engine_file)) // { // byte[] hashBytes = sha256.ComputeHash(fileStream); // now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty); // } // } // if (CacheSha.GetE() != now_bit) // { // Trace.WriteLine("lalalala1"); // throw new FileReadException("error esu0!"); // } // if (DataStream.dataStream.ecs != now_bit) { DataStream.dataStream.ecs = now_bit; DataStream.write(); } // is_check = true; //} #endregion var process = new Process { StartInfo = new ProcessStartInfo { FileName = engine_file, Arguments = $"{StaticHandleA.GameMode} {needShowTis}", UseShellExecute = false, CreateNoWindow = true, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true }, EnableRaisingEvents = true }; if (needShowTis) needShowTis = false; return process; } } }