extract FrameData from OrderManager. fix disconnect bug in NetworkConnection
This commit is contained in:
@@ -114,12 +114,13 @@ namespace OpenRA.Network
|
|||||||
receivedPackets.Add( new ReceivedPacket { FromClient = client, Data = buf } );
|
receivedPackets.Add( new ReceivedPacket { FromClient = client, Data = buf } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( SocketException )
|
catch { }
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
connectionState = ConnectionState.NotConnected;
|
connectionState = ConnectionState.NotConnected;
|
||||||
|
if( socket != null )
|
||||||
|
socket.Close();
|
||||||
}
|
}
|
||||||
catch ( IOException ) { socket.Close(); }
|
|
||||||
catch (ThreadAbortException ) { socket.Close(); }
|
|
||||||
}
|
}
|
||||||
) { IsBackground = true };
|
) { IsBackground = true };
|
||||||
t.Start();
|
t.Start();
|
||||||
@@ -134,12 +135,10 @@ namespace OpenRA.Network
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
ms.Write(BitConverter.GetBytes((int)packet.Length));
|
ms.Write(BitConverter.GetBytes((int)packet.Length));
|
||||||
ms.Write(packet);
|
ms.Write(packet);
|
||||||
ms.WriteTo(socket.GetStream());
|
ms.WriteTo(socket.GetStream());
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (SocketException) { /* drop this on the floor; we'll pick up the disconnect from the reader thread */ }
|
catch (SocketException) { /* drop this on the floor; we'll pick up the disconnect from the reader thread */ }
|
||||||
catch (ObjectDisposedException) { /* ditto */ }
|
catch (ObjectDisposedException) { /* ditto */ }
|
||||||
|
|||||||
56
OpenRA.Game/Network/FrameData.cs
Executable file
56
OpenRA.Game/Network/FrameData.cs
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace OpenRA.Network
|
||||||
|
{
|
||||||
|
class FrameData
|
||||||
|
{
|
||||||
|
public struct ClientOrder
|
||||||
|
{
|
||||||
|
public int Client;
|
||||||
|
public Order Order;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly Dictionary<int, int> clientQuitTimes = new Dictionary<int, int>();
|
||||||
|
readonly Dictionary<int, Dictionary<int, byte[]>> framePackets = new Dictionary<int, Dictionary<int, byte[]>>();
|
||||||
|
|
||||||
|
public IEnumerable<int> ClientsPlayingInFrame( int frame )
|
||||||
|
{
|
||||||
|
return clientQuitTimes
|
||||||
|
.Where( x => frame <= x.Value )
|
||||||
|
.Select( x => x.Key )
|
||||||
|
.OrderBy( x => x );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClientQuit( int clientId, int lastClientFrame )
|
||||||
|
{
|
||||||
|
clientQuitTimes.Add( clientId, lastClientFrame );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddFrameOrders( int clientId, int frame, byte[] orders )
|
||||||
|
{
|
||||||
|
var frameData = framePackets.GetOrAdd( frame );
|
||||||
|
frameData.Add( clientId, orders );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsReadyForFrame( int frame )
|
||||||
|
{
|
||||||
|
var frameData = framePackets.GetOrAdd( frame );
|
||||||
|
return ClientsPlayingInFrame( frame )
|
||||||
|
.All( client => frameData.ContainsKey( client ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ClientOrder> OrdersForFrame( World world, int frame )
|
||||||
|
{
|
||||||
|
var frameData = framePackets[ frame ];
|
||||||
|
var clientData = ClientsPlayingInFrame( frame )
|
||||||
|
.ToDictionary( k => k, v => frameData[ v ] );
|
||||||
|
|
||||||
|
return clientData
|
||||||
|
.SelectMany( x => x.Value
|
||||||
|
.ToOrderList( world )
|
||||||
|
.Select( o => new ClientOrder { Client = x.Key, Order = o } ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,8 @@ namespace OpenRA.Network
|
|||||||
{
|
{
|
||||||
class OrderManager : IDisposable
|
class OrderManager : IDisposable
|
||||||
{
|
{
|
||||||
SyncReport syncReport = new SyncReport();
|
readonly SyncReport syncReport = new SyncReport();
|
||||||
|
readonly FrameData frameData = new FrameData();
|
||||||
|
|
||||||
public int FrameNumber { get; private set; }
|
public int FrameNumber { get; private set; }
|
||||||
|
|
||||||
@@ -29,10 +30,6 @@ namespace OpenRA.Network
|
|||||||
|
|
||||||
public readonly int SyncHeaderSize = 9;
|
public readonly int SyncHeaderSize = 9;
|
||||||
|
|
||||||
Dictionary<int, int> clientQuitTimes = new Dictionary<int, int>();
|
|
||||||
|
|
||||||
Dictionary<int, Dictionary<int, byte[]>> frameClientData =
|
|
||||||
new Dictionary<int, Dictionary<int, byte[]>>();
|
|
||||||
List<Order> localOrders = new List<Order>();
|
List<Order> localOrders = new List<Order>();
|
||||||
|
|
||||||
public void StartGame()
|
public void StartGame()
|
||||||
@@ -74,13 +71,13 @@ namespace OpenRA.Network
|
|||||||
{
|
{
|
||||||
var frame = BitConverter.ToInt32( packet, 0 );
|
var frame = BitConverter.ToInt32( packet, 0 );
|
||||||
if( packet.Length == 5 && packet[ 4 ] == 0xBF )
|
if( packet.Length == 5 && packet[ 4 ] == 0xBF )
|
||||||
clientQuitTimes[ clientId ] = frame;
|
frameData.ClientQuit( clientId, frame );
|
||||||
else if( packet.Length >= 5 && packet[ 4 ] == 0x65 )
|
else if( packet.Length >= 5 && packet[ 4 ] == 0x65 )
|
||||||
CheckSync( packet );
|
CheckSync( packet );
|
||||||
else if( frame == 0 )
|
else if( frame == 0 )
|
||||||
immediatePackets.Add( Pair.New( clientId, packet ) );
|
immediatePackets.Add( Pair.New( clientId, packet ) );
|
||||||
else
|
else
|
||||||
frameClientData.GetOrAdd( frame ).Add( clientId, packet );
|
frameData.AddFrameOrders( clientId, frame, packet );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
foreach( var p in immediatePackets )
|
foreach( var p in immediatePackets )
|
||||||
@@ -121,14 +118,9 @@ namespace OpenRA.Network
|
|||||||
syncForFrame.Add(frame, packet);
|
syncForFrame.Add(frame, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutOfSync( int frame , int index)
|
void OutOfSync(int frame, int index)
|
||||||
{
|
{
|
||||||
var frameData = clientQuitTimes
|
var order = frameData.OrdersForFrame( Game.world, frame ).ElementAt(index);
|
||||||
.Where( x => frame <= x.Value )
|
|
||||||
.OrderBy( x => x.Key )
|
|
||||||
.ToDictionary( k => k.Key, v => frameClientData[ FrameNumber ][ v.Key ] );
|
|
||||||
|
|
||||||
var order = frameData.SelectMany( o => o.Value.ToOrderList( Game.world ).Select( a => new { Client = o.Key, Order = a } ) ).ElementAt(index);
|
|
||||||
throw new InvalidOperationException("Out of sync in frame {0}.\n {1}".F(frame, order.Order.ToString()));
|
throw new InvalidOperationException("Out of sync in frame {0}.\n {1}".F(frame, order.Order.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,13 +136,7 @@ namespace OpenRA.Network
|
|||||||
|
|
||||||
public bool IsReadyForNextFrame
|
public bool IsReadyForNextFrame
|
||||||
{
|
{
|
||||||
get
|
get { return FrameNumber >= 1 && frameData.IsReadyForFrame( FrameNumber ); }
|
||||||
{
|
|
||||||
return FrameNumber > 0 &&
|
|
||||||
clientQuitTimes
|
|
||||||
.Where( x => FrameNumber <= x.Value )
|
|
||||||
.All( x => frameClientData.GetOrAdd( FrameNumber ).ContainsKey( x.Key ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick( World world )
|
public void Tick( World world )
|
||||||
@@ -161,14 +147,10 @@ namespace OpenRA.Network
|
|||||||
Connection.Send( localOrders.Serialize( FrameNumber + FramesAhead ) );
|
Connection.Send( localOrders.Serialize( FrameNumber + FramesAhead ) );
|
||||||
localOrders.Clear();
|
localOrders.Clear();
|
||||||
|
|
||||||
var frameData = clientQuitTimes
|
|
||||||
.Where( x => FrameNumber <= x.Value )
|
|
||||||
.OrderBy( x => x.Key )
|
|
||||||
.ToDictionary( k => k.Key, v => frameClientData[ FrameNumber ][ v.Key ] );
|
|
||||||
var sync = new List<int>();
|
var sync = new List<int>();
|
||||||
sync.Add( world.SyncHash() );
|
sync.Add( world.SyncHash() );
|
||||||
|
|
||||||
foreach( var order in frameData.SelectMany( o => o.Value.ToOrderList( world ).Select( a => new { Client = o.Key, Order = a } ) ) )
|
foreach( var order in frameData.OrdersForFrame( world, FrameNumber) )
|
||||||
{
|
{
|
||||||
UnitOrders.ProcessOrder( world, order.Client, order.Order );
|
UnitOrders.ProcessOrder( world, order.Client, order.Order );
|
||||||
sync.Add( world.SyncHash() );
|
sync.Add( world.SyncHash() );
|
||||||
|
|||||||
@@ -222,6 +222,7 @@
|
|||||||
<Compile Include="ActorReference.cs" />
|
<Compile Include="ActorReference.cs" />
|
||||||
<Compile Include="ModData.cs" />
|
<Compile Include="ModData.cs" />
|
||||||
<Compile Include="Map.cs" />
|
<Compile Include="Map.cs" />
|
||||||
|
<Compile Include="Network\FrameData.cs" />
|
||||||
<Compile Include="Network\ReplayConnection.cs" />
|
<Compile Include="Network\ReplayConnection.cs" />
|
||||||
<Compile Include="Network\Session.cs" />
|
<Compile Include="Network\Session.cs" />
|
||||||
<Compile Include="ObjectCreator.cs" />
|
<Compile Include="ObjectCreator.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user