Beispiel #1
0
        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);
        }
Beispiel #2
0
        private static bool Build(BuildingMod mod, IBuildStatus status)
        {
            byte[] winDLL  = null;
            byte[] monoDLL = null;
            byte[] winPDB  = null;
            if (mod.properties.noCompile)
            {
                winDLL = monoDLL = ReadIfExists(Path.Combine(mod.path, "All.dll"));
                winPDB = ReadIfExists(Path.Combine(mod.path, "All.pdb"));

                if (winDLL == null)
                {
                    winDLL  = ReadIfExists(Path.Combine(mod.path, "Windows.dll"));
                    monoDLL = ReadIfExists(Path.Combine(mod.path, "Mono.dll"));
                    winPDB  = ReadIfExists(Path.Combine(mod.path, "Windows.pdb"));
                }

                if (winDLL == null || monoDLL == null)
                {
                    ErrorLogger.LogDllBuildError(mod.path);
                    return(false);
                }
            }
            else
            {
                var refMods = FindReferencedMods(mod.properties);
                if (refMods == null)
                {
                    return(false);
                }

                if (Program.LaunchParameters.ContainsKey("-eac"))
                {
                    if (!windows)
                    {
                        ErrorLogger.LogBuildError("Edit and continue is only supported on windows");
                        return(false);
                    }

                    try {
                        status.SetStatus("Loading pre-compiled Windows.dll with edit and continue support");
                        var winPath = Program.LaunchParameters["-eac"];
                        var pdbPath = Path.ChangeExtension(winPath, "pdb");
                        winDLL = File.ReadAllBytes(winPath);
                        winPDB = File.ReadAllBytes(pdbPath);
                        mod.properties.editAndContinue = true;
                    }
                    catch (Exception e) {
                        ErrorLogger.LogBuildError("Failed to load pre-compiled edit and continue dll " + e);
                        return(false);
                    }
                }
                else
                {
                    status.SetStatus("Compiling " + mod + " for Windows...");
                    status.SetProgress(0, 2);
                    CompileMod(mod, refMods, true, ref winDLL, ref winPDB);
                }
                if (winDLL == null)
                {
                    return(false);
                }

                status.SetStatus("Compiling " + mod + " for Mono...");
                status.SetProgress(1, 2);
                CompileMod(mod, refMods, false, ref monoDLL, ref winPDB);                //the pdb reference won't actually be written to
                if (monoDLL == null)
                {
                    return(false);
                }
            }

            if (!VerifyName(mod.Name, winDLL) || !VerifyName(mod.Name, monoDLL))
            {
                return(false);
            }

            status.SetStatus("Building " + mod + "...");
            status.SetProgress(0, 1);

            mod.modFile.AddFile("Info", mod.properties.ToBytes());

            if (Equal(winDLL, monoDLL))
            {
                mod.modFile.AddFile("All.dll", winDLL);
                if (winPDB != null)
                {
                    mod.modFile.AddFile("All.pdb", winPDB);
                }
            }
            else
            {
                mod.modFile.AddFile("Windows.dll", winDLL);
                mod.modFile.AddFile("Mono.dll", monoDLL);
                if (winPDB != null)
                {
                    mod.modFile.AddFile("Windows.pdb", winPDB);
                }
            }

            foreach (var resource in Directory.GetFiles(mod.path, "*", SearchOption.AllDirectories))
            {
                var relPath = resource.Substring(mod.path.Length + 1);
                if (mod.properties.ignoreFile(relPath) ||
                    relPath == "build.txt" ||
                    !mod.properties.includeSource && sourceExtensions.Contains(Path.GetExtension(resource)) ||
                    Path.GetFileName(resource) == "Thumbs.db")
                {
                    continue;
                }

                mod.modFile.AddFile(relPath, File.ReadAllBytes(resource));
            }

            WAVCacheIO.ClearCache(mod.Name);

            mod.modFile.Save();
            EnableMod(mod.modFile);
            ActivateExceptionReporting();
            return(true);
        }
Beispiel #3
0
        private static void CompileMod(BuildingMod mod, List <LoadingMod> refMods, bool forWindows,
                                       ref byte[] dll, ref byte[] pdb)
        {
            LoadReferences();
            bool generatePDB = mod.properties.includePDB && forWindows;

            if (generatePDB && !windows)
            {
                Console.WriteLine("PDB files can only be generated for windows, on windows.");
                generatePDB = false;
            }

            //collect all dll references
            var tempDir = Path.Combine(ModPath, "compile_temp");

            Directory.CreateDirectory(tempDir);
            var refs = new List <string>();

            //everything used to compile the tModLoader for the target platform
            refs.AddRange(GetTerrariaReferences(tempDir, forWindows));

            //libs added by the mod
            refs.AddRange(mod.properties.dllReferences.Select(refDll => Path.Combine(mod.path, "lib/" + refDll + ".dll")));

            //all dlls included in all referenced mods
            foreach (var refMod in refMods)
            {
                var path = Path.Combine(tempDir, refMod + ".dll");
                File.WriteAllBytes(path, refMod.modFile.GetMainAssembly(forWindows));
                refs.Add(path);

                foreach (var refDll in refMod.properties.dllReferences)
                {
                    path = Path.Combine(tempDir, refDll + ".dll");
                    File.WriteAllBytes(path, refMod.modFile.GetFile("lib/" + refDll + ".dll"));
                    refs.Add(path);
                }
            }

            var compileOptions = new CompilerParameters {
                OutputAssembly          = Path.Combine(tempDir, mod + ".dll"),
                GenerateExecutable      = false,
                GenerateInMemory        = false,
                TempFiles               = new TempFileCollection(tempDir, true),
                IncludeDebugInformation = generatePDB
            };

            compileOptions.ReferencedAssemblies.AddRange(refs.ToArray());
            var files = Directory.GetFiles(mod.path, "*.cs", SearchOption.AllDirectories).Where(file => !mod.properties.ignoreFile(file.Substring(mod.path.Length + 1))).ToArray();

            try {
                CompilerResults results;
                if (mod.properties.languageVersion == 6)
                {
                    if (Environment.Version.Revision < 10000)
                    {
                        ErrorLogger.LogBuildError(".NET Framework 4.5 must be installed to compile C# 6.0");
                        return;
                    }

                    results = RoslynCompile(compileOptions, files);
                }
                else
                {
                    var options = new Dictionary <string, string> {
                        { "CompilerVersion", "v" + mod.properties.languageVersion + ".0" }
                    };
                    results = new CSharpCodeProvider(options).CompileAssemblyFromFile(compileOptions, files);
                }

                if (results.Errors.HasErrors)
                {
                    ErrorLogger.LogCompileErrors(results.Errors, forWindows);
                    return;
                }

                dll = File.ReadAllBytes(compileOptions.OutputAssembly);
                dll = PostProcess(dll, forWindows);
                if (generatePDB)
                {
                    pdb = File.ReadAllBytes(Path.Combine(tempDir, mod + ".pdb"));
                }
            }
            finally {
                int numTries = 10;
                while (numTries > 0)
                {
                    try {
                        Directory.Delete(tempDir, true);
                        numTries = 0;
                    }
                    catch {
                        System.Threading.Thread.Sleep(1);
                        numTries--;
                    }
                }
            }
        }
Beispiel #4
0
        internal static List <Mod> InstantiateMods(List <LocalMod> modsToLoad)
        {
            var modList = new List <LoadedMod>();

            foreach (var loading in modsToLoad)
            {
                if (!loadedMods.TryGetValue(loading.Name, out LoadedMod mod))
                {
                    mod = loadedMods[loading.Name] = new LoadedMod();
                }

                mod.SetMod(loading);
                modList.Add(mod);
            }

            RecalculateReferences();

            if (Debugger.IsAttached)
            {
                ModLoader.isModder = true;
                foreach (var mod in modList.Where(mod => mod.properties.editAndContinue && mod.CanEaC))
                {
                    mod.EnableEaC();
                }
            }
            if (ModLoader.alwaysLogExceptions)
            {
                ModCompile.ActivateExceptionReporting();
            }

            try
            {
                //load all the assemblies in parallel.
                Interface.loadMods.SetLoadStage("tModLoader.MSSandboxing", modsToLoad.Count);
                int i = 0;
                Parallel.ForEach(modList, mod =>
                {
                    Interface.loadMods.SetCurrentMod(i++, mod.Name);
                    mod.LoadAssemblies();
                });

                Interface.loadMods.SetLoadStage("tModLoader.MSInstantiating");
                //Assemblies must be loaded before any instantiation occurs to satisfy dependencies
                return(modList.Select(Instantiate).ToList());
            }
            catch (AggregateException ae)
            {
                ErrorLogger.LogMulti(ae.InnerExceptions.Select(e => new Action(() =>
                {
                    var mod = modList.Single(m => m.Name == (string)e.Data["mod"]);
                    ModLoader.DisableMod(mod.Name);
                    ErrorLogger.LogLoadingError(mod.Name, mod.modFile.tModLoaderVersion, e);
                })));
                Main.menuMode = Interface.errorMessageID;
                return(null);
            }
            catch (Exception e)
            {
                var mod = modList.Single(m => m.Name == (string)e.Data["mod"]);
                ModLoader.DisableMod(mod.Name);
                ErrorLogger.LogLoadingError(mod.Name, mod.modFile.tModLoaderVersion, e);
                Main.menuMode = Interface.errorMessageID;
                return(null);
            }
        }
Beispiel #5
0
        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();
            foreach (var mod in modInstances)
            {
                loadOrder.Push(mod.Name);
                mods[mod.Name] = mod;
            }

            return(true);
        }
Beispiel #6
0
        private static void do_Load(object threadContext)
        {
            if (!LoadMods())
            {
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            int num = 0;

            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressInit(mod.Name, num, mods.Count);
                try
                {
                    mod.Autoload();
                    mod.Load();
                }
                catch (Exception e)
                {
                    DisableMod(mod.file);
                    ErrorLogger.LogLoadingError(mod.file, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            Interface.loadMods.SetProgressSetup(0f);
            ResizeArrays();
            num = 0;
            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressLoad(mod.Name, num, mods.Count);
                try
                {
                    mod.SetupContent();
                }
                catch (Exception e)
                {
                    DisableMod(mod.file);
                    ErrorLogger.LogLoadingError(mod.file, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            Interface.loadMods.SetProgressRecipes();
            for (int k = 0; k < Recipe.maxRecipes; k++)
            {
                Main.recipe[k] = new Recipe();
            }
            Recipe.numRecipes = 0;
            try
            {
                CraftGroup.ResetVanillaGroups();
                AddCraftGroups();
                Recipe.SetupRecipes();
            }
            catch (Exception e)
            {
                ErrorLogger.LogLoadingError("recipes", e);
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            Main.menuMode = 0;
        }
Beispiel #7
0
        internal static void do_Load(object threadContext)
        {
            if (!LoadMods())
            {
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            if (Main.dedServ)
            {
                Console.WriteLine("Adding mod content...");
            }
            int num = 0;

            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressInit(mod.Name, num, mods.Count);
                try
                {
                    mod.loading = true;
                    mod.File?.Read(TmodFile.LoadedState.Streaming, mod.LoadResourceFromStream);
                    mod.Autoload();
                    Interface.loadMods.SetSubProgressInit("");
                    mod.Load();
                    mod.loading = false;
                }
                catch (Exception e)
                {
                    DisableMod(mod.Name);
                    ErrorLogger.LogLoadingError(mod.Name, mod.tModLoaderVersion, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            Interface.loadMods.SetProgressSetup(0f);
            ResizeArrays();
            RecipeGroupHelper.FixRecipeGroupLookups();
            num = 0;
            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressLoad(mod.Name, num, mods.Count);
                try
                {
                    mod.SetupContent();
                    mod.PostSetupContent();
                    mod.File?.UnloadAssets();
                }
                catch (Exception e)
                {
                    DisableMod(mod.Name);
                    ErrorLogger.LogLoadingError(mod.Name, mod.tModLoaderVersion, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            RefreshModLanguage(Language.ActiveCulture);

            if (Main.dedServ)
            {
                ModNet.AssignNetIDs();
                //Main.player[0] = new Player();
            }
            Main.player[255] = new Player(false);             // setup inventory is unnecessary

            MapLoader.SetupModMap();
            ItemSorting.SetupWhiteLists();

            Interface.loadMods.SetProgressRecipes();
            for (int k = 0; k < Recipe.maxRecipes; k++)
            {
                Main.recipe[k] = new Recipe();
            }
            Recipe.numRecipes = 0;
            RecipeGroupHelper.ResetRecipeGroups();
            try
            {
                Recipe.SetupRecipes();
            }
            catch (AddRecipesException e)
            {
                ErrorLogger.LogLoadingError(e.modName, version, e.InnerException, true);
                Main.menuMode = Interface.errorMessageID;
                return;
            }

            if (PostLoad != null)
            {
                PostLoad();
                PostLoad = null;
            }
            else
            {
                Main.menuMode = 0;
            }
            GameInput.PlayerInput.ReInitialize();
        }
Beispiel #8
0
        internal static void ReceiveMod(BinaryReader reader)
        {
            if (downloadingMod == null)
            {
                return;
            }

            try
            {
                if (downloadingFile == null)
                {
                    Interface.downloadMod.SetDownloading(reader.ReadString());
                    Interface.downloadMod.SetCancel(() =>
                    {
                        downloadingFile?.Close();
                        downloadingMod     = null;
                        Netplay.disconnect = true;
                        Main.menuMode      = 0;
                    });
                    Main.menuMode = Interface.downloadModID;

                    downloadingLength = reader.ReadInt64();
                    downloadingFile   = new FileStream(downloadingMod.path, FileMode.Create);
                    return;
                }

                var bytes = reader.ReadBytes((int)Math.Min(downloadingLength - downloadingFile.Position, CHUNK_SIZE));
                downloadingFile.Write(bytes, 0, bytes.Length);
                Interface.downloadMod.SetProgress(downloadingFile.Position, downloadingLength);

                if (downloadingFile.Position == downloadingLength)
                {
                    downloadingFile.Close();
                    var mod = new TmodFile(downloadingMod.path);
                    mod.Read();
                    var ex = mod.ValidMod();
                    if (ex != null)
                    {
                        throw ex;
                    }

                    if (!downloadingMod.Matches(mod))
                    {
                        throw new Exception("Hash mismatch");
                    }

                    if (downloadingMod.signed && !mod.ValidModBrowserSignature)
                    {
                        throw new Exception("Mod was not signed by the Mod Browser");
                    }

                    ModLoader.EnableMod(mod);

                    if (downloadQueue.Count > 0)
                    {
                        DownloadNextMod();
                    }
                    else
                    {
                        OnModsDownloaded(true);
                    }
                }
            }
            catch (Exception e)
            {
                try
                {
                    downloadingFile?.Close();
                }
                catch { }

                File.Delete(downloadingMod.path);
                ErrorLogger.LogException(e, "An error occured while downloading " + downloadingMod.name);
                downloadingMod = null;
            }
        }
Beispiel #9
0
        internal static void SyncClientMods(BinaryReader reader)
        {
            AllowVanillaClients = reader.ReadBoolean();

            Main.statusText = "Syncing Mods";
            var clientMods  = ModLoader.LoadedMods;
            var modFiles    = ModLoader.FindMods();
            var needsReload = false;

            downloadQueue.Clear();
            var syncSet     = new HashSet <string>();
            var blockedList = new List <ModHeader>();

            int n = reader.ReadInt32();

            for (int i = 0; i < n; i++)
            {
                var header = new ModHeader(reader.ReadString(), new Version(reader.ReadString()), reader.ReadBytes(20), reader.ReadBoolean());
                syncSet.Add(header.name);

                var clientMod = clientMods.SingleOrDefault(m => m.Name == header.name);
                if (clientMod != null)
                {
                    if (header.Matches(clientMod.File))
                    {
                        continue;
                    }

                    header.path = clientMod.File.path;
                }
                else
                {
                    var disabledVersions = modFiles.Where(m => m.name == header.name).ToArray();
                    var matching         = disabledVersions.FirstOrDefault(header.Matches);
                    if (matching != null)
                    {
                        ModLoader.EnableMod(matching);
                        needsReload = true;
                        continue;
                    }

                    if (disabledVersions.Length > 0)
                    {
                        header.path = disabledVersions[0].path;
                    }
                }

                if (downloadModsFromServers && (header.signed || !onlyDownloadSignedMods))
                {
                    downloadQueue.Enqueue(header);
                }
                else
                {
                    blockedList.Add(header);
                }
            }

            foreach (var mod in clientMods)
            {
                if (mod.Side == ModSide.Both && !syncSet.Contains(mod.Name))
                {
                    ModLoader.DisableMod(mod.File);
                    needsReload = true;
                }
            }

            if (blockedList.Count > 0)
            {
                var msg = "The following mods are installed on the server but cannot be downloaded ";
                msg += downloadModsFromServers
                                        ? "because you only accept mods signed by the mod browser"
                                        : "because you have disabled automatic mod downloading";
                msg += ".\nYou will need to change your settings or acquire the mods from the server owner.\n";
                foreach (var mod in blockedList)
                {
                    msg += "\n    " + mod;
                }

                ErrorLogger.LogMissingMods(msg);
                return;
            }

            if (downloadQueue.Count > 0)
            {
                DownloadNextMod();
            }
            else
            {
                OnModsDownloaded(needsReload);
            }
        }
Beispiel #10
0
        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();
            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
            {
                Interface.buildMod.SetCompiling(0);
                windowsData = CompileMod(modToBuild, properties, true);
                Interface.buildMod.SetCompiling(1);
                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(version);
                    writer.Write(propertiesData.Length);
                    writer.Write(propertiesData);
                    writer.Flush();
                    modFile.AddFile("Info", memoryStream.ToArray());
                }
            }
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(memoryStream))
                {
                    writer.Write(Path.GetFileName(modToBuild));
                    string[] resources = Directory.GetFiles(modToBuild, "*", SearchOption.AllDirectories);
                    foreach (string resource in resources)
                    {
                        if (properties.ignoreFile(resource.Replace(modToBuild + Path.DirectorySeparatorChar, null)))
                        {
                            continue;
                        }
                        if (Path.GetExtension(resource) == ".cs" && !properties.includeSource)
                        {
                            continue;
                        }
                        if (Path.GetFileName(resource) == "Thumbs.db")
                        {
                            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();
            WAVCacheIO.ClearCache(modFile.Name);
            EnableMod(file);
            if (!buildAll)
            {
                Main.menuMode = reloadAfterBuild ? Interface.reloadModsID : 0;
            }
            return(true);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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, properties[modsToLoad[k].Name].modBuildVersion, 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);
        }
Beispiel #13
0
        internal static void do_Load(object threadContext)
        {
            if (!LoadMods())
            {
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            if (Main.dedServ)
            {
                Console.WriteLine("Adding mod content...");
            }
            int num = 0;

            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressInit(mod.Name, num, mods.Count);
                try
                {
                    mod.Autoload();
                    mod.Load();
                }
                catch (Exception e)
                {
                    DisableMod(mod.file);
                    ErrorLogger.LogLoadingError(mod.file, mod.buildVersion, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            Interface.loadMods.SetProgressSetup(0f);
            ResizeArrays();
            num = 0;
            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressLoad(mod.Name, num, mods.Count);
                try
                {
                    mod.SetupContent();
                    mod.PostSetupContent();
                }
                catch (Exception e)
                {
                    DisableMod(mod.file);
                    ErrorLogger.LogLoadingError(mod.file, mod.buildVersion, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            MapLoader.SetupModMap();
            Interface.loadMods.SetProgressRecipes();
            for (int k = 0; k < Recipe.maxRecipes; k++)
            {
                Main.recipe[k] = new Recipe();
            }
            Recipe.numRecipes = 0;
            try
            {
                CraftGroup.ResetVanillaGroups();
                AddCraftGroups();
                Recipe.SetupRecipes();
            }
            catch (Exception e)
            {
                ErrorLogger.LogLoadingError("recipes", version, e);
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            Main.menuMode = 0;
            numLoads++;
        }
Beispiel #14
0
        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 List <Mod> InstantiateMods(List <ModLoader.LoadingMod> modsToLoad)
        {
            var modList = new List <LoadedMod>();

            foreach (var loading in modsToLoad)
            {
                LoadedMod mod;
                if (!loadedMods.TryGetValue(loading.Name, out mod))
                {
                    mod = loadedMods[loading.Name] = new LoadedMod();
                }

                mod.SetMod(loading);
                modList.Add(mod);
            }

            RecalculateReferences();

            if (Debugger.IsAttached)
            {
                ModLoader.isModder = true;
                foreach (var mod in modList.Where(mod => mod.properties.editAndContinue && mod.CanEaC))
                {
                    mod.EnableEaC();
                }
            }
            if (ModLoader.alwaysLogExceptions)
            {
                ModCompile.ActivateExceptionReporting();
            }

            var modInstances = new List <Mod>();

            int i = 0;

            foreach (var mod in modList)
            {
                Interface.loadMods.SetProgressCompatibility(mod.Name, i++, modsToLoad.Count);
                try {
                    Interface.loadMods.SetProgressReading(mod.Name, 0, 1);
                    mod.LoadAssemblies();

                    Interface.loadMods.SetProgressReading(mod.Name, 1, 2);
                    Type modType;
                    try
                    {
                        modType = mod.assembly.GetTypes().Single(t => t.IsSubclassOf(typeof(Mod)));
                    }
                    catch (Exception e)
                    {
                        throw new Exception("It looks like this mod doesn't have a class extending Mod. Mods need a Mod class to function.", e)
                              {
                                  HelpLink = "https://github.com/blushiemagic/tModLoader/wiki/Basic-tModLoader-Modding-FAQ#sequence-contains-no-matching-element-error"
                              };
                    }
                    var m = (Mod)Activator.CreateInstance(modType);
                    m.File        = mod.modFile;
                    m.Code        = mod.assembly;
                    m.Side        = mod.properties.side;
                    m.DisplayName = mod.properties.displayName;
                    modInstances.Add(m);
                }
                catch (Exception e) {
                    ModLoader.DisableMod(mod.modFile);
                    ErrorLogger.LogLoadingError(mod.Name, mod.modFile.tModLoaderVersion, e);
                    return(null);
                }
            }

            return(modInstances);
        }
Beispiel #16
0
        private static void CompileMod(BuildingMod mod, List <LoadingMod> refMods, bool forWindows,
                                       ref byte[] dll, ref byte[] pdb)
        {
            LoadReferences();
            var  terrariaModule = Assembly.GetExecutingAssembly();
            bool generatePDB    = mod.properties.includePDB && forWindows;

            if (generatePDB && !windows)
            {
                Console.WriteLine("PDB files can only be generated for windows, on windows.");
                generatePDB = false;
            }

            var refs = new List <string>(terrariaReferences);

            if (forWindows == windows)
            {
                refs.Add(terrariaModule.Location);
            }
            else
            {
                refs = refs.Where(path => {
                    var name = Path.GetFileName(path);
                    return(name != "FNA.dll" && !name.StartsWith("Microsoft.Xna.Framework"));
                }).ToList();
                var names = forWindows
                    ? new[] {
                    "tModLoaderWindows.exe",
                    "Microsoft.Xna.Framework.dll",
                    "Microsoft.Xna.Framework.Game.dll",
                    "Microsoft.Xna.Framework.Graphics.dll",
                    "Microsoft.Xna.Framework.Xact.dll"
                }
                    : new[] {
                    "tModLoaderMac.exe",
                    "FNA.dll"
                };
                refs.AddRange(names.Select(f => Path.Combine(modCompileDir, f)));
            }

            refs.AddRange(mod.properties.dllReferences.Select(refDll => Path.Combine(mod.path, "lib/" + refDll + ".dll")));

            var tempDir = Path.Combine(ModPath, "compile_temp");

            Directory.CreateDirectory(tempDir);

            foreach (var resName in terrariaModule.GetManifestResourceNames().Where(n => n.EndsWith(".dll")))
            {
                var path = Path.Combine(tempDir, Path.GetFileName(resName));
                using (Stream res = terrariaModule.GetManifestResourceStream(resName), file = File.Create(path))
                    res.CopyTo(file);

                refs.Add(path);
            }

            foreach (var refMod in refMods)
            {
                var path = Path.Combine(tempDir, refMod.Name + ".dll");
                File.WriteAllBytes(path, refMod.modFile.GetMainAssembly(forWindows));
                refs.Add(path);

                foreach (var refDll in refMod.properties.dllReferences)
                {
                    path = Path.Combine(tempDir, refDll + ".dll");
                    File.WriteAllBytes(path, refMod.modFile.GetFile("lib/" + refDll + ".dll"));
                    refs.Add(path);
                }
            }

            var compileOptions = new CompilerParameters {
                OutputAssembly          = Path.Combine(tempDir, mod.Name + ".dll"),
                GenerateExecutable      = false,
                GenerateInMemory        = false,
                TempFiles               = new TempFileCollection(tempDir, true),
                IncludeDebugInformation = generatePDB
            };

            compileOptions.ReferencedAssemblies.AddRange(refs.ToArray());
            var files = Directory.GetFiles(mod.path, "*.cs", SearchOption.AllDirectories);

            try {
                CompilerResults results;
                if (mod.properties.languageVersion == 6)
                {
                    if (Environment.Version.Revision < 10000)
                    {
                        ErrorLogger.LogBuildError(".NET Framework 4.5 must be installed to compile C# 6.0");
                        return;
                    }

                    results = RoslynCompile(compileOptions, files);
                }
                else
                {
                    var options = new Dictionary <string, string> {
                        { "CompilerVersion", "v" + mod.properties.languageVersion + ".0" }
                    };
                    results = new CSharpCodeProvider(options).CompileAssemblyFromFile(compileOptions, files);
                }

                if (results.Errors.HasErrors)
                {
                    ErrorLogger.LogCompileErrors(results.Errors);
                    return;
                }

                dll = File.ReadAllBytes(compileOptions.OutputAssembly);
                if (generatePDB)
                {
                    pdb = File.ReadAllBytes(Path.Combine(tempDir, mod.Name + ".pdb"));
                }
            }
            finally {
                int numTries = 10;
                while (numTries > 0)
                {
                    try {
                        Directory.Delete(tempDir, true);
                        numTries = 0;
                    }
                    catch {
                        System.Threading.Thread.Sleep(1);
                        numTries--;
                    }
                }
            }
        }
Beispiel #17
0
        internal static void do_Load(object threadContext)
        {
            if (!LoadMods())
            {
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            if (Main.dedServ)
            {
                Console.WriteLine("Adding mod content...");
            }
            int num = 0;

            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressInit(mod.Name, num, mods.Count);
                try
                {
                    mod.Autoload();
                    mod.Load();
                }
                catch (Exception e)
                {
                    DisableMod(mod.File);
                    ErrorLogger.LogLoadingError(mod.Name, mod.tModLoaderVersion, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }
            Interface.loadMods.SetProgressSetup(0f);
            ResizeArrays();
            num = 0;
            foreach (Mod mod in mods.Values)
            {
                Interface.loadMods.SetProgressLoad(mod.Name, num, mods.Count);
                try
                {
                    mod.SetupContent();
                    mod.PostSetupContent();
                }
                catch (Exception e)
                {
                    DisableMod(mod.File);
                    ErrorLogger.LogLoadingError(mod.Name, mod.tModLoaderVersion, e);
                    Main.menuMode = Interface.errorMessageID;
                    return;
                }
                num++;
            }

            if (Main.dedServ)
            {
                ModNet.AssignNetIDs();
            }

            MapLoader.SetupModMap();
            ItemSorting.SetupWhiteLists();

            Interface.loadMods.SetProgressRecipes();
            for (int k = 0; k < Recipe.maxRecipes; k++)
            {
                Main.recipe[k] = new Recipe();
            }
            Recipe.numRecipes = 0;
            RecipeGroupHelper.ResetRecipeGroups();
            try
            {
                Recipe.SetupRecipes();
            }
            catch (AddRecipesException e)
            {
                ErrorLogger.LogLoadingError(e.modName, version, e.InnerException, true);
                Main.menuMode = Interface.errorMessageID;
                return;
            }
            if (PostLoad != null)
            {
                PostLoad();
                PostLoad = null;
            }
            else
            {
                Main.menuMode = 0;
            }
            GameInput.PlayerInput.ReInitialize();
        }
Beispiel #18
0
        internal static void SyncClientMods(BinaryReader reader)
        {
            AllowVanillaClients = reader.ReadBoolean();

            Main.statusText = Language.GetTextValue("tModLoader.MPSyncingMods");
            var clientMods  = ModLoader.Mods;
            var modFiles    = ModOrganizer.FindMods();
            var needsReload = false;

            downloadQueue.Clear();
            var syncSet     = new HashSet <string>();
            var blockedList = new List <ModHeader>();

            int n = reader.ReadInt32();

            for (int i = 0; i < n; i++)
            {
                var header = new ModHeader(reader.ReadString(), new Version(reader.ReadString()), reader.ReadBytes(20), reader.ReadBoolean());
                syncSet.Add(header.name);

                var clientMod = clientMods.SingleOrDefault(m => m.Name == header.name);
                if (clientMod != null)
                {
                    if (header.Matches(clientMod.File))
                    {
                        continue;
                    }

                    header.path = clientMod.File.path;
                }
                else
                {
                    var disabledVersions = modFiles.Where(m => m.Name == header.name).ToArray();
                    var matching         = disabledVersions.FirstOrDefault(mod => header.Matches(mod.modFile));
                    if (matching != null)
                    {
                        matching.Enabled = true;
                        needsReload      = true;
                        continue;
                    }

                    if (disabledVersions.Length > 0)
                    {
                        header.path = disabledVersions[0].modFile.path;
                    }
                }

                if (downloadModsFromServers && (header.signed || !onlyDownloadSignedMods))
                {
                    downloadQueue.Enqueue(header);
                }
                else
                {
                    blockedList.Add(header);
                }
            }

            foreach (var mod in clientMods)
            {
                if (mod.Side == ModSide.Both && !syncSet.Contains(mod.Name))
                {
                    ModLoader.DisableMod(mod.Name);
                    needsReload = true;
                }
            }

            if (blockedList.Count > 0)
            {
                var msg = Language.GetTextValue("tModLoader.MPServerModsCantDownload");
                msg += downloadModsFromServers
                                        ? Language.GetTextValue("tModLoader.MPServerModsCantDownloadReasonSigned")
                                        : Language.GetTextValue("tModLoader.MPServerModsCantDownloadReasonAutomaticDownloadDisabled");
                msg += ".\n" + Language.GetTextValue("tModLoader.MPServerModsCantDownloadChangeSettingsHint") + "\n";
                foreach (var mod in blockedList)
                {
                    msg += "\n    " + mod;
                }

                ErrorLogger.LogMissingMods(msg);
                return;
            }

            if (downloadQueue.Count > 0)
            {
                DownloadNextMod();
            }
            else
            {
                OnModsDownloaded(needsReload);
            }
        }