Better LoggerService

This commit is contained in:
Evil Factory
2026-02-09 19:51:31 -03:00
parent 64831bd580
commit a61e705dbf
4 changed files with 128 additions and 123 deletions

View File

@@ -1052,6 +1052,7 @@ namespace Barotrauma
SoundManager?.Update();
LuaCs.EventService.PublishEvent<IEventUpdate>(sub => sub.OnUpdate(Timing.Step));
LuaCs.Logger.ProcessLogs();
Timing.Accumulator -= Timing.Step;

View File

@@ -365,6 +365,8 @@ namespace Barotrauma
CoroutineManager.Update(paused: false, (float)Timing.Step);
LuaCs.EventService.PublishEvent<IEventUpdate>(sub => sub.OnUpdate(Timing.Step));
LuaCs.Logger.ProcessLogs();
performanceCounterTimer.Stop();
if (GameMain.LuaCs.PerformanceCounter.EnablePerformanceCounter)
{

View File

@@ -1,9 +1,11 @@
using System;
using System.Linq;
using Barotrauma.Networking;
using Barotrauma.Networking;
using FluentResults;
using HarmonyLib;
using Microsoft.Xna.Framework;
using MoonSharp.Interpreter;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace Barotrauma.LuaCs;
@@ -11,18 +13,118 @@ public partial class LoggerService : ILoggerService
{
public bool HideUserNames = true;
#if SERVER
private const string LogPrefix = "SV";
private const int NetMaxLength = 1024; // character limit of vanilla Barotrauma's chat system.
private const int NetMaxMessages = 60;
private List<ILoggerSubscriber> logSubscribers = [];
private ConcurrentQueue<PendingLog> logQueue = [];
// This is used so it's possible to call logging functions inside the serverLog
// hook without creating an infinite loop
private bool _lockLog = false;
#if SERVER
private const string TargetPrefix = "[SV]";
private const int NetMaxLength = 1024; // character limit of vanilla Barotrauma's chat system.
private const int NetMaxMessages = 60;
// This is used so it's possible to call logging functions inside the serverLog
// hook without creating an infinite loop
private bool _isInsideLogCall = false;
#else
private const string LogPrefix = "CL";
private const string TargetPrefix = "[CL]";
#endif
public LoggerService() { }
public void Subscribe(ILoggerSubscriber subscriber)
{
logSubscribers.Add(subscriber);
}
public void Unsubscribe(ILoggerSubscriber subscriber)
{
logSubscribers.Remove(subscriber);
}
public void ProcessLogs()
{
while (logQueue.TryDequeue(out PendingLog log))
{
logSubscribers.ForEach(s => s.OnLog(log));
DebugConsole.NewMessage(log.Message, log.Color);
#if SERVER
if (GameMain.Server != null)
{
if (GameMain.Server.ServerSettings.SaveServerLogs)
{
string logMessage = "[LuaCs] " + log.Message;
GameMain.Server.ServerSettings.ServerLog.WriteLine(logMessage, log.MessageType, false);
if (!_isInsideLogCall)
{
_isInsideLogCall = true;
GameMain.LuaCs?.Hook?.Call("serverLog", logMessage, log.MessageType);
_isInsideLogCall = false;
}
}
for (int i = 0; i < log.Message.Length; i += NetMaxLength)
{
string subStr = log.Message.Substring(i, Math.Min(1024, log.Message.Length - i));
BroadcastMessage(subStr);
}
}
void BroadcastMessage(string m)
{
foreach (var client in GameMain.Server.ConnectedClients)
{
ChatMessage consoleMessage = ChatMessage.Create("", m, ChatMessageType.Console, null, textColor: log.Color);
GameMain.Server.SendDirectChatMessage(consoleMessage, client);
if (!GameMain.Server.ServerSettings.SaveServerLogs || !client.HasPermission(ClientPermissions.ServerLog))
{
continue;
}
ChatMessage logMessage = ChatMessage.Create(log.MessageType.ToString(), "[LuaCs] " + m, ChatMessageType.ServerLog, null);
GameMain.Server.SendDirectChatMessage(logMessage, client);
}
}
#endif
}
}
public void Log(string message, Color? color = null, ServerLog.MessageType messageType = ServerLog.MessageType.ServerMessage)
{
if (HideUserNames && !Environment.UserName.IsNullOrEmpty())
{
message = message.Replace(Environment.UserName, "USERNAME");
}
message = $"{TargetPrefix} {message}";
logQueue.Enqueue(new PendingLog(message, color, messageType));
}
public void LogError(string message)
{
Log($"{message}", Color.Red, ServerLog.MessageType.Error);
}
public void LogWarning(string message)
{
Log($"{message}", Color.Yellow, ServerLog.MessageType.ServerMessage);
}
public void LogMessage(string message, Color? serverColor = null, Color? clientColor = null)
{
serverColor ??= Color.MediumPurple;
clientColor ??= Color.Purple;
#if SERVER
Log(message, serverColor);
#else
Log(message, clientColor);
#endif
}
public void HandleException(Exception exception, string prefix = null)
{
string errorString = "";
@@ -54,120 +156,10 @@ public partial class LoggerService : ILoggerService
errorString = $"{prefix ?? ""}{s}";
break;
}
LogError(prefix + Environment.UserName + " " + errorString);
}
public void LogError(string message)
{
Log($"{message}", Color.Red, ServerLog.MessageType.Error);
}
public void LogWarning(string message)
{
Log($"{message}", Color.Yellow, ServerLog.MessageType.ServerMessage);
}
public void LogMessage(string message, Color? serverColor = null, Color? clientColor = null)
{
serverColor ??= Color.MediumPurple;
clientColor ??= Color.Purple;
#if SERVER
Log(message, serverColor);
#else
Log(message, clientColor);
#endif
}
public void Log(string message, Color? color = null, ServerLog.MessageType messageType = ServerLog.MessageType.ServerMessage)
{
// TODO: Make this thread Async compatible.
if (HideUserNames && !Environment.UserName.IsNullOrEmpty())
{
message = message.Replace(Environment.UserName, "USERNAME");
}
DebugConsole.NewMessage(message, color);
#if SERVER
void BroadcastMessage(string m)
{
foreach (var client in GameMain.Server.ConnectedClients)
{
ChatMessage consoleMessage = ChatMessage.Create("", m, ChatMessageType.Console, null, textColor: color);
GameMain.Server.SendDirectChatMessage(consoleMessage, client);
if (!GameMain.Server.ServerSettings.SaveServerLogs || !client.HasPermission(ClientPermissions.ServerLog))
{
continue;
}
ChatMessage logMessage = ChatMessage.Create(messageType.ToString(), "[LuaCs] " + m, ChatMessageType.ServerLog, null);
GameMain.Server.SendDirectChatMessage(logMessage, client);
}
}
if (GameMain.Server != null)
{
if (GameMain.Server.ServerSettings.SaveServerLogs)
{
string logMessage = "[LuaCs] " + message;
GameMain.Server.ServerSettings.ServerLog.WriteLine(logMessage, messageType, false);
if (!_lockLog)
{
_lockLog = true;
GameMain.LuaCs?.Hook?.Call("serverLog", logMessage, messageType);
_lockLog = false;
}
}
for (int i = 0; i < message.Length; i += NetMaxLength)
{
string subStr = message.Substring(i, Math.Min(1024, message.Length - i));
BroadcastMessage(subStr);
}
}
#endif
}
public void HandleException(Exception ex)
{
string errorString = "";
switch (ex)
{
case NetRuntimeException netRuntimeException:
if (netRuntimeException.DecoratedMessage == null)
{
errorString = netRuntimeException.ToString();
}
else
{
// FIXME: netRuntimeException.ToString() doesn't print the InnerException's stack trace...
errorString = $"{netRuntimeException.DecoratedMessage}: {netRuntimeException}";
}
break;
case InterpreterException interpreterException:
if (interpreterException.DecoratedMessage == null)
{
errorString = interpreterException.ToString();
}
else
{
errorString = interpreterException.DecoratedMessage;
}
break;
default:
errorString = ex.StackTrace != null
? ex.ToString()
: $"{ex}\n{Environment.StackTrace}";
break;
}
LogError(errorString);
}
public void LogResults(FluentResults.Result result)
{

View File

@@ -5,11 +5,21 @@ using Microsoft.Xna.Framework;
namespace Barotrauma.LuaCs;
public readonly record struct PendingLog(string Message, Color? Color, ServerLog.MessageType MessageType);
public interface ILoggerSubscriber
{
void OnLog(PendingLog pendingLog);
}
/// <summary>
/// Provides console and debug logging services
/// </summary>
public interface ILoggerService : IReusableService
{
void Subscribe(ILoggerSubscriber subscriber);
void Unsubscribe(ILoggerSubscriber subscriber);
void ProcessLogs();
void HandleException(Exception exception, string prefix = null);
void LogError(string message);
void LogWarning(string message);