From d09249272c72a4d00dceedf6ff553258a56dff0c Mon Sep 17 00:00:00 2001 From: 1415ddfer <1783488228@qq.com> Date: Sat, 9 Mar 2024 18:29:16 +0800 Subject: [PATCH] sycn --- AboutDialog/About1.xaml | 2 +- App.xaml | 1 - App.xaml.cs | 23 ++++- Defender/EngineCacheSha.cs | 40 ++++++-- MainWindow.xaml.cs | 1 - Manager/CloundMananger.cs | 82 +++++++++++++++ Manager/DataStream.cs | 3 +- Manager/EngineManager.cs | 96 +++++++++++------- Manager/LoginManager.cs | 13 ++- Manager/UpDateManager.cs | 99 ++++++++---------- ServicesStaticInfo.cs | 1 - StaticHandleProtol.cs | 2 + Zerolauncher.csproj | 1 + dialog/DialogHelper.cs | 8 +- dialog/DownloadControl.xaml | 6 +- dialog/DownloadControl.xaml.cs | 111 +++++++------------- util/Download.cs | 9 ++ util/MyEncrypt.cs | 162 ++++++++++++++++++++++++++++++ {Manager => util}/SpaceEncoder.cs | 2 +- 19 files changed, 472 insertions(+), 190 deletions(-) create mode 100644 Manager/CloundMananger.cs create mode 100644 util/Download.cs create mode 100644 util/MyEncrypt.cs rename {Manager => util}/SpaceEncoder.cs (98%) diff --git a/AboutDialog/About1.xaml b/AboutDialog/About1.xaml index 5c53078..32095f4 100644 --- a/AboutDialog/About1.xaml +++ b/AboutDialog/About1.xaml @@ -10,7 +10,7 @@ - + diff --git a/App.xaml b/App.xaml index 3605fff..b4990f2 100644 --- a/App.xaml +++ b/App.xaml @@ -1,7 +1,6 @@  diff --git a/App.xaml.cs b/App.xaml.cs index f15a2e9..f56410c 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -11,10 +11,25 @@ namespace Zerolauncher protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); - _ = UpDateManager.TakeQMessage(); - DataStream.Load(); - _ = WebApiManager.StartListener(); - AccountManager.initLoadData(); + + var a = CloundMananger.TakeQMessage(); + a.Wait(); + UpDateManager.DoCheckUpdate(); + if (DownloadTask.state) + { + + }else + { + DataStream.Load(); + _ = WebApiManager.StartListener(); + AccountManager.initLoadData(); + } + } + + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + WebApiManager.StopListener(); } } diff --git a/Defender/EngineCacheSha.cs b/Defender/EngineCacheSha.cs index 4c3aa44..9d018dd 100644 --- a/Defender/EngineCacheSha.cs +++ b/Defender/EngineCacheSha.cs @@ -3,33 +3,57 @@ using System.Text; namespace Zerolauncher.Defender { - class EngineCacheSha + class CacheSha { const string key = "mysecretkey"; - static string? sha; + static string? sha_engine; + static string? sha_main; public static int errorCode = 0; - public static void Put(string eSha) + public static void PutE(string eSha) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < eSha.Length; i++) { sb.Append((char)(eSha[i] ^ key[i % key.Length])); } - sha = sb.ToString(); + sha_engine = sb.ToString(); } - public static string? Get() + public static string? GetE() { - if (sha == null) { return null; } + if (sha_engine == null) { return null; } var sb = new StringBuilder(); - for (int i = 0; i < sha.Length; i++) + for (int i = 0; i < sha_engine.Length; i++) { - sb.Append((char)(sha[i] ^ key[i % key.Length])); + sb.Append((char)(sha_engine[i] ^ key[i % key.Length])); + } + return sb.ToString(); + + } + + public static void PutM(string eSha) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < eSha.Length; i++) + { + sb.Append((char)(eSha[i] ^ key[i % key.Length])); + } + sha_main = sb.ToString(); + } + + public static string? GetM() + { + if (sha_main == null) { return null; } + var sb = new StringBuilder(); + for (int i = 0; i < sha_main.Length; i++) + { + sb.Append((char)(sha_main[i] ^ key[i % key.Length])); } return sb.ToString(); } } + } diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 19d7137..4a6db47 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -145,7 +145,6 @@ namespace Zerolauncher private void Button_Click_3(object sender, RoutedEventArgs e) { - WebApiManager.StopListener(); Close(); } diff --git a/Manager/CloundMananger.cs b/Manager/CloundMananger.cs new file mode 100644 index 0000000..a226679 --- /dev/null +++ b/Manager/CloundMananger.cs @@ -0,0 +1,82 @@ +using System.Net.Http; +using System.Net; +using Zerolauncher.Defender; +using Zerolauncher.util; + +namespace Zerolauncher.Manager +{ + class StaticUrl + { + public const string QMessageMain = "https://sharechain.qq.com/"; + public const string MasterMessage = "54aeb77c47b967d22c2c1396d00d91f0"; + public const string SummerMessage = "037846c482eddc948612b0d0f8ed98d5"; + public const string LoveMessage = ""; + } + + class UpDateData + { + public static bool state = false; + public static string version = ""; + public static string tis = ""; + public static string mini_packet_url = ""; + public static string full_packet_url = ""; + } + + class CloundMananger + { + public static async Task TakeQMessage() + { + var client = new HttpClient(); + client.DefaultRequestVersion = HttpVersion.Version20; + client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; + client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (iPad; U; CPU OS 6_0 like Mac OS X; zh-CN; iPad2)"); + HttpResponseMessage response; + try + { + client.Timeout = TimeSpan.FromMinutes(3); + response = await client.GetAsync($"{StaticUrl.QMessageMain}{StaticUrl.MasterMessage}"); + } + catch (Exception _ex) + { + CacheSha.errorCode = 1; + return; + } + var responseString = await response.Content.ReadAsStringAsync(); + if(!FormatMessage(responseString)) + { + CacheSha.errorCode = 2; + } + } + + static bool FormatMessage(string message) + { + message = message.Split("
")[1].Split("")[0].Replace("
", "").Replace("\n", "").Replace("\t", "").Replace("\r", "").Replace("'", ""); + var arr = message.Split("
"); + if (arr.Length >= 7 && FormatSha(arr[6], false) && FormatSha(arr[5], true)) + { + UpDateData.version = arr[1]; + UpDateData.tis = arr[2]; + UpDateData.mini_packet_url = arr[3]; + UpDateData.full_packet_url = arr[4]; + UpDateData.state = true; + return true; + } + return false; + } + + static bool FormatSha(string sha0, bool e) + { + if (sha0.Length < 90) return false; + int count; + var sha = SpaceEncoder.Decode(sha0[..86], out count); + if (sha == null) + { + //Console.WriteLine($"faile: {count}"); + return false; + } + if (e) CacheSha.PutE(sha); + else CacheSha.PutM(sha); + return true; + } + } +} diff --git a/Manager/DataStream.cs b/Manager/DataStream.cs index 3a8d2f0..7b76871 100644 --- a/Manager/DataStream.cs +++ b/Manager/DataStream.cs @@ -20,7 +20,7 @@ namespace Zerolauncher.Manager else { dataStream = JsonConvert.DeserializeObject( - "{\"teamIndex\":0,\"Groups\":[{\"Name\":\"队伍1\", \"Accounts\": [{\"providerId\":0,\"userName\":\"test\",\"userPWD\":\"test\",\"nickName\":\"测试账号\",\"serverId\":\"1\"}]}]}"); + "{\"teamIndex\":0,\"Groups\":[{\"Name\":\"队伍1\", \"Accounts\": [{\"providerId\":0,\"userName\":\"test\",\"userPWD\":\"test\",\"nickName\":\"测试账号\",\"serverId\":\"1\"}]}], \"engine_cache_ver\": 0}"); } } @@ -85,5 +85,6 @@ namespace Zerolauncher.Manager { public int teamIndex; public List Groups; + public int engine_cache_ver; } } \ No newline at end of file diff --git a/Manager/EngineManager.cs b/Manager/EngineManager.cs index 7c6de48..166cdbd 100644 --- a/Manager/EngineManager.cs +++ b/Manager/EngineManager.cs @@ -19,10 +19,11 @@ namespace Zerolauncher.Manager public static bool CreateGame(Account account) { + var key = AccToKey(account); if (mGame.ContainsKey(key)) { return false; } - if (EngineCacheSha.errorCode != 0) { - switch (EngineCacheSha.errorCode) + if (CacheSha.errorCode != 0) { + switch (CacheSha.errorCode) { case 1: MessageBox.Show("发生网络错误==EMS。\n 请检查网络", "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error); @@ -118,23 +119,36 @@ namespace Zerolauncher.Manager public int mHandle; - public Account account; + public Account? account; + string gameMode; - public SingleGame(Account acc) + public SingleGame(Account? acc, string mod = StaticHandleA.GameMode) { restartUrl = null; - this.account = acc; + account = acc; + gameMode = mod; mHandle = 0; - process = EngineShell.CheckEngineSafe(); - process.OutputDataReceived += Handle; - process.Exited += Process_Exited; + process = EngineShell.CheckEngineSafe(gameMode); + if (gameMode != StaticHandleA.UpdateMode) + { + process.OutputDataReceived += Handle; + process.Exited += Process_Exited; + } process.Start(); - process.BeginOutputReadLine(); // 开始异步读取 + if (gameMode != StaticHandleA.UpdateMode) + { + process.BeginOutputReadLine(); // 开始异步读取 + if (gameMode == StaticHandleA.Version) + { + process.WaitForExit(); + } + } + } private void CreateProcess() { - process = EngineShell.CheckEngineSafe(); + process = EngineShell.CheckEngineSafe(gameMode); process.OutputDataReceived += Handle; process.Exited += Process_Exited; process.Start(); @@ -143,12 +157,13 @@ namespace Zerolauncher.Manager 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 ( restartUrl == null ) + //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; @@ -165,7 +180,11 @@ namespace Zerolauncher.Manager if(restartUrl == null) { Send($"{StaticHandleS.ShowWindow} {ServicesStaticInfo.ServicesName[account.providerId]}-{account.nickName}"); - _ = LoginManager.DoLogin(this); + Task.Run(async delegate + { + if (lines[1] == "True") await Task.Delay(5000); + _ =LoginManager.DoLogin(this); + }); } else { @@ -181,6 +200,9 @@ namespace Zerolauncher.Manager restartUrl = lines[1]; Send(StaticHandleS.CloseGame); break; + case StaticHandleC.Version: + mHandle = int.Parse(lines[1]); + break; } } @@ -204,31 +226,33 @@ namespace Zerolauncher.Manager { static bool is_check = false; const string engine_file = @"ZeroEngine.exe"; - public static Process CheckEngineSafe() + public static Process CheckEngineSafe(string mod) { - if (!is_check && EngineManager.CheckEmpy()) - { - 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 (EngineCacheSha.Get() != now_bit) - { - throw new FileReadException("无法读取文件内容"); - } - } - is_check = true; + bool is_first_luancher = EngineManager.CheckEmpy(); + //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 (EngineCacheSha.Get() != now_bit) + // { + // throw new FileReadException("无法读取文件内容"); + // } + // is_check = true; + //} + var process = new Process { StartInfo = new ProcessStartInfo { FileName = engine_file, - Arguments = StaticHandleA.GameMode, + Arguments = $"{mod} {is_first_luancher}", UseShellExecute = false, CreateNoWindow = true, RedirectStandardInput = true, diff --git a/Manager/LoginManager.cs b/Manager/LoginManager.cs index d38be5e..9c19aa2 100644 --- a/Manager/LoginManager.cs +++ b/Manager/LoginManager.cs @@ -57,7 +57,7 @@ namespace Zerolauncher.Manager { var client = new HttpClient(); string? need_web = null; - client.Timeout = TimeSpan.FromSeconds(10); + client.Timeout = TimeSpan.FromSeconds(3); switch (game.account.providerId) { case 0: @@ -122,7 +122,16 @@ namespace Zerolauncher.Manager break; } responseString = responseString.Split("name=\"game_box\"")[1].Split("src=\"")[1].Split("\"")[0]; - response = await client.PostAsync(responseString, null); + try + { + response = await client.PostAsync(responseString, null); + } + catch (Exception ex) + { + game.Send($"{StaticHandleS.HintText} 网络发生错误,类型:{ex.GetType().Name.Replace(" ", "_")},消息:{ex.Message.Replace(" ", "_")}"); + need_web = $"http://web.4399.com/stat/togame.php?target=ddt&server_id=S{game.account.serverId}"; + break; + } responseString = await response.Content.ReadAsStringAsync(); responseString = "http://" + response.RequestMessage.RequestUri.ToString().Split("/")[2] + "/" + responseString.Split("movie\" value='")[1].Split("'")[0]; Trace.WriteLine(responseString); diff --git a/Manager/UpDateManager.cs b/Manager/UpDateManager.cs index 34f2018..6c75e34 100644 --- a/Manager/UpDateManager.cs +++ b/Manager/UpDateManager.cs @@ -1,73 +1,62 @@ -using System.IO; +using System.Diagnostics; +using System.IO; using System.Net; -using System.Net.Http; +using System.Security.Cryptography; using Zerolauncher.Defender; namespace Zerolauncher.Manager { - + + class DownloadTask + { + public static bool state = false; + public static string url = ""; + } + class UpDateManager { + public static bool isCheeking = false; - public static async Task TakeQMessage() + public static void DoCheckUpdate(bool checkMain=true, bool needEngine = false) { - var client = new HttpClient(); - client.DefaultRequestVersion = HttpVersion.Version20; - client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; - client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (iPad; U; CPU OS 6_0 like Mac OS X; zh-CN; iPad2)"); - HttpResponseMessage response; - try + if (isCheeking) return; + isCheeking=true; + bool needMian= false; + if(checkMain) { - client.Timeout = TimeSpan.FromMinutes(3); - response = await client.GetAsync("https://sharechain.qq.com/037846c482eddc948612b0d0f8ed98d5"); // 初夏 - }catch (Exception _ex) - { - EngineCacheSha.errorCode = 1; - return; - } - var responseString = await response.Content.ReadAsStringAsync(); - responseString = responseString.Split("
")[1].Split("")[0].Replace("
", "").Replace("\n", "").Replace("\t", "").Replace("\r", "").Replace("'", ""); - var arr = responseString.Split("
").Last(); - - if (arr.Length < 90) - { - EngineCacheSha.errorCode = 2; - return; - } - int count; - var sha = SpaceEncoder.Decode(arr[..86], out count); - if (sha == null) - { - //Console.WriteLine($"faile: {count}"); - EngineCacheSha.errorCode = 2; - return; - } - EngineCacheSha.Put(sha); - } - - public async Task GetTask() - { - var client = new HttpClient(); - client.DefaultRequestVersion = HttpVersion.Version20; - client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; - client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (iPad; U; CPU OS 6_0 like Mac OS X; zh-CN; iPad2)"); - var response = await client.GetAsync("https://sharechain.qq.com/13111bbd6ffbffa3057878431bef103e"); - var responseString = await response.Content.ReadAsStringAsync(); - if (responseString.Contains("
")) - { - responseString = responseString.Split("
")[1].Split("")[0].Replace("
", "").Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", "").Replace("'", ""); - Console.WriteLine(responseString.Replace("
", "\n")); - var arr = responseString.Split("
"); - int main_version, engine_version, sa_version; - if (int.TryParse(arr[0], out main_version) && int.TryParse(arr[1], out engine_version)) + string filePath = Process.GetCurrentProcess().MainModule.FileName; + string? now_bit; + using (SHA256 sha256 = SHA256.Create()) { - + using (FileStream fileStream = File.OpenRead(filePath)) + { + byte[] hashBytes = sha256.ComputeHash(fileStream); + now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty); + } } + needMian = now_bit == CacheSha.GetM() && now_bit != null; } - // todo open faile update dialog + if(!needEngine) + { + string? now_bit; + using (SHA256 sha256 = SHA256.Create()) + { + using (FileStream fileStream = File.OpenRead(@"ZeroEngine.exe")) + { + byte[] hashBytes = sha256.ComputeHash(fileStream); + now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty); + } + } + needEngine = now_bit == CacheSha.GetE() && now_bit != null; + } + if(needEngine && needMian) { isCheeking = false; return; } + DownloadTask.state = true; + if(needEngine == needMian) DownloadTask.url = UpDateData.full_packet_url; + else DownloadTask.url = UpDateData.mini_packet_url; + isCheeking = false; } - public static void DownLoad(string Url, string FileName) + public static void DownLoad(string Url, string FileName, bool has) { bool Value = false; WebResponse response = null; diff --git a/ServicesStaticInfo.cs b/ServicesStaticInfo.cs index e02a536..f5403dd 100644 --- a/ServicesStaticInfo.cs +++ b/ServicesStaticInfo.cs @@ -4,6 +4,5 @@ { public static string[] ServicesName = ["4399大区", "7k7k大区", "第七大道"]; public static string[] ServicesShortName = ["43", "7k", "7d"]; - } } diff --git a/StaticHandleProtol.cs b/StaticHandleProtol.cs index bd7f213..16df3a0 100644 --- a/StaticHandleProtol.cs +++ b/StaticHandleProtol.cs @@ -17,11 +17,13 @@ public const string BrowserDone = "0b"; public const string StartGame = "0c"; public const string GameDone = "0d"; + public const string Version = "0e"; } class StaticHandleA { public const string GameMode = "0a"; public const string UpdateMode = "0b"; + public const string Version = "0c"; } } diff --git a/Zerolauncher.csproj b/Zerolauncher.csproj index 4323124..b6a26b6 100644 --- a/Zerolauncher.csproj +++ b/Zerolauncher.csproj @@ -37,6 +37,7 @@ + diff --git a/dialog/DialogHelper.cs b/dialog/DialogHelper.cs index 1e01054..fa6ac2f 100644 --- a/dialog/DialogHelper.cs +++ b/dialog/DialogHelper.cs @@ -97,12 +97,14 @@ namespace Zerolauncher.dialog baseDialog.Close(); } } + } class UpdateDialog { static BaseDialog? baseDialog; - static DownloadControl? editControl; + public static DownloadControl1? editControl; + public static bool ui_enale = false; public static void CreateDailog(Window p) { @@ -110,9 +112,11 @@ namespace Zerolauncher.dialog { return; } - editControl = new DownloadControl(); + editControl = new DownloadControl1(); baseDialog = new BaseDialog(editControl); + ui_enale = true; baseDialog.ShowDialog(); + ui_enale = false; baseDialog = null; editControl = null; } diff --git a/dialog/DownloadControl.xaml b/dialog/DownloadControl.xaml index 22a801a..b496850 100644 --- a/dialog/DownloadControl.xaml +++ b/dialog/DownloadControl.xaml @@ -1,4 +1,4 @@ - - + - diff --git a/dialog/DownloadControl.xaml.cs b/dialog/DownloadControl.xaml.cs index 86c2a7d..a66da98 100644 --- a/dialog/DownloadControl.xaml.cs +++ b/dialog/DownloadControl.xaml.cs @@ -1,5 +1,5 @@ -using System.IO; -using System.Net.Http; +using Downloader; +using System.ComponentModel; using System.Windows.Controls; namespace Zerolauncher.dialog @@ -7,97 +7,60 @@ namespace Zerolauncher.dialog /// /// DownloadControl.xaml 的交互逻辑 /// - public partial class DownloadControl : UserControl + public partial class DownloadControl1 : UserControl { const string cache_dir = "./.cache/auto.cache"; + static bool is_strat = false; - public DownloadControl() + public DownloadControl1() { InitializeComponent(); + if (!is_strat) text2.Text = "正在连接服务器"; } - private void OnError(Exception ex) - { - // UnityEngine.Debug.Log("捕获异常 >>> " + ex); - } + - public async Task Download(string fileUrl) + public static void DoDownload(string fileUrl) { - using (HttpClient client = new HttpClient()) + var downloadOpt = new DownloadConfiguration() { - // 获取文件大小 - HttpResponseMessage responseHead = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, fileUrl)); - long? contentLength = responseHead.Content.Headers.ContentLength; - Console.WriteLine($"文件大小:{contentLength} 字节"); + ChunkCount = 8, // file parts to download, the default value is 1 + ParallelDownload = true // download parts of the file as parallel or not. The default value is false + }; + var downloader = new DownloadService(downloadOpt); + // Provide `FileName` and `TotalBytesToReceive` at the start of each download + downloader.DownloadStarted += OnDownloadStarted; - // 计算块大小 - int blockSize = 1024 * 1024; // 1MB - int blockCount = (int)Math.Ceiling((double)contentLength / blockSize); + // Provide any information about download progress, + // like progress percentage of sum of chunks, total speed, + // average speed, total received bytes and received bytes array + // to live streaming. + downloader.DownloadProgressChanged += OnDownloadProgressChanged; - // 创建SemaphoreSlim以限制同时进行的下载任务的数量 - SemaphoreSlim semaphore = new SemaphoreSlim(4); // 最多允许4个并发下载任务 + // Download completed event that can include errors or + // canceled or download completed successfully. + downloader.DownloadFileCompleted += OnDownloadFileCompleted; + } - using (FileStream fileStream = new FileStream(cache_dir, FileMode.Create, FileAccess.Write, FileShare.None, blockSize, true)) - { - // 创建任务列表 - Task[] tasks = new Task[blockCount]; + private static void OnDownloadFileCompleted(object? sender, AsyncCompletedEventArgs e) + { - for (int i = 0; i < blockCount; i++) - { - int blockNumber = i; - tasks[i] = Task.Run(async () => - { - await semaphore.WaitAsync(); // 等待获取许可 + } - try - { - // 计算当前块的范围 - var start = blockNumber * blockSize; - var end = (blockNumber == blockCount - 1) ? contentLength - 1 : start + blockSize - 1; - - // 设置请求头,请求指定范围的数据 - var request = new HttpRequestMessage { RequestUri = new Uri(fileUrl), Method = HttpMethod.Get }; - request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(start, end); - - // 下载当前块 - using (HttpResponseMessage response = await client.SendAsync(request)) - { - response.EnsureSuccessStatusCode(); - byte[] buffer = await response.Content.ReadAsByteArrayAsync(); - await fileStream.WriteAsync(buffer, 0, buffer.Length); - } - - // 显示下载进度 - double percent = (double)(blockNumber + 1) / blockCount * 100; - Console.WriteLine($"已下载:{percent:F2}%"); - } - finally - { - semaphore.Release(); // 释放许可 - } - }); - } - - // 等待所有任务完成 - await Task.WhenAll(tasks); - } + private static void OnDownloadProgressChanged(object? sender, DownloadProgressChangedEventArgs e) + { + if (UpdateDialog.ui_enale) + { + UpdateDialog.editControl.pbDown.Value = e.ProgressPercentage; + UpdateDialog.editControl.text2.Text = $"{e.AverageBytesPerSecondSpeed}"; } - - Console.WriteLine("下载完成!"); + throw new NotImplementedException(); } - private void OnUpdate(long size, long count) - { - - } - - private void OnDone(byte[] data) - { - - } - - private void OnDestroy() + private static void OnDownloadStarted(object? sender, DownloadStartedEventArgs e) { + is_strat = true; + if (UpdateDialog.ui_enale) UpdateDialog.editControl.text1.Text = "零蛋正在更新装备..."; } } diff --git a/util/Download.cs b/util/Download.cs new file mode 100644 index 0000000..b1cdcab --- /dev/null +++ b/util/Download.cs @@ -0,0 +1,9 @@ + + +namespace Zerolauncher.util +{ + class Download + { + + } +} diff --git a/util/MyEncrypt.cs b/util/MyEncrypt.cs new file mode 100644 index 0000000..ad96b37 --- /dev/null +++ b/util/MyEncrypt.cs @@ -0,0 +1,162 @@ +using System.Security.Cryptography; +using System.IO; +namespace Zerolauncher.util +{ + + // MyEncrypt.SHA_Encrypt("test.txt", "test1.txt", "123456"); //文件加密 + // MyEncrypt.SHA_Dencrypt("test1.txt", "test2.txt", "123456"); //文件解密 + + public class MyEncrypt + { + private const ulong FC_TAG = 0xFC010203040506CF; + private const int BUFFER_SIZE = 128 * 1024; + //检验两个Byte数组是否相同 + private static bool CheckByteArrays(byte[] b1, byte[] b2) + { + if (b1.Length == b2.Length) + { + for (int i = 0; i < b1.Length; ++i) + { + if (b1[i] != b2[i]) + return false; + } + return true; + } + return false; + } + /// 密码 + /// + /// 加密对象 + private static SymmetricAlgorithm CreateRijndael(string password, byte[] salt) + { + PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt, "SHA256", 1000); + SymmetricAlgorithm sma = Rijndael.Create(); + sma.KeySize = 256; + sma.Key = pdb.GetBytes(32); + sma.Padding = PaddingMode.PKCS7; + return sma; + } + // 加密文件随机数生成 + private static RandomNumberGenerator rand = new RNGCryptoServiceProvider(); + // 生成指定长度的随机Byte数组 + private static byte[] GenerateRandomBytes(int count) + { + byte[] bytes = new byte[count]; + rand.GetBytes(bytes); + return bytes; + } + + // 加密文件 + public static void SHA_Encrypt(string inFile, string outFile, string password) + { + using (FileStream fin = File.OpenRead(inFile), + fout = File.OpenWrite(outFile)) + { + long lSize = fin.Length; // 输入文件长度 + int size = (int)lSize; + byte[] bytes = new byte[BUFFER_SIZE]; // 缓存 + int read = -1; // 输入文件读取数量 + int value = 0; + // 获取IV和salt + byte[] IV = GenerateRandomBytes(16); + byte[] salt = GenerateRandomBytes(16); + // 创建加密对象 + SymmetricAlgorithm sma = CreateRijndael(password, salt); + sma.IV = IV; + // 在输出文件开始部分写入IV和salt + fout.Write(IV, 0, IV.Length); + fout.Write(salt, 0, salt.Length); + // 创建散列加密 + HashAlgorithm hasher = SHA256.Create(); + using (CryptoStream cout = new CryptoStream(fout, sma.CreateEncryptor(), CryptoStreamMode.Write), + chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) + { + BinaryWriter bw = new BinaryWriter(cout); + bw.Write(lSize); + bw.Write(FC_TAG); + // 读写字节块到加密流缓冲区 + while ((read = fin.Read(bytes, 0, bytes.Length)) != 0) + { + cout.Write(bytes, 0, read); + chash.Write(bytes, 0, read); + value += read; + } + // 关闭加密流 + chash.Flush(); + chash.Close(); + // 读取散列 + byte[] hash = hasher.Hash; + // 输入文件写入散列 + cout.Write(hash, 0, hash.Length); + // 关闭文件流 + cout.Flush(); + cout.Close(); + } + } + } + // 解密文件 + public static void SHA_Dencrypt(string inFile, string outFile, string password) + { + // 创建打开文件流 + using (FileStream fin = File.OpenRead(inFile), + fout = File.OpenWrite(outFile)) + { + int size = (int)fin.Length; + byte[] bytes = new byte[BUFFER_SIZE]; + int read = -1; + int value = 0; + int outValue = 0; + byte[] IV = new byte[16]; + fin.Read(IV, 0, 16); + byte[] salt = new byte[16]; + fin.Read(salt, 0, 16); + SymmetricAlgorithm sma = CreateRijndael(password, salt); + sma.IV = IV; + value = 32; + long lSize = -1; + // 创建散列对象, 校验文件 + HashAlgorithm hasher = SHA256.Create(); + using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read), + chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) + { + // 读取文件长度 + BinaryReader br = new BinaryReader(cin); + lSize = br.ReadInt64(); + ulong tag = br.ReadUInt64(); + if (FC_TAG != tag) + throw new Exception("文件被破坏"); + long numReads = lSize / BUFFER_SIZE; + long slack = (long)lSize % BUFFER_SIZE; + for (int i = 0; i < numReads; ++i) + { + read = cin.Read(bytes, 0, bytes.Length); + fout.Write(bytes, 0, read); + chash.Write(bytes, 0, read); + value += read; + outValue += read; + } + if (slack > 0) + { + read = cin.Read(bytes, 0, (int)slack); + fout.Write(bytes, 0, read); + chash.Write(bytes, 0, read); + value += read; + outValue += read; + } + chash.Flush(); + chash.Close(); + fout.Flush(); + fout.Close(); + byte[] curHash = hasher.Hash; + // 获取比较和旧的散列对象 + byte[] oldHash = new byte[hasher.HashSize / 8]; + read = cin.Read(oldHash, 0, oldHash.Length); + if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash))) + throw new Exception("文件被破坏"); + } + if (outValue != lSize) + throw new Exception("文件大小不匹配"); + } + } + } +} diff --git a/Manager/SpaceEncoder.cs b/util/SpaceEncoder.cs similarity index 98% rename from Manager/SpaceEncoder.cs rename to util/SpaceEncoder.cs index 50138a2..f1c7bb6 100644 --- a/Manager/SpaceEncoder.cs +++ b/util/SpaceEncoder.cs @@ -1,6 +1,6 @@ using System.Text; -namespace Zerolauncher.Manager +namespace Zerolauncher.util { class SpaceEncoder {