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 _key(keycode: Key, unicode: int, pressed: bool) -> void: var event := InputEventKey.new() event.keycode = keycode event.physical_keycode = keycode event.unicode = unicode event.pressed = pressed root.push_input(event) func _press(keycode: Key) -> void: _key(keycode, 0, true) _key(keycode, 0, false) func _type(text: String) -> void: for i in text.length(): var ch := text.unicode_at(i) var keycode := OS.find_keycode_from_string(text[i].to_upper()) _key(keycode, ch, true) _key(keycode, ch, false) 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() world.name = "Python3DSurface" ui = PythonUISurface.new() ui.name = "PythonUISurface" root.add_child(ui) root.add_child(world) var err: String = ui.run_app() if err != "": quit(1) return await _pump_until(15, func(): return _py( "import __main__, os, networkModule, introLogin, introSelect\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)" )) _py( "_env = os.environ\n" + "_stream.SetConnectInfo(_env['MT_LIVE_HOST'], int(_env.get('MT_LIVE_GAME_PORT', '13000')), " + "_env['MT_LIVE_HOST'], int(_env.get('MT_LIVE_AUTH_PORT', '11000')))\n" + "_w = _stream.curPhaseWindow\n" + "_w._LoginWindow__OpenLoginBoard()\n" + "_w.idEditLine.SetText('')\n" + "_w.pwdEditLine.SetText('')\n" + "_w.idEditLine.SetFocus()" ) _type(OS.get_environment("MT_LIVE_LOGIN")) _press(KEY_TAB) _type(OS.get_environment("MT_LIVE_PASSWORD")) _py("del _env, _w") _press(KEY_ENTER) await _pump_until(30, func(): return _py( "assert isinstance(_stream.curPhaseWindow, introSelect.SelectCharacterWindow)" )) for i in 15: await process_frame var img_final = root.get_texture().get_image() img_final.save_png("/tmp/select_character_final.png") print("Saved /tmp/select_character_final.png") quit(0)