/// <summary> Parses the replay.tracker.events file, applying it to a Replay object. </summary> /// <param name="replay"> The replay object to apply the parsed information to. </param> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> /// <param name="onlyParsePlayerSetupEvents"> If true, speeds up parsing by skipping Unit data, which is most of this file </param> public static void Parse(Replay replay, byte[] buffer, bool onlyParsePlayerSetupEvents = false) { replay.TrackerEvents = new List<TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { var intro = reader.ReadBytes(3); // Always 03 ?? 09; Middle digit seems to have at least two possible values currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = new TimeSpan(0, 0, (int)(currentFrameCount / 16.0)) }; intro = reader.ReadBytes(1); // Always 09 trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); replay.TrackerEvents.Add(trackerEvent); if (onlyParsePlayerSetupEvents && trackerEvent.TrackerEventType != TrackerEventType.PlayerSetupEvent) break; } // Populate the client list using player indexes var playerIndexes = replay.TrackerEvents.Where(i => i.TrackerEventType == TrackerEventType.PlayerSetupEvent && i.Data.dictionary[2].optionalData != null).Select(i => i.Data.dictionary[2].optionalData.vInt.Value).Distinct().OrderBy(i => i).ToArray(); for (var i = 0; i < playerIndexes.Length; i++) // The references between both of these classes are the same on purpose. // We want updates to one to propogate to the other. replay.ClientList[playerIndexes[i]] = replay.Players[i]; }
/// <summary> Parses the replay.tracker.events file </summary> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> public static List<TrackerEvent> Parse(byte[] buffer) { var trackerEvents = new List<TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { reader.ReadBytes(3); // Always 03 ?? 09; Middle digit seems to have at least two possible values currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = TimeSpan.FromSeconds((int)(currentFrameCount / 16.0)) }; reader.ReadBytes(1); // Always 09 trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); if (trackerEvent.TrackerEventType == TrackerEventType.StatGameEvent && trackerEvent.Data.dictionary[3].optionalData != null) // m_fixedData is stored in fixed point 20.12 format foreach (var trackerEventArrayItem in trackerEvent.Data.dictionary[3].optionalData.array) trackerEventArrayItem.dictionary[1].vInt = trackerEventArrayItem.dictionary[1].vInt.Value / 4096; trackerEvents.Add(trackerEvent); } return trackerEvents; }
/// <summary> Parses the replay.tracker.events file, applying it to a Replay object. </summary> /// <param name="replay"> The replay object to apply the parsed information to. </param> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> public static void Parse(Replay replay, byte[] buffer) { replay.TrackerEvents = new List <TrackerEvent>(); using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { var intro = reader.ReadBytes(3); // Always 03 00 09 (Edit: Middle digit seems to have at least two possible values) if (intro[0] != 3 || /* intro[1] != 0 || */ intro[2] != 9) { throw new Exception("Unexpected data in tracker event"); } var trackerEvent = new TrackerEvent(); trackerEvent.FramesSinceLastEvent = (int)TrackerEventStructure.read_vint(reader); intro = reader.ReadBytes(1); // Always 09 if (intro[0] != 9) { throw new Exception("Unexpected data in tracker event"); } trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); replay.TrackerEvents.Add(trackerEvent); } replay.Frames = replay.TrackerEvents.Sum(i => i.FramesSinceLastEvent); replay.ReplayLength = new TimeSpan(0, 0, (int)(replay.Frames / 16.0)); /* var trackerEventGroupBy = replay.TrackerEvents.GroupBy(i => i.TrackerEventType).OrderBy(i => i.Key); * Console.WriteLine(trackerEventGroupBy.Count()); */ }
/// <summary> Parses the replay.tracker.events file, applying it to a Replay object. </summary> /// <param name="replay"> The replay object to apply the parsed information to. </param> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> public static void Parse(Replay replay, byte[] buffer) { replay.TrackerEvents = new List <TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { var intro = reader.ReadBytes(3); // Always 03 00 09 (Edit: Middle digit seems to have at least two possible values) if (intro[0] != 3 || /* intro[1] != 0 || */ intro[2] != 9) { throw new Exception("Unexpected data in tracker event"); } currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = new TimeSpan(0, 0, (int)(currentFrameCount / 16.0)) }; intro = reader.ReadBytes(1); // Always 09 if (intro[0] != 9) { throw new Exception("Unexpected data in tracker event"); } trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); replay.TrackerEvents.Add(trackerEvent); } replay.Frames = currentFrameCount; replay.ReplayLength = replay.TrackerEvents.Last().TimeSpan; // Need to verify the player ID in the below code - particularly Custom Games where observers can take up spots in the client list replay.TimelineEvents.AddRange(replay.TrackerEvents.Where(i => i.TrackerEventType == TrackerEventType.CreepColor && i.Data.dictionary[1].blobText == "VehicleDragonUpgrade") .Select(i => new TimelineEvent { TimeSpan = i.TimeSpan, TimelineEventType = TimelineEventType.MapMechanicDragonShireDragon, PlayerID = (int)i.Data.dictionary[0].vInt.Value, Value = 1 })); /* var trackerEventGroupBy = replay.TrackerEvents.GroupBy(i => i.TrackerEventType).OrderBy(i => i.Key); * Console.WriteLine(trackerEventGroupBy.Count()); */ }
/// <summary> Parses the replay.tracker.events file, applying it to a Replay object. </summary> /// <param name="replay"> The replay object to apply the parsed information to. </param> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> /// <param name="parseUnitData"> Determines whether or not to parse unit data </param> public static void Parse(Replay replay, byte[] buffer) { replay.TrackerEvents = new List <TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { var intro = reader.ReadBytes(3); // Always 03 00 09 (Edit: Middle digit seems to have at least two possible values) if (intro[0] != 3 || /* intro[1] != 0 || */ intro[2] != 9) { throw new Exception("Unexpected data in tracker event"); } currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = new TimeSpan(0, 0, (int)(currentFrameCount / 16.0)) }; intro = reader.ReadBytes(1); // Always 09 if (intro[0] != 9) { throw new Exception("Unexpected data in tracker event"); } trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); replay.TrackerEvents.Add(trackerEvent); } replay.Frames = currentFrameCount; replay.ReplayLength = replay.TrackerEvents.Last().TimeSpan; // Populate the client list using player indexes var playerIndexes = replay.TrackerEvents.Where(i => i.TrackerEventType == ReplayTrackerEvents.TrackerEventType.PlayerSetupEvent && i.Data.dictionary[2].optionalData != null).Select(i => i.Data.dictionary[2].optionalData.vInt.Value).Distinct().OrderBy(i => i).ToArray(); for (var i = 0; i < playerIndexes.Length; i++) { // The references between both of these classes are the same on purpose. // We want updates to one to propogate to the other. replay.ClientList[playerIndexes[i]] = replay.Players[i]; } }
/// <summary> Parses the replay.tracker.events file, applying it to a Replay object. </summary> /// <param name="replay"> The replay object to apply the parsed information to. </param> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> /// <param name="onlyParsePlayerSetupEvents"> If true, speeds up parsing by skipping Unit data, which is most of this file </param> public static void Parse(Replay replay, byte[] buffer, bool onlyParsePlayerSetupEvents = false) { replay.TrackerEvents = new List <TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { var intro = reader.ReadBytes(3); // Always 03 ?? 09; Middle digit seems to have at least two possible values currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = new TimeSpan(0, 0, (int)(currentFrameCount / 16.0)) }; intro = reader.ReadBytes(1); // Always 09 trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); replay.TrackerEvents.Add(trackerEvent); if (onlyParsePlayerSetupEvents && trackerEvent.TrackerEventType != TrackerEventType.PlayerSetupEvent) { break; } } // Populate the client list using player indexes var playerIndexes = replay.TrackerEvents.Where(i => i.TrackerEventType == TrackerEventType.PlayerSetupEvent && i.Data.dictionary[2].optionalData != null).Select(i => i.Data.dictionary[2].optionalData.vInt.Value).Distinct().OrderBy(i => i).ToArray(); for (var i = 0; i < playerIndexes.Length; i++) { // The references between both of these classes are the same on purpose. // We want updates to one to propogate to the other. replay.ClientList[playerIndexes[i]] = replay.Players[i]; } }
/// <summary> Parses the replay.tracker.events file </summary> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> public static List <TrackerEvent> Parse(byte[] buffer) { var trackerEvents = new List <TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { reader.ReadBytes(3); // Always 03 ?? 09; Middle digit seems to have at least two possible values currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = TimeSpan.FromSeconds((int)(currentFrameCount / 16.0)) }; reader.ReadBytes(1); // Always 09 trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); if (trackerEvent.TrackerEventType == TrackerEventType.StatGameEvent && trackerEvent.Data.dictionary[3].optionalData != null) { // m_fixedData is stored in fixed point 20.12 format foreach (var trackerEventArrayItem in trackerEvent.Data.dictionary[3].optionalData.array) { trackerEventArrayItem.dictionary[1].vInt = trackerEventArrayItem.dictionary[1].vInt.Value / 4096; } } trackerEvents.Add(trackerEvent); } return(trackerEvents); }
/// <summary> Parses the replay.tracker.events file, applying it to a Replay object. </summary> /// <param name="replay"> The replay object to apply the parsed information to. </param> /// <param name="buffer"> The buffer containing the replay.tracker.events file. </param> /// <param name="parseUnitData"> Determines whether or not to parse unit data </param> public static void Parse(Replay replay, byte[] buffer) { replay.TrackerEvents = new List<TrackerEvent>(); var currentFrameCount = 0; using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) while (stream.Position < stream.Length) { var intro = reader.ReadBytes(3); // Always 03 00 09 (Edit: Middle digit seems to have at least two possible values) if (intro[0] != 3 || /* intro[1] != 0 || */ intro[2] != 9) throw new Exception("Unexpected data in tracker event"); currentFrameCount += (int)TrackerEventStructure.read_vint(reader); var trackerEvent = new TrackerEvent { TimeSpan = new TimeSpan(0, 0, (int)(currentFrameCount / 16.0)) }; intro = reader.ReadBytes(1); // Always 09 if (intro[0] != 9) throw new Exception("Unexpected data in tracker event"); trackerEvent.TrackerEventType = (TrackerEventType)TrackerEventStructure.read_vint(reader); trackerEvent.Data = new TrackerEventStructure(reader); replay.TrackerEvents.Add(trackerEvent); } replay.Frames = currentFrameCount; replay.ReplayLength = replay.TrackerEvents.Last().TimeSpan; // Populate the client list using player indexes var playerIndexes = replay.TrackerEvents.Where(i => i.TrackerEventType == ReplayTrackerEvents.TrackerEventType.PlayerSetupEvent && i.Data.dictionary[2].optionalData != null).Select(i => i.Data.dictionary[2].optionalData.vInt.Value).Distinct().OrderBy(i => i).ToArray(); for (var i = 0; i < playerIndexes.Length; i++) // The references between both of these classes are the same on purpose. // We want updates to one to propogate to the other. replay.ClientList[playerIndexes[i]] = replay.Players[i]; }