Files
MRCC/launcher/PCL-CE/Plain Craft Launcher 2/Modules/Minecraft/CrashAnalysis/Presentation/CrashResultFormatter.cs
T
xyou f70b061d1a
CI / Go Backend (push) Canceled after 0s
feat: 项目初始化 + 3D方块世界原型 + AI助搭系统
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器

HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块

Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚

AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
2026-08-08 14:07:56 +08:00

525 lines
20 KiB
C#

using PCL.Core.App.Localization;
using PCL.Core.Logging;
using PCL.Core.Utils;
using PCL.Core.Utils.Exts;
namespace PCL;
internal sealed class CrashResultFormatter
{
public CrashDialogContent Format(
CrashAnalysisContext context,
bool isHandAnalyze)
{
var result = context.Result ?? new CrashAnalysisResult();
if (!result.Any)
return _CreateUnknownContent(isHandAnalyze);
var specs = result.Findings
.Select(finding => _CreateMessageSpec(finding, context.LogAll))
.ToList();
var text = _JoinParagraphs(specs.Select(_Render));
if (!isHandAnalyze)
text = _AppendFollowUps(text, specs);
return new CrashDialogContent(
_NormalizeLineEndings(text).Trim('\r', '\n'),
specs[0].SuggestedAction);
}
private static CrashDialogContent _CreateUnknownContent(bool isHandAnalyze)
{
var spec = isHandAnalyze
? _Spec("Crash.Reason.Unknown.Manual")
: _Spec("Crash.Reason.Unknown.Auto", "Crash.Suggestion.ExportReport");
return new CrashDialogContent(
_NormalizeLineEndings(_Render(spec)).Trim('\r', '\n'),
CrashSuggestedAction.None);
}
private static string _AppendFollowUps(
string text,
IReadOnlyCollection<CrashMessageSpec> specs)
{
var followUps = new List<string>();
if (specs.Any(spec => spec.AppendReportHint))
followUps.Add(Lang.Text("Crash.Suggestion.ViewReport"));
if (specs.Any(spec => spec.AppendHelpHint))
followUps.Add(Lang.Text("Crash.Suggestion.ExportReport"));
var launcherOutdatedSuggestion = _GetLauncherOutdatedSuggestion();
if (!string.IsNullOrWhiteSpace(launcherOutdatedSuggestion))
followUps.Add(launcherOutdatedSuggestion);
return followUps.Count == 0
? text
: Lang.Text(
"Crash.Presentation.WithFollowUps",
text,
_JoinParagraphs(followUps));
}
private static string _Render(CrashMessageSpec spec)
{
var reason = Lang.Text(spec.ReasonKey, spec.ReasonArgs);
if (spec.SuggestionKey is null)
return Lang.Text("Crash.Presentation.ReasonOnly", reason);
return Lang.Text(
"Crash.Presentation.WithSuggestion",
reason,
Lang.Text(spec.SuggestionKey, spec.SuggestionArgs));
}
private static CrashMessageSpec _CreateMessageSpec(
CrashFinding finding,
string combinedLogText)
{
var additional = finding.Details.ToList();
switch (finding.Cause)
{
case CrashCause.ExtractedModFile:
return _Spec(
"Crash.Reason.ExtractedModFile",
"Crash.Suggestion.ExtractedModFile");
case CrashCause.OutOfMemory:
return _Spec(
"Crash.Reason.OutOfMemory",
"Crash.Suggestion.OutOfMemory",
help: true);
case CrashCause.UsingOpenJ9:
return _Spec(
"Crash.Reason.UsingOpenJ9",
"Crash.Suggestion.UsingOpenJ9");
case CrashCause.UsingJdk:
return _Spec(
"Crash.Reason.UsingJdk",
"Crash.Suggestion.UsingJdk");
case CrashCause.JavaTooNew:
return _Spec(
"Crash.Reason.JavaTooNew",
"Crash.Suggestion.JavaTooNew");
case CrashCause.JavaIncompatible:
return _Spec(
"Crash.Reason.JavaIncompatible",
"Crash.Suggestion.JavaIncompatible");
case CrashCause.InvalidModFileName:
return _Spec(
"Crash.Reason.InvalidModFileName",
"Crash.Suggestion.InvalidModFileName");
case CrashCause.MissingMixinBootstrap:
return _Spec(
"Crash.Reason.MissingMixinBootstrap",
"Crash.Suggestion.MissingMixinBootstrap");
case CrashCause.X86JavaMemoryLimit:
return Environment.Is64BitOperatingSystem
? _Spec(
"Crash.Reason.X86JavaMemoryLimit.OnX64Os",
"Crash.Suggestion.X86JavaMemoryLimit.OnX64Os")
: _Spec(
"Crash.Reason.X86JavaMemoryLimit.OnX86Os",
"Crash.Suggestion.X86JavaMemoryLimit.OnX86Os",
help: true);
case CrashCause.MissingDependencyOrWrongMcVersion:
return _FormatMissingDependency(additional);
case CrashCause.StackKeywordFound:
return additional.Count == 1
? _Spec(
"Crash.Reason.StackKeyword.Single",
"Crash.Suggestion.StackKeyword", _Args(additional[0]),
help: true)
: _Spec(
"Crash.Reason.StackKeyword.Multiple",
"Crash.Suggestion.StackKeyword",
_Args(_BulletList(additional)),
help: true);
case CrashCause.StackModNameFound or CrashCause.SuspectedModCrash:
return additional.Count == 1
? _Spec(
"Crash.Reason.SuspectedMod.Single",
"Crash.Suggestion.DisableThisMod",
_Args(additional[0]),
report: true,
help: true)
: _Spec(
"Crash.Reason.SuspectedMod.Multiple",
"Crash.Suggestion.DisableTheseMods",
_Args(_BulletList(additional)),
report: true,
help: true);
case CrashCause.ConfirmedModCrash:
return additional.Count == 1
? _Spec(
"Crash.Reason.ConfirmedMod.Single",
"Crash.Suggestion.DisableThisMod",
_Args(additional[0]),
report: true,
help: true)
: _Spec(
"Crash.Reason.ConfirmedMod.Multiple",
"Crash.Suggestion.DisableTheseMods",
_Args(_BulletList(additional)),
report: true,
help: true);
case CrashCause.ModMixinFailed:
if (additional.Count == 0)
return _Spec(
"Crash.Reason.ModMixinFailed.None",
"Crash.Suggestion.ModMixinFailed",
report: true,
help: true);
return additional.Count == 1
? _Spec(
"Crash.Reason.ModMixinFailed.Single",
"Crash.Suggestion.DisableThisMod",
_Args(additional[0]),
report: true,
help: true)
: _Spec(
"Crash.Reason.ModMixinFailed.Multiple",
"Crash.Suggestion.DisableTheseMods",
_Args(_BulletList(additional)),
report: true,
help: true);
case CrashCause.ModConfigCrash:
return additional.Count > 1 && additional[1] is not null
? _Spec(
"Crash.Reason.ModConfigCrash.WithConfig",
"Crash.Suggestion.ModConfigCrash",
_Args(additional[0], additional[1]))
: _Spec(
"Crash.Reason.ModConfigCrash.Simple",
"Crash.Suggestion.DisableThisMod",
_Args(additional.FirstOrDefault() ?? string.Empty),
report: true,
help: true);
case CrashCause.ModInitializationFailed:
return additional.Count == 1
? _Spec(
"Crash.Reason.ModInitializationFailed.Single",
"Crash.Suggestion.DisableThisMod",
_Args(additional[0]),
report: true,
help: true)
: _Spec(
"Crash.Reason.ModInitializationFailed.Multiple",
"Crash.Suggestion.DisableTheseMods",
_Args(_BulletList(additional)),
report: true,
help: true);
case CrashCause.SpecificBlockCrash:
return additional.Count == 1
? _Spec(
"Crash.Reason.SpecificBlock.Single",
"Crash.Suggestion.SpecificBlock.Single",
_Args(additional[0]),
help: true)
: _Spec(
"Crash.Reason.SpecificBlock.Multiple",
"Crash.Suggestion.SpecificBlock.Multiple",
help: true);
case CrashCause.DuplicateMods:
return additional.Count >= 2
? _Spec(
"Crash.Reason.DuplicateMods.Known",
"Crash.Suggestion.DuplicateMods",
_Args(_BulletList(additional)))
: _Spec(
"Crash.Reason.DuplicateMods.Unknown",
"Crash.Suggestion.DuplicateMods",
report: true,
help: true);
case CrashCause.SpecificEntityCrash:
return additional.Count == 1
? _Spec(
"Crash.Reason.SpecificEntity.Single",
"Crash.Suggestion.SpecificEntity.Single",
_Args(additional[0]),
help: true)
: _Spec(
"Crash.Reason.SpecificEntity.Multiple",
"Crash.Suggestion.SpecificEntity.Multiple",
help: true);
case CrashCause.OptiFineForgeIncompatible:
return _Spec(
"Crash.Reason.OptiFineForgeIncompatible",
"Crash.Suggestion.OptiFineForgeIncompatible");
case CrashCause.ShadersModWithOptiFine:
return _Spec(
"Crash.Reason.ShadersModWithOptiFine",
"Crash.Suggestion.ShadersModWithOptiFine");
case CrashCause.OldForgeNewJavaIncompatible:
return _Spec(
"Crash.Reason.OldForgeNewJavaIncompatible",
"Crash.Suggestion.OldForgeNewJavaIncompatible");
case CrashCause.MultipleForgeInInstanceJson:
return _Spec(
"Crash.Reason.MultipleForgeInInstanceJson",
"Crash.Suggestion.MultipleForgeInInstanceJson");
case CrashCause.ManualDebugCrash:
return _Spec("Crash.Reason.ManualDebugCrash");
case CrashCause.ModRequiresJava11:
return _Spec(
"Crash.Reason.ModRequiresJava11",
"Crash.Suggestion.ModRequiresJava11");
case CrashCause.VeryShortOutput:
return _Spec(
"Crash.Reason.VeryShortOutput",
"Crash.Suggestion.ExportReport",
_Args(additional.FirstOrDefault() ?? string.Empty));
case CrashCause.OptiFineWorldLoadCrash:
return _Spec(
"Crash.Reason.OptiFineWorldLoadCrash",
"Crash.Suggestion.OptiFineWorldLoadCrash",
help: true);
case CrashCause.PixelFormatNotSupported
or CrashCause.IntelDriverAccessViolation
or CrashCause.AmdDriverAccessViolation
or CrashCause.NvidiaDriverAccessViolation
or CrashCause.UnsupportedOpenGl:
return combinedLogText.Contains("hd graphics ")
? _Spec(
"Crash.Reason.GraphicsDriver.IntelOrIntegrated",
"Crash.Suggestion.GraphicsDriver.IntelOrIntegrated",
help: true)
: _Spec(
"Crash.Reason.GraphicsDriver.Generic",
"Crash.Suggestion.GraphicsDriver.Generic",
help: true);
case CrashCause.ResourcePackTooLarge:
return _Spec(
"Crash.Reason.ResourcePackTooLarge",
"Crash.Suggestion.ResourcePackTooLarge",
help: true);
case CrashCause.NightConfigBug:
return _Spec(
"Crash.Reason.NightConfigBug",
"Crash.Suggestion.NightConfigBug",
help: true);
case CrashCause.OpenGl1282:
return _Spec(
"Crash.Reason.OpenGl1282",
"Crash.Suggestion.OpenGl1282",
help: true);
case CrashCause.TooManyModsIdLimit:
return _Spec(
"Crash.Reason.TooManyModsIdLimit",
"Crash.Suggestion.TooManyModsIdLimit");
case CrashCause.FileOrContentValidationFailed:
return _Spec(
"Crash.Reason.FileOrContentValidationFailed",
"Crash.Suggestion.FileOrContentValidationFailed",
help: true);
case CrashCause.IncompleteForgeInstallation:
return _Spec(
"Crash.Reason.IncompleteForgeInstallation",
"Crash.Suggestion.IncompleteForgeInstallation",
help: true);
case CrashCause.FabricError:
return additional.Count == 1
? _Spec(
"Crash.Reason.FabricError.WithDetail",
"Crash.Suggestion.FollowLoaderInstructions",
_Args(additional[0]))
: _Spec(
"Crash.Reason.FabricError.Generic",
"Crash.Suggestion.FollowLoaderInstructions",
help: true);
case CrashCause.IncompatibleMods:
return _FormatIncompatibleMods(additional);
case CrashCause.ModLoaderError:
return additional.Count == 1
? _Spec(
"Crash.Reason.ModLoaderError.WithDetail",
"Crash.Suggestion.FollowLoaderInstructions",
_Args(additional[0]))
: _Spec(
"Crash.Reason.ModLoaderError.Generic",
"Crash.Suggestion.FollowLoaderInstructions",
help: true);
case CrashCause.FabricSolutionProvided:
return additional.Count == 1
? _Spec(
"Crash.Reason.FabricSolution.WithDetail",
"Crash.Suggestion.FollowLoaderInstructions",
_Args(additional[0]))
: _Spec(
"Crash.Reason.FabricSolution.Generic",
"Crash.Suggestion.FollowLoaderInstructions",
help: true);
case CrashCause.ForgeError:
return additional.Count == 1
? _Spec(
"Crash.Reason.ForgeError.WithDetail",
"Crash.Suggestion.FollowLoaderInstructions",
_Args(additional[0]))
: _Spec(
"Crash.Reason.ForgeError.Generic",
"Crash.Suggestion.FollowLoaderInstructions",
help: true);
case CrashCause.NoAnalyzableFile:
return _Spec(
"Crash.Reason.NoAnalyzableFile",
"Crash.Suggestion.ExportReport",
help: true);
default:
return _Spec(
"Crash.Reason.UnknownFinding",
"Crash.Suggestion.ExportReport",
_Args(finding.Cause.ToString()),
help: true);
}
}
private static CrashMessageSpec _FormatMissingDependency(List<string> additional)
{
if (additional.Count == 0)
return _Spec(
"Crash.Reason.MissingDependency.Generic",
"Crash.Suggestion.FollowLoaderInstructions",
help: true);
var info = _BulletList(additional);
return info.IsMatch(RegexPatterns.IncompatibleModLoaderErrorHint)
? _Spec(
"Crash.Reason.ModLoaderIncompatible",
"Crash.Suggestion.ModLoaderIncompatible",
_Args(info),
action: CrashSuggestedAction.OpenInstanceSettings)
: _Spec(
"Crash.Reason.MissingDependency.WithDetail",
"Crash.Suggestion.FollowLoaderInstructions",
_Args(info));
}
private static CrashMessageSpec _FormatIncompatibleMods(List<string> additional)
{
if (additional.Count != 1)
return _Spec(
"Crash.Reason.IncompatibleMods.Generic",
"Crash.Suggestion.FollowLoaderInstructions",
help: true);
var info = additional[0];
return info.IsMatch(RegexPatterns.IncompatibleModLoaderErrorHint)
? _Spec(
"Crash.Reason.ModLoaderIncompatible",
"Crash.Suggestion.ModLoaderIncompatible",
_Args(info),
action: CrashSuggestedAction.OpenInstanceSettings)
: _Spec(
"Crash.Reason.IncompatibleMods.WithDetail",
"Crash.Suggestion.FollowLoaderInstructions",
_Args(info));
}
private static CrashMessageSpec _Spec(
string reasonKey,
string? suggestionKey = null,
object?[]? reasonArgs = null,
object?[]? suggestionArgs = null,
bool report = false,
bool help = false,
CrashSuggestedAction action = CrashSuggestedAction.None)
{
return new CrashMessageSpec(
reasonKey,
reasonArgs ?? [],
suggestionKey,
suggestionArgs ?? [],
report,
help,
action);
}
private static object?[] _Args(params object?[] args)
{
return args;
}
private static string _BulletList(IEnumerable<string> items)
{
return string.Join(
Environment.NewLine,
items.Select(item => Lang.Text("Crash.Presentation.ListItem", item)));
}
private static string _JoinParagraphs(IEnumerable<string> items)
{
return string.Join(
Environment.NewLine + Environment.NewLine,
items.Where(item => !string.IsNullOrWhiteSpace(item)));
}
private static string _NormalizeLineEndings(string text)
{
return text
.Replace("\r\n", "\r")
.Replace("\n", "\r")
.Replace("\r", "\r\n");
}
private static string? _GetLauncherOutdatedSuggestion()
{
try
{
return UpdateManager.GetVersionStatus() == UpdateEnums.VersionStatus.Latest
? null
: Lang.Text("Crash.Suggestion.LauncherOutdated");
}
catch (Exception ex)
{
LogWrapper.Error(ex, "Crash", "确认启动器更新失败");
return null;
}
}
}