private void worker_DoWork(object sender, DoWorkEventArgs e, IList<MapEntry> generatorMaps, string outputPath, BackgroundWorker worker) { var globalMaps = new Dictionary<string, MetaMap>(); DateTime startTime = DateTime.Now; string gameIdentifier = ""; for (int i = 0; i < generatorMaps.Count; i++) { var tagMaps = new Dictionary<ITag, MetaMap>(); IReader reader; KeyValuePair<ICacheFile, EngineDescription> cacheData = LoadMap(generatorMaps[i].LocalMapPath, out reader); ICacheFile cacheFile = cacheData.Key; var analyzer = new MetaAnalyzer(cacheFile); if (gameIdentifier == "") gameIdentifier = cacheData.Value.Settings.GetSetting<string>("shortName"); var mapsToProcess = new Queue<MetaMap>(); foreach (ITag tag in cacheFile.Tags) { if (tag.MetaLocation == null) continue; var map = new MetaMap(); tagMaps[tag] = map; mapsToProcess.Enqueue(map); reader.SeekTo(tag.MetaLocation.AsOffset()); analyzer.AnalyzeArea(reader, tag.MetaLocation.AsPointer(), map); } GenerateSubMaps(mapsToProcess, analyzer, reader, cacheFile); var classMaps = new Dictionary<string, MetaMap>(); foreach (ITag tag in cacheFile.Tags) { if (tag.MetaLocation == null) continue; MetaMap map = tagMaps[tag]; EstimateMapSize(map, tag.MetaLocation.AsPointer(), 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 (var map in classMaps) { MetaMap globalMap; if (globalMaps.TryGetValue(map.Key, out globalMap)) globalMap.MergeWith(map.Value); else globalMaps[map.Key] = map.Value; } reader.Close(); worker.ReportProgress(100*i/(generatorMaps.Count - 1)); } string badChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); foreach (var map in globalMaps) { string filename = badChars.Aggregate(map.Key, (current, badChar) => current.Replace(badChar, '_')); filename += ".xml"; string path = Path.Combine(outputPath, filename); var settings = new XmlWriterSettings { Indent = true, IndentChars = "\t" }; using (XmlWriter writer = XmlWriter.Create(path, settings)) { var pluginWriter = new AssemblyPluginWriter(writer, gameIdentifier); 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(); } } DateTime endTime = DateTime.Now; e.Result = endTime.Subtract(startTime); }
private void GenerateSubMaps(Queue<MetaMap> maps, MetaAnalyzer analyzer, IReader reader, ICacheFile cacheFile) { var generatedMaps = new Dictionary<uint, MetaMap>(); while (maps.Count > 0) { MetaMap map = maps.Dequeue(); foreach (MetaValueGuess guess in map.Guesses.Where(guess => guess.Type == MetaValueType.Reflexive)) { MetaMap subMap; if (!generatedMaps.TryGetValue(guess.Pointer, out subMap)) { subMap = new MetaMap(); reader.SeekTo(cacheFile.MetaArea.PointerToOffset(guess.Pointer)); analyzer.AnalyzeArea(reader, guess.Pointer, subMap); maps.Enqueue(subMap); generatedMaps[guess.Pointer] = subMap; } map.AssociateSubMap(guess.Offset, subMap); } } }