using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using IjwFramework.Types; namespace OpenRa.Game { class OrderManager { BinaryWriter savingReplay; List players; int frameNumber = 0; public int FrameNumber { get { return frameNumber; } } public OrderManager( IEnumerable players ) { this.players = players.ToList(); } public OrderManager( IEnumerable players, string replayFilename ) : this( players ) { savingReplay = new BinaryWriter( new FileStream( replayFilename, FileMode.Create ) ); } public void Tick() { var localOrders = Game.controller.GetRecentOrders(); foreach( var p in players ) p.Tick( localOrders ); if( savingReplay != null ) savingReplay.Write( frameNumber ); var allOrders = players.SelectMany(p => p.OrdersForFrame(frameNumber)).OrderBy(o => o.Player.Index); foreach (var order in allOrders) { UnitOrders.ProcessOrder(order); if (savingReplay != null) savingReplay.Write(order.Serialize()); } ++frameNumber; // sanity check on the framenumber. This is 2^31 frames maximum, or multiple *years* at 40ms/frame. if( ( frameNumber & 0x80000000 ) != 0 ) throw new InvalidOperationException( "(OrderManager) Frame number too large" ); } } interface OrderSource { void Tick( List localOrders ); List OrdersForFrame( int frameNumber ); } class LocalOrderSource : OrderSource { List orders; public void Tick( List localOrders ) { orders = localOrders; } public List OrdersForFrame( int frameNumber ) { return orders; } } class ReplayOrderSource : OrderSource { BinaryReader replayReader; public ReplayOrderSource( string replayFilename ) { replayReader = new BinaryReader( File.Open( replayFilename, FileMode.Open ) ); replayReader.ReadUInt32(); } public void Tick( List localOrders ) { } public List OrdersForFrame( int frameNumber ) { var ret = new List(); while( true ) { try { var first = replayReader.ReadUInt32(); var order = Order.Deserialize( replayReader, first ); if( order == null ) { if( (uint)frameNumber + 1 != first ) throw new NotImplementedException(); return ret; } ret.Add( order ); } catch( EndOfStreamException ) { return ret; } } } } }