Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CustomLoadingScreens v0.9.7
CustomLoadingScreens.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.9.7")] [assembly: AssemblyInformationalVersion("0.9.7+f5b4472023e021319b5052bfbf00f6018987d118")] [assembly: AssemblyVersion("0.9.7.0")] namespace CustomLoadingScreens; [BepInPlugin("cjayride.CustomLoadingScreens", "Custom Loading Screens", "0.9.7")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(FejdStartup), "LoadMainScene")] public static class LoadMainScene_Patch { public static void Prefix(FejdStartup __instance) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) PickScreensAndTips(); if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_loading == (Object)null || (Object)(object)loadingSprite == (Object)null) { return; } Transform val = __instance.m_loading.transform.Find("Bkg"); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)context).Logger.LogWarning((object)"FejdStartup.m_loading has no Bkg child."); return; } Image component = ((Component)val).GetComponent<Image>(); if (!((Object)(object)component == (Object)null)) { ApplyToLoadingImage(Object.Instantiate<Image>(component, __instance.m_loading.transform), loadingSprite, loadingColorMask.Value, preserveAspect: true); } } } [HarmonyPriority(800)] [HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake")] public static class ZNet_RPC_ClientHandshake_Patch { public static void Prefix(ZNet __instance) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || __instance.IsServer()) { return; } if ((Object)(object)loadingSprite == (Object)null) { PickScreensAndTips(); } Hud instance = Hud.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)loadingSprite == (Object)null)) { ApplyToLoadingImage(instance.m_loadingImage, loadingSprite, loadingColorMask.Value, preserveAspect: true); if (showTipsOnLoadingScreen.Value && loadingTips.Length != 0 && !string.IsNullOrEmpty(loadingTip) && !((Object)(object)instance.m_loadingTip == (Object)null)) { instance.m_loadingTip.text = loadingTip; ((Graphic)instance.m_loadingTip).color = tipTextColor.Value; } } } } [HarmonyPatch(typeof(Hud), "UpdateBlackScreen")] public static class UpdateBlackScreen_Patch { public static void Prefix(Hud __instance, bool ___m_haveSetupLoadScreen, ref bool __state) { __state = !___m_haveSetupLoadScreen; } public static void Postfix(Hud __instance, Player player, bool ___m_haveSetupLoadScreen, bool __state) { if ((Object)(object)__instance == (Object)null) { return; } if ((Object)(object)loadingSprite == (Object)null) { PickScreensAndTips(); } bool flag = ShouldUsePortalLoadingScreen(player); if (flag && !portalLoadingActive) { OnPortalTeleportStarted(); } portalLoadingActive = flag; Sprite val = (differentSpawnScreen.Value ? loadingSprite2 : loadingSprite); if ((Object)(object)val == (Object)null) { return; } bool flag2 = __state && ___m_haveSetupLoadScreen; bool flag3 = IsHudLoadingVisible(__instance); if (flag2 || flag3 || flag) { if (flag) { ShowSpawnStyleLoadingPanel(__instance); } if ((Object)(object)__instance.m_loadingImage != (Object)null && (Object)(object)__instance.m_loadingImage.sprite != (Object)(object)val) { ApplySpawnLoadingScreen(__instance, val); } else if (flag2 || flag) { ApplySpawnLoadingScreen(__instance, val); } } } } private static BepInExPlugin context; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<string> loadingText; public static ConfigEntry<bool> differentSpawnScreen; public static ConfigEntry<bool> differentSpawnTip; public static ConfigEntry<bool> showTipsOnLoadingScreen; public static ConfigEntry<bool> removeVignette; public static ConfigEntry<Color> spawnColorMask; public static ConfigEntry<Color> loadingColorMask; public static ConfigEntry<Color> loadingTextColor; public static ConfigEntry<Color> tipTextColor; public static ConfigEntry<string> imagePath; public static ConfigEntry<string> tipsPath; public static List<string> loadingScreens = new List<string>(); public static string[] loadingTips = new string[0]; private static Sprite loadingSprite; private static Sprite loadingSprite2; private static string loadingTip; private static string loadingTip2; private static bool vignetteRemovedThisSession; private static bool portalLoadingActive; private static Sprite lastAppliedSpawnSprite; private static MethodInfo loadImageBytes; private const int MaxCachedSprites = 4; private static readonly Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>(4); private static readonly Queue<string> spriteCacheOrder = new Queue<string>(4); private void Awake() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Invalid comparison between Unknown and I4 context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); differentSpawnScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DifferentSpawnScreen", true, "Use a different screen for the spawn part"); differentSpawnTip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DifferentSpawnTip", true, "Use a different tip for the spawn part"); spawnColorMask = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "SpawnColorMask", new Color(0.532f, 0.588f, 0.853f, 1f), "Change the color mask of the spawn screen (set last number to 0 to disable)"); loadingColorMask = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "LoadingColorMask", Color.white, "Change the color mask of the initial loading screen (set to white to disable)"); removeVignette = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RemoveMask", true, "Remove dark edges for the spawn part"); loadingText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "LoadingText", "Loading...", "Custom Loading... text"); loadingTextColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "LoadingTextColor", new Color(1f, 0.641f, 0f, 1f), "Custom Loading... text color"); tipTextColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "TipTextColor", Color.white, "Custom tip text color"); showTipsOnLoadingScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowTipsOnLoadingScreen", true, "Show a tip on the initial loading overlay"); imagePath = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PathToImagesFolder", "plugins\\cjayride-CustomLoadingScreens\\CustomLoadingScreens", "Path to image files. Example: config\\CustomLoadingScreens or plugins\\cjayride-CustomLoadingScreens\\CustomLoadingScreens"); tipsPath = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PathToTipsFolder", "plugins\\cjayride-CustomLoadingScreens\\CustomLoadingScreens", "Path to tips file. Example: config\\CustomLoadingScreens or plugins\\cjayride-CustomLoadingScreens\\CustomLoadingScreens"); if (!modEnabled.Value || Application.isBatchMode || (int)SystemInfo.graphicsDeviceType == 4) { return; } loadImageBytes = FindLoadImageMethod(); if (loadImageBytes == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not find ImageConversion.LoadImage(Texture2D, byte[]). Screens will not decode."); } LoadCustomLoadingScreens(); LoadTips(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Found " + loadingScreens.Count + " loading images and " + loadingTips.Length + " tips.")); if (loadingScreens.Count > 0) { Sprite orLoadSprite = GetOrLoadSprite(loadingScreens[0]); if ((Object)(object)orLoadSprite != (Object)null && (Object)(object)orLoadSprite.texture != (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Warmup decode OK: " + ((Texture)orLoadSprite.texture).width + "x" + ((Texture)orLoadSprite.texture).height)); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Warmup decode failed for " + loadingScreens[0])); } } Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private static MethodInfo FindLoadImageMethod() { MethodInfo[] methods = typeof(ImageConversion).GetMethods(BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < methods.Length; i++) { if (!(methods[i].Name != "LoadImage")) { ParameterInfo[] parameters = methods[i].GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(Texture2D) && parameters[1].ParameterType == typeof(byte[])) { return methods[i]; } } } return null; } private static string GetPluginDirectory() { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } private static string GetBepInExRoot() { string pluginDirectory = GetPluginDirectory(); string directoryName = Path.GetDirectoryName(pluginDirectory); if (string.Equals(Path.GetFileName(pluginDirectory), "plugins", StringComparison.OrdinalIgnoreCase)) { return directoryName; } return Path.GetDirectoryName(directoryName); } private static bool IsImageFile(string file) { if (Path.GetFileName(file).Equals("icon.png", StringComparison.OrdinalIgnoreCase)) { return false; } string extension = Path.GetExtension(file); if (!extension.Equals(".png", StringComparison.OrdinalIgnoreCase) && !extension.Equals(".jpg", StringComparison.OrdinalIgnoreCase)) { return extension.Equals(".jpeg", StringComparison.OrdinalIgnoreCase); } return true; } private static bool DirectoryHasImages(string path) { if (string.IsNullOrEmpty(path) || !Directory.Exists(path)) { return false; } try { string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { if (IsImageFile(files[i])) { return true; } } } catch (Exception ex) { ((BaseUnityPlugin)context).Logger.LogWarning((object)("Could not scan " + path + ": " + ex.Message)); } return false; } private static string GetContentDirectory(string configuredRelativePath) { string pluginDirectory = GetPluginDirectory(); string text = Path.Combine(pluginDirectory, "CustomLoadingScreens"); string text2 = Path.Combine(GetBepInExRoot(), configuredRelativePath); if (DirectoryHasImages(text)) { return text; } if (DirectoryHasImages(pluginDirectory)) { return pluginDirectory; } if (DirectoryHasImages(text2)) { return text2; } Directory.CreateDirectory(text); return text; } private void LoadTips() { string contentDirectory = GetContentDirectory(tipsPath.Value); string path = Path.Combine(contentDirectory, "tips.txt"); if (!File.Exists(path)) { string text = Path.Combine(GetPluginDirectory(), "tips.txt"); if (File.Exists(text)) { path = text; } } if (!File.Exists(path)) { File.WriteAllText(Path.Combine(contentDirectory, "tips.txt"), string.Empty); loadingTips = new string[0]; return; } string[] array = File.ReadAllLines(path); int num = 0; for (int i = 0; i < array.Length; i++) { if (!string.IsNullOrWhiteSpace(array[i])) { num++; } } if (num == 0) { loadingTips = new string[0]; return; } string[] array2 = new string[num]; int num2 = 0; for (int j = 0; j < array.Length; j++) { if (!string.IsNullOrWhiteSpace(array[j])) { array2[num2++] = array[j]; } } loadingTips = array2; } private static void LoadCustomLoadingScreens() { loadingScreens.Clear(); string contentDirectory = GetContentDirectory(imagePath.Value); if (!Directory.Exists(contentDirectory)) { Directory.CreateDirectory(contentDirectory); ((BaseUnityPlugin)context).Logger.LogWarning((object)("No loading images found. Put png/jpg files in " + contentDirectory)); return; } string[] files = Directory.GetFiles(contentDirectory, "*.*", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { if (IsImageFile(files[i])) { loadingScreens.Add(files[i]); } } if (loadingScreens.Count == 0) { ((BaseUnityPlugin)context).Logger.LogWarning((object)("No png/jpg loading images in " + contentDirectory)); } else { ((BaseUnityPlugin)context).Logger.LogInfo((object)("Using loading images from " + contentDirectory)); } } private static Sprite GetRandomLoadingScreen() { int count = loadingScreens.Count; if (count == 0) { return null; } return GetOrLoadSprite(loadingScreens[Random.Range(0, count)]); } private static bool TryLoadImage(Texture2D tex, byte[] imageData) { if (loadImageBytes == null) { return false; } try { object obj = loadImageBytes.Invoke(null, new object[2] { tex, imageData }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { ((BaseUnityPlugin)context).Logger.LogWarning((object)("LoadImage failed: " + ex.Message)); return false; } } private static Sprite GetOrLoadSprite(string path) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (spriteCache.TryGetValue(path, out var value) && (Object)(object)value != (Object)null && (Object)(object)value.texture != (Object)null) { return value; } byte[] imageData; try { imageData = File.ReadAllBytes(path); } catch (Exception ex) { ((BaseUnityPlugin)context).Logger.LogWarning((object)("Failed to read loading screen " + path + ": " + ex.Message)); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).anisoLevel = 0; if (!TryLoadImage(val, imageData)) { Object.Destroy((Object)(object)val); ((BaseUnityPlugin)context).Logger.LogWarning((object)("Failed to decode loading screen " + path)); return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); ((Object)val2).name = "CLS_" + Path.GetFileName(path); while (spriteCache.Count >= 4 && spriteCacheOrder.Count > 0) { string key = spriteCacheOrder.Dequeue(); if (!spriteCache.TryGetValue(key, out var value2)) { continue; } spriteCache.Remove(key); if ((Object)(object)value2 != (Object)null && (Object)(object)value2 != (Object)(object)loadingSprite && (Object)(object)value2 != (Object)(object)loadingSprite2) { if ((Object)(object)value2.texture != (Object)null) { Object.Destroy((Object)(object)value2.texture); } Object.Destroy((Object)(object)value2); } } spriteCache[path] = val2; spriteCacheOrder.Enqueue(path); return val2; } private static void PickScreensAndTips() { vignetteRemovedThisSession = false; lastAppliedSpawnSprite = null; if (loadingScreens.Count == 0) { LoadCustomLoadingScreens(); } loadingSprite = GetRandomLoadingScreen(); loadingSprite2 = (differentSpawnScreen.Value ? GetRandomLoadingScreen() : loadingSprite); if ((Object)(object)loadingSprite != (Object)null && (Object)(object)loadingSprite.texture != (Object)null) { ((BaseUnityPlugin)context).Logger.LogInfo((object)("Picked loading sprites " + ((Texture)loadingSprite.texture).width + "x" + ((Texture)loadingSprite.texture).height)); } else { ((BaseUnityPlugin)context).Logger.LogWarning((object)"PickScreensAndTips: no loading sprite (check png/jpg decode)."); } if (loadingTips.Length != 0) { loadingTip = loadingTips[Random.Range(0, loadingTips.Length)]; loadingTip2 = (differentSpawnTip.Value ? loadingTips[Random.Range(0, loadingTips.Length)] : loadingTip); } else { loadingTip = null; loadingTip2 = null; } } private static bool IsHudLoadingVisible(Hud hud) { if ((Object)(object)hud == (Object)null) { return false; } if ((Object)(object)hud.m_loadingScreen != (Object)null && ((Component)hud.m_loadingScreen).gameObject.activeInHierarchy && hud.m_loadingScreen.alpha > 0.05f) { return true; } if ((Object)(object)hud.m_loadingImage != (Object)null) { return ((Behaviour)hud.m_loadingImage).isActiveAndEnabled; } return false; } private static void ApplyToLoadingImage(Image image, Sprite sprite, Color color, bool preserveAspect) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null) && !((Object)(object)sprite == (Object)null)) { image.sprite = sprite; ((Graphic)image).color = color; image.type = (Type)0; image.preserveAspect = preserveAspect; ((Behaviour)image).enabled = true; ((Component)image).transform.SetAsLastSibling(); } } private static bool ShouldUsePortalLoadingScreen(Player player) { if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || player.IsSleeping() || !((Character)player).IsTeleporting()) { return false; } Game instance = Game.instance; if (!((Object)(object)instance == (Object)null)) { return !instance.IsShuttingDown(); } return true; } private static void OnPortalTeleportStarted() { if (differentSpawnScreen.Value) { loadingSprite2 = GetRandomLoadingScreen(); } if (differentSpawnTip.Value && loadingTips.Length != 0) { loadingTip2 = loadingTips[Random.Range(0, loadingTips.Length)]; } vignetteRemovedThisSession = false; } private static void ShowSpawnStyleLoadingPanel(Hud hud) { if ((Object)(object)hud.m_sleepingProgress != (Object)null) { hud.m_sleepingProgress.SetActive(false); } if ((Object)(object)hud.m_teleportingProgress != (Object)null) { hud.m_teleportingProgress.SetActive(false); } if ((Object)(object)hud.m_loadingProgress != (Object)null) { hud.m_loadingProgress.SetActive(true); } } private static void ApplySpawnLoadingScreen(Hud hud, Sprite sprite) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hud == (Object)null) && !((Object)(object)sprite == (Object)null)) { ApplyToLoadingImage(hud.m_loadingImage, sprite, spawnColorMask.Value, preserveAspect: true); if ((Object)(object)hud.m_loadingTip != (Object)null && loadingTips.Length != 0) { hud.m_loadingTip.text = (differentSpawnTip.Value ? loadingTip2 : loadingTip); ((Graphic)hud.m_loadingTip).color = tipTextColor.Value; } if (!vignetteRemovedThisSession && removeVignette.Value && (Object)(object)hud.m_loadingProgress != (Object)null) { Transform transform = hud.m_loadingProgress.transform; DisableChild(transform, "TopFade"); DisableChild(transform, "BottomFade"); DisableChild(transform, "text_darken"); vignetteRemovedThisSession = true; } if ((Object)(object)lastAppliedSpawnSprite != (Object)(object)sprite) { lastAppliedSpawnSprite = sprite; ((BaseUnityPlugin)context).Logger.LogInfo((object)"Applied spawn loading screen to Hud.m_loadingImage."); } } } private static void DisableChild(Transform parent, string name) { Transform val = parent.Find(name); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } } }