Files
mtgodot-poc/project/debug_anomalies.gd
T
2026-09-27 19:44:41 -07:00

117 lines
3.6 KiB
GDScript

extends SceneTree
const PythonUISurface = preload("res://python_ui_surface.gd")
const Python3DSurface = preload("res://python_3d_surface.gd")
var ui: Control
var world: Node3D
func _initialize() -> void:
call_deferred("run")
func _py(source: String) -> bool:
return Metin2PythonHost.run_line(source) == ""
func _pump_until(seconds: float, condition: Callable) -> bool:
var deadline := Time.get_ticks_msec() + int(seconds * 1000.0)
while Time.get_ticks_msec() < deadline:
if condition.call():
return true
await process_frame
return condition.call()
func run() -> void:
root.size = Vector2i(1024, 768)
world = Python3DSurface.new()
ui = PythonUISurface.new()
root.add_child(ui)
root.add_child(world)
ui.run_app()
await _pump_until(15, func(): return _py(
"import __main__, os, networkModule, introLogin, introSelect, game, player, background, chr, chrmgr\n"
+ "__main__._stream = [o for o in __import__('gc').get_objects() if isinstance(o, networkModule.MainStream)][0]"
))
await _pump_until(20, func(): return _py(
"assert isinstance(_stream.curPhaseWindow, introLogin.LoginWindow)"
))
var host = OS.get_environment("MT_LIVE_HOST")
var login = OS.get_environment("MT_LIVE_LOGIN")
var pwd = OS.get_environment("MT_LIVE_PASSWORD")
var auth_port = int(OS.get_environment("MT_LIVE_AUTH_PORT"))
var game_port = int(OS.get_environment("MT_LIVE_GAME_PORT"))
_py("_stream.SetConnectInfo('%s', %d, '%s', %d)\n" % [host, game_port, host, auth_port]
+ "_stream.curPhaseWindow.Connect('%s', '%s')" % [login, pwd])
await _pump_until(30, func(): return _py(
"assert isinstance(_stream.curPhaseWindow, introSelect.SelectCharacterWindow)"
))
_py("_stream.curPhaseWindow.SelectSlot(0)\n_stream.curPhaseWindow.StartGame()")
await _pump_until(30, func(): return _py(
"assert isinstance(_stream.curPhaseWindow, game.GameWindow) and _stream.curPhaseWindow.IsShow()"
))
for i in 60:
await process_frame
print("=== INVESTIGATING ALL 518 ACTORS ===")
var draws: Array = Metin2PythonHost.render3d_draws()
var actor_draws := {}
for d in draws:
var wm: PackedFloat32Array = d["world"]
var key := "%.1f,%.1f,%.1f" % [wm[12], wm[13], wm[14]]
if not actor_draws.has(key):
actor_draws[key] = []
actor_draws[key].append(d)
print("Unique actor positions: ", actor_draws.size())
var anomalies := []
for key in actor_draws:
var ds: Array = actor_draws[key]
var wm: PackedFloat32Array = ds[0]["world"]
var map_x := wm[12]
var map_y := -wm[13]
var actor_z := wm[14]
var bg_h = float(Metin2PythonHost.evaluate("str(background.GetHeight(%f, %f))" % [map_x, map_y]))
var terrain_h = float(world.terrain.call("sample_height", map_x / 100.0, map_y / 100.0)) * 100.0 if world.terrain else 0.0
var diff_bg = actor_z - bg_h
var diff_terrain = actor_z - terrain_h
# Find textures
var texs := []
var min_vert_z := 1e9
for d in ds:
var t: String = d.get("texture0", "")
if not t.is_empty():
texs.append(t.get_file())
for p in d["positions"]:
min_vert_z = minf(min_vert_z, actor_z + p.z)
if absf(diff_bg) > 5.0 or absf(diff_terrain) > 5.0:
anomalies.append({
"pos": [map_x, map_y, actor_z],
"bg_h": bg_h,
"terrain_h": terrain_h,
"diff_bg": diff_bg,
"diff_terrain": diff_terrain,
"vert_min_diff": min_vert_z - bg_h,
"textures": texs
})
print("Found %d anomalies with gap > 5cm!" % anomalies.size())
for a in anomalies.slice(0, 30):
print("Anomaly: pos=(%.1f, %.1f, %.1f), bg_h=%.1f, terrain_h=%.1f, diff_bg=%.1f, diff_terrain=%.1f, vert_min_diff=%.1f, tex=%s" % [
a["pos"][0], a["pos"][1], a["pos"][2], a["bg_h"], a["terrain_h"], a["diff_bg"], a["diff_terrain"], a["vert_min_diff"], a["textures"]
])
quit(0)