예제 #1
0
        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;
                }
            };
        }