using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace Island.StandardLib
{
///
/// 表示输出内容的等级
///
public enum LogLevel
{
///
/// 提示
///
Info,
///
/// 正常
///
Default,
///
/// 警告
///
Warning,
///
/// 错误
///
Error
}
internal class LogLine
{
internal string str;
internal LogLevel lvl;
}
public interface ILogger
{
void Write(string data);
void WriteLine(string data);
void SetForegroundColor(Color color);
void GetForegroundColor(ref Color color);
void ReadLine(ref string str);
}
public static class Logger
{
public static bool ShowInfo = true;
public static ILogger __Logger__;
public static bool ShowDefault = true;
public static bool ShowWarning = true;
static bool mainThread = false;
public static bool RunInMainThread
{
get
{
return mainThread;
}
set
{
mainThread = value;
if (value)
WriteLine(LogLevel.Warning, "已强制Logger使用单线程,这将影响服务器执行效率。");
else WriteLine(LogLevel.Warning, "已关闭强制Logger使用单线程。");
}
}
static StreamWriter writer;
static ConsoleColor srcColor;
static Color srcColor2;
static List lines;
public static void InitLoggerOnce(bool saveToFile = true, string fileName = null)
{
if (lines != null) return;
if (saveToFile)
{
if (writer != null) return;
string file = fileName ?? "log.txt";
writer = new StreamWriter(file, true, Encoding.UTF8);
}
if (__Logger__ == null)
srcColor = Console.ForegroundColor;
else __Logger__.GetForegroundColor(ref srcColor2);
lines = new List();
Thread thread = new Thread(Loop);
thread.IsBackground = true;
thread.Start();
}
static bool flushd;
public static void Flush()
{
flushd = false;
while (!flushd) { }
}
static void Loop()
{
while (true)
{
lock (lines)
{
for (int i = 0; i < lines.Count; i++)
{
if (i < 0) continue;
if (lines[i] != null)
writeInternal(lines[i].lvl, lines[i].str);
lines.RemoveAt(i);
i--;
}
}
flushd = true;
Thread.Sleep(1);
}
}
static void writeInternal(LogLevel level, string str)
{
string[] tline = str.Split('\n');
foreach (string t in tline)
{
string timeStr = "[" + DateTime.Now.ToString() + "] ";
string logStr = timeStr;
switch (level)
{
case LogLevel.Default:
logStr += "[Default] ";
break;
case LogLevel.Error:
logStr += "[Error] ";
break;
case LogLevel.Info:
logStr += "[Info] ";
break;
case LogLevel.Warning:
logStr += "[Warning] ";
break;
}
logStr += t;
if (level != LogLevel.Info)
{
writer?.WriteLine(logStr);
writer?.Flush();
}
if (__Logger__ == null)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Write(timeStr);
}
else
{
__Logger__.SetForegroundColor(Color.DarkGray);
__Logger__.Write(timeStr);
}
string writeStr = t;
switch (level)
{
case LogLevel.Default:
if (!ShowDefault) return;
if (__Logger__ == null)
Console.ForegroundColor = ConsoleColor.White;
else
__Logger__.SetForegroundColor(Color.White);
break;
case LogLevel.Error:
if (__Logger__ == null)
Console.ForegroundColor = ConsoleColor.Red;
else
__Logger__.SetForegroundColor(Color.Red);
break;
case LogLevel.Info:
if (!ShowInfo) return;
if (__Logger__ == null)
Console.ForegroundColor = ConsoleColor.DarkGray;
else
__Logger__.SetForegroundColor(Color.DarkGray);
break;
case LogLevel.Warning:
if (!ShowWarning) return;
if (__Logger__ == null)
Console.ForegroundColor = ConsoleColor.Yellow;
else
__Logger__.SetForegroundColor(Color.Yellow);
break;
}
if (__Logger__ == null)
{
Console.WriteLine(writeStr);
Console.ForegroundColor = srcColor;
}
else
{
__Logger__.WriteLine(writeStr);
__Logger__.SetForegroundColor(srcColor2);
}
}
}
public static void Log(LogLevel level, string str)
{
WriteLine(level, str);
}
public static void Log(string str)
{
WriteLine(str);
}
public static void Log(string str, params object[] cs)
{
WriteLine(str, cs);
}
public static void Log(LogLevel level, string str, params object[] cs)
{
WriteLine(level, str, cs);
}
public static void WriteLine(LogLevel level, string str)
{
if (mainThread)
{
writeInternal(level, str);
}
else
{
LogLine ll = new LogLine();
ll.lvl = level;
ll.str = str;
lock (lines)
lines.Add(ll);
}
}
public static void WriteLine(string str)
{
WriteLine(LogLevel.Default, str);
}
public static void WriteLine(string str, params object[] cs)
{
string c = str;
for (int i = 0; i < cs.Length; i++)
c = c.Replace("{" + i + "}", cs[i].ToString());
WriteLine(c);
}
public static void WriteLine(LogLevel level, string str, params object[] cs)
{
string c = str;
for (int i = 0; i < cs.Length; i++)
c = c.Replace("{" + i + "}", cs[i].ToString());
WriteLine(level, c);
}
public static void LogError(Exception e)
{
WriteLine(LogLevel.Error, e.ToString());
}
public static string ReadLine()
{
string cmd = null;
if (__Logger__ == null)
cmd = Console.ReadLine();
else __Logger__.ReadLine(ref cmd);
return cmd;
}
public static string ReadData(string helpText, string defValue = null)
{
string txt = helpText + (defValue == null ? "" : $"({defValue})") + "> ";
if (__Logger__ == null)
Console.Write(txt);
else __Logger__.Write(txt);
string dat = ReadLine();
return dat == "" ? defValue : dat;
}
public static T ReadData(string helpText, Func parseFunc)
{
while (true)
{
string data = ReadData(helpText);
try
{
return parseFunc(data);
}
catch
{
if (__Logger__ == null)
Console.WriteLine("Parse Error, Retry.");
else __Logger__.WriteLine("Parse Error, Retry.");
}
}
}
public static T ReadData(string helpText, Func parseFunc, string defValue)
{
while (true)
{
string data = ReadData(helpText, defValue);
try
{
return parseFunc(data);
}
catch
{
if (__Logger__ == null)
Console.WriteLine("Parse Error, Retry.");
else __Logger__.WriteLine("Parse Error, Retry.");
}
}
}
}
}