Files
PixelLauncher/launcher/crash.py
T
kosta2014p ec6f13ddcc PixelLauncher 2.1.0 — стабильная сборка
Офлайн-лаунчер Minecraft: аккаунты без Microsoft, установка версий и лоадеров
(Fabric, Quilt, Forge, NeoForge), каталог модпаков Modrinth, поиск и обновление
модов, разбор вылетов, системный трей, автозагрузка, плагины, прокси и зеркала.
2026-10-18 22:44:19 +07:00

91 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
"""Разбор логов вылетов Minecraft.
Ищет в логе последний exception-блок и определяет причину:
нехватка ОЗУ, проблемы с Java, конкретный мод или «неизвестно».
"""
import re
# "java.lang.NullPointerException: ..." / "Caused by: ...Exception: ..."
_EXC = re.compile(
r"^(?:Caused by: |Exception in thread [^\s]+ )?"
r"([\w.$]+(?:Exception|Error|Throwable))(?::\s*(.*))?$")
_MOD_JAR = re.compile(r"mods[/\\]([\w.\- ]+\.jar)")
_MOD_AT = re.compile(r"\(([\w\-]+)@[\d.]+\)") # SomeMod@1.2.3 в кадрах
_XMX = re.compile(r"-xmx(\d+)([mg])")
def analyze(text=None, path=None, tail=600):
"""Разбирает лог. Возвращает dict:
kind — "crash" | "oom" | "java" | "unknown"
exc — класс исключения (без пакета)
msg — сообщение исключения
culprit — имя файла мода (mods/xxx.jar) или id мода, если найдено
hints — подсказки ("oom", "xmx=2048", "classver", ...)
"""
res = {"kind": "unknown", "exc": "", "msg": "", "culprit": None,
"hints": []}
lines = []
if text is not None:
lines = text.splitlines()[-tail:]
elif path:
try:
with open(path, encoding="utf-8", errors="replace") as f:
lines = f.readlines()[-tail:]
except OSError:
pass
joined = "\n".join(lines)
if not joined.strip():
return res
low = joined.lower()
# --- нехватка ОЗУ
if ("outofmemoryerror" in low
or "could not reserve enough space" in low
or "gc overhead limit exceeded" in low):
res["kind"] = "oom"
res["exc"] = "OutOfMemoryError"
res["hints"].append("oom")
m = _XMX.search(low)
if m:
res["hints"].append("xmx=" + m.group(1) + m.group(2))
return res
# --- проблемы с Java
for pat, tag in ((r"unsupported class file major version (\d+)",
"classver"),
(r"unsupportedclassversionerror", "classver"),
(r"could not create the java virtual machine", "jvm"),
(r"invalid java runtime|no jvm could be found",
"java")):
if re.search(pat, low):
res["kind"] = "java"
res["exc"] = tag
res["hints"].append(tag)
return res
# --- последний exception-блок
idx = [i for i, ln in enumerate(lines) if _EXC.match(ln.strip())]
if not idx:
return res
caused = [i for i in idx if lines[i].strip().startswith("Caused by:")]
# корневая причина — последний Caused by в цепочке
m = _EXC.match(lines[caused[-1] if caused else idx[0]].strip())
res["kind"] = "crash"
if m:
res["exc"] = m.group(1).split(".")[-1]
res["msg"] = (m.group(2) or "")[:200]
# --- виновник: файл мода в тексте или mixin-кадр с mod id
m2 = _MOD_JAR.search(joined)
if m2:
res["culprit"] = m2.group(1)
else:
m3 = _MOD_AT.search(joined)
if m3:
res["culprit"] = m3.group(1)
return res