Пример #1
0
        public static Packet ReadPacket(Stream stream)
        {
            var    packetType = stream.ReadByte();
            Packet packet     = null;

            switch (packetType)
            {
            case 1:
                packet = new RequestConnectPacket();
                packet.ReadPacketData(stream);
                return(packet);

            case 2:
                packet = new ConnectDecisionPacket();
                packet.ReadPacketData(stream);
                return(packet);

            case 3:
                packet = new InputPacket();
                packet.ReadPacketData(stream);
                return(packet);

            case 4:
                packet = new GameStatePacket();
                packet.ReadPacketData(stream);
                return(packet);

            default:
                throw new Exception("Unrecognized Packet Type");
            }
        }
        private void UpdateClientGamePad(InputPacket input)
        {
            Vector3 lookingAt = (input.CameraRotation - input.CameraPosition);
            var     unit      = (units.FirstOrDefault(a => a.ID() == input.SelectedBlackHoleID)) as IMovable;

            if (unit != null)
            {
                if (input.Front)
                {
                    var lookingAt2 = lookingAt;
                    lookingAt2.Normalize();
                    unit.Accelerate(lookingAt2);
                }
                if (input.Left)
                {
                    var lookingAt2 = Vector3.Cross(lookingAt, Vector3.Down);
                    lookingAt2.Normalize();
                    unit.Accelerate(lookingAt2);
                }
                if (input.Back)
                {
                    var lookingAt2 = -lookingAt;
                    lookingAt2.Normalize();
                    unit.Accelerate(lookingAt2);
                }
                if (input.Right)
                {
                    var lookingAt2 = Vector3.Cross(lookingAt, Vector3.Up);
                    lookingAt2.Normalize();
                    unit.Accelerate(lookingAt2);
                }
                if (input.Up)
                {
                    var lookingAt2 = Vector3.Cross(lookingAt, Vector3.Left);
                    lookingAt2.Normalize();
                    unit.Accelerate(lookingAt2);
                }
                if (input.Down)
                {
                    var lookingAt2 = Vector3.Cross(lookingAt, Vector3.Right);
                    lookingAt2.Normalize();
                    unit.Accelerate(lookingAt2);
                }
                if (input.Brake)
                {
                    unit.Brake();
                }
            }
        }
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);
            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
            {
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            }
            else
            {
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);
            }
            if (curPlayer.name == null)
            {
                curPlayer.name = Interaction.InputBox("Enter your name: ", "Name Entry");
                if (curPlayer.name.Length == 0)
                {
                    ExitScreen();
                }
            }

            var state = Keyboard.GetState();

            if (state.IsKeyDown(Keys.Home) && IsServer == null)
            {
                IsServer = true;
                selectedUnits.Add(units.First(a => (a is Blackhole) && (a as Blackhole).Owner() == IsServer.Value));
                new Task(() =>
                {
                    client  = client ?? new UdpClient(PORT, AddressFamily.InterNetwork);
                    client2 = client2 ?? new UdpClient(PORT2, AddressFamily.InterNetwork);
                    client3 = client3 ?? new UdpClient(PORT3, AddressFamily.InterNetwork);

                    IPHostEntry host;
                    string localIP = "?";
                    host           = Dns.GetHostEntry(Dns.GetHostName());
                    foreach (var ip in host.AddressList)
                    {
                        if (ip.AddressFamily == AddressFamily.InterNetwork)
                        {
                            localIP = ip.ToString();
                        }
                    }

                    ServerIP        = localIP;
                    ReceivingThread = new Thread(() => PacketQueue.Instance.TestLoop(client2, new IPEndPoint(IPAddress.Any, PORT2), packetProcessQueue, packetProcessQueueLock));
                    ReceivingThread.IsBackground = true;
                    ReceivingThread.Start();
                }).Start();
            }

            if (state.IsKeyDown(Keys.End) && IsServer == null)
            {
                IsServer = false;
                selectedUnits.Add(units.First(a => (a is Blackhole) && (a as Blackhole).Owner() == IsServer.Value));
                new Task(() =>
                {
                    ServerIP = Interaction.InputBox("What is the IP adress of the host?", "Connect");
                    if (ServerIP.Length == 0)
                    {
                        IsServer = null;
                        selectedUnits.Clear();
                        return;
                    }
                    client          = client ?? new UdpClient(PORT, AddressFamily.InterNetwork);
                    client2         = client2 ?? new UdpClient(PORT2, AddressFamily.InterNetwork);
                    client3         = client3 ?? new UdpClient(PORT3, AddressFamily.InterNetwork);
                    ReceivingThread = new Thread(() => PacketQueue.Instance.TestLoop(client, new IPEndPoint(new IPAddress(ServerIP.Split('.').Select(byte.Parse).ToArray()), PORT), packetProcessQueue, packetProcessQueueLock));
                    ReceivingThread.IsBackground = true;
                    ReceivingThread.Start();
                    ReceiveStatesThread = new Thread(() => ReceiveStates(client3, new IPEndPoint(new IPAddress(ServerIP.Split('.').Select(byte.Parse).ToArray()), PORT3)));
                    ReceiveStatesThread.IsBackground = true;
                    ReceiveStatesThread.Start();
                    curPlayer.playerID = false;
                    PacketQueue.Instance.AddPacket(new RequestConnectPacket {
                        Nickname = curPlayer.name
                    });
                }).Start();
            }

            if (state.IsKeyDown(Keys.Escape))
            {
                ExitScreen();
            }

            lock (packetProcessQueueLock)
                while (packetProcessQueue.Any())
                {
                    var packet = packetProcessQueue.Dequeue();
                    if (packet.GetPacketID() == 1)
                    {
                        var packet2 = (RequestConnectPacket)packet;
                        new Task(() =>
                        {
                            var response = Interaction.MsgBox("Would you like to allow " + packet2.Nickname + " to connect?", MsgBoxStyle.YesNo);
                            if (response == MsgBoxResult.Yes)
                            {
                                ClientIP = packet2.IPAddress;
                                PacketQueue.Instance.AddPacket(new ConnectDecisionPacket {
                                    Accepted = true
                                });
                                SendStatePacket(true);
                            }
                            else
                            {
                                ClientIP = packet2.IPAddress;
                                PacketQueue.Instance.AddPacket(new ConnectDecisionPacket {
                                    Accepted = false
                                });
                            }
                        }).Start();
                    }
                    if (packet.GetPacketID() == 2)
                    {
                        var packet2 = (ConnectDecisionPacket)packet;
                        Console.WriteLine(packet2.Accepted);
                        if (!packet2.Accepted)
                        {
                            IsServer = null;
                            selectedUnits.Clear();
                            ServerIP = null;
                            ReceivingThread.Abort();
                            ReceivingThread = null;
                            ReceiveStatesThread.Abort();
                            ReceiveStatesThread = null;
                            curPlayer.playerID  = false;
                            Interaction.MsgBox(
                                "Server declined your request to connect. You may try connecting to another host.");
                        }
                    }
                    if (packet.GetPacketID() == 3)
                    {
                        var packet2 = (InputPacket)packet;
                        if (!FrameNumber.HasValue)
                        {
                            //x frame delay before starting inputs. This allows the other players inputs to be here before we start processing.
                            FrameNumber = 0;
                        }
                        ClientInputBuffer.Add(packet2);
                    }
                    if (packet.GetPacketID() == 4)
                    {
                        var packet2 = (GameStatePacket)packet;
                        UpdateToState(packet2);

                        FrameNumber = 0;
                    }
                }

            if (FrameNumber.HasValue)
            {
                if (DateTime.Now - lastNetworkReceived > TimeSpan.FromSeconds(1))
                {
                    Environment.Exit(-1);
                }
                Vector3 average = new Vector3();
                foreach (IUnit u in selectedUnits)
                {
                    average += u.Position();
                }
                average        /= selectedUnits.Count;
                cameraDirection = average;
                //Send keyboard input to server. This is done using reliable UDP as keyboard inputs should generally not be dropped unless they don't arrive within the buffer on the other side.
                if (IsServer == false)
                {
                    UpdateGamePad();
                    //Selected units sounds like a bad idea considering it's a hashset and .First() can be any element...
                    //Yeah whatever John the Hashset was your idea
                    var packet = new InputPacket
                    {
                        FrameNumber         = FrameNumber.Value,
                        CameraPosition      = cameraPosition,
                        CameraRotation      = cameraDirection,
                        SelectedBlackHoleID = !selectedUnits.Any(a => a is Blackhole) ? -1 : selectedUnits.First(a => a is Blackhole).ID(),
                        Front = Keyboard.GetState().IsKeyDown(Keys.W),
                        Back  = Keyboard.GetState().IsKeyDown(Keys.S),
                        Left  = Keyboard.GetState().IsKeyDown(Keys.A),
                        Right = Keyboard.GetState().IsKeyDown(Keys.D),
                        Up    = Keyboard.GetState().IsKeyDown(Keys.LeftShift),
                        Down  = Keyboard.GetState().IsKeyDown(Keys.LeftControl),
                        Brake = Keyboard.GetState().IsKeyDown(Keys.Space)
                    };
                    PacketQueue.Instance.AddPacket(packet);

                    GameStatePacket best;
                    lock (ServerStateBufferLock)
                        best = ServerStateBuffer.OrderBy(a => a.Sequence).LastOrDefault();
                    if (best != default(GameStatePacket))
                    {
                        lock (ServerStateBufferLock)
                            ServerStateBuffer.Clear();
                        UpdateToState(best);
                    }
                }
                else if (IsServer == true)
                {
                    if (FrameNumber >= 0)
                    {
                        for (int i = 0; i < ClientInputBuffer.Count; i++)
                        {
                            if (ClientInputBuffer[i].FrameNumber <= FrameNumber)
                            {
                                var item = ClientInputBuffer[i];
                                UpdateGamePad();
                                UpdateClientGamePad(item);
                                ClientInputBuffer.RemoveAt(i);
                                i--;
                            }
                        }
                    }
                }
                Vector3 temp = cameraDirection - cameraPosition;
                temp.Normalize();
                cameraPosition      = cameraDirection - (camToPosition * temp);
                elapsedTimeSeconds += gameTime.ElapsedGameTime.TotalSeconds;
                List <GravitationalField> objects = new List <GravitationalField>();
                foreach (GravitationalField gravityObject in gravityObjects)
                {
                    objects.Add(gravityObject);
                }
                if (IsServer != false)
                {
                    foreach (GravitationalField gravityObject in gravityObjects)
                    {
                        if (gravityObject is Spheroid)
                        {
                            (gravityObject as Spheroid).Update(objects);
                        }
                    }
                    foreach (GravitationalField gravityObject in gravityObjects)
                    {
                        if (gravityObject is Spheroid)
                        {
                            (gravityObject as Spheroid).updatedInLoop = false;
                        }
                        //RK4
                        //gravityObject.Update((float)gameTime.TotalGameTime.TotalSeconds,(float)gameTime.ElapsedGameTime.TotalSeconds);
                        //EULER
                        gravityObject.Update();
                        foreach (IUnit unit in units)
                        {
                            if (unit is Base)
                            {
                                if (unit.GetBounds().Intersects(gravityObject.GetBounds()) && gravityObject.Owner() != unit.Owner())
                                {
                                    //end game
                                }
                            }
                        }
                    }
                    foreach (GravitationalField g in swallowedObjects)
                    {
                        units.Remove(g);
                        gravityObjects.Remove(g);
                        selectedUnits.Remove(g);
                    }
                    swallowedObjects.Clear();
                    if (selectedUnits.Count == 0)
                    {
                        selectedUnits.Add(units.First(a => a is Blackhole && ((Blackhole)a).Owner() == IsServer));
                    }

                    SendStatePacket();
                }
                FrameNumber++;
            }
            if (ServerIP != null)
            {
                if (IsServer == true && client != null && ClientIP != null)
                {
                    PacketQueue.TestFunc(client, new IPEndPoint(new IPAddress(ClientIP.Split('.').Select(byte.Parse).ToArray()), PORT));
                }
                else if (IsServer == false && client2 != null)
                {
                    PacketQueue.TestFunc(client2, new IPEndPoint(new IPAddress(ServerIP.Split('.').Select(byte.Parse).ToArray()), PORT2));
                }
            }
        }