diff --git a/CAPI/cpp/API/src/main.cpp b/CAPI/cpp/API/src/main.cpp index 611e347..459679d 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,26 @@ #pragma warning(disable : 4996) #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( + + _____ _ _ _ _ _ ___ __ + |_ _| | | | | | | / \ |_ _/ /_ + | | | |_| | | | |/ _ \ | | '_ \ + | | | _ | |_| / ___ \ | | (_) | + |_| |_| |_|\___/_/ \_\___\___/ + + ____ _ _ ____ _ _ _ + / ___|_ __ __ _ __| |_ _ __ _| |_ ___ / ___(_)_ __| |___| | + | | _| '__/ _` |/ _` | | | |/ _` | __/ _ \ | | _| | '__| / __| | + | |_| | | | (_| | (_| | |_| | (_| | || __/_ | |_| | | | | \__ \_| + \____|_| \__,_|\__,_|\__,_|\__,_|\__\___( ) \____|_|_| |_|___(_) + + +)welcome"sv; + int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) { int pID = 0; @@ -84,6 +105,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..553e7e0 100644 --- a/CAPI/python/PyAPI/main.py +++ b/CAPI/python/PyAPI/main.py @@ -9,8 +9,28 @@ 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: + # Generated by http://www.network-science.de/ascii/ with font "standard" + welcomeString = """ + + _____ _ _ _ _ _ ___ __ + |_ _| | | | | | | / \ |_ _/ /_ + | | | |_| | | | |/ _ \ | | '_ \ + | | | _ | |_| / ___ \ | | (_) | + |_| |_| |_|\___/_/ \_\___\___/ + + ____ _ _ ____ _ _ _ + / ___|_ __ __ _ __| |_ _ __ _| |_ ___ / ___(_)_ __| |___| | + | | _| '__/ _` |/ _` | | | |/ _` | __/ _ \ | | _| | '__| / __| | + | |_| | | | (_| | (_| | |_| | (_| | || __/_ | |_| | | | | \__ \_| + \____|_| \__,_|\__,_|\__,_|\__,_|\__\___( ) \____|_|_| |_|___(_) + + +""" + print(welcomeString) def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: pID: int = 0 @@ -45,6 +65,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/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 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 0000000..cbafc97 Binary files /dev/null and b/installer/Installer/eesast_software_trans_enlarged.ico differ 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 + \ + + + 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..85bfe48 100644 --- a/logic/Server/Program.cs +++ b/logic/Server/Program.cs @@ -1,15 +1,55 @@ -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 { + /// + /// Generated by http://www.network-science.de/ascii/ with font "standard" + /// + 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); + } + static int Main(string[] args) { foreach (var arg in args) @@ -26,63 +66,36 @@ namespace Server return 1; } + if (options.StartLockFile == DefaultArgumentOptions.FileName) + { + Console.WriteLine(welcome); + } Console.WriteLine("Server begins to run: " + options.ServerPort.ToString()); - if (options.Playback) + try { - try + var server = CreateServer(options); + Grpc.Core.Server rpcServer = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) { - 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(); + Services = { AvailableService.BindService(server) }, + Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) } + }; + rpcServer.Start(); - Console.WriteLine("Server begins to listen!"); - playbackServer.WaitForGame(); - Console.WriteLine("Server end!"); - server.ShutdownAsync().Wait(); + 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: {playbackServer.FinalScore[0]}"); - Console.WriteLine($"Tricker: {playbackServer.FinalScore[1]}"); - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } + 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(); + } +}