{"record":{"id":"25a800006c12a80c","repo":"babalae/better-genshin-impact","slug":"multigameplayercount-playerinde","errorCode":null,"errorMessage":"切换角色：无法为 {_multiGamePlayerCount} 人联机的 {_playerIndex}P 生成可控槽位","messagePattern":"切换角色：无法为 (.+?) 人联机的 (.+?)P 生成可控槽位","errorType":"exception","errorClass":"PartySetupFailedException","httpStatus":null,"severity":"critical","filePath":"BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs","lineNumber":1255,"sourceCode":"        throw new PartySetupFailedException(\n            $\"切换角色：等待单机图标、联机状态及 top_left 玩家标记超时（{timeoutMilliseconds / 1000} 秒），最后结果：{lastResult}\");\n    }\n\n    private void ConfigureOperableSlots()\n    {\n        int[] physicalSlots = (_multiGamePlayerCount, _playerIndex) switch\n        {\n            (1, _) => [1, 2, 3, 4],\n            (2, 1) => [1, 2],\n            (2, 2) => [3, 4],\n            (3, 1) => [1, 2],\n            (3, 2) => [3],\n            (3, 3) => [4],\n            (4, 1) => [1],\n            (4, 2) => [2],\n            (4, 3) => [3],\n            (4, 4) => [4],\n            _ => throw new PartySetupFailedException(\n                $\"切换角色：无法为 {_multiGamePlayerCount} 人联机的 {_playerIndex}P 生成可控槽位\")\n        };\n\n        _maxControlAvatarCount = physicalSlots.Length;\n        _logicalToPhysicalSlot = physicalSlots\n            .Select((physical, index) => (Logical: index + 1, Physical: physical))\n            .ToDictionary(pair => pair.Logical, pair => pair.Physical);\n\n        _logger.LogInformation(\"切换角色：{PlayerCount} 人队伍，{PlayerIndex}P 可控物理槽位 {Slots}\",\n            _multiGamePlayerCount, _playerIndex, string.Join(\",\", physicalSlots));\n    }\n\n    private void EnsureSlotIsOperable(int logicalSlot)\n    {\n        if (!_logicalToPhysicalSlot.ContainsKey(logicalSlot))\n        {\n            throw new PartySetupFailedException($\"切换角色：{logicalSlot} 号位超出当前账号可操作角色数 {_maxControlAvatarCount}\");\n        }","sourceCodeStart":1237,"sourceCodeEnd":1273,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs#L1237-L1273","documentation":"ConfigureOperableSlots maps the (playerCount, playerIndex) pair to the controllable physical slots via a switch expression covering only the documented co-op configurations. The default arm throws when the pair is outside that set — i.e. an unrecognized or impossible co-op combination that the slot-mapping table cannot handle.","triggerScenarios":"(_multiGamePlayerCount, _playerIndex) is none of the listed cases: commonly _playerIndex == 0 (never resolved), _playerIndex > _multiGamePlayerCount, or _multiGamePlayerCount > 4.","commonSituations":"DetectPlayerIndex left _playerIndex at 0 (detection partially failed then ConfigureOperableSlots ran anyway); a co-op mode with >4 players the code does not model; _multiGamePlayerCount was set from a noisy MultiGameStatus to a value >4; logic invoked ConfigureOperableSlots before player detection completed.","solutions":["Ensure DetectPlayerIndex succeeds (see error 387) before ConfigureOperableSlots; do not call ConfigureOperableSlots with _playerIndex==0.","Clamp/validate _multiGamePlayerCount to 1..4 and _playerIndex to 1.._multiGamePlayerCount before the switch.","If a new co-op configuration ships, add its case to the switch expression with the correct physical slots."],"exampleFix":"// before\nint[] physicalSlots = (_multiGamePlayerCount, _playerIndex) switch { ... };\n\n// after\nif (_playerIndex < 1 || _playerIndex > _multiGamePlayerCount || _multiGamePlayerCount is < 1 or > 4)\n{\n    throw new PartySetupFailedException($\"切换角色：无法为 {_multiGamePlayerCount} 人联机的 {_playerIndex}P 生成可控槽位\");\n}\nint[] physicalSlots = (_multiGamePlayerCount, _playerIndex) switch { ... };","handlingStrategy":"validation","validationCode":"if (_playerIndex < 1 || _playerIndex > _multiGamePlayerCount || _multiGamePlayerCount is < 1 or > 4)\n{\n    throw new PartySetupFailedException($\"切换角色：无效联机参数 count={_multiGamePlayerCount} index={_playerIndex}\");\n}","typeGuard":"static bool IsValidCoopPair(int count, int index)\n    => count is >= 1 and <= 4 && index is >= 1 and <= count;","tryCatchPattern":"try { await switchTask.Start(...); }\ncatch (PartySetupFailedException ex) when (ex.Message.Contains(\"生成可控槽位\"))\n{ _logger.LogError(ex, \"联机参数超出已支持范围，请确认玩家检测正确\"); }","preventionTips":["Never call ConfigureOperableSlots before DetectPlayerIndex resolves _playerIndex.","Clamp _multiGamePlayerCount to 1..4 and _playerIndex to 1..count.","Add new co-op configurations to the switch as the game evolves."],"tags":["party-setup","co-op","invariant","logic-bug","switch-character"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}