public ReplayInitData(MPQBlock DetailsBlock, ReplayViewModel ParentRVM) { BinaryReader BinaryReader = new BinaryReader(new MemoryStream(DetailsBlock.RawContents)); int NumPlayers = BinaryReader.ReadByte(); int NameLen; Players = new string[NumPlayers]; for (int i = 0; i < NumPlayers; i++) { NameLen = BinaryReader.ReadByte(); if (NameLen > 0) { Players[i] = Encoding.Default.GetString(BinaryReader.ReadBytes(NameLen)); } else { Players[i] = String.Empty; } BinaryReader.ReadBytes(5); // Advance 5 bytes } BinaryReader.ReadBytes(6); // Advance 6 unknown bytes BinaryReader.ReadBytes(4); // Advance 4 bytes (string literal "Dflt") BinaryReader.ReadBytes(14); // Advance 15 unknown bytes int AccountIdLen = BinaryReader.ReadByte(); if (AccountIdLen > 0) { AccountIdentifier = Encoding.Default.GetString(BinaryReader.ReadBytes(AccountIdLen)); } BinaryReader.ReadBytes(684); // Some fixed length of data that changes based on the number of players string temp; while (true) { temp = Encoding.Default.GetString(BinaryReader.ReadBytes(4)); if (temp != "s2ma") { BinaryReader.BaseStream.Position -= 4; break; } BinaryReader.ReadBytes(2); // 0x00 0x00 Realm = Encoding.Default.GetString(BinaryReader.ReadBytes(2)); MapHash = Conversion.BytesToHexString(BinaryReader.ReadBytes(32)).ToLower(); if (Conversion.MapHash.ContainsKey(MapHash)) { MapName = Conversion.MapHash[MapHash]; } else { MapName = "Unknown"; } } if ((MapName == "Unknown") && !Conversion.MapLocales.ContainsKey(ParentRVM.ReplayDetails.LocalizedMapName)) { foreach (KeyValuePair<string, Dictionary<string, string>> MapKVP in Conversion.MapLocales) { foreach (KeyValuePair<string, string> LocalesKVP in MapKVP.Value) { if (LocalesKVP.Value == ParentRVM.ReplayDetails.LocalizedMapName) { MapName = MapKVP.Value["enUS"]; } } } } BinaryReader.ReadBytes(2); BinaryReader.ReadBytes(4); }
public void LoadReplay(string Filename) { ReplayViewModel tempRVM = new ReplayViewModel(); tempRVM.LoadReplay(Filename); ReplayList.Add(tempRVM); }
public ReplayAttributesEvents(MPQBlock DetailsBlock, ReplayViewModel ParentRVM) { BinaryReader BinaryReader = new BinaryReader(new MemoryStream(DetailsBlock.RawContents)); Dictionary<uint, Dictionary<int, string>> AttribDict = new Dictionary<uint, Dictionary<int, string>>(); BinaryReader.ReadBytes(4); // Skip 4 Byte header if (ParentRVM.MPQArchive.MPQHeader.VersionBuild >= 17326) { BinaryReader.ReadByte(); } #region Enumerate all attributes into a nested Dictionary<uint, Dictionary<int, string>> uint NumAttribs = BinaryReader.ReadUInt32(); uint AttribHeader; uint AttribId; int PlayerId; string AttribVal; int NumSlots; for (int i = 0; i < NumAttribs; i++) { AttribHeader = BinaryReader.ReadUInt32(); AttribId = BinaryReader.ReadUInt32(); PlayerId = BinaryReader.ReadByte(); AttribVal = Conversion.ReverseString(Encoding.Default.GetString(BinaryReader.ReadBytes(4))).Replace("\0", String.Empty); if (!AttribDict.ContainsKey(AttribId)) { AttribDict.Add(AttribId, new Dictionary<int, string>()); } AttribDict[AttribId].Add(PlayerId, AttribVal); } if (NumAttribs == 0) { throw new Exception("Zero attributes."); } #endregion #region Set Player Ids if (AttribDict.ContainsKey(0x01F4)) { PlayerId = 0; int i; for (i = 1; AttribDict[0x01F4].ContainsKey(i); i++) { if (AttribDict[0x01F4][i] == "Open") { throw new Exception("\"Open\" in Attributes Events!"); } ParentRVM.ReplayDetails.Players[i - 1].Id = i; } NumSlots = i; } else { NumSlots = 0; } #endregion #region Get team locations within file uint TeamAttribLocation; switch (AttribDict[0x07D1][0x10]) { case "1v1": TeamAttribLocation = 0x07D2; break; case "2v2": TeamAttribLocation = 0x07D3; break; case "3v3": TeamAttribLocation = 0x07D4; break; case "4v4": TeamAttribLocation = 0x07D5; break; case "FFA": TeamAttribLocation = 0x07D6; break; default: throw new Exception("Unknown game mode in Attibutes Events!"); } // Custom games have different values. Not tested thoroughly, may be wrong. switch (AttribDict[0x07D0][0x10]) { case "Cust": if (AttribDict[0x03E9][0x10] == "no") { TeamAttribLocation += 10; } break; } #endregion Hashtable TempTeamSize = new Hashtable(); int CurPlayerNum = -1; for (int i = 1; i < NumSlots; i++) { #region Find this Player for (int x = 0; x < ParentRVM.ReplayDetails.Players.Length; x++) { if (ParentRVM.ReplayDetails.Players[x].Id == i) { CurPlayerNum = i; } } if (CurPlayerNum == -1) { continue; } PlayerDetails CurPlayer = ParentRVM.ReplayDetails.Players[CurPlayerNum - 1]; #endregion CurPlayer.HandicapAttrib = Convert.ToInt32(AttribDict[0x0BBB][i]); #region Difficulty switch (AttribDict[0x0BBC][i]) { case "VyEy": CurPlayer.Difficulty = Difficulty.VeryEasy; break; case "Easy": CurPlayer.Difficulty = Difficulty.Easy; break; case "Medi": CurPlayer.Difficulty = Difficulty.Medium; break; case "Hard": CurPlayer.Difficulty = Difficulty.Hard; break; case "VyHd": CurPlayer.Difficulty = Difficulty.VeryHard; break; case "Insa": CurPlayer.Difficulty = Difficulty.Insane; break; } #endregion #region Race switch (AttribDict[0x0BB9][i]) { case "Zerg": CurPlayer.StartingRace = Race.Zerg; break; case "Terr": CurPlayer.StartingRace = Race.Terran; break; case "Prot": CurPlayer.StartingRace = Race.Protoss; break; default: throw new Exception("Unknown Race."); } #endregion if (AttribDict[0x01F4][i] == "Comp") { CurPlayer.IsCPU = true; } else { CurPlayer.IsCPU = false; } #region Color CurPlayer.ColorIndex = Convert.ToInt32(AttribDict[0x0BBA][i].Substring(2)); switch (CurPlayer.ColorIndex) { case 1: CurPlayer.Color = Color.Red; break; case 2: CurPlayer.Color = Color.Blue; break; case 3: CurPlayer.Color = Color.Teal; break; case 4: CurPlayer.Color = Color.Purple; break; case 5: CurPlayer.Color = Color.Yellow; break; case 6: CurPlayer.Color = Color.Orange; break; case 7: CurPlayer.Color = Color.Green; break; case 8: CurPlayer.Color = Color.LightPink; break; case 9: CurPlayer.Color = Color.Violet; break; case 10: CurPlayer.Color = Color.LightGray; break; case 11: CurPlayer.Color = Color.DarkGreen; break; case 12: CurPlayer.Color = Color.Brown; break; case 13: CurPlayer.Color = Color.LightGreen; break; case 14: CurPlayer.Color = Color.DarkGray; break; case 15: CurPlayer.Color = Color.Pink; break; default: CurPlayer.Color = Color.Unknown; break; } #endregion #region Team CurPlayer.Team = Convert.ToInt32(AttribDict[TeamAttribLocation][i].Substring(1)); if (!TempTeamSize.ContainsKey(CurPlayer.Team)) { TempTeamSize[CurPlayer.Team] = 1; } else { TempTeamSize[CurPlayer.Team] = (int)TempTeamSize[CurPlayer.Team] + 1; } #endregion ParentRVM.ReplayDetails.Players[CurPlayerNum - 1] = CurPlayer; CurPlayerNum = -1; } #region Overall Team Size foreach (DictionaryEntry Item in TempTeamSize) { ParentRVM.ReplayDetails.RealTeamSize += "v" + Item.Value; } if (ParentRVM.ReplayDetails.RealTeamSize.Length > 0) { ParentRVM.ReplayDetails.RealTeamSize = ParentRVM.ReplayDetails.RealTeamSize.Substring(1); } else { ParentRVM.ReplayDetails.RealTeamSize = "0v0"; } #endregion ParentRVM.ReplayDetails.TeamSize = AttribDict[0x07D1][0x10]; #region Game Speed switch (AttribDict[0x0BB8][0x10]) { case "Slor": ParentRVM.ReplayDetails.GameSpeed = GameSpeed.Slower; break; case "Slow": ParentRVM.ReplayDetails.GameSpeed = GameSpeed.Slow; break; case "Norm": ParentRVM.ReplayDetails.GameSpeed = GameSpeed.Normal; break; case "Fast": ParentRVM.ReplayDetails.GameSpeed = GameSpeed.Fast; break; case "Fasr": ParentRVM.ReplayDetails.GameSpeed = GameSpeed.Faster; break; default: ParentRVM.ReplayDetails.GameSpeed = GameSpeed.Unknown; break; } #endregion if (AttribDict[0x0BC1][0x10] == "Priv") { ParentRVM.ReplayDetails.IsPublic = false; } else { ParentRVM.ReplayDetails.IsPublic = true; } }