添加日志级别;添加匿名服务器监听;模组线程安全改进 (#41)

* 添加日志级别;添加匿名服务器监听(不要求客户端安装)

* 修复不同时间多客户端连接游戏模组时可能产生的线程安全问题

* 更新了匿名服务器令牌确认
This commit is contained in:
milimoe 2025-01-17 18:59:44 +08:00 committed by GitHub
parent ef8f6e1007
commit ccf75528cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 271 additions and 63 deletions

View File

@ -70,6 +70,21 @@ void StartServer()
try try
{ {
ServerHelper.WriteLine("正在读取配置文件并初始化服务 . . ."); ServerHelper.WriteLine("正在读取配置文件并初始化服务 . . .");
// 检查是否存在配置文件
if (!INIHelper.ExistINIFile())
{
ServerHelper.WriteLine("未检测到配置文件,将自动创建配置文件 . . .");
INIHelper.Init(Config.FunGameType);
ServerHelper.WriteLine("配置文件FunGame.ini创建成功请修改该配置文件然后重启服务器。");
return;
}
else
{
ServerHelper.GetServerSettings();
Console.Title = Config.ServerName + " - FunGame Server Port: " + Config.ServerPort;
}
// 初始化命令菜单 // 初始化命令菜单
ServerHelper.InitOrderList(); ServerHelper.InitOrderList();
@ -88,19 +103,6 @@ void StartServer()
// 读取Server插件 // 读取Server插件
FunGameSystem.GetServerPlugins(); FunGameSystem.GetServerPlugins();
// 检查是否存在配置文件
if (!INIHelper.ExistINIFile())
{
ServerHelper.WriteLine("未检测到配置文件,将自动创建配置文件 . . .");
INIHelper.Init(Config.FunGameType);
ServerHelper.WriteLine("配置文件FunGame.ini创建成功请修改该配置文件然后重启服务器。");
return;
}
else
{
ServerHelper.GetServerSettings();
Console.Title = Config.ServerName + " - FunGame Server Port: " + Config.ServerPort;
}
ServerHelper.WriteLine("请输入 help 来获取帮助,按下 Ctrl+C 关闭服务器。"); ServerHelper.WriteLine("请输入 help 来获取帮助,按下 Ctrl+C 关闭服务器。");
ServerHelper.PrintFunGameTitle(); ServerHelper.PrintFunGameTitle();
@ -120,9 +122,11 @@ void StartServer()
ServerHelper.WriteLine("服务器启动成功,开始监听 . . ."); ServerHelper.WriteLine("服务器启动成功,开始监听 . . .");
if (Config.ServerNotice != "") if (Config.ServerNotice != "")
ServerHelper.WriteLine("\n\n********** 服务器公告 **********\n\n" + Config.ServerNotice + "\n"); Console.WriteLine("\n\n********** 服务器公告 **********\n\n" + Config.ServerNotice + "\n");
else else
ServerHelper.WriteLine("无法读取服务器公告"); Console.WriteLine("无法读取服务器公告");
ServerHelper.Type();
while (Running) while (Running)
{ {

View File

@ -75,9 +75,18 @@ namespace Milimoe.FunGame.Server.Model
if (type == SocketMessageType.EndGame) if (type == SocketMessageType.EndGame)
{ {
if (NowGamingServer != null && NowGamingServer.IsAnonymous)
{
NowGamingServer.CloseAnonymousServer(this);
}
NowGamingServer = null; NowGamingServer = null;
return true; return true;
} }
if (type == SocketMessageType.AnonymousGameServer)
{
return await AnonymousGameServerHandler(obj);
}
if (type == SocketMessageType.DataRequest) if (type == SocketMessageType.DataRequest)
{ {
@ -110,7 +119,7 @@ namespace Milimoe.FunGame.Server.Model
bool result = await Send(SocketMessageType.HeartBeat); bool result = await Send(SocketMessageType.HeartBeat);
if (!result) if (!result)
{ {
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(HeartBeat) + ": " + result, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(HeartBeat) + ": " + result, InvokeMessageType.Error);
} }
return result; return result;
} }
@ -144,12 +153,12 @@ namespace Milimoe.FunGame.Server.Model
bool sendResult = await Send(SocketMessageType.DataRequest, type, requestID, result); bool sendResult = await Send(SocketMessageType.DataRequest, type, requestID, result);
if (!sendResult) if (!sendResult)
{ {
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(DataRequestHandler) + ": " + sendResult, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(DataRequestHandler) + ": " + sendResult, InvokeMessageType.Error);
} }
return sendResult; return sendResult;
} }
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(DataRequestHandler) + ": " + false, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(DataRequestHandler) + ": " + false, InvokeMessageType.Error);
return false; return false;
} }
@ -169,7 +178,7 @@ namespace Milimoe.FunGame.Server.Model
requestID = obj.GetParam<Guid>(1); requestID = obj.GetParam<Guid>(1);
Dictionary<string, object> data = obj.GetParam<Dictionary<string, object>>(2) ?? []; Dictionary<string, object> data = obj.GetParam<Dictionary<string, object>>(2) ?? [];
result = await NowGamingServer.GamingMessageHandler(_username, type, data); result = await NowGamingServer.GamingMessageHandler(this, type, data);
} }
catch (Exception e) catch (Exception e)
{ {
@ -181,12 +190,12 @@ namespace Milimoe.FunGame.Server.Model
bool sendResult = await Send(SocketMessageType.GamingRequest, type, requestID, result); bool sendResult = await Send(SocketMessageType.GamingRequest, type, requestID, result);
if (!sendResult) if (!sendResult)
{ {
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(GamingRequestHandler) + ": " + sendResult, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(GamingRequestHandler) + ": " + sendResult, InvokeMessageType.Error);
} }
return sendResult; return sendResult;
} }
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(GamingRequestHandler) + ": " + false, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(GamingRequestHandler) + ": " + false, InvokeMessageType.Error);
return false; return false;
} }
@ -204,7 +213,7 @@ namespace Milimoe.FunGame.Server.Model
type = obj.GetParam<GamingType>(0); type = obj.GetParam<GamingType>(0);
Dictionary<string, object> data = obj.GetParam<Dictionary<string, object>>(1) ?? []; Dictionary<string, object> data = obj.GetParam<Dictionary<string, object>>(1) ?? [];
result = await NowGamingServer.GamingMessageHandler(_username, type, data); result = await NowGamingServer.GamingMessageHandler(this, type, data);
} }
catch (Exception e) catch (Exception e)
{ {
@ -216,12 +225,71 @@ namespace Milimoe.FunGame.Server.Model
bool sendResult = await Send(SocketMessageType.Gaming, type, result); bool sendResult = await Send(SocketMessageType.Gaming, type, result);
if (!sendResult) if (!sendResult)
{ {
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(GamingMessageHandler) + ": " + sendResult, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(GamingMessageHandler) + ": " + sendResult, InvokeMessageType.Error);
} }
return sendResult; return sendResult;
} }
ServerHelper.WriteLine("[ " + _username + " ] " + nameof(GamingMessageHandler) + ": " + false, InvokeMessageType.Error); ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(GamingMessageHandler) + ": " + false, InvokeMessageType.Error);
return false;
}
protected async Task<bool> AnonymousGameServerHandler(SocketObject obj)
{
string serverName = "";
Dictionary<string, object> data = [];
Dictionary<string, object> result = [];
if (obj.Parameters.Length > 0) serverName = obj.GetParam<string>(0) ?? "";
if (obj.Parameters.Length > 1) data = obj.GetParam<Dictionary<string, object>>(1) ?? [];
bool willSend = false;
if (NowGamingServer != null)
{
try
{
result = await NowGamingServer.AnonymousGameServerHandler(this, data);
willSend = true;
}
catch (Exception e)
{
ServerHelper.Error(e);
return await Send(SocketMessageType.AnonymousGameServer, result);
}
}
else
{
// 建立连接
if (Config.GameModuleLoader != null && Config.GameModuleLoader.ModuleServers.ContainsKey(serverName))
{
GameModuleServer mod = Config.GameModuleLoader.GetServerMode(serverName);
if (mod.StartAnonymousServer(this, data))
{
NowGamingServer = mod;
try
{
result = await NowGamingServer.AnonymousGameServerHandler(this, data);
willSend = true;
}
catch (Exception e)
{
ServerHelper.Error(e);
return await Send(SocketMessageType.AnonymousGameServer, result);
}
}
}
}
if (willSend)
{
bool sendResult = await Send(SocketMessageType.AnonymousGameServer, result);
if (!sendResult)
{
ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(AnonymousGameServerHandler) + ": " + sendResult, InvokeMessageType.Error);
}
return sendResult;
}
ServerHelper.WriteLine("[ " + GetClientName() + " ] " + nameof(AnonymousGameServerHandler) + ": " + false, InvokeMessageType.Error);
return false; return false;
} }

View File

@ -8,6 +8,36 @@ namespace Milimoe.FunGame.Server.Others
{ {
public static class Config public static class Config
{ {
/// <summary>
/// 使用 ASP.NET Core Web API
/// </summary>
public static bool AspNetCore { get; set; } = false;
/// <summary>
/// 日志级别
/// </summary>
public static string LogLevel { get; set; } = "INFO";
/// <summary>
/// 日志级别(枚举值)
/// </summary>
public static LogLevel LogLevelValue
{
get
{
return LogLevel.ToUpper() switch
{
"TRACE" => Core.Library.Constant.LogLevel.Trace,
"DEBUG" => Core.Library.Constant.LogLevel.Debug,
"INFO" => Core.Library.Constant.LogLevel.Info,
"WARN" => Core.Library.Constant.LogLevel.Warning,
"ERROR" => Core.Library.Constant.LogLevel.Error,
"CRIT" => Core.Library.Constant.LogLevel.Critical,
_ => Core.Library.Constant.LogLevel.Info
};
}
}
/// <summary> /// <summary>
/// 服务器名称 /// 服务器名称
/// </summary> /// </summary>

View File

@ -93,7 +93,7 @@ namespace Milimoe.FunGame.Server.Others
List<string> supported = []; List<string> supported = [];
// 构建AddonController // 构建AddonController
Dictionary<string, object> delegates = []; Dictionary<string, object> delegates = [];
delegates.Add("WriteLine", new Action<string>(msg => ServerHelper.WriteLine(msg, InvokeMessageType.GameModule))); delegates.Add("WriteLine", new Action<string, string, LogLevel, bool>((name, msg, level, useLevel) => ServerHelper.WriteLine_Addons(name, msg, InvokeMessageType.GameModule, level, useLevel)));
delegates.Add("Error", new Action<Exception>(ServerHelper.Error)); delegates.Add("Error", new Action<Exception>(ServerHelper.Error));
// 读取modules目录下的模组 // 读取modules目录下的模组
try try
@ -107,12 +107,13 @@ namespace Milimoe.FunGame.Server.Others
// 检查模组是否有相对应的地图 // 检查模组是否有相对应的地图
if (!Config.GameModuleLoader.Maps.ContainsKey(module.DefaultMap)) if (!Config.GameModuleLoader.Maps.ContainsKey(module.DefaultMap))
{ {
ServerHelper.WriteLine("GameModule Load Failed: " + module + " 没有找到相对应的地图,加载失败", InvokeMessageType.Error); ServerHelper.WriteLine("GameModule Load Failed: " + module.Name + " 没有找到相对应的地图,加载失败", InvokeMessageType.Error);
check = false; check = false;
} }
if (check) if (check)
{ {
supported.Add(module.Name); if (!module.IsAnonymous) supported.Add(module.Name);
ServerHelper.WriteLine("Loaded: " + module.Name, InvokeMessageType.GameModule);
} }
} }
catch (Exception e) catch (Exception e)
@ -127,10 +128,6 @@ namespace Milimoe.FunGame.Server.Others
} }
// 设置全局 // 设置全局
Config.GameModuleSupported = supported.Distinct().ToArray(); Config.GameModuleSupported = supported.Distinct().ToArray();
foreach (string modename in Config.GameModuleSupported)
{
ServerHelper.WriteLine("Loaded: " + modename, InvokeMessageType.GameModule);
}
return Config.GameModuleSupported.Length > 0; return Config.GameModuleSupported.Length > 0;
} }
@ -141,7 +138,7 @@ namespace Milimoe.FunGame.Server.Others
public static void GetServerPlugins() public static void GetServerPlugins()
{ {
Dictionary<string, object> delegates = []; Dictionary<string, object> delegates = [];
delegates.Add("WriteLine", new Action<string>(msg => ServerHelper.WriteLine(msg, InvokeMessageType.Plugin))); delegates.Add("WriteLine", new Action<string, string, LogLevel, bool>((name, msg, level, useLevel) => ServerHelper.WriteLine_Addons(name, msg, InvokeMessageType.Plugin, level, useLevel)));
delegates.Add("Error", new Action<Exception>(ServerHelper.Error)); delegates.Add("Error", new Action<Exception>(ServerHelper.Error));
try try
{ {
@ -164,7 +161,7 @@ namespace Milimoe.FunGame.Server.Others
public static void GetWebAPIPlugins() public static void GetWebAPIPlugins()
{ {
Dictionary<string, object> delegates = []; Dictionary<string, object> delegates = [];
delegates.Add("WriteLine", new Action<string>(msg => ServerHelper.WriteLine(msg, InvokeMessageType.Plugin))); delegates.Add("WriteLine", new Action<string, string, LogLevel, bool>((name, msg, level, useLevel) => ServerHelper.WriteLine_Addons(name, msg, InvokeMessageType.Plugin, level, useLevel)));
delegates.Add("Error", new Action<Exception>(ServerHelper.Error)); delegates.Add("Error", new Action<Exception>(ServerHelper.Error));
try try
{ {

View File

@ -17,7 +17,7 @@ namespace Milimoe.FunGame.Server.Utility
Console.ResetColor(); Console.ResetColor();
} }
public static string GetPrefix(InvokeMessageType type) public static string GetPrefix(InvokeMessageType type, LogLevel level, string addon = "")
{ {
string prefix; string prefix;
switch (type) switch (type)
@ -61,28 +61,69 @@ namespace Milimoe.FunGame.Server.Utility
prefix = "[System] "; prefix = "[System] ";
break; break;
} }
string levelPrefix = CommonSet.GetLogLevelPrefix(level);
DateTime now = DateTime.Now; DateTime now = DateTime.Now;
return now.AddMilliseconds(-now.Millisecond).ToString() + " " + prefix + Config.ServerName + ""; return now.AddMilliseconds(-now.Millisecond).ToString() + " " + levelPrefix + prefix + (addon.Trim() != "" ? addon : Config.ServerName) + "";
} }
public static void Error(Exception e) public static void Error(Exception e)
{ {
Console.WriteLine("\r" + GetPrefix(InvokeMessageType.Error) + e.Message + "\n" + e.StackTrace); Console.WriteLine("\r" + GetPrefix(InvokeMessageType.Error, LogLevel.Error) + e.Message + "\n" + e.StackTrace);
Console.ResetColor(); Type();
Console.Write("\r> ");
} }
public static void Write(string msg, InvokeMessageType type = InvokeMessageType.System) public static void Write(string msg, InvokeMessageType type = InvokeMessageType.System, LogLevel level = LogLevel.Info, bool useLevel = true)
{ {
if (msg.Trim() != "") Console.Write("\r" + GetPrefix(type) + msg + "> "); if (type == InvokeMessageType.Warning)
Console.ResetColor(); {
level = LogLevel.Warning;
}
if (type == InvokeMessageType.Error)
{
level = LogLevel.Error;
}
if (!useLevel || (useLevel && (int)level >= (int)Config.LogLevelValue))
{
if (msg.Trim() != "") Console.Write("\r" + GetPrefix(type, level) + msg + "> ");
Console.ResetColor();
}
else Type();
} }
public static void WriteLine(string msg, InvokeMessageType type = InvokeMessageType.System) public static void WriteLine(string msg, InvokeMessageType type = InvokeMessageType.System, LogLevel level = LogLevel.Info, bool useLevel = true)
{ {
if (msg.Trim() != "") Console.WriteLine("\r" + GetPrefix(type) + msg); if (type == InvokeMessageType.Warning)
Console.ResetColor(); {
Console.Write("\r> "); level = LogLevel.Warning;
}
if (type == InvokeMessageType.Error)
{
level = LogLevel.Error;
}
if (!useLevel || ((int)level >= (int)Config.LogLevelValue))
{
if (msg.Trim() != "") Console.WriteLine("\r" + GetPrefix(type, level) + msg);
}
Type();
}
public static void WriteLine_Addons(string addon, string msg, InvokeMessageType type = InvokeMessageType.System, LogLevel level = LogLevel.Info, bool useLevel = true)
{
if (type == InvokeMessageType.Warning)
{
level = LogLevel.Warning;
}
if (type == InvokeMessageType.Error)
{
level = LogLevel.Error;
}
if (!useLevel || ((int)level >= (int)Config.LogLevelValue))
{
if (msg.Trim() != "") Console.WriteLine("\r" + GetPrefix(type, level, addon) + msg);
}
Type();
} }
public static void Type() public static void Type()
@ -106,9 +147,10 @@ namespace Milimoe.FunGame.Server.Utility
Hashtable settings = []; Hashtable settings = [];
if (INIHelper.ExistINIFile()) if (INIHelper.ExistINIFile())
{ {
settings.Add("LogLevel", INIHelper.ReadINI("Console", "LogLevel"));
settings.Add("Name", INIHelper.ReadINI("Server", "Name")); settings.Add("Name", INIHelper.ReadINI("Server", "Name"));
settings.Add("Password", INIHelper.ReadINI("Server", "Password")); settings.Add("Password", INIHelper.ReadINI("Server", "Password"));
settings.Add("Describe", INIHelper.ReadINI("Server", "Describe")); settings.Add("Description", INIHelper.ReadINI("Server", "Description"));
settings.Add("Notice", INIHelper.ReadINI("Server", "Notice")); settings.Add("Notice", INIHelper.ReadINI("Server", "Notice"));
settings.Add("Key", INIHelper.ReadINI("Server", "Key")); settings.Add("Key", INIHelper.ReadINI("Server", "Key"));
settings.Add("Status", Convert.ToInt32(INIHelper.ReadINI("Server", "Status"))); settings.Add("Status", Convert.ToInt32(INIHelper.ReadINI("Server", "Status")));
@ -134,16 +176,20 @@ namespace Milimoe.FunGame.Server.Utility
Hashtable settings = GetServerSettingHashtable(); Hashtable settings = GetServerSettingHashtable();
if (settings != null) if (settings != null)
{ {
string? LogLevel = (string?)settings["LogLevel"];
if (LogLevel != null) Config.LogLevel = LogLevel;
string? Name = (string?)settings["Name"]; string? Name = (string?)settings["Name"];
string? Password = (string?)settings["Password"]; string? Password = (string?)settings["Password"];
string? Describe = (string?)settings["Describe"]; string? Description = (string?)settings["Description"];
string? Notice = (string?)settings["Notice"]; string? Notice = (string?)settings["Notice"];
string? Key = (string?)settings["Key"]; string? Key = (string?)settings["Key"];
string? BannedList = (string?)settings["BannedList"]; string? BannedList = (string?)settings["BannedList"];
if (Name != null) Config.ServerName = Name; if (Name != null) Config.ServerName = Name;
if (Password != null) Config.ServerPassword = Password; if (Password != null) Config.ServerPassword = Password;
if (Describe != null) Config.ServerDescription = Describe; if (Description != null) Config.ServerDescription = Description;
if (Notice != null) Config.ServerNotice = Notice; if (Notice != null) Config.ServerNotice = Notice;
if (Key != null) Config.ServerKey = Key; if (Key != null) Config.ServerKey = Key;
if (BannedList != null) Config.ServerBannedList = BannedList.Split(',').Select(s => s.Trim()).ToList(); if (BannedList != null) Config.ServerBannedList = BannedList.Split(',').Select(s => s.Trim()).ToList();
@ -174,6 +220,7 @@ namespace Milimoe.FunGame.Server.Utility
if (MaxPlayer != null) Config.MaxPlayers = (int)MaxPlayer; if (MaxPlayer != null) Config.MaxPlayers = (int)MaxPlayer;
if (MaxConnectFailed != null) Config.MaxConnectionFaileds = (int)MaxConnectFailed; if (MaxConnectFailed != null) Config.MaxConnectionFaileds = (int)MaxConnectFailed;
} }
WriteLine($"当前输出的日志级别为:{Config.LogLevelValue}", useLevel: false);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -51,6 +51,21 @@ namespace Milimoe.FunGame.WebAPI.Models
return false; return false;
} }
if (type == SocketMessageType.EndGame)
{
if (NowGamingServer != null && NowGamingServer.IsAnonymous)
{
NowGamingServer.CloseAnonymousServer(this);
}
NowGamingServer = null;
return true;
}
if (type == SocketMessageType.AnonymousGameServer)
{
return await AnonymousGameServerHandler(obj);
}
if (type == SocketMessageType.DataRequest) if (type == SocketMessageType.DataRequest)
{ {
return await DataRequestHandler(obj); return await DataRequestHandler(obj);

View File

@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.Logging.Console;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
@ -27,8 +28,24 @@ try
{ {
Console.Title = Config.ServerName; Console.Title = Config.ServerName;
Console.WriteLine(FunGameInfo.GetInfo(Config.FunGameType)); Console.WriteLine(FunGameInfo.GetInfo(Config.FunGameType));
Config.AspNetCore = true;
ServerHelper.WriteLine("正在读取配置文件并初始化服务 . . ."); ServerHelper.WriteLine("正在读取配置文件并初始化服务 . . .");
// 检查是否存在配置文件
if (!INIHelper.ExistINIFile())
{
ServerHelper.WriteLine("未检测到配置文件,将自动创建配置文件 . . .");
INIHelper.Init(Config.FunGameType);
ServerHelper.WriteLine("配置文件FunGame.ini创建成功请修改该配置文件然后重启服务器。");
Console.ReadKey();
return;
}
else
{
ServerHelper.GetServerSettings();
}
// 初始化命令菜单 // 初始化命令菜单
ServerHelper.InitOrderList(); ServerHelper.InitOrderList();
@ -50,20 +67,6 @@ try
// 读取Web API插件 // 读取Web API插件
FunGameSystem.GetWebAPIPlugins(); FunGameSystem.GetWebAPIPlugins();
// 检查是否存在配置文件
if (!INIHelper.ExistINIFile())
{
ServerHelper.WriteLine("未检测到配置文件,将自动创建配置文件 . . .");
INIHelper.Init(Config.FunGameType);
ServerHelper.WriteLine("配置文件FunGame.ini创建成功请修改该配置文件然后重启服务器。");
Console.ReadKey();
return;
}
else
{
ServerHelper.GetServerSettings();
}
// 创建单例 // 创建单例
RESTfulAPIListener apiListener = new(); RESTfulAPIListener apiListener = new();
RESTfulAPIListener.Instance = apiListener; RESTfulAPIListener.Instance = apiListener;
@ -165,6 +168,11 @@ try
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"] ?? "undefined")) IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"] ?? "undefined"))
}; };
}).AddScheme<AuthenticationSchemeOptions, CustomBearerAuthenticationHandler>("CustomBearer", options => { }); }).AddScheme<AuthenticationSchemeOptions, CustomBearerAuthenticationHandler>("CustomBearer", options => { });
builder.Logging.AddConsole(options =>
{
options.FormatterName = "CustomFormatter";
});
builder.Services.AddSingleton<ConsoleFormatter, CustomConsoleFormatter>();
WebApplication app = builder.Build(); WebApplication app = builder.Build();

View File

@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
namespace Milimoe.FunGame.WebAPI.Architecture namespace Milimoe.FunGame.WebAPI.Services
{ {
public class CustomBearerAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder) : AuthenticationHandler<AuthenticationSchemeOptions>(options, logger, encoder) public class CustomBearerAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder) : AuthenticationHandler<AuthenticationSchemeOptions>(options, logger, encoder)
{ {

View File

@ -0,0 +1,39 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console;
namespace Milimoe.FunGame.WebAPI.Services
{
public class CustomConsoleFormatter() : ConsoleFormatter("CustomFormatter")
{
public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider? scopeProvider, TextWriter textWriter)
{
string message = logEntry.Formatter(logEntry.State, logEntry.Exception);
string level = logEntry.LogLevel.ToString()[..1].ToUpper();
string category = logEntry.Category.Split('.')[^1];
string colorLevel = GetColorCode(logEntry.LogLevel);
DateTime now = DateTime.Now;
string timestamp = now.AddMilliseconds(-now.Millisecond).ToString();
if ((int)logEntry.LogLevel >= (int)Server.Others.Config.LogLevelValue)
{
textWriter.Write("\r");
textWriter.WriteLine($"{colorLevel}{timestamp} {level}/[{category}] {message}");
}
textWriter.Write("\x1b[0m\r> ");
}
private static string GetColorCode(LogLevel logLevel)
{
return logLevel switch
{
LogLevel.Trace => "\x1b[37m", // 灰色 ConsoleColor.Gray
LogLevel.Debug => "\x1b[34m", // 蓝色 ConsoleColor.Blue
LogLevel.Information => "\x1b[32m", // 绿色 ConsoleColor.Green
LogLevel.Warning => "\x1b[33m", // 黄色 ConsoleColor.Yellow
LogLevel.Error => "\x1b[31m", // 红色 ConsoleColor.Red
LogLevel.Critical => "\x1b[31m", // 红色 ConsoleColor.Red
_ => "\x1b[0m" // 重置颜色
};
}
}
}