Пример #1
0
        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);
            }
        }
Пример #2
0
        internal static LocalMod[] FindMods()
        {
            Directory.CreateDirectory(ModPath);
            var mods = new List <LocalMod>();

            foreach (string fileName in Directory.GetFiles(ModPath, "*.tmod", SearchOption.TopDirectoryOnly))
            {
                var lastModified = File.GetLastWriteTime(fileName);
                if (!modsDirCache.TryGetValue(fileName, out var mod) || mod.lastModified != lastModified)
                {
                    var modFile = new TmodFile(fileName);
                    try
                    {
                        modFile.Read(TmodFile.LoadedState.Info);
                    }
                    catch (Exception e)                     //this will probably spam, given the number of calls to FindMods
                    {
                        ErrorLogger.LogException(e, Language.GetTextValue("tModLoader.LoadErrorErrorReadingModFile", modFile.path));
                        continue;
                    }

                    mod = new LocalMod(modFile)
                    {
                        lastModified = lastModified
                    };
                    modsDirCache[fileName] = mod;
                }
                mods.Add(mod);
            }
            return(mods.OrderBy(x => x.Name, StringComparer.InvariantCulture).ToArray());
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
            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;
            }
Пример #6
0
        internal static Dictionary <string, List <string> > dependencyCache;    // for some internal features that need to lookup dependencies after load

        internal static LocalMod[] FindMods()
        {
            Directory.CreateDirectory(ModLoader.ModPath);
            var mods = new List <LocalMod>();

            foreach (string fileName in Directory.GetFiles(ModLoader.ModPath, "*.tmod", SearchOption.TopDirectoryOnly))
            {
                if (Path.GetFileName(fileName) == "temporaryDownload.tmod")
                {
                    continue;
                }
                var lastModified = File.GetLastWriteTime(fileName);
                if (!modsDirCache.TryGetValue(fileName, out var mod) || mod.lastModified != lastModified)
                {
                    try
                    {
                        var modFile = new TmodFile(fileName);
                        modFile.Read();
                        modFile.VerifyCoreFiles();
                        mod = new LocalMod(modFile)
                        {
                            lastModified = lastModified
                        };
                        modFile.Close();
                    }
                    catch (Exception e)
                    {
                        if (!readFailures.Contains(fileName))
                        {
                            Logging.tML.Warn("Failed to read " + fileName, e);
                        }
                        else
                        {
                            readFailures.Add(fileName);
                        }
                        continue;
                    }
                    modsDirCache[fileName] = mod;
                }
                mods.Add(mod);
            }
            return(mods.OrderBy(x => x.Name, StringComparer.InvariantCulture).ToArray());
        }
Пример #7
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");
            Mod[]      clientMods = ModLoader.Mods;
            LocalMod[] 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()));
                }

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

                needsReload = true;

                LocalMod[] localVersions = modFiles.Where(m => m.Name == header.name).ToArray();
                LocalMod   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 (Mod mod in clientMods)
            {
                if (mod.Side == ModSide.Both && !syncSet.Contains(mod.Name))
                {
                    ModLoader.DisableMod(mod.Name);
                    needsReload = true;
                }
            }

            if (blockedList.Count > 0)
            {
                string msg = Language.GetTextValue("tModLoader.MPServerModsCantDownload");
                msg += downloadModsFromServers
                                        ? Language.GetTextValue("tModLoader.MPServerModsCantDownloadReasonSigned")
                                        : Language.GetTextValue("tModLoader.MPServerModsCantDownloadReasonAutomaticDownloadDisabled");
                msg += ".\n" + Language.GetTextValue("tModLoader.MPServerModsCantDownloadChangeSettingsHint") + "\n";
                foreach (ModHeader 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 (NetConfig pendingConfig in pendingConfigs)
                {
                    JsonConvert.PopulateObject(pendingConfig.json, ConfigManager.GetConfig(pendingConfig), ConfigManager.serializerSettingsCompact);
                }

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

            return(true);
        }