internal void Register(Manifest mod, string launchPath, ModRegistration registration) { if (mod.Metadata.Hidden) { return; } var iconData = ""; using (var stream = mod.Package.GetStream("icon.png")) if (stream != null) { iconData = Convert.ToBase64String(stream.ReadAllBytes()); } var key = ExternalMod.MakeKey(mod); var yaml = new List <MiniYamlNode>() { new MiniYamlNode("Registration", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("Id", mod.Id), new MiniYamlNode("Version", mod.Metadata.Version), new MiniYamlNode("Title", mod.Metadata.Title), new MiniYamlNode("Icon", iconData), new MiniYamlNode("LaunchPath", launchPath), new MiniYamlNode("LaunchArgs", "Game.Mod=" + mod.Id) })) }; var sources = new List <string>(); if (registration.HasFlag(ModRegistration.System)) { sources.Add(Platform.SystemSupportDir); } if (registration.HasFlag(ModRegistration.User)) { sources.Add(Platform.SupportDir); } // Make sure the mod is available for this session, even if saving it fails LoadMod(yaml.First().Value, forceRegistration: true); foreach (var source in sources.Distinct()) { var metadataPath = Path.Combine(source, "ModMetadata"); try { Directory.CreateDirectory(metadataPath); File.WriteAllLines(Path.Combine(metadataPath, key + ".yaml"), yaml.ToLines().ToArray()); } catch (Exception e) { Log.Write("debug", "Failed to register current mod metadata"); Log.Write("debug", e.ToString()); } } }
internal void Unregister(Manifest mod, ModRegistration registration) { var sources = new List <string>(); if (registration.HasFlag(ModRegistration.System)) { sources.Add(Platform.SystemSupportDir); } if (registration.HasFlag(ModRegistration.User)) { sources.Add(Platform.SupportDir); } var key = ExternalMod.MakeKey(mod); mods.Remove(key); foreach (var source in sources.Distinct()) { var path = Path.Combine(source, "ModMetadata", key + ".yaml"); try { if (File.Exists(path)) { File.Delete(path); } } catch (Exception e) { Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } } }
internal void Unregister(Manifest mod, ModRegistration registration) { var sources = new List<string>(); if (registration.HasFlag(ModRegistration.System)) sources.Add(Platform.GetSupportDir(SupportDirType.System)); if (registration.HasFlag(ModRegistration.User)) { // User support dir may be using the modern or legacy value, or overridden by the user // Add all the possibilities and let the .Distinct() below ignore the duplicates sources.Add(Platform.GetSupportDir(SupportDirType.User)); sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser)); sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser)); } var key = ExternalMod.MakeKey(mod); mods.Remove(key); foreach (var source in sources.Distinct()) { var path = Path.Combine(source, "ModMetadata", key + ".yaml"); try { if (File.Exists(path)) File.Delete(path); } catch (Exception e) { Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } } }
void IUtilityCommand.Run(Utility utility, string[] args) { ModRegistration type = 0; if (args[1] == "system" || args[1] == "both") type |= ModRegistration.System; if (args[1] == "user" || args[1] == "both") type |= ModRegistration.User; new ExternalMods().Unregister(utility.ModData.Manifest, type); }
/// <summary> /// Removes invalid mod registrations: /// * LaunchPath no longer exists /// * LaunchPath and mod id matches the active mod, but the version is different /// * Filename doesn't match internal key /// * Fails to parse as a mod registration /// </summary> internal void ClearInvalidRegistrations(ModRegistration registration) { foreach (var source in GetSupportDirs(registration)) { var metadataPath = Path.Combine(source, "ModMetadata"); if (!Directory.Exists(metadataPath)) { continue; } foreach (var path in Directory.GetFiles(metadataPath, "*.yaml")) { string modKey = null; try { var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value; var m = FieldLoader.Load <ExternalMod>(yaml); modKey = ExternalMod.MakeKey(m); // Continue to the next entry if this one is valid // HACK: Explicitly invalidate paths to OpenRA.dll to clean up bogus metadata files // that were created after the initial migration from .NET Framework to Core/5. if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey && Path.GetExtension(m.LaunchPath) != ".dll") { continue; } } catch (Exception e) { Log.Write("debug", "Failed to parse mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } // Remove from the ingame mod switcher if (Path.GetFileNameWithoutExtension(path) == modKey) { mods.Remove(modKey); } // Remove stale or corrupted metadata try { File.Delete(path); Log.Write("debug", "Removed invalid mod metadata file '{0}'", path); } catch (Exception e) { Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } } } }
void IUtilityCommand.Run(Utility utility, string[] args) { ModRegistration type = 0; if (args[2] == "system" || args[2] == "both") { type |= ModRegistration.System; } if (args[2] == "user" || args[2] == "both") { type |= ModRegistration.User; } new ExternalMods().Register(utility.ModData.Manifest, args[1], Enumerable.Empty <string>(), type); }
void IUtilityCommand.Run(Utility utility, string[] args) { ModRegistration type = 0; if (args[1] == "system" || args[1] == "both") { type |= ModRegistration.System; } if (args[1] == "user" || args[1] == "both") { type |= ModRegistration.User; } new ExternalMods().ClearInvalidRegistrations(type); }
IEnumerable <string> GetSupportDirs(ModRegistration registration) { var sources = new HashSet <string>(4); if (registration.HasFlag(ModRegistration.System)) { sources.Add(Platform.GetSupportDir(SupportDirType.System)); } if (registration.HasFlag(ModRegistration.User)) { // User support dir may be using the modern or legacy value, or overridden by the user // Add all the possibilities and let the HashSet ignore the duplicates sources.Add(Platform.GetSupportDir(SupportDirType.User)); sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser)); sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser)); } return(sources); }
void IUtilityCommand.Run(Utility utility, string[] args) { ModRegistration type = 0; if (args[1] == "system" || args[1] == "both") { type |= ModRegistration.System; } if (args[1] == "user" || args[1] == "both") { type |= ModRegistration.User; } var mods = new ExternalMods(); ExternalMod activeMod = null; mods.TryGetValue(ExternalMod.MakeKey(utility.ModData.Manifest), out activeMod); mods.ClearInvalidRegistrations(activeMod, type); }
internal void Unregister(Manifest mod, ModRegistration registration) { var key = ExternalMod.MakeKey(mod); mods.Remove(key); foreach (var source in GetSupportDirs(registration)) { var path = Path.Combine(source, "ModMetadata", key + ".yaml"); try { if (File.Exists(path)) { File.Delete(path); } } catch (Exception e) { Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } } }
/// <summary> /// Removes invalid mod registrations: /// * LaunchPath no longer exists /// * LaunchPath and mod id matches the active mod, but the version is different /// * Filename doesn't match internal key /// * Fails to parse as a mod registration /// </summary> internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration) { var sources = new List <string>(); if (registration.HasFlag(ModRegistration.System)) { sources.Add(Platform.GetSupportDir(SupportDirType.System)); } if (registration.HasFlag(ModRegistration.User)) { // User support dir may be using the modern or legacy value, or overridden by the user // Add all the possibilities and let the .Distinct() below ignore the duplicates sources.Add(Platform.GetSupportDir(SupportDirType.User)); sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser)); sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser)); } var activeModKey = ExternalMod.MakeKey(activeMod); foreach (var source in sources.Distinct()) { var metadataPath = Path.Combine(source, "ModMetadata"); if (!Directory.Exists(metadataPath)) { continue; } foreach (var path in Directory.GetFiles(metadataPath, "*.yaml")) { string modKey = null; try { var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value; var m = FieldLoader.Load <ExternalMod>(yaml); modKey = ExternalMod.MakeKey(m); // Continue to the next entry if it is the active mod (even if the LaunchPath is bogus) if (modKey == activeModKey) { continue; } // Continue to the next entry if this one is valid if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey && !(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version)) { continue; } } catch (Exception e) { Log.Write("debug", "Failed to parse mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } // Remove from the ingame mod switcher if (Path.GetFileNameWithoutExtension(path) == modKey) { mods.Remove(modKey); } // Remove stale or corrupted metadata try { File.Delete(path); Log.Write("debug", "Removed invalid mod metadata file '{0}'", path); } catch (Exception e) { Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } } } }
internal void Register(Manifest mod, string launchPath, IEnumerable <string> launchArgs, ModRegistration registration) { if (mod.Metadata.Hidden) { return; } var key = ExternalMod.MakeKey(mod); var yaml = new MiniYamlNode("Registration", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("Id", mod.Id), new MiniYamlNode("Version", mod.Metadata.Version), new MiniYamlNode("Title", mod.Metadata.Title), new MiniYamlNode("LaunchPath", launchPath), new MiniYamlNode("LaunchArgs", new[] { "Game.Mod=" + mod.Id }.Concat(launchArgs).JoinWith(", ")) })); using (var stream = mod.Package.GetStream("icon.png")) if (stream != null) { yaml.Value.Nodes.Add(new MiniYamlNode("Icon", Convert.ToBase64String(stream.ReadAllBytes()))); } using (var stream = mod.Package.GetStream("icon-2x.png")) if (stream != null) { yaml.Value.Nodes.Add(new MiniYamlNode("Icon2x", Convert.ToBase64String(stream.ReadAllBytes()))); } using (var stream = mod.Package.GetStream("icon-3x.png")) if (stream != null) { yaml.Value.Nodes.Add(new MiniYamlNode("Icon3x", Convert.ToBase64String(stream.ReadAllBytes()))); } var sources = new List <string>(); if (registration.HasFlag(ModRegistration.System)) { sources.Add(Platform.GetSupportDir(SupportDirType.System)); } if (registration.HasFlag(ModRegistration.User)) { sources.Add(Platform.GetSupportDir(SupportDirType.User)); // If using the modern support dir we must also write the registration // to the legacy support dir for older engine versions, but ONLY if it exists var legacyPath = Platform.GetSupportDir(SupportDirType.LegacyUser); if (Directory.Exists(legacyPath)) { sources.Add(legacyPath); } } // Make sure the mod is available for this session, even if saving it fails LoadMod(yaml.Value, forceRegistration: true); var lines = new List <MiniYamlNode> { yaml }.ToLines().ToArray(); foreach (var source in sources.Distinct()) { var metadataPath = Path.Combine(source, "ModMetadata"); try { Directory.CreateDirectory(metadataPath); File.WriteAllLines(Path.Combine(metadataPath, key + ".yaml"), lines); } catch (Exception e) { Log.Write("debug", "Failed to register current mod metadata"); Log.Write("debug", e.ToString()); } } }
/// <summary> /// Removes invalid mod registrations: /// * LaunchPath no longer exists /// * LaunchPath and mod id matches the active mod, but the version is different /// * Filename doesn't match internal key /// * Fails to parse as a mod registration /// </summary> internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration) { var sources = new List <string>(); if (registration.HasFlag(ModRegistration.System)) { sources.Add(Platform.SystemSupportDir); } if (registration.HasFlag(ModRegistration.User)) { sources.Add(Platform.SupportDir); } foreach (var source in sources.Distinct()) { var metadataPath = Path.Combine(source, "ModMetadata"); if (!Directory.Exists(metadataPath)) { continue; } foreach (var path in Directory.GetFiles(metadataPath, "*.yaml")) { string modKey = null; try { var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value; var m = FieldLoader.Load <ExternalMod>(yaml); modKey = ExternalMod.MakeKey(m); // Continue to the next entry if this one is valid if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey && !(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version)) { continue; } } catch (Exception e) { Log.Write("debug", "Failed to parse mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } // Remove from the ingame mod switcher if (Path.GetFileNameWithoutExtension(path) == modKey) { mods.Remove(modKey); } // Remove stale or corrupted metadata try { File.Delete(path); Log.Write("debug", "Removed invalid mod metadata file '{0}'", path); } catch (Exception e) { Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString()); } } } }