// Assets/_Project/Scripts/Dev/DebugCommandRelay.cs using System.Collections.Generic; using Unity.Netcode; using UnityEngine; using TD.Gameplay.Draft; namespace TD.Dev { /// /// Debug-only network relay: exposes one RPC that force-applies a /// by its index, bypassing PlayerDraft's "must currently be /// offered" check. /// /// /// Lives entirely separate from PlayerDraft/DraftOption/DraftPool — none of those files /// know this component exists. Removing this component (and TD.Dev.DebugConsole, which /// calls it) leaves the shipping draft system completely untouched. /// /// Added to the Player prefab alongside PlayerDraft/PlayerGoldManager/etc. so it spawns /// with a per-player OwnerClientId. Static per-client registry mirrors PlayerDraft's /// GetForClient/Local pattern. /// public class DebugCommandRelay : NetworkBehaviour { private static readonly Dictionary s_byClientId = new Dictionary(); public static DebugCommandRelay GetForClient(ulong clientId) { s_byClientId.TryGetValue(clientId, out var relay); return relay; } public static DebugCommandRelay Local { get { var nm = NetworkManager.Singleton; if (nm == null || !nm.IsClient) return null; return GetForClient(nm.LocalClientId); } } public override void OnNetworkSpawn() { s_byClientId[OwnerClientId] = this; } public override void OnNetworkDespawn() { if (s_byClientId.TryGetValue(OwnerClientId, out var registered) && registered == this) s_byClientId.Remove(OwnerClientId); } /// /// Owning client: force-apply the DraftOption at (its /// DraftPool index) immediately, skipping the normal "must be currently offered" gate. /// Debug/testing only — any connected client can grant themselves anything via this /// RPC, same tradeoff DevWaveControls already accepts for its hotkeys. /// [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Owner)] public void DebugGrantDraftOptionRpc(int optionId) { var option = DraftPool.Instance != null ? DraftPool.Instance.Get(optionId) : null; if (option == null) { Debug.LogWarning($"[DebugCommandRelay] Grant requested for unknown option id {optionId}."); return; } if (option.ServerApply(OwnerClientId)) Debug.Log($"[DebugCommandRelay] Granted '{option.DisplayName}' to client {OwnerClientId}."); else Debug.LogWarning($"[DebugCommandRelay] '{option.DisplayName}' could not be applied " + $"to client {OwnerClientId}."); } } }