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()); }
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; }
public override bool Equals(GMAFileHeader x, GMAFileHeader y) { return(GMAFile.PathEqual(x.Path, y.Path)); }