From a2636133cabf346bc869b0b7e7c0cfcb8c48db36 Mon Sep 17 00:00:00 2001 From: Regalis11 Date: Sun, 12 Jul 2015 18:25:34 +0300 Subject: [PATCH] WIP network message validation --- Subsurface/Characters/AI/EnemyAIController.cs | 38 ++++++++++---- Subsurface/Characters/Character.cs | 42 +++++++++------ Subsurface/Characters/Ragdoll.cs | 6 ++- Subsurface/Content/Items/Door/doors.xml | 4 +- Subsurface/Game1.cs | 4 +- Subsurface/Items/Components/Machines/Pump.cs | 15 +++++- .../Items/Components/Machines/Reactor.cs | 26 ++++++++-- Subsurface/Map/Submarine.cs | 30 ++++++----- Subsurface/MathUtils.cs | 27 ++++++---- Subsurface/Networking/GameClient.cs | 51 +++++++++++++++++-- Subsurface/Networking/NetworkEvent.cs | 10 ++-- Subsurface/Networking/NetworkMember.cs | 1 + Subsurface/Physics/PhysicsBody.cs | 18 +++++-- 13 files changed, 199 insertions(+), 73 deletions(-) diff --git a/Subsurface/Characters/AI/EnemyAIController.cs b/Subsurface/Characters/AI/EnemyAIController.cs index 0ff95d7e4..b372d7e55 100644 --- a/Subsurface/Characters/AI/EnemyAIController.cs +++ b/Subsurface/Characters/AI/EnemyAIController.cs @@ -475,19 +475,37 @@ namespace Subsurface public override void ReadNetworkData(NetIncomingMessage message) { - state = (AiState)(message.ReadByte()); + AiState newState = AiState.None; + Vector2 newWallAttackPos; + float wanderAngle; + float updateTargetsTimer, raycastTimer, coolDownTimer; - wallAttackPos.X = message.ReadFloat(); - wallAttackPos.Y = message.ReadFloat(); + int targetID; - steeringManager.WanderAngle = message.ReadFloat(); - updateTargetsTimer = message.ReadFloat(); - raycastTimer = message.ReadFloat(); - coolDownTimer = message.ReadFloat(); + try + { - int targetID = message.ReadInt32(); - - if (targetID>-1) + newState = (AiState)(message.ReadByte()); + newWallAttackPos = new Vector2(message.ReadFloat(), message.ReadFloat()); + + wanderAngle = MathUtils.WrapAngleTwoPi(message.ReadFloat()); + updateTargetsTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, UpdateTargetsInterval); + raycastTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, RaycastInterval); + coolDownTimer = MathHelper.Clamp(message.ReadFloat(), 0.0f, attackCoolDown); + + targetID = message.ReadInt32(); + } + + catch { return; } + + wallAttackPos = newWallAttackPos; + + steeringManager.WanderAngle = wanderAngle; + this.updateTargetsTimer = updateTargetsTimer; + this.raycastTimer = raycastTimer; + this.coolDownTimer = coolDownTimer; + + if (targetID > -1) targetEntity = Entity.FindEntityByID(targetID) as IDamageable; } diff --git a/Subsurface/Characters/Character.cs b/Subsurface/Characters/Character.cs index 65938ee66..25b82a20b 100644 --- a/Subsurface/Characters/Character.cs +++ b/Subsurface/Characters/Character.cs @@ -972,23 +972,35 @@ namespace Subsurface return; } - actionKeyDown.State = message.ReadBoolean(); - secondaryKeyDown.State = message.ReadBoolean(); + bool actionKeyState = false; + bool secondaryKeyState = false; + double sendingTime = 0.0f; + Vector2 targetMovement = Vector2.Zero; + bool targetDir = false; + Vector2 cursorPos = Vector2.Zero; - double sendingTime = message.ReadDouble(); - - Vector2 targetMovement = Vector2.Zero; - - targetMovement.X = message.ReadFloat(); - targetMovement.Y = message.ReadFloat(); + try + { + actionKeyState = message.ReadBoolean(); + secondaryKeyState = message.ReadBoolean(); + sendingTime = message.ReadDouble(); + + targetMovement = new Vector2 (message.ReadFloat(), message.ReadFloat()); + targetDir = message.ReadBoolean(); + + cursorPos = new Vector2(message.ReadFloat(), message.ReadFloat()); + } + + catch + { + return; + } + AnimController.IsStanding = true; - bool targetDir = message.ReadBoolean(); - - Vector2 cursorPos = Vector2.Zero; - cursorPos.X = message.ReadFloat(); - cursorPos.Y = message.ReadFloat(); + actionKeyDown.State = actionKeyState; + secondaryKeyDown.State = secondaryKeyState; if (sendingTime <= LastNetworkUpdate) return; @@ -1012,9 +1024,9 @@ namespace Subsurface float rotation = message.ReadFloat(); float angularVel = message.ReadFloat(); - if (vel != Vector2.Zero && vel.Length() > 100.0f) { } + //if (vel != Vector2.Zero && vel.Length() > 100.0f) { } - if (pos != Vector2.Zero && pos.Length() > 100.0f) { } + //if (pos != Vector2.Zero && pos.Length() > 100.0f) { } if (limb.body != null) { diff --git a/Subsurface/Characters/Ragdoll.cs b/Subsurface/Characters/Ragdoll.cs index cbd3b6d1f..dc9160fd4 100644 --- a/Subsurface/Characters/Ragdoll.cs +++ b/Subsurface/Characters/Ragdoll.cs @@ -62,7 +62,11 @@ namespace Subsurface public Vector2 TargetMovement { get { return (correctionMovement == Vector2.Zero) ? targetMovement : correctionMovement; } - set { targetMovement = value; } + set + { + targetMovement.X = MathHelper.Clamp(value.X, -3.0f, 3.0f); + targetMovement.Y = MathHelper.Clamp(value.Y, -3.0f, 3.0f); + } } public float HeadPosition diff --git a/Subsurface/Content/Items/Door/doors.xml b/Subsurface/Content/Items/Door/doors.xml index 3db3e79cd..f62eba26c 100644 --- a/Subsurface/Content/Items/Door/doors.xml +++ b/Subsurface/Content/Items/Door/doors.xml @@ -4,7 +4,7 @@ linkable="true" pickdistance="150.0"> - + @@ -26,7 +26,7 @@ linkable="true" pickdistance="150.0"> - + diff --git a/Subsurface/Game1.cs b/Subsurface/Game1.cs index 0d3ba535c..b4244a162 100644 --- a/Subsurface/Game1.cs +++ b/Subsurface/Game1.cs @@ -86,7 +86,7 @@ namespace Subsurface Graphics.PreferredBackBufferWidth = graphicsWidth; Graphics.PreferredBackBufferHeight = graphicsHeight; Content.RootDirectory = "Content"; - + //graphics.SynchronizeWithVerticalRetrace = false; //graphics.ApplyChanges(); @@ -132,7 +132,7 @@ namespace Subsurface { graphicsWidth = GraphicsDevice.Viewport.Width; graphicsHeight = GraphicsDevice.Viewport.Height; - + Sound.Init(); ConvertUnits.SetDisplayUnitToSimUnitRatio(Physics.DisplayToSimRation); diff --git a/Subsurface/Items/Components/Machines/Pump.cs b/Subsurface/Items/Components/Machines/Pump.cs index 5d6db21a5..409011e4d 100644 --- a/Subsurface/Items/Components/Machines/Pump.cs +++ b/Subsurface/Items/Components/Machines/Pump.cs @@ -188,8 +188,19 @@ namespace Subsurface.Items.Components public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message) { - flowPercentage = message.ReadFloat(); - isActive = message.ReadBoolean(); + float newFlow = 0.0f; + bool newActive; + + try + { + newFlow = MathHelper.Clamp(message.ReadFloat(), -100.0f, 100.0f); + newActive = message.ReadBoolean(); + } + + catch { return; } + + flowPercentage = newFlow; + isActive = newActive; } } } diff --git a/Subsurface/Items/Components/Machines/Reactor.cs b/Subsurface/Items/Components/Machines/Reactor.cs index 7a7a0927e..a1174408b 100644 --- a/Subsurface/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Items/Components/Machines/Reactor.cs @@ -393,12 +393,28 @@ namespace Subsurface.Items.Components public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) { - autoTemp = message.ReadBoolean(); - temperature = message.ReadFloat(); - shutDownTemp = message.ReadFloat(); + bool newAutoTemp; + float newTemperature, newShutDownTemp; + float newCoolingRate, newFissionRate; - coolingRate = message.ReadFloat(); - fissionRate = message.ReadFloat(); + try + { + newAutoTemp = message.ReadBoolean(); + newTemperature = message.ReadFloat(); + newShutDownTemp = message.ReadFloat(); + + newCoolingRate = message.ReadFloat(); + newFissionRate = message.ReadFloat(); + } + + catch { return; } + + autoTemp = newAutoTemp; + Temperature = newTemperature; + shutDownTemp = newShutDownTemp; + + CoolingRate = newCoolingRate; + FissionRate = newFissionRate; } } } diff --git a/Subsurface/Map/Submarine.cs b/Subsurface/Map/Submarine.cs index 9c65ec3ed..3ed35e861 100644 --- a/Subsurface/Map/Submarine.cs +++ b/Subsurface/Map/Submarine.cs @@ -109,7 +109,7 @@ namespace Subsurface public Vector2 Position { - get { return (Level.Loaded==null) ? Vector2.Zero : -Level.Loaded.Position; } + get { return (Level.Loaded == null) ? Vector2.Zero : -Level.Loaded.Position; } } public string FilePath @@ -561,20 +561,26 @@ namespace Subsurface public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message) { - double sendingTime = message.ReadDouble(); + double sendingTime; + Vector2 newTargetPosition, newSpeed; + try + { + sendingTime = message.ReadDouble(); - if (sendingTime <= lastNetworkUpdate) return; + if (sendingTime <= lastNetworkUpdate) return; - //Vector2 newPosition = - //if (newPosition == Position) return; - //if ((newPosition - Position).Length() > 500.0f) - //{ - // System.Diagnostics.Debug.WriteLine("Submarine has moved over 500 pixels since last update"); - // return; - //} + newTargetPosition = new Vector2(message.ReadFloat(), message.ReadFloat()); + newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat()); + } - targetPosition = new Vector2(message.ReadFloat(), message.ReadFloat()); - speed = new Vector2(message.ReadFloat(), message.ReadFloat()); + catch + { + return; + } + + + targetPosition = newTargetPosition; + speed = newSpeed; lastNetworkUpdate = sendingTime; } diff --git a/Subsurface/MathUtils.cs b/Subsurface/MathUtils.cs index 696d424df..d1c9e67c4 100644 --- a/Subsurface/MathUtils.cs +++ b/Subsurface/MathUtils.cs @@ -27,16 +27,9 @@ namespace Subsurface public static float CurveAngle(float from, float to, float step) { - // Ensure that 0 <= angle < 2pi for both "from" and "to" - while (from < 0) - from += MathHelper.TwoPi; - while (from >= MathHelper.TwoPi) - from -= MathHelper.TwoPi; - while (to < 0) - to += MathHelper.TwoPi; - while (to >= MathHelper.TwoPi) - to -= MathHelper.TwoPi; + from = WrapAngleTwoPi(from); + to = WrapAngleTwoPi(to); if (Math.Abs(from - to) < MathHelper.Pi) { @@ -59,9 +52,16 @@ namespace Subsurface return retVal; } + /// + /// wrap the angle between 0.0f and 2pi + /// public static float WrapAngleTwoPi(float angle) { - // Ensure that 0 <= angle < 2pi for both "from" and "to" + if (float.IsInfinity(angle) || float.IsNegativeInfinity(angle) || float.IsNaN(angle)) + { + return 0.0f; + } + while (angle < 0) angle += MathHelper.TwoPi; while (angle >= MathHelper.TwoPi) @@ -70,8 +70,15 @@ namespace Subsurface return angle; } + /// + /// wrap the angle between -pi and pi + /// public static float WrapAnglePi(float angle) { + if (float.IsInfinity(angle) || float.IsNegativeInfinity(angle) || float.IsNaN(angle)) + { + return 0.0f; + } // Ensure that -pi <= angle < pi for both "from" and "to" while (angle < -MathHelper.Pi) angle += MathHelper.TwoPi; diff --git a/Subsurface/Networking/GameClient.cs b/Subsurface/Networking/GameClient.cs index 1a7a5d6a4..2b70a109c 100644 --- a/Subsurface/Networking/GameClient.cs +++ b/Subsurface/Networking/GameClient.cs @@ -188,13 +188,20 @@ namespace Subsurface.Networking public override void Update() { + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.K)) + { + SendRandomData(); + } + + if (!connected || updateTimer > DateTime.Now) return; - if (reconnectBox != null) - { - ConnectToServer(serverIP); - return; - } + //if (reconnectBox != null) + //{ + // ConnectToServer(serverIP); + // return; + //} if (Client.ConnectionStatus == NetConnectionStatus.Disconnected) { @@ -458,5 +465,39 @@ namespace Subsurface.Networking Client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } + /// + /// sends some random data to the server (can be a networkevent or just something completely random) + /// use for debugging purposes + /// + public void SendRandomData() + { + NetOutgoingMessage msg = Client.CreateMessage(); + switch (Rand.Int(4)) + { + case 0: + msg.Write((byte)PacketTypes.NetworkEvent); + msg.Write((byte)NetworkEventType.UpdateEntity); + msg.Write(Rand.Int(MapEntity.mapEntityList.Count)); + break; + case 1: + msg.Write((byte)PacketTypes.NetworkEvent); + msg.Write((byte)Enum.GetNames(typeof(NetworkEventType)).Length); + msg.Write(Rand.Int(MapEntity.mapEntityList.Count)); + break; + case 2: + msg.Write((byte)Enum.GetNames(typeof(PacketTypes)).Length); + break; + } + + int byteCount = Rand.Int(100); + for (int i = 0; i