Beispiel #1
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.
                int i = 0;
                Parallel.ForEach(modList, mod =>
                {
                    Interface.loadMods.SetProgressCompatibility(mod.Name, i++, modsToLoad.Count);
                    mod.LoadAssemblies();
                });

                //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);
                })));
                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);
                return(null);
            }
        }
        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)
            {
                foreach (var mod in modList.Where(mod => mod.properties.editAndContinue && mod.CanEaC))
                {
                    mod.EnableEaC();
                }
            }

            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);
                    var modType = mod.assembly.GetTypes().Single(t => t.IsSubclassOf(typeof(Mod)));
                    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 #3
0
 internal static void PostAddRecipes()
 {
     foreach (Mod mod in ModLoader.mods.Values)
     {
         try
         {
             mod.PostAddRecipes();
         }
         catch (Exception e)
         {
             ModLoader.DisableMod(mod.Name);
             throw new AddRecipesException(mod, "An error occured after adding recipes for " + mod.Name, e);
         }
     }
 }
 internal static void AddRecipeGroups()
 {
     foreach (Mod mod in ModLoader.mods.Values)
     {
         try
         {
             mod.AddRecipeGroups();
         }
         catch (Exception e)
         {
             ModLoader.DisableMod(mod.File);
             throw new AddRecipesException(mod, "An error occured in adding recipe groups for " + mod.Name, e);
         }
     }
 }
Beispiel #5
0
        internal static bool Load()
        {
            try
            {
                Interface.loadMods.SetLoadStage("tModLoader.MSIntializing", ModLoader.Mods.Length);
                LoadModContent(mod => {
                    mod.loading = true;
                    mod.File?.Read(TmodFile.LoadedState.Streaming, mod.LoadResourceFromStream);
                    mod.Autoload();
                    mod.Load();
                    mod.loading = false;
                });

                Interface.loadMods.SetLoadStage("tModLoader.MSSettingUp");
                ResizeArrays();
                RecipeGroupHelper.FixRecipeGroupLookups();

                Interface.loadMods.SetLoadStage("tModLoader.MSLoading", ModLoader.Mods.Length);
                LoadModContent(mod => {
                    mod.SetupContent();
                    mod.PostSetupContent();
                    mod.File?.UnloadAssets();
                });

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

                Main.player[255] = new Player(false);                 // setup inventory is unnecessary

                RefreshModLanguage(Language.ActiveCulture);
                MapLoader.SetupModMap();
                ItemSorting.SetupWhiteLists();
                PlayerInput.ReInitialize();
                SetupRecipes();
                return(true);
            }
            catch (LoadingException e)
            {
                ModLoader.DisableMod(e.mod.Name);
                ErrorLogger.LogLoadingError(e.mod.Name, e.mod.Version, e.InnerException, e is AddRecipesException);
                Main.menuMode = Interface.errorMessageID;
                return(false);
            }
        }
Beispiel #6
0
 internal static void AddRecipes()
 {
     foreach (Mod mod in ModLoader.mods.Values)
     {
         try
         {
             mod.AddRecipes();
             foreach (ModItem item in mod.items.Values)
             {
                 item.AddRecipes();
             }
         }
         catch (Exception e)
         {
             ModLoader.DisableMod(mod.Name);
             throw new AddRecipesException(mod, "An error occured in adding recipes for " + mod.Name, e);
         }
     }
 }
Beispiel #7
0
 //in Terraria.Item.SetDefaults get rid of type-too-high check
 //add near end of Terraria.Item.SetDefaults after setting netID
 //in Terraria.Item.SetDefaults move Lang stuff before SetupItem
 internal static void SetupItem(Item item)
 {
     if (IsModItem(item))
     {
         GetItem(item.type).SetupItem(item);
     }
     foreach (GlobalItem globalItem in globalItems)
     {
         try
         {
             globalItem.SetDefaults(item);
         }
         catch
         {
             ModLoader.DisableMod(globalItem.mod.file);
             throw;
         }
     }
 }
Beispiel #8
0
        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)
            {
                foreach (var mod in modList.Where(mod => mod.properties.editAndContinue && mod.CanEaC))
                {
                    mod.EnableEaC();
                }
            }

            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/bluemagic123/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 #9
0
        // This method is split so that the local variables aren't held by the GC when reloading
        internal static bool SyncClientMods(BinaryReader reader, out bool needsReload)
        {
            AllowVanillaClients = reader.ReadBoolean();
            Logging.tML.Info($"Server reports AllowVanillaClients set to {AllowVanillaClients}");

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

            needsReload = false;
            downloadQueue.Clear();
            pendingConfigs.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);

                int configCount = reader.ReadInt32();
                for (int c = 0; c < configCount; c++)
                {
                    pendingConfigs.Add(new NetConfig(header.name, reader.ReadString(), reader.ReadString()));
                }

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

                needsReload = true;

                var localVersions = modFiles.Where(m => m.Name == header.name).ToArray();
                var matching      = Array.Find(localVersions, mod => header.Matches(mod.modFile));
                if (matching != null)
                {
                    matching.Enabled = true;
                    continue;
                }

                // overwrite an existing version of the mod if there is one
                if (localVersions.Length > 0)
                {
                    header.path = localVersions[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;
                }

                Logging.tML.Warn(msg);
                Interface.errorMessage.Show(msg, 0);
                return(false);
            }

            // ready to connect, apply configs. Config manager will apply the configs on reload automatically
            if (!needsReload)
            {
                foreach (var pendingConfig in pendingConfigs)
                {
                    JsonConvert.PopulateObject(pendingConfig.json, ConfigManager.GetConfig(pendingConfig), ConfigManager.serializerSettingsCompact);
                }

                if (ConfigManager.AnyModNeedsReload())
                {
                    needsReload = true;
                }
                else
                {
                    foreach (var pendingConfig in pendingConfigs)
                    {
                        ConfigManager.GetConfig(pendingConfig).OnChanged();
                    }
                }
            }

            return(true);
        }
Beispiel #10
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;
                }

                Logging.tML.Warn(msg);
                Interface.errorMessage.SetMessage(msg);
                Interface.errorMessage.SetGotoMenu(0);
                Main.gameMenu = true;
                Main.menuMode = Interface.errorMessageID;
                return;
            }

            if (downloadQueue.Count > 0)
            {
                DownloadNextMod();
            }
            else
            {
                OnModsDownloaded(needsReload);
            }
        }
Beispiel #11
0
        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]));
                        }
                    }
                }
            }
        }
Beispiel #12
0
        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]));
                        }
                    }
                }
            }
        }
Beispiel #13
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);
            }
        }