ZeroLauncher/Manager/EngineManager.cs
2024-03-19 21:32:07 +08:00

297 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<string, SingleGame> mGame = new Dictionary<string, SingleGame>();
//运行时才能决定是否执行内联
[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)
{
Trace.WriteLine("lalalala2");
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.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.StartDone:
if (gameMode == StaticHandleA.UpdateMode)
{
UpDateManager.DoUpdate1();
return;
}
if(restartUrl == null)
{
Send($"{StaticHandleS.ShowWindow} {ServicesStaticInfo.ServicesName[account.providerId]}-{account.nickName}");
Task.Run(async delegate
{
if (lines[1] == "True") await Task.Delay(5000);
_ =LoginManager.DoLogin(this);
});
}
else
{
Send($"{StaticHandleS.ShowWindow} {ServicesStaticInfo.ServicesName[account.providerId]}-{account.nickName}");
Send($"{StaticHandleS.GameSa} {restartUrl}");
restartUrl = null;
}
break;
case StaticHandleC.GameDone:
mHandle = int.Parse(lines[1]);
break;
case StaticHandleC.BrowserDone:
restartUrl = lines[1];
Send(StaticHandleS.CloseGame);
break;
case StaticHandleC.Version:
mHandle = int.Parse(lines[1]);
break;
case StaticHandleC.DownloadDone:
UpDateManager.OnDownLoadDone(lines[1]);
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();
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;
}
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = engine_file,
Arguments = $"{StaticHandleA.GameMode} {needShowTis}",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true
},
EnableRaisingEvents = true
};
if (needShowTis) needShowTis = false;
return process;
}
}
}