using MegaKoop.Game.WeaponSystem; using Steamworks; using UnityEngine; namespace MegaKoop.Game.Networking { [DisallowMultipleComponent] public class SteamWeaponNetworkBridge : MonoBehaviour { [SerializeField] private WeaponController weaponController; [SerializeField] private NetworkIdentity identity; [SerializeField] private bool disableLocalFiringWhenClient = true; private SteamCoopNetworkManager networkManager; private bool isRegistered; private void Awake() { networkManager = SteamCoopNetworkManager.Instance; if (weaponController == null) { weaponController = GetComponent(); } if (identity == null) { identity = GetComponent(); } } private void OnEnable() { if (weaponController == null || identity == null) { Debug.LogWarning("[SteamWeaponNetworkBridge] Missing references."); return; } if (networkManager == null) { networkManager = SteamCoopNetworkManager.Instance; } if (networkManager != null) { networkManager.RegisterHandler(NetworkMessageType.ProjectileSpawn, HandleProjectileSpawnMessage); isRegistered = true; } weaponController.ProjectileSpawned += OnProjectileSpawned; if (!IsAuthoritative() && disableLocalFiringWhenClient) { weaponController.enabled = false; } } private void OnDisable() { if (weaponController != null) { weaponController.ProjectileSpawned -= OnProjectileSpawned; if (!IsAuthoritative() && disableLocalFiringWhenClient) { weaponController.enabled = true; } } if (isRegistered && networkManager != null) { networkManager.UnregisterHandler(NetworkMessageType.ProjectileSpawn, HandleProjectileSpawnMessage); isRegistered = false; } } private bool IsAuthoritative() { if (networkManager == null) { return true; } return networkManager.IsHost; } private void OnProjectileSpawned(WeaponController.ProjectileSpawnEvent spawnEvent) { if (!IsAuthoritative()) { return; } if (networkManager == null) { return; } var message = new ProjectileSpawnMessage(identity.NetworkId, spawnEvent.WeaponIndex, spawnEvent.Position, spawnEvent.Direction, spawnEvent.Speed, spawnEvent.Lifetime, spawnEvent.Damage); byte[] payload = ProjectileSpawnMessage.Serialize(message); networkManager.SendToAll(NetworkMessageType.ProjectileSpawn, payload, EP2PSend.k_EP2PSendUnreliableNoDelay); } private void HandleProjectileSpawnMessage(NetworkMessage message) { if (message.Sender == SteamUser.GetSteamID().m_SteamID) { // Ignore our own echo. return; } ProjectileSpawnMessage spawnMessage = ProjectileSpawnMessage.Deserialize(message.Payload); if (spawnMessage.NetworkId != identity.NetworkId) { return; } if (IsAuthoritative()) { // Host already spawned real projectile, don't duplicate. return; } weaponController.SpawnNetworkProjectile(spawnMessage.WeaponIndex, spawnMessage.Position, spawnMessage.Direction, spawnMessage.Speed, spawnMessage.Life, spawnMessage.Damage); } } }