Beispiel #1
0
 private static byte[] GetMpqArchiveFileBytes(MpqArchive archive, string fileName)
 {
     using (var mpqStream = archive.OpenFile(archive.Single(i => i.Filename == fileName)))
     {
         var buffer = new byte[mpqStream.Length];
         mpqStream.Read(buffer, 0, buffer.Length);
         return buffer;
     }
 }
Beispiel #2
0
        /// <summary>
        /// Moves the files from the chunked archive to a flat file one
        /// </summary>
        /// <param name="archivename"></param>
        /// <param name="block"></param>
        private void DoFileSwap(string archivename, string block)
        {
            Directory.CreateDirectory("Temp");

            string filename = Path.GetFileName(archivename);

            using (var mpq = MpqArchive.CreateNew(archivename, MpqArchiveVersion.Version3))
                using (var tmp = new MpqArchive(block, FileAccess.Read, OpenArchiveFlags.BLOCK4))
                {
                    if (TryGetFileList(tmp, false, out var lf))
                    {
                        _progressBar.Start();

                        string tempPath;
                        for (int i = 0; i < lf.Count; i++)
                        {
                            using (var fs = tmp.OpenFile(lf[i]))
                            {
                                // incremental patch files can't be written directly with StormLib SFileCreateFile?
                                if ((fs.TFileEntry.dwFlags & 0x100000u) != 0x100000u)
                                {
                                    mpq.AddFileFromStream(fs);
                                }
                                else
                                {
                                    tempPath = Path.Combine("Temp", lf[i]);
                                    Directory.CreateDirectory(Path.GetDirectoryName(tempPath));

                                    tmp.ExtractFile(lf[i], tempPath);
                                    mpq.AddFileFromDisk(tempPath, lf[i], fs.TFileEntry.dwFlags);
                                }
                            }

                            _progressBar.Update(filename, i / (float)lf.Count);

                            if (i % 10000 == 0)
                            {
                                mpq.Flush();
                            }
                        }
                    }
                }

            Console.WriteLine("Emptying Temp Folder...");
            DeleteDirectory("Temp");
            _progressBar.Stop();
        }
Beispiel #3
0
        public ItemTag(MpqArchive archive, MpqEntry mpqEntry, string archiveName = null)
        {
            MpqEntry           = mpqEntry;
            FileName           = mpqEntry.FileName;
            ArchiveName        = archiveName ?? string.Empty;
            OriginalFileStream = archive.OpenFile(mpqEntry);

            if (!OriginalFileStream.CanRead)
            {
                OriginalFileStream.Dispose();
                Status = MapFileStatus.Locked;
            }
            else
            {
                Adapter = AdapterFactory.GetAdapter(OriginalFileStream, FileName);
                Status  = Adapter is null ? MapFileStatus.Unknown : MapFileStatus.Pending;
            }
        }
Beispiel #4
0
        public static void GenerateMainListFileFromMPQ()
        {
            //Only generate list if empty
            if (MainListFile.Count == 0)
            {
                DirectoryInfo directory = new DirectoryInfo(ConfigurationManager.GameDir + "\\data\\");
                FileInfo[]    Archives  = directory.GetFiles("*.mpq", SearchOption.TopDirectoryOnly);
                string        listFile;

                foreach (FileInfo fileinfo in Archives)
                {
                    try
                    {
                        using (MpqArchive archive = new MpqArchive(fileinfo.FullName, FileAccess.Read))
                        {
                            using (MpqFileStream file = archive.OpenFile("(listfile)"))
                                using (StreamReader sr = new StreamReader(file))
                                {
                                    listFile = sr.ReadToEnd();
                                    MainListFile.Add(listFile.ToLower() + ";" + fileinfo.Name);
                                }
                        }
                    }
                    catch
                    {
                        throw new Exception("Could not read: \"" + fileinfo.FullName + "\".");
                    }
                }

                //Add locale to the listfile:
                if (ConfigurationManager.Profile != 1) //Anything else than Vanilla
                {
                    using (MpqArchive archive = new MpqArchive(ConfigurationManager.GameDir + "\\data\\" + locale + "\\" + "locale-" + locale + ".mpq", FileAccess.Read))
                    {
                        using (MpqFileStream file = archive.OpenFile("(listfile)"))
                            using (StreamReader sr = new StreamReader(file))
                            {
                                listFile = sr.ReadToEnd();
                                MainListFile.Add(listFile.ToLower() + ";" + "locale1.txt"); //.txt because i need an extension, that's how i coded the damn thing, and that's how it will stay for the moment
                            }
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Some alpha MPQs are hotswappable and only contain a single file and it's checksum
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="archivename"></param>
        private bool TryReadAlpha(MpqArchive mpq, string archivename)
        {
            // strip the local path and extension to get the filename
            var file = Path.ChangeExtension(GetInternalPath(archivename), null).WoWNormalise();

            if (FileList.ContainsKey(file))
            {
                return(true);
            }

            // add the filename as the listfile
            var internalname = Path.GetFileName(file);

            mpq.AddListFile(internalname);

            // read file if known
            if (mpq.HasFile(internalname))
            {
                using var fs = mpq.OpenFile(internalname);

                if (fs.CanRead && fs.Length > 0)
                {
                    var map = BlockTableEncoder.GetEMapFromExtension(file, fs.Length);

                    if (!EncodingCache.TryGetRecord(MD5Hash.Parse(fs.GetMD5Hash()), file, out var record))
                    {
                        record = BlockTableEncoder.EncodeAndExport(fs, map, Options.TempDirectory, file);
                        EncodingCache.AddOrUpdate(record);
                    }

                    record.EBlock.EncodingMap = map;
                    FileList.TryAdd(file, record);
                    return(true);
                }
            }

            return(false);
        }
Beispiel #6
0
        /// <summary>
        /// Parses the archive file.
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="filename"></param>
        /// <param name="overridename">Alpha MPQ filename override.</param>
        /// <returns></returns>
        private IFormat ReadFileImpl(MpqArchive mpq, string filename, string overridename = null)
        {
            using var md5    = MD5.Create();
            using var stream = mpq.OpenFile(overridename ?? filename);
            if (stream == null || !stream.CanRead || stream.Length <= 1)
            {
                return(null);
            }

            // validate filesize limit
            if (_options.MaxFileSize > 0 && stream.Length > _options.MaxFileSize)
            {
                return(null);
            }

            Structures.Meta.FileInfo entry = new Structures.Meta.FileInfo()
            {
                Build = _build.Build,
                Name  = filename.WoWNormalize()
            };

            if (_options.ParseMode.HasFlag(ParseMode.FileInfo))
            {
                entry.Checksum = stream.GetMd5Hash();
                if (string.IsNullOrWhiteSpace(entry.Checksum) || entry.Checksum == EMPTY_CHECKSUM)
                {
                    entry.Checksum = md5.ComputeHash(stream).ToChecksum();
                }
                entry.Created = stream.CreatedDate;
                entry.Size    = (uint)stream.Length;
            }

            stream.FileName = filename;

            using var bs = new BufferedStream(stream);
            return(_fileReader.Read(bs, entry));
        }
Beispiel #7
0
        // TODO: Add stream opening support
        /// <inheritdoc/>
        public Dictionary <string, List <string> > Scan(Scanner scanner, Stream stream, string file)
        {
            // If the mpq file itself fails
            try
            {
                string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                Directory.CreateDirectory(tempPath);

                using (MpqArchive mpqArchive = new MpqArchive(file, FileAccess.Read))
                {
                    // Try to open the listfile
                    string        listfile   = null;
                    MpqFileStream listStream = mpqArchive.OpenFile("(listfile)");

                    // If we can't read the listfile, we just return
                    if (!listStream.CanRead)
                    {
                        return(null);
                    }

                    // Read the listfile in for processing
                    using (StreamReader sr = new StreamReader(listStream))
                    {
                        listfile = sr.ReadToEnd();
                    }

                    // Split the listfile by newlines
                    string[] listfileLines = listfile.Replace("\r\n", "\n").Split('\n');

                    // Loop over each entry
                    foreach (string sub in listfileLines)
                    {
                        // If an individual entry fails
                        try
                        {
                            string tempFile = Path.Combine(tempPath, sub);
                            Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
                            mpqArchive.ExtractFile(sub, tempFile);
                        }
                        catch { }
                    }
                }

                // Collect and format all found protections
                var protections = scanner.GetProtections(tempPath);

                // If temp directory cleanup fails
                try
                {
                    Directory.Delete(tempPath, true);
                }
                catch { }

                // Remove temporary path references
                Utilities.StripFromKeys(protections, tempPath);

                return(protections);
            }
            catch { }

            return(null);
        }
Beispiel #8
0
 public Stream OpenRead(string file)
 {
     return(mpqArchive.OpenFile(file));
 }
Beispiel #9
0
        public static bool ExtractDBC()
        {
            try
            {
                Logger.Notice("Extracting DBC files...");
                //Check if dbc.MPQ exist.
                if (!File.Exists(Paths.DBCMPQPath))
                {
                    Logger.Error($"Unable to locate dbc.MPQ at path {Paths.DBCMPQPath}, please check Config.txt and set a proper installation path.");
                    return(false);
                }

                // Clean up output directory if neccesary.
                if (Directory.Exists(Paths.DBCLoadPath))
                {
                    Directory.Delete(Paths.DBCLoadPath, true);
                }

                using (MpqArchive archive = new MpqArchive(Paths.DBCMPQPath))
                {
                    archive.AddListfileFilenames();
                    foreach (var entry in archive)
                    {
                        if (!string.IsNullOrEmpty(entry.Filename))
                        {
                            var outputFileName  = Paths.Combine(Paths.DBCLoadPath, Path.GetFileName(entry.Filename));
                            var outputPlainName = Path.GetFileNameWithoutExtension(outputFileName);

                            if (File.Exists(outputFileName))
                            {
                                File.Delete(outputFileName);
                            }

                            if (InterestedDBC.Any(name => outputPlainName.ToLower().Equals(name.ToLower())))
                            {
                                byte[] buf = new byte[0x40000];
                                using (Stream streamIn = archive.OpenFile(entry))
                                {
                                    using (Stream streamOut = new FileStream(outputFileName, FileMode.Create))
                                    {
                                        while (true)
                                        {
                                            int cb = streamIn.Read(buf, 0, buf.Length);
                                            if (cb == 0)
                                            {
                                                break;
                                            }

                                            streamOut.Write(buf, 0, cb);
                                        }

                                        streamOut.Close();
                                    }
                                }

                                Logger.Success($"Extracted DBC file [{entry.Filename}].");
                            }
                        }
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                Logger.Error(ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Logger.Error(ex.InnerException.Message);
                    Logger.Error(ex.InnerException.StackTrace);
                }
            }

            return(false);
        }
Beispiel #10
0
        public static Stream ReadThisFile(string filename)
        {
            Stream stream = null;

            if (usingCasc) //CASC
            {
                stream = cascHandler.OpenFile(filename);
            }
            else //MPQ
            {
                //Find the goddamn file in the archive hell
                int index = MainListFile.FindIndex(a => a.Contains(filename.ToLower()));

                if (index != -1)
                {
                    //Get the archive in which the requested file resides
                    string archive = MainListFile[index];
                    archive = archive.Substring(archive.LastIndexOf(';', archive.Length - 2) + 1);

                    switch (archive.Substring(0, archive.Length - 4).Replace("-", ""))
                    {
                    //Mysts
                    case "expansion4":
                        stream = expansion4.OpenFile(filename);
                        break;

                    case "model":
                        stream = model.OpenFile(filename);
                        break;

                    //Cataclysm
                    case "art":
                        stream = art.OpenFile(filename);
                        break;

                    case "expansion1":
                        stream = expansion1.OpenFile(filename);
                        break;

                    case "expansion2":
                        stream = expansion2.OpenFile(filename);
                        break;

                    case "expansion3":
                        stream = expansion3.OpenFile(filename);
                        break;

                    case "world":
                        stream = world.OpenFile(filename);
                        break;

                    case "world2":
                        stream = world2.OpenFile(filename);
                        break;

                    case "locale1":
                        stream = locale1.OpenFile(filename);
                        break;

                    //Lich King
                    case "common":
                        stream = common.OpenFile(filename);
                        break;

                    case "common2":
                        stream = common2.OpenFile(filename);
                        break;

                    case "expansion":
                        stream = expansion.OpenFile(filename);
                        break;

                    case "lichking":
                        stream = lichking.OpenFile(filename);
                        break;

                    case "patch":
                        stream = patch.OpenFile(filename);
                        break;

                    case "patch2":
                        stream = patch2.OpenFile(filename);
                        break;

                    case "patch3":
                        stream = patch3.OpenFile(filename);
                        break;

                    //Vanilla
                    case "base":
                        stream = baseMPQ.OpenFile(filename);
                        break;

                    case "dbc":
                        stream = dbc.OpenFile(filename);
                        break;

                    case "interface":
                        stream = interfaceMPQ.OpenFile(filename);
                        break;

                    case "misc":
                        stream = misc.OpenFile(filename);
                        break;

                    case "sound":
                        stream = sound.OpenFile(filename);
                        break;

                    case "terrain":
                        stream = terrain.OpenFile(filename);
                        break;

                    case "texture":
                        stream = texture.OpenFile(filename);
                        break;

                    case "wmo":
                        stream = wmo.OpenFile(filename);
                        break;
                    }
                }
                else
                {
                    //Missing file
                    stream = null;
                }
            }
            return(stream);
        }
Beispiel #11
0
        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("-",""));
        }
Beispiel #12
0
        private void ExtractArchive()
        {
            using (MpqArchive archive = new MpqArchive(this.archiveFile))
            {
                if ((this.destDir == null) || (this.destDir == ""))
                {
                    this.destDir = Path.GetTempPath();
                }
                archive.AddListfileFilenames();
                if ((this.listFile != null) && (this.listFile != ""))
                {
                    using (Stream stream = File.OpenRead(this.listFile))
                    {
                        archive.AddFilenames(stream);
                    }
                }
                byte[] buffer = new byte[0x40000];
                if (!this.quietOutput)
                {
                    Console.WriteLine("Extracting to {0}", this.destDir);
                }
                foreach (MpqEntry entry in (IEnumerable <MpqEntry>)archive)
                {
                    if ((this.regex != null) && !this.regex.Match(entry.Filename).Success)
                    {
                        continue;
                    }
                    if (!this.quietOutput)
                    {
                        Console.Write(entry.Filename + " .. ");
                    }
                    string filename = entry.Filename;
                    if (this.stripPath)
                    {
                        filename = Path.GetFileName(filename);
                    }
                    string path          = Path.Combine(this.destDir, filename);
                    string directoryName = Path.GetDirectoryName(path);
                    this.CreateDirectory(directoryName);
                    using (Stream stream2 = archive.OpenFile(entry))
                    {
                        using (Stream stream3 = new FileStream(path, FileMode.Create))
                        {
                            int num;
Label_0135:
                            num = stream2.Read(buffer, 0, buffer.Length);
                            if (num != 0)
                            {
                                stream3.Write(buffer, 0, num);
                                goto Label_0135;
                            }
                            stream3.Close();
                        }
                    }
                    if (!this.quietOutput)
                    {
                        Console.WriteLine("Done.");
                    }
                }
            }
        }
Beispiel #13
0
        /// <summary>
        /// Extracts files from the archive matching the pattern (if any)
        /// </summary>
        void ExtractArchive()
        {
            using(MpqArchive archive = new MpqArchive(archiveFile))
            {
                // destination directory
                if(destDir == null || destDir == "")
                    destDir = Directory.GetCurrentDirectory();    // default to current dir of not specified

                archive.AddListfileFilenames();

                // setup external listfile if specified
                if (listFile != null && listFile != "")
                    using (Stream s = File.OpenRead(listFile))
                        archive.AddFilenames(s);

                // buffers
                byte[] buf = new byte[0x40000];

                if(!quietOutput)
                    Console.WriteLine("Extracting to {0}", destDir);

                foreach(MpqEntry entry in archive)
                {
                    // match pattern
                    if (regex != null && !regex.Match(entry.Filename).Success)
                        continue;

                    if(!quietOutput)
                        Console.Write(entry.Filename + " .. ");

                    string srcFile = entry.Filename;
                    if (stripPath)
                        srcFile = Path.GetFileName(srcFile);

                    // create destination directory
                    string destFile = Path.Combine(destDir, srcFile);
                    string absDestDir = Path.GetDirectoryName(destFile);
                    CreateDirectory(absDestDir);

                    // copy to destination file
                    using(Stream stmIn = archive.OpenFile(entry))
                    {
                        using(Stream stmOut = new FileStream(destFile, FileMode.Create))
                        {
                            while(true)
                            {
                                int cb = stmIn.Read(buf, 0, buf.Length);
                                if(cb == 0)
                                    break;

                                stmOut.Write(buf, 0, cb);
                            }

                            stmOut.Close();
                        }
                    }

                    if(!quietOutput)
                        Console.WriteLine("Done.");
                }
            }
        }
Beispiel #14
0
        public static void UnpackMap(string inputMapPath, string outputFolderPath)
        {
            if (!File.Exists(inputMapPath))
            {
                throw new FileNotFoundException(String.Format("Input map at {0} does not exist.", inputMapPath));
            }

            if (Directory.Exists(outputFolderPath) && Directory.EnumerateFileSystemEntries(outputFolderPath).Any())
            {
                throw new IOException(String.Format("Output folder at {0} is not empty.", outputFolderPath));
            }


            // Strategy is as follows:
            // Copy map to the target location. Then extract all files, but convert the map into a container by deleting all the files inside.
            // Goal is that we are left with the MPQ container which contains all the other misc information which we are currently unable to manage.
            // In future, we might be able to generate the MPQ from scratch, but for now we will keep a big chunk of "unmanaged" data and focus
            // on the files we are able to manage.

            string containerPath = Path.Combine(outputFolderPath, FILENAME_CONTAINER);

            Directory.CreateDirectory(outputFolderPath);

            // Copy map to target location in preparation to convert it into a container
            File.Copy(inputMapPath, containerPath);

            string listFile = null;

            // Extract all files from the map and remove them from the container
            using (MpqArchive container = new MpqArchive(containerPath, FileAccess.ReadWrite))
                using (MpqArchive archive = new MpqArchive(inputMapPath, FileAccess.Read))
                {
                    // Check if somebody is trying to unpack a container - lets avoid creating Matroshchkas
                    if (archive.HasFile(DUMMY_FILENAME))
                    {
                        throw new Exception("Input map seems to be a container rather than a packed map.");
                    }

                    using (MpqFileStream file = archive.OpenFile(MPQ_LISTFILE))
                        using (StreamReader sr = new StreamReader(file))
                        {
                            listFile = sr.ReadToEnd();
                        }

                    // We have to add a dummy file as otherwise the listfile gets deleted and somehow doesnt get restored...
                    if (!container.HasFile(DUMMY_FILENAME))
                    {
                        string dummyFilePath = Path.GetTempFileName();
                        try
                        {
                            using (StreamWriter listFileHandle = new StreamWriter(dummyFilePath))
                            {
                                listFileHandle.WriteLine("Dummy file");
                            }
                            container.AddFileFromDiskEx(dummyFilePath, DUMMY_FILENAME, MpqFileAddFileExFlags.MPQ_FILE_COMPRESS, MpqFileAddFileExCompression.MPQ_COMPRESSION_BZIP2, MpqFileAddFileExCompression.MPQ_COMPRESSION_NEXT_SAME);
                        }
                        finally
                        {
                            File.Delete(dummyFilePath);
                        }
                    }

                    using (StringReader reader = new StringReader(listFile))
                    {
                        string currentArchiveFile = string.Empty;
                        do
                        {
                            currentArchiveFile = reader.ReadLine();
                            if (currentArchiveFile != null)
                            {
                                if (currentArchiveFile == DUMMY_FILENAME)
                                {
                                    continue;
                                }

                                string targetPath = Path.Combine(outputFolderPath, currentArchiveFile.Trim('\\'));

                                Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                                archive.ExtractFile(currentArchiveFile, targetPath);

                                container.RemoveFile(currentArchiveFile);
                            }
                        } while (currentArchiveFile != null);
                    }

                    container.Compact(MPQ_LISTFILE);
                }
        }
Beispiel #15
0
        /// <summary>
        /// Extracts files from the archive matching the pattern (if any)
        /// </summary>
        void ExtractArchive()
        {
            using (MpqArchive archive = new MpqArchive(archiveFile))
            {
                // destination directory
                if (destDir == null || destDir == "")
                {
                    destDir = Directory.GetCurrentDirectory();    // default to current dir of not specified
                }
                archive.AddListfileFilenames();

                // setup external listfile if specified
                if (listFile != null && listFile != "")
                {
                    using (Stream s = File.OpenRead(listFile))
                        archive.AddFilenames(s);
                }

                // buffers
                byte[] buf = new byte[0x40000];

                if (!quietOutput)
                {
                    Console.WriteLine("Extracting to {0}", destDir);
                }

                foreach (MpqEntry entry in archive)
                {
                    // match pattern
                    if (regex != null && !regex.Match(entry.Filename).Success)
                    {
                        continue;
                    }

                    if (!quietOutput)
                    {
                        Console.Write(entry.Filename + " .. ");
                    }

                    string srcFile = entry.Filename;
                    if (stripPath)
                    {
                        srcFile = Path.GetFileName(srcFile);
                    }

                    // create destination directory
                    string destFile   = Path.Combine(destDir, srcFile);
                    string absDestDir = Path.GetDirectoryName(destFile);
                    CreateDirectory(absDestDir);

                    // copy to destination file
                    using (Stream stmIn = archive.OpenFile(entry))
                    {
                        using (Stream stmOut = new FileStream(destFile, FileMode.Create))
                        {
                            while (true)
                            {
                                int cb = stmIn.Read(buf, 0, buf.Length);
                                if (cb == 0)
                                {
                                    break;
                                }

                                stmOut.Write(buf, 0, cb);
                            }

                            stmOut.Close();
                        }
                    }

                    if (!quietOutput)
                    {
                        Console.WriteLine("Done.");
                    }
                }
            }
        }
Beispiel #16
0
        public static void ExtractCommand(string[] args)
        {
            var        pmap   = ConsoleManager.ParseCommand(args);
            string     filter = ParamCheck <string>(pmap, "-f", false);
            string     source = ParamCheck <string>(pmap, "-s");
            string     output = ParamCheck <string>(pmap, "-o");
            SourceType sType  = GetSourceType(source);

            if (string.IsNullOrWhiteSpace(filter))
            {
                filter = "*";
            }

            string regexfilter            = "(" + Regex.Escape(filter).Replace(@"\*", @".*").Replace(@"\?", ".") + ")";
            Func <string, bool> TypeCheck = t => Path.GetExtension(t).ToLower() == ".dbc" || Path.GetExtension(t).ToLower() == ".db2";


            var dic = new ConcurrentDictionary <string, MemoryStream>();

            switch (sType)
            {
            case SourceType.MPQ:
                Console.WriteLine("Loading from MPQ archive...");
                using (MpqArchive archive = new MpqArchive(source, FileAccess.Read))
                {
                    string line = string.Empty;
                    using (MpqFileStream listfile = archive.OpenFile("(listfile)"))
                        using (StreamReader sr = new StreamReader(listfile))
                        {
                            while ((line = sr.ReadLine()) != null)
                            {
                                if (TypeCheck(line) && Regex.IsMatch(line, regexfilter, RegexOptions.Compiled | RegexOptions.IgnoreCase))
                                {
                                    var ms = new MemoryStream();
                                    archive.OpenFile(line).CopyTo(ms);
                                    dic.TryAdd(Path.GetFileName(line), ms);
                                }
                            }
                        }
                }
                break;

            case SourceType.CASC:
                Console.WriteLine("Loading from CASC directory...");
                using (var casc = new CASCHandler(source))
                {
                    var files = Constants.ClientDBFileNames.Where(x => Regex.IsMatch(Path.GetFileName(x), regexfilter, RegexOptions.Compiled | RegexOptions.IgnoreCase));
                    foreach (var file in files)
                    {
                        var stream = casc.ReadFile(file);
                        if (stream != null)
                        {
                            dic.TryAdd(Path.GetFileName(file), stream);
                        }
                    }
                }
                break;
            }

            if (dic.Count == 0)
            {
                throw new Exception("   No matching files found.");
            }

            if (!Directory.Exists(output))
            {
                Directory.CreateDirectory(output);
            }

            foreach (var d in dic)
            {
                using (var fs = new FileStream(Path.Combine(output, d.Key), FileMode.Create))
                {
                    fs.Write(d.Value.ToArray(), 0, (int)d.Value.Length);
                    fs.Close();
                }
            }

            dic.Clear();

            Console.WriteLine($"   Successfully extracted files.");
            Console.WriteLine("");
        }
Beispiel #17
0
        /// <summary>
        /// Loads a file into the console
        /// <para>load -f "*.dbc" -s ".mpq/wow dir" -b 11802</para>
        /// </summary>
        /// <param name="args"></param>
        ///
        public static void LoadCommand(string[] args)
        {
            var        pmap      = ConsoleManager.ParseCommand(args);
            string     file      = ParamCheck <string>(pmap, "-f");
            string     filename  = Path.GetFileName(file);
            string     filenoext = Path.GetFileNameWithoutExtension(file);
            string     source    = ParamCheck <string>(pmap, "-s", false);
            int        build     = ParamCheck <int>(pmap, "-b");
            SourceType sType     = GetSourceType(source);

            //Check file exists if loaded from the filesystem
            if (!File.Exists(file) && sType == SourceType.File)
            {
                throw new Exception($"   File not found {file}.");
            }

            //Check the required definition exists
            var def = Database.Definitions.Tables.FirstOrDefault(x => x.Build == build && x.Name.Equals(filenoext, IGNORECASE));

            if (def == null)
            {
                throw new Exception($"   Could not find definition for {Path.GetFileName(file)} build {build}.");
            }

            Database.BuildNumber = build;
            var    dic   = new ConcurrentDictionary <string, MemoryStream>();
            string error = string.Empty;

            switch (sType)
            {
            case SourceType.MPQ:
                Console.WriteLine("Loading from MPQ archive...");
                using (MpqArchive archive = new MpqArchive(source, FileAccess.Read))
                {
                    string line = string.Empty;
                    bool   loop = true;
                    using (MpqFileStream listfile = archive.OpenFile("(listfile)"))
                        using (StreamReader sr = new StreamReader(listfile))
                        {
                            while ((line = sr.ReadLine()) != null && loop)
                            {
                                if (line.EndsWith(filename, IGNORECASE))
                                {
                                    loop = false;
                                    var ms = new MemoryStream();
                                    archive.OpenFile(line).CopyTo(ms);
                                    dic.TryAdd(filename, ms);

                                    error = Database.LoadFiles(dic).Result.FirstOrDefault();
                                }
                            }
                        }
                }
                break;

            case SourceType.CASC:
                Console.WriteLine("Loading from CASC directory...");
                using (var casc = new CASCHandler(source))
                {
                    string fullname = filename;
                    if (!fullname.StartsWith("DBFilesClient", IGNORECASE))
                    {
                        fullname = "DBFilesClient\\" + filename;     //Ensure we have the current file name structure
                    }
                    var stream = casc.ReadFile(fullname);
                    if (stream != null)
                    {
                        dic.TryAdd(filename, stream);

                        error = Database.LoadFiles(dic).Result.FirstOrDefault();
                    }
                }
                break;

            default:
                error = Database.LoadFiles(new string[] { file }).Result.FirstOrDefault();
                break;
            }

            dic.Clear();

            if (!string.IsNullOrWhiteSpace(error))
            {
                throw new Exception("   " + error);
            }

            if (Database.Entries.Count == 0)
            {
                throw new Exception("   File could not be loaded.");
            }

            Console.WriteLine($"{Path.GetFileName(file)} loaded.");
            Console.WriteLine("");
        }
Beispiel #18
0
        /// <exception cref="ArgumentException">Thrown when the <see cref="MpqArchive"/> does not contain an <see cref="Attributes"/> file.</exception>
        public static bool VerifyAttributes(this MpqArchive archive)
        {
            if (!archive.TryOpenFile(Attributes.FileName, out var attributesStream))
            {
                throw new ArgumentException($"The archive must contain an {Attributes.FileName} file.", nameof(archive));
            }

            archive.AddFileName(Signature.FileName);

            using var reader = new BinaryReader(attributesStream);

            var attributes  = reader.ReadAttributes();
            var hasCrc32    = attributes.Flags.HasFlag(AttributesFlags.Crc32);
            var hasDateTime = attributes.Flags.HasFlag(AttributesFlags.DateTime);
            var hasUnk0x04  = attributes.Flags.HasFlag(AttributesFlags.Unk0x04);

            var count = 0;

            foreach (var mpqEntry in archive)
            {
                if (hasCrc32)
                {
                    var actualCrc32 = attributes.Crc32s[count];
                    if (string.Equals(mpqEntry.FileName, Attributes.FileName, StringComparison.OrdinalIgnoreCase))
                    {
                        if (actualCrc32 != 0)
                        {
                            return(false);
                        }
                    }
                    else if (string.Equals(mpqEntry.FileName, Signature.FileName, StringComparison.OrdinalIgnoreCase))
                    {
                        if (actualCrc32 != _signatureCrc32)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        using var mpqEntryStream = archive.OpenFile(mpqEntry);
                        if (actualCrc32 != new CRC32().GetCrc32(mpqEntryStream))
                        {
                            return(false);
                        }
                    }
                }

                if (hasUnk0x04)
                {
                    var unk0x04 = attributes.Unk0x04s[count];
                    if (unk0x04.Length != 16)
                    {
                        return(false);
                    }

                    for (var i = 0; i < 16; i++)
                    {
                        if (unk0x04[i] != 0)
                        {
                            return(false);
                        }
                    }
                }

                count++;
            }

            return((!hasCrc32 || attributes.Crc32s.Count == count) &&
                   (!hasDateTime || attributes.DateTimes.Count == count) &&
                   (!hasUnk0x04 || attributes.Unk0x04s.Count == count));
        }
Beispiel #19
0
        private static void OpenArchiveBackgroundWork(object?sender, DoWorkEventArgs e)
        {
            _archive = MpqArchive.Open((string)e.Argument, true);
            _archive.DiscoverFileNames();

            var mapsList = new HashSet <string>();

            if (_archive.IsCampaignArchive(out var campaignInfo))
            {
                for (var i = 0; i < campaignInfo.Maps.Count; i++)
                {
                    mapsList.Add(campaignInfo.Maps[i].MapFilePath);
                }
            }
            else
            {
                using var mpqStream = _archive.OpenFile(MapInfo.FileName);
                using var reader    = new BinaryReader(mpqStream);
                _originPatch        = reader.ReadMapInfo().GetOriginGamePatch();
            }

            var listViewItems         = new List <ListViewItem>();
            var possibleOriginPatches = new HashSet <GamePatch>();
            var files = _archive.ToList();

            var progress = new OpenArchiveProgress();

            progress.Maximum = files.Count;

            foreach (var file in files)
            {
                if (mapsList.Contains(file.FileName))
                {
                    var mapName = file.FileName;

                    using var mapArchiveStream = _archive.OpenFile(mapName);
                    using var mapArchive       = MpqArchive.Open(mapArchiveStream, true);
                    mapArchive.DiscoverFileNames();

                    var children = new List <ListViewItem>();
                    var mapFiles = mapArchive.ToList();

                    progress.Maximum += mapFiles.Count;

                    foreach (var mapFile in mapArchive)
                    {
                        var subItem = ListViewItemExtensions.Create(new ItemTag(mapArchive, mapFile, mapName));

                        subItem.IndentCount = 1;
                        children.Add(subItem);

                        _openArchiveWorker.ReportProgress(0, progress);
                    }

                    using (var mapInfoFileStream = mapArchive.OpenFile(MapInfo.FileName))
                    {
                        using var reader = new BinaryReader(mapInfoFileStream);
                        var mapArchiveOriginPatch = reader.ReadMapInfo().GetOriginGamePatch();

                        var mapArchiveItem = ListViewItemExtensions.Create(new ItemTag(_archive, file, children.ToArray(), mapArchiveOriginPatch));

                        listViewItems.Add(mapArchiveItem);

                        _openArchiveWorker.ReportProgress(0, progress);

                        if (mapArchiveOriginPatch.HasValue)
                        {
                            possibleOriginPatches.Add(mapArchiveOriginPatch.Value);
                        }
                    }

                    foreach (var child in children)
                    {
                        listViewItems.Add(child);
                    }
                }
                else
                {
                    var item = ListViewItemExtensions.Create(new ItemTag(_archive, file));

                    listViewItems.Add(item);

                    _openArchiveWorker.ReportProgress(0, progress);
                }
            }

            if (_originPatch is null)
            {
                _originPatch = possibleOriginPatches.Count == 1 ? possibleOriginPatches.Single() : _latestPatch;
            }

            e.Result = listViewItems;
        }
Beispiel #20
0
        private static void SaveArchiveBackgroundWork(object?sender, DoWorkEventArgs e)
        {
            var archiveBuilder = new MpqArchiveBuilder(_archive);

            var progress = new SaveArchiveProgress();

            progress.Saving = false;

            for (var i = 0; i < _fileList.Items.Count; i++)
            {
                var tag = _fileList.Items[i].GetTag();
                if (tag.Parent is not null)
                {
                    continue;
                }

                if (tag.Status == MapFileStatus.Removed)
                {
                    if (tag.TryGetHashedFileName(out var hashedFileName))
                    {
                        archiveBuilder.RemoveFile(hashedFileName);
                    }
                    else
                    {
                        archiveBuilder.RemoveFile(_archive, tag.MpqEntry);
                    }
                }
                else if (tag.Children is not null)
                {
                    if (tag.Children.All(child => child.Status == MapFileStatus.Removed))
                    {
                        throw new InvalidOperationException("Parent tag should have been removed since all child tags are removed, but was " + tag.Status);
                    }
                    else if (tag.Children.Any(child => child.IsModified || child.Status == MapFileStatus.Removed))
                    {
                        // Assume at most one nested archive (for campaign archives), so no recursion.
                        using var subArchive = MpqArchive.Open(_archive.OpenFile(tag.FileName));
                        foreach (var child in tag.Children)
                        {
                            if (child.FileName != null)
                            {
                                subArchive.AddFileName(child.FileName);
                            }
                        }

                        var subArchiveBuilder = new MpqArchiveBuilder(subArchive);
                        foreach (var child in tag.Children)
                        {
                            if (child.Status == MapFileStatus.Removed)
                            {
                                if (child.TryGetHashedFileName(out var hashedFileName))
                                {
                                    subArchiveBuilder.RemoveFile(hashedFileName);
                                }
                                else
                                {
                                    subArchiveBuilder.RemoveFile(subArchive, child.MpqEntry);
                                }
                            }
                            else if (child.TryGetModifiedMpqFile(out var subArchiveAdaptedFile))
                            {
                                subArchiveBuilder.AddFile(subArchiveAdaptedFile);

                                _saveArchiveWorker.ReportProgress(0, progress);
                            }
                            else
                            {
                                _saveArchiveWorker.ReportProgress(0, progress);
                            }
                        }

                        var adaptedSubArchiveStream = new MemoryStream();
                        subArchiveBuilder.SaveWithPreArchiveData(adaptedSubArchiveStream, true);

                        adaptedSubArchiveStream.Position = 0;
                        var adaptedFile = MpqFile.New(adaptedSubArchiveStream, tag.FileName, false);
                        adaptedFile.TargetFlags = tag.MpqEntry.Flags;
                        archiveBuilder.AddFile(adaptedFile);

                        _saveArchiveWorker.ReportProgress(0, progress);
                    }
                    else
                    {
                        _saveArchiveWorker.ReportProgress(tag.Children.Length, progress);
                    }
                }
                else if (tag.TryGetModifiedMpqFile(out var adaptedFile))
                {
                    archiveBuilder.AddFile(adaptedFile);

                    _saveArchiveWorker.ReportProgress(0, progress);
                }
                else
                {
                    _saveArchiveWorker.ReportProgress(0, progress);
                }
            }

            progress.Saving = true;
            _saveArchiveWorker.ReportProgress(0, progress);

            using (var fileStream = File.Create((string)e.Argument))
            {
                archiveBuilder.SaveWithPreArchiveData(fileStream);
            }
        }
Beispiel #21
0
        public void ProcessMPQ(List <string> lstAllMPQFiles)
        {
            // Create a folder to dump all this into
            Directory.CreateDirectory(DBCOutputDir);

            // Go through all the files, getting all DBCs
            foreach (var mpqFileName in lstAllMPQFiles)
            {
                //Directory.CreateDirectory(Path.Combine(DBCOutputDir, Path.GetFileNameWithoutExtension(mpqFileName)));

                using (var oArchive = new MpqArchive(mpqFileName))
                {
                    var dbcFiles = oArchive.FindAllFiles("*.dbc");
                    //var dbcsFiles = from a in oArchive.Files
                    //                where a.Name.EndsWith(".dbc")
                    //                select a.Name;

                    foreach (var strFileName in dbcFiles)
                    {
                        var strLocalFilePath = string.Format(@"{0}\{1}", DBCOutputDir, Path.GetFileName(strFileName));
                        //var strLocalFilePath = Path.Combine(DBCOutputDir, Path.GetFileNameWithoutExtension(mpqFileName));
                        //strLocalFilePath = Path.Combine(strLocalFilePath, Path.GetFileName(strFileName));

                        if (File.Exists(strLocalFilePath))
                        {
                            continue;
                        }

                        using (Stream stmOutput = new FileStream(strLocalFilePath, FileMode.Create))
                        {
                            using (Stream stmInput = oArchive.OpenFile(strFileName).GetStream())
                            {
                                // Writing...
                                Console.Write(string.Format("Writing File {0}....", Path.GetFileName(strFileName)));

                                // Create an 8kb buffer
                                var byFileContents = new byte[8192];

                                // Loop until we're out of data
                                while (true)
                                {
                                    // Read from the MPQ
                                    int intBytesRead = stmInput.Read(byFileContents, 0, byFileContents.Length);

                                    // Was there anything to read?
                                    if (intBytesRead == 0)
                                    {
                                        break;
                                    }

                                    // Write to the file
                                    stmOutput.Write(byFileContents, 0, intBytesRead);
                                }
                            }

                            Console.WriteLine("Done");
                        }
                    }
                }
            }
        }
Beispiel #22
0
        public static bool ExtractDBC()
        {
            try
            {
                Console.WriteLine("Extracting DBC files...");
                //Check if dbc.MPQ exist.
                if (!File.Exists(Globals.DBCPath))
                {
                    Console.WriteLine($"Unable to locate dbc.MPQ at path {Globals.DBCPath}, please check Config.txt and set a proper installation path.");
                    return(false);
                }

                // Clean up output directory if neccesary.
                if (Directory.Exists(OutputPath))
                {
                    Directory.Delete(OutputPath, true);
                }
                Directory.CreateDirectory(OutputPath);

                using (MpqArchive archive = new MpqArchive(Globals.DBCPath))
                {
                    archive.AddListfileFilenames();
                    foreach (var entry in archive)
                    {
                        if (!string.IsNullOrEmpty(entry.Filename))
                        {
                            var outputFileName = Path.Combine(OutputPath, Path.GetFileName(entry.Filename));

                            if (File.Exists(outputFileName))
                            {
                                File.Delete(outputFileName);
                            }

                            if (entry.Filename.Equals("DBFilesClient\\AreaTable.dbc"))
                            {
                                byte[] buf = new byte[0x40000];
                                using (Stream streamIn = archive.OpenFile(entry))
                                {
                                    using (Stream streamOut = new FileStream(outputFileName, FileMode.Create))
                                    {
                                        while (true)
                                        {
                                            int cb = streamIn.Read(buf, 0, buf.Length);
                                            if (cb == 0)
                                            {
                                                break;
                                            }

                                            streamOut.Write(buf, 0, cb);
                                            Program.UpdateLoadingStatus();
                                        }

                                        streamOut.Close();
                                    }
                                }

                                Console.WriteLine($"Extracted DBC file {entry.Filename}");
                            }
                        }
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return(false);
        }