public ObjectCreator(Manifest manifest, FileSystem.FileSystem modFiles) { typeCache = new Cache <string, Type>(FindType); ctorCache = new Cache <Type, ConstructorInfo>(GetCtor); // Allow mods to load types from the core Game assembly, and any additional assemblies they specify. var assemblyList = new List <Assembly>() { typeof(Game).Assembly }; foreach (var path in manifest.Assemblies) { var data = modFiles.Open(path).ReadAllBytes(); // .NET doesn't provide any way of querying the metadata of an assembly without either: // (a) loading duplicate data into the application domain, breaking the world. // (b) crashing if the assembly has already been loaded. // We can't check the internal name of the assembly, so we'll work off the data instead var hash = CryptoUtil.SHA1Hash(data); Assembly assembly; if (!ResolvedAssemblies.TryGetValue(hash, out assembly)) { assembly = Assembly.Load(data); ResolvedAssemblies.Add(hash, assembly); } assemblyList.Add(assembly); } AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray(); AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly; }
public IReadOnlyPackage OpenPackage(string filename, FileSystem context) { return(Parent.OpenPackage(path + '/' + filename, context)); }
public ModData(Manifest mod, InstalledMods mods, bool useLoadScreen = false) { Languages = Array.Empty <string>(); // Take a local copy of the manifest Manifest = new Manifest(mod.Id, mod.Package); ObjectCreator = new ObjectCreator(Manifest, mods); PackageLoaders = ObjectCreator.GetLoaders <IPackageLoader>(Manifest.PackageFormats, "package"); ModFiles = new FS(mod.Id, mods, PackageLoaders); ModFiles.LoadFromManifest(Manifest); Manifest.LoadCustomData(ObjectCreator); if (useLoadScreen) { LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value); LoadScreen.Init(this, Manifest.LoadScreen.ToDictionary(my => my.Value)); LoadScreen.Display(); } WidgetLoader = new WidgetLoader(this); MapCache = new MapCache(this); SoundLoaders = ObjectCreator.GetLoaders <ISoundLoader>(Manifest.SoundFormats, "sound"); SpriteLoaders = ObjectCreator.GetLoaders <ISpriteLoader>(Manifest.SpriteFormats, "sprite"); VideoLoaders = ObjectCreator.GetLoaders <IVideoLoader>(Manifest.VideoFormats, "video"); var terrainFormat = Manifest.Get <TerrainFormat>(); var terrainLoader = ObjectCreator.FindType(terrainFormat.Type + "Loader"); var terrainCtor = terrainLoader?.GetConstructor(new[] { typeof(ModData) }); if (terrainLoader == null || !terrainLoader.GetInterfaces().Contains(typeof(ITerrainLoader)) || terrainCtor == null) { throw new InvalidOperationException($"Unable to find a terrain loader for type '{terrainFormat.Type}'."); } TerrainLoader = (ITerrainLoader)terrainCtor.Invoke(new[] { this }); var sequenceFormat = Manifest.Get <SpriteSequenceFormat>(); var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader"); var sequenceCtor = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null; if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || sequenceCtor == null) { throw new InvalidOperationException($"Unable to find a sequence loader for type '{sequenceFormat.Type}'."); } SpriteSequenceLoader = (ISpriteSequenceLoader)sequenceCtor.Invoke(new[] { this }); var modelFormat = Manifest.Get <ModelSequenceFormat>(); var modelLoader = ObjectCreator.FindType(modelFormat.Type + "Loader"); var modelCtor = modelLoader != null?modelLoader.GetConstructor(new[] { typeof(ModData) }) : null; if (modelLoader == null || !modelLoader.GetInterfaces().Contains(typeof(IModelSequenceLoader)) || modelCtor == null) { throw new InvalidOperationException($"Unable to find a model loader for type '{modelFormat.Type}'."); } ModelSequenceLoader = (IModelSequenceLoader)modelCtor.Invoke(new[] { this }); ModelSequenceLoader.OnMissingModelError = s => Log.Write("debug", s); Hotkeys = new HotkeyManager(ModFiles, Game.Settings.Keys, Manifest); defaultRules = Exts.Lazy(() => Ruleset.LoadDefaults(this)); defaultTerrainInfo = Exts.Lazy(() => { var items = new Dictionary <string, ITerrainInfo>(); foreach (var file in Manifest.TileSets) { var t = TerrainLoader.ParseTerrain(DefaultFileSystem, file); items.Add(t.Id, t); } return((IReadOnlyDictionary <string, ITerrainInfo>)(new ReadOnlyDictionary <string, ITerrainInfo>(items))); }); defaultSequences = Exts.Lazy(() => { var items = DefaultTerrainInfo.ToDictionary(t => t.Key, t => new SequenceProvider(DefaultFileSystem, this, t.Key, null)); return((IReadOnlyDictionary <string, SequenceProvider>)(new ReadOnlyDictionary <string, SequenceProvider>(items))); }); initialThreadId = Environment.CurrentManagedThreadId; }
public IReadOnlyPackage OpenPackage(string filename, FileSystem context) { // Not implemented return(null); }
public bool TryParsePackage(Stream s, string filename, OpenRA.FileSystem.FileSystem context, out IReadOnlyPackage package) { package = new DataFile(s, filename); return(true); }
public IReadOnlyPackage OpenPackage(string filename, OpenRA.FileSystem.FileSystem context) { return(null); }
public LvlPackage(Stream s, string filename, FS context) { stream = s; Name = filename; var lvlLookup = new Dictionary <string, string>(); var updateLookup = false; Stream s2; if (context.TryOpen(filename + ".yaml", out s2)) { lvlLookup = MiniYaml.FromStream(s2).ToDictionary(x => x.Key, x => x.Value.Value); } var fileTypeListOffset = s.ReadUInt32(); s.Position = fileTypeListOffset; uint firstFileListOffset = 0; for (var i = 0; s.Position < s.Length; i++) { s.Position = fileTypeListOffset + i * 8; var fileType = s.ReadASCII(4); var fileListOffset = s.ReadUInt32(); // List terminator reached. if (fileListOffset == 0) { break; } // We need this to calculate the last fileLength. if (firstFileListOffset == 0) { firstFileListOffset = fileListOffset; } // To determine when this list ends, check the next entry s.Position += 4; var fileListEndOffset = s.ReadUInt32(); // List terminator reached, so assume the list goes on till the fileTypeList starts. if (fileListEndOffset == 0) { fileListEndOffset = fileTypeListOffset; } s.Position = fileListOffset; for (var j = 0; s.Position < fileListEndOffset; j++) { var fileOffset = s.ReadUInt32(); // Removed file, still increments fileId. if (fileOffset == 0) { continue; } // As the fileLength is nowhere stored, but files always follow in order, calculate the previous fileLength. if (index.Count > 0) { var entry = index.ElementAt(index.Count - 1).Value; entry[1] = fileOffset - entry[0]; } var assetFileName = j + "." + fileType.ToLower(); // Lookup assumed original filename for better readability in yaml files. if (lvlLookup.ContainsKey(assetFileName)) { assetFileName = lvlLookup[assetFileName]; } else { lvlLookup.Add(assetFileName, assetFileName); updateLookup = true; } index.Add(assetFileName, new uint[] { fileOffset, 0 }); } } // Calculate the last fileLength. if (index.Count > 0) { var entry = index.ElementAt(index.Count - 1).Value; entry[1] = firstFileListOffset - entry[0]; } if (updateLookup) { File.WriteAllText(filename + ".yaml", lvlLookup.Select(e => e.Key + ": " + e.Value).JoinWith("\n") + "\n"); } /*if (!Directory.Exists("XTRACT/" + filename)) * Directory.CreateDirectory("XTRACT/" + filename); * * foreach (var entry in index) * { * stream.Position = entry.Value[0]; * File.WriteAllBytes("XTRACT/" + filename + "/" + entry.Key, stream.ReadBytes((int)entry.Value[1])); * }*/ }
public ModContentLogic(Widget widget, ModData modData, Manifest mod, ModContent content, Action onCancel) { this.content = content; var panel = widget.Get("CONTENT_PANEL"); var modObjectCreator = new ObjectCreator(mod, Game.Mods); var modPackageLoaders = modObjectCreator.GetLoaders <IPackageLoader>(mod.PackageFormats, "package"); var modFileSystem = new FS(mod.Id, Game.Mods, modPackageLoaders); modFileSystem.LoadFromManifest(mod); var sourceYaml = MiniYaml.Load(modFileSystem, content.Sources, null); foreach (var s in sourceYaml) { sources.Add(s.Key, new ModContent.ModSource(s.Value)); } var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null); foreach (var d in downloadYaml) { downloads.Add(d.Key, new ModContent.ModDownload(d.Value)); } modFileSystem.UnmountAll(); scrollPanel = panel.Get <ScrollPanelWidget>("PACKAGES"); template = scrollPanel.Get <ContainerWidget>("PACKAGE_TEMPLATE"); var headerTemplate = panel.Get <LabelWidget>("HEADER_TEMPLATE"); var headerLines = !string.IsNullOrEmpty(content.HeaderMessage) ? content.HeaderMessage.Replace("\\n", "\n").Split('\n') : new string[0]; var headerHeight = 0; foreach (var l in headerLines) { var line = (LabelWidget)headerTemplate.Clone(); line.GetText = () => l; line.Bounds.Y += headerHeight; panel.AddChild(line); headerHeight += headerTemplate.Bounds.Height; } panel.Bounds.Height += headerHeight; panel.Bounds.Y -= headerHeight / 2; scrollPanel.Bounds.Y += headerHeight; var discButton = panel.Get <ButtonWidget>("CHECK_DISC_BUTTON"); discButton.Bounds.Y += headerHeight; discButton.IsVisible = () => discAvailable; discButton.OnClick = () => Ui.OpenWindow("DISC_INSTALL_PANEL", new WidgetArgs { { "afterInstall", () => { } }, { "sources", sources }, { "content", content } }); var backButton = panel.Get <ButtonWidget>("BACK_BUTTON"); backButton.Bounds.Y += headerHeight; backButton.OnClick = () => { Ui.CloseWindow(); onCancel(); }; PopulateContentList(); Game.RunAfterTick(Ui.ResetTooltips); }
public ModContentPromptLogic(Widget widget, ModData modData, Manifest mod, ModContent content, Action continueLoading) { this.content = content; CheckRequiredContentInstalled(); var panel = widget.Get("CONTENT_PROMPT_PANEL"); var headerTemplate = panel.Get <LabelWidget>("HEADER_TEMPLATE"); var headerLines = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : new string[0]; var headerHeight = 0; foreach (var l in headerLines) { var line = (LabelWidget)headerTemplate.Clone(); line.GetText = () => l; line.Bounds.Y += headerHeight; panel.AddChild(line); headerHeight += headerTemplate.Bounds.Height; } panel.Bounds.Height += headerHeight; panel.Bounds.Y -= headerHeight / 2; var advancedButton = panel.Get <ButtonWidget>("ADVANCED_BUTTON"); advancedButton.Bounds.Y += headerHeight; advancedButton.OnClick = () => { Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs { { "mod", mod }, { "content", content }, { "onCancel", CheckRequiredContentInstalled } }); }; var quickButton = panel.Get <ButtonWidget>("QUICK_BUTTON"); quickButton.IsVisible = () => !string.IsNullOrEmpty(content.QuickDownload); quickButton.Bounds.Y += headerHeight; quickButton.OnClick = () => { var modObjectCreator = new ObjectCreator(mod, Game.Mods); var modPackageLoaders = modObjectCreator.GetLoaders <IPackageLoader>(mod.PackageFormats, "package"); var modFileSystem = new FS(Game.Mods, modPackageLoaders); modFileSystem.LoadFromManifest(mod); var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null); modFileSystem.UnmountAll(); var download = downloadYaml.FirstOrDefault(n => n.Key == content.QuickDownload); if (download == null) { throw new InvalidOperationException("Mod QuickDownload `{0}` definition not found.".F(content.QuickDownload)); } Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", new WidgetArgs { { "download", new ModContent.ModDownload(download.Value) }, { "onSuccess", continueLoading } }); }; var quitButton = panel.Get <ButtonWidget>("QUIT_BUTTON"); quitButton.GetText = () => requiredContentInstalled ? "Continue" : "Quit"; quitButton.Bounds.Y += headerHeight; quitButton.OnClick = () => { if (requiredContentInstalled) { continueLoading(); } else { Game.Exit(); } }; Game.RunAfterTick(Ui.ResetTooltips); }