using System; using System.Collections.Generic; using UnityEngine; namespace Webserver { public class LogBuffer { private const int maxEntries = 3000; private static LogBuffer instance; private readonly List logEntries = new List (); private int listOffset; public static void Init () { instance ??= new LogBuffer (); } private LogBuffer () { Log.LogCallbacksExtended += LogCallback; } public static LogBuffer Instance => instance ??= new LogBuffer (); public int OldestLine { get { lock (logEntries) { return listOffset; } } } public int LatestLine { get { lock (logEntries) { return listOffset + logEntries.Count - 1; } } } public int StoredLines { get { lock (logEntries) { return logEntries.Count; } } } public LogEntry this [int _index] { get { lock (logEntries) { if (_index >= listOffset && _index < listOffset + logEntries.Count) { return logEntries [_index]; } } return null; } } private void LogCallback (string _formattedMsg, string _plainMsg, string _trace, LogType _type, DateTime _timestamp, long _uptime) { LogEntry le = new LogEntry (_timestamp, _plainMsg, _trace, _type, _uptime); lock (logEntries) { logEntries.Add (le); if (logEntries.Count <= maxEntries) { return; } listOffset += logEntries.Count - maxEntries; logEntries.RemoveRange (0, logEntries.Count - maxEntries); } } private readonly List emptyList = new List (); public List GetRange (ref int _start, int _count, out int _end) { lock (logEntries) { int index; if (_count < 0) { _count = -_count; if (_start >= listOffset + logEntries.Count) { _start = listOffset + logEntries.Count - 1; } _end = _start; if (_start < listOffset) { return emptyList; } _start -= _count - 1; if (_start < listOffset) { _start = listOffset; } index = _start - listOffset; _end += 1; _count = _end - _start; } else { if (_start < listOffset) { _start = listOffset; } if (_start >= listOffset + logEntries.Count) { _end = _start; return emptyList; } index = _start - listOffset; if (index + _count > logEntries.Count) { _count = logEntries.Count - index; } _end = _start + _count; } return logEntries.GetRange (index, _count); } } public class LogEntry { public readonly DateTime Timestamp; public readonly string IsoTime; public readonly string Message; public readonly string Trace; public readonly LogType Type; public readonly long Uptime; public LogEntry (DateTime _timestamp, string _message, string _trace, LogType _type, long _uptime) { Timestamp = _timestamp; IsoTime = _timestamp.ToString ("o"); Message = _message; Trace = _trace; Type = _type; Uptime = _uptime; } } } }