Introduce the LuaCsLogger class and make everything use that instead

This commit is contained in:
EvilFactory
2022-12-28 16:01:48 -03:00
parent 5807900556
commit 8fdf2156dc
16 changed files with 168 additions and 151 deletions
@@ -13,136 +13,159 @@ namespace Barotrauma
CSharpMod,
}
internal delegate void LuaCsMessageLogger(string prefix, object o);
internal delegate void LuaCsExceptionHandler(Exception ex, LuaCsMessageOrigin origin);
// TODO: make it a separate class
partial class LuaCsSetup
class LuaCsLogger
{
#if SERVER
private const string LOG_PREFIX = "SV";
private const string LogPrefix = "SV";
private const int NetMaxLength = 1024;
private const int NetMaxMessages = 60;
#else
private const string LOG_PREFIX = "CL";
private const string LogPrefix = "CL";
#endif
public static void PrintLuaError(object o) => PrintErrorBase($"[{LOG_PREFIX} LUA ERROR] ", o, "nil");
public static void PrintCsError(object o) => PrintErrorBase($"[{LOG_PREFIX} CS ERROR] ", o, "Null");
public static void PrintGenericError(object o) => PrintErrorBase($"[{LOG_PREFIX} ERROR] ", o, "Null");
public static LuaCsMessageLogger MessageLogger;
public static LuaCsExceptionHandler ExceptionHandler;
private static void PrintErrorBase(string prefix, object message, string empty)
{
message ??= empty;
var str = message.ToString();
for (int i = 0; i < str.Length; i += 1024)
{
var subStr = str.Substring(i, Math.Min(1024, str.Length - i));
var errorMsg = subStr;
if (i == 0) errorMsg = prefix + errorMsg;
DebugConsole.ThrowError(errorMsg);
#if SERVER
if (GameMain.Server != null)
{
foreach (var c in GameMain.Server.ConnectedClients)
{
GameMain.Server.SendDirectChatMessage(ChatMessage.Create("", errorMsg, ChatMessageType.Console, null, textColor: Color.Red), c);
}
GameServer.Log(errorMsg, ServerLog.MessageType.Error);
}
#endif
}
}
// TODO: deprecate this (in an effort to get rid of as much global state as possible)
public void PrintError(object o, LuaCsMessageOrigin origin)
{
switch (origin)
{
case LuaCsMessageOrigin.LuaCs:
PrintGenericError(o);
break;
case LuaCsMessageOrigin.LuaMod:
PrintLuaError(o);
break;
case LuaCsMessageOrigin.CSharpMod:
PrintCsError(o);
break;
}
}
private void DefaultExceptionHandler(Exception ex, LuaCsMessageOrigin origin)
public static void HandleException(Exception ex, LuaCsMessageOrigin origin)
{
switch (ex)
{
case NetRuntimeException netRuntimeException:
if (netRuntimeException.DecoratedMessage == null)
{
PrintError(netRuntimeException, origin);
LogError(netRuntimeException.ToString(), origin);
}
else
{
// FIXME: netRuntimeException.ToString() doesn't print the InnerException's stack trace...
PrintError($"{netRuntimeException.DecoratedMessage}: {netRuntimeException}", origin);
LogError($"{netRuntimeException.DecoratedMessage}: {netRuntimeException}", origin);
}
break;
case InterpreterException interpreterException:
if (interpreterException.DecoratedMessage == null)
{
PrintError(interpreterException, origin);
LogError(interpreterException.ToString(), origin);
}
else
{
PrintError(interpreterException.DecoratedMessage, origin);
LogError(interpreterException.DecoratedMessage, origin);
}
break;
default:
var msg = ex.StackTrace != null
? ex.ToString()
: $"{ex}\n{Environment.StackTrace}";
PrintError(msg, origin);
LogError(msg, origin);
break;
}
}
private static void DefaultMessageLogger(string prefix, object o)
public static void LogError(string message, LuaCsMessageOrigin origin)
{
var message = o.ToString();
for (int i = 0; i < message.Length; i += 1024)
switch (origin)
{
var subStr = message.Substring(i, Math.Min(1024, message.Length - i));
#if SERVER
if (GameMain.Server != null)
{
foreach (var c in GameMain.Server.ConnectedClients)
{
GameMain.Server.SendDirectChatMessage(ChatMessage.Create("", subStr, ChatMessageType.Console, null, textColor: Color.MediumPurple), c);
}
#if !DEBUG
GameServer.Log(prefix + subStr, ServerLog.MessageType.ServerMessage);
#endif
}
#endif
case LuaCsMessageOrigin.LuaCs:
LogError($"[{LogPrefix} ERROR] {message}");
break;
case LuaCsMessageOrigin.LuaMod:
LogError($"[{LogPrefix} LUA ERROR] {message}");
break;
case LuaCsMessageOrigin.CSharpMod:
LogError($"[{LogPrefix} CS ERROR] {message}");
break;
}
}
public static void LogError(string message)
{
Log($"{message}", Color.Red, ServerLog.MessageType.Error);
}
public static void LogMessage(string message, Color? serverColor = null, Color? clientColor = null)
{
if (serverColor == null) { serverColor = Color.MediumPurple; }
if (clientColor == null) { clientColor = Color.Purple; }
#if SERVER
DebugConsole.NewMessage(message.ToString(), Color.MediumPurple);
Log(message, serverColor);
#else
DebugConsole.NewMessage(message.ToString(), Color.Purple);
Log(message, clientColor);
#endif
}
private void PrintMessageBase(string prefix, object message, string empty) => MessageLogger?.Invoke(prefix, message ?? empty);
internal void PrintMessage(object message) => PrintMessageBase("[LuaCs] ", message, "nil");
// This is used so its possible to call logging functions inside the serverLog
// hook without creating an infinite loop
private static bool lockLog = false;
// TODO: deprecate this (in an effort to get rid of as much global state as possible)
public static void PrintCsMessage(object message) => GameMain.LuaCs.PrintMessage(message);
public static void Log(string message, Color? color = null, ServerLog.MessageType messageType = ServerLog.MessageType.ServerMessage)
{
MessageLogger?.Invoke(message);
DebugConsole.NewMessage(message, color);
#if SERVER
void broadcastMessage(string m)
{
foreach (var client in GameMain.Server.ConnectedClients)
{
//if (client.ChatMsgQueue.Count > NetMaxMessages)
//{
// If there's an error or message happening many times per second (inside Update loop for example)
// we will need to discart some messages so the client doesn't get overloaded by all
// those net messages.
// continue;
//}
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
}
partial class LuaCsSetup
{
// Compatibility with cs mods that use this method.
public void PrintLuaError(string message) => LuaCsLogger.LogError(message, LuaCsMessageOrigin.LuaMod);
public void PrintCsError(string message) => LuaCsLogger.LogError(message, LuaCsMessageOrigin.CSharpMod);
public void PrintGenericError(string message) => LuaCsLogger.LogError(message, LuaCsMessageOrigin.LuaCs);
internal void PrintMessage(string message) => LuaCsLogger.LogMessage(message);
public static void PrintCsMessage(string message) => LuaCsLogger.LogMessage(message);
internal void HandleException(Exception ex, LuaCsMessageOrigin origin) => LuaCsLogger.HandleException(ex, origin);
}
}
}