Skip to content

Commit

Permalink
添加更详细的日志解析
Browse files Browse the repository at this point in the history
  • Loading branch information
YangSpring114 committed Apr 30, 2024
1 parent e1aeada commit 8341fed
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 36 deletions.
30 changes: 15 additions & 15 deletions MinecraftLaunch.Test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,27 @@

#region Optifine Install

GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
//GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");

VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.12.2", MirrorDownloadManager.Bmcl);
vanlliaInstaller.ProgressChanged += (_, args) => {
Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
};
//VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.12.2", MirrorDownloadManager.Bmcl);
//vanlliaInstaller.ProgressChanged += (_, args) => {
// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
//};

await vanlliaInstaller.InstallAsync();
//await vanlliaInstaller.InstallAsync();

Console.WriteLine();
//Console.WriteLine();

OptifineInstaller forgeInstaller = new(gameResolver.GetGameEntity("1.12.2"),
(await OptifineInstaller.EnumerableFromVersionAsync("1.12.2")).First(),
"C:\\Program Files\\Java\\jdk1.8.0_301\\bin\\javaw.exe",
"1.12.2-optifine-114514");
//OptifineInstaller optifineInstaller = new(gameResolver.GetGameEntity("1.12.2"),
// (await OptifineInstaller.EnumerableFromVersionAsync("1.12.2")).First(),
// "C:\\Program Files\\Java\\jdk1.8.0_301\\bin\\javaw.exe",
// "1.12.2-optifine-114514");

forgeInstaller.ProgressChanged += (_, args) => {
Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
};
//optifineInstaller.ProgressChanged += (_, args) => {
// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
//};

await forgeInstaller.InstallAsync();
//await optifineInstaller.InstallAsync();

#endregion

Expand Down
12 changes: 12 additions & 0 deletions MinecraftLaunch/Classes/Enums/LogType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace MinecraftLaunch.Classes.Enums;

public enum LogType {
Error = 1,
Info,
Debug,
Fatal,
Warning,
Exception,
StackTrace,
Unknown
}
10 changes: 8 additions & 2 deletions MinecraftLaunch/Classes/Models/Event/LogReceivedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
namespace MinecraftLaunch.Classes.Models.Event;
using MinecraftLaunch.Classes.Enums;
using MinecraftLaunch.Classes.Models.Game;

public sealed class LogReceivedEventArgs(string log) : EventArgs {
namespace MinecraftLaunch.Classes.Models.Event;

public sealed class LogReceivedEventArgs(string log, string time, string source, LogType logType) : EventArgs {
public string Text => log;
public string Time => time;
public string Source => source;
public LogType LogType => logType;
}
13 changes: 13 additions & 0 deletions MinecraftLaunch/Classes/Models/Game/GameLogEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using MinecraftLaunch.Classes.Enums;

namespace MinecraftLaunch.Classes.Models.Game;

public sealed record GameLogEntry {
public string Log { get; set; }

public string Time { get; set; }

public string Source { get; set; }

public LogType LogType { get; set; }
}
28 changes: 16 additions & 12 deletions MinecraftLaunch/Components/Checker/PreLaunchChecker.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
using MinecraftLaunch.Classes.Interfaces;
using MinecraftLaunch.Classes.Models.Game;

namespace MinecraftLaunch.Components.Checker {//W.I.P
internal class PreLaunchChecker(GameEntry entry) : IChecker {
public bool IsCheckResource { get; set; }
namespace MinecraftLaunch.Components.Checker;

public bool IsCheckAccount { get; set; }
public GameEntry Entry => entry;
/// <summary>
/// 预启动检查器
/// </summary>
/// <param name="entry"></param>
public sealed class PreLaunchChecker(GameEntry entry) : IChecker {
public bool IsCheckResource { get; set; }

public ValueTask<bool> CheckAsync() {
/*
*
*/
throw new NotImplementedException();
}
public bool IsCheckAccount { get; set; }
public GameEntry Entry => entry;

public ValueTask<bool> CheckAsync() {
/*
*
*/
throw new NotImplementedException();
}
}
}
89 changes: 89 additions & 0 deletions MinecraftLaunch/Components/Resolver/GameLogResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using MinecraftLaunch.Classes.Enums;
using System.Text.RegularExpressions;
using MinecraftLaunch.Classes.Models.Game;

namespace MinecraftLaunch.Components.Resolver;

/// <summary>
/// 游戏日志解析器
/// </summary>
public sealed class GameLogResolver {
public GameLogEntry Resolve(string log) {
return new GameLogEntry {
Log = GetLog(log),
Source = GetSource(log),
Time = Regex.IsMatch(log, "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d", RegexOptions.Compiled) ? GetLogTime(log) : DateTime.Now.ToString(),
LogType = GetLogType(log) switch {
"FATAL" => LogType.Fatal,
"ERROR" => LogType.Error,
"WARN" => LogType.Warning,
"INFO" => LogType.Info,
"DEBUG" => LogType.Debug,
"STACK" => LogType.StackTrace,
"Exception" => LogType.Exception,
_ => LogType.Unknown
},
};
}

public string GetLog(string log) {
var res = GetTotalPrefix(log);
var s = log.Split(res);
return (s.Length >= 2 ? s[1] : log).Trim();
}

/// <summary>
/// 获取日志等级类型
/// </summary>
/// <param name="log"></param>
/// <returns></returns>
public string GetLogType(string log) {
//是否是堆栈信息
if (Regex.IsMatch(log, "(at .*)", RegexOptions.Compiled)) {
return "STACK";
}

//是否是异常信息
if (Regex.IsMatch(log, "(?m)^.*?Exception.*", RegexOptions.Compiled)) {
return "Exception";
}

return Regex.Match(log, "FATAL|ERROR|WARN|INFO|DEBUG", RegexOptions.Compiled).Value;
}

/// <summary>
/// 获取日志源
/// </summary>
/// <param name="log"></param>
/// <returns></returns>
public string GetSource(string log) {
var content = Regex.Match(log, $"[\\w\\W\\s]{{2,}}/(FATAL|ERROR|WARN|INFO|DEBUG)", RegexOptions.Compiled)
.Value.Split('/')
.FirstOrDefault();

return content?.Replace($"{Regex.Match(log,
$"\\[(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\]").Value} [",
string.Empty)!;
}

/// <summary>
/// 获取日志时间
/// </summary>
/// <param name="log"></param>
/// <returns></returns>
public string GetLogTime(string log) {
return Regex.Match(log, "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d",
RegexOptions.Compiled).Value;
}

/// <summary>
/// 获取日志所有前缀
/// </summary>
/// <param name="log"></param>
/// <returns></returns>
public string GetTotalPrefix(string log) {
return Regex.Match(log,
$"\\[(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\] \\[[\\w\\W\\s]{{2,}}/(FATAL|ERROR|WARN|INFO|DEBUG)\\]",
RegexOptions.Compiled).Value;
}
}
17 changes: 10 additions & 7 deletions MinecraftLaunch/Components/Watcher/GameProcessWatcher.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
using System;
using System.Diagnostics;
using System.Diagnostics;
using MinecraftLaunch.Classes.Interfaces;
using MinecraftLaunch.Components.Resolver;
using MinecraftLaunch.Classes.Models.Event;

namespace MinecraftLaunch.Components.Watcher;

/// <summary>
/// 游戏进程监视器
/// </summary>
public class GameProcessWatcher : IWatcher, IGameProcessWatcher {
public Process Process { get; }
public sealed class GameProcessWatcher : IWatcher, IGameProcessWatcher {
private readonly GameLogResolver _gameLogResolver;

public Process Process { get; }
public IEnumerable<string> Arguments { get; }

public event EventHandler<ExitedEventArgs> Exited;

public event EventHandler<LogReceivedEventArgs> OutputLogReceived;

public GameProcessWatcher(Process process, IEnumerable<string> arguments) {
Process = process;
Arguments = arguments;
_gameLogResolver = new();

Start();
}

Expand All @@ -40,8 +42,9 @@ private void OnExited(object sender, EventArgs e) {
}

private void OnOutputDataReceived(object sender, DataReceivedEventArgs e) {
if(!string.IsNullOrEmpty(e.Data)) {
OutputLogReceived?.Invoke(this, new(e.Data));
if (!string.IsNullOrEmpty(e.Data)) {
var log = _gameLogResolver.Resolve(e.Data);
OutputLogReceived?.Invoke(this, new(log.Log, log.Time, log.Time, log.LogType));
}
}
}

0 comments on commit 8341fed

Please sign in to comment.