From f9be09d2c2b9598499f2cad1fdbf55708ed77eb6 Mon Sep 17 00:00:00 2001 From: shenlei Date: Wed, 30 Sep 2026 17:33:46 +0900 Subject: [PATCH] fix(touch): show the joystick and skill buttons only in the game phase The controls keyed off CPythonBackground's warp map name, which the loading window sets before the game window exists, so the loading screen already showed them. Also require CPythonNetworkStream's phase to be "Game" (PORT_IsGamePhase, exposed as PythonBoot::InGamePhase). Co-Authored-By: Claude Opus 5.5 --- src/host/touch_controller.h | 2 +- src/platform/ScriptLib/PythonBoot.cpp | 5 +++++ src/platform/ScriptLib/PythonBoot.h | 2 ++ src/port/UserInterface/PythonNetworkStream.h | 2 ++ tests/port/port_login_flow_test.cpp | 6 ++++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/host/touch_controller.h b/src/host/touch_controller.h index a4615a88..3bbc95d9 100644 --- a/src/host/touch_controller.h +++ b/src/host/touch_controller.h @@ -588,7 +588,7 @@ public: private: bool gameplay_controls_visible() const { #ifdef MT_NATIVE_HAS_LIVE_CLIENT - return !PythonBoot::CurrentMapName().empty(); + return PythonBoot::InGamePhase() && !PythonBoot::CurrentMapName().empty(); #else return false; #endif diff --git a/src/platform/ScriptLib/PythonBoot.cpp b/src/platform/ScriptLib/PythonBoot.cpp index 9e6a4631..bbfa65ba 100644 --- a/src/platform/ScriptLib/PythonBoot.cpp +++ b/src/platform/ScriptLib/PythonBoot.cpp @@ -277,6 +277,11 @@ std::string CurrentMapName() return CPythonBackground::Instance().GetWarpMapName(); } +bool InGamePhase() +{ + return g_network_stream && g_network_stream->PORT_IsGamePhase(); +} + bool IsRunning() { return g_launcher != nullptr; diff --git a/src/platform/ScriptLib/PythonBoot.h b/src/platform/ScriptLib/PythonBoot.h index c2059677..dce18aab 100644 --- a/src/platform/ScriptLib/PythonBoot.h +++ b/src/platform/ScriptLib/PythonBoot.h @@ -46,6 +46,8 @@ int ScriptThreadId(); bool AppFrame(); // Native CPythonBackground map selection, in the local coordinate frame of RenderGame. std::string CurrentMapName(); +// CPythonNetworkStream is in the game phase (SetGamePhase opened game.GameWindow); false while loading. +bool InGamePhase(); // Used by the platform CPythonApplication: Loop() calls AppLoopWait() before each Process() and stops // when it returns false; Exit()/Abort() call AppRequestQuit() (40250: PostQuitMessage). diff --git a/src/port/UserInterface/PythonNetworkStream.h b/src/port/UserInterface/PythonNetworkStream.h index 70e1f701..18b8cb01 100644 --- a/src/port/UserInterface/PythonNetworkStream.h +++ b/src/port/UserInterface/PythonNetworkStream.h @@ -118,6 +118,8 @@ class CPythonNetworkStream : public CNetworkStream, public CSingletonHas("game2:entergame"))); }); CHECK(entered && !failed()); + // CG_ENTERGAME's PHASE_GAME answer switches the stream to "Game" a round trip after the window opens. + CHECK(pump_until(5, [] { return PythonBoot::InGamePhase(); }) && !PythonBoot::CurrentMapName().empty()); // 7. (批次 2V2-b) The server answers CG_ENTERGAME with the character's own insert packets and // PHASE_GAME, then the Entergame burst (PVP/land list, time, channel, greet chat, ...). GamePhase