PixelLauncher 2.1.0 — стабильная сборка
Офлайн-лаунчер Minecraft: аккаунты без Microsoft, установка версий и лоадеров (Fabric, Quilt, Forge, NeoForge), каталог модпаков Modrinth, поиск и обновление модов, разбор вылетов, системный трей, автозагрузка, плагины, прокси и зеркала.
This commit is contained in:
commit
ec6f13ddcc
33 files changed
+10445
No files matched your search
@@ -0,0 +1,90 @@
|
||||
# -*- 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
|
||||
Reference in new issue
Block a user