Improve replay metadata and the replay browser
List of changes: * Better and more filters with new layout, for both mods. * Rename/Delete/Detele all functionality. * Simplified ReplayMetadata class considerably by introducing a new GameInformation data object. The new GameInformation class contains more information than previously available so the new solution is not compatible with old replays, meaning it can't read old replays. * Better and cleaner game information gathering in order to be written at the end of the replay file. * Revert changes to ReplayConnection, no longer necessary. * Better exception message on missing sprites and fonts. * New "SpawnOccupant" class that holds all the information needed by the MapPreviewWidget to visualize a spawn point. It was using Session.Client before and it was necessary to separate it to be able to show information not available at lobby time. * Fix keyboard focus UI bug when closing a window would not remove focus.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Network
|
||||
@@ -34,60 +35,52 @@ namespace OpenRA.Network
|
||||
public readonly Session LobbyInfo;
|
||||
|
||||
public ReplayConnection(string replayFilename)
|
||||
{
|
||||
using (var rs = File.OpenRead(replayFilename))
|
||||
Read(rs, ref TickCount, ref IsValid, ref LobbyInfo);
|
||||
|
||||
ordersFrame = LobbyInfo.GlobalSettings.OrderLatency;
|
||||
}
|
||||
|
||||
public ReplayConnection(FileStream rs)
|
||||
{
|
||||
Read(rs, ref TickCount, ref IsValid, ref LobbyInfo);
|
||||
}
|
||||
|
||||
void Read(FileStream rs, ref int TickCount, ref bool IsValid, ref Session LobbyInfo)
|
||||
{
|
||||
// Parse replay data into a struct that can be fed to the game in chunks
|
||||
// to avoid issues with all immediate orders being resolved on the first tick.
|
||||
var chunk = new Chunk();
|
||||
|
||||
while (rs.Position < rs.Length)
|
||||
using (var rs = File.OpenRead(replayFilename))
|
||||
{
|
||||
var client = rs.ReadInt32();
|
||||
if (client == FileFormats.ReplayMetadata.MetaStartMarker)
|
||||
break;
|
||||
var packetLen = rs.ReadInt32();
|
||||
var packet = rs.ReadBytes(packetLen);
|
||||
var frame = BitConverter.ToInt32(packet, 0);
|
||||
chunk.Packets.Add(Pair.New(client, packet));
|
||||
var chunk = new Chunk();
|
||||
|
||||
if (packet.Length == 5 && packet[4] == 0xBF)
|
||||
continue; // disconnect
|
||||
else if (packet.Length >= 5 && packet[4] == 0x65)
|
||||
continue; // sync
|
||||
else if (frame == 0)
|
||||
while (rs.Position < rs.Length)
|
||||
{
|
||||
// Parse replay metadata from orders stream
|
||||
var orders = packet.ToOrderList(null);
|
||||
foreach (var o in orders)
|
||||
var client = rs.ReadInt32();
|
||||
if (client == ReplayMetadata.MetaStartMarker)
|
||||
break;
|
||||
var packetLen = rs.ReadInt32();
|
||||
var packet = rs.ReadBytes(packetLen);
|
||||
var frame = BitConverter.ToInt32(packet, 0);
|
||||
chunk.Packets.Add(Pair.New(client, packet));
|
||||
|
||||
if (packet.Length == 5 && packet[4] == 0xBF)
|
||||
continue; // disconnect
|
||||
else if (packet.Length >= 5 && packet[4] == 0x65)
|
||||
continue; // sync
|
||||
else if (frame == 0)
|
||||
{
|
||||
if (o.OrderString == "StartGame")
|
||||
IsValid = true;
|
||||
else if (o.OrderString == "SyncInfo" && !IsValid)
|
||||
LobbyInfo = Session.Deserialize(o.TargetString);
|
||||
// Parse replay metadata from orders stream
|
||||
var orders = packet.ToOrderList(null);
|
||||
foreach (var o in orders)
|
||||
{
|
||||
if (o.OrderString == "StartGame")
|
||||
IsValid = true;
|
||||
else if (o.OrderString == "SyncInfo" && !IsValid)
|
||||
LobbyInfo = Session.Deserialize(o.TargetString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular order - finalize the chunk
|
||||
chunk.Frame = frame;
|
||||
chunks.Enqueue(chunk);
|
||||
chunk = new Chunk();
|
||||
|
||||
TickCount = Math.Max(TickCount, frame);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular order - finalize the chunk
|
||||
chunk.Frame = frame;
|
||||
chunks.Enqueue(chunk);
|
||||
chunk = new Chunk();
|
||||
|
||||
TickCount = Math.Max(TickCount, frame);
|
||||
}
|
||||
}
|
||||
|
||||
ordersFrame = LobbyInfo.GlobalSettings.OrderLatency;
|
||||
}
|
||||
|
||||
// Do nothing: ignore locally generated orders
|
||||
|
||||
Reference in New Issue
Block a user