private static bool FindReferencedMods(BuildProperties properties, Dictionary <string, LocalMod> mods) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) { continue; } var modFile = new TmodFile(Path.Combine(ModPath, refName + ".tmod")); try { modFile.Read(TmodFile.LoadedState.Code); } catch (Exception ex) { ErrorLogger.LogBuildError("Mod reference " + refName + " " + ex); return(false); } var mod = new LocalMod(modFile); mods[refName] = mod; FindReferencedMods(mod.properties, mods); } return(true); }
private static bool CompileMod(string modDir, BuildProperties properties) { CompilerParameters compileOptions = new CompilerParameters(); compileOptions.GenerateExecutable = false; compileOptions.GenerateInMemory = false; compileOptions.OutputAssembly = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modDir) + ".tmod"; foreach (string reference in buildReferences) { compileOptions.ReferencedAssemblies.Add(reference); } Directory.CreateDirectory(DllPath); foreach (string reference in properties.dllReferences) { compileOptions.ReferencedAssemblies.Add(DllPath + Path.DirectorySeparatorChar + reference + ".dll"); } foreach (string reference in properties.modReferences) { compileOptions.ReferencedAssemblies.Add(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } CodeDomProvider codeProvider = new CSharpCodeProvider(); CompilerResults results = codeProvider.CompileAssemblyFromFile(compileOptions, Directory.GetFiles(modDir, "*.cs", SearchOption.AllDirectories)); CompilerErrorCollection errors = results.Errors; foreach (string reference in properties.modReferences) { File.Delete(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } if (errors.HasErrors) { ErrorLogger.LogCompileErrors(errors); return(false); } return(true); }
private static BuildingMod ReadProperties(string modFolder, IBuildStatus status) { if (modFolder.EndsWith("\\") || modFolder.EndsWith("/")) { modFolder = modFolder.Substring(0, modFolder.Length - 1); } var modName = Path.GetFileName(modFolder); status.SetStatus(Language.GetTextValue("tModLoader.MSReadingProperties") + modName); BuildProperties properties; try { properties = BuildProperties.ReadBuildFile(modFolder); } catch (Exception e) { ErrorLogger.LogBuildError("Failed to load " + Path.Combine(modFolder, "build.txt") + Environment.NewLine + e); return(null); } var file = Path.Combine(ModPath, modName + ".tmod"); var modFile = new TmodFile(file) { name = modName, version = properties.version }; return(new BuildingMod(modFile, properties, modFolder)); }
private BuildingMod ReadProperties(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) { status.LogError(Language.GetTextValue("tModLoader.BuildErrorFailedLoadBuildTxt", Path.Combine(modFolder, "build.txt")), e); return(null); } var file = Path.Combine(ModPath, modName + ".tmod"); var modFile = new TmodFile(file) { name = modName, version = properties.version }; return(new BuildingMod(modFile, properties, modFolder)); }
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) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) { continue; } LocalMod mod; try { var modFile = new TmodFile(Path.Combine(ModPath, refName + ".tmod")); modFile.Read(); mod = new LocalMod(modFile); modFile.Close(); } catch (Exception ex) { throw new Exception(Language.GetTextValue("tModLoader.BuildErrorModReference", refName), ex); } mods[refName] = mod; FindReferencedMods(mod.properties, mods); } }
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(ModPath, refName + ".tmod")); modFile.Read(); mod = new LocalMod(modFile); modFile.Close(); } 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 Exception(Language.GetTextValue("tModLoader.BuildErrorModReference", refName), ex); } mods[refName] = mod; FindReferencedMods(mod.properties, mods, false); } }
internal static BuildProperties LoadBuildProperties(string modFile) { BuildProperties properties = new BuildProperties(); byte[] data; using (FileStream fileStream = File.OpenRead(modFile)) { using (BinaryReader reader = new BinaryReader(fileStream)) { data = reader.ReadBytes(reader.ReadInt32()); } } if (data.Length == 0) { return(properties); } using (MemoryStream memoryStream = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(memoryStream)) { for (string tag = reader.ReadString(); tag.Length > 0; tag = reader.ReadString()) { if (tag == "dllReferences") { List <string> dllReferences = new List <string>(); for (string reference = reader.ReadString(); reference.Length > 0; reference = reader.ReadString()) { dllReferences.Add(reference); } properties.dllReferences = dllReferences.ToArray(); } if (tag == "modReferences") { List <string> modReferences = new List <string>(); for (string reference = reader.ReadString(); reference.Length > 0; reference = reader.ReadString()) { modReferences.Add(reference); } properties.modReferences = modReferences.ToArray(); } if (tag == "author") { properties.author = reader.ReadString(); } if (tag == "version") { properties.version = reader.ReadString(); } if (tag == "displayName") { properties.displayName = reader.ReadString(); } } } } return(properties); }
public void SetMod(ModLoader.LoadingMod mod) { if (modFile == null || modFile.version != mod.modFile.version || !modFile.hash.SequenceEqual(mod.modFile.hash)) SetNeedsReload(); modFile = mod.modFile; properties = mod.properties; }
public void SetMod(LocalMod mod) { if (modFile == null || modFile.version != mod.modFile.version || !modFile.hash.SequenceEqual(mod.modFile.hash)) { SetNeedsReload(); } modFile = mod.modFile; properties = mod.properties; }
private static bool LoadMods() { //load all referenced assemblies before mods for compiling ModCompile.LoadReferences(); Interface.loadMods.SetProgressFinding(); var modsToLoad = FindMods() .Where(IsEnabled) .Select(mod => new LoadingMod(mod, BuildProperties.ReadModFile(mod))) .Where(mod => LoadSide(mod.properties.side)) .ToList(); if (!VerifyNames(modsToLoad)) { return(false); } try { EnsureDependenciesExist(modsToLoad, false); EnsureTargetVersionsMet(modsToLoad); modsToLoad = Sort(modsToLoad); } catch (ModSortingException e) { foreach (var mod in e.errored) { DisableMod(mod.modFile); } ErrorLogger.LogDependencyError(e.Message); return(false); } var modInstances = AssemblyManager.InstantiateMods(modsToLoad); if (modInstances == null) { return(false); } modInstances.Insert(0, new ModLoaderMod()); loadedMods = modInstances.ToArray(); foreach (var mod in modInstances) { loadOrder.Push(mod.Name); mods[mod.Name] = mod; } return(true); }
internal static bool BuildAll(string[] modFolders, IBuildStatus status) { var modList = new List <LoadingMod>(); foreach (var modFolder in modFolders) { var mod = ReadProperties(modFolder, status); if (mod == null) { return(false); } modList.Add(mod); } foreach (var modFile in FindMods()) { if (modList.Exists(m => m.Name == modFile.name)) { continue; } modList.Add(new LoadingMod(modFile, BuildProperties.ReadModFile(modFile))); } List <BuildingMod> modsToBuild; try { EnsureDependenciesExist(modList, true); EnsureTargetVersionsMet(modList); var sortedModList = Sort(modList); modsToBuild = sortedModList.OfType <BuildingMod>().ToList(); } catch (ModSortingException e) { ErrorLogger.LogDependencyError(e.Message); return(false); } int num = 0; foreach (var mod in modsToBuild) { status.SetProgress(num++, modsToBuild.Count); if (!Build(mod, status)) { return(false); } } return(true); }
private static byte[] PropertiesToBytes(BuildProperties properties) { byte[] data; using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memoryStream)) { if (properties.dllReferences.Length > 0) { writer.Write("dllReferences"); foreach (string reference in properties.dllReferences) { writer.Write(reference); } writer.Write(""); } if (properties.modReferences.Length > 0) { writer.Write("modReferences"); foreach (string reference in properties.modReferences) { writer.Write(reference); } writer.Write(""); } if (properties.author.Length > 0) { writer.Write("author"); writer.Write(properties.author); } if (properties.version.Length > 0) { writer.Write("version"); writer.Write(properties.version); } if (properties.displayName.Length > 0) { writer.Write("displayName"); writer.Write(properties.displayName); } writer.Write(""); writer.Flush(); data = memoryStream.ToArray(); } } return(data); }
private static void LoadMod(string modFile, BuildProperties properties) { AddAssemblyResolver(); Assembly modCode; using (FileStream fileStream = File.OpenRead(modFile)) { using (BinaryReader reader = new BinaryReader(fileStream)) { fileStream.Seek(reader.ReadInt32(), SeekOrigin.Current); modCode = Assembly.Load(reader.ReadBytes(reader.ReadInt32())); for (string texturePath = reader.ReadString(); texturePath != "endImages"; texturePath = reader.ReadString()) { byte[] imageData = reader.ReadBytes(reader.ReadInt32()); using (MemoryStream buffer = new MemoryStream(imageData)) { textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer); } } for (string soundPath = reader.ReadString(); soundPath != "endSounds"; soundPath = reader.ReadString()) { byte[] soundData = reader.ReadBytes(reader.ReadInt32()); // ErrorLogger.Log("sound data: "+ soundPath +" "+imageData.Length); using (MemoryStream buffer = new MemoryStream(soundData)) { sounds[soundPath] = SoundEffect.FromStream(buffer); } } } } Type[] classes = modCode.GetTypes(); foreach (Type type in classes) { if (type.IsSubclassOf(typeof(Mod))) { Mod mod = (Mod)Activator.CreateInstance(type); mod.file = modFile; mod.code = modCode; mod.Init(); if (mods.ContainsKey(mod.Name)) { throw new Exception("Two mods share the internal name " + mod.Name); } mods[mod.Name] = mod; } } }
internal static bool CreateModReferenceDlls(BuildProperties properties) { TmodFile[] refFiles = new TmodFile[properties.modReferences.Length]; for (int k = 0; k < properties.modReferences.Length; k++) { string modReference = properties.modReferences[k]; string filePath = ModLoader.ModPath + Path.DirectorySeparatorChar + modReference + ".tmod"; TmodFile refFile = new TmodFile(filePath); refFile = new TmodFile(filePath); refFile.Read(); if (!refFile.ValidMod()) { ErrorLogger.LogModReferenceError(refFile.Name); return(false); } refFiles[k] = refFile; } for (int k = 0; k < refFiles.Length; k++) { TmodFile refFile = refFiles[k]; string modReference = properties.modReferences[k]; byte[] data1; byte[] data2; if (refFile.HasFile("All")) { data1 = refFile.GetFile("All"); data2 = refFile.GetFile("All"); } else { data1 = refFile.GetFile("Windows"); data2 = refFile.GetFile("Other"); } string refFileName = ModLoader.ModSourcePath + Path.DirectorySeparatorChar + modReference; File.WriteAllBytes(refFileName + "1.dll", data1); File.WriteAllBytes(refFileName + "2.dll", data2); } return(true); }
private static bool FindReferencedMods(BuildProperties properties, Dictionary <string, LoadingMod> mods) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) { continue; } var modFile = new TmodFile(Path.Combine(ModPath, refName + ".tmod")); modFile.Read(); var ex = modFile.ValidMod(); if (ex != null) { ErrorLogger.LogBuildError("Mod reference " + refName + " " + ex); return(false); } var mod = new LoadingMod(modFile, BuildProperties.ReadModFile(modFile)); mods[refName] = mod; FindReferencedMods(mod.properties, mods); } return(true); }
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); }
private static bool FindReferencedMods(BuildProperties properties, Dictionary<string, LoadingMod> mods) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) continue; var modFile = new TmodFile(Path.Combine(ModPath, refName + ".tmod")); modFile.Read(); var ex = modFile.ValidMod(); if (ex != null) { ErrorLogger.LogBuildError("Mod reference " + refName + " " + ex); return false; } var mod = new LoadingMod(modFile, BuildProperties.ReadModFile(modFile)); mods[refName] = mod; FindReferencedMods(mod.properties, mods); } return true; }
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); }
public LoadingMod(TmodFile modFile, BuildProperties properties) { this.modFile = modFile; this.properties = properties; }
private static bool LoadMods() { Interface.loadMods.SetProgressFinding(); TmodFile[] modFiles = FindMods(); List <TmodFile> enabledMods = new List <TmodFile>(); foreach (TmodFile modFile in modFiles) { if (IsEnabled(modFile.Name)) { enabledMods.Add(modFile); } } IDictionary <string, BuildProperties> properties = new Dictionary <string, BuildProperties>(); List <TmodFile> modsToLoad = new List <TmodFile>(); foreach (TmodFile modFile in enabledMods) { properties[modFile.Name] = BuildProperties.ReadModFile(modFile); modsToLoad.Add(modFile); } int previousCount = 0; int num = 0; Mod defaultMod = new ModLoaderMod(); defaultMod.Init(); mods[defaultMod.Name] = defaultMod; loadedMods.Add(defaultMod.Name); while (modsToLoad.Count > 0 && modsToLoad.Count != previousCount) { previousCount = modsToLoad.Count; int k = 0; while (k < modsToLoad.Count) { bool canLoad = true; foreach (string reference in properties[modsToLoad[k].Name].modReferences) { if (!ModLoaded(ModPath + Path.DirectorySeparatorChar + reference + ".tmod")) { canLoad = false; break; } } if (canLoad) { Interface.loadMods.SetProgressCompatibility(Path.GetFileNameWithoutExtension(modsToLoad[k].Name), num, enabledMods.Count); try { LoadMod(modsToLoad[k], properties[modsToLoad[k].Name]); } catch (Exception e) { DisableMod(modsToLoad[k].Name); ErrorLogger.LogLoadingError(modsToLoad[k].Name, e); return(false); } loadedMods.Add(modsToLoad[k].Name); num++; modsToLoad.RemoveAt(k); } else { k++; } } } if (modsToLoad.Count > 0) { foreach (TmodFile modFile in modsToLoad) { DisableMod(modFile.Name); } ErrorLogger.LogMissingLoadReference(modsToLoad); return(false); } return(true); }
private static void LoadMod(TmodFile modFile, BuildProperties properties) { AddAssemblyResolver(); Interface.loadMods.SetProgressReading(Path.GetFileNameWithoutExtension(modFile.Name)); Assembly modCode; string rootDirectory; if (modFile.HasFile("All")) { modCode = Assembly.Load(modFile.GetFile("All")); } else { modCode = Assembly.Load(modFile.GetFile(windows ? "Windows" : "Other")); } using (MemoryStream memoryStream = new MemoryStream(modFile.GetFile("Resources"))) { using (BinaryReader reader = new BinaryReader(memoryStream)) { memoryStream.Seek(reader.ReadInt32(), SeekOrigin.Current); rootDirectory = reader.ReadString(); for (string path = reader.ReadString(); path != "end"; path = reader.ReadString()) { byte[] data = reader.ReadBytes(reader.ReadInt32()); files[path] = data; string extension = Path.GetExtension(path); switch (extension) { case ".png": string texturePath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer); } break; case ".wav": string soundPath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { sounds[soundPath] = SoundEffect.FromStream(buffer); } break; case ".mp3": // TODO, better way to do this? string mp3Path = Path.ChangeExtension(path, null); MemoryStream wavData = new MemoryStream(); MemoryStream wavFile = new MemoryStream(); ushort wFormatTag = 1; ushort nChannels; uint nSamplesPerSec; uint nAvgBytesPerSec; ushort nBlockAlign; ushort wBitsPerSample = 16; using (MemoryStream buffer = new MemoryStream(data)) { using (MP3Sharp.MP3Stream s = new MP3Sharp.MP3Stream(buffer)) { s.CopyTo(wavData); nChannels = (ushort)s.ChannelCount; nSamplesPerSec = (uint)s.Frequency; } } nBlockAlign = (ushort)(nChannels * (wBitsPerSample / 8)); nAvgBytesPerSec = (uint)(nSamplesPerSec * nChannels * (wBitsPerSample / 8)); using (BinaryWriter bw = new BinaryWriter(wavFile)) { bw.Write("RIFF".ToCharArray()); bw.Write((UInt32)(wavData.Length + 36)); bw.Write("WAVE".ToCharArray()); bw.Write("fmt ".ToCharArray()); bw.Write(16); bw.Write(wFormatTag); bw.Write(nChannels); bw.Write(nSamplesPerSec); bw.Write(nAvgBytesPerSec); bw.Write(nBlockAlign); bw.Write(wBitsPerSample); bw.Write("data".ToCharArray()); bw.Write((UInt32)(wavData.Length)); bw.Write(wavData.ToArray()); } using (MemoryStream buffer = new MemoryStream(wavFile.ToArray())) { sounds[mp3Path] = SoundEffect.FromStream(buffer); } break; } } } } Type[] classes = modCode.GetTypes(); foreach (Type type in classes) { if (type.IsSubclassOf(typeof(Mod))) { Mod mod = (Mod)Activator.CreateInstance(type); mod.file = modFile.Name; mod.code = modCode; mod.Init(); if (mods.ContainsKey(mod.Name)) { throw new DuplicateNameException("Two mods share the internal name " + mod.Name); } if (rootDirectory != mod.Name) { throw new MissingResourceException("Mod name " + mod.Name + " does not match source directory name " + rootDirectory); } mods[mod.Name] = mod; } } }
internal static bool CreateModReferenceDlls(BuildProperties properties) { TmodFile[] refFiles = new TmodFile[properties.modReferences.Length]; for (int k = 0; k < properties.modReferences.Length; k++) { string modReference = properties.modReferences[k]; string filePath = ModLoader.ModPath + Path.DirectorySeparatorChar + modReference + ".tmod"; TmodFile refFile = new TmodFile(filePath); refFile = new TmodFile(filePath); refFile.Read(); if (!refFile.ValidMod()) { ErrorLogger.LogModReferenceError(refFile.Name); return false; } refFiles[k] = refFile; } for (int k = 0; k < refFiles.Length; k++) { TmodFile refFile = refFiles[k]; string modReference = properties.modReferences[k]; byte[] data1; byte[] data2; if (refFile.HasFile("All")) { data1 = refFile.GetFile("All"); data2 = refFile.GetFile("All"); } else { data1 = refFile.GetFile("Windows"); data2 = refFile.GetFile("Other"); } string refFileName = ModLoader.ModSourcePath + Path.DirectorySeparatorChar + modReference; File.WriteAllBytes(refFileName + "1.dll", data1); File.WriteAllBytes(refFileName + "2.dll", data2); } return true; }
internal static void ServerModMenu() { bool exit = false; while (!exit) { Console.WriteLine("Terraria Server " + Main.versionNumber2 + " - " + ModLoader.versionedName); Console.WriteLine(); TmodFile[] mods = ModLoader.FindMods(); for (int k = 0; k < mods.Length; k++) { BuildProperties properties = BuildProperties.ReadModFile(mods[k]); string name = properties.displayName; name = mods[k].name; string line = (k + 1) + "\t\t" + name + "("; line += (ModLoader.IsEnabled(mods[k]) ? "enabled" : "disabled") + ")"; Console.WriteLine(line); } Console.WriteLine("e\t\tEnable All"); Console.WriteLine("d\t\tDisable All"); Console.WriteLine("r\t\tReload and return to world menu"); Console.WriteLine("Type a number to switch between enabled/disabled"); Console.WriteLine(); Console.WriteLine("Type a command: "); string command = Console.ReadLine(); if (command == null) { command = ""; } command = command.ToLower(); Console.Clear(); if (command == "e") { foreach (TmodFile mod in mods) { ModLoader.EnableMod(mod); } } else if (command == "d") { foreach (TmodFile mod in mods) { ModLoader.DisableMod(mod); } } else if (command == "r") { Console.WriteLine("Unloading mods..."); ModLoader.Unload(); ModLoader.do_Load(null); exit = true; } else { int value; if (Int32.TryParse(command, out value)) { value--; if (value >= 0 && value < mods.Length) { ModLoader.SetModActive(mods[value], !ModLoader.IsEnabled(mods[value])); } } } } }
public BuildingMod(TmodFile modFile, BuildProperties properties, string path) : base(modFile, properties) { this.path = path; }
private static byte[] CompileMod(string modDir, BuildProperties properties, bool forWindows) { CompilerParameters compileOptions = new CompilerParameters(); compileOptions.GenerateExecutable = false; compileOptions.GenerateInMemory = false; string outFile = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modDir) + ".dll"; compileOptions.OutputAssembly = outFile; bool flag = false; foreach (string reference in buildReferences) { if (forWindows) { if (reference.IndexOf("FNA.dll") >= 0) { compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Game.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Graphics.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Xact.dll"); continue; } else if (!windows && reference.IndexOf("Terraria.exe") >= 0) { compileOptions.ReferencedAssemblies.Add("TerrariaWindows.exe"); continue; } } else { if (reference.IndexOf("Microsoft.Xna.Framework") >= 0) { if (!flag) { compileOptions.ReferencedAssemblies.Add("FNA.dll"); flag = true; } continue; } else if (windows && reference.IndexOf(System.AppDomain.CurrentDomain.FriendlyName) >= 0) { compileOptions.ReferencedAssemblies.Add("TerrariaMac.exe"); continue; } } compileOptions.ReferencedAssemblies.Add(reference); } Directory.CreateDirectory(DllPath); foreach (string reference in properties.dllReferences) { compileOptions.ReferencedAssemblies.Add(DllPath + Path.DirectorySeparatorChar + reference + ".dll"); } foreach (string reference in properties.modReferences) { string refFile = ModSourcePath + Path.DirectorySeparatorChar + reference; string realRefFile = refFile + ".dll"; refFile += forWindows ? "1.dll" : "2.dll"; if (File.Exists(realRefFile)) { File.Delete(realRefFile); } File.Move(refFile, realRefFile); compileOptions.ReferencedAssemblies.Add(realRefFile); } CodeDomProvider codeProvider = new CSharpCodeProvider(); CompilerResults results = codeProvider.CompileAssemblyFromFile(compileOptions, Directory.GetFiles(modDir, "*.cs", SearchOption.AllDirectories)); CompilerErrorCollection errors = results.Errors; foreach (string reference in properties.modReferences) { File.Delete(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } if (errors.HasErrors) { ErrorLogger.LogCompileErrors(errors); return(null); } byte[] data = File.ReadAllBytes(outFile); File.Delete(outFile); return(data); }
internal static void ServerModMenu() { bool exit = false; while (!exit) { Console.WriteLine("Terraria Server " + Main.versionNumber2 + " - " + ModLoader.versionedName); Console.WriteLine(); TmodFile[] mods = ModLoader.FindMods(); for (int k = 0; k < mods.Length; k++) { BuildProperties properties = BuildProperties.ReadModFile(mods[k]); string name = properties.displayName; name = mods[k].name; string line = (k + 1) + "\t\t" + name + "("; line += (ModLoader.IsEnabled(mods[k]) ? "enabled" : "disabled") + ")"; Console.WriteLine(line); } if (mods.Length == 0) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"No mods were found in: \"{ModLoader.ModPath}\"\nIf you are running a dedicated server, you may wish to use the 'modpath' command line switch or server config setting to specify a custom mods directory.\n"); Console.ResetColor(); } Console.WriteLine("e\t\tEnable All"); Console.WriteLine("d\t\tDisable All"); Console.WriteLine("r\t\tReload and return to world menu"); Console.WriteLine("Type a number to switch between enabled/disabled"); Console.WriteLine(); Console.WriteLine("Type a command: "); string command = Console.ReadLine(); if (command == null) { command = ""; } command = command.ToLower(); Console.Clear(); if (command == "e") { foreach (TmodFile mod in mods) { ModLoader.EnableMod(mod); } } else if (command == "d") { foreach (TmodFile mod in mods) { ModLoader.DisableMod(mod); } } else if (command == "r") { Console.WriteLine("Unloading mods..."); ModLoader.Unload(); ModLoader.do_Load(null); exit = true; } else { int value; if (Int32.TryParse(command, out value)) { value--; if (value >= 0 && value < mods.Length) { ModLoader.SetModActive(mods[value], !ModLoader.IsEnabled(mods[value])); } } } } }
private static void LoadMod(string modFile, BuildProperties properties) { AddAssemblyResolver(); Assembly modCode; using (FileStream fileStream = File.OpenRead(modFile)) { using (BinaryReader reader = new BinaryReader(fileStream)) { fileStream.Seek(reader.ReadInt32(), SeekOrigin.Current); modCode = Assembly.Load(reader.ReadBytes(reader.ReadInt32())); for (string texturePath = reader.ReadString(); texturePath != "end"; texturePath = reader.ReadString()) { byte[] imageData = reader.ReadBytes(reader.ReadInt32()); using (MemoryStream buffer = new MemoryStream(imageData)) { textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer); } } } } Type[] classes = modCode.GetTypes(); foreach (Type type in classes) { if (type.IsSubclassOf(typeof(Mod))) { Mod mod = (Mod)Activator.CreateInstance(type); mod.file = modFile; mod.code = modCode; mod.Init(); mods[mod.Name] = mod; } } }
internal static bool do_BuildMod(object threadContext) { Interface.buildMod.SetReading(); BuildProperties properties = BuildProperties.ReadBuildFile(modToBuild); if (!CreateModReferenceDlls(properties)) { if (!buildAll) { Main.menuMode = Interface.errorMessageID; } return(false); } LoadReferences(); Interface.buildMod.SetCompiling(); byte[] windowsData; byte[] otherData; if (properties.noCompile) { string modDir = modToBuild + Path.DirectorySeparatorChar; if (File.Exists(modDir + "All.dll")) { windowsData = File.ReadAllBytes(modDir + "All.dll"); otherData = File.ReadAllBytes(modDir + "All.dll"); } else if (File.Exists(modDir + "Windows.dll") && File.Exists(modDir + "Other.dll")) { windowsData = File.ReadAllBytes(modDir + "Windows.dll"); otherData = File.ReadAllBytes(modDir + "Other.dll"); } else { ErrorLogger.LogDllBuildError(modToBuild); if (!buildAll) { Main.menuMode = Interface.errorMessageID; } return(false); } } else { windowsData = CompileMod(modToBuild, properties, true); otherData = CompileMod(modToBuild, properties, false); if (windowsData == null || otherData == null) { if (!buildAll) { Main.menuMode = Interface.errorMessageID; } return(false); } } Interface.buildMod.SetBuildText(); string file = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modToBuild) + ".tmod"; byte[] propertiesData = properties.ToBytes(); TmodFile modFile = new TmodFile(file); using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(memoryStream)) { writer.Write(propertiesData.Length); writer.Write(propertiesData); writer.Write(Path.GetFileName(modToBuild)); string[] resources = Directory.GetFiles(modToBuild, "*", SearchOption.AllDirectories); foreach (string resource in resources) { if (Path.GetExtension(resource) == ".cs") { continue; } if (resource.Substring(modToBuild.Length + 1) == "build.txt") { continue; } string resourcePath = resource.Replace(ModSourcePath + Path.DirectorySeparatorChar, null); resourcePath = resourcePath.Replace(Path.DirectorySeparatorChar, '/'); byte[] buffer = File.ReadAllBytes(resource); writer.Write(resourcePath); writer.Write(buffer.Length); writer.Write(buffer); } writer.Write("end"); writer.Flush(); modFile.AddFile("Resources", memoryStream.ToArray()); } } bool same = windowsData.Length == otherData.Length; if (same) { for (int k = 0; k < windowsData.Length; k++) { if (windowsData[k] != otherData[k]) { same = false; break; } } } if (same) { modFile.AddFile("All", windowsData); } else { modFile.AddFile("Windows", windowsData); modFile.AddFile("Other", otherData); } modFile.Save(); EnableMod(file); if (!buildAll) { Main.menuMode = reloadAfterBuild ? Interface.reloadModsID : 0; } return(true); }
private static void LoadMod(TmodFile modFile, BuildProperties properties) { AddAssemblyResolver(); string fileName = Path.GetFileNameWithoutExtension(modFile.Name); Interface.loadMods.SetProgressReading(fileName, 0, 2); Assembly modCode; string rootDirectory; if (modFile.HasFile("All")) { modCode = Assembly.Load(modFile.GetFile("All")); } else { modCode = Assembly.Load(modFile.GetFile(windows ? "Windows" : "Other")); } Interface.loadMods.SetProgressReading(fileName, 1, 2); using (MemoryStream memoryStream = new MemoryStream(modFile.GetFile("Resources"))) { using (BinaryReader reader = new BinaryReader(memoryStream)) { memoryStream.Seek(reader.ReadInt32(), SeekOrigin.Current); rootDirectory = reader.ReadString(); for (string path = reader.ReadString(); path != "end"; path = reader.ReadString()) { byte[] data = reader.ReadBytes(reader.ReadInt32()); files[path] = data; string extension = Path.GetExtension(path); switch (extension) { case ".png": string texturePath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer); } break; case ".wav": string soundPath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { sounds[soundPath] = SoundEffect.FromStream(buffer); } break; case ".mp3": string mp3Path = Path.ChangeExtension(path, null); ushort wFormatTag = 1; ushort nChannels; uint nSamplesPerSec; uint nAvgBytesPerSec; ushort nBlockAlign; ushort wBitsPerSample = 16; MemoryStream output = new MemoryStream(); using (MemoryStream yourMp3FileStream = new MemoryStream(data)) using (var input = new MP3Sharp.MP3Stream(yourMp3FileStream)) using (var writer = new BinaryWriter(output, Encoding.UTF8)) { var headerSize = 44; output.Position = headerSize; input.CopyTo(output); UInt32 wavDataLength = (UInt32)output.Length - 44; output.Position = 0; nChannels = (ushort)input.ChannelCount; nSamplesPerSec = (uint)input.Frequency; nBlockAlign = (ushort)(nChannels * (wBitsPerSample / 8)); nAvgBytesPerSec = (uint)(nSamplesPerSec * nChannels * (wBitsPerSample / 8)); //write the header writer.Write("RIFF".ToCharArray()); //4 writer.Write((UInt32)(wavDataLength + 36)); // 4 writer.Write("WAVE".ToCharArray()); //4 writer.Write("fmt ".ToCharArray()); //4 writer.Write(16); //4 writer.Write(wFormatTag); // writer.Write((ushort)nChannels); writer.Write(nSamplesPerSec); writer.Write(nAvgBytesPerSec); writer.Write(nBlockAlign); writer.Write(wBitsPerSample); writer.Write("data".ToCharArray()); writer.Write((UInt32)(wavDataLength)); output.Position = 0; sounds[mp3Path] = SoundEffect.FromStream(output); } break; } } } } Type[] classes = modCode.GetTypes(); foreach (Type type in classes) { if (type.IsSubclassOf(typeof(Mod))) { Mod mod = (Mod)Activator.CreateInstance(type); mod.file = modFile.Name; mod.code = modCode; mod.Init(); if (mods.ContainsKey(mod.Name)) { throw new DuplicateNameException("Two mods share the internal name " + mod.Name); } if (rootDirectory != mod.Name) { throw new MissingResourceException("Mod name " + mod.Name + " does not match source directory name " + rootDirectory); } mods[mod.Name] = mod; loadOrder.Push(mod.Name); } } }
private static bool LoadMods() { //load all referenced assemblies before mods for compiling ModCompile.LoadReferences(); if (!CommandLineModPackOverride()) { return(false); } Interface.loadMods.SetProgressFinding(); var modsToLoad = FindMods() .Where(IsEnabled) .Select(mod => new LoadingMod(mod, BuildProperties.ReadModFile(mod))) .Where(mod => LoadSide(mod.properties.side)) .ToList(); // Press shift while starting up tModLoader or while trapped in a reload cycle to skip loading all mods. if (Main.oldKeyState.PressingShift()) { modsToLoad.Clear(); } if (!VerifyNames(modsToLoad)) { return(false); } try { EnsureDependenciesExist(modsToLoad, false); EnsureTargetVersionsMet(modsToLoad); modsToLoad = Sort(modsToLoad); } catch (ModSortingException e) { foreach (var mod in e.errored) { DisableMod(mod.modFile); } ErrorLogger.LogDependencyError(e.Message); return(false); } var modInstances = AssemblyManager.InstantiateMods(modsToLoad); if (modInstances == null) { return(false); } modInstances.Insert(0, new ModLoaderMod()); loadedMods = modInstances.ToArray(); loadedModsWeakReferences = loadedMods.Skip(1).Select(x => new WeakReference(x)).ToArray(); foreach (var mod in modInstances) { loadOrder.Push(mod.Name); mods[mod.Name] = mod; } return(true); }
internal static List <LoadingMod> FindReferencedMods(BuildProperties properties) { var mods = new Dictionary <string, LoadingMod>(); return(FindReferencedMods(properties, mods) ? mods.Values.ToList() : null); }
internal static bool BuildAll(string[] modFolders, IBuildStatus status) { var modList = new List <LoadingMod>(); //read mod sources folder foreach (var modFolder in modFolders) { var mod = ReadProperties(modFolder, status); if (mod == null) { return(false); } modList.Add(mod); } //figure out which of the installed mods are required for building var installedMods = FindMods() .Where(mod => !modList.Exists(m => m.Name == mod.name)) .Select(mod => new LoadingMod(mod, BuildProperties.ReadModFile(mod))) .ToList(); var requiredFromInstall = new HashSet <LoadingMod>(); Action <LoadingMod> require = null; require = (mod) => { foreach (var dep in mod.properties.RefNames(true)) { var depMod = installedMods.SingleOrDefault(m => m.Name == dep); if (depMod != null && requiredFromInstall.Add(depMod)) { require(depMod); } } }; foreach (var mod in modList) { require(mod); } modList.AddRange(requiredFromInstall); //sort and version check List <BuildingMod> modsToBuild; try { EnsureDependenciesExist(modList, true); EnsureTargetVersionsMet(modList); var sortedModList = Sort(modList); modsToBuild = sortedModList.OfType <BuildingMod>().ToList(); } catch (ModSortingException e) { ErrorLogger.LogDependencyError(e.Message); return(false); } //build int num = 0; foreach (var mod in modsToBuild) { status.SetProgress(num++, modsToBuild.Count); if (!Build(mod, status)) { return(false); } } return(true); }
private static void LoadMod(TmodFile modFile, BuildProperties properties) { AddAssemblyResolver(); string fileName = Path.GetFileNameWithoutExtension(modFile.Name); Interface.loadMods.SetProgressReading(fileName, 0, 2); Assembly modCode; string rootDirectory; if (modFile.HasFile("All")) { modCode = Assembly.Load(modFile.GetFile("All")); } else { modCode = Assembly.Load(modFile.GetFile(windows ? "Windows" : "Other")); } Interface.loadMods.SetProgressReading(fileName, 1, 2); using (MemoryStream memoryStream = new MemoryStream(modFile.GetFile("Resources"))) { using (BinaryReader reader = new BinaryReader(memoryStream)) { rootDirectory = reader.ReadString(); for (string path = reader.ReadString(); path != "end"; path = reader.ReadString()) { byte[] data = reader.ReadBytes(reader.ReadInt32()); files[path] = data; if (Main.dedServ) { continue; } string extension = Path.GetExtension(path); switch (extension) { case ".png": string texturePath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer); } break; case ".wav": string soundPath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { sounds[soundPath] = SoundEffect.FromStream(buffer); } break; case ".mp3": string mp3Path = Path.ChangeExtension(path, null); string wavCacheFilename = mp3Path.Replace('/', '_') + "_" + properties.version + ".wav"; if (WAVCacheIO.WAVCacheAvailable(wavCacheFilename)) { sounds[mp3Path] = SoundEffect.FromStream(WAVCacheIO.GetWavStream(wavCacheFilename)); break; } ushort wFormatTag = 1; ushort nChannels; uint nSamplesPerSec; uint nAvgBytesPerSec; ushort nBlockAlign; ushort wBitsPerSample = 16; const int headerSize = 44; MemoryStream output = new MemoryStream(headerSize + data.Length); using (MemoryStream yourMp3FileStream = new MemoryStream(data)) { using (MP3Sharp.MP3Stream input = new MP3Sharp.MP3Stream(yourMp3FileStream)) { using (BinaryWriter writer = new BinaryWriter(output, Encoding.UTF8)) { output.Position = headerSize; input.CopyTo(output); UInt32 wavDataLength = (UInt32)output.Length - headerSize; output.Position = 0; nChannels = (ushort)input.ChannelCount; nSamplesPerSec = (uint)input.Frequency; nBlockAlign = (ushort)(nChannels * (wBitsPerSample / 8)); nAvgBytesPerSec = (uint)(nSamplesPerSec * nChannels * (wBitsPerSample / 8)); //write the header writer.Write("RIFF".ToCharArray()); //4 writer.Write((UInt32)(wavDataLength + 36)); // 4 writer.Write("WAVE".ToCharArray()); //4 writer.Write("fmt ".ToCharArray()); //4 writer.Write(16); //4 writer.Write(wFormatTag); // writer.Write((ushort)nChannels); writer.Write(nSamplesPerSec); writer.Write(nAvgBytesPerSec); writer.Write(nBlockAlign); writer.Write(wBitsPerSample); writer.Write("data".ToCharArray()); writer.Write((UInt32)(wavDataLength)); output.Position = 0; WAVCacheIO.SaveWavStream(output, wavCacheFilename); sounds[mp3Path] = SoundEffect.FromStream(output); } } } break; } } } } Type[] classes = modCode.GetTypes(); foreach (Type type in classes) { if (type.IsSubclassOf(typeof(Mod))) { Mod mod = (Mod)Activator.CreateInstance(type); mod.file = modFile.Name; mod.buildVersion = properties.modBuildVersion; mod.code = modCode; mod.Init(); if (mod.Name == "Terraria") { throw new DuplicateNameException("Mods cannot be named Terraria"); } if (mods.ContainsKey(mod.Name)) { throw new DuplicateNameException("Two mods share the internal name " + mod.Name); } if (rootDirectory != mod.Name) { throw new MissingResourceException("Mod name " + mod.Name + " does not match source directory name " + rootDirectory); } mods[mod.Name] = mod; loadOrder.Push(mod.Name); } } }
internal static BuildProperties ReadModFile(TmodFile modFile) { BuildProperties properties = new BuildProperties(); byte[] data = modFile.GetFile("Info"); if (data.Length == 0) { return(properties); } using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) { 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 == "editAndContinue") { properties.editAndContinue = true; } if (tag == "side") { properties.side = (ModSide)reader.ReadByte(); } } } return(properties); }
private static byte[] CompileMod(string modDir, BuildProperties properties, bool forWindows) { CompilerParameters compileOptions = new CompilerParameters(); compileOptions.GenerateExecutable = false; compileOptions.GenerateInMemory = false; string outFile = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modDir) + ".dll"; compileOptions.OutputAssembly = outFile; bool flag = false; foreach (string reference in buildReferences) { if (forWindows) { if (reference.IndexOf("FNA.dll") >= 0) { compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Game.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Graphics.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Xact.dll"); continue; } else if (!windows && reference.IndexOf("Terraria.exe") >= 0) { compileOptions.ReferencedAssemblies.Add("TerrariaWindows.exe"); continue; } } else { if (reference.IndexOf("Microsoft.Xna.Framework") >= 0) { if (!flag) { compileOptions.ReferencedAssemblies.Add("FNA.dll"); flag = true; } continue; } else if (windows && reference.IndexOf(System.AppDomain.CurrentDomain.FriendlyName) >= 0) { compileOptions.ReferencedAssemblies.Add("TerrariaMac.exe"); continue; } } compileOptions.ReferencedAssemblies.Add(reference); } Directory.CreateDirectory(DllPath); foreach (string reference in properties.dllReferences) { compileOptions.ReferencedAssemblies.Add(DllPath + Path.DirectorySeparatorChar + reference + ".dll"); } foreach (string reference in properties.modReferences) { string refFile = ModSourcePath + Path.DirectorySeparatorChar + reference; string realRefFile = refFile + ".dll"; refFile += forWindows ? "1.dll" : "2.dll"; if (File.Exists(realRefFile)) { File.Delete(realRefFile); } File.Move(refFile, realRefFile); compileOptions.ReferencedAssemblies.Add(realRefFile); } var options = new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }; CodeDomProvider codeProvider = new CSharpCodeProvider(options); CompilerResults results = codeProvider.CompileAssemblyFromFile(compileOptions, Directory.GetFiles(modDir, "*.cs", SearchOption.AllDirectories)); CompilerErrorCollection errors = results.Errors; foreach (string reference in properties.modReferences) { File.Delete(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } if (errors.HasErrors) { ErrorLogger.LogCompileErrors(errors); return null; } byte[] data = File.ReadAllBytes(outFile); File.Delete(outFile); return data; }
private static void LoadMod(TmodFile modFile, BuildProperties properties) { AddAssemblyResolver(); Interface.loadMods.SetProgressReading(Path.GetFileNameWithoutExtension(modFile.Name)); Assembly modCode; string rootDirectory; modCode = Assembly.Load(modFile.GetFile(windows ? "Windows" : "Other")); using (MemoryStream memoryStream = new MemoryStream(modFile.GetFile("Resources"))) { using (BinaryReader reader = new BinaryReader(memoryStream)) { memoryStream.Seek(reader.ReadInt32(), SeekOrigin.Current); rootDirectory = reader.ReadString(); for (string path = reader.ReadString(); path != "end"; path = reader.ReadString()) { byte[] data = reader.ReadBytes(reader.ReadInt32()); files[path] = data; string extension = Path.GetExtension(path); switch (extension) { case ".png": string texturePath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer); } break; case ".wav": string soundPath = Path.ChangeExtension(path, null); using (MemoryStream buffer = new MemoryStream(data)) { sounds[soundPath] = SoundEffect.FromStream(buffer); } break; } } } } Type[] classes = modCode.GetTypes(); foreach (Type type in classes) { if (type.IsSubclassOf(typeof(Mod))) { Mod mod = (Mod)Activator.CreateInstance(type); mod.file = modFile.Name; mod.code = modCode; mod.Init(); if (mods.ContainsKey(mod.Name)) { throw new DuplicateNameException("Two mods share the internal name " + mod.Name); } if (rootDirectory != mod.Name) { throw new MissingResourceException("Mod name " + mod.Name + " does not match source directory name " + rootDirectory); } mods[mod.Name] = mod; } } }
private static bool CompileMod(string modDir, BuildProperties properties, bool forWindows) { CompilerParameters compileOptions = new CompilerParameters(); compileOptions.GenerateExecutable = false; compileOptions.GenerateInMemory = false; compileOptions.OutputAssembly = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modDir); compileOptions.OutputAssembly += forWindows ? ".tmod1" : ".tmod2"; bool flag = false; foreach (string reference in buildReferences) { if (forWindows) { if (reference.IndexOf("FNA.dll") >= 0) { compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Game.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Graphics.dll"); compileOptions.ReferencedAssemblies.Add("Microsoft.Xna.Framework.Xact.dll"); continue; } else if (!windows && reference.IndexOf("Terraria.exe") >= 0) { compileOptions.ReferencedAssemblies.Add("TerrariaWindows.exe"); continue; } } else { if (reference.IndexOf("Microsoft.Xna.Framework") >= 0) { if (!flag) { compileOptions.ReferencedAssemblies.Add("FNA.dll"); flag = true; } continue; } else if (windows && reference.IndexOf("Terraria.exe") >= 0) { compileOptions.ReferencedAssemblies.Add("TerrariaMac.exe"); continue; } } compileOptions.ReferencedAssemblies.Add(reference); } Directory.CreateDirectory(DllPath); foreach (string reference in properties.dllReferences) { compileOptions.ReferencedAssemblies.Add(DllPath + Path.DirectorySeparatorChar + reference + ".dll"); } foreach (string reference in properties.modReferences) { string refFile = ModSourcePath + Path.DirectorySeparatorChar + reference; refFile += forWindows ? "1.dll" : "2.dll"; compileOptions.ReferencedAssemblies.Add(refFile); } CodeDomProvider codeProvider = new CSharpCodeProvider(); CompilerResults results = codeProvider.CompileAssemblyFromFile(compileOptions, Directory.GetFiles(modDir, "*.cs", SearchOption.AllDirectories)); CompilerErrorCollection errors = results.Errors; foreach (string reference in properties.modReferences) { string refFile = ModSourcePath + Path.DirectorySeparatorChar + reference; refFile += forWindows ? "1.dll" : "2.dll"; File.Delete(refFile); } if (errors.HasErrors) { ErrorLogger.LogCompileErrors(errors); return false; } return true; }
internal static BuildProperties LoadBuildProperties(string modFile) { BuildProperties properties = new BuildProperties(); byte[] data; using(FileStream fileStream = File.OpenRead(modFile)) { using(BinaryReader reader = new BinaryReader(fileStream)) { data = reader.ReadBytes(reader.ReadInt32()); } } if(data.Length == 0) { return properties; } using(MemoryStream memoryStream = new MemoryStream(data)) { using(BinaryReader reader = new BinaryReader(memoryStream)) { for(string tag = reader.ReadString(); tag.Length > 0; tag = reader.ReadString()) { if(tag == "dllReferences") { List<string> dllReferences = new List<string>(); for(string reference = reader.ReadString(); reference.Length > 0; reference = reader.ReadString()) { dllReferences.Add(reference); } properties.dllReferences = dllReferences.ToArray(); } if(tag == "modReferences") { List<string> modReferences = new List<string>(); for(string reference = reader.ReadString(); reference.Length > 0; reference = reader.ReadString()) { modReferences.Add(reference); } properties.modReferences = modReferences.ToArray(); } if(tag == "author") { properties.author = reader.ReadString(); } if(tag == "version") { properties.version = reader.ReadString(); } if(tag == "displayName") { properties.displayName = reader.ReadString(); } } } } return properties; }
private static bool CompileMod(string modDir, BuildProperties properties) { CompilerParameters compileOptions = new CompilerParameters(); compileOptions.GenerateExecutable = false; compileOptions.GenerateInMemory = false; compileOptions.OutputAssembly = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modDir) + ".tmod"; foreach(string reference in buildReferences) { compileOptions.ReferencedAssemblies.Add(reference); } foreach(string reference in properties.dllReferences) { compileOptions.ReferencedAssemblies.Add(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } foreach(string reference in properties.modReferences) { compileOptions.ReferencedAssemblies.Add(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } CodeDomProvider codeProvider = new CSharpCodeProvider(); CompilerResults results = codeProvider.CompileAssemblyFromFile(compileOptions, Directory.GetFiles(modDir, "*.cs", SearchOption.AllDirectories)); CompilerErrorCollection errors = results.Errors; foreach(string reference in properties.modReferences) { File.Delete(ModSourcePath + Path.DirectorySeparatorChar + reference + ".dll"); } if(errors.HasErrors) { ErrorLogger.LogCompileErrors(errors); return false; } return true; }
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); } string[] lines = File.ReadAllLines(propertiesFile); foreach (string line in lines) { if (line.Length == 0) { 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.sortAfter = ReadList(value).ToArray(); break; case "sortAfter": properties.sortBefore = 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 = value.ToLower() == "true"; break; case "hideCode": properties.hideCode = value.ToLower() != "false"; break; case "hideResources": properties.hideResources = value.ToLower() != "false"; break; case "includeSource": properties.includeSource = value.ToLower() == "true"; break; case "includePDB": properties.includePDB = value.ToLower() == "true"; break; case "buildIgnore": properties.buildIgnores = value.Split(',').Select(s => s.Trim()).Where(s => s.Length > 0).ToArray(); break; case "languageVersion": if (!int.TryParse(value, out properties.languageVersion)) { throw new Exception("languageVersion not an int: " + value); } if (properties.languageVersion < 4 || properties.languageVersion > 6) { throw new Exception("languageVersion (" + properties.languageVersion + ") must be between 4 and 6"); } 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); }
private static byte[] PropertiesToBytes(BuildProperties properties) { byte[] data; using(MemoryStream memoryStream = new MemoryStream()) { using(BinaryWriter writer = new BinaryWriter(memoryStream)) { if(properties.dllReferences.Length > 0) { writer.Write("dllReferences"); foreach(string reference in properties.dllReferences) { writer.Write(reference); } writer.Write(""); } if(properties.modReferences.Length > 0) { writer.Write("modReferences"); foreach(string reference in properties.modReferences) { writer.Write(reference); } writer.Write(""); } if(properties.author.Length > 0) { writer.Write("author"); writer.Write(properties.author); } if(properties.version.Length > 0) { writer.Write("version"); writer.Write(properties.version); } if(properties.displayName.Length > 0) { writer.Write("displayName"); writer.Write(properties.displayName); } writer.Write(""); writer.Flush(); data = memoryStream.ToArray(); } } return data; }
private static BuildProperties ReadBuildProperties(string modDir) { string propertiesFile = modDir + Path.DirectorySeparatorChar + "build.txt"; BuildProperties properties = new BuildProperties(); if (!File.Exists(propertiesFile)) { return properties; } string[] lines = File.ReadAllLines(propertiesFile); foreach (string line in lines) { if (line.Length == 0) { 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": string[] dllReferences = value.Split(','); for (int k = 0; k < dllReferences.Length; k++) { string dllReference = dllReferences[k].Trim(); if (dllReference.Length > 0) { dllReferences[k] = dllReference; } } properties.dllReferences = dllReferences; break; case "modReferences": string[] modReferences = value.Split(','); for (int k = 0; k < modReferences.Length; k++) { string modReference = modReferences[k].Trim(); if (modReference.Length > 0) { modReferences[k] = modReference; } } properties.modReferences = modReferences; break; case "author": properties.author = value; break; case "version": properties.version = value; break; case "displayName": properties.displayName = value; break; } } foreach (string modReference in properties.modReferences) { TmodFile refFile = new TmodFile(ModPath + Path.DirectorySeparatorChar + modReference + ".tmod"); refFile.Read(); if (!refFile.ValidMod()) { ErrorLogger.LogModReferenceError(refFile.Name); return null; } byte[] data1 = refFile.GetFile("Windows"); byte[] data2 = refFile.GetFile("Other"); string refFileName = ModSourcePath + Path.DirectorySeparatorChar + modReference; File.WriteAllBytes(refFileName + "1.dll", refFile.GetFile("Windows")); File.WriteAllBytes(refFileName + "2.dll", refFile.GetFile("Other")); } return properties; }
private static BuildProperties ReadBuildProperties(string modDir) { string propertiesFile = modDir + Path.DirectorySeparatorChar + "build.txt"; BuildProperties properties = new BuildProperties(); if(!File.Exists(propertiesFile)) { return properties; } string[] lines = File.ReadAllLines(propertiesFile); foreach (string line in lines) { if(line.Length == 0) { 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": string[] dllReferences = value.Split(','); for (int k = 0; k < dllReferences.Length; k++) { string dllReference = dllReferences[k].Trim(); if (dllReference.Length > 0) { dllReferences[k] = dllReference; } } properties.dllReferences = dllReferences; break; case "modReferences": string[] modReferences = value.Split(','); for (int k = 0; k < modReferences.Length; k++) { string modReference = modReferences[k].Trim(); if (modReference.Length > 0) { modReferences[k] = modReference; } } properties.modReferences = modReferences; break; case "author": properties.author = value; break; case "version": properties.version = value; break; case "displayName": properties.displayName = value; break; } } foreach(string modReference in properties.modReferences) { string path = ModPath + Path.DirectorySeparatorChar + modReference + ".tmod"; if(!File.Exists(path)) { ErrorLogger.LogModReferenceError(modReference); return null; } byte[] data; using(FileStream fileStream = File.OpenRead(path)) { using(BinaryReader reader = new BinaryReader(fileStream)) { fileStream.Seek(reader.ReadInt32(), SeekOrigin.Current); data = reader.ReadBytes(reader.ReadInt32()); } } using (FileStream writeStream = File.Create(ModSourcePath + Path.DirectorySeparatorChar + modReference + ".dll")) { using (BinaryWriter writer = new BinaryWriter(writeStream)) { writer.Write(data); } } } return properties; }
internal static BuildProperties ReadModFile(TmodFile modFile) { BuildProperties properties = new BuildProperties(); byte[] data; using (MemoryStream memoryStream = new MemoryStream(modFile.GetFile("Info"))) { using (BinaryReader reader = new BinaryReader(memoryStream)) { properties.modBuildVersion = reader.ReadString(); data = reader.ReadBytes(reader.ReadInt32()); } } if (data.Length == 0) { return properties; } using (MemoryStream memoryStream = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(memoryStream)) { for (string tag = reader.ReadString(); tag.Length > 0; tag = reader.ReadString()) { if (tag == "dllReferences") { List<string> dllReferences = new List<string>(); for (string reference = reader.ReadString(); reference.Length > 0; reference = reader.ReadString()) { dllReferences.Add(reference); } properties.dllReferences = dllReferences.ToArray(); } if (tag == "modReferences") { List<string> modReferences = new List<string>(); for (string reference = reader.ReadString(); reference.Length > 0; reference = reader.ReadString()) { modReferences.Add(reference); } properties.modReferences = modReferences.ToArray(); } if (tag == "author") { properties.author = reader.ReadString(); } if (tag == "version") { properties.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; } } } } return properties; }
internal static List<LoadingMod> FindReferencedMods(BuildProperties properties) { var mods = new Dictionary<string, LoadingMod>(); return FindReferencedMods(properties, mods) ? mods.Values.ToList() : null; }
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); } string[] lines = File.ReadAllLines(propertiesFile); foreach (string line in lines) { if (line.Length == 0) { 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": string[] dllReferences = value.Split(','); for (int k = 0; k < dllReferences.Length; k++) { string dllReference = dllReferences[k].Trim(); if (dllReference.Length > 0) { dllReferences[k] = dllReference; } } properties.dllReferences = dllReferences; break; case "modReferences": string[] modReferences = value.Split(','); for (int k = 0; k < modReferences.Length; k++) { string modReference = modReferences[k].Trim(); if (modReference.Length > 0) { modReferences[k] = modReference; } } properties.modReferences = modReferences; break; case "author": properties.author = value; break; case "version": properties.version = value; break; case "displayName": properties.displayName = value; break; case "homepage": properties.homepage = value; break; case "noCompile": properties.noCompile = value.ToLower() == "true"; break; case "hideCode": properties.hideCode = value.ToLower() != "false"; break; case "hideResources": properties.hideResources = value.ToLower() != "false"; break; case "includeSource": properties.includeSource = value.ToLower() == "true"; break; case "buildIgnore": string[] buildIgnores = value.Split(','); for (int k = 0; k < buildIgnores.Length; k++) { string buildIgnore = buildIgnores[k].Trim(); if (buildIgnore.Length > 0) { buildIgnores[k] = buildIgnore; } } properties.buildIgnores = buildIgnores; break; } } return properties; }
internal static BuildProperties ReadBuildFile(string modDir) { string propertiesFile = modDir + Path.DirectorySeparatorChar + "build.txt"; BuildProperties properties = new BuildProperties(); if (!File.Exists(propertiesFile)) { return properties; } string[] lines = File.ReadAllLines(propertiesFile); foreach (string line in lines) { if (line.Length == 0) { 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": string[] dllReferences = value.Split(','); for (int k = 0; k < dllReferences.Length; k++) { string dllReference = dllReferences[k].Trim(); if (dllReference.Length > 0) { dllReferences[k] = dllReference; } } properties.dllReferences = dllReferences; break; case "modReferences": string[] modReferences = value.Split(','); for (int k = 0; k < modReferences.Length; k++) { string modReference = modReferences[k].Trim(); if (modReference.Length > 0) { modReferences[k] = modReference; } } properties.modReferences = modReferences; break; case "author": properties.author = value; break; case "version": properties.version = value; break; case "displayName": properties.displayName = value; break; case "noCompile": properties.noCompile = value.ToLower() == "true" ? true : false; break; } } return properties; }