From 99d006c73f7d5acf96b8d44ed3bd256d6db10330 Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 16 Nov 2009 17:26:38 +1300 Subject: [PATCH] NetworkOrderSource. - Also, fixed the bug where watching a replay that contained non-localplayer production orders crashed. --- OpenRa.Game/Game.cs | 5 ++- OpenRa.Game/OrderManager.cs | 74 +++++++++++++++++++++++++++++++------ OpenRa.Game/Player.cs | 3 ++ OpenRa.Game/Sidebar.cs | 1 - 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 26bc780818..20a917c19f 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -10,6 +10,7 @@ using OpenRa.Game.GameRules; using OpenRa.Game.Graphics; using OpenRa.Game.Traits; using OpenRa.Game.Support; +using System.Net.Sockets; namespace OpenRa.Game { @@ -78,8 +79,10 @@ namespace OpenRa.Game soundEngine = new ISoundEngine(); sounds = new Cache(LoadSound); + var socket = new TcpClient( "127.0.0.1", 1234 ); + orderManager = (Replay == "") - ? new OrderManager(new[] { new LocalOrderSource() }, "replay.rep") + ? new OrderManager(new[] { new NetworkOrderSource( socket ) }, "replay.rep") : new OrderManager(new[] { new ReplayOrderSource(Replay) }); PlaySound("intro.aud", false); diff --git a/OpenRa.Game/OrderManager.cs b/OpenRa.Game/OrderManager.cs index 5f86d5dfb6..bf7f714e74 100755 --- a/OpenRa.Game/OrderManager.cs +++ b/OpenRa.Game/OrderManager.cs @@ -5,6 +5,7 @@ using System.Text; using System.IO; using System.Net; using IjwFramework.Types; +using System.Net.Sockets; namespace OpenRa.Game { @@ -34,7 +35,7 @@ namespace OpenRa.Game return false; foreach( var p in players ) - p.Tick( localOrders ); + p.SendLocalOrders( frameNumber, localOrders ); if( savingReplay != null ) savingReplay.Write( frameNumber ); @@ -58,22 +59,23 @@ namespace OpenRa.Game interface OrderSource { - void Tick( List localOrders ); - List OrdersForFrame( int frameNumber ); + void SendLocalOrders( int localFrame, List localOrders ); + List OrdersForFrame( int currentFrame ); } class LocalOrderSource : OrderSource { - List orders; + Dictionary> orders = new Dictionary>(); - public void Tick( List localOrders ) + public List OrdersForFrame( int currentFrame ) { - orders = localOrders; + // TODO: prune `orders` based on currentFrame. + return orders[ currentFrame ]; } - public List OrdersForFrame( int frameNumber ) + public void SendLocalOrders( int localFrame, List localOrders ) { - return orders; + orders[ localFrame ] = localOrders; } } @@ -86,9 +88,7 @@ namespace OpenRa.Game replayReader.ReadUInt32(); } - public void Tick( List localOrders ) - { - } + public void SendLocalOrders( int localFrame, List localOrders ) { } public List OrdersForFrame( int frameNumber ) { @@ -113,5 +113,57 @@ namespace OpenRa.Game } } } + + } + + class NetworkOrderSource : OrderSource + { + int nextLocalOrderFrame = 0; + TcpClient socket; + BinaryReader reader; + + public NetworkOrderSource( TcpClient socket ) + { + this.socket = socket; + reader = new BinaryReader( socket.GetStream() ); + + var nextFrameId = System.BitConverter.GetBytes( nextLocalOrderFrame ); + socket.GetStream().Write( nextFrameId, 0, nextFrameId.Length ); + } + + public List OrdersForFrame( int currentFrame ) + { + if( currentFrame == 0 ) + { + var firstFrameNum = reader.ReadInt32(); + if( firstFrameNum != 0 ) + throw new InvalidOperationException( "Wrong frame number at start of stream" ); + } + + var ret = new List(); + while( true ) + { + var first = reader.ReadUInt32(); + if( first == currentFrame + 1 ) + return ret; + ret.Add( Order.Deserialize( reader, first ) ); + } + } + + public void SendLocalOrders( int localFrame, List localOrders ) + { + if( nextLocalOrderFrame != localFrame ) + throw new InvalidOperationException( "Attempted time-travel in NetworkOrderSource.SendLocalOrders()" ); + + foreach( var order in localOrders ) + { + var bytes = order.Serialize(); + socket.GetStream().Write( bytes, 0, bytes.Length ); + } + + ++nextLocalOrderFrame; + var nextFrameId = System.BitConverter.GetBytes( nextLocalOrderFrame ); + socket.GetStream().Write( nextFrameId, 0, nextFrameId.Length ); + } } } diff --git a/OpenRa.Game/Player.cs b/OpenRa.Game/Player.cs index 76d43c7e59..7d8c10dbac 100644 --- a/OpenRa.Game/Player.cs +++ b/OpenRa.Game/Player.cs @@ -22,6 +22,9 @@ namespace OpenRa.Game this.Race = race; this.Cash = 10000; this.powerProvided = this.powerDrained = 0; + + foreach( var cat in Rules.Categories.Keys ) + ProductionInit( cat ); } public void ChangePower(int dPower) diff --git a/OpenRa.Game/Sidebar.cs b/OpenRa.Game/Sidebar.cs index 2ff6fcc6c7..808c90ea2e 100644 --- a/OpenRa.Game/Sidebar.cs +++ b/OpenRa.Game/Sidebar.cs @@ -49,7 +49,6 @@ namespace OpenRa.Game foreach (string group in groups) { - player.ProductionInit( group ); clockAnimations.Add( group, new Animation( "clock" ) ); clockAnimations[ group ].PlayFetchIndex( "idle", ClockAnimFrame( group ) ); }