// 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); }
// Receive a mod when connecting to server internal static void ReceiveMod(BinaryReader reader) { if (downloadingMod == null) { return; } try { if (downloadingFile == null) { Interface.progress.Show(displayText: reader.ReadString(), cancel: CancelDownload); ModLoader.GetMod(downloadingMod.name)?.Close(); 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.progress.Progress = downloadingFile.Position / (float)downloadingLength; if (downloadingFile.Position == downloadingLength) { downloadingFile.Close(); var mod = new TmodFile(downloadingMod.path); using (mod.Open()) { } if (!downloadingMod.Matches(mod)) { throw new Exception(Language.GetTextValue("tModLoader.MPErrorModHashMismatch")); } if (downloadingMod.signed && !mod.ValidModBrowserSignature) { throw new Exception(Language.GetTextValue("tModLoader.MPErrorModNotSigned")); } ModLoader.EnableMod(mod.name); if (downloadQueue.Count > 0) { DownloadNextMod(); } else { OnModsDownloaded(true); } } } catch (Exception e) { try { downloadingFile?.Close(); File.Delete(downloadingMod.path); } catch (Exception exc2) { Logging.tML.Error("Unknown error during mod sync", exc2); } var msg = Language.GetTextValue("tModLoader.MPErrorModDownloadError", downloadingMod.name); Logging.tML.Error(msg, e); Interface.errorMessage.Show(msg + e, 0); Netplay.disconnect = true; downloadingMod = null; } }
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); } }
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(TmodFile.LoadedState.Info); if (!downloadingMod.Matches(mod)) { throw new Exception(Language.GetTextValue("tModLoader.MPErrorModHashMismatch")); } if (downloadingMod.signed && !mod.ValidModBrowserSignature) { throw new Exception(Language.GetTextValue("tModLoader.MPErrorModNotSigned")); } ModLoader.EnableMod(mod.name); if (downloadQueue.Count > 0) { DownloadNextMod(); } else { OnModsDownloaded(true); } } } catch (Exception e) { try { downloadingFile?.Close(); } catch { } File.Delete(downloadingMod.path); ErrorLogger.LogException(e, Language.GetTextValue("tModLoader.MPErrorModDownloadError", downloadingMod.name)); downloadingMod = null; } }
internal static void ReceiveMod(BinaryReader reader) { if (downloadingMod == null) { return; } try { if (downloadingFile == null) { // TODO migrate to download UI, create new StreamingDownloadRequest // TODO I hope this works fine without UI for the moment... //Interface.downloadMod.SetDownloading(reader.ReadString()); //Interface.downloadMod.SetCancel(CancelDownload); Main.menuMode = Interface.downloadModID; ModLoader.GetMod(downloadingMod.name)?.File?.Close(); 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(); mod.Close(); if (!downloadingMod.Matches(mod)) { throw new Exception(Language.GetTextValue("tModLoader.MPErrorModHashMismatch")); } if (downloadingMod.signed && !mod.ValidModBrowserSignature) { throw new Exception(Language.GetTextValue("tModLoader.MPErrorModNotSigned")); } ModLoader.EnableMod(mod.name); if (downloadQueue.Count > 0) { DownloadNextMod(); } else { OnModsDownloaded(true); } } } catch (Exception e) { try { downloadingFile?.Close(); File.Delete(downloadingMod.path); } catch { } var msg = Language.GetTextValue("tModLoader.MPErrorModDownloadError", downloadingMod.name); Logging.tML.Error(msg, e); Interface.errorMessage.Show(msg + e, 0); Netplay.disconnect = true; downloadingMod = null; } }
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); } }
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); }