示例#1
0
        private static void DumpSharedResources(string mapPath, EngineDatabase db)
        {
            ICacheFile    cacheFile;
            ResourceTable resources;

            using (var reader = new EndianReader(File.OpenRead(mapPath), Endian.BigEndian))
            {
                cacheFile = CacheFileLoader.LoadCacheFile(reader, db);
                resources = cacheFile.Resources.LoadResourceTable(reader);
            }

            using (var output = new StreamWriter(Path.ChangeExtension(mapPath, ".txt")))
            {
                output.WriteLine("Shared resources referenced by {0}:", Path.GetFileName(mapPath));
                output.WriteLine();
                output.WriteLine("Rsrc Datum  Map File      Class  Tag");
                output.WriteLine("----------  --------      -----  ---");

                foreach (Resource resource in resources.Resources.Where(r => r.Location != null && r.ParentTag != null))
                {
                    // If either page has a null file path, then it's shared
                    ResourcePointer loc           = resource.Location;
                    string          primaryFile   = (loc.PrimaryPage != null) ? loc.PrimaryPage.FilePath : null;
                    string          secondaryFile = (loc.SecondaryPage != null) ? loc.SecondaryPage.FilePath : null;
                    if (primaryFile != null || secondaryFile != null)
                    {
                        string className = CharConstant.ToString(resource.ParentTag.Class.Magic);
                        string name      = cacheFile.FileNames.GetTagName(resource.ParentTag) ?? resource.ParentTag.Index.ToString();
                        string fileName  = primaryFile ?? secondaryFile;
                        fileName = fileName.Substring(fileName.IndexOf('\\') + 1);
                        output.WriteLine("{0}  {1, -12}  {2}   {3}", resource.Index, fileName, className, name);
                    }
                }
            }
        }
示例#2
0
        public static Dictionary <string, IEnumerable <UnitSeatMapping> > LoadAllSeatMappings(string path, EngineDatabase db, out EngineDescription engineInfo)
        {
            Dictionary <string, IEnumerable <UnitSeatMapping> > result = new Dictionary <string, IEnumerable <UnitSeatMapping> >();

            string fileName = Path.GetFileNameWithoutExtension(path);

            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                var reader = new EndianReader(stream, Endian.BigEndian);
                var cache  = CacheFileLoader.LoadCacheFile(reader, fileName, db, out engineInfo);
                if (cache.Type != CacheFileType.Shared && cache.Type != CacheFileType.SinglePlayerShared && cache.ScriptFiles.Length > 0)
                {
                    foreach (var file in cache.ScriptFiles)
                    {
                        if (file is ScnrScriptFile scnr)
                        {
                            var mappings = SeatMappingNameExtractor.ExtractScnrSeatMappings(scnr, reader, engineInfo.ScriptInfo);

                            if (mappings.Any())
                            {
                                result[file.Name] = mappings;
                            }
                        }
                    }
                }
            }

            return(result);
        }
        private KeyValuePair <ICacheFile, EngineDescription> LoadMap(string path, out IReader reader)
        {
            reader = new EndianReader(File.OpenRead(path), Endian.BigEndian);

            var cacheFile = CacheFileLoader.LoadCacheFile(reader, path, App.AssemblyStorage.AssemblySettings.DefaultDatabase, out EngineDescription buildInfo);

            return
                (new KeyValuePair <ICacheFile, EngineDescription>(cacheFile, buildInfo));
        }
        public static async Task Create(Dictionary <string, string> arguments, Dictionary <string, string> options)
        {
            await Task.Delay(1);

            var cacheFilePath    = arguments["cache"];
            var projectDirectory = arguments["project"];

            // Check file exists
            if (cacheFilePath == null || !File.Exists(cacheFilePath))
            {
                throw new ComposerException("Cache doesn't exist");
            }

            // Create project directory
            // TODO: think about logic if directory already exists
            if (!Directory.Exists(projectDirectory))
            {
                Directory.CreateDirectory(projectDirectory);
            }

            // Create Project
            var project = new Models.Project
            {
                Title       = "Example Halo Project",
                Version     = "1.0.0",
                Description = "Simple project for testing the tool",
                Properties  = new ProjectProperties
                {
                    TagsFolder = "tags",
                    GitEnabled = true
                }
            };

            using (var stream = File.OpenRead(cacheFilePath))
                using (var reader = new EndianReader(stream, Endian.BigEndian))
                {
                    EngineDescription engineDescription = null;
                    EngineDatabase    engineDatabase    = XMLEngineDatabaseLoader.LoadDatabase("data/formats/engines.xml");
                    var cacheFile    = CacheFileLoader.LoadCacheFile(reader, engineDatabase, out engineDescription);
                    var stringIdTrie = new Trie();
                    if (cacheFile.StringIDs != null)
                    {
                        stringIdTrie.AddRange(cacheFile.StringIDs);
                    }

                    if (cacheFile.TagClasses.Any())
                    {
                        LoadTags(project, cacheFile, projectDirectory, stringIdTrie);
                    }
                }

            File.WriteAllText(Path.Combine(projectDirectory, "project.json"), JsonConvert.SerializeObject(project, Formatting.Indented));
        }
示例#5
0
        public static IEnumerable <ICacheFile> LoadAllMaps(string[] paths, EngineDatabase db)
        {
            List <ICacheFile> result = new List <ICacheFile>();

            foreach (string path in paths)
            {
                using var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
                var reader = new EndianReader(stream, Endian.BigEndian);
                var cache  = CacheFileLoader.LoadCacheFile(reader, Path.GetFileNameWithoutExtension(path), db);
                result.Add(cache);
            }
            return(result);
        }
示例#6
0
        private static ScriptTable LoadScripts(string path, EngineDatabase db, out EngineDescription desc)
        {
            using (var stream = File.OpenRead(path))
            {
                EngineDescription engine;

                var reader = new EndianReader(stream, Endian.BigEndian);
                var cache  = CacheFileLoader.LoadCacheFile(reader, Path.GetFileName(path), db, out engine);
                desc = engine;
                var scripts = cache.ScriptFiles[0].LoadScripts(reader);

                return(scripts);
            }
        }
        public static bool applyPatch(ZipArchiveEntry zippedPatchFile, string patchFileName, string unmoddedMapPath, string outputPath)
        {
            createTmpDir();
            try {
                zippedPatchFile.ExtractToFile(Config.modpack_dir + @"\tmp\" + patchFileName);
            } catch (IOException) {
                rmTmpDir();
                createTmpDir();
                zippedPatchFile.ExtractToFile(Config.modpack_dir + @"\tmp\" + patchFileName);
            }
            Patch currentPatch = LoadPatch(Config.modpack_dir + @"\tmp\" + patchFileName);

            // Copy the original map to the destination path
            IO.CopyFile(unmoddedMapPath, outputPath, true);             //if modpack has written to unmoddedmap, take from backups

            // Open the destination map
            using (var stream = new EndianStream(File.Open(outputPath, FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian)) {
                EngineDatabase engineDb = XMLEngineDatabaseLoader.LoadDatabase("Formats/Engines.xml");
                ICacheFile     cacheFile;
                try {
                    cacheFile = CacheFileLoader.LoadCacheFile(stream, engineDb);
                } catch (NotSupportedException nse) {
                    form1.showMsg("Error patching '" + patchFileName + "':" + nse.Message, "Error");
                    return(false);
                }
                if (!string.IsNullOrEmpty(currentPatch.BuildString) && cacheFile.BuildString != currentPatch.BuildString)
                {
                    form1.showMsg("Unable to patch. That patch is for a map with a build version of " + currentPatch.BuildString +
                                  ", and the unmodified map file doesn't match that.", "Error");
                    return(false);
                }

                if (currentPatch.MapInternalName == null)
                {
                    // Because Ascension doesn't include this, and ApplyPatch() will complain otherwise
                    currentPatch.MapInternalName = cacheFile.InternalName;
                }

                // Apply the patch!
                try {
                    PatchApplier.ApplyPatch(currentPatch, cacheFile, stream);
                } catch (ArgumentException ae) {
                    form1.showMsg("There was an issue applying the patch file '" + patchFileName + "': " + ae.Message, "Info");
                    return(false);
                }
            }

            rmTmpDir();
            return(true);
        }
示例#8
0
        public static Dictionary <string, ScriptTable> LoadAllScriptFiles(string path, EngineDatabase db, out EngineDescription engineInfo)
        {
            Dictionary <string, ScriptTable> result = new Dictionary <string, ScriptTable>();

            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                var reader = new EndianReader(stream, Endian.BigEndian);
                var cache  = CacheFileLoader.LoadCacheFile(reader, path, db, out engineInfo);
                if (cache.Type != CacheFileType.Shared && cache.Type != CacheFileType.SinglePlayerShared && cache.ScriptFiles.Length > 0)
                {
                    foreach (var file in cache.ScriptFiles)
                    {
                        result.Add(file.Name, file.LoadScripts(reader));
                    }
                }
            }
            return(result);
        }
示例#9
0
        // Patch Applying
        private void btnApplyPatch_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Check the user isn't completly retarded
                if (!CheckAllApplyMandatoryFields() || currentPatch == null)
                {
                    return;
                }

                // Check the output name
                if (cacheOutputName != "")
                {
                    if (Path.GetFileNameWithoutExtension(txtApplyPatchOutputMap.Text) != cacheOutputName)
                    {
                        if (MetroMessageBox.Show("Warning",
                                                 "This patch suggests to use the filename \"" + cacheOutputName +
                                                 ".map\" to save this map. This filename may be required in order for the map to work correctly.\r\n\r\nAre you sure you want to save this map as \"" +
                                                 Path.GetFileName(txtApplyPatchOutputMap.Text) + "\"?",
                                                 MetroMessageBox.MessageBoxButtons.OkCancel) != MetroMessageBox.MessageBoxResult.OK)
                        {
                            Close();
                            return;
                        }
                    }
                }

                // Paths
                string unmoddedMapPath = txtApplyPatchUnmodifiedMap.Text;
                string outputPath      = txtApplyPatchOutputMap.Text;

                // Copy the original map to the destination path
                File.Copy(unmoddedMapPath, outputPath, true);

                // Open the destination map
                using (var stream = new EndianStream(File.Open(outputPath, FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian))
                {
                    EngineDatabase engineDb  = XMLEngineDatabaseLoader.LoadDatabase("Formats/Engines.xml");
                    ICacheFile     cacheFile = CacheFileLoader.LoadCacheFile(stream, outputPath, engineDb);
                    if (currentPatch.MapInternalName != null && cacheFile.InternalName != currentPatch.MapInternalName)
                    {
                        MetroMessageBox.Show("Unable to apply patch",
                                             "Hold on there! That patch is for " + currentPatch.MapInternalName +
                                             ".map, and the unmodified map file you selected doesn't seem to match that. Find the correct file and try again.");
                        return;
                    }
                    if (!string.IsNullOrEmpty(currentPatch.BuildString) && cacheFile.BuildString != currentPatch.BuildString)
                    {
                        MetroMessageBox.Show("Unable to apply patch",
                                             "Hold on there! That patch is for a map with a build version of" + currentPatch.BuildString +
                                             ", and the unmodified map file you selected doesn't seem to match that. Find the correct file and try again.");
                        return;
                    }

                    // Apply the patch!
                    if (currentPatch.MapInternalName == null)
                    {
                        currentPatch.MapInternalName = cacheFile.InternalName;
                    }
                    // Because Ascension doesn't include this, and ApplyPatch() will complain otherwise

                    PatchApplier.ApplyPatch(currentPatch, cacheFile, stream);

                    // Check for blf snaps
                    if (cbApplyPatchBlfExtraction.IsChecked != null &&
                        (PatchApplicationPatchExtra.Visibility == Visibility.Visible && (bool)cbApplyPatchBlfExtraction.IsChecked))
                    {
                        string extractDir   = Path.GetDirectoryName(outputPath);
                        string blfDirectory = Path.Combine(extractDir, "images");
                        string infDirectory = Path.Combine(extractDir, "info");
                        if (!Directory.Exists(blfDirectory))
                        {
                            Directory.CreateDirectory(blfDirectory);
                        }
                        if (!Directory.Exists(infDirectory))
                        {
                            Directory.CreateDirectory(infDirectory);
                        }

                        string infPath = Path.Combine(infDirectory, Path.GetFileName(currentPatch.CustomBlfContent.MapInfoFileName));
                        File.WriteAllBytes(infPath, currentPatch.CustomBlfContent.MapInfo);

                        foreach (BlfContainerEntry blfContainerEntry in currentPatch.CustomBlfContent.BlfContainerEntries)
                        {
                            string blfPath = Path.Combine(blfDirectory, Path.GetFileName(blfContainerEntry.FileName));
                            File.WriteAllBytes(blfPath, blfContainerEntry.BlfContainer);
                        }
                    }
                }

                MetroMessageBox.Show("Patch Applied!", "Your patch has been applied successfully. Have fun!");
            }
            catch (Exception ex)
            {
                MetroException.Show(ex);
            }
        }
示例#10
0
        // Patch Creation
        private void btnCreatePatch_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Check the user isn't completly retarded
                if (!CheckAllCreateMandatoryFields())
                {
                    return;
                }

                // Check the user isn't a skid
                if (!CheckAllCreateMetaFilesExists())
                {
                    return;
                }

                // Paths
                string cleanMapPath  = txtCreatePatchUnModifiedMap.Text;
                string moddedMapPath = txtCreatePatchModifiedMap.Text;
                string outputPath    = txtCreatePatchOutputPatch.Text;
                string previewImage  = txtCreatePatchPreviewImage.Text;

                // Details
                string author     = txtCreatePatchContentAuthor.Text;
                string desc       = txtCreatePatchContentDescription.Text;
                string name       = txtCreatePatchContentName.Text;
                string outputName = txtCreatePatchOutputName.Text;

                // Make dat patch
                var patch = new Patch
                {
                    Author      = author,
                    Description = desc,
                    Name        = name,
                    OutputName  = outputName,
                    Screenshot  = String.IsNullOrEmpty(previewImage)
                                                ? null
                                                : File.ReadAllBytes(previewImage),
                    BuildString = _buildInfo.Version,
                    PC          = String.IsNullOrEmpty(_buildInfo.GameExecutable)
                                                ? false
                                                : true
                };

                EndianReader originalReader = null;
                EndianReader newReader      = null;
                try
                {
                    originalReader = new EndianReader(File.OpenRead(cleanMapPath), Endian.BigEndian);
                    newReader      = new EndianReader(File.OpenRead(moddedMapPath), Endian.BigEndian);

                    ICacheFile originalFile = CacheFileLoader.LoadCacheFile(originalReader, cleanMapPath,
                                                                            App.AssemblyStorage.AssemblySettings.DefaultDatabase);
                    ICacheFile newFile = CacheFileLoader.LoadCacheFile(newReader, moddedMapPath, App.AssemblyStorage.AssemblySettings.DefaultDatabase);

                    if (cbCreatePatchHasCustomMeta.IsChecked != null && (bool)cbCreatePatchHasCustomMeta.IsChecked &&
                        cboxCreatePatchTargetGame.SelectedIndex < 4)
                    {
                        var      targetGame      = (TargetGame)cboxCreatePatchTargetGame.SelectedIndex;
                        byte[]   mapInfo         = File.ReadAllBytes(txtCreatePatchMapInfo.Text);
                        var      mapInfoFileInfo = new FileInfo(txtCreatePatchMapInfo.Text);
                        FileInfo blfFileInfo;

                        patch.CustomBlfContent = new BlfContent(mapInfoFileInfo.FullName, mapInfo, targetGame);

                        #region Blf Data

                        if (PatchCreationBlfOption0.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf0.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }
                        if (PatchCreationBlfOption1.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf1.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }
                        if (PatchCreationBlfOption2.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf2.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }
                        if (PatchCreationBlfOption3.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf3.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }

                        #endregion
                    }

                    PatchBuilder.BuildPatch(originalFile, originalReader, newFile, newReader, patch);
                }
                finally
                {
                    if (originalReader != null)
                    {
                        originalReader.Dispose();
                    }
                    if (newReader != null)
                    {
                        newReader.Dispose();
                    }
                }

                IWriter output = new EndianWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write), Endian.BigEndian);
                AssemblyPatchWriter.WritePatch(patch, output);
                output.Dispose();

                MetroMessageBox.Show("Patch Created!",
                                     "Your patch has been created in the designated location. Happy sailing, modder!");
            }
            catch (Exception ex)
            {
                MetroException.Show(ex);
            }
        }
示例#11
0
        static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("Usage: BlockAlignmentScanner <map dir> <in plugin dir> <out plugin dir>");
                return;
            }

            var mapDir = args[0];
            var inDir  = args[1];
            var outDir = args[2];

            Console.WriteLine("Loading plugins...");
            var pluginsByClass = new Dictionary <string, XDocument>();

            foreach (var pluginPath in Directory.EnumerateFiles(inDir, "*.xml"))
            {
                Console.WriteLine("- {0}", pluginPath);
                var document  = XDocument.Load(pluginPath);
                var className = Path.GetFileNameWithoutExtension(pluginPath);
                pluginsByClass[className] = document;
            }

            Console.WriteLine("Loading engine database...");
            var exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var dbPath = Path.Combine(exeDir, "Formats", "Engines.xml");
            var db     = XMLEngineDatabaseLoader.LoadDatabase(dbPath);

            Console.WriteLine("Processing maps...");
            var alignsByElem = new Dictionary <XElement, int>();

            foreach (var mapPath in Directory.EnumerateFiles(mapDir, "*.map"))
            {
                Console.WriteLine("- {0}", Path.GetFileName(mapPath));
                using (var reader = new EndianReader(File.OpenRead(mapPath), Endian.BigEndian))
                {
                    var map = CacheFileLoader.LoadCacheFile(reader, db);
                    var visitedTagBlocks = new HashSet <uint>();
                    foreach (var tag in map.Tags)
                    {
                        if (tag == null || tag.Class == null || tag.MetaLocation == null)
                        {
                            continue;
                        }

                        // Get the plugin for the tag
                        var       className = CharConstant.ToString(tag.Class.Magic);
                        XDocument plugin;
                        if (!pluginsByClass.TryGetValue(className, out plugin))
                        {
                            continue;
                        }

                        // Process it
                        var baseOffset  = tag.MetaLocation.AsOffset();
                        var baseElement = plugin.Element("plugin");
                        DetectAlignment(map, reader, baseOffset, baseElement, alignsByElem, visitedTagBlocks);
                    }
                }
            }

            Console.WriteLine("Adjusting plugins...");
            foreach (var align in alignsByElem)
            {
                if (align.Value != 4)
                {
                    Console.WriteLine("- \"{0}\" -> align 0x{1:X}", align.Key.Attribute("name").Value, align.Value);
                    align.Key.SetAttributeValue(XName.Get("align"), "0x" + align.Value.ToString("X"));
                }
            }

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

            Console.WriteLine("Saving plugins...");
            foreach (var plugin in pluginsByClass)
            {
                var outPath = Path.Combine(outDir, plugin.Key + ".xml");
                Console.WriteLine("- {0}", outPath);

                var settings = new XmlWriterSettings();
                settings.Indent      = true;
                settings.IndentChars = "\t";
                using (var writer = XmlWriter.Create(outPath, settings))
                    plugin.Value.Save(writer);
            }
        }
示例#12
0
        private static void Main(string[] args)
        {
            var ofd = new OpenFileDialog();

            ofd.Title  = "Open Cache File";
            ofd.Filter = "Blam Cache Files|*.map";
            if (ofd.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            var sfd = new SaveFileDialog();

            sfd.Title  = "Save String Dump";
            sfd.Filter = "Text Files|*.txt";
            if (sfd.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            string mapPath  = ofd.FileName;
            string dumpPath = sfd.FileName;

            EngineDatabase engineDb = XMLEngineDatabaseLoader.LoadDatabase("Formats/Engines.xml");
            ICacheFile     cacheFile;
            LanguagePack   locales;

            using (IReader reader = new EndianReader(File.OpenRead(mapPath), Endian.BigEndian))
            {
                Console.WriteLine("Loading cache file...");
                cacheFile = CacheFileLoader.LoadCacheFile(reader, mapPath, engineDb);

                Console.WriteLine("Loading locales...");
                locales = cacheFile.Languages.LoadLanguage(GameLanguage.English, reader);
            }

            var output = new StreamWriter(dumpPath);

            output.WriteLine("Input file: {0}.map", cacheFile.InternalName);
            output.WriteLine();

            // Sort locales by stringID
            var localesById = new List <LocalizedString>();

            localesById.AddRange(locales.StringLists.SelectMany(l => l.Strings).Where(s => s != null && s.Value != null));
            localesById.Sort((x, y) => x.Key.Value.CompareTo(y.Key.Value));

            // Dump locales
            Console.WriteLine("Dumping locales...");
            output.WriteLine("---------------");
            output.WriteLine("English Locales");
            output.WriteLine("---------------");
            foreach (LocalizedString str in localesById)
            {
                if (str != null)
                {
                    output.WriteLine("{0} = \"{1}\"", str.Key, str.Value);
                }
            }
            output.WriteLine();

            // Dump stringIDs
            Console.WriteLine("Dumping stringIDs...");
            output.WriteLine("---------");
            output.WriteLine("StringIDs");
            output.WriteLine("---------");
            int index = 0;

            foreach (string str in cacheFile.StringIDs)
            {
                if (str != null)
                {
                    output.WriteLine("0x{0:X} = \"{1}\"", index, str);
                }
                else
                {
                    output.WriteLine("0x{0:X} = (null)", index);
                }

                index++;
            }
            output.Close();

            Console.WriteLine("Done!");
        }