internal static ReplayHeader Parse(BinaryReader reader) { var gameType = ParseGameType(reader.BaseStream); var result = new ReplayHeader { GameType = gameType }; result.StartTime = ReadTimestamp(reader); result.EndTime = ReadTimestamp(reader); if (gameType == ReplayGameType.Generals) { result.NumTimecodes = reader.ReadUInt16(); var zero = reader.ReadBytes(12); // TODO //for (var i = 0; i < zero.Length; i++) //{ // if (zero[i] != 0) // { // throw new InvalidDataException(); // } //} } else { throw new NotImplementedException(); } result.Filename = reader.ReadNullTerminatedString(); result.Timestamp = ReplayTimestamp.Parse(reader); result.Version = reader.ReadNullTerminatedString(); result.BuildDate = reader.ReadNullTerminatedString(); result.VersionMinor = reader.ReadUInt16(); result.VersionMajor = reader.ReadUInt16(); result.UnknownHash = reader.ReadBytes(8); result.Metadata = ReplayMetadata.Parse(reader); result.Unknown1 = reader.ReadUInt16(); result.Unknown2 = reader.ReadUInt32(); result.Unknown3 = reader.ReadUInt32(); result.Unknown4 = reader.ReadUInt32(); result.GameSpeed = reader.ReadUInt32(); return(result); }
internal static ReplayMetadata Parse(BinaryReader reader) { var raw = reader.ReadNullTerminatedAsciiString(); var rawSplit = raw.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); var result = new ReplayMetadata(); foreach (var rawEntry in rawSplit) { var keyValue = rawEntry.Split('='); switch (keyValue[0]) { case "US": break; case "M": result.MapFileUnknownInt = Convert.ToInt32(keyValue[1].Substring(0, 2)); result.MapFile = keyValue[1].Substring(2); break; case "MC": result.MapCrc = Convert.ToInt32(keyValue[1], 16); break; case "MS": result.MapSize = Convert.ToInt32(keyValue[1]); break; case "SD": result.SD = Convert.ToInt32(keyValue[1]); break; case "C": result.C = Convert.ToInt32(keyValue[1]); break; case "SR": result.SR = Convert.ToInt32(keyValue[1]); break; case "SC": result.StartingCredits = Convert.ToInt32(keyValue[1]); break; case "O": result.O = keyValue[1]; break; case "S": var slots = keyValue[1].Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); result.Slots = new ReplaySlot[slots.Length]; for (var i = 0; i < slots.Length; i++) { result.Slots[i] = ReplaySlot.Parse(slots[i]); } break; default: throw new NotImplementedException($"Unexpected replay metadata key: '{keyValue[0]}'."); } } return(result); }