394 lines
13 KiB
C#
394 lines
13 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace MegaKoop.Game.Networking
|
|
{
|
|
public enum NetworkMessageType : byte
|
|
{
|
|
Heartbeat = 0,
|
|
LobbyState = 1,
|
|
PlayerInput = 2,
|
|
CharacterTransform = 3,
|
|
WeaponFire = 4,
|
|
HealthSync = 5,
|
|
ProjectileSpawn = 6,
|
|
ProjectileImpact = 7,
|
|
GameState = 8,
|
|
EnemySpawn = 9,
|
|
EnemyDespawn = 10
|
|
}
|
|
|
|
public enum ProjectileImpactKind : byte
|
|
{
|
|
Hero = 0,
|
|
Enemy = 1
|
|
}
|
|
|
|
public readonly struct NetworkMessage
|
|
{
|
|
public readonly NetworkMessageType Type;
|
|
public readonly byte[] Payload;
|
|
public readonly ulong Sender;
|
|
|
|
public NetworkMessage(NetworkMessageType type, byte[] payload, ulong sender)
|
|
{
|
|
Type = type;
|
|
Payload = payload;
|
|
Sender = sender;
|
|
}
|
|
}
|
|
|
|
public readonly struct PlayerInputMessage
|
|
{
|
|
public readonly int NetworkId;
|
|
public readonly Vector2 MoveInput;
|
|
public readonly bool JumpPressed;
|
|
|
|
public PlayerInputMessage(int networkId, Vector2 moveInput, bool jumpPressed)
|
|
{
|
|
NetworkId = networkId;
|
|
MoveInput = moveInput;
|
|
JumpPressed = jumpPressed;
|
|
}
|
|
|
|
public static byte[] Serialize(PlayerInputMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.NetworkId);
|
|
writer.Write(message.MoveInput.x);
|
|
writer.Write(message.MoveInput.y);
|
|
writer.Write(message.JumpPressed);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static PlayerInputMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
int id = reader.ReadInt();
|
|
float moveX = reader.ReadFloat();
|
|
float moveY = reader.ReadFloat();
|
|
bool jump = reader.ReadBool();
|
|
return new PlayerInputMessage(id, new Vector2(moveX, moveY), jump);
|
|
}
|
|
}
|
|
|
|
public readonly struct CharacterTransformMessage
|
|
{
|
|
public readonly int NetworkId;
|
|
public readonly Vector3 Position;
|
|
public readonly Quaternion Rotation;
|
|
public readonly Vector3 Velocity;
|
|
|
|
public CharacterTransformMessage(int networkId, Vector3 position, Quaternion rotation, Vector3 velocity)
|
|
{
|
|
NetworkId = networkId;
|
|
Position = position;
|
|
Rotation = rotation;
|
|
Velocity = velocity;
|
|
}
|
|
|
|
public static byte[] Serialize(CharacterTransformMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.NetworkId);
|
|
writer.Write(message.Position);
|
|
writer.Write(message.Rotation);
|
|
writer.Write(message.Velocity);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static CharacterTransformMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
int id = reader.ReadInt();
|
|
Vector3 position = reader.ReadVector3();
|
|
Quaternion rotation = reader.ReadQuaternion();
|
|
Vector3 velocity = reader.ReadVector3();
|
|
return new CharacterTransformMessage(id, position, rotation, velocity);
|
|
}
|
|
}
|
|
|
|
public readonly struct WeaponFireMessage
|
|
{
|
|
public readonly int NetworkId;
|
|
public readonly int WeaponIndex;
|
|
public readonly Vector3 MuzzlePosition;
|
|
public readonly Vector3 Direction;
|
|
public readonly float Timestamp;
|
|
|
|
public WeaponFireMessage(int networkId, int weaponIndex, Vector3 muzzlePosition, Vector3 direction, float timestamp)
|
|
{
|
|
NetworkId = networkId;
|
|
WeaponIndex = weaponIndex;
|
|
MuzzlePosition = muzzlePosition;
|
|
Direction = direction;
|
|
Timestamp = timestamp;
|
|
}
|
|
|
|
public static byte[] Serialize(WeaponFireMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.NetworkId);
|
|
writer.Write(message.WeaponIndex);
|
|
writer.Write(message.MuzzlePosition);
|
|
writer.Write(message.Direction);
|
|
writer.Write(message.Timestamp);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static WeaponFireMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
int networkId = reader.ReadInt();
|
|
int index = reader.ReadInt();
|
|
Vector3 muzzle = reader.ReadVector3();
|
|
Vector3 direction = reader.ReadVector3();
|
|
float time = reader.ReadFloat();
|
|
return new WeaponFireMessage(networkId, index, muzzle, direction, time);
|
|
}
|
|
}
|
|
|
|
public readonly struct HealthSyncMessage
|
|
{
|
|
public readonly int NetworkId;
|
|
public readonly float NormalizedHealth;
|
|
|
|
public HealthSyncMessage(int networkId, float normalizedHealth)
|
|
{
|
|
NetworkId = networkId;
|
|
NormalizedHealth = normalizedHealth;
|
|
}
|
|
|
|
public static byte[] Serialize(HealthSyncMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.NetworkId);
|
|
writer.Write(message.NormalizedHealth);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static HealthSyncMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
int id = reader.ReadInt();
|
|
float normalized = reader.ReadFloat();
|
|
return new HealthSyncMessage(id, normalized);
|
|
}
|
|
}
|
|
|
|
public readonly struct ProjectileSpawnMessage
|
|
{
|
|
public readonly int NetworkId;
|
|
public readonly int WeaponIndex;
|
|
public readonly Vector3 Position;
|
|
public readonly Vector3 Direction;
|
|
public readonly float Speed;
|
|
public readonly float Life;
|
|
public readonly float Damage;
|
|
|
|
public ProjectileSpawnMessage(int networkId, int weaponIndex, Vector3 position, Vector3 direction, float speed, float life, float damage)
|
|
{
|
|
NetworkId = networkId;
|
|
WeaponIndex = weaponIndex;
|
|
Position = position;
|
|
Direction = direction;
|
|
Speed = speed;
|
|
Life = life;
|
|
Damage = damage;
|
|
}
|
|
|
|
public static byte[] Serialize(ProjectileSpawnMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.NetworkId);
|
|
writer.Write(message.WeaponIndex);
|
|
writer.Write(message.Position);
|
|
writer.Write(message.Direction);
|
|
writer.Write(message.Speed);
|
|
writer.Write(message.Life);
|
|
writer.Write(message.Damage);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static ProjectileSpawnMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
int networkId = reader.ReadInt();
|
|
int index = reader.ReadInt();
|
|
Vector3 position = reader.ReadVector3();
|
|
Vector3 direction = reader.ReadVector3();
|
|
float speed = reader.ReadFloat();
|
|
float life = reader.ReadFloat();
|
|
float damage = reader.ReadFloat();
|
|
return new ProjectileSpawnMessage(networkId, index, position, direction, speed, life, damage);
|
|
}
|
|
}
|
|
|
|
public readonly struct ProjectileImpactMessage
|
|
{
|
|
public readonly ProjectileImpactKind Kind;
|
|
public readonly Vector3 Position;
|
|
public readonly Vector3 Normal;
|
|
|
|
public ProjectileImpactMessage(ProjectileImpactKind kind, Vector3 position, Vector3 normal)
|
|
{
|
|
Kind = kind;
|
|
Position = position;
|
|
Normal = normal;
|
|
}
|
|
|
|
public static byte[] Serialize(ProjectileImpactMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write((byte)message.Kind);
|
|
writer.Write(message.Position);
|
|
writer.Write(message.Normal);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static ProjectileImpactMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
ProjectileImpactKind kind = (ProjectileImpactKind)reader.ReadByte();
|
|
Vector3 position = reader.ReadVector3();
|
|
Vector3 normal = reader.ReadVector3();
|
|
return new ProjectileImpactMessage(kind, position, normal);
|
|
}
|
|
}
|
|
|
|
public enum GameStateEvent : byte
|
|
{
|
|
Started = 0,
|
|
Paused = 1,
|
|
Resumed = 2,
|
|
Stopped = 3,
|
|
WaveAdvanced = 4,
|
|
BossSpawned = 5,
|
|
Heartbeat = 6
|
|
}
|
|
|
|
public readonly struct GameStateMessage
|
|
{
|
|
public readonly GameStateEvent Event;
|
|
public readonly float Elapsed;
|
|
public readonly int CurrentWave;
|
|
public readonly int PreviousWave;
|
|
public readonly bool IsPaused;
|
|
public readonly bool IsRunning;
|
|
public readonly string DefinitionId;
|
|
public readonly int Count;
|
|
|
|
public GameStateMessage(GameStateEvent evt, float elapsed, int currentWave, int previousWave, bool isPaused, bool isRunning, string definitionId, int count)
|
|
{
|
|
Event = evt;
|
|
Elapsed = elapsed;
|
|
CurrentWave = currentWave;
|
|
PreviousWave = previousWave;
|
|
IsPaused = isPaused;
|
|
IsRunning = isRunning;
|
|
DefinitionId = definitionId ?? string.Empty;
|
|
Count = count;
|
|
}
|
|
|
|
public static byte[] Serialize(GameStateMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write((byte)message.Event);
|
|
writer.Write(message.Elapsed);
|
|
writer.Write(message.CurrentWave);
|
|
writer.Write(message.PreviousWave);
|
|
writer.Write(message.IsPaused);
|
|
writer.Write(message.IsRunning);
|
|
writer.Write(message.DefinitionId ?? string.Empty);
|
|
writer.Write(message.Count);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static GameStateMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
GameStateEvent evt = (GameStateEvent)reader.ReadByte();
|
|
float elapsed = reader.ReadFloat();
|
|
int currentWave = reader.ReadInt();
|
|
int previousWave = reader.ReadInt();
|
|
bool isPaused = reader.ReadBool();
|
|
bool isRunning = reader.ReadBool();
|
|
string definitionId = reader.ReadString();
|
|
int count = reader.ReadInt();
|
|
return new GameStateMessage(evt, elapsed, currentWave, previousWave, isPaused, isRunning, definitionId, count);
|
|
}
|
|
}
|
|
|
|
public readonly struct EnemySpawnMessage
|
|
{
|
|
public readonly string DefinitionId;
|
|
public readonly Vector3 Position;
|
|
public readonly Quaternion Rotation;
|
|
public readonly int NetworkId;
|
|
public readonly bool IsBoss;
|
|
public readonly int WaveIndex;
|
|
public readonly float Timestamp;
|
|
|
|
public EnemySpawnMessage(string definitionId, Vector3 position, Quaternion rotation, int networkId, bool isBoss, int waveIndex, float timestamp)
|
|
{
|
|
DefinitionId = definitionId ?? string.Empty;
|
|
Position = position;
|
|
Rotation = rotation;
|
|
NetworkId = networkId;
|
|
IsBoss = isBoss;
|
|
WaveIndex = waveIndex;
|
|
Timestamp = timestamp;
|
|
}
|
|
|
|
public static byte[] Serialize(EnemySpawnMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.DefinitionId ?? string.Empty);
|
|
writer.Write(message.Position);
|
|
writer.Write(message.Rotation);
|
|
writer.Write(message.NetworkId);
|
|
writer.Write(message.IsBoss);
|
|
writer.Write(message.WaveIndex);
|
|
writer.Write(message.Timestamp);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static EnemySpawnMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
string definitionId = reader.ReadString();
|
|
Vector3 position = reader.ReadVector3();
|
|
Quaternion rotation = reader.ReadQuaternion();
|
|
int networkId = reader.ReadInt();
|
|
bool isBoss = reader.ReadBool();
|
|
int waveIndex = reader.ReadInt();
|
|
float timestamp = reader.ReadFloat();
|
|
return new EnemySpawnMessage(definitionId, position, rotation, networkId, isBoss, waveIndex, timestamp);
|
|
}
|
|
}
|
|
|
|
public readonly struct EnemyDespawnMessage
|
|
{
|
|
public readonly int NetworkId;
|
|
|
|
public EnemyDespawnMessage(int networkId)
|
|
{
|
|
NetworkId = networkId;
|
|
}
|
|
|
|
public static byte[] Serialize(EnemyDespawnMessage message)
|
|
{
|
|
using var writer = new NetworkWriter();
|
|
writer.Write(message.NetworkId);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
public static EnemyDespawnMessage Deserialize(byte[] buffer)
|
|
{
|
|
using var reader = new NetworkReader(buffer);
|
|
int id = reader.ReadInt();
|
|
return new EnemyDespawnMessage(id);
|
|
}
|
|
}
|
|
}
|