using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace Fusion {
[Serializable]
public partial class FusionUnityLogger : Fusion.ILogger {
///
/// Implement this to modify values of this logger.
///
///
static partial void InitializePartial(ref FusionUnityLogger logger);
StringBuilder _builder = new StringBuilder();
///
/// If true, all messages will be prefixed with [Fusion] tag
///
public bool UseGlobalPrefix;
///
/// If true, some parts of messages will be enclosed with <color> tags.
///
public bool UseColorTags;
///
/// Color of the global prefix (see ).
///
public string GlobalPrefixColor;
///
///
///
public Color32 MinRandomColor;
///
///
///
public Color32 MaxRandomColor;
public Color ServerColor;
///
/// Converts object to a color . By default works only for and uses and fields.
///
public Func GetColor { get; set; }
public FusionUnityLogger() {
bool isDarkMode = false;
#if UNITY_EDITOR
isDarkMode = UnityEditor.EditorGUIUtility.isProSkin;
#endif
MinRandomColor = isDarkMode ? new Color32(158, 158, 158, 255) : new Color32(30, 30, 30, 255);
MaxRandomColor = isDarkMode ? new Color32(255, 255, 255, 255) : new Color32(90, 90, 90, 255);
ServerColor = isDarkMode ? new Color32(255, 255, 158, 255) : new Color32(30, 90, 200, 255);
UseColorTags = true;
UseGlobalPrefix = true;
GlobalPrefixColor = Color32ToRGBString(isDarkMode ? new Color32(115, 172, 229, 255) : new Color32(20, 64, 120, 255));
GetColor = (obj) => {
if (obj is NetworkRunner runner) {
// flag server/host runners as special with seed of -1
var seed = runner.GetHashCodeForLogger();
return GetRandomColor(seed);
}
return default;
};
}
public void Log(LogType logType, string prefix, ref T context, string message) where T : ILogBuilder {
Debug.Assert(_builder.Length == 0);
string fullMessage;
try {
if (logType == LogType.Debug) {
_builder.Append("[DEBUG] ");
} else if (logType == LogType.Trace) {
_builder.Append("[TRACE] ");
}
if (UseGlobalPrefix) {
if (UseColorTags) {
_builder.Append("");
}
_builder.Append("[Fusion");
if (!string.IsNullOrEmpty(prefix)) {
_builder.Append("/");
_builder.Append(prefix);
}
_builder.Append("]");
if (UseColorTags) {
_builder.Append(" ");
}
_builder.Append(" ");
} else {
if (!string.IsNullOrEmpty(prefix)) {
_builder.Append(prefix);
_builder.Append(": ");
}
}
var options = new LogOptions(UseColorTags, GetColor);
context.BuildLogMessage(_builder, message, options);
fullMessage = _builder.ToString();
} finally {
_builder.Clear();
}
var obj = context as UnityEngine.Object;
switch (logType) {
case LogType.Error:
Debug.LogError(fullMessage, obj);
break;
case LogType.Warn:
Debug.LogWarning(fullMessage, obj);
break;
default:
Debug.Log(fullMessage, obj);
break;
}
}
public void LogException(string prefix, ref T context, Exception ex) where T : ILogBuilder {
Log(LogType.Error, string.Empty, ref context, $"{ex.GetType()}\nSee next error log entry for details. ");
if (context is UnityEngine.Object obj) {
Debug.LogException(ex, obj);
} else {
Debug.LogException(ex);
}
}
int GetRandomColor(int seed) => GetRandomColor(seed, MinRandomColor, MaxRandomColor, ServerColor);
static int GetRandomColor(int seed, Color32 min, Color32 max, Color32 svr) {
var random = new NetworkRNG(seed);
int r, g, b;
// -1 indicates host/client - give it a more pronounced color.
if (seed == -1) {
r = svr.r;
g = svr.g;
b = svr.b;
} else {
r = random.RangeInclusive(min.r, max.r);
g = random.RangeInclusive(min.g, max.g);
b = random.RangeInclusive(min.b, max.b);
}
r = Mathf.Clamp(r, 0, 255);
g = Mathf.Clamp(g, 0, 255);
b = Mathf.Clamp(b, 0, 255);
int rgb = (r << 16) | (g << 8) | b;
return rgb;
}
static int Color32ToRGB24(Color32 c) {
return (c.r << 16) | (c.g << 8) | c.b;
}
static string Color32ToRGBString(Color32 c) {
return string.Format("#{0:X6}", Color32ToRGB24(c));
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Initialize() {
if (Fusion.Log.Initialized) {
return;
}
var logger = new FusionUnityLogger();
// Optional override of default values
InitializePartial(ref logger);
if (logger != null) {
Fusion.Log.Init(logger);
}
}
}
}