Skip to content

Commit

Permalink
Refactor server orders
Browse files Browse the repository at this point in the history
  • Loading branch information
teinarss committed Jun 14, 2021
1 parent b3b1072 commit 947239f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 13 deletions.
10 changes: 10 additions & 0 deletions OpenRA.Game/Network/Order.cs
Expand Up @@ -199,6 +199,12 @@ public static Order Deserialize(World world, BinaryReader r)
return new Order(name, null, false) { Type = OrderType.Handshake, TargetString = targetString };
}

case OrderType.Disconnect:
r.ReadString();
var extraData1 = r.ReadUInt32();

return new Order("disconnect", null, false) { Type = OrderType.Disconnect, ExtraData = extraData1 };

default:
{
Log.Write("debug", "Received unknown order with type {0}", type);
Expand Down Expand Up @@ -310,6 +316,10 @@ public byte[] Serialize()

switch (Type)
{
case OrderType.Disconnect:
w.Write(ExtraData);
break;

case OrderType.Handshake:
{
// Changing the Handshake order format will break cross-version switching
Expand Down
8 changes: 6 additions & 2 deletions OpenRA.Game/Network/OrderManager.cs
Expand Up @@ -131,8 +131,12 @@ public void TickImmediate()
return;
var frame = BitConverter.ToInt32(packet, 0);
if (packet.Length == 5 && packet[4] == (byte)OrderType.Disconnect)
pendingPackets.Remove(clientId);
if (packet.Length == 20 && packet[4] == (byte)OrderType.Disconnect)
{
var disconnectPacket = packet.ToOrderList(World).First();
pendingPackets.Remove((int)disconnectPacket.ExtraData);
}
else if (packet.Length > 4 && packet[4] == (byte)OrderType.SyncHash)
{
if (packet.Length != 4 + Order.SyncHashOrderLength)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Network/ReplayConnection.cs
Expand Up @@ -115,7 +115,7 @@ public ReplayConnection(string replayFilename)
continue;

var packet = tmpPacketPair.Packet;
if (packet.Length == 5 && packet[4] == (byte)OrderType.Disconnect)
if (packet.Length == 20 && packet[4] == (byte)OrderType.Disconnect)
{
var lastClientFrame = lastClientsFrame[client];
var lastFramePacket = BitConverter.GetBytes(lastClientFrame);
Expand Down
39 changes: 29 additions & 10 deletions OpenRA.Game/Server/Server.cs
Expand Up @@ -743,20 +743,38 @@ public void DispatchOrdersToClients(Connection conn, int frame, byte[] data)
if (c != conn && c.Validated)
DispatchFrameToClient(c, from, frameData);

RecordOrder(frame, data, @from);
}

void RecordOrder(int frame, byte[] data, int @from)
{
if (recorder != null)
{
recorder.ReceiveFrame(from, frame, data);
recorder.ReceiveFrame(@from, frame, data);

if (data.Length > 0 && data[0] == (byte)OrderType.SyncHash)
{
if (data.Length == Order.SyncHashOrderLength)
HandleSyncOrder(frame, data);
else
Log.Write("server", $"Dropped sync order with length {data.Length} from client {from}. Expected length {Order.SyncHashOrderLength}.");
Log.Write("server",
$"Dropped sync order with length {data.Length} from client {@from}. Expected length {Order.SyncHashOrderLength}.");
}
}
}

public void DispatchServerOrdersToClients(byte[] data)
{
var from = 0;
var frame = 0;
var frameData = CreateFrame(from, frame, data);
foreach (var c in Conns.ToList())
if (c.Validated)
DispatchFrameToClient(c, from, frameData);

RecordOrder(frame, data, @from);
}

public void DispatchOrders(Connection conn, int frame, byte[] data)
{
if (frame == 0 && conn != null)
Expand Down Expand Up @@ -1039,7 +1057,9 @@ public void DropClient(Connection toDrop)
}
}

DispatchOrders(toDrop, toDrop.MostRecentFrame, new[] { (byte)OrderType.Disconnect });
var order = new Order("disconnect", null, false) { Type = OrderType.Disconnect, ExtraData = (uint)toDrop.PlayerIndex };

DispatchServerOrdersToClients(order.Serialize());

// All clients have left: clean up
if (!Conns.Any(c => c.Validated))
Expand All @@ -1061,7 +1081,7 @@ public void SyncLobbyInfo()
lock (LobbyInfo)
{
if (State == ServerState.WaitingPlayers) // Don't do this while the game is running, it breaks things!
DispatchOrders(null, 0, Order.FromTargetString("SyncInfo", LobbyInfo.Serialize(), true).Serialize());
DispatchServerOrdersToClients(Order.FromTargetString("SyncInfo", LobbyInfo.Serialize(), true).Serialize());

foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
t.LobbyInfoSynced(this);
Expand All @@ -1078,7 +1098,7 @@ public void SyncLobbyClients()
// TODO: Only need to sync the specific client that has changed to avoid conflicts!
var clientData = LobbyInfo.Clients.Select(client => client.Serialize()).ToList();

DispatchOrders(null, 0, Order.FromTargetString("SyncLobbyClients", clientData.WriteToString(), true).Serialize());
DispatchServerOrdersToClients(Order.FromTargetString("SyncLobbyClients", clientData.WriteToString(), true).Serialize());

foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
t.LobbyInfoSynced(this);
Expand All @@ -1095,7 +1115,7 @@ public void SyncLobbySlots()
// TODO: Don't sync all the slots if just one changed!
var slotData = LobbyInfo.Slots.Select(slot => slot.Value.Serialize()).ToList();

DispatchOrders(null, 0, Order.FromTargetString("SyncLobbySlots", slotData.WriteToString(), true).Serialize());
DispatchServerOrdersToClients(Order.FromTargetString("SyncLobbySlots", slotData.WriteToString(), true).Serialize());

foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
t.LobbyInfoSynced(this);
Expand All @@ -1111,7 +1131,7 @@ public void SyncLobbyGlobalSettings()
{
var sessionData = new List<MiniYamlNode> { LobbyInfo.GlobalSettings.Serialize() };

DispatchOrders(null, 0, Order.FromTargetString("SyncLobbyGlobalSettings", sessionData.WriteToString(), true).Serialize());
DispatchServerOrdersToClients(Order.FromTargetString("SyncLobbyGlobalSettings", sessionData.WriteToString(), true).Serialize());

foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
t.LobbyInfoSynced(this);
Expand All @@ -1126,7 +1146,7 @@ public void SyncClientPing()
var clientPings = LobbyInfo.ClientPings.Select(ping => ping.Serialize()).ToList();

// Note that syncing pings doesn't trigger INotifySyncLobbyInfo
DispatchOrders(null, 0, Order.FromTargetString("SyncClientPings", clientPings.WriteToString(), true).Serialize());
DispatchServerOrdersToClients(Order.FromTargetString("SyncClientPings", clientPings.WriteToString(), true).Serialize());
}
}

Expand Down Expand Up @@ -1194,8 +1214,7 @@ public void StartGame()
}
}

DispatchOrders(null, 0,
Order.FromTargetString("StartGame", startGameData, true).Serialize());
DispatchServerOrdersToClients(Order.FromTargetString("StartGame", startGameData, true).Serialize());

foreach (var t in serverTraits.WithInterface<IStartGame>())
t.GameStarted(this);
Expand Down

0 comments on commit 947239f

Please sign in to comment.