private List <LocalMod> FindReferencedMods(BuildProperties properties) { var mods = new Dictionary <string, LocalMod>(); FindReferencedMods(properties, mods, true); return(mods.Values.ToList()); }
private void FindReferencedMods(BuildProperties properties, Dictionary <string, LocalMod> mods, bool requireWeak) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) { continue; } bool isWeak = properties.weakReferences.Any(r => r.mod == refName); LocalMod mod; try { var modFile = new TmodFile(Path.Combine(ModLoader.ModPath, refName + ".tmod")); using (modFile.Open()) mod = new LocalMod(modFile); } catch (FileNotFoundException) when(isWeak && !requireWeak) { // don't recursively require weak deps, if the mod author needs to compile against them, they'll have them installed continue; } catch (Exception ex) { throw new BuildException(Language.GetTextValue("tModLoader.BuildErrorModReference", refName), ex); } mods[refName] = mod; FindReferencedMods(mod.properties, mods, false); } }
private void Upgrade() { Interface.loadMods.SubProgressText = $"Upgrading: {Path.GetFileName(path)}"; Logging.tML.InfoFormat("Upgrading: {0}", Path.GetFileName(path)); using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Decompress, true)) using (var reader = new BinaryReader(deflateStream)) { name = reader.ReadString(); version = new Version(reader.ReadString()); int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { AddFile(reader.ReadString(), reader.ReadBytes(reader.ReadInt32())); } } // update buildVersion var info = BuildProperties.ReadModFile(this); info.buildVersion = tModLoaderVersion; // TODO should be turn this into .info? Generally files starting with . are ignored, at least on Windows (and are much harder to accidentally delete or even manually create) AddFile("Info", info.ToBytes()); // make a backup fileStream.Seek(0, SeekOrigin.Begin); var backupFolder = Path.Combine(Path.GetDirectoryName(path), "UpgradeBackup"); Directory.CreateDirectory(backupFolder); using (var backupStream = File.OpenWrite(Path.Combine(backupFolder, Path.GetFileName(path)))) fileStream.CopyTo(backupStream); // close stream before upgrade Close(); // write to the new format (also updates the file offset table) Save(); // clear all the file contents from AddFile ResetCache(); // Save closes the file so re-open it Open(); // Read contract fulfilled }
private BuildingMod ReadBuildInfo(string modFolder) { if (modFolder.EndsWith("\\") || modFolder.EndsWith("/")) { modFolder = modFolder.Substring(0, modFolder.Length - 1); } var modName = Path.GetFileName(modFolder); status.SetStatus(Language.GetTextValue("tModLoader.ReadingProperties", modName)); BuildProperties properties; try { properties = BuildProperties.ReadBuildFile(modFolder); } catch (Exception e) { throw new BuildException(Language.GetTextValue("tModLoader.BuildErrorFailedLoadBuildTxt", Path.Combine(modFolder, "build.txt")), e); } var file = Path.Combine(ModLoader.ModPath, modName + ".tmod"); var modFile = new TmodFile(file, modName, properties.version); return(new BuildingMod(modFile, properties, modFolder)); }
public BuildingMod(TmodFile modFile, BuildProperties properties, string path) : base(modFile, properties) { this.path = path; }
internal static void InfoToBuildTxt(Stream src, Stream dst) { BuildProperties properties = ReadFromStream(src); var sb = new StringBuilder(); if (properties.displayName.Length > 0) { sb.AppendLine($"displayName = {properties.displayName}"); } if (properties.author.Length > 0) { sb.AppendLine($"author = {properties.author}"); } sb.AppendLine($"version = {properties.version}"); if (properties.homepage.Length > 0) { sb.AppendLine($"homepage = {properties.homepage}"); } if (properties.dllReferences.Length > 0) { sb.AppendLine($"dllReferences = {string.Join(", ", properties.dllReferences)}"); } if (properties.modReferences.Length > 0) { sb.AppendLine($"modReferences = {string.Join(", ", properties.modReferences)}"); } if (properties.weakReferences.Length > 0) { sb.AppendLine($"weakReferences = {string.Join(", ", properties.weakReferences)}"); } if (properties.noCompile) { sb.AppendLine($"noCompile = true"); } if (properties.hideCode) { sb.AppendLine($"hideCode = true"); } if (properties.hideResources) { sb.AppendLine($"hideResources = true"); } if (properties.includeSource) { sb.AppendLine($"includeSource = true"); } if (properties.includePDB) { sb.AppendLine($"includePDB = true"); } // buildIgnores isn't preserved in Info, but it doesn't matter with extraction since the ignored files won't be present anyway. // if (properties.buildIgnores.Length > 0) // sb.AppendLine($"buildIgnores = {string.Join(", ", properties.buildIgnores)}"); if (properties.side != ModSide.Both) { sb.AppendLine($"side = {properties.side}"); } if (properties.sortAfter.Length > 0) { sb.AppendLine($"sortAfter = {string.Join(", ", properties.sortAfter)}"); } if (properties.sortBefore.Length > 0) { sb.AppendLine($"sortBefore = {string.Join(", ", properties.sortBefore)}"); } var bytes = Encoding.UTF8.GetBytes(sb.ToString()); dst.Write(bytes, 0, bytes.Length); }
internal static BuildProperties ReadFromStream(Stream stream) { BuildProperties properties = new BuildProperties(); using (var reader = new BinaryReader(stream)) { for (string tag = reader.ReadString(); tag.Length > 0; tag = reader.ReadString()) { if (tag == "dllReferences") { properties.dllReferences = ReadList(reader).ToArray(); } if (tag == "modReferences") { properties.modReferences = ReadList(reader).Select(ModReference.Parse).ToArray(); } if (tag == "weakReferences") { properties.weakReferences = ReadList(reader).Select(ModReference.Parse).ToArray(); } if (tag == "sortAfter") { properties.sortAfter = ReadList(reader).ToArray(); } if (tag == "sortBefore") { properties.sortBefore = ReadList(reader).ToArray(); } if (tag == "author") { properties.author = reader.ReadString(); } if (tag == "version") { properties.version = new Version(reader.ReadString()); } if (tag == "displayName") { properties.displayName = reader.ReadString(); } if (tag == "homepage") { properties.homepage = reader.ReadString(); } if (tag == "description") { properties.description = reader.ReadString(); } if (tag == "noCompile") { properties.noCompile = true; } if (tag == "!hideCode") { properties.hideCode = false; } if (tag == "!hideResources") { properties.hideResources = false; } if (tag == "includeSource") { properties.includeSource = true; } if (tag == "includePDB") { properties.includePDB = true; } if (tag == "eacPath") { properties.eacPath = reader.ReadString(); } if (tag == "side") { properties.side = (ModSide)reader.ReadByte(); } if (tag == "beta") { properties.beta = true; } if (tag == "buildVersion") { properties.buildVersion = new Version(reader.ReadString()); } } } return(properties); }
internal static BuildProperties ReadBuildFile(string modDir) { string propertiesFile = modDir + Path.DirectorySeparatorChar + "build.txt"; string descriptionfile = modDir + Path.DirectorySeparatorChar + "description.txt"; BuildProperties properties = new BuildProperties(); if (!File.Exists(propertiesFile)) { return(properties); } if (File.Exists(descriptionfile)) { properties.description = File.ReadAllText(descriptionfile); } foreach (string line in File.ReadAllLines(propertiesFile)) { if (string.IsNullOrWhiteSpace(line)) { continue; } int split = line.IndexOf('='); string property = line.Substring(0, split).Trim(); string value = line.Substring(split + 1).Trim(); if (value.Length == 0) { continue; } switch (property) { case "dllReferences": properties.dllReferences = ReadList(value).ToArray(); break; case "modReferences": properties.modReferences = ReadList(value).Select(ModReference.Parse).ToArray(); break; case "weakReferences": properties.weakReferences = ReadList(value).Select(ModReference.Parse).ToArray(); break; case "sortBefore": properties.sortBefore = ReadList(value).ToArray(); break; case "sortAfter": properties.sortAfter = ReadList(value).ToArray(); break; case "author": properties.author = value; break; case "version": properties.version = new Version(value); break; case "displayName": properties.displayName = value; break; case "homepage": properties.homepage = value; break; case "noCompile": properties.noCompile = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); break; case "hideCode": properties.hideCode = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); break; case "hideResources": properties.hideResources = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); break; case "includeSource": properties.includeSource = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); break; case "includePDB": properties.includePDB = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); break; case "buildIgnore": properties.buildIgnores = value.Split(',').Select(s => s.Trim().Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar)).Where(s => s.Length > 0).ToArray(); break; case "side": if (!Enum.TryParse(value, true, out properties.side)) { throw new Exception("side is not one of (Both, Client, Server, NoSync): " + value); } break; } } var refs = properties.RefNames(true).ToList(); if (refs.Count != refs.Distinct().Count()) { throw new Exception("Duplicate mod/weak reference"); } //add (mod|weak)References that are not in sortBefore to sortAfter properties.sortAfter = properties.RefNames(true).Where(dep => !properties.sortBefore.Contains(dep)) .Concat(properties.sortAfter).Distinct().ToArray(); return(properties); }