137 lines
4.1 KiB
C#
137 lines
4.1 KiB
C#
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<WeaponController>();
|
|
}
|
|
|
|
if (identity == null)
|
|
{
|
|
identity = GetComponent<NetworkIdentity>();
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
ApplyLocalAuthoritySetting();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (weaponController != null)
|
|
{
|
|
weaponController.ProjectileSpawned -= OnProjectileSpawned;
|
|
|
|
if (disableLocalFiringWhenClient)
|
|
{
|
|
weaponController.SetLocalAuthority(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);
|
|
}
|
|
|
|
private void ApplyLocalAuthoritySetting()
|
|
{
|
|
if (weaponController == null || !disableLocalFiringWhenClient)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool allowLocalControl = IsAuthoritative();
|
|
weaponController.SetLocalAuthority(allowLocalControl);
|
|
}
|
|
}
|
|
}
|