1using Microsoft.Xna.Framework.Audio;
 
    2using Microsoft.Xna.Framework.Graphics;
 
    5using System.Collections.Generic;
 
    6using System.Diagnostics;
 
    8using System.Linq.Expressions;
 
    9using System.Reflection;
 
   10using System.Security.Cryptography;
 
   11using System.Threading;
 
   12using System.Threading.Tasks;
 
   13using System.Windows.Forms;
 
   15using Terraria.Localization;
 
   17using Terraria.ModLoader.Core;
 
   18using Terraria.ModLoader.Default;
 
   19using Terraria.ModLoader.Engine;
 
   20using Terraria.ModLoader.UI;
 
   38        public static readonly 
int beta = 0;
 
   41        public static readonly 
string versionedName = $
"tModLoader v{version}" +
 
   42                                                      (branchName.Length == 0 ? 
"" : $
" {branchName}") +
 
   43                                                      (
beta == 0 ? 
"" : $
" Beta {beta}");
 
   45        public static readonly 
string versionTag = $
"v{version}" +
 
   46                                                    (branchName.Length == 0 ? 
"" : $
"-{branchName.ToLower()}") +
 
   47                                                    (
beta == 0 ? 
"" : $
"-beta{beta}");
 
   49        [Obsolete(
"Use Platform.IsWindows")]
 
   50        public static readonly 
bool windows = Platform.IsWindows;
 
   51        [Obsolete(
"Use Platform.IsLinux")]
 
   52        public static readonly 
bool linux = Platform.IsLinux;
 
   53        [Obsolete(
"Use Platform.IsOSX")]
 
   54        public static readonly 
bool mac = Platform.IsOSX;
 
   56        [Obsolete(
"Use CompressedPlatformRepresentation instead")]
 
   61        public static string ModPath => ModOrganizer.modPath;
 
   63        private static readonly IDictionary<string, Mod> 
modsByName = 
new Dictionary<string, Mod>(StringComparer.OrdinalIgnoreCase);
 
   66        internal static readonly 
string modBrowserPublicKey = 
"<RSAKeyValue><Modulus>oCZObovrqLjlgTXY/BKy72dRZhoaA6nWRSGuA+aAIzlvtcxkBK5uKev3DZzIj0X51dE/qgRS3OHkcrukqvrdKdsuluu0JmQXCv+m7sDYjPQ0E6rN4nYQhgfRn2kfSvKYWGefp+kqmMF9xoAq666YNGVoERPm3j99vA+6EIwKaeqLB24MrNMO/TIf9ysb0SSxoV8pC/5P/N6ViIOk3adSnrgGbXnFkNQwD0qsgOWDks8jbYyrxUFMc4rFmZ8lZKhikVR+AisQtPGUs3ruVh4EWbiZGM2NOkhOCOM4k1hsdBOyX2gUliD0yjK5tiU3LBqkxoi2t342hWAkNNb4ZxLotw==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
 
   67        internal static string modBrowserPassphrase = 
"";
 
   70        internal static string SteamID64 {
 
   71            get => InstallVerifier.IsGoG ? 
steamID64 : Steamworks.SteamUser.GetSteamID().ToString();
 
   75        internal static bool autoReloadAndEnableModsLeavingModBrowser = 
true;
 
   76        internal static bool dontRemindModBrowserUpdateReload;
 
   77        internal static bool dontRemindModBrowserDownloadEnable;
 
   78        internal static bool removeForcedMinimumZoom;
 
   79        internal static bool showMemoryEstimates = 
true;
 
   81        internal static bool skipLoad;
 
   83        internal static Action OnSuccessfulLoad;
 
   85        public static Mod[] 
Mods { 
get; 
private set; } = 
new Mod[0];
 
   96        public static Mod GetMod(
int index) => index >= 0 && index < Mods.Length ? 
Mods[index] : 
null;
 
   98        [Obsolete(
"Use ModLoader.Mods", 
true)]
 
  101        [Obsolete(
"Use ModLoader.Mods.Length", 
true)]
 
  104        [Obsolete(
"Use ModLoader.Mods.Select(m => m.Name)", 
true)]
 
  107        internal static void EngineInit()
 
  110            FileAssociationSupport.UpdateFileAssociation();
 
  112            HiDefGraphicsIssues.Init();
 
  114            ZipExtractFix.Init();
 
  117        internal static void BeginLoad(CancellationToken token) => Task.Run(() => 
Load(token));
 
  120        private static void Load(CancellationToken token = 
default)
 
  124                    throw new Exception(
"Load called twice");
 
  130                var modInstances = ModOrganizer.LoadMods(token);
 
  133                modInstances.Insert(0, 
new ModLoaderMod());
 
  134                Mods = modInstances.ToArray();
 
  135                foreach (var mod 
in Mods)
 
  140                if (OnSuccessfulLoad != 
null) {
 
  147            catch when (token.IsCancellationRequested) {
 
  150                OnSuccessfulLoad += () => Main.menuMode = Interface.modsMenuID;
 
  156                var responsibleMods = 
new List<string>();
 
  157                if (e.Data.Contains(
"mod"))
 
  158                    responsibleMods.Add((
string)e.Data[
"mod"]);
 
  159                if (e.Data.Contains(
"mods"))
 
  161                responsibleMods.Remove(
"ModLoader");
 
  163                if (responsibleMods.Count == 0 && AssemblyManager.FirstModInStackTrace(
new StackTrace(e), out var stackMod))
 
  164                    responsibleMods.Add(stackMod);
 
  166                var msg = Language.GetTextValue(
"tModLoader.LoadError", 
string.Join(
", ", responsibleMods));
 
  167                if (responsibleMods.Count == 1) {
 
  168                    var mod = ModOrganizer.FindMods().FirstOrDefault(m => m.Name == responsibleMods[0]); 
 
  169                    if (mod != 
null && (mod.tModLoaderVersion.Major != 
version.Major || mod.tModLoaderVersion.Minor != 
version.Minor || mod.tModLoaderVersion.Build != 
version.Build))
 
  170                        msg += 
"\n" + Language.GetTextValue(
"tModLoader.LoadErrorVersionMessage", mod.tModLoaderVersion, 
versionedName);
 
  172                if (responsibleMods.Count > 0)
 
  173                    msg += 
"\n" + Language.GetTextValue(
"tModLoader.LoadErrorDisabled");
 
  175                    msg += 
"\n" + Language.GetTextValue(
"tModLoader.LoadErrorCulpritUnknown");
 
  177                if (e is ReflectionTypeLoadException reflectionTypeLoadException)
 
  178                    msg += 
"\n\n" + 
string.Join(
"\n", reflectionTypeLoadException.LoaderExceptions.Select(x => x.Message));
 
  182                foreach (var mod 
in responsibleMods)
 
  186                DisplayLoadError(msg, e, e.Data.Contains(
"fatal"), responsibleMods.Count == 0);
 
  190                OnSuccessfulLoad = 
null;
 
  192                ModNet.NetReloadActive = 
false;
 
  201            var msg = Language.GetTextValue(
"tModLoader.LoadErrorDotNet45Required");
 
  203            Interface.MessageBoxShow(msg);
 
  204            Process.Start(
"https://dotnet.microsoft.com/download/dotnet-framework");
 
  206            Console.ForegroundColor = ConsoleColor.Red;
 
  209            Console.WriteLine(
"Press any key to exit...");
 
  215        internal static void Reload()
 
  220                Main.menuMode = Interface.loadModsID;
 
  232                var msg = Language.GetTextValue(
"tModLoader.UnloadError");
 
  234                if (e.Data.Contains(
"mod"))
 
  235                    msg += 
"\n" + Language.GetTextValue(
"tModLoader.DefensiveUnload", e.Data[
"mod"]);
 
  246            Logging.tML.Info(
"Unloading mods");
 
  248                Console.WriteLine(
"Unloading mods...");
 
  251                Interface.loadMods.SetLoadStage(
"tModLoader.MSUnloading", 
Mods.Length);
 
  259            MemoryTracking.Clear();
 
  260            Thread.MemoryBarrier();
 
  264        internal static List<string> badUnloaders = 
new List<string>();
 
  267            badUnloaders = 
weakModReferences.Where(r => r.IsAlive).Select(r => ((
Mod)r.Target).Name).ToList();
 
  268            foreach (var modName 
in badUnloaders)
 
  269                Logging.tML.WarnFormat(
"{0} not fully unloaded during unload.", modName);
 
  274            msg += 
"\n\n" + (e.Data.Contains(
"hideStackTrace") ? e.Message : e.ToString());
 
  277                Console.ForegroundColor = ConsoleColor.Red;
 
  282                    Console.WriteLine(
"Press any key to exit...");
 
  291                Interface.errorMessage.Show(msg,
 
  292                    gotoMenu: fatal ? -1 : Interface.reloadModsID,
 
  293                    webHelpURL: e.HelpLink,
 
  294                    continueIsRetry: continueIsRetry,
 
  300        public static bool IsSignedBy(TmodFile mod, 
string xmlPublicKey)
 
  302            var f = 
new RSAPKCS1SignatureDeformatter();
 
  303            var v = AsymmetricAlgorithm.Create(
"RSA");
 
  304            f.SetHashAlgorithm(
"SHA1");
 
  305            v.FromXmlString(xmlPublicKey);
 
  307            return f.VerifySignature(mod.hash, mod.signature);
 
  312        internal static bool PauseSavingEnabledMods {
 
  317                    ModOrganizer.SaveEnabledMods();
 
  327        internal static bool IsEnabled(
string modName) => EnabledMods.Contains(modName);
 
  328        internal static void EnableMod(
string modName) => SetModEnabled(modName, 
true);
 
  329        internal static void DisableMod(
string modName) => SetModEnabled(modName, 
false);
 
  330        internal static void SetModEnabled(
string modName, 
bool active)
 
  333                EnabledMods.Add(modName);
 
  334                Logging.tML.InfoFormat(
"Enabling Mod: {0}", modName);
 
  337                EnabledMods.Remove(modName);
 
  338                Logging.tML.InfoFormat(
"Disabling Mod: {0}", modName);
 
  340            if (PauseSavingEnabledMods) {
 
  344                ModOrganizer.SaveEnabledMods();
 
  348        internal static void SaveConfiguration()
 
  350            Main.Configuration.Put(
"ModBrowserPassphrase", modBrowserPassphrase);
 
  351            Main.Configuration.Put(
"SteamID64", 
steamID64);
 
  352            Main.Configuration.Put(
"DownloadModsFromServers", 
ModNet.downloadModsFromServers);
 
  353            Main.Configuration.Put(
"OnlyDownloadSignedModsFromServers", 
ModNet.onlyDownloadSignedMods);
 
  354            Main.Configuration.Put(
"AutomaticallyReloadAndEnableModsLeavingModBrowser", autoReloadAndEnableModsLeavingModBrowser);
 
  355            Main.Configuration.Put(
"DontRemindModBrowserUpdateReload", dontRemindModBrowserUpdateReload);
 
  356            Main.Configuration.Put(
"DontRemindModBrowserDownloadEnable", dontRemindModBrowserDownloadEnable);
 
  357            Main.Configuration.Put(
"RemoveForcedMinimumZoom", removeForcedMinimumZoom);
 
  358            Main.Configuration.Put(
"ShowMemoryEstimates", showMemoryEstimates);
 
  359            Main.Configuration.Put(
"AvoidGithub", UI.ModBrowser.UIModBrowser.AvoidGithub);
 
  360            Main.Configuration.Put(
"AvoidImgur", UI.ModBrowser.UIModBrowser.AvoidImgur);
 
  361            Main.Configuration.Put(nameof(UI.ModBrowser.UIModBrowser.EarlyAutoUpdate), UI.ModBrowser.UIModBrowser.EarlyAutoUpdate);
 
  362            Main.Configuration.Put(
"LastLaunchedTModLoaderVersion", 
version.ToString());
 
  365        internal static void LoadConfiguration()
 
  367            Main.Configuration.Get(
"ModBrowserPassphrase", ref modBrowserPassphrase);
 
  368            Main.Configuration.Get(
"SteamID64", ref 
steamID64);
 
  369            Main.Configuration.Get(
"DownloadModsFromServers", ref 
ModNet.downloadModsFromServers);
 
  370            Main.Configuration.Get(
"OnlyDownloadSignedModsFromServers", ref 
ModNet.onlyDownloadSignedMods);
 
  371            Main.Configuration.Get(
"AutomaticallyReloadAndEnableModsLeavingModBrowser", ref autoReloadAndEnableModsLeavingModBrowser);
 
  372            Main.Configuration.Get(
"DontRemindModBrowserUpdateReload", ref dontRemindModBrowserUpdateReload);
 
  373            Main.Configuration.Get(
"DontRemindModBrowserDownloadEnable", ref dontRemindModBrowserDownloadEnable);
 
  374            Main.Configuration.Get(
"RemoveForcedMinimumZoom", ref removeForcedMinimumZoom);
 
  375            Main.Configuration.Get(
"ShowMemoryEstimates", ref showMemoryEstimates);
 
  376            Main.Configuration.Get(
"AvoidGithub", ref UI.ModBrowser.UIModBrowser.AvoidGithub);
 
  377            Main.Configuration.Get(
"AvoidImgur", ref UI.ModBrowser.UIModBrowser.AvoidImgur);
 
  378            Main.Configuration.Get(nameof(UI.ModBrowser.UIModBrowser.EarlyAutoUpdate), ref UI.ModBrowser.UIModBrowser.EarlyAutoUpdate);
 
  382        internal static void MigrateSettings()
 
  385                showMemoryEstimates = 
true;
 
  397        internal static void BuildGlobalHook<T, F>(ref F[] list, IList<T> providers, Expression<Func<T, F>> expr)
 
  399            list = BuildGlobalHook(providers, expr).Select(expr.Compile()).ToArray();
 
  402        internal static T[] BuildGlobalHook<T, F>(IList<T> providers, Expression<Func<T, F>> expr)
 
  404            return BuildGlobalHook(providers, Method(expr));
 
  407        internal static T[] BuildGlobalHook<T>(IList<T> providers, MethodInfo method)
 
  409            if (!method.IsVirtual) 
throw new ArgumentException(
"Cannot build hook for non-virtual method " + method);
 
  410            var argTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
 
  411            return providers.Where(p => p.GetType().GetMethod(method.Name, argTypes).DeclaringType != typeof(T)).ToArray();
 
  414        internal static MethodInfo Method<T, F>(Expression<Func<T, F>> expr)
 
  418                var convert = expr.Body as UnaryExpression;
 
  419                var makeDelegate = convert.Operand as MethodCallExpression;
 
  420                var methodArg = makeDelegate.Object as ConstantExpression;
 
  421                method = methodArg.Value as MethodInfo;
 
  422                if (method == 
null) 
throw new NullReferenceException();
 
  425                throw new ArgumentException(
"Invalid hook expression " + expr, e);
 
  433        [Obsolete(
"ModLoader.GetFileBytes is deprecated since v0.11, use ModContent.GetFileBytes instead.", 
true)]
 
  436        [Obsolete(
"ModLoader.FileExists is deprecated since v0.11, use ModContent.FileExists instead.", 
true)]
 
  439        [Obsolete(
"ModLoader.GetTexture is deprecated since v0.11, use ModContent.GetTexture instead.", 
true)]
 
  442        [Obsolete(
"ModLoader.TextureExists is deprecated since v0.11, use ModContent.TextureExists instead.", 
true)]
 
  445        [Obsolete(
"ModLoader.GetSound is deprecated since v0.11, use ModContent.GetSound instead.", 
true)]
 
  448        [Obsolete(
"ModLoader.SoundExists is deprecated since v0.1, use ModContent.SoundExists instead.", 
true)]
 
  451        [Obsolete(
"ModLoader.GetMusic is deprecated since v0.11, use ModContent.GetMusic instead.", 
true)]
 
  454        [Obsolete(
"ModLoader.MusicExists is deprecated since v0.11, use ModContent.MusicExists instead.", 
true)]
 
static readonly Version Version
 
static readonly Framework Framework
 
Manages content added by mods. Liasons between mod content and Terraria's arrays and oversees the Loa...
 
static bool TextureExists(string name)
Returns whether or not a texture with the specified name exists.
 
static bool FileExists(string name)
Returns whether or not a file with the specified name exists.
 
static SoundEffect GetSound(string name)
Gets the sound with the specified name. The name is in the same format as for texture names....
 
static Music GetMusic(string name)
Gets the music with the specified name. The name is in the same format as for texture names....
 
static Texture2D GetTexture(string name)
Gets the texture with the specified name. The name is in the format of "ModFolder/OtherFolders/FileNa...
 
static bool SoundExists(string name)
Returns whether or not a sound with the specified name exists.
 
static bool MusicExists(string name)
Returns whether or not a sound with the specified name exists.
 
static byte[] GetFileBytes(string name)
Gets the byte representation of the file with the specified name. The name is in the format of "ModFo...
 
Mod is an abstract class that you will override. It serves as a central place from which the mod's co...
 
This serves as the central class which loads mods. It contains many static fields and methods related...
 
static readonly IDictionary< string, Mod > modsByName
 
static readonly Version version
 
static bool SoundExists(string name)
 
static void Load(CancellationToken token=default)
 
static string CompressedPlatformRepresentation
 
static Music GetMusic(string name)
 
static void DisplayLoadError(string msg, Exception e, bool fatal, bool continueIsRetry=false)
 
static bool TextureExists(string name)
 
static SoundEffect GetSound(string name)
 
static readonly bool linux
 
static Mod GetMod(int index)
 
static void DotNet45Check()
 
static HashSet< string > _enabledMods
A cached list of enabled mods (not necessarily currently loaded or even installed),...
 
static byte[] GetFileBytes(string name)
 
static Texture2D GetTexture(string name)
 
static bool _pauseSavingEnabledMods
 
static string[] GetLoadedMods()
 
static readonly bool windows
 
static readonly string compressedPlatformRepresentation
 
static bool MusicExists(string name)
 
static bool _needsSavingEnabledMods
 
static Version LastLaunchedTModLoaderVersion
 
static readonly string versionedName
 
static bool ShowFirstLaunchWelcomeMessage
 
static void WarnModsStillLoaded()
 
static WeakReference[] weakModReferences
 
static readonly string versionTag
 
static bool FileExists(string name)
 
static Mod GetMod(string name)
Gets the instance of the Mod with the specified name.
 
static bool IsSignedBy(TmodFile mod, string xmlPublicKey)
 
static readonly string branchName
 
@ Environment
Sandstorm, Hell, Above surface during Eclipse, Space
 
@ Console
Command can be used in server console during MP.