public SkirmishManager(Game game) { _game = game; _listener = new EventBasedNetListener(); _manager = new NetManager(_listener) { ReuseAddress = true, IPv6Enabled = IPv6Mode.Disabled, // TODO: temporary }; _writer = new NetDataWriter(); _processor = new NetPacketProcessor(); _processor.RegisterNestedType(SkirmishSlot.Serialize, SkirmishSlot.Deserialize); _processor.SubscribeReusable <SkirmishClientConnectPacket, SkirmishSlot>(SkirmishClientConnectPacketReceived); _processor.SubscribeReusable <SkirmishClientUpdatePacket, (IPEndPoint endPoint, int processId)>(SkirmishClientUpdatePacketReceived); _processor.SubscribeReusable <SkirmishSlotStatusPacket>(SkirmishStatusPacketReceived); _listener.PeerConnectedEvent += peer => Logger.Trace($"{peer.EndPoint} connected"); _listener.PeerDisconnectedEvent += (peer, info) => Logger.Trace($"{peer.EndPoint} disconnected with reason {info.Reason}"); _listener.ConnectionRequestEvent += request => { var nextFreeSlot = SkirmishGame.Slots.FirstOrDefault(s => s.State == SkirmishSlotState.Open); if (nextFreeSlot != null) { Logger.Trace($"Accepting connection from {request.RemoteEndPoint}"); var peer = request.Accept(); _processor.ReadPacket(request.Data, nextFreeSlot); nextFreeSlot.State = SkirmishSlotState.Human; nextFreeSlot.EndPoint = peer.EndPoint; } else { Logger.Trace($"Rejecting connection from {request.RemoteEndPoint}"); request.Reject(); } }; _listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod) => { var type = (PacketType)dataReader.GetByte(); switch (type) { case PacketType.SkirmishSlotStatus: _processor.ReadPacket(dataReader); break; case PacketType.SkirmishClientUpdate: _processor.ReadPacket(dataReader, fromPeer.Id); break; case PacketType.SkirmishStartGame: Logger.Trace($"Received start game packet"); CreateNetworkConnection(); break; } }; }