小井盖面板全程压制:不再放回、关控制台后关闭并抑制 2.5 秒

- 触发条件改为「面板真的可见」而不是「窗口存在」,避免隐藏缓存的旧面板被当成点击
- 控制台打开期间面板一露头就 SW_HIDE,关控制台时关面板并在 2.5 秒内持续压制、最多再请 4 次关闭
- 轮询从 250ms 提到 40/60ms,消除旧页面闪现
- 服务端指纹回绑 CE86D4DF… (1258496)
This commit is contained in:
hanfuit committed 2026-11-05 13:26:06 +08:00
1 parent 32469e4341
commit 0c7ef6d645
3 files changed
+70 -55

No files matched your search

+66 -52
View File
@@ -631,24 +631,31 @@ DWORD WINAPI WorkerThread(void*)
HWND imeHwnd = nullptr;
unsigned imeTick = 0;
HWND hiddenPanel = nullptr;
HWND consumedPanel = nullptr;
bool ownShown = false;
int mode = g_cfg.external ? MODE_GM_WINDOW : MODE_INLINE;
DWORD lastPoll = 0;
DWORD lastLaunch = 0;
// 玩家关掉控制台之后的抑制期:这段时间里面板只要露头就继续藏、继续请它关闭,
// 免得游戏的关闭动画把旧页面又画出来(残留)。
DWORD suppressUntil = 0;
int closeAttempts = 0;
for (;;) {
if (InterlockedCompareExchange(&g_stop, 0, 0) != 0) break;
// WebView2 要靠消息泵跑起来,窗口开着时必须泵得勤,否则页面会顿。
GmPumpMessages(ownShown ? 50 : 250);
const DWORD now = GetTickCount();
if (now - lastPoll < 250) continue;
const bool suppressing = suppressUntil && now < suppressUntil;
// WebView2 要靠消息泵跑起来,窗口开着时必须泵得勤,否则页面会顿。
GmPumpMessages((ownShown || suppressing) ? 40 : 120);
// 原面板绝不能出现在画面上,所以轮询要快;空闲时放宽一点省 CPU。
const DWORD interval = (ownShown || suppressing) ? 40 : 60;
if (now - lastPoll < interval) continue;
lastPoll = now;
const HWND panel = FindWebPanelWindow();
const bool panelVisible = panel != nullptr && IsWindowVisible(panel) != FALSE;
if (mode == MODE_INLINE) {
HWND ieHwnd = FindIeServerWindow();
@@ -666,49 +673,59 @@ DWORD WINAPI WorkerThread(void*)
continue;
}
if (!panel) {
// 面板被游戏关掉了:把我们自己的窗口也收起来,状态归零
if (mode == MODE_GM_WINDOW && GmWindowIsVisible()) GmWindowHide();
RestoreGameFromConsole();
hiddenPanel = nullptr;
consumedPanel = nullptr;
ownShown = false;
continue;
}
const bool mine = OwnWindowVisible(mode);
// 玩家把我们的窗口关了:把面板放回去(或直接关掉),交回游戏
if (ownShown && !mine) {
ownShown = false;
HWND target = (hiddenPanel && IsWindow(hiddenPanel)) ? hiddenPanel : panel;
if (g_cfg.closePanel) {
PostMessageW(target, WM_CLOSE, 0, 0);
LogLine("web window: own window closed, panel closed hwnd=%p", (void*)target);
} else {
if (!IsWindowVisible(target)) ShowWindow(target, SW_SHOW);
LogLine("web window: own window closed, panel restored hwnd=%p", (void*)target);
// 控制台开着:原面板全程压制,一露头就藏,绝不让旧 IE 页面出现在画面上。
if (ownShown) {
if (!OwnWindowVisible(mode)) {
// 玩家把控制台关了:直接把原面板关掉并进入抑制期,不再放回游戏,
// 这样游戏自己的关闭动画不会把旧页面又画出来(残留)。
ownShown = false;
if (panel) {
if (panelVisible) ShowWindow(panel, SW_HIDE);
if (g_cfg.closePanel) {
PostMessageW(panel, WM_CLOSE, 0, 0);
suppressUntil = now + 2500;
closeAttempts = 1;
LogLine("web window: console closed, panel closed hwnd=%p", (void*)panel);
} else {
ShowWindow(panel, SW_SHOW);
LogLine("web window: console closed, panel restored hwnd=%p", (void*)panel);
}
}
RestoreGameFromConsole();
continue;
}
consumedPanel = target;
hiddenPanel = nullptr;
RestoreGameFromConsole();
continue;
}
if (mine) {
ownShown = true;
if (panelVisible) {
ShowWindow(panel, SW_HIDE);
LogLine("web window: panel suppressed hwnd=%p", (void*)panel);
}
// 全屏游戏会抢窗口栈,每轮确认一次置顶
GmWindowAssertTop();
if (g_cfg.suppress && IsWindowVisible(panel)) {
ShowWindow(panel, SW_HIDE);
hiddenPanel = panel;
LogLine("web window: panel hidden hwnd=%p", (void*)panel);
}
continue;
}
// 这一块面板玩家已经关过一次了,别再自动弹,等他重新点小井盖
if (consumedPanel == panel) continue;
// 抑制期:面板只要还露着就继续藏、继续请它关闭,期间不重新弹控制台。
if (suppressUntil) {
if (!panel || now > suppressUntil) {
suppressUntil = 0;
closeAttempts = 0;
} else {
if (panelVisible) {
ShowWindow(panel, SW_HIDE);
if (g_cfg.closePanel && closeAttempts < 4) {
PostMessageW(panel, WM_CLOSE, 0, 0);
++closeAttempts;
}
LogLine("web window: panel re-hidden after close hwnd=%p attempts=%d",
(void*)panel, closeAttempts);
}
continue;
}
}
// 面板不存在,或者存在但被游戏自己藏着 —— 都不该弹控制台。
// 只有「玩家点了小井盖、面板真的显示出来」才算一次打开请求。
if (!panelVisible) continue;
if (mode == MODE_GM_WINDOW) {
if (GmWindowFailed()) {
@@ -716,16 +733,15 @@ DWORD WINAPI WorkerThread(void*)
mode = MODE_APP_WINDOW;
continue;
}
// 先藏面板再建窗口,避免旧页面在中间闪一下
ShowWindow(panel, SW_HIDE);
if (GmWindowShow(g_cfg.url.c_str(), g_cfg.width, g_cfg.height)) {
ownShown = true;
if (g_cfg.suppress && IsWindowVisible(panel)) {
ShowWindow(panel, SW_HIDE);
hiddenPanel = panel;
LogLine("web window: panel hidden while showing hwnd=%p", (void*)panel);
}
// 独占全屏时先让游戏让位,否则控制台会被游戏画面压住
MakeRoomForConsole();
LogLine("web window: gm window shown");
LogLine("web window: gm window shown, panel suppressed hwnd=%p", (void*)panel);
} else {
LogLine("web window: gm window show failed hwnd=%p", (void*)panel);
}
continue;
}
@@ -733,12 +749,10 @@ DWORD WINAPI WorkerThread(void*)
// MODE_APP_WINDOW
if (now - lastLaunch > 3000) {
lastLaunch = now;
ShowWindow(panel, SW_HIDE);
if (LaunchOwnWindow()) {
ownShown = true;
if (g_cfg.suppress && IsWindowVisible(panel)) {
ShowWindow(panel, SW_HIDE);
hiddenPanel = panel;
}
ShowWindow(panel, SW_HIDE);
LogLine("web window: app window launched");
} else {
mode = MODE_INLINE;