From fb7f1f281749afca0dbdc6ddc16ac4a2f2c8cb66 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Wed, 2 Dec 2009 19:10:12 +1300 Subject: [PATCH] order validation; don't hold refs in local orders; etc --- OpenRa.Game/Order.cs | 44 ++++++++++++++++++++++++++++++--------- OpenRa.Game/UnitOrders.cs | 10 ++++++--- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/OpenRa.Game/Order.cs b/OpenRa.Game/Order.cs index 6fae49cdfb..7b07969f49 100644 --- a/OpenRa.Game/Order.cs +++ b/OpenRa.Game/Order.cs @@ -11,23 +11,41 @@ namespace OpenRa.Game { public readonly Player Player; public readonly string OrderString; - public readonly Actor Subject; - public readonly Actor TargetActor; + readonly uint SubjectId; + readonly uint TargetActorId; public readonly int2 TargetLocation; public readonly string TargetString; public bool IsImmediate; + public Actor Subject { get { return ActorFromUInt(SubjectId); } } + public Actor TargetActor { get { return ActorFromUInt(TargetActorId); } } + public Order(Player player, string orderString, Actor subject, Actor targetActor, int2 targetLocation, string targetString) + : this( player, orderString, UIntFromActor( subject ), + UIntFromActor( targetActor ), targetLocation, targetString ) {} + + Order(Player player, string orderString, uint subjectId, + uint targetActorId, int2 targetLocation, string targetString) { this.Player = player; this.OrderString = orderString; - this.Subject = subject; - this.TargetActor = targetActor; + this.SubjectId = subjectId; + this.TargetActorId = targetActorId; this.TargetLocation = targetLocation; this.TargetString = targetString; } + public bool Validate() + { + if ((SubjectId != 0xffffffff) && Subject == null) + return false; + if ((TargetActorId != 0xffffffff) && TargetActor == null) + return false; + + return true; + } + public byte[] Serialize() { if (IsImmediate) /* chat, whatever */ @@ -55,8 +73,8 @@ namespace OpenRa.Game w.Write( (byte)0xFF ); w.Write( (uint)Player.Index ); w.Write(OrderString); - w.Write(Subject == null ? 0xFFFFFFFF : Subject.ActorID); - w.Write(TargetActor == null ? 0xFFFFFFFF : TargetActor.ActorID); + w.Write(SubjectId); + w.Write(TargetActorId); w.Write(TargetLocation.X); w.Write(TargetLocation.Y); w.Write(TargetString != null); @@ -82,8 +100,8 @@ namespace OpenRa.Game { var playerID = r.ReadUInt32(); var order = r.ReadString(); - var subject = ActorFromUInt(r.ReadUInt32()); - var targetActor = ActorFromUInt(r.ReadUInt32()); + var subjectId = r.ReadUInt32(); + var targetActorId = r.ReadUInt32(); var targetLocation = new int2(r.ReadInt32(), 0); targetLocation.Y = r.ReadInt32(); var targetString = null as string; @@ -91,7 +109,7 @@ namespace OpenRa.Game targetString = r.ReadString(); return new Order( LookupPlayer(playerID), - order, subject, targetActor, targetLocation, + order, subjectId, targetActorId, targetLocation, targetString); } @@ -110,10 +128,16 @@ namespace OpenRa.Game } } + static uint UIntFromActor(Actor a) + { + if (a == null) return 0xffffffff; + return a.ActorID; + } + static Actor ActorFromUInt(uint aID) { if (aID == 0xFFFFFFFF) return null; - return Game.world.Actors.Where(x => x.ActorID == aID).First(); + return Game.world.Actors.SingleOrDefault(x => x.ActorID == aID); } // Named constructors for Orders. diff --git a/OpenRa.Game/UnitOrders.cs b/OpenRa.Game/UnitOrders.cs index c9a8e53b84..cdc374b95f 100755 --- a/OpenRa.Game/UnitOrders.cs +++ b/OpenRa.Game/UnitOrders.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; +using IjwFramework.Types; using OpenRa.Game.GameRules; using OpenRa.Game.Traits; -using IjwFramework.Types; -using System.Diagnostics; namespace OpenRa.Game { @@ -12,6 +10,12 @@ namespace OpenRa.Game { public static void ProcessOrder( Order order ) { + if (!order.Validate()) + { + /* todo: log this if we care */ + return; + } + switch( order.OrderString ) { case "Move":