From f07f182fd8d28477cfc061449f0c14ae444561e2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 20 Oct 2026 13:43:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(team):=20=E6=9C=AC=E5=9C=B0=E9=98=9F?= =?UTF-8?q?=E4=BC=8D=E7=BC=93=E5=AD=98=E4=B8=8D=E5=86=8D=E9=9A=8F=20gm=20?= =?UTF-8?q?=E9=87=8D=E5=BB=BA=E6=B8=85=E7=A9=BA=EF=BC=8C=E5=B9=B6=E9=94=81?= =?UTF-8?q?=E5=AE=9A=E5=8D=95=E5=B1=80=E6=95=8C=E6=88=91=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../play/static/js/unpacked/hornet_bundle.js | 37 +++++++++++++------ 3dtank_bundle.js | 37 +++++++++++++------ tools/hornet_lib.js | 37 +++++++++++++------ 3 files changed, 78 insertions(+), 33 deletions(-) diff --git a/3dtank.com/play/static/js/unpacked/hornet_bundle.js b/3dtank.com/play/static/js/unpacked/hornet_bundle.js index ba36db3..bd29e68 100644 --- a/3dtank.com/play/static/js/unpacked/hornet_bundle.js +++ b/3dtank.com/play/static/js/unpacked/hornet_bundle.js @@ -466,19 +466,21 @@ } // 本地队伍缓存:死亡后 u10b_1 会被清空(onTankUnpossessed),不能再用"当前观察目标"推断。 - // 这里记住最后一次有效的本地队伍,整局沿用。 + // ⚠ 这里**不跟随 gm 变化重置**:hook 重新捕获 GameMode 时 gm 会换实例, + // 若此时重置,死亡/观战状态下就会拿观战目标当基准 → 敌我整体翻转。 + // 只在「本地坦克实体变了」(换局/换车)时才重新缓存。 var LocalTeam = null; - var LocalTeamGm = null; + var LocalTeamTankId = null; function RememberLocalTeam(gm) { if (!ZCt) return; - if (gm !== LocalTeamGm) { LocalTeamGm = gm; LocalTeam = null; } - if (LocalTeam) return; + var t = null; + try { t = gm.u10b_1; } catch (e) { t = null; } + if (!t) return; // 死亡/观战:保持已有缓存 + var Id = t.iz1_1; + if (LocalTeam && LocalTeamTankId === Id) return; try { - var t = gm.u10b_1; - if (!t) return; var Team = ZCt(t); - // 只缓存"非中立"队伍(m2Fn(Team,Team) 为 true 表示同队且非中立) - if (Team && (!m2Fn || m2Fn(Team, Team))) LocalTeam = Team; + if (Team && (!m2Fn || m2Fn(Team, Team))) { LocalTeam = Team; LocalTeamTankId = Id; } } catch (e) {} } @@ -487,6 +489,7 @@ // 处理:① 每辆坦克缓存最近一次**非中立**队伍;② 无法判定时沿用上一次判定结果。 var TankTeamCache = new WeakMap(); // tank -> 非中立队伍对象 var TankFriendCache = new WeakMap(); // tank -> 上一次的友方判定 + var TeamLockLogged = new WeakSet(); function ResolveTankTeam(tank) { if (!ZCt) return null; var Team = null; @@ -501,6 +504,9 @@ function IsFriendly(tank, playerTank, gm) { if (!tank) return false; if (gm) RememberLocalTeam(gm); + // 一旦在「本地队伍可靠」时判过,就锁定本局结果,避免任何同步抖动导致颜色翻转 + var Locked = TankFriendCache.get(tank); + if (Locked !== undefined) return Locked; if (ZCt && m2Fn) { try { var tankTeam = ResolveTankTeam(tank); @@ -508,13 +514,22 @@ if (!BaseTeam && playerTank) BaseTeam = ResolveTankTeam(playerTank); if (tankTeam && BaseTeam) { var Friendly = m2Fn(tankTeam, BaseTeam); - TankFriendCache.set(tank, Friendly); + if (LocalTeam) { + TankFriendCache.set(tank, Friendly); + // 诊断:首次锁定为友方时记一条,便于核对有没有把敌人锁成队友 + if (Friendly && !TeamLockLogged.has(tank)) { + TeamLockLogged.add(tank); + try { + console.log('[敌我] 锁定为友方 id=' + tank.iz1_1 + ' name=' + (GetTankName(tank) || '?')); + } catch (e) {} + } + } return Friendly; } } catch(e) {} } - var Prev = TankFriendCache.get(tank); - return Prev === undefined ? false : Prev; + // 还没有可靠基准:先按敌人显示,但**不锁定** + return false; } // ===== 获取相机信息(场景主相机 scene.iyx_1) ===== diff --git a/3dtank_bundle.js b/3dtank_bundle.js index ba36db3..bd29e68 100644 --- a/3dtank_bundle.js +++ b/3dtank_bundle.js @@ -466,19 +466,21 @@ } // 本地队伍缓存:死亡后 u10b_1 会被清空(onTankUnpossessed),不能再用"当前观察目标"推断。 - // 这里记住最后一次有效的本地队伍,整局沿用。 + // ⚠ 这里**不跟随 gm 变化重置**:hook 重新捕获 GameMode 时 gm 会换实例, + // 若此时重置,死亡/观战状态下就会拿观战目标当基准 → 敌我整体翻转。 + // 只在「本地坦克实体变了」(换局/换车)时才重新缓存。 var LocalTeam = null; - var LocalTeamGm = null; + var LocalTeamTankId = null; function RememberLocalTeam(gm) { if (!ZCt) return; - if (gm !== LocalTeamGm) { LocalTeamGm = gm; LocalTeam = null; } - if (LocalTeam) return; + var t = null; + try { t = gm.u10b_1; } catch (e) { t = null; } + if (!t) return; // 死亡/观战:保持已有缓存 + var Id = t.iz1_1; + if (LocalTeam && LocalTeamTankId === Id) return; try { - var t = gm.u10b_1; - if (!t) return; var Team = ZCt(t); - // 只缓存"非中立"队伍(m2Fn(Team,Team) 为 true 表示同队且非中立) - if (Team && (!m2Fn || m2Fn(Team, Team))) LocalTeam = Team; + if (Team && (!m2Fn || m2Fn(Team, Team))) { LocalTeam = Team; LocalTeamTankId = Id; } } catch (e) {} } @@ -487,6 +489,7 @@ // 处理:① 每辆坦克缓存最近一次**非中立**队伍;② 无法判定时沿用上一次判定结果。 var TankTeamCache = new WeakMap(); // tank -> 非中立队伍对象 var TankFriendCache = new WeakMap(); // tank -> 上一次的友方判定 + var TeamLockLogged = new WeakSet(); function ResolveTankTeam(tank) { if (!ZCt) return null; var Team = null; @@ -501,6 +504,9 @@ function IsFriendly(tank, playerTank, gm) { if (!tank) return false; if (gm) RememberLocalTeam(gm); + // 一旦在「本地队伍可靠」时判过,就锁定本局结果,避免任何同步抖动导致颜色翻转 + var Locked = TankFriendCache.get(tank); + if (Locked !== undefined) return Locked; if (ZCt && m2Fn) { try { var tankTeam = ResolveTankTeam(tank); @@ -508,13 +514,22 @@ if (!BaseTeam && playerTank) BaseTeam = ResolveTankTeam(playerTank); if (tankTeam && BaseTeam) { var Friendly = m2Fn(tankTeam, BaseTeam); - TankFriendCache.set(tank, Friendly); + if (LocalTeam) { + TankFriendCache.set(tank, Friendly); + // 诊断:首次锁定为友方时记一条,便于核对有没有把敌人锁成队友 + if (Friendly && !TeamLockLogged.has(tank)) { + TeamLockLogged.add(tank); + try { + console.log('[敌我] 锁定为友方 id=' + tank.iz1_1 + ' name=' + (GetTankName(tank) || '?')); + } catch (e) {} + } + } return Friendly; } } catch(e) {} } - var Prev = TankFriendCache.get(tank); - return Prev === undefined ? false : Prev; + // 还没有可靠基准:先按敌人显示,但**不锁定** + return false; } // ===== 获取相机信息(场景主相机 scene.iyx_1) ===== diff --git a/tools/hornet_lib.js b/tools/hornet_lib.js index 80ad67d..b22b4dc 100644 --- a/tools/hornet_lib.js +++ b/tools/hornet_lib.js @@ -251,19 +251,21 @@ } // 本地队伍缓存:死亡后 u10b_1 会被清空(onTankUnpossessed),不能再用"当前观察目标"推断。 - // 这里记住最后一次有效的本地队伍,整局沿用。 + // ⚠ 这里**不跟随 gm 变化重置**:hook 重新捕获 GameMode 时 gm 会换实例, + // 若此时重置,死亡/观战状态下就会拿观战目标当基准 → 敌我整体翻转。 + // 只在「本地坦克实体变了」(换局/换车)时才重新缓存。 var LocalTeam = null; - var LocalTeamGm = null; + var LocalTeamTankId = null; function RememberLocalTeam(gm) { if (!ZCt) return; - if (gm !== LocalTeamGm) { LocalTeamGm = gm; LocalTeam = null; } - if (LocalTeam) return; + var t = null; + try { t = gm.u10b_1; } catch (e) { t = null; } + if (!t) return; // 死亡/观战:保持已有缓存 + var Id = t.iz1_1; + if (LocalTeam && LocalTeamTankId === Id) return; try { - var t = gm.u10b_1; - if (!t) return; var Team = ZCt(t); - // 只缓存"非中立"队伍(m2Fn(Team,Team) 为 true 表示同队且非中立) - if (Team && (!m2Fn || m2Fn(Team, Team))) LocalTeam = Team; + if (Team && (!m2Fn || m2Fn(Team, Team))) { LocalTeam = Team; LocalTeamTankId = Id; } } catch (e) {} } @@ -272,6 +274,7 @@ // 处理:① 每辆坦克缓存最近一次**非中立**队伍;② 无法判定时沿用上一次判定结果。 var TankTeamCache = new WeakMap(); // tank -> 非中立队伍对象 var TankFriendCache = new WeakMap(); // tank -> 上一次的友方判定 + var TeamLockLogged = new WeakSet(); function ResolveTankTeam(tank) { if (!ZCt) return null; var Team = null; @@ -286,6 +289,9 @@ function IsFriendly(tank, playerTank, gm) { if (!tank) return false; if (gm) RememberLocalTeam(gm); + // 一旦在「本地队伍可靠」时判过,就锁定本局结果,避免任何同步抖动导致颜色翻转 + var Locked = TankFriendCache.get(tank); + if (Locked !== undefined) return Locked; if (ZCt && m2Fn) { try { var tankTeam = ResolveTankTeam(tank); @@ -293,13 +299,22 @@ if (!BaseTeam && playerTank) BaseTeam = ResolveTankTeam(playerTank); if (tankTeam && BaseTeam) { var Friendly = m2Fn(tankTeam, BaseTeam); - TankFriendCache.set(tank, Friendly); + if (LocalTeam) { + TankFriendCache.set(tank, Friendly); + // 诊断:首次锁定为友方时记一条,便于核对有没有把敌人锁成队友 + if (Friendly && !TeamLockLogged.has(tank)) { + TeamLockLogged.add(tank); + try { + console.log('[敌我] 锁定为友方 id=' + tank.iz1_1 + ' name=' + (GetTankName(tank) || '?')); + } catch (e) {} + } + } return Friendly; } } catch(e) {} } - var Prev = TankFriendCache.get(tank); - return Prev === undefined ? false : Prev; + // 还没有可靠基准:先按敌人显示,但**不锁定** + return false; } // ===== 获取相机信息(场景主相机 scene.iyx_1) =====