Files
CapySR/gui/Models.cs
T
2026-10-17 21:03:23 -07:00

169 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using System.Windows;
using System.Windows.Media;
namespace CapyLauncher
{
public enum Level { Debug, Info, Warn, Error }
public class LogLine
{
static readonly Regex Shape = new Regex(@"^(\d\d:\d\d:\d\d\.\d{3})\s+(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)\s+(\S+)\s+(.*)$", RegexOptions.Compiled);
static Brush Frozen(string hex)
{
var brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(hex));
brush.Freeze();
return brush;
}
static readonly Brush TextBrush = Frozen("#ECE3DA");
static readonly Brush DimBrush = Frozen("#9A8FA8");
static readonly Brush FaintBrush = Frozen("#6B6078");
static readonly Brush PinkBrush = Frozen("#FF9AA2");
static readonly Brush BlueBrush = Frozen("#7DC8FF");
static readonly Brush GreenBrush = Frozen("#9FE0A0");
static readonly Brush WarnBrush = Frozen("#FFD58A");
static readonly Brush FailBrush = Frozen("#FF6B7F");
static readonly Brush DebugBack = Frozen("#1A9A8FA8");
static readonly Brush InfoBack = Frozen("#1F7DC8FF");
static readonly Brush WarnBack = Frozen("#26FFD58A");
static readonly Brush FailBack = Frozen("#2EFF6B7F");
public string Time { get; private set; } = "";
public Level Kind { get; private set; } = Level.Info;
public string LevelName => Kind == CapyLauncher.Level.Debug ? "DEBUG" : Kind == CapyLauncher.Level.Warn ? "WARN" : Kind == CapyLauncher.Level.Error ? "ERROR" : "INFO";
public string Tag { get; private set; } = "";
public string Arrow { get; private set; } = "";
public string Message { get; private set; } = "";
public bool Continued { get; private set; }
public Visibility LevelVisibility => Continued ? Visibility.Hidden : Visibility.Visible;
public Brush LevelBrush => Kind == CapyLauncher.Level.Debug ? DimBrush : Kind == CapyLauncher.Level.Warn ? WarnBrush : Kind == CapyLauncher.Level.Error ? FailBrush : BlueBrush;
public Brush LevelBack => Kind == CapyLauncher.Level.Debug ? DebugBack : Kind == CapyLauncher.Level.Warn ? WarnBack : Kind == CapyLauncher.Level.Error ? FailBack : InfoBack;
public Brush TagBrush => Tag == "recv" || Tag == "send" ? FaintBrush : PinkBrush;
public Brush ArrowBrush => Tag == "recv" ? GreenBrush : BlueBrush;
public Brush MessageBrush => Continued ? DimBrush
: Kind == CapyLauncher.Level.Warn ? WarnBrush
: Kind == CapyLauncher.Level.Error ? FailBrush
: Kind == CapyLauncher.Level.Debug ? DimBrush : TextBrush;
public static LogLine Parse(string raw, LogLine previous)
{
Match match = Shape.Match(raw);
if (!match.Success)
{
return new LogLine
{
Kind = previous?.Kind ?? CapyLauncher.Level.Info,
Message = raw.Trim(),
Continued = true,
};
}
var line = new LogLine
{
Time = match.Groups[1].Value,
Kind = LevelOf(match.Groups[2].Value),
Tag = match.Groups[3].Value,
Message = match.Groups[4].Value,
};
if (line.Message.StartsWith("<- ") || line.Message.StartsWith("-> "))
{
line.Arrow = line.Message.StartsWith("<-") ? "← " : "→ ";
line.Message = line.Message.Substring(3);
}
return line;
}
static Level LevelOf(string name)
{
switch (name)
{
case "TRACE":
case "DEBUG": return CapyLauncher.Level.Debug;
case "WARN": return CapyLauncher.Level.Warn;
case "ERROR":
case "FATAL": return CapyLauncher.Level.Error;
default: return CapyLauncher.Level.Info;
}
}
public override string ToString() =>
Continued ? " " + Message : Time + " " + LevelName.PadRight(5) + " " + Tag + " " + Arrow + Message;
}
public class Settings
{
static readonly string Folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CapySR");
static readonly string FilePath = Path.Combine(Folder, "launcher.json");
public string ClientFolder { get; set; } = "";
public bool ShowDebug { get; set; }
public bool AutoScroll { get; set; } = true;
public string TextLanguage { get; set; } = "";
public static Settings Load()
{
try
{
if (File.Exists(FilePath))
return new JavaScriptSerializer().Deserialize<Settings>(File.ReadAllText(FilePath)) ?? new Settings();
}
catch (Exception) { }
return new Settings();
}
public void Save()
{
try
{
Directory.CreateDirectory(Folder);
File.WriteAllText(FilePath, new JavaScriptSerializer().Serialize(this));
}
catch (Exception) { }
}
}
public class ServerConfig
{
public string HttpHost { get; private set; } = "127.0.0.1";
public int HttpPort { get; private set; } = 21000;
public int GamePort { get; private set; } = 23301;
public string BattleSource { get; private set; } = "auto";
public string SrToolsFile { get; private set; } = "data/freesr-data.json";
public string Dispatch => "http://" + HttpHost + ":" + HttpPort;
public static ServerConfig Load(string root)
{
var config = new ServerConfig();
try
{
var doc = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(
File.ReadAllText(Path.Combine(root, "config", "config.json")));
if (doc.TryGetValue("gameplay", out object gameplay) && gameplay is Dictionary<string, object> play && play.TryGetValue("battle_source", out object source))
config.BattleSource = Convert.ToString(source);
if (doc.TryGetValue("paths", out object paths) && paths is Dictionary<string, object> p && p.TryGetValue("srtools_file", out object srtools))
config.SrToolsFile = Convert.ToString(srtools);
if (doc.TryGetValue("server", out object server) && server is Dictionary<string, object> s)
{
if (s.TryGetValue("http", out object http) && http is Dictionary<string, object> h)
{
if (h.TryGetValue("port", out object port)) config.HttpPort = Convert.ToInt32(port);
if (h.TryGetValue("public_host", out object host)) config.HttpHost = Convert.ToString(host);
}
if (s.TryGetValue("game", out object game) && game is Dictionary<string, object> g && g.TryGetValue("port", out object gamePort))
config.GamePort = Convert.ToInt32(gamePort);
}
}
catch (Exception) { }
return config;
}
}
}