Ejemplo n.º 1
0
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            GeneratorWorkerArgs args = (GeneratorWorkerArgs)e.Argument;

            Dictionary<string, MetaMap> globalMaps = new Dictionary<string, MetaMap>();
            DateTime startTime = DateTime.Now;

            List<string> mapFiles = Directory.EnumerateFiles(args.InputFolder, "*.map").ToList();
            for (int i = mapFiles.Count - 1; i >= 0; i--)
            {
                if (mapFiles[i].EndsWith("shared.map") || mapFiles[i].EndsWith("campaign.map"))
                    mapFiles.RemoveAt(i);
            }

            for (int i = 0; i < mapFiles.Count; i++)
            {
                Dictionary<ITag, MetaMap> tagMaps = new Dictionary<ITag, MetaMap>();

                IReader reader;
                ICacheFile cacheFile = LoadMap(mapFiles[i], out reader);
                MetaAnalyzer analyzer = new MetaAnalyzer(cacheFile);

                Queue<MetaMap> mapsToProcess = new Queue<MetaMap>();
                foreach (ITag tag in cacheFile.Tags)
                {
                    if (tag.MetaLocation.AsAddress() > 0)
                    {
                        MetaMap map = new MetaMap();
                        tagMaps[tag] = map;
                        mapsToProcess.Enqueue(map);

                        reader.SeekTo(tag.MetaLocation.AsOffset());
                        analyzer.AnalyzeArea(reader, tag.MetaLocation.AsAddress(), map);
                    }
                }
                GenerateSubMaps(mapsToProcess, analyzer, reader, cacheFile);

                Dictionary<string, MetaMap> classMaps = new Dictionary<string, MetaMap>();
                foreach (ITag tag in cacheFile.Tags)
                {
                    if (tag.MetaLocation.AsAddress() > 0)
                    {
                        MetaMap map = tagMaps[tag];
                        EstimateMapSize(map, tag.MetaLocation.AsAddress(), analyzer.GeneratedMemoryMap, 1);

                        string magicStr = CharConstant.ToString(tag.Class.Magic);
                        MetaMap oldClassMap;
                        if (classMaps.TryGetValue(magicStr, out oldClassMap))
                            oldClassMap.MergeWith(map);
                        else
                            classMaps[magicStr] = map;
                    }
                }

                foreach (KeyValuePair<string, MetaMap> map in classMaps)
                {
                    MetaMap globalMap;
                    if (globalMaps.TryGetValue(map.Key, out globalMap))
                        globalMap.MergeWith(map.Value);
                    else
                        globalMaps[map.Key] = map.Value;
                }

                reader.Close();

                args.Worker.ReportProgress(100 * i / (mapFiles.Count - 1));
            }

            string badChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
            foreach (KeyValuePair<string, MetaMap> map in globalMaps)
            {
                string filename = map.Key;
                foreach (char badChar in badChars)
                    filename = filename.Replace(badChar, '_');
                filename += ".xml";
                string path = Path.Combine(args.OutputFolder, filename);

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.IndentChars = "\t";
                XmlWriter writer = XmlWriter.Create(path, settings);
                AssemblyPluginWriter pluginWriter = new AssemblyPluginWriter(writer, "Halo4");

                int size = map.Value.GetBestSizeEstimate();
                FoldSubMaps(map.Value);

                pluginWriter.EnterPlugin(size);

                pluginWriter.EnterRevisions();
                pluginWriter.VisitRevision(new PluginRevision("Assembly", 1, "Generated plugin from scratch."));
                pluginWriter.LeaveRevisions();

                WritePlugin(map.Value, size, pluginWriter);
                pluginWriter.LeavePlugin();

                writer.Dispose();
            }

            DateTime endTime = DateTime.Now;
            e.Result = endTime.Subtract(startTime);
        }
Ejemplo n.º 2
0
        private void WritePlugin(MetaMap map, int size, AssemblyPluginWriter writer)
        {
            for (int offset = 0; offset < size; offset += 4)
            {
                MetaValueGuess guess = map.GetGuess(offset);
                if (guess != null)
                {
                    switch (guess.Type)
                    {
                        case MetaValueType.DataReference:
                            if (offset <= size - 0x14)
                            {
                                writer.VisitDataReference("Unknown", (uint)offset, false, 0);
                                offset += 0x10;
                                continue;
                            }
                            break;

                        case MetaValueType.TagReference:
                            if (offset <= size - 0x10)
                            {
                                writer.VisitTagReference("Unknown", (uint)offset, false, true, true, 0);
                                offset += 0xC;
                                continue;
                            }
                            break;

                        case MetaValueType.Reflexive:
                            if (offset <= size - 0xC)
                            {
                                MetaMap subMap = map.GetSubMap(offset);
                                if (subMap != null)
                                {
                                    int subMapSize = subMap.GetBestSizeEstimate();
                                    writer.EnterReflexive("Unknown", (uint)offset, false, (uint)subMapSize, 0);
                                    WritePlugin(subMap, subMapSize, writer);
                                    writer.LeaveReflexive();
                                    offset += 0x8;
                                    continue;
                                }
                            }
                            break;
                    }
                }

                // Just write an unknown value depending upon how much space we have left
                if (offset <= size - 4)
                    writer.VisitUndefined("Unknown", (uint)offset, false, 0);
                else if (offset <= size - 2)
                    writer.VisitInt16("Unknown", (uint)offset, false, 0);
                else
                    writer.VisitInt8("Unknown", (uint)offset, false, 0);
            }
        }
Ejemplo n.º 3
0
        private void doConvert(BackgroundWorker worker, IEnumerable<string> files, string outputDir, string gameName)
        {
            int progress = 0;
            foreach (string file in files)
            {
                string name = Path.GetFileName(file);
                worker.ReportProgress(progress, "Converting " + name + "...");
                progress++;

                if (file.EndsWith(".asc") || file.EndsWith(".alt") || file.EndsWith(".ent") || file.EndsWith(".xml"))
                {
                    XmlReader reader = null;
                    XmlWriter writer = null;
                    try
                    {
                        string extension = ".xml";
                        if (ascensionFmt.Checked)
                            extension = ".asc";
                        else if (alterationFmt.Checked)
                            extension = ".alt";

                        XmlWriterSettings settings = new XmlWriterSettings();
                        settings.Indent = true;
                        settings.IndentChars = "\t";
                        string outPath = Path.Combine(outputDir, Path.ChangeExtension(name, extension));
                        writer = XmlWriter.Create(outPath, settings);
                        reader = XmlReader.Create(file);

                        IPluginVisitor visitor;
                        if (assemblyFmt.Checked)
                            visitor = new AssemblyPluginWriter(writer, gameName);
                        else if (ascensionFmt.Checked)
                            visitor = new AscensionPluginWriter(writer, Path.GetFileNameWithoutExtension(file));
                        else
                            throw new InvalidOperationException("Unsupported output format.");

                        UniversalPluginLoader.LoadPlugin(reader, visitor);
                    }
                    finally
                    {
                        if (reader != null)
                            reader.Close();
                        if (writer != null)
                            writer.Close();
                    }
                }
            }
            worker.ReportProgress(progress, "Done!");
        }