public _7thWrapperLib.RuntimeMod GetRuntime(_7thWrapperLib.LoaderContext context) { var mod = Sys.Library.GetItem(ModID); if (mod == null) { return(null); } string location = System.IO.Path.Combine(Sys.Settings.LibraryLocation, mod.LatestInstalled.InstalledLocation); _7thWrapperLib.ModInfo modinfo = null; if (mod.LatestInstalled.InstalledLocation.EndsWith(".iro")) { using (var arc = new _7thWrapperLib.IrosArc(location)) { if (arc.HasFile("mod.xml")) { var doc = new System.Xml.XmlDocument(); doc.Load(arc.GetData("mod.xml")); modinfo = new _7thWrapperLib.ModInfo(doc, context); } } } else { string mfile = System.IO.Path.Combine(location, "mod.xml"); if (System.IO.File.Exists(mfile)) { modinfo = new _7thWrapperLib.ModInfo(mfile, context); } } modinfo = modinfo ?? new _7thWrapperLib.ModInfo(); foreach (var opt in modinfo.Options) { if (!Settings.Any(s => s.ID.Equals(opt.ID, StringComparison.InvariantCultureIgnoreCase))) { Settings.Add(new ProfileSetting() { ID = opt.ID, Value = opt.Default }); } } return(new _7thWrapperLib.RuntimeMod( location, modinfo.Conditionals.Where(f => IsActive(f.ActiveWhen)), modinfo.ModFolders.Where(f => IsActive(f.ActiveWhen)).Select(f => f.Folder), modinfo.LoadLibraries, modinfo.LoadAssemblies, modinfo.LoadPlugins )); }
public static void ImportMod(string source, string name, bool iroMode, bool noCopy) { Mod m = new Mod() { Author = String.Empty, Description = "Imported mod", ID = Guid.NewGuid(), Link = String.Empty, Tags = new List <string>(), Name = name, LatestVersion = new ModVersion() { CompatibleGameVersions = GameVersions.All, Links = new List <string>(), PreviewImage = String.Empty, ReleaseDate = DateTime.Now, ReleaseNotes = String.Empty, Version = 1.00m, } }; string location; if (noCopy) { location = System.IO.Path.GetFileName(source); } else { location = String.Format("{0}_{1}", m.ID, name); } System.Xml.XmlDocument doc = null; Func <string, byte[]> getData = null; if (!iroMode) { if (!noCopy) { foreach (string file in System.IO.Directory.GetFiles(source, "*", System.IO.SearchOption.AllDirectories)) { string part = file.Substring(source.Length).Trim('\\', '/'); string dest = System.IO.Path.Combine(Sys.Settings.LibraryLocation, location, part); System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(dest)); System.IO.File.Copy(file, dest, true); } } string mx = System.IO.Path.Combine(Sys.Settings.LibraryLocation, location, "mod.xml"); if (System.IO.File.Exists(mx)) { doc = new System.Xml.XmlDocument(); doc.Load(mx); } getData = s => { string file = System.IO.Path.Combine(Sys.Settings.LibraryLocation, location, s); if (System.IO.File.Exists(file)) { return(System.IO.File.ReadAllBytes(file)); } return(null); }; //System.IO.Directory.Move(txtFolder.Text, System.IO.Path.Combine(Sys.Settings.LibraryLocation, location)); } else { if (!noCopy) { location = location + ".iro"; System.IO.File.Copy(source, System.IO.Path.Combine(Sys.Settings.LibraryLocation, location), true); } var arc = new _7thWrapperLib.IrosArc(source); if (arc.HasFile("mod.xml")) { doc = new System.Xml.XmlDocument(); doc.Load(arc.GetData("mod.xml")); } getData = s => arc.HasFile(s) ? arc.GetBytes(s) : null; } if (doc != null) { m.Author = doc.SelectSingleNode("/ModInfo/Author").NodeTextS(); m.Link = doc.SelectSingleNode("/ModInfo/Link").NodeTextS(); m.Description = doc.SelectSingleNode("/ModInfo/Description").NodeTextS(); decimal ver; if (decimal.TryParse(doc.SelectSingleNode("/ModInfo/Version").NodeTextS().Replace(',', '.'), out ver)) { m.LatestVersion.Version = ver; } var pv = doc.SelectSingleNode("/ModInfo/PreviewFile"); if (pv != null) { byte[] data = getData(pv.InnerText); if (data != null) { string url = "iros://Preview/Auto/" + m.ID.ToString(); m.LatestVersion.PreviewImage = url; Sys.ImageCache.InsertManual(url, data); } } } Sys.Library.AddInstall(new InstalledItem() { CachedDetails = m, CachePreview = String.Empty, ModID = m.ID, UpdateType = UpdateType.Ignore, Versions = new List <InstalledVersion>() { new InstalledVersion() { VersionDetails = m.LatestVersion, InstalledLocation = location } }, }); }
/// <summary> /// Parses mod.xml from a folder or .iro and returns the <see cref="Mod"/> /// </summary> /// <param name="sourceFileOrFolder">absolute path to folder or .iro file </param> /// <param name="defaultModIfMissing"> default mod properties to use if the mod.xml file is not found </param> /// <returns></returns> public Mod ParseModXmlFromSource(string sourceFileOrFolder, Mod defaultModIfMissing = null) { if (defaultModIfMissing == null) { defaultModIfMissing = new Mod() { Author = String.Empty, Description = "Imported mod", Category = "Unknown", ID = ParseModGuidFromFileOrFolderName(sourceFileOrFolder), Link = String.Empty, Tags = new List <string>(), Name = "", LatestVersion = new ModVersion() { CompatibleGameVersions = GameVersions.All, Links = new List <string>(), PreviewImage = String.Empty, ReleaseDate = DateTime.Now, ReleaseNotes = String.Empty, Version = 1.00m, } }; } Mod parsedMod = Mod.CopyMod(defaultModIfMissing); if (string.IsNullOrWhiteSpace(sourceFileOrFolder)) { return(parsedMod); } if (!File.Exists(sourceFileOrFolder) && !Directory.Exists(sourceFileOrFolder)) { return(parsedMod); } bool isIroFile = sourceFileOrFolder.EndsWith(".iro"); System.Xml.XmlDocument doc = null; Func <string, byte[]> getImageData = null; _7thWrapperLib.IrosArc arc = null; string[] musicFiles = FF7FileLister.GetMusicFiles(); string[] movieFiles = FF7FileLister.GetMovieFiles().Keys.ToArray(); if (isIroFile) { RaiseProgressChanged("Getting mod.xml data from .iro", 10); arc = new _7thWrapperLib.IrosArc(sourceFileOrFolder, patchable: false, (i, fileCount) => { double newProgress = 10.0 + ((double)i / fileCount) * 30.0; RaiseProgressChanged($"Scanning .iro archive files {i} / {fileCount}", newProgress); }); if (arc.HasFile("mod.xml")) { doc = new System.Xml.XmlDocument(); doc.Load(arc.GetData("mod.xml")); } RaiseProgressChanged($"Scanning .iro archive files for movie and music files", 45); foreach (string file in arc.AllFileNames()) { if (musicFiles.Any(f => f.Equals(Path.GetFileName(file), StringComparison.InvariantCultureIgnoreCase))) { parsedMod.ContainsMusic = true; } if (movieFiles.Any(f => f.Equals(Path.GetFileName(file), StringComparison.InvariantCultureIgnoreCase))) { parsedMod.ContainsMovies = true; } if (parsedMod.ContainsMovies && parsedMod.ContainsMusic) { break; // break out of loop to stop scanning since confirmed both music and movie files exist in mod } } getImageData = s => { return(arc.HasFile(s) ? arc.GetBytes(s) : null); }; } else { string pathToModXml = Path.Combine(sourceFileOrFolder, "mod.xml"); RaiseProgressChanged("Getting mod.xml data from file", 10); if (File.Exists(pathToModXml)) { doc = new System.Xml.XmlDocument(); doc.Load(pathToModXml); } RaiseProgressChanged($"Scanning mod folder for movie and music files", 25); foreach (string file in FileUtils.GetAllFilesInDirectory(sourceFileOrFolder)) { if (musicFiles.Any(f => f.Equals(Path.GetFileName(file), StringComparison.InvariantCultureIgnoreCase))) { parsedMod.ContainsMusic = true; } if (movieFiles.Any(f => f.Equals(Path.GetFileName(file), StringComparison.InvariantCultureIgnoreCase))) { parsedMod.ContainsMovies = true; } if (parsedMod.ContainsMovies && parsedMod.ContainsMusic) { break; // break out of loop to stop scanning since confirmed both music and movie files exist in mod } } getImageData = s => { string file = Path.Combine(sourceFileOrFolder, s); if (File.Exists(file)) { return(File.ReadAllBytes(file)); } return(null); }; } if (doc != null) { RaiseProgressChanged("Parsing information from mod.xml", 50); //If mod.xml contains an ID GUID, then use that instead of generating random one string modidstr = doc.SelectSingleNode("/ModInfo/ID").NodeTextS(); if (!string.IsNullOrWhiteSpace(modidstr)) { try { parsedMod.ID = new Guid(modidstr); } catch (Exception e) { Sys.Message(new WMessage("Invalid GUID found for Mod ID ... Using guid from file/folder name (or new guid).", WMessageLogLevel.LogOnly, e)); parsedMod.ID = ParseModGuidFromFileOrFolderName(sourceFileOrFolder); } } parsedMod.Name = doc.SelectSingleNode("/ModInfo/Name").NodeTextS(); if (string.IsNullOrWhiteSpace(parsedMod.Name)) { parsedMod.Name = defaultModIfMissing.Name; } parsedMod.Author = doc.SelectSingleNode("/ModInfo/Author").NodeTextS(); if (string.IsNullOrWhiteSpace(parsedMod.Author)) { parsedMod.Author = defaultModIfMissing.Author; } parsedMod.Link = doc.SelectSingleNode("/ModInfo/Link").NodeTextS(); if (string.IsNullOrWhiteSpace(parsedMod.Link)) { parsedMod.Link = defaultModIfMissing.Link; } parsedMod.Description = doc.SelectSingleNode("/ModInfo/Description").NodeTextS(); if (string.IsNullOrWhiteSpace(parsedMod.Description)) { parsedMod.Description = defaultModIfMissing.Description; } parsedMod.Category = doc.SelectSingleNode("/ModInfo/Category").NodeTextS(); if (string.IsNullOrWhiteSpace(parsedMod.Category)) { parsedMod.Category = defaultModIfMissing.Category; } parsedMod.LatestVersion.ReleaseNotes = doc.SelectSingleNode("/ModInfo/ReleaseNotes").NodeTextS(); if (string.IsNullOrWhiteSpace(parsedMod.LatestVersion.ReleaseNotes)) { parsedMod.LatestVersion.ReleaseNotes = defaultModIfMissing.LatestVersion.ReleaseNotes; } if (DateTime.TryParse(doc.SelectSingleNode("/ModInfo/ReleaseDate").NodeTextS(), out DateTime parsedDate)) { parsedMod.LatestVersion.ReleaseDate = parsedDate; } else { parsedMod.LatestVersion.ReleaseDate = defaultModIfMissing.LatestVersion.ReleaseDate; } string versionText = doc.SelectSingleNode("/ModInfo/Version").NodeTextS().Replace(',', '.'); // in-case Xml has "1,7" format then replace with "1.7" if (decimal.TryParse(versionText, System.Globalization.NumberStyles.AllowDecimalPoint, new System.Globalization.CultureInfo(""), out decimal ver)) { parsedMod.LatestVersion.Version = ver; } else { parsedMod.LatestVersion.Version = defaultModIfMissing.LatestVersion.Version; } var pv = doc.SelectSingleNode("/ModInfo/PreviewFile"); if (pv != null) { // add the preview file to image cache and set the url prefixed with iros://Preview/Auto since it came from auto-import byte[] data = getImageData(pv.InnerText); if (data != null) { string url = $"iros://Preview/Auto/{parsedMod.ID}_{pv.InnerText.Replace('\\', '_')}"; parsedMod.LatestVersion.PreviewImage = url; Sys.ImageCache.InsertManual(url, data); } } } if (arc != null) { arc.Dispose(); } return(parsedMod); }