From 52c589aa3d829fedc311a52f430d67f0fb0f84eb Mon Sep 17 00:00:00 2001 From: Mili Date: Sat, 27 Aug 2022 17:32:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AE=9E=E4=BD=93=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FunGameServer.csproj | 11 ++++++- Main.cs | 41 +++++++++++++++---------- Models/Config/Config.cs | 3 +- Models/Config/SocketEnums.cs | 22 +++++--------- Models/Entity/ActiveItem.cs | 18 +++++++++++ Models/Entity/ActiveSkill.cs | 29 ++++++++++++++++++ Models/Entity/Character.cs | 42 +++++++++++++++++++++++++ Models/Entity/CharacterStatistics.cs | 34 +++++++++++++++++++++ Models/Entity/GameStatistics.cs | 35 +++++++++++++++++++++ Models/Entity/Item.cs | 19 ++++++++++++ Models/Entity/PassiveItem.cs | 18 +++++++++++ Models/Entity/PassiveSkill.cs | 27 ++++++++++++++++ Models/Entity/Room.cs | 33 ++++++++++++++++++++ Models/Entity/Skill.cs | 17 +++++++++++ Models/Entity/Stock.cs | 23 ++++++++++++++ Models/Entity/User.cs | 44 +++++++++++++++++++++++++++ Models/Entity/UserStatistics.cs | 35 +++++++++++++++++++++ Sockets/ClientSocket.cs | 40 +++++++++++++++--------- Utils/SocketHelper.cs | 28 ++++++++++++++++- logo.ico | Bin 0 -> 16958 bytes 20 files changed, 470 insertions(+), 49 deletions(-) create mode 100644 Models/Entity/ActiveItem.cs create mode 100644 Models/Entity/ActiveSkill.cs create mode 100644 Models/Entity/Character.cs create mode 100644 Models/Entity/CharacterStatistics.cs create mode 100644 Models/Entity/GameStatistics.cs create mode 100644 Models/Entity/Item.cs create mode 100644 Models/Entity/PassiveItem.cs create mode 100644 Models/Entity/PassiveSkill.cs create mode 100644 Models/Entity/Room.cs create mode 100644 Models/Entity/Skill.cs create mode 100644 Models/Entity/Stock.cs create mode 100644 Models/Entity/User.cs create mode 100644 Models/Entity/UserStatistics.cs create mode 100644 logo.ico diff --git a/FunGameServer.csproj b/FunGameServer.csproj index 2b0c232..a187999 100644 --- a/FunGameServer.csproj +++ b/FunGameServer.csproj @@ -5,10 +5,19 @@ net6.0 enable enable + logo.ico + logo.ico - + + + + + + True + \ + diff --git a/Main.cs b/Main.cs index a8d4a90..4d6584b 100644 --- a/Main.cs +++ b/Main.cs @@ -11,15 +11,17 @@ using FunGameServer.Utils; bool Running = true; Socket? ServerSocket = null; -string host = Config.SERVER_IPADRESS; +string hostname = Config.SERVER_NAME; int port = Config.SERVER_PORT; +Console.Title = Config.CONSOLE_TITLE; + try { Task t = Task.Factory.StartNew(() => { // 创建IP地址终结点对象 - IPEndPoint ip = new(IPAddress.Parse(host), port); + IPEndPoint ip = new(IPAddress.Any, port); // 创建TCP Socket对象并绑定终结点 ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); @@ -27,7 +29,7 @@ try // 开始监听连接 ServerSocket.Listen(Config.MAX_PLAYERS); - Console.WriteLine("服务器启动成功,正在监听 . . ."); + Console.WriteLine(SocketHelper.GetPrefix() + "服务器启动成功,正在监听 . . ."); while (Running) { @@ -37,9 +39,9 @@ try socket = ServerSocket.Accept(); IPEndPoint? clientIP = (IPEndPoint?)socket.RemoteEndPoint; if (clientIP != null) - Console.WriteLine("客户端" + clientIP.ToString() + "连接 . . ."); + Console.WriteLine(SocketHelper.GetPrefix() + "客户端" + clientIP.ToString() + "连接 . . ."); else - Console.WriteLine("未知地点客户端连接 . . ."); + Console.WriteLine(SocketHelper.GetPrefix() + "未知地点客户端连接 . . ."); if (Read(socket) && Send(socket)) Task.Factory.StartNew(() => { @@ -47,13 +49,13 @@ try }); else if (clientIP != null) - Console.WriteLine("客户端" + clientIP.ToString() + "连接失败。"); + Console.WriteLine(SocketHelper.GetPrefix() + "客户端" + clientIP.ToString() + "连接失败。"); else - Console.WriteLine("客户端连接失败。"); + Console.WriteLine(SocketHelper.GetPrefix() + "客户端连接失败。"); } catch (Exception e) { - Console.WriteLine("ERROR: 客户端断开连接!\n" + e.StackTrace); + Console.WriteLine(SocketHelper.GetPrefix() + "ERROR: 客户端断开连接!\n" + e.StackTrace); } } @@ -86,7 +88,7 @@ finally } } -Console.WriteLine("服务器已关闭,按任意键退出程序。"); +Console.WriteLine(SocketHelper.GetPrefix() + "服务器已关闭,按任意键退出程序。"); Console.ReadKey(); @@ -98,27 +100,34 @@ bool Read(Socket socket) if (length > 0) { string msg = Config.DEFAULT_ENCODING.GetString(buffer, 0, length); - Console.WriteLine("收到来自:客户端(玩家ID) -> " + msg); - return true; + string typestring = SocketHelper.GetTypeString(SocketHelper.GetType(msg)); + msg = SocketHelper.GetMessage(msg); + if (typestring != SocketEnums.TYPE_UNKNOWN) + { + Console.WriteLine(SocketHelper.GetPrefix() + "[ 客户端(" + typestring + ")] -> " + msg); + return true; + } + Console.WriteLine(SocketHelper.GetPrefix() + "客户端发送了不符合FunGame规定的字符,拒绝连接。"); + return false; } else - Console.WriteLine("客户端没有回应。"); + Console.WriteLine(SocketHelper.GetPrefix() + "客户端没有回应。"); return false; } bool Send(Socket socket) { // 发送消息给客户端 - string msg = ">> 已连接至服务器 -> [ " + host + " ] 连接成功"; + string msg = ">> 已连接至服务器 -> [ " + hostname + " ] 连接成功"; byte[] buffer = new byte[2048]; - buffer = Config.DEFAULT_ENCODING.GetBytes(SocketHelper.MakeMessage((int)SocketEnums.SendType.CheckLogin, msg)); + buffer = Config.DEFAULT_ENCODING.GetBytes(SocketHelper.MakeMessage((int)SocketEnums.Type.CheckLogin, msg)); if (socket.Send(buffer) > 0) { - Console.WriteLine("发送给:客户端 <- " + msg); + Console.WriteLine(SocketHelper.GetPrefix() + "[ 客户端 ] <- " + msg); return true; } else - Console.WriteLine("无法传输数据,与客户端的连接可能丢失。"); + Console.WriteLine(SocketHelper.GetPrefix() + "无法传输数据,与客户端的连接可能丢失。"); return false; } diff --git a/Models/Config/Config.cs b/Models/Config/Config.cs index c07540b..c084d1b 100644 --- a/Models/Config/Config.cs +++ b/Models/Config/Config.cs @@ -14,10 +14,11 @@ namespace FunGameServer.Models.Config public static int MAX_PLAYERS = 16; // 最多接受连接的玩家数量 public static int ONLINE_PLAYERS = 0; // 已连接的玩家数量 public static int CONNECTING_PLAYERS = 0; // 正在连接的玩家数量 - public static string SERVER_IPADRESS = "127.0.0.1"; // 默认IP地址 + public static string SERVER_NAME = "米粒的糖果屋"; // 服务器名称 public static int SERVER_PORT = 22222; // 默认端口 public static Encoding DEFAULT_ENCODING = Encoding.UTF8; // 默认传输字符集 public static int MAX_CONNECTFAILED = 5; // 最大连接失败次数 + public const string CONSOLE_TITLE = "FunGame Server"; /// /// string: 玩家标识ID diff --git a/Models/Config/SocketEnums.cs b/Models/Config/SocketEnums.cs index 7489d1f..7fcf791 100644 --- a/Models/Config/SocketEnums.cs +++ b/Models/Config/SocketEnums.cs @@ -8,7 +8,7 @@ namespace FunGameServer.Models.Config { public static class SocketEnums { - public enum SendType + public enum Type { GetNotice = 1, Login = 2, @@ -17,19 +17,11 @@ namespace FunGameServer.Models.Config HeartBeat = 5 } - public enum ReadType - { - GetNotice = 1, - Login = 2, - CheckLogin = 3, - Logout = 4, - HeartBeat = 5 - } - - public static string SENDTYPE_GetNotice = "GetNotice"; - public static string SENDTYPE_Login = "Login"; - public static string SENDTYPE_CheckLogin = "CheckLogin"; - public static string SENDTYPE_Logout = "Logout"; - public static string SENDTYPE_HeartBeat = "HeartBeat"; + public const string TYPE_UNKNOWN = "Unknown Type"; + public const string TYPE_GetNotice = "GetNotice"; + public const string TYPE_Login = "Login"; + public const string TYPE_CheckLogin = "CheckLogin"; + public const string TYPE_Logout = "Logout"; + public const string TYPE_HeartBeat = "HeartBeat"; } } diff --git a/Models/Entity/ActiveItem.cs b/Models/Entity/ActiveItem.cs new file mode 100644 index 0000000..144b53c --- /dev/null +++ b/Models/Entity/ActiveItem.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class ActiveItem : Item + { + public ActiveSkill? Skill { get; set; } = null; + + public ActiveItem() + { + Active = true; + } + } +} diff --git a/Models/Entity/ActiveSkill.cs b/Models/Entity/ActiveSkill.cs new file mode 100644 index 0000000..61392f2 --- /dev/null +++ b/Models/Entity/ActiveSkill.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class ActiveSkill : Skill + { + public decimal MP { get; set; } = 0; + public decimal EP { get; set; } = 0; + public decimal Reference1 { get; set; } = 0; + public decimal Reference2 { get; set; } = 0; + public decimal Reference3 { get; set; } = 0; + public decimal Reference4 { get; set; } = 0; + public decimal Reference5 { get; set; } = 0; + public decimal Reference6 { get; set; } = 0; + public decimal Reference7 { get; set; } = 0; + public decimal Reference8 { get; set; } = 0; + public decimal Reference9 { get; set; } = 0; + public decimal Reference10 { get; set; } = 0; + + public ActiveSkill() + { + Active = true; + } + } +} diff --git a/Models/Entity/Character.cs b/Models/Entity/Character.cs new file mode 100644 index 0000000..04135b3 --- /dev/null +++ b/Models/Entity/Character.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class Character + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public string FirstName { get; set; } = ""; + public User? User { get; set; } = null; + public CharacterStatistics? Statistics { get; set; } = null; + public int Level { get; set; } = 1; + public decimal EXP { get; set; } + public decimal HP { get; set; } + public decimal MP { get; set; } + public decimal EP { get; set; } + public decimal ATK { get; set; } + public decimal DEF { get; set; } + public decimal PhysicalReduction { get; set; } + public decimal MDF { get; set; } + public decimal HPRecovery { get; set; } = 0; + public decimal MPRecovery { get; set; } = 0; + public decimal EPRecovery { get; set; } = 0; + public decimal SPD { get; set; } + public decimal ATR { get; set; } + public decimal CritRate { get; set; } = 0.05M; + public decimal CritDMG { get; set; } = 1.25M; + public decimal EvadeRate { get; set; } = 0.05M; + public Hashtable? Skills { get; set; } = new Hashtable(); + public Hashtable? Items { get; set; } = new Hashtable(); + + public Character() + { + + } + } +} diff --git a/Models/Entity/CharacterStatistics.cs b/Models/Entity/CharacterStatistics.cs new file mode 100644 index 0000000..a611f4b --- /dev/null +++ b/Models/Entity/CharacterStatistics.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class CharacterStatistics + { + public int Id { get; set; } + public Character? Character { get; set; } = null; + public Hashtable? DamageStats { get; set; } = new Hashtable(); + public Hashtable? PhysicalDamageStats { get; set; } = new Hashtable(); + public Hashtable? MagicDamageStats { get; set; } = new Hashtable(); + public Hashtable? RealDamageStats { get; set; } = new Hashtable(); + public Hashtable? AvgDamageStats { get; set; } = new Hashtable(); + public Hashtable? AvgLiveRoundStats { get; set; } = new Hashtable(); + public Hashtable? AvgDamageRoundStats { get; set; } = new Hashtable(); + public Hashtable? KillStats { get; set; } = new Hashtable(); + public Hashtable? DeathStats { get; set; } = new Hashtable(); + public Hashtable? AssistStats { get; set; } = new Hashtable(); + public Hashtable? Plays { get; set; } = new Hashtable(); + public Hashtable? Wins { get; set; } = new Hashtable(); + public Hashtable? Loses { get; set; } = new Hashtable(); + public Hashtable? Winrates { get; set; } = new Hashtable(); + + public CharacterStatistics() + { + + } + } +} diff --git a/Models/Entity/GameStatistics.cs b/Models/Entity/GameStatistics.cs new file mode 100644 index 0000000..e13409a --- /dev/null +++ b/Models/Entity/GameStatistics.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class GameStatistics + { + public int Id { get; set; } + public Room? Room { get; set; } = null; + public string? GameRecord { get; set; } = null; + public string? RunTime { get; set; } = null; + public Hashtable? DamageStats { get; set; } = new Hashtable(); + public Hashtable? PhysicalDamageStats { get; set; } = new Hashtable(); + public Hashtable? MagicDamageStats { get; set; } = new Hashtable(); + public Hashtable? RealDamageStats { get; set; } = new Hashtable(); + public Hashtable? AvgDamageStats { get; set; } = new Hashtable(); + public Hashtable? KillStats { get; set; } = new Hashtable(); + public Hashtable? KillDetailStats { get; set; } = new Hashtable(); + public Hashtable? DeathStats { get; set; } = new Hashtable(); + public Hashtable? DeathDetailStats { get; set; } = new Hashtable(); + public Hashtable? AssistStats { get; set; } = new Hashtable(); + public Hashtable? RatingStats { get; set; } = new Hashtable(); + public Hashtable? EloStats { get; set; } = new Hashtable(); + public Hashtable? RankStats { get; set; } = new Hashtable(); + + public GameStatistics() + { + + } + } +} diff --git a/Models/Entity/Item.cs b/Models/Entity/Item.cs new file mode 100644 index 0000000..11cac8b --- /dev/null +++ b/Models/Entity/Item.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public abstract class Item + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public string Describe { get; set; } = ""; + public decimal Price { get; set; } + public char Key { get; set; } + public bool Active { get; set; } + public Character? Character { get; set; } = null; + } +} diff --git a/Models/Entity/PassiveItem.cs b/Models/Entity/PassiveItem.cs new file mode 100644 index 0000000..1d88be2 --- /dev/null +++ b/Models/Entity/PassiveItem.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class PassiveItem : Item + { + public PassiveSkill? Skill { get; set; } = null; + + public PassiveItem() + { + Active = false; + } + } +} diff --git a/Models/Entity/PassiveSkill.cs b/Models/Entity/PassiveSkill.cs new file mode 100644 index 0000000..8dee862 --- /dev/null +++ b/Models/Entity/PassiveSkill.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class PassiveSkill : Skill + { + public decimal Reference1 { get; set; } = 0; + public decimal Reference2 { get; set; } = 0; + public decimal Reference3 { get; set; } = 0; + public decimal Reference4 { get; set; } = 0; + public decimal Reference5 { get; set; } = 0; + public decimal Reference6 { get; set; } = 0; + public decimal Reference7 { get; set; } = 0; + public decimal Reference8 { get; set; } = 0; + public decimal Reference9 { get; set; } = 0; + public decimal Reference10 { get; set; } = 0; + + public PassiveSkill() + { + Active = false; + } + } +} diff --git a/Models/Entity/Room.cs b/Models/Entity/Room.cs new file mode 100644 index 0000000..9b56d23 --- /dev/null +++ b/Models/Entity/Room.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class Room + { + public int Id { get; set; } + public string Roomid { get; set; } = ""; + public DateTime Time { get; set; } = DateTime.Now; + public Hashtable PlayerList { get; set; } = new Hashtable(); + public User? RoomMaster { get; set; } + public int RoomType { get; set; } + public int RoomState { get; set; } + public GameStatistics? Statistics { get; set; } = null; + + public Room(User? master = null) + { + if (master != null) RoomMaster = master; + } + + public Room(string roomid, User? master = null) + { + Roomid = roomid; + if (master != null) RoomMaster = master; + } + } +} diff --git a/Models/Entity/Skill.cs b/Models/Entity/Skill.cs new file mode 100644 index 0000000..4b150f6 --- /dev/null +++ b/Models/Entity/Skill.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public abstract class Skill + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public string Describe { get; set; } = ""; + public char Key { get; set; } + public bool Active { get; set; } + } +} diff --git a/Models/Entity/Stock.cs b/Models/Entity/Stock.cs new file mode 100644 index 0000000..3587f5f --- /dev/null +++ b/Models/Entity/Stock.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class Stock + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public User? User { get; set; } = null; + public Hashtable? Characters { get; set; } = new Hashtable(); + public Hashtable? Items { get; set; } = new Hashtable(); + + public Stock() + { + + } + } +} diff --git a/Models/Entity/User.cs b/Models/Entity/User.cs new file mode 100644 index 0000000..38411a8 --- /dev/null +++ b/Models/Entity/User.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class User + { + public int Id { get; set; } + public string Userame { get; set; } = ""; + public string Password { get; set; } = ""; + public DateTime RegTime { get; set; } + public DateTime LastTime { get; set; } + public string Email { get; set; } = ""; + public string NickName { get; set; } = ""; + public bool IsAdmin { get; set; } = false; + public bool IsOperator { get; set; } = false; + public bool IsEnable { get; set; } = false; + public int OnlineState { get; set; } = 0; + public string Roomid { get; set; } = ""; + public int Credits { get; set; } = 0; + public int Material { get; set; } = 0; + public UserStatistics? Statistics { get; set; } = null; + public Stock? Stock { get; set; } = null; + + public User() + { + + } + + public User(string username) + { + Userame = username; + } + + public User(string username, string password) + { + Userame = username; + Password = password; + } + } +} diff --git a/Models/Entity/UserStatistics.cs b/Models/Entity/UserStatistics.cs new file mode 100644 index 0000000..9132c53 --- /dev/null +++ b/Models/Entity/UserStatistics.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FunGame.Models.Entity +{ + public class UserStatistics + { + public int Id { get; set; } + public User? User { get; set; } = null; + public Hashtable? DamageStats { get; set; } = new Hashtable(); + public Hashtable? PhysicalDamageStats { get; set; } = new Hashtable(); + public Hashtable? MagicDamageStats { get; set; } = new Hashtable(); + public Hashtable? RealDamageStats { get; set; } = new Hashtable(); + public Hashtable? AvgDamageStats { get; set; } = new Hashtable(); + public Hashtable? KillStats { get; set; } = new Hashtable(); + public Hashtable? DeathStats { get; set; } = new Hashtable(); + public Hashtable? AssistStats { get; set; } = new Hashtable(); + public Hashtable? Plays { get; set; } = new Hashtable(); + public Hashtable? Wins { get; set; } = new Hashtable(); + public Hashtable? Loses { get; set; } = new Hashtable(); + public Hashtable? Winrates { get; set; } = new Hashtable(); + public Hashtable? RatingStats { get; set; } = new Hashtable(); + public Hashtable? EloStats { get; set; } = new Hashtable(); + public Hashtable? RankStats { get; set; } = new Hashtable(); + + public UserStatistics() + { + + } + } +} diff --git a/Sockets/ClientSocket.cs b/Sockets/ClientSocket.cs index d078441..a64f62f 100644 --- a/Sockets/ClientSocket.cs +++ b/Sockets/ClientSocket.cs @@ -8,6 +8,8 @@ using System.Text; using System.Threading.Tasks; using System.Data.SqlTypes; using FunGameServer.Utils; +using System.Reflection.Metadata; +using FunGame.Models.Entity; namespace FunGameServer.Sockets { @@ -16,6 +18,8 @@ namespace FunGameServer.Sockets public bool Running { get; set; } = false; public Socket? Socket { get; set; } = null; + private User? user = null; + public ClientSocket(Socket socket, bool running) { Socket = socket; @@ -35,19 +39,21 @@ namespace FunGameServer.Sockets { string msg = Config.DEFAULT_ENCODING.GetString(buffer, 0, length); int type = SocketHelper.GetType(msg); + string typestring = SocketHelper.GetTypeString(type); msg = SocketHelper.GetMessage(msg); - Console.WriteLine("收到来自:客户端(" + type + ") -> " + msg); + Console.WriteLine(SocketHelper.GetPrefix() + "[ 客户端(" + typestring + ")] -> " + msg); switch (type) { - case (int)SocketEnums.ReadType.GetNotice: + case (int)SocketEnums.Type.GetNotice: break; - case (int)SocketEnums.ReadType.Login: + case (int)SocketEnums.Type.Login: break; - case (int)SocketEnums.ReadType.CheckLogin: + case (int)SocketEnums.Type.CheckLogin: + return true; + case (int)SocketEnums.Type.Logout: break; - case (int)SocketEnums.ReadType.Logout: - break; - case (int)SocketEnums.ReadType.HeartBeat: + case (int)SocketEnums.Type.HeartBeat: + msg = ""; break; } return Send(socket, type, msg); @@ -56,7 +62,7 @@ namespace FunGameServer.Sockets } catch (Exception e) { - Console.WriteLine("ERROR:客户端没有回应。\n" + e.StackTrace); + Console.WriteLine(SocketHelper.GetPrefix() + "ERROR:客户端没有回应。\n" + e.StackTrace); return false; } } @@ -68,16 +74,20 @@ namespace FunGameServer.Sockets { byte[] buffer = new byte[2048]; buffer = Config.DEFAULT_ENCODING.GetBytes(Convert.ToString(SocketHelper.MakeMessage(type, msg))); + string typestring = SocketHelper.GetTypeString(type); if (socket.Send(buffer) > 0) { - Console.WriteLine("发送给:客户端(" + type + ") <- " + msg); + if (msg != "") + Console.WriteLine(SocketHelper.GetPrefix() + "[ 客户端(" + typestring + ")] <- " + msg); + else + Console.WriteLine(SocketHelper.GetPrefix() + "-> [ 客户端(" + typestring + ")]"); return true; } throw new Exception(); } catch (Exception e) { - Console.WriteLine("ERROR:客户端没有回应。" + e.StackTrace); + Console.WriteLine(SocketHelper.GetPrefix() + "ERROR:客户端没有回应。" + e.StackTrace); return false; } } @@ -93,7 +103,7 @@ namespace FunGameServer.Sockets private void CreateStreamReader() { Thread.Sleep(1000); - Console.WriteLine("Creating: StreamReader...OK"); + Console.WriteLine(SocketHelper.GetPrefix() + "Creating: StreamReader...OK"); while (Running) { if (Socket != null) @@ -103,8 +113,8 @@ namespace FunGameServer.Sockets FailedTimes++; if (FailedTimes >= Config.MAX_CONNECTFAILED) { - Console.WriteLine("ERROR: Too Many Faileds."); - Console.WriteLine("DONE: StreamReader is Closed."); + Console.WriteLine(SocketHelper.GetPrefix() + "ERROR: Too Many Faileds."); + Console.WriteLine(SocketHelper.GetPrefix() + "CLOSE: StreamReader is Closed."); break; } } @@ -112,8 +122,8 @@ namespace FunGameServer.Sockets } else { - Console.WriteLine("ERROR: Socket is Closed."); - Console.WriteLine("DONE: StringStream is Closed."); + Console.WriteLine(SocketHelper.GetPrefix() + "ERROR: Socket is Closed."); + Console.WriteLine(SocketHelper.GetPrefix() + "CLOSE: StringStream is Closed."); break; } } diff --git a/Utils/SocketHelper.cs b/Utils/SocketHelper.cs index 212f4bb..882dd13 100644 --- a/Utils/SocketHelper.cs +++ b/Utils/SocketHelper.cs @@ -1,4 +1,5 @@ -using System; +using FunGameServer.Models.Config; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -17,6 +18,25 @@ namespace FunGameServer.Utils return Convert.ToInt32(msg[..1]); } + public static string GetTypeString(int type) + { + switch (type) + { + case (int)SocketEnums.Type.GetNotice: + return SocketEnums.TYPE_GetNotice; + case (int)SocketEnums.Type.Login: + return SocketEnums.TYPE_Login; + case (int)SocketEnums.Type.CheckLogin: + return SocketEnums.TYPE_CheckLogin; + case (int)SocketEnums.Type.Logout: + return SocketEnums.TYPE_Logout; + case (int)SocketEnums.Type.HeartBeat: + return SocketEnums.TYPE_HeartBeat; + default: + return SocketEnums.TYPE_UNKNOWN; + } + } + public static string GetMessage(string msg) { int index = msg.IndexOf(';') + 1; @@ -27,5 +47,11 @@ namespace FunGameServer.Utils { return type + ";" + msg; } + + public static string GetPrefix() + { + DateTime now = System.DateTime.Now; + return now.AddMilliseconds(-now.Millisecond).ToString() + " " + Config.SERVER_NAME + ":"; + } } } diff --git a/logo.ico b/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..4082874accbeb80cd336bcb14ff9004ad35920ff GIT binary patch literal 16958 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 literal 0 HcmV?d00001