예제 #1
0
        private static GMAFileHeader[] PickModels(GMAFile file)
        {
            GMAFileHeader[] files          = file.Files;
            GMAFileHeader[] workshopModels = files.Where(f => Path.GetExtension(f.Path) == ".mdl").OrderBy(f => f.Path.ToLowerInvariant()).ToArray();

            Pl("Here is a list of all models I found in this addon:");
            for (int i = 0; i < workshopModels.Length; i++)
            {
                Pl("({0}): {1}", i, workshopModels[i].Path.ToLowerInvariant());
            }

            Pl("\nType in the left-hand-side numbers of the models you're interested in, comma separated, use dash for ranges (eg: 1,3,7 or 1,3,6-9).");

            List <GMAFileHeader> pickedModels = new List <GMAFileHeader>();

            while (true)
            {
                string input = Console.ReadLine();
                if (!string.IsNullOrEmpty(input))
                {
                    string[] inputSplit = input.Split(',');
                    foreach (string snumber in inputSplit)
                    {
                        MatchCollection regexMatches = Regex.Matches(snumber, @"(\d+)-(\d+)");

                        if (int.TryParse(snumber, out int output))
                        {
                            if (output < 0 || output >= workshopModels.Length)
                            {
                                Pl($"Invalid index \"{output}\".");
                                goto PickModelsTryAgain;
                            }

                            pickedModels.Add(workshopModels[output]);
                        }
                        else if (regexMatches.Count > 0)
                        {
                            Match m     = regexMatches[0];
                            int   start = int.Parse(m.Groups[1].Value);
                            int   end   = int.Parse(m.Groups[2].Value);
                            for (int i = start; i <= end; i++)
                            {
                                pickedModels.Add(workshopModels[i]);
                            }
                        }
                        else
                        {
                            Pl($"Malformed number \"{snumber}\".");
                            goto PickModelsTryAgain;
                        }
                    }

                    break;
                }

PickModelsTryAgain:
                Pl("Try again.");
            }

            return(pickedModels.Distinct(new GMAFileHeaderComparer()).ToArray());
        }
예제 #2
0
        private static void RunProgram()
        {
            _tempPath = Path.Combine(Path.GetTempPath(), "gmoditemextractor");
            try
            {
                if (Directory.Exists(_tempPath))
                {
                    Directory.Delete(_tempPath, true);
                }
            }
            catch (IOException)
            {
            }

            Pl("Welcome to this tool made by Donkie.\nIt's designed to help you extract the correct model and materials related to said model from a Garrysmod workshop addon.");

            _addonsPath = StartupAddonsPath();
            Pl();

GetAddonPath:
            string addonPath = GetAddonPath();

            Thread.Sleep(1000);

            Pl("Extracting GMA...");
            GMAFile gmaFile = new GMAFile(addonPath);

PickModels:
            GMAFileHeader[] pickedModels = PickModels(gmaFile);
            Pl("Picked models:");
            foreach (GMAFileHeader f in pickedModels)
            {
                Pl("{0}", f.Path);
            }

            if (!YesNo("Is this correct?"))
            {
                goto PickModels;
            }

            List <GMAFileHeader> filesToKeep = new List <GMAFileHeader>();

            foreach (GMAFileHeader s in pickedModels)
            {
                MDLFiles files;
                try
                {
                    //Textures
                    files = MDLInfo.GetInfo(gmaFile.GetFileData(s.FileNumber));
                }
                catch (CRCMismatchException e)
                {
                    Pl(e.Message + " - ignoring");
                    continue;
                }

                //Model files
                GMAFileHeader[] modelFiles = gmaFile.GetModelFiles(s);
                filesToKeep.AddRange(modelFiles);

                foreach (string locmatpath in files.Paths)
                {
                    string matpath = Path.Combine("materials", locmatpath);

                    foreach (string vmtname in files.FileNames)
                    {
                        string vmtpath = CleanPath(Path.Combine(matpath, vmtname + ".vmt"));

                        GMAFileHeader?file = gmaFile.GetFileByPath(vmtpath);
                        if (!file.HasValue)
                        {
                            continue;
                        }

                        filesToKeep.Add(file.Value);

                        //Finds all VTF files in this VMT file, prepends absolute path, checks if it exists and adds to the list
                        try
                        {
                            string vmtFile = Encoding.UTF8.GetString(gmaFile.GetFileData(file.Value.FileNumber));
                            filesToKeep.AddRange(
                                gmaFile.GetFilesByPaths(
                                    VMTInfo.GetTextureFiles(vmtFile)
                                    )
                                );
                        }
                        catch (CRCMismatchException e)
                        {
                            Pl(e.Message + " - ignoring");
                        }
                    }
                }
            }

            filesToKeep = filesToKeep.Distinct(new GMAFileHeaderComparer()).ToList();

            string addonName = Path.GetFileNameWithoutExtension(addonPath);
            string outputdir = Path.Combine(_addonsPath, $"gie_{addonName}");

            Pl("Necessary files:");
            foreach (GMAFileHeader file in filesToKeep)
            {
                Pl(file.Path);
                string topath       = Path.Combine(outputdir, file.Path);
                string topathFolder = Path.GetDirectoryName(topath);
                if (!Directory.Exists(topathFolder))
                {
                    Directory.CreateDirectory(topathFolder);
                }

                try
                {
                    File.WriteAllBytes(topath, gmaFile.GetFileData(file.FileNumber));
                }
                catch (CRCMismatchException e)
                {
                    Pl(e.Message + " - ignoring");
                }
            }

            gmaFile.Dispose();
            gmaFile = null;

            Pl($"Files extracted to {outputdir}!");

            goto GetAddonPath;
        }
예제 #3
0
 public override bool Equals(GMAFileHeader x, GMAFileHeader y)
 {
     return(GMAFile.PathEqual(x.Path, y.Path));
 }