public static bool FileExists(MpqArchive archive, string path) { if (archive.FileExists(path)) { return(true); } // Check if file is contained in an mpq archive. var subPath = path; var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length; while (!archive.FileExists(subPath)) { var directoryName = new FileInfo(subPath).DirectoryName; if (directoryName.Length <= ignoreLength) { return(false); } subPath = directoryName.Substring(ignoreLength); } var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1)); using var subArchiveStream = archive.OpenFile(subPath); using var subArchive = MpqArchive.Open(subArchiveStream); return(FileExists(subArchive, relativePath)); }
/// <exception cref="FileNotFoundException"></exception> public static Stream GetFile(MpqArchive archive, string path) { if (archive.FileExists(path)) { return(GetArchiveFileStream(archive, path)); } // Assume file is contained in an mpq archive. var subPath = path; var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length; while (!archive.FileExists(subPath)) { var directoryName = new FileInfo(subPath).DirectoryName; if (directoryName.Length <= ignoreLength) { throw new FileNotFoundException($"File not found: {path}"); } subPath = directoryName.Substring(ignoreLength); } var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1)); using var subArchiveStream = archive.OpenFile(subPath); using var subArchive = MpqArchive.Open(subArchiveStream); return(GetArchiveFileStream(subArchive, relativePath)); }
static void TestStrings(MpqArchive mpq, string dot, int count, char[] test, int index) { if (index == count) { entry_count++; if (entry_count % 10000 == 0) { lock (consolelock) { Console.Write(dot); Console.Out.Flush(); } } String entry = new String(test, 0, count); if (mpq.FileExists(entry)) { lock (iolock) { sw.WriteLine(entry); } } return; } for (int j = 0; j < allowable.Length; j++) { test[index] = allowable[j]; TestStrings(mpq, dot, count, test, index + 1); } }
public static Replay ParseRejoin(string fileName) { try { using (var archive = new MpqArchive(fileName)) { archive.AddListfileFilenames(); var replay = new Replay(); // Replay Details ReplayDetails.Parse(replay, DataParser.GetMpqFile(archive, "save.details"), true); // Player level is stored there // does not exist in brawl if (archive.FileExists("replay.attributes.events")) { ReplayAttributeEvents.Parse(replay, DataParser.GetMpqFile(archive, "replay.attributes.events")); } return(replay); } } catch (Exception ex) { //TODO: WE REALLY DON't want to do this Debug.WriteLine(ex); return(null); } }
public string Parse() { var s2MaPathNum = m_lobbyBytes[0]; var s2MaPathLen = m_lobbyBytes[1]; var dict = new Dictionary <string, int>(); foreach (var map in m_maps) { dict.Add(map, 0); } for (var i = 0; i < s2MaPathNum; i++) { var s2MaPath = Encoding.Default.GetString(m_lobbyBytes.Skip(2 + i * (s2MaPathLen + 2)).Take(s2MaPathLen).ToArray()); try { var tempPath = Path.GetTempFileName(); File.Copy(s2MaPath, tempPath, true); s2MaPath = tempPath; var mpq = new MpqArchive(s2MaPath); if (mpq.FileExists("DocumentInfo")) { using (var ms = mpq.OpenFile("DocumentInfo")) { var buffer = new byte[ms.Length]; ms.Read(buffer, 0, (int)ms.Length); var str = Encoding.Default.GetString(buffer); foreach (var map in m_maps) { dict[map] += Regex.Matches(str, map.Substring(0, 8)).Count; } } } File.Delete(tempPath); } catch { } } var count = 0; var mapName = "Unknown Map"; foreach (var map in m_maps) { if (dict[map] > count) { count = dict[map]; mapName = map; } } return(mapName); }
public Map(string filename) { MapPath = filename; using (FileStream fs = new FileStream(filename, FileMode.Open)) { byte[] d = new byte[fs.Length]; fs.Read(d, 0, d.Length); fs.Seek(0, SeekOrigin.Begin); this.MapSize = BitConverter.GetBytes((int)fs.Length); this.MapInfo = new CRC32().ComputeHash(d, 0, d.Length); using (MpqArchive a = new MpqArchive(fs, true)) { uint CRCVal = 0; SHA1Managed sha = new SHA1Managed(); byte[] commonJData, blizzardJData; if (a.FileExists("Scripts\\common.j")) { using (var commonOverload = a.OpenFile("Scripts\\common.j")){ var ms = new MemoryStream(); commonOverload.CopyTo(ms); commonJData = ms.ToArray(); ms.Dispose(); } } else { commonJData = File.ReadAllBytes("dep/common.j"); } if (a.FileExists("Scripts\\blizzard.j")) { using (var blizzardOverload = a.OpenFile("Scripts\\blizzard.j")){ var ms = new MemoryStream(); blizzardOverload.CopyTo(ms); blizzardJData = ms.ToArray(); ms.Dispose(); } } else { blizzardJData = File.ReadAllBytes("dep/blizzard.j"); } CRCVal = CRCVal ^ XORRotateLeft(commonJData); CRCVal = CRCVal ^ XORRotateLeft(blizzardJData); sha.TransformBlock(commonJData, 0, commonJData.Length, commonJData, 0); sha.TransformBlock(blizzardJData, 0, blizzardJData.Length, blizzardJData, 0); var magicBytes = new byte[] { 0x9e, 0x37, 0xf1, 0x03 }; uint magicInt = 0x03F1379E; CRCVal = ROTL(CRCVal, 3); CRCVal = ROTL(CRCVal ^ magicInt, 3); sha.TransformBlock(magicBytes, 0, magicBytes.Length, magicBytes, 0); string[] filenames = { "war3map.j", "scripts\\war3map.j", "war3map.w3e", "war3map.wpm", "war3map.doo", "war3map.w3u", "war3map.w3b", "war3map.w3d", "war3map.w3a", "war3map.w3q" }; var foundScript = false; foreach (string fn in filenames) { if (foundScript && fn == filenames[2]) { continue; } if (!a.FileExists(fn)) { continue; } using (MpqStream s = a.OpenFile(fn)){ var ms = new MemoryStream(); s.CopyTo(ms); var fdata = ms.ToArray(); ms.Dispose(); CRCVal = ROTL(CRCVal ^ XORRotateLeft(fdata), 3); sha.TransformBlock(fdata, 0, fdata.Length, fdata, 0); } } MapCRC = BitConverter.GetBytes(CRCVal); sha.TransformFinalBlock(new byte[] {}, 0, 0); MapSha = sha.Hash; //loading actual map shit now int MapFlags; using (MpqStream m = a.OpenFile("war3map.w3i")){ BinaryReader br = new BinaryReader(m); var FileFormat = br.ReadInt32(); if (FileFormat != 18 && FileFormat != 25) { throw new Exception("Unknown w3i file format " + FileFormat); } //most of these are practically garbage, but still fun to have :) int g_NumSaves = br.ReadInt32(); int g_EditorVer = br.ReadInt32(); string g_MapName = ConvertUtils.parseStringZ(br); string g_MapAuthor = ConvertUtils.parseStringZ(br); string g_MapDesc = ConvertUtils.parseStringZ(br); string g_MapReccomendedPlayers = ConvertUtils.parseStringZ(br); byte[] g_CameraBounds = br.ReadBytes(32); byte[] g_CameraBoundsExt = br.ReadBytes(16); int g_MapWidth = MapWidth = br.ReadInt32(); int g_MapHeight = MapHeight = br.ReadInt32(); int g_MapFlags = MapFlags = br.ReadInt32(); byte g_MapGroundType = br.ReadByte(); bool g_TFTLoading = FileFormat == 25; int g_LoadingScreenId; string g_LoadingScreenPath = ""; if (!g_TFTLoading) { g_LoadingScreenId = br.ReadInt32(); } else { g_LoadingScreenId = br.ReadInt32(); g_LoadingScreenPath = ConvertUtils.parseStringZ(br); } string g_LoadingText = ConvertUtils.parseStringZ(br); string g_LoadingTitle = ConvertUtils.parseStringZ(br); string g_LoadingSubTitle = ConvertUtils.parseStringZ(br); int g_PrologueScreenId; string g_PrologueScreenPath = ""; if (!g_TFTLoading) { g_PrologueScreenId = br.ReadInt32(); } else { g_PrologueScreenId = br.ReadInt32(); g_PrologueScreenPath = ConvertUtils.parseStringZ(br); } string g_PrologueText = ConvertUtils.parseStringZ(br); string g_PrologueTitle = ConvertUtils.parseStringZ(br); string g_PrologueSubTitle = ConvertUtils.parseStringZ(br); if (FileFormat == 25) { br.ReadBytes(4 + 4 + 4 + 4 + 1 + 1 + 1 + 1 + 4); // int fog, int fog startz, int fog endz, int fogdensity, byte fogRED, byte ffogGREEN, byte fogBLUE, byte fogALPHA, int globalWeatherId ConvertUtils.parseStringZ(br); // custom sound environment br.ReadBytes(5); // bytes[5] {tilesetid, waterTintRED, waterTintGREEN, waterTintBLUE, waterTintALPHA} } int g_NumPlayers = MapNumPlayers = br.ReadInt32(); int ClosedSlots = 0; for (int i = 0; i < MapNumPlayers; i++) { Slot s = new Slot(); s.color = (byte)br.ReadInt32(); int status = br.ReadInt32(); if (status == 1) { s.slotStatus = (byte)SlotStatus.OPEN; } else if (status == 2) { s.slotStatus = (byte)SlotStatus.OCCUPIED; s.computer = 1; s.computertype = (byte)SlotCompType.NORMAL; } else { s.slotStatus = (byte)SlotStatus.CLOSED; ClosedSlots++; } switch (br.ReadInt32()) { case 1: s.race = (byte)SlotRace.HUMAN; break; case 2: s.race = (byte)SlotRace.ORC; break; case 3: s.race = (byte)SlotRace.UNDEAD; break; case 4: s.race = (byte)SlotRace.NIGHTELF; break; default: s.race = (byte)SlotRace.RANDOM; break; } br.ReadBytes(4); // fixedstart ConvertUtils.parseStringZ(br); //playername (could be interesting) br.ReadBytes(16); // startx, starty, allylow, allyhigh if (s.slotStatus != (byte)SlotStatus.CLOSED) { Slots.Add(s); } } MapNumPlayers -= ClosedSlots; int g_NumTeams = MapNumTeams = br.ReadInt32(); for (int i = 0; i < MapNumTeams; i++) { int Flags = br.ReadInt32(); int PlayerMask = br.ReadInt32(); for (int si = 0; si < MAX_SLOTS; si++) { if ((PlayerMask & 1) == 1) { foreach (Slot s in Slots) { if (s.color == si) { s.team = (byte)i; } } } PlayerMask >>= 1; } ConvertUtils.parseStringZ(br); //Team Name } } MapOptions = MapFlags & ((int)MAPOPTIONS.MELEE | (int)MAPOPTIONS.FIXEDPLAYERSETTINGS | (int)MAPOPTIONS.CUSTOMFORCES); MapFilterType = (int)MAPFILTERTYPE.SCENARIO; if ((MapOptions & (int)MAPOPTIONS.MELEE) == (int)MAPOPTIONS.MELEE) { byte team = 0; foreach (Slot s in Slots) { s.team = team++; s.race = (byte)SlotRace.RANDOM; } MapFilterType = (int)MAPFILTERTYPE.MELEE; } if ((MapOptions & (int)MAPOPTIONS.FIXEDPLAYERSETTINGS) != (int)MAPOPTIONS.FIXEDPLAYERSETTINGS) { foreach (Slot s in Slots) { s.race = (byte)(s.race | (byte)SlotRace.SELECTABLE); } } } } LoadGameVariables(); if ((MapFlags & (int)MAPFLAGS.RANDOMRACES) == (int)MAPFLAGS.RANDOMRACES) { foreach (Slot s in Slots) { s.race = (byte)SlotRace.RANDOM; } } if ((MapObservers & (int)MAPOBSERVERS.ALLOWED) == (int)MAPOBSERVERS.ALLOWED || (MapObservers & (int)MAPOBSERVERS.REFEREES) == (int)MAPOBSERVERS.REFEREES) { var observercount = MAX_SLOTS; if ((MapOptions & (int)MAPOPTIONS.MELEE) == (int)MAPOPTIONS.MELEE) { observercount = 12; } while (Slots.Count < observercount) { Slots.Add(new Slot(0, 255, (byte)SlotStatus.OPEN, 0, MAX_SLOTS, MAX_SLOTS, (byte)SlotRace.RANDOM | (byte)SlotRace.SELECTABLE)); } } // System.Console.WriteLine(BitConverter.ToString(MapInfo).Replace("-","")); // System.Console.WriteLine(BitConverter.ToString(MapCRC).Replace("-","")); // System.Console.WriteLine(BitConverter.ToString(MapSha).Replace("-","")); }
public bool Exists(string file) { return(mpqArchive.FileExists(file)); }