From dc2297bbdfecbe8d98af3176585a9abe8ed2827f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=96=B9=E6=88=90?= Date: Sun, 8 Feb 2026 11:04:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E6=89=AB=E9=9B=B7=20?= =?UTF-8?q?=E5=85=8D=E8=B4=B9-=E4=BB=98=E8=B4=B9=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/nakamaManager.js | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/utils/nakamaManager.js b/utils/nakamaManager.js index 9fd7484..58c0824 100644 --- a/utils/nakamaManager.js +++ b/utils/nakamaManager.js @@ -351,13 +351,23 @@ class NakamaManager { throw new Error('Missing game token in manager'); } - console.log('[Nakama] Adding to matchmaker:', minCount, '-', maxCount); + // ✅ 解析 gameType 确保免费场和付费场隔离匹配 + const gameType = this._parseGameTypeFromToken(this.gameToken); + if (!gameType) { + console.error('[Nakama] Failed to parse game_type from token'); + throw new Error('Invalid game token: missing game_type'); + } + + console.log('[Nakama] Adding to matchmaker:', minCount, '-', maxCount, 'gameType:', gameType); const response = await this._send({ matchmaker_add: { min_count: minCount || 2, max_count: maxCount || 2, - query: '+properties.game_token:*', - string_properties: { game_token: this.gameToken } + query: `+properties.game_type:${gameType}`, // ✅ 按游戏类型过滤匹配 + string_properties: { + game_token: this.gameToken, + game_type: gameType // ✅ 传递游戏类型用于匹配 + } } }); console.log('[Nakama] Matchmaker ticket:', response.matchmaker_ticket); @@ -619,6 +629,32 @@ class NakamaManager { return null; } } + + /** + * 从 game_token (JWT) 中解析 game_type + * 用于确保免费场和付费场隔离匹配 + */ + _parseGameTypeFromToken(token) { + try { + const parts = token.split('.'); + if (parts.length !== 3) return null; + + const payload = parts[1]; + // Base64 URL 解码 + const base64 = payload.replace(/-/g, '+').replace(/_/g, '/'); + const padded = base64 + '=='.slice(0, (4 - base64.length % 4) % 4); + + // 复用现有的 base64 解码工具 + const bytes = this._base64ToUint8Array(padded); + const str = this._utf8Decode(bytes); + const parsed = JSON.parse(str); + + return parsed.game_type || null; + } catch (e) { + console.error('[Nakama] Failed to parse game_type from token:', e); + return null; + } + } } export const nakamaManager = new NakamaManager();