Reworked some umu / proton 7 maximize window and keyboard issues.
This commit is contained in:
@@ -1095,6 +1095,7 @@ def _run_and_watch(
|
||||
detected_at_ns: int | None = None
|
||||
timed_out = False
|
||||
stop_reason = "process-exited"
|
||||
failure_reason: str | None = None
|
||||
with runner_log_path.open("a", encoding="utf-8") as runner_log:
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
@@ -1151,18 +1152,26 @@ def _run_and_watch(
|
||||
current_state = state
|
||||
current_analysis = analysis.to_summary()
|
||||
current_text = read_current_run_log_text(state, baseline)
|
||||
if analysis.load_texture_to_material_failed:
|
||||
if (
|
||||
analysis.load_texture_to_material_failed
|
||||
or analysis.asset_pack_health_failed
|
||||
):
|
||||
failure_state = state
|
||||
failure_trigger_mtime_ns = state.mtime_ns
|
||||
detected_at_ns = now_ns
|
||||
post_failure_deadline_ns = now_ns + int(
|
||||
testcase.stop_after_failure_seconds * 1_000_000_000
|
||||
)
|
||||
failure_reason = (
|
||||
"asset-pack-health"
|
||||
if analysis.asset_pack_health_failed
|
||||
else "load-texture-to-material"
|
||||
)
|
||||
break
|
||||
if post_failure_deadline_ns is not None and now_ns >= post_failure_deadline_ns:
|
||||
stop_reason = "load-texture-to-material"
|
||||
_stop_process_group(process)
|
||||
break
|
||||
if post_failure_deadline_ns is not None and now_ns >= post_failure_deadline_ns:
|
||||
stop_reason = failure_reason or "load-texture-to-material"
|
||||
_stop_process_group(process)
|
||||
break
|
||||
if now_ns >= deadline_ns:
|
||||
timed_out = True
|
||||
stop_reason = "timeout"
|
||||
@@ -1216,6 +1225,9 @@ def _run_and_watch(
|
||||
"load_texture_to_material_failed": analysis.get(
|
||||
"load_texture_to_material_failed", False
|
||||
),
|
||||
"asset_pack_health_failed": analysis.get(
|
||||
"asset_pack_health_failed", False
|
||||
),
|
||||
"import_scene_threw": analysis.get("import_scene_threw", False),
|
||||
}
|
||||
)
|
||||
@@ -1244,6 +1256,7 @@ def _run_and_watch(
|
||||
whispering_vale
|
||||
and not timed_out
|
||||
and not current_analysis.get("load_texture_to_material_failed", False)
|
||||
and not current_analysis.get("asset_pack_health_failed", False)
|
||||
and not current_analysis.get("import_scene_threw", False)
|
||||
and not current_analysis.get("failed_import_scenes", [])
|
||||
) if isinstance(current_analysis, Mapping) else False
|
||||
|
||||
@@ -9,6 +9,7 @@ from typing import Iterable, Mapping
|
||||
|
||||
|
||||
DEFAULT_NATIVE_LOG_PATTERNS = ("log_*.txt", "*.log")
|
||||
_ASSET_MISSING_FILE_THRESHOLD = 200
|
||||
|
||||
_SCENE_RE = re.compile(
|
||||
r"\[S1]\s+after import\s+(?P<scene>[^:]+):\s*"
|
||||
@@ -72,6 +73,12 @@ class NativeLogAnalysis:
|
||||
scenes: dict[str, list[SceneImport]] = field(default_factory=dict)
|
||||
events: list[LogEvent] = field(default_factory=list)
|
||||
failed_files: list[LogEvent] = field(default_factory=list)
|
||||
failed_file_find_count: int = 0
|
||||
failed_file_load_count: int = 0
|
||||
failed_file_read_count: int = 0
|
||||
failed_asset_file_count: int = 0
|
||||
failed_texture_file_count: int = 0
|
||||
failed_effect_file_count: int = 0
|
||||
failed_import_scenes: list[str] = field(default_factory=list)
|
||||
load_texture_to_material_failed: bool = False
|
||||
import_scene_threw: bool = False
|
||||
@@ -83,6 +90,14 @@ class NativeLogAnalysis:
|
||||
module_code_sync_delta: int | None = None
|
||||
banned_code_1: bool = False
|
||||
|
||||
@property
|
||||
def asset_pack_health_failed(self) -> bool:
|
||||
return (
|
||||
self.failed_asset_file_count >= _ASSET_MISSING_FILE_THRESHOLD
|
||||
or self.failed_texture_file_count >= _ASSET_MISSING_FILE_THRESHOLD // 3
|
||||
or self.failed_effect_file_count >= max(25, _ASSET_MISSING_FILE_THRESHOLD // 8)
|
||||
)
|
||||
|
||||
def latest_scene(self, name: str) -> SceneImport | None:
|
||||
wanted = _scene_key(name)
|
||||
for scene_name, imports in self.scenes.items():
|
||||
@@ -98,6 +113,13 @@ class NativeLogAnalysis:
|
||||
},
|
||||
"load_texture_to_material_failed": self.load_texture_to_material_failed,
|
||||
"import_scene_threw": self.import_scene_threw,
|
||||
"failed_file_find_count": self.failed_file_find_count,
|
||||
"failed_file_load_count": self.failed_file_load_count,
|
||||
"failed_file_read_count": self.failed_file_read_count,
|
||||
"failed_asset_file_count": self.failed_asset_file_count,
|
||||
"failed_texture_file_count": self.failed_texture_file_count,
|
||||
"failed_effect_file_count": self.failed_effect_file_count,
|
||||
"asset_pack_health_failed": self.asset_pack_health_failed,
|
||||
"failed_import_scenes": self.failed_import_scenes,
|
||||
"failed_files": [event.to_dict() for event in self.failed_files],
|
||||
"stage_without_new_stage": self.stage_without_new_stage,
|
||||
@@ -291,6 +313,18 @@ def parse_native_log_lines(lines: Iterable[str]) -> NativeLogAnalysis:
|
||||
event = LogEvent(f"failed_{operation}_file", line_number, raw, timestamp, value)
|
||||
analysis.failed_files.append(event)
|
||||
analysis.events.append(event)
|
||||
if operation == "find":
|
||||
analysis.failed_file_find_count += 1
|
||||
elif operation == "load":
|
||||
analysis.failed_file_load_count += 1
|
||||
else:
|
||||
analysis.failed_file_read_count += 1
|
||||
if _is_game_asset_path(value):
|
||||
analysis.failed_asset_file_count += 1
|
||||
if _is_texture_path(value):
|
||||
analysis.failed_texture_file_count += 1
|
||||
if _is_effect_path(value):
|
||||
analysis.failed_effect_file_count += 1
|
||||
|
||||
if "Stage without new stage" in raw:
|
||||
analysis.stage_without_new_stage = True
|
||||
@@ -319,3 +353,61 @@ def _scene_key(value: str) -> str:
|
||||
def _timestamp(line: str) -> str | None:
|
||||
match = _TIMESTAMP_RE.match(line)
|
||||
return match.group("timestamp") if match is not None else None
|
||||
|
||||
|
||||
def _is_game_asset_path(path: str) -> bool:
|
||||
lower = path.casefold()
|
||||
if not lower:
|
||||
return False
|
||||
if lower.startswith("save/") or lower.startswith("save\\"):
|
||||
return False
|
||||
if lower.startswith(("game\\", "game/")):
|
||||
return True
|
||||
if lower.startswith(("field\\", "field/")):
|
||||
return True
|
||||
if lower.startswith(("image\\", "image/")):
|
||||
return True
|
||||
if lower.startswith(("effect\\", "effect/")):
|
||||
return True
|
||||
if lower.startswith(("startimage\\", "startimage/")):
|
||||
return True
|
||||
return (
|
||||
"\\effect\\" in lower
|
||||
or "\\image\\" in lower
|
||||
or "\\field\\" in lower
|
||||
or "\\weapons\\" in lower
|
||||
or "\\char\\" in lower
|
||||
or "\\sinimage\\" in lower
|
||||
or "\\skill\\" in lower
|
||||
or lower.endswith(".bmp")
|
||||
or lower.endswith(".tga")
|
||||
or lower.endswith(".png")
|
||||
or lower.endswith(".jpg")
|
||||
or lower.endswith(".jpeg")
|
||||
or lower.endswith(".gif")
|
||||
or lower.endswith(".ase")
|
||||
or lower.endswith(".part")
|
||||
)
|
||||
|
||||
|
||||
def _is_texture_path(path: str) -> bool:
|
||||
lower = path.casefold()
|
||||
return (
|
||||
lower.endswith(".bmp")
|
||||
or lower.endswith(".tga")
|
||||
or lower.endswith(".png")
|
||||
or lower.endswith(".jpg")
|
||||
or lower.endswith(".jpeg")
|
||||
or lower.endswith(".gif")
|
||||
or lower.endswith(".dds")
|
||||
)
|
||||
|
||||
|
||||
def _is_effect_path(path: str) -> bool:
|
||||
lower = path.casefold()
|
||||
return (
|
||||
"\\effect\\" in lower
|
||||
or lower.startswith("effect\\")
|
||||
or lower.startswith("effect/")
|
||||
or lower.endswith(".part")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user