using System.Collections.Generic; using ProjectM.Simulation; using Unity.Entities; using Unity.NetCode; using UnityEngine; namespace ProjectM.Client { /// /// Client-side meta-purchase sender: a static enqueue (the Step-14 base meta-shop panel / execute_code) drained /// into RPCs. Carries only the upgrade ID — the tier is server-computed and the /// server re-validates everything (Staging gate, class mask, MaxTier, prereq, Aether affordability), so a stale /// or forged request is simply dropped. A real QUEUE (unlike the single-slot boon pick) — two rapid clicks on /// two different shop rows must both arrive. Statics reset on play-enter (the stale-bridge hazard). /// [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)] public partial class MetaSpendSendSystem : SystemBase { static readonly Queue s_Queue = new(); [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void ResetStatics() => s_Queue.Clear(); /// Queue a permanent-upgrade purchase by catalog id. The shop row click + execute_code drive this. public static void RequestPurchase(byte upgradeId) => s_Queue.Enqueue(upgradeId); protected override void OnCreate() { RequireForUpdate(); } protected override void OnUpdate() { while (s_Queue.Count > 0) { var req = EntityManager.CreateEntity(typeof(MetaSpendRequest), typeof(SendRpcCommandRequest)); EntityManager.SetComponentData(req, new MetaSpendRequest { UpgradeId = s_Queue.Dequeue() }); } } } }