예제 #1
0
        private void ProcessPlayerMovement(NetPlayer p)
        {
            //TODO: if the player is too far behind, we insert fake movement

            while (p.MoveQueueUnverified.Count > 0)
            {
                var move = p.MoveQueueUnverified[0];
                p.MoveQueueUnverified.RemoveAt(0);
                //TODO: check for speed hacks etc
                Shared.ProcessMovementAndCollisions(move, p.ClientSimPlayer, shots, p.PreviousHits);
                var attackState = Shared.ProcessPlayerAttackCharge(move, p.ClientSimPlayer);
                if (attackState != null)
                {
                    PlayerAttack(p.ClientSimPlayer, attackState.Radius);
                }
                p.MoveQueueVerified.Add(move);
            }
            //Copy health and charge from client version to shared version of player
            //TODO: think through whether doing this immediately is bad (it won't be in sync with movement)
            p.Player.Health = p.ClientSimPlayer.Health;
            p.Player.Charge = p.ClientSimPlayer.Charge;

            //Publish any movement that is sufficiently old
            while (p.MoveQueueVerified.Count > 0)
            {
                int count = 0;
                var first = p.MoveQueueVerified[0];
                if (first.Tick < lastStep - playerReplayLag)
                {
                    p.Player.X += first.X;
                    p.Player.Y += first.Y;
                    p.MoveQueueVerified.RemoveAt(0);
                    count++;
                }
                else
                {
                    break;
                }
            }
        }
예제 #2
0
        private void Start()
        {
            Console.WriteLine("Starting game server…");

            creatureTypes    = new CreatureType[1];
            creatureTypes[0] = new CreatureType();

            stopwatch.Start();
            netPlayers = new List <NetPlayer>();
            players    = new List <Player>();
            creatures  = new List <Creature>();
            shots      = new List <Shot>();

            EventBasedNetListener listener = new EventBasedNetListener();
            NetManager            server   = new NetManager(listener, MaxClients, connectionKey);

            if (Packets.SimulateLatency)
            {
                server.SimulateLatency            = true;
                server.SimulationMinLatency       = Packets.SimulationMinLatency;
                server.SimulationMaxLatency       = Packets.SimulationMaxLatency;
                server.SimulatePacketLoss         = Packets.SimulatePacketLoss;
                server.SimulationPacketLossChance = Packets.SimulationPacketLossChance;
            }
            server.Start(Port);

            listener.PeerConnectedEvent += peer =>
            {
                Console.WriteLine("We got connection: {0}", peer.EndPoint);
                var netPlayer = new NetPlayer(peer.ConnectId, peer);
                netPlayer.Player          = new Player(NewPlayerId());
                netPlayer.ClientSimPlayer = new Player(NewPlayerId());
                netPlayers.Add(netPlayer);
                players.Add(netPlayer.Player);
                Console.WriteLine("{0} clients", server.GetPeers().Count());
                NetDataWriter writer = new NetDataWriter();
                writer.Put(Packets.WelcomeClient);
                writer.Put(netPlayer.Player.Id);
                writer.Put(lastStep);
                writer.Put(netPlayer.Player.X);
                writer.Put(netPlayer.Player.Y);
                peer.Send(writer, SendOptions.ReliableOrdered);
            };

            listener.NetworkReceiveEvent += (peer, reader) =>
            {
                byte packetType = reader.GetByte();
                if (packetType == Packets.Pong)
                {
                    var pingStart = reader.GetLong();
                    var lag       = stopwatch.ElapsedMilliseconds - pingStart;
                    Console.WriteLine("Ping: " + lag);
                }
                if (packetType == Packets.ClientMovement)
                {
                    var player = netPlayers.Find(p => p.PeerId == peer.ConnectId);
                    if (player == null)
                    {
                        Console.WriteLine("Peer tried to move but has no associated NetPlayer");
                    }
                    else
                    {
                        //Console.Write("Getting moveticks ");
                        var  count = reader.GetInt();
                        long tick  = reader.GetLong();
                        for (var i = 0; i < count; i++)
                        {
                            tick += reader.GetInt();                             //delta
                            sbyte x        = reader.GetSByte();
                            sbyte y        = reader.GetSByte();
                            bool  charging = reader.GetBool();
                            if (tick > player.LastAckedMove &&
                                !player.MoveQueueUnverified.Any(qm => qm.Tick == tick) &&
                                !player.MoveQueueVerified.Any(qm => qm.Tick == tick))
                            {
                                player.MoveQueueUnverified.Add(new QueuedMove(tick, x, y, charging));
                                //Console.WriteLine("Client Move: " + tick + " vs real time " + lastStep + " with " + count + " move snapshots");
                                //Console.WriteLine("Move lag: " + (lastStep - tick));
                            }                             // else dropping duplicate or out-of-order movement
                            if (i == count - 1 && player.LastAckedMove < tick)
                            {
                                player.LastAckedMove = tick;
                                player.RecordLatency((int)(lastStep - tick));
                            }
                        }
                        //Console.WriteLine();
                    }
                }
            };

            while (!Console.KeyAvailable)
            {
                long elapsed = stopwatch.ElapsedMilliseconds;
                while (elapsed > lastStep + simulationTickRate)
                {
                    Update(server);
                    lastStep = lastStep + simulationTickRate;
                }
                long postUpdateElapsed = stopwatch.ElapsedMilliseconds;
                int  earlyAmount       = (int)(lastStep + simulationTickRate - postUpdateElapsed);
                if (earlyAmount > 2)
                {
                    Thread.Sleep(earlyAmount - 2);
                }
            }

            server.Stop();
        }