#nullable enable using System; using System.Collections.Generic; namespace ShrinkNetwork { public sealed class ShrinkNetworkMessageRegistry { private readonly Dictionary _opcodeToMeta = new(); private readonly Dictionary _typeToMeta = new(); public void Register(int opcode, string? route = null) where TMessage : IShrinkNetworkMessage => Register(typeof(TMessage), opcode, route); public void Register(Type messageType, int opcode, string? route = null) { if (messageType == null) throw new ArgumentNullException(nameof(messageType)); if (!typeof(IShrinkNetworkMessage).IsAssignableFrom(messageType)) throw new ArgumentException($"Type {messageType.FullName} is not a network message.", nameof(messageType)); if (_opcodeToMeta.ContainsKey(opcode)) throw new InvalidOperationException($"Opcode {opcode} is already registered."); if (_typeToMeta.ContainsKey(messageType)) throw new InvalidOperationException($"Message type {messageType.FullName} is already registered."); var meta = new ShrinkNetworkMessageMeta(opcode, messageType, route); _opcodeToMeta.Add(opcode, meta); _typeToMeta.Add(messageType, meta); } public bool TryGetMeta(int opcode, out ShrinkNetworkMessageMeta? meta) => _opcodeToMeta.TryGetValue(opcode, out meta); public bool TryGetMeta(Type type, out ShrinkNetworkMessageMeta? meta) => _typeToMeta.TryGetValue(type, out meta); public ShrinkNetworkMessageMeta GetMeta() where TMessage : IShrinkNetworkMessage => GetMeta(typeof(TMessage)); public ShrinkNetworkMessageMeta GetMeta(Type type) { if (_typeToMeta.TryGetValue(type, out var meta)) return meta; throw new KeyNotFoundException($"Message type {type.FullName} is not registered."); } } public sealed class ShrinkNetworkMessageMeta { public int Opcode { get; } public Type MessageType { get; } public string? Route { get; } public ShrinkNetworkMessageMeta(int opcode, Type messageType, string? route) { Opcode = opcode; MessageType = messageType; Route = route; } } }