private void FindReferencedMods(BuildProperties properties, Dictionary <string, LocalMod> mods, bool requireWeak) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) { continue; } bool isWeak = properties.weakReferences.Any(r => r.mod == refName); LocalMod mod; try { var modFile = new TmodFile(Path.Combine(ModPath, refName + ".tmod")); modFile.Read(); mod = new LocalMod(modFile); modFile.Close(); } catch (FileNotFoundException) when(isWeak && !requireWeak) { // don't recursively require weak deps, if the mod author needs to compile against them, they'll have them installed continue; } catch (Exception ex) { throw new Exception(Language.GetTextValue("tModLoader.BuildErrorModReference", refName), ex); } mods[refName] = mod; FindReferencedMods(mod.properties, mods, false); } }
internal static 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()); }
private static bool FindReferencedMods(BuildProperties properties, Dictionary <string, LocalMod> mods) { foreach (var refName in properties.RefNames(true)) { if (mods.ContainsKey(refName)) { continue; } var modFile = new TmodFile(Path.Combine(ModPath, refName + ".tmod")); try { modFile.Read(TmodFile.LoadedState.Code); } catch (Exception ex) { ErrorLogger.LogBuildError("Mod reference " + refName + " " + ex); return(false); } var mod = new LocalMod(modFile); mods[refName] = mod; FindReferencedMods(mod.properties, mods); } return(true); }
private 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); } }
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; }
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()); }
// 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); }