From 8135da30223ea73740023cb1eb79e0e584fd6814 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Sat, 29 Apr 2023 03:20:23 +0800 Subject: [PATCH 1/5] refactor(server): :recycle: make server base class to unify gameserver and playback server --- logic/Server/GameServer.cs | 21 ++++----- logic/Server/PlaybackServer.cs | 22 ++++----- logic/Server/Program.cs | 84 +++++++++++----------------------- logic/Server/RpcServices.cs | 15 ++---- logic/Server/ServerBase.cs | 14 ++++++ 5 files changed, 64 insertions(+), 92 deletions(-) create mode 100644 logic/Server/ServerBase.cs diff --git a/logic/Server/GameServer.cs b/logic/Server/GameServer.cs index 5d2724c..6573e7b 100644 --- a/logic/Server/GameServer.cs +++ b/logic/Server/GameServer.cs @@ -1,22 +1,17 @@ -using Grpc.Core; -using Protobuf; -using System.Threading; -using Timothy.FrameRateTask; -using System; -using System.Net.Http.Headers; +using GameClass.GameObj; using Gaming; -using GameClass.GameObj; -using Preparation.Utility; -using Playback; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Preparation.Interface; +using Playback; +using Preparation.Utility; +using Protobuf; using System.Collections.Concurrent; +using Timothy.FrameRateTask; namespace Server { - public partial class GameServer : AvailableService.AvailableServiceBase + partial class GameServer : ServerBase { private ConcurrentDictionary semaDict = new(); // private object semaDictLock = new(); @@ -86,7 +81,7 @@ namespace Server } } - public void WaitForEnd() + public override void WaitForEnd() { this.endGameSem.Wait(); mwr?.Dispose(); @@ -202,7 +197,7 @@ namespace Server return false; } - public int[] GetScore() + public override int[] GetScore() { int[] score = new int[2]; // 0代表Student,1代表Tricker game.GameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); diff --git a/logic/Server/PlaybackServer.cs b/logic/Server/PlaybackServer.cs index 449c1ed..dc347ce 100644 --- a/logic/Server/PlaybackServer.cs +++ b/logic/Server/PlaybackServer.cs @@ -1,26 +1,23 @@ -using Protobuf; -using Playback; -using System; -using System.Threading; -using Timothy.FrameRateTask; -using Gaming; +using Gaming; using Grpc.Core; +using Playback; +using Protobuf; using System.Collections.Concurrent; +using Timothy.FrameRateTask; namespace Server { - class PlaybackServer : AvailableService.AvailableServiceBase + class PlaybackServer : ServerBase { protected readonly ArgumentOptions options; private int[,] teamScore; private ConcurrentDictionary semaDict = new(); - private object semaDictLock = new(); + // private object semaDictLock = new(); private MessageToClient? currentGameInfo = new(); private MessageOfObj currentMapMsg = new(); private uint spectatorMinPlayerID = 2023; - private List spectatorList = new List(); + // private List spectatorList = new List(); public int TeamCount => options.TeamCount; - private MessageWriter? mwr = null; private object spetatorJoinLock = new(); protected object spectatorLock = new object(); protected bool isSpectatorJoin = false; @@ -47,6 +44,7 @@ namespace Server return finalScore; } } + public override int[] GetScore() => FinalScore; public PlaybackServer(ArgumentOptions options) { this.options = options; @@ -57,6 +55,7 @@ namespace Server public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter responseStream, ServerCallContext context) { + Console.WriteLine($"AddPlayer: {request.PlayerId}"); if (request.PlayerId >= spectatorMinPlayerID && options.NotAllowSpectator == false) { // 观战模式 @@ -95,6 +94,7 @@ namespace Server } catch { } Console.WriteLine($"The spectator {request.PlayerId} exited"); + return; } } catch (Exception) @@ -139,7 +139,7 @@ namespace Server } } - public void WaitForGame() + public override void WaitForEnd() { try { diff --git a/logic/Server/Program.cs b/logic/Server/Program.cs index c934cd1..1acffd6 100644 --- a/logic/Server/Program.cs +++ b/logic/Server/Program.cs @@ -1,15 +1,16 @@ -using Grpc.Core; +using CommandLine; +using Grpc.Core; using Protobuf; -using System.Threading; -using Timothy.FrameRateTask; -using System; -using System.Net.Http.Headers; -using CommandLine; namespace Server { public class Program { + static ServerBase CreateServer(ArgumentOptions options) + { + return options.Playback ? new PlaybackServer(options) : new GameServer(options); + } + static int Main(string[] args) { foreach (var arg in args) @@ -28,61 +29,30 @@ namespace Server Console.WriteLine("Server begins to run: " + options.ServerPort.ToString()); - if (options.Playback) + try { - try - { - PlaybackServer? playbackServer = new(options); - Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) - { - Services = { AvailableService.BindService(playbackServer) }, - Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) } - }; - server.Start(); - - Console.WriteLine("Server begins to listen!"); - playbackServer.WaitForGame(); - Console.WriteLine("Server end!"); - server.ShutdownAsync().Wait(); - - Thread.Sleep(50); - Console.WriteLine(""); - Console.WriteLine("=================== Final Score ===================="); - Console.WriteLine($"Studnet: {playbackServer.FinalScore[0]}"); - Console.WriteLine($"Tricker: {playbackServer.FinalScore[1]}"); - } - catch (Exception ex) + var server = CreateServer(options); + Grpc.Core.Server rpcServer = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) { - Console.WriteLine(ex.ToString()); - } + Services = { AvailableService.BindService(server) }, + Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) } + }; + rpcServer.Start(); + + Console.WriteLine("Server begins to listen!"); + server.WaitForEnd(); + Console.WriteLine("Server end!"); + rpcServer.ShutdownAsync().Wait(); + + Thread.Sleep(50); + Console.WriteLine(""); + Console.WriteLine("=================== Final Score ===================="); + Console.WriteLine($"Studnet: {server.GetScore()[0]}"); + Console.WriteLine($"Tricker: {server.GetScore()[1]}"); } - else + catch (Exception ex) { - try - { - GameServer? gameServer = new(options); - Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) - { - Services = { AvailableService.BindService(gameServer) }, - Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) } - }; - server.Start(); - - Console.WriteLine("Server begins to listen!"); - gameServer.WaitForEnd(); - Console.WriteLine("Server end!"); - server.ShutdownAsync().Wait(); - - Thread.Sleep(50); - Console.WriteLine(""); - Console.WriteLine("=================== Final Score ===================="); - Console.WriteLine($"Studnet: {gameServer.GetScore()[0]}"); - Console.WriteLine($"Tricker: {gameServer.GetScore()[1]}"); - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } + Console.WriteLine(ex.ToString()); } return 0; } diff --git a/logic/Server/RpcServices.cs b/logic/Server/RpcServices.cs index e65bacf..2db93b2 100644 --- a/logic/Server/RpcServices.cs +++ b/logic/Server/RpcServices.cs @@ -1,19 +1,12 @@ -using Grpc.Core; -using Protobuf; -using System.Threading; -using System; -using System.Net.Http.Headers; +using GameClass.GameObj; using Gaming; -using GameClass.GameObj; +using Grpc.Core; using Preparation.Utility; -using Playback; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Preparation.Interface; +using Protobuf; namespace Server { - public partial class GameServer : AvailableService.AvailableServiceBase + partial class GameServer : ServerBase { private int playerCountNow = 0; protected object spectatorLock = new object(); diff --git a/logic/Server/ServerBase.cs b/logic/Server/ServerBase.cs new file mode 100644 index 0000000..dbb578c --- /dev/null +++ b/logic/Server/ServerBase.cs @@ -0,0 +1,14 @@ +using Grpc.Core; +using Playback; +using Protobuf; +using System.Collections.Concurrent; +using Timothy.FrameRateTask; + +namespace Server +{ + abstract class ServerBase : AvailableService.AvailableServiceBase + { + public abstract void WaitForEnd(); + public abstract int[] GetScore(); + } +} From 3a0f407bc59cb4d5dba5206f6463d93e241c022a Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Sat, 29 Apr 2023 03:53:20 +0800 Subject: [PATCH 2/5] feat(logo): :sparkles: show logo on local server & win capi --- CAPI/cpp/API/src/main.cpp | 24 +++++++++++++++++++++ CAPI/python/PyAPI/logic.py | 4 ++-- CAPI/python/PyAPI/main.py | 23 ++++++++++++++++++++ logic/Server/Program.cs | 43 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/CAPI/cpp/API/src/main.cpp b/CAPI/cpp/API/src/main.cpp index 611e347..ea74fdc 100644 --- a/CAPI/cpp/API/src/main.cpp +++ b/CAPI/cpp/API/src/main.cpp @@ -3,6 +3,7 @@ #include "structures.h" #include #include +#include #undef GetMessage #undef SendMessage @@ -12,6 +13,24 @@ #pragma warning(disable : 4996) #endif +using namespace std::literals::string_view_literals; +static constexpr std::string_view welcomeString = R"welcome( + + _____ _ _ _ _ _ ___ __ + |_ _| | | | | | | / \ |_ _/ /_ + | | | |_| | | | |/ _ \ | | '_ \ + | | | _ | |_| / ___ \ | | (_) | + |_| |_| |_|\___/_/ \_\___\___/ + + ____ _ _ ____ _ _ _ + / ___|_ __ __ _ __| |_ _ __ _| |_ ___ / ___(_)_ __| |___| | + | | _| '__/ _` |/ _` | | | |/ _` | __/ _ \ | | _| | '__| / __| | + | |_| | | | (_| | (_| | |_| | (_| | || __/_ | |_| | | | | \__ \_| + \____|_| \__,_|\__,_|\__,_|\__,_|\__\___( ) \____|_|_| |_|___(_) + + +)welcome"sv; + int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) { int pID = 0; @@ -84,6 +103,11 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) playerType = THUAI6::PlayerType::StudentPlayer; stuType = studentType[pID]; } + +#ifdef _MSC_VER + std::cout << welcomeString << std::endl; +#endif + Logic logic(playerType, pID, trickerType, stuType); logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); } diff --git a/CAPI/python/PyAPI/logic.py b/CAPI/python/PyAPI/logic.py index e1dcf7f..383878d 100644 --- a/CAPI/python/PyAPI/logic.py +++ b/CAPI/python/PyAPI/logic.py @@ -512,10 +512,10 @@ class Logic(ILogic): if platform.system().lower() == "windows": os.system( - f"mkdir {os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '/logs'}") + f"mkdir \"{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}\\logs\"") else: os.system( - f"mkdir -p {os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '/logs'}") + f"mkdir -p \"{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}/logs\"") fileHandler = logging.FileHandler(os.path.dirname( os.path.dirname(os.path.realpath(__file__))) + "/logs/logic" + str(self.__playerID) + "-log.txt", "w+", encoding="utf-8") diff --git a/CAPI/python/PyAPI/main.py b/CAPI/python/PyAPI/main.py index d915634..32bbb9b 100644 --- a/CAPI/python/PyAPI/main.py +++ b/CAPI/python/PyAPI/main.py @@ -9,8 +9,27 @@ from PyAPI.AI import AI from PyAPI.logic import Logic from typing import List, Callable import argparse +import platform import PyAPI.structures as THUAI6 +def PrintWelcomeString() -> None: + welcomeString = """ + + _____ _ _ _ _ _ ___ __ + |_ _| | | | | | | / \ |_ _/ /_ + | | | |_| | | | |/ _ \ | | '_ \ + | | | _ | |_| / ___ \ | | (_) | + |_| |_| |_|\___/_/ \_\___\___/ + + ____ _ _ ____ _ _ _ + / ___|_ __ __ _ __| |_ _ __ _| |_ ___ / ___(_)_ __| |___| | + | | _| '__/ _` |/ _` | | | |/ _` | __/ _ \ | | _| | '__| / __| | + | |_| | | | (_| | (_| | |_| | (_| | || __/_ | |_| | | | | \__ \_| + \____|_| \__,_|\__,_|\__,_|\__,_|\__\___( ) \____|_|_| |_|___(_) + + +""" + print(welcomeString) def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: pID: int = 0 @@ -45,6 +64,10 @@ def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: playerType = THUAI6.PlayerType.TrickerPlayer else: playerType = THUAI6.PlayerType.StudentPlayer + + if platform.system().lower() == "windows": + PrintWelcomeString() + logic = Logic(pID, playerType) logic.Main(AIBuilder, sIP, sPort, file, screen, warnOnly) diff --git a/logic/Server/Program.cs b/logic/Server/Program.cs index 1acffd6..a4c5678 100644 --- a/logic/Server/Program.cs +++ b/logic/Server/Program.cs @@ -6,6 +6,45 @@ namespace Server { public class Program { + /// + /// Generated by http://www.network-science.de/ascii/ + /// + const string welcome = +@" + + _____ _ _ _ _ _ ___ __ + |_ _| | | | | | | / \ |_ _/ /_ + | | | |_| | | | |/ _ \ | | '_ \ + | | | _ | |_| / ___ \ | | (_) | + |_| |_| |_|\___/_/ \_\___\___/ + + ____ _ _ ____ _ _ _ + / ___|_ __ __ _ __| |_ _ __ _| |_ ___ / ___(_)_ __| |___| | + | | _| '__/ _` |/ _` | | | |/ _` | __/ _ \ | | _| | '__| / __| | + | |_| | | | (_| | (_| | |_| | (_| | || __/_ | |_| | | | | \__ \_| + \____|_| \__,_|\__,_|\__,_|\__,_|\__\___( ) \____|_|_| |_|___(_) + + +"; + // 特别说明:在 .NET 7 及以上,C# 支持新的多行字符串,允许多行前面缩进,因此可以不必再定格写字符串, + // 即升级 .NET 版本后可以改为如下的: + // const string welcome = """ + // + // _____ _ _ _ _ _ ___ __ + // |_ _| | | | | | | / \ |_ _/ /_ + // | | | |_| | | | |/ _ \ | | '_ \ + // | | | _ | |_| / ___ \ | | (_) | + // |_| |_| |_|\___/_/ \_\___\___/ + // + // ____ _ _ ____ _ _ _ + // / ___|_ __ __ _ __| |_ _ __ _| |_ ___ / ___(_)_ __| |___| | + // | | _| '__/ _` |/ _` | | | |/ _` | __/ _ \ | | _| | '__| / __| | + // | |_| | | | (_| | (_| | |_| | (_| | || __/_ | |_| | | | | \__ \_| + // \____|_| \__,_|\__,_|\__,_|\__,_|\__\___( ) \____|_|_| |_|___(_) + // + // + // """; // 将以此结束符为基准开始缩进(但 Python 没有这个 feature,差评 x) + static ServerBase CreateServer(ArgumentOptions options) { return options.Playback ? new PlaybackServer(options) : new GameServer(options); @@ -27,6 +66,10 @@ namespace Server return 1; } + if (options.StartLockFile == DefaultArgumentOptions.FileName) + { + Console.WriteLine(welcome); + } Console.WriteLine("Server begins to run: " + options.ServerPort.ToString()); try From 1d1617f6918555f7ea5072cb7cb0ff005b3e9261 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Sat, 29 Apr 2023 04:05:34 +0800 Subject: [PATCH 3/5] chore(logo): :bulb: add logo source website --- CAPI/cpp/API/src/main.cpp | 2 ++ CAPI/python/PyAPI/main.py | 1 + logic/Server/Program.cs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CAPI/cpp/API/src/main.cpp b/CAPI/cpp/API/src/main.cpp index ea74fdc..459679d 100644 --- a/CAPI/cpp/API/src/main.cpp +++ b/CAPI/cpp/API/src/main.cpp @@ -14,6 +14,8 @@ #endif using namespace std::literals::string_view_literals; + +// Generated by http://www.network-science.de/ascii/ with font "standard" static constexpr std::string_view welcomeString = R"welcome( _____ _ _ _ _ _ ___ __ diff --git a/CAPI/python/PyAPI/main.py b/CAPI/python/PyAPI/main.py index 32bbb9b..553e7e0 100644 --- a/CAPI/python/PyAPI/main.py +++ b/CAPI/python/PyAPI/main.py @@ -13,6 +13,7 @@ import platform import PyAPI.structures as THUAI6 def PrintWelcomeString() -> None: + # Generated by http://www.network-science.de/ascii/ with font "standard" welcomeString = """ _____ _ _ _ _ _ ___ __ diff --git a/logic/Server/Program.cs b/logic/Server/Program.cs index a4c5678..85bfe48 100644 --- a/logic/Server/Program.cs +++ b/logic/Server/Program.cs @@ -7,7 +7,7 @@ namespace Server public class Program { /// - /// Generated by http://www.network-science.de/ascii/ + /// Generated by http://www.network-science.de/ascii/ with font "standard" /// const string welcome = @" From 2724dab361a78036691ecdc7bc04936eb3b84b45 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Sat, 29 Apr 2023 05:17:16 +0800 Subject: [PATCH 4/5] chore(logo): change installer logo --- installer/Installer/Installer.csproj | 13 +++ installer/Installer/Model.cs | 83 ++++++++++-------- .../eesast_software_trans_enlarged.ico | Bin 0 -> 270398 bytes .../InstallerUpdater/InstallerUpdater.csproj | 8 ++ 4 files changed, 66 insertions(+), 38 deletions(-) create mode 100644 installer/Installer/eesast_software_trans_enlarged.ico diff --git a/installer/Installer/Installer.csproj b/installer/Installer/Installer.csproj index 53d5639..0d16d13 100644 --- a/installer/Installer/Installer.csproj +++ b/installer/Installer/Installer.csproj @@ -6,8 +6,21 @@ enable true true + eesast_software_trans_enlarged.ico + eesast_software_trans.png + + + + + + + True + \ + + + diff --git a/installer/Installer/Model.cs b/installer/Installer/Model.cs index 552c8cd..a95f17b 100644 --- a/installer/Installer/Model.cs +++ b/installer/Installer/Model.cs @@ -392,7 +392,7 @@ namespace Downloader public class Data { public static string path = ""; // 标记路径记录文件THUAI6.json的路径 - public static string FilePath = ""; // 最后一级为THUAI6文件夹所在目录 + public static string FilePath = ""; // 最后一级为THUAI6文件夹所在目录 public static string dataPath = ""; // C盘的文档文件夹 public Data(string path) { @@ -401,7 +401,7 @@ namespace Downloader Data.path = System.IO.Path.Combine(dataPath, "THUAI6.json"); if (File.Exists(Data.path)) { - var dict = new Dictionary(); + Dictionary? dict; using (StreamReader r = new StreamReader(Data.path)) { string json = r.ReadToEnd(); @@ -409,7 +409,7 @@ namespace Downloader { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json); + dict = Utils.TryDeserializeJson>(json); if (dict != null && dict.ContainsKey("installpath")) { FilePath = dict["installpath"].Replace('\\', '/'); @@ -424,7 +424,7 @@ namespace Downloader else { FilePath = System.IO.Path.GetDirectoryName(@path) - ?? throw new Exception("Fail to find the path of the file"); + ?? throw new Exception("Failed to get the path of the file"); //将dat文件写入程序运行路径 string json; @@ -437,7 +437,7 @@ namespace Downloader { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json); + dict = Utils.TryDeserializeJson>(json); dict?.Add("installpath", path); } using FileStream fs2 = new FileStream(Data.path, FileMode.Create, FileAccess.ReadWrite); @@ -461,7 +461,7 @@ namespace Downloader { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json); + dict = Utils.TryDeserializeJson>(json); if (dict != null && dict.ContainsKey("installpath")) { dict["installpath"] = newPath; @@ -634,7 +634,7 @@ namespace Downloader using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, jsonName))) json = r.ReadToEnd(); json = json.Replace("\r", string.Empty).Replace("\n", string.Empty); - Dictionary jsonDict = Utils.DeserializeJson>(json); + var jsonDict = Utils.DeserializeJson1>(json); string updatingFolder = ""; switch (OS) { @@ -815,7 +815,7 @@ namespace Downloader { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - var dict = Utils.DeserializeJson>(json); + var dict = Utils.TryDeserializeJson>(json); if (dict == null || !dict.ContainsKey("download") || "false" == dict["download"]) { return false; @@ -865,7 +865,7 @@ namespace Downloader using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, jsonName))) json = r.ReadToEnd(); json = json.Replace("\r", string.Empty).Replace("\n", string.Empty); - Dictionary jsonDict = Utils.DeserializeJson>(json); + // var jsonDict = Utils.DeserializeJson>(json); newFileName.Clear(); updateFileName.Clear(); @@ -899,7 +899,7 @@ namespace Downloader FileInfo fileInfo = new FileInfo(System.IO.Path.Combine(Data.FilePath, "THUAI6.tar.gz")); fileInfo.Delete(); string json2; - Dictionary dict = new Dictionary(); + Dictionary? dict; string existpath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json"); using FileStream fs = new FileStream(existpath, FileMode.Open, FileAccess.ReadWrite); using (StreamReader r = new StreamReader(fs)) @@ -909,7 +909,7 @@ namespace Downloader { json2 += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json2); + dict = Utils.TryDeserializeJson>(json2); if (dict == null || !dict.ContainsKey("download")) { dict?.Add("download", "true"); @@ -1000,7 +1000,7 @@ namespace Downloader using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, "hash.json"))) json = r.ReadToEnd(); json = json.Replace("\r", string.Empty).Replace("\n", string.Empty).Replace("/", @"\\"); - Dictionary jsonDict = Utils.DeserializeJson>(json); + Dictionary jsonDict = Utils.DeserializeJson1>(json); Change_all_hash(Data.FilePath, jsonDict); OverwriteHash(jsonDict); break; @@ -1058,7 +1058,7 @@ namespace Downloader } string json2; - Dictionary dict = new Dictionary(); + Dictionary? dict; string existpath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json"); using FileStream fs = new FileStream(existpath, FileMode.Open, FileAccess.ReadWrite); using (StreamReader r = new StreamReader(fs)) @@ -1068,7 +1068,7 @@ namespace Downloader { json2 += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json2); + dict = Utils.TryDeserializeJson>(json2); if (dict == null || !dict.ContainsKey("download")) { dict?.Add("download", "false"); @@ -1302,7 +1302,7 @@ namespace Downloader using (StreamReader r = new StreamReader(System.IO.Path.Combine(dir, hashName))) json = r.ReadToEnd(); json = json.Replace("\r", string.Empty).Replace("\n", string.Empty); - Dictionary jsonDict = Utils.DeserializeJson>(json); + var jsonDict = Utils.TryDeserializeJson>(json); string md5 = ""; List awaitUpdate = new List(); if (jsonDict != null) @@ -1351,9 +1351,9 @@ namespace Downloader using (StreamReader r = new StreamReader(System.IO.Path.Combine(dir, "updateList.json"))) json = r.ReadToEnd(); json = json.Replace("\r", string.Empty).Replace("\n", string.Empty); - List jsonList; + List? jsonList; if (json != null) - jsonList = Utils.DeserializeJson>(json); + jsonList = Utils.TryDeserializeJson>(json); else return false; if (jsonList != null && jsonList.Contains("Dismiss")) @@ -1405,7 +1405,7 @@ namespace WebConnect throw new Exception("no token!"); logintoken = token; SaveToken(); - var info = Utils.DeserializeJson>(await response.Content.ReadAsStringAsync()); + var info = Utils.DeserializeJson1>(await response.Content.ReadAsStringAsync()); Downloader.UserInfo._id = info["_id"]; Downloader.UserInfo.email = info["email"]; break; @@ -1461,19 +1461,19 @@ namespace WebConnect { case System.Net.HttpStatusCode.OK: - var res = Utils.DeserializeJson>(await response.Content.ReadAsStringAsync()); - string appid = "1255334966"; // 设置腾讯云账户的账户标识(APPID) - string region = "ap-beijing"; // 设置一个默认的存储桶地域 + var res = Utils.DeserializeJson1>(await response.Content.ReadAsStringAsync()); + string appid = "1255334966"; // 设置腾讯云账户的账户标识(APPID) + string region = "ap-beijing"; // 设置一个默认的存储桶地域 CosXmlConfig config = new CosXmlConfig.Builder() - .IsHttps(true) // 设置默认 HTTPS 请求 - .SetAppid(appid) // 设置腾讯云账户的账户标识 APPID - .SetRegion(region) // 设置一个默认的存储桶地域 - .SetDebugLog(true) // 显示日志 - .Build(); // 创建 CosXmlConfig 对象 - string tmpSecretId = res["TmpSecretId"]; //"临时密钥 SecretId"; - string tmpSecretKey = res["TmpSecretKey"]; //"临时密钥 SecretKey"; - string tmpToken = res["SecurityToken"]; //"临时密钥 token"; - long tmpExpiredTime = Convert.ToInt64(res["ExpiredTime"]);//临时密钥有效截止时间,精确到秒 + .IsHttps(true) // 设置默认 HTTPS 请求 + .SetAppid(appid) // 设置腾讯云账户的账户标识 APPID + .SetRegion(region) // 设置一个默认的存储桶地域 + .SetDebugLog(true) // 显示日志 + .Build(); // 创建 CosXmlConfig 对象 + string tmpSecretId = res["TmpSecretId"]; //"临时密钥 SecretId"; + string tmpSecretKey = res["TmpSecretKey"]; //"临时密钥 SecretKey"; + string tmpToken = res["SecurityToken"]; //"临时密钥 token"; + long tmpExpiredTime = Convert.ToInt64(res["ExpiredTime"]); //临时密钥有效截止时间,精确到秒 QCloudCredentialProvider cosCredentialProvider = new DefaultSessionQCloudCredentialProvider( tmpSecretId, tmpSecretKey, tmpExpiredTime, tmpToken ); @@ -1586,7 +1586,7 @@ namespace WebConnect { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json); + dict = Utils.DeserializeJson1>(json); if (dict.ContainsKey("token")) { dict.Remove("token"); @@ -1629,7 +1629,7 @@ namespace WebConnect json += @"{""THUAI6""" + ":" + @"""2023""}"; } Dictionary dict = new Dictionary(); - dict = Utils.DeserializeJson>(json); + dict = Utils.DeserializeJson1>(json); if (!dict.ContainsKey(key)) { dict.Add(key, data); @@ -1666,7 +1666,7 @@ namespace WebConnect { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json); + dict = Utils.DeserializeJson1>(json); fs.Close(); sr.Close(); return dict[key]; @@ -1693,7 +1693,7 @@ namespace WebConnect { json += @"{""THUAI6""" + ":" + @"""2023""}"; } - dict = Utils.DeserializeJson>(json); + dict = Utils.DeserializeJson1>(json); if (!dict.ContainsKey("token")) { return false; @@ -1747,9 +1747,9 @@ namespace WebConnect var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var info = await response.Content.ReadAsStringAsync(); - var s1 = Utils.DeserializeJson>(info)["data"]; - var s2 = Utils.DeserializeJson>>(s1.ToString() ?? "")["contest_team_member"]; - var sres = Utils.DeserializeJson>(s2[0].ToString() ?? "")["team_id"]; + var s1 = Utils.DeserializeJson1>(info)["data"]; + var s2 = Utils.DeserializeJson1>>(s1.ToString() ?? "")["contest_team_member"]; + var sres = Utils.DeserializeJson1>(s2[0].ToString() ?? "")["team_id"]; return sres; } async public Task GetUserId(string learnNumber) @@ -1777,11 +1777,18 @@ namespace WebConnect internal static class Utils { - public static T DeserializeJson(string json) + public static T DeserializeJson1(string json) + where T : notnull { return JsonConvert.DeserializeObject(json) ?? throw new Exception("Failed to deserialize json."); } + + public static T? TryDeserializeJson(string json) + where T : notnull + { + return JsonConvert.DeserializeObject(json); + } } } diff --git a/installer/Installer/eesast_software_trans_enlarged.ico b/installer/Installer/eesast_software_trans_enlarged.ico new file mode 100644 index 0000000000000000000000000000000000000000..cbafc97f8ee28af4b4d98412f9f788f967d6479b GIT binary patch literal 270398 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 literal 0 HcmV?d00001 diff --git a/installer/InstallerUpdater/InstallerUpdater.csproj b/installer/InstallerUpdater/InstallerUpdater.csproj index 0dd4fb5..3be5681 100644 --- a/installer/InstallerUpdater/InstallerUpdater.csproj +++ b/installer/InstallerUpdater/InstallerUpdater.csproj @@ -5,8 +5,16 @@ net6.0-windows enable true + eesast_software_trans.png + + + True + \ + + + From 04c651ec95adb8762dd73dc4bdd89d623cadbd7d Mon Sep 17 00:00:00 2001 From: Changli Tang <84725343+TCL606@users.noreply.github.com> Date: Sat, 29 Apr 2023 11:44:39 +0800 Subject: [PATCH 5/5] Update requirements.txt --- CAPI/python/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CAPI/python/requirements.txt b/CAPI/python/requirements.txt index 1e31ecf..3f4ef6c 100644 --- a/CAPI/python/requirements.txt +++ b/CAPI/python/requirements.txt @@ -1,2 +1,3 @@ grpcio==1.52.0 grpcio-tools==1.52.0 +numpy