Decompiled source of NewSafetyHelp v2.6.0
Mods/NewSafetyHelp.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using System.Threading.Tasks; using HarmonyLib; using JetBrains.Annotations; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using NewSafetyHelp; using NewSafetyHelp.ARG; using NewSafetyHelp.Audio; using NewSafetyHelp.Audio.AudioPatches; using NewSafetyHelp.Audio.Music.Data; using NewSafetyHelp.Audio.Music.Intermission; using NewSafetyHelp.Callers.CallerHelpers; using NewSafetyHelp.Callers.CallerModel; using NewSafetyHelp.Callers.UI.AnimatedEntry; using NewSafetyHelp.CustomCampaignSystem; using NewSafetyHelp.CustomCampaignSystem.Abstract; using NewSafetyHelp.CustomCampaignSystem.CustomCampaignModel; using NewSafetyHelp.CustomCampaignSystem.CustomComputer3DScreen; using NewSafetyHelp.CustomCampaignSystem.CustomRingtone; using NewSafetyHelp.CustomCampaignSystem.CustomTextFiles; using NewSafetyHelp.CustomCampaignSystem.CutsceneLogic; using NewSafetyHelp.CustomCampaignSystem.Helper; using NewSafetyHelp.CustomCampaignSystem.Helper.AccuracyHelpers; using NewSafetyHelp.CustomCampaignSystem.Helper.AccuracyModel; using NewSafetyHelp.CustomCampaignSystem.Helper.CallerRequirementHelper; using NewSafetyHelp.CustomCampaignSystem.LinkApps; using NewSafetyHelp.CustomCampaignSystem.Modifier.Data; using NewSafetyHelp.CustomCampaignSystem.Saving; using NewSafetyHelp.CustomCampaignSystem.Themes; using NewSafetyHelp.CustomCampaignSystem.TimedCaller; using NewSafetyHelp.CustomDesktop; using NewSafetyHelp.CustomDesktop.CustomDoubleClickButton; using NewSafetyHelp.CustomDesktop.Utils; using NewSafetyHelp.CustomThemes; using NewSafetyHelp.CustomVideos; using NewSafetyHelp.Emails; using NewSafetyHelp.EntryManager; using NewSafetyHelp.EntryManager.EntryData; using NewSafetyHelp.EntryManager.EntryUnlocker; using NewSafetyHelp.ErrorDebugging; using NewSafetyHelp.HelperFunctions; using NewSafetyHelp.ImportFiles; using NewSafetyHelp.InGameSettings; using NewSafetyHelp.JSONParsing; using NewSafetyHelp.JSONParsing.CCParsing; using NewSafetyHelp.JSONParsing.EntryParsing; using NewSafetyHelp.JSONParsing.ParsingHelpers; using NewSafetyHelp.LoggingSystem; using NewSafetyHelp.VersionChecker; using Newtonsoft.Json.Linq; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Profiling; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("NewSafetyHelp")] [assembly: AssemblyDescription("A mod for Home Safety Hotline, which allows adding new features and campaigns.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("NewSafetyHelp")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9e2a6c17-9bee-4db1-a42f-f7c09a8601d6")] [assembly: AssemblyFileVersion("2.6.0")] [assembly: MelonInfo(typeof(NewSafetyHelpMainClass), "NewSafetyHelp", "2.6.0", "Gasterbuzzer", "https://github.com/Gasterbuzzer/NewSafetyHelp/releases/")] [assembly: MelonAuthorColor(1, 208, 12, 252)] [assembly: MelonGame("Night Signal Entertainment", "Home Safety Hotline")] [assembly: MelonPriority(99)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.6.0.0")] namespace NewSafetyHelp { public class NewSafetyHelpMainClass : MelonMod { public override void OnInitializeMelon() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown GlobalPreferences.InitializeMelonPreferences(); Application.logMessageReceived += new LogCallback(UnityLogHook.HandleUnityLog); AsyncVersionChecker.CheckForUpdates(); } public override void OnLateInitializeMelon() { EmbedHelpers.DeleteTempFiles(); if (GlobalPreferences.SkipComputerScene.Value) { SceneManager.LoadScene("MainMenuScene"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { LoggingHelper.DebugLog(() => $"Scene {sceneName} with build index {buildIndex} has been loaded!"); MelonPreferences.Save(); } } [HarmonyPatch(typeof(EntryUnlockController), "Awake")] public static class MainClassForMonsterEntries { public static bool ShowUpdateMessage = false; private static bool isInitializedMainOnce = false; public static bool AddedEntriesToCustomCampaign = false; public static MonsterProfile[] CopyMonsterProfiles; private static int monsterProfileSize = 0; public static readonly List<MonsterProfile[]> CopyTierUnlocks = new List<MonsterProfile[]>(); public static readonly List<MonsterProfile[]> CopyXmasTier = new List<MonsterProfile[]>(); private static MonsterProfile[] copyMonsterProfilesAfterAdding; private static int monsterProfileSizeAfterAdding = 0; private static void Postfix(EntryUnlockController __instance) { if (!CustomCampaignGlobal.InCustomCampaign) { if (AddedEntriesToCustomCampaign) { AddedEntriesToCustomCampaign = false; __instance.allEntries.monsterProfiles = copyMonsterProfilesAfterAdding; } if (isInitializedMainOnce) { LoggingHelper.DebugLog("Custom Entries were already added. Skipping adding them again. (This happens on scene reload)."); return; } CopyMonsterProfiles = __instance.allEntries.monsterProfiles; monsterProfileSize = CopyMonsterProfiles.Length; CopyTierUnlocks.Add(__instance.firstTierUnlocks.monsterProfiles); CopyTierUnlocks.Add(__instance.secondTierUnlocks.monsterProfiles); CopyTierUnlocks.Add(__instance.thirdTierUnlocks.monsterProfiles); CopyTierUnlocks.Add(__instance.fourthTierUnlocks.monsterProfiles); CopyTierUnlocks.Add(__instance.fifthTierUnlocks.monsterProfiles); CopyTierUnlocks.Add(__instance.sixthTierUnlocks.monsterProfiles); CopyXmasTier.Add(__instance.xmastFirstTier.monsterProfiles); CopyXmasTier.Add(__instance.xmasSecondTier.monsterProfiles); CopyXmasTier.Add(__instance.xmasThirdTier.monsterProfiles); CopyXmasTier.Add(__instance.xmasFourthTier.monsterProfiles); StartingJSONParsing(__instance); } else { CustomCampaignInitialization(__instance); } } private static void CustomCampaignInitialization(EntryUnlockController __instance) { if (AddedEntriesToCustomCampaign) { return; } if (CopyMonsterProfiles.Length == 0 || monsterProfileSize <= 0) { LoggingHelper.CriticalErrorLog("Loading of old values to add the entries to failed! (Count == 0)"); return; } CustomCampaign activeCustomCampaign = CustomCampaignGlobal.GetActiveCustomCampaign(); if (activeCustomCampaign != null) { if (activeCustomCampaign.RemoveExistingEntries) { __instance.allEntries.monsterProfiles = Array.Empty<MonsterProfile>(); } else if (activeCustomCampaign.UseDLCEntries) { LoggingHelper.DebugLog("Using DLC monster profiles."); __instance.allEntries.monsterProfiles = __instance.allXmasEntries.monsterProfiles; } else { __instance.allEntries.monsterProfiles = CopyMonsterProfiles; } LoggingHelper.InfoLog("Entries are now being added... (Custom Campaign)", LoggingHelper.LoggingCategory.NONE, ConsoleColor.Green); CustomCampaignGlobal.ReplaceAllProvidedCampaignEntries(ref __instance.allEntries); CustomCampaignGlobal.AddAllCustomCampaignEntriesToArray(ref __instance.allEntries); AddedEntriesToCustomCampaign = true; LoggingHelper.InfoLog("Added/Modified all custom entries successfully! (Custom Campaign)", LoggingHelper.LoggingCategory.NONE, ConsoleColor.Green); } } public static void StartingJSONParsing(EntryUnlockController __instance) { LoggingHelper.InfoLog("Now parsing all '.json' files...", LoggingHelper.LoggingCategory.NONE, ConsoleColor.Green); ParseJSONFiles.LoadAllJSON(__instance); copyMonsterProfilesAfterAdding = __instance.allEntries.monsterProfiles; monsterProfileSizeAfterAdding = copyMonsterProfilesAfterAdding.Length; isInitializedMainOnce = true; LoggingHelper.InfoLog("Loaded all '.json' files successfully!", LoggingHelper.LoggingCategory.NONE, ConsoleColor.Green); } } } namespace NewSafetyHelp.VersionChecker { public static class AsyncVersionChecker { private static Version GetCurrentVersion() { return Assembly.GetExecutingAssembly().GetName().Version; } private static bool IsOutDatedVersion(Version currentVersion, Version newVersion) { LoggingHelper.DebugLog($"Checking for outdated version with current version '{currentVersion}' and the new version '{newVersion}'. " + $"(Equal?: {currentVersion == newVersion}) " + $"(Newer available? {currentVersion < newVersion}) " + $"(Current version newer?: {currentVersion > newVersion})"); return currentVersion < newVersion; } [CanBeNull] private static Version ParseVersionTag(string tag) { if (string.IsNullOrEmpty(tag) || string.IsNullOrWhiteSpace(tag) || tag == "NO_VERSION_FOUND") { return null; } tag = tag.Trim(); if (tag.StartsWith("v", StringComparison.OrdinalIgnoreCase)) { tag = tag.Substring(1); } Version.TryParse(tag, out Version result); return result; } private static async Task<Version> GetLatestReleaseVersionAsync() { HttpClient http = new HttpClient(); try { http.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("NewSafetyHelp-Mod", GetCurrentVersion().ToString())); http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json")); HttpResponseMessage resp = await http.GetAsync("https://api.github.com/repos/Gasterbuzzer/NewSafetyHelp/releases/latest"); if (!resp.IsSuccessStatusCode) { LoggingHelper.WarningLog($"GitHub API returned error code {resp.StatusCode}. " + "Could not check for updates."); return null; } JObject jsonObjectParsed = JObject.Parse(await resp.Content.ReadAsStringAsync()); string tag = "NO_VERSION_FOUND"; if (jsonObjectParsed["tag_name"] != null) { tag = (string)jsonObjectParsed["tag_name"]; } else if (jsonObjectParsed["name"] != null) { tag = (string)jsonObjectParsed["name"]; } Version parsedVersion = ParseVersionTag(tag); if (parsedVersion == null) { LoggingHelper.WarningLog("Was unable of parsing version number. Failed check."); return null; } return parsedVersion; } finally { ((IDisposable)http)?.Dispose(); } } public static void ShowUpdateMessage() { string text = "NEW VERSION AVAILABLE! Download through your preferred method."; MelonLogger.Msg(ConsoleColor.White, "------------------------"); MelonLogger.Msg(ConsoleColor.Blue, "------------------------"); MelonLogger.Msg(ConsoleColor.Yellow, "------------------------"); MelonLogger.Msg(ConsoleColor.Magenta, "\n\n\n"); MelonLogger.Msg(ConsoleColor.Magenta, text); MelonLogger.Msg(ConsoleColor.Red, text); MelonLogger.Msg(ConsoleColor.Magenta, text); MelonLogger.Msg(ConsoleColor.Magenta, "\n\n\n"); MelonLogger.Msg(ConsoleColor.Yellow, "------------------------"); MelonLogger.Msg(ConsoleColor.Blue, "------------------------"); MelonLogger.Msg(ConsoleColor.White, "------------------------"); } public static async Task CheckForUpdates() { Version newestVersion = await GetLatestReleaseVersionAsync(); if (newestVersion == null) { LoggingHelper.WarningLog("Unable of checking if there is a new version available. Check your internet connection."); } else if (IsOutDatedVersion(GetCurrentVersion(), newestVersion)) { MainClassForMonsterEntries.ShowUpdateMessage = true; ShowUpdateMessage(); } } } } namespace NewSafetyHelp.MainGameBugFixes { public static class CloseErrorPopupFix { [HarmonyPatch(typeof(GenericErrorPopupBehavior), "ExitButton")] public static class ExitButtonFix { private static bool Prefix(GenericErrorPopupBehavior __instance) { __instance.ConfirmButton(); return false; } } [HarmonyPatch(typeof(GenericErrorPopupBehavior), "OnEnable")] public static class OnEnableFix { private static void Prefix(GenericErrorPopupBehavior __instance) { GameObject gameObject = ((Component)((Component)__instance).transform.Find("WindowsBar").Find("CloseButton")).gameObject; if ((Object)(object)gameObject != (Object)null && gameObject.GetComponents<Button>().Length >= 2) { Object.Destroy((Object)(object)gameObject.GetComponent<Button>()); } } } [HarmonyPatch(typeof(SubmitWindowBehavior), "OnEnable")] public static class SubmitAnswerCloseButtonFix { private static readonly MethodInfo PopulateDropdownList = typeof(SubmitWindowBehavior).GetMethod("PopulateDropdownList", BindingFlags.Instance | BindingFlags.NonPublic); private static bool Prefix(SubmitWindowBehavior __instance) { GameObject gameObject = ((Component)((Component)__instance).transform.Find("WindowsBar").Find("CloseButton")).gameObject; if ((Object)(object)gameObject != (Object)null && gameObject.GetComponents<Button>().Length >= 2) { Object.Destroy((Object)(object)gameObject.GetComponent<Button>()); } __instance.answerToSubmit = null; __instance.submitButton.SetActive(true); __instance.loadingText.SetActive(false); PopulateDropdownList.Invoke(__instance, null); return false; } } } public static class EmailLoadingBugFix { [HarmonyPatch(typeof(EmailWindowBehavior), "DisplayEmail", new Type[] { typeof(Email) })] public static class DisplayEmailPatch { private static readonly int ScreenLoad = Animator.StringToHash("ScreenLoad"); private static readonly MethodInfo UpdateLayoutGroupMethod = typeof(EmailWindowBehavior).GetMethod("UpdateLayoutGroup", BindingFlags.Instance | BindingFlags.NonPublic); private static bool Prefix(EmailWindowBehavior __instance, ref Email emailToDisplay) { //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) if (UpdateLayoutGroupMethod == null) { LoggingHelper.ReflectionError("UpdateLayoutGroupMethod"); return true; } if ((Object)(object)__instance.selectedEmail != (Object)null) { string text = "<b>Subject Line: " + __instance.selectedEmail.subjectLine + "</b> \n\nFrom: " + __instance.selectedEmail.sender + "\n\n\n" + __instance.selectedEmail.emailBody; if (((TMP_Text)__instance.displayedEmailBody).text.Equals(text)) { if (!((Object)(object)__instance.selectedEmail.imageAttachment != (Object)null)) { return false; } if (((object)__instance.displayedImage.sprite).Equals((object?)__instance.selectedEmail.imageAttachment)) { return false; } } ((TMP_Text)__instance.displayedEmailBody).text = text; bool flag = false; if (CustomCampaignGlobal.InCustomCampaign) { CustomCampaign activeCustomCampaign = CustomCampaignGlobal.GetActiveCustomCampaign(); if (activeCustomCampaign == null) { return true; } CustomEmail customEmail = CustomCampaignGlobal.GetCustomEmailFromActiveCampaign(__instance.selectedEmail); LoggingHelper.DebugLog(() => "Trying to find associated custom email. Did we find a custom email? " + $"{customEmail != null}.", LoggingHelper.LoggingCategory.EMAIL); if (customEmail != null) { if (customEmail.HasAnimatedVideo) { LoggingHelper.DebugLog(() => "Playing email video: '" + customEmail.EmailAnimatedVideo + "'.", LoggingHelper.LoggingCategory.EMAIL); EmailHelper.SetVideoUrlEmail(customEmail.EmailAnimatedVideo); if (customEmail.EmailAnimatedVideoShouldLoop.HasChanged) { EmailHelper.SetLoopInAnimatedImage(customEmail.EmailAnimatedVideoShouldLoop.Data); } else { EmailHelper.SetLoopInAnimatedImage(shouldLoop: true); } flag = true; } else { EmailHelper.RestoreEmailPortrait(); } EmailHelper.SetClickUrlToOpen(customEmail.EmailClickURL == null, customEmail.EmailClickURL, customEmail.HasAnimatedVideo); } else { EmailHelper.RestoreEmailPortrait(); EmailHelper.DisableEmailImageCursorHover(); } } if (flag || (Object)(object)__instance.selectedEmail.imageAttachment != (Object)null) { ((Component)((Component)__instance.displayedImage).transform.parent).gameObject.SetActive(true); } else { ((Component)((Component)__instance.displayedImage).transform.parent).gameObject.SetActive(false); } if ((Object)(object)__instance.selectedEmail.imageAttachment != (Object)null) { __instance.displayedImage.sprite = __instance.selectedEmail.imageAttachment; } } else { ((TMP_Text)__instance.displayedEmailBody).text = "No Message to Display."; ((Component)((Component)__instance.displayedImage).transform.parent).gameObject.SetActive(false); } AnimatorStateInfo currentAnimatorStateInfo = __instance.loadingHiderAnimator.GetCurrentAnimatorStateInfo(0); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("ScreenLoad") && !__instance.loadingHiderAnimator.IsInTransition(0)) { __instance.loadingHiderAnimator.SetTrigger(ScreenLoad); } else { __instance.loadingHiderAnimator.ResetTrigger(ScreenLoad); __instance.loadingHiderAnimator.Play(ScreenLoad, 0, 0f); } __instance.previewScrollbar.value = 1f; IEnumerator enumerator = (IEnumerator)UpdateLayoutGroupMethod.Invoke(__instance, new object[1] { __instance.inboxLayoutGroup }); ((MonoBehaviour)__instance).StartCoroutine(enumerator); return false; } } } public static class EntryLoadingBuxFix { [HarmonyPatch(typeof(MainCanvasBehavior), "UpdateSelectedEntry", new Type[] { typeof(MonsterProfile) })] public static class MainCanvasUpdateSelectedEntryPatch { private static readonly MethodInfo IsNetworkDown = typeof(MainCanvasBehavior).GetMethod("IsNetworkDown", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); private static readonly MethodInfo SelectMonsterPortrait = typeof(MainCanvasBehavior).GetMethod("SelectMonsterPortrait", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); private static readonly MethodInfo UpdateLayoutGroupMethod = typeof(MainCanvasBehavior).GetMethod("UpdateLayoutGroup", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); private static bool Prefix(MainCanvasBehavior __instance, ref MonsterProfile profile) { //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) if (SelectMonsterPortrait == null || IsNetworkDown == null || UpdateLayoutGroupMethod == null) { LoggingHelper.ReflectionError("IsNetworkDown", "SelectMonsterPortrait", "UpdateLayoutGroupMethod"); return true; } if ((Object)(object)__instance.selectedMonsterProfile != (Object)null && ((object)__instance.selectedMonsterProfile).Equals((object?)profile)) { return false; } __instance.selectedMonsterProfile = profile; if ((bool)IsNetworkDown.Invoke(__instance, null)) { profile = __instance.errorProfile; __instance.cameraAnimator.SetTrigger(Glitch); } ((Component)__instance.selectedMonsterPortraitImage).gameObject.SetActive(false); __instance.monsterAudioSamplePlayer.SetActive(false); if ((Object)(object)profile.monsterPortrait != (Object)null) { ((Component)__instance.selectedMonsterPortraitImage).gameObject.SetActive(true); __instance.selectedMonsterPortraitImage.sprite = (Sprite)SelectMonsterPortrait.Invoke(__instance, new object[1] { profile }); if (hasActiveEasterEgg) { ((Graphic)__instance.selectedMonsterPortraitImage).color = Color.white; MelonCoroutines.Stop(easterEggCoroutine); hasActiveEasterEgg = false; } if (((Object)__instance.selectedMonsterProfile).name == "Boggart") { easterEggCoroutine = MelonCoroutines.Start(EasterEgg(delegate { //IL_0021: Unknown result type (might be due to invalid IL or missing references) LoggingHelper.DebugLog("Easter Egg!"); ((Graphic)__instance.selectedMonsterPortraitImage).color = Color.red; })); } } if (CustomCampaignGlobal.InCustomCampaign) { EntryMetadata entryFromActiveCampaign = CustomCampaignGlobal.GetEntryFromActiveCampaign(profile.monsterName); if (entryFromActiveCampaign != null && entryFromActiveCampaign.IsVideoPortrait) { ((Component)__instance.selectedMonsterPortraitImage).gameObject.SetActive(true); MainCanvasEntry.SetVideoUrl(entryFromActiveCampaign.VideoUrlPortrait, MainCanvasEntry.PortraitType.ENTRY); if (entryFromActiveCampaign.VideoPortraitShouldLoop.HasChanged) { MainCanvasEntry.SetVideoLoop(entryFromActiveCampaign.VideoPortraitShouldLoop.Data, MainCanvasEntry.PortraitType.ENTRY); } } else { MainCanvasEntry.RestorePortrait(MainCanvasEntry.PortraitType.ENTRY); MainCanvasEntry.SetVideoLoop(shouldLoop: true, MainCanvasEntry.PortraitType.ENTRY); } } if ((Object)(object)profile.monsterAudioClip != (Object)null) { __instance.monsterAudioSamplePlayer.SetActive(true); } ((TMP_Text)__instance.selectedMonsterTitle).text = profile.monsterName; ((TMP_Text)__instance.selectedMonsterDescription).text = profile.monsterDescription; AnimatorStateInfo currentAnimatorStateInfo = __instance.screenLoader.GetCurrentAnimatorStateInfo(0); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("ScreenLoad") && !__instance.screenLoader.IsInTransition(0)) { __instance.screenLoader.SetTrigger(ScreenLoad); } else { __instance.screenLoader.ResetTrigger(ScreenLoad); __instance.screenLoader.Play(ScreenLoad, 0, 0f); } IEnumerator enumerator = (IEnumerator)UpdateLayoutGroupMethod.Invoke(__instance, new object[1] { __instance.mainEntryLayoutGroup }); ((MonoBehaviour)__instance).StartCoroutine(enumerator); if ((Object)(object)GlobalVariables.UISoundControllerScript != (Object)null) { GlobalVariables.UISoundControllerScript.myMonsterSampleAudioSource.Stop(); } __instance.selectedEntryScrollbar.value = 1f; return false; } private static IEnumerator EasterEgg(Action updateSpriteAction) { hasActiveEasterEgg = true; yield return (object)new WaitForSeconds(603f); updateSpriteAction(); } } [HarmonyPatch(typeof(EntryCanvasStandaloneBehavior), "UpdateSelectedEntry", new Type[] { typeof(MonsterProfile) })] public static class EntryCanvasUpdateSelectedEntryPatch { private static readonly MethodInfo SelectMonsterPortrait = typeof(EntryCanvasStandaloneBehavior).GetMethod("SelectMonsterPortrait", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); private static readonly MethodInfo UpdateLayoutGroupMethod = typeof(EntryCanvasStandaloneBehavior).GetMethod("UpdateLayoutGroup", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); private static bool Prefix(EntryCanvasStandaloneBehavior __instance, ref MonsterProfile profile) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) if (SelectMonsterPortrait == null || UpdateLayoutGroupMethod == null) { LoggingHelper.ReflectionError("SelectMonsterPortrait", "UpdateLayoutGroupMethod"); return true; } if ((Object)(object)__instance.selectedMonsterProfile != (Object)null && ((object)__instance.selectedMonsterProfile).Equals((object?)profile)) { return false; } __instance.selectedMonsterProfile = profile; ((Component)__instance.selectedMonsterPortraitImage).gameObject.SetActive(false); __instance.monsterAudioSamplePlayer.SetActive(false); if ((Object)(object)profile.monsterPortrait != (Object)null) { ((Component)__instance.selectedMonsterPortraitImage).gameObject.SetActive(true); __instance.selectedMonsterPortraitImage.sprite = (Sprite)SelectMonsterPortrait.Invoke(__instance, new object[1] { profile }); } if (CustomCampaignGlobal.InCustomCampaign) { EntryMetadata entryFromActiveCampaign = CustomCampaignGlobal.GetEntryFromActiveCampaign(profile.monsterName); if (entryFromActiveCampaign != null && entryFromActiveCampaign.IsVideoPortrait) { ((Component)__instance.selectedMonsterPortraitImage).gameObject.SetActive(true); EntryCanvasStandaloneEntry.SetVideoUrlEntryStandaloneCanvas(entryFromActiveCampaign.VideoUrlPortrait); } else { EntryCanvasStandaloneEntry.RestoreNormalPortrait(); } } if ((Object)(object)profile.monsterAudioClip != (Object)null) { __instance.monsterAudioSamplePlayer.SetActive(true); } ((TMP_Text)__instance.selectedMonsterTitle).text = profile.monsterName; ((TMP_Text)__instance.selectedMonsterDescription).text = profile.monsterDescription; AnimatorStateInfo currentAnimatorStateInfo = __instance.screenLoader.GetCurrentAnimatorStateInfo(0); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("ScreenLoad") && !__instance.screenLoader.IsInTransition(0)) { __instance.screenLoader.SetTrigger(ScreenLoad); } else { __instance.screenLoader.ResetTrigger(ScreenLoad); __instance.screenLoader.Play(ScreenLoad, 0, 0f); } IEnumerator enumerator = (IEnumerator)UpdateLayoutGroupMethod.Invoke(__instance, new object[1] { __instance.mainEntryLayoutGroup }); ((MonoBehaviour)__instance).StartCoroutine(enumerator); if ((Object)(object)GlobalVariables.UISoundControllerScript != (Object)null) { GlobalVariables.UISoundControllerScript.myMonsterSampleAudioSource.Stop(); } __instance.selectedEntryScrollbar.value = 1f; return false; } } private static readonly int ScreenLoad = Animator.StringToHash("ScreenLoad"); private static readonly int Glitch = Animator.StringToHash("glitch"); private static object easterEggCoroutine; private static bool hasActiveEasterEgg; } public static class EntryViewNotUpdating { [HarmonyPatch(typeof(OptionsExecutable), "Open")] public static class UpdateListDesktop { private static readonly MethodInfo StartMethod = typeof(EntryCanvasStandaloneBehavior).GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static void Prefix(OptionsExecutable __instance) { if (((Object)__instance.myPopup).name == "EntryCanvasStandalone") { if (StartMethod == null) { LoggingHelper.ReflectionError("StartMethod"); } else { StartMethod.Invoke(__instance.myPopup.GetComponent<EntryCanvasStandaloneBehavior>(), null); } } } } } public static class ScreenResolutionBugFix { [HarmonyPatch(typeof(ScreenResolutions), "SetMenuValue", new Type[] { typeof(int), typeof(int), typeof(int) })] public static class FixScreenResolutionOptions { private static bool Prefix(ScreenResolutions __instance, ref int width, ref int height, ref int refresh) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = typeof(ScreenResolutions).GetField("resolutions", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { LoggingHelper.ErrorLog("ScreenResolutions field not found. Unable of patching out bug. Defaulting to normal function."); return true; } Resolution[] array = (Resolution[])field.GetValue(__instance); if (array.Length == 0) { LoggingHelper.ErrorLog("ScreenResolutions field was empty. Unable of patching out bug. Defaulting to normal function."); return true; } for (int i = 0; i < array.Length; i++) { Resolution val = array[i]; if (((Resolution)(ref val)).width == width && ((Resolution)(ref val)).height == height && ((Resolution)(ref val)).refreshRate == refresh) { if (i >= __instance.dropdownMenu.options.Count) { __instance.dropdownMenu.value = i; } else { __instance.dropdownMenu.value = i; __instance.dropdownMenu.captionText.text = __instance.dropdownMenu.options[i].text; } return false; } } return false; } } } public static class UISoundBugFix { [HarmonyPatch(typeof(UISoundController), "FadeInLoopingSound", new Type[] { typeof(RichAudioClip), typeof(AudioSource), typeof(float) })] public static class FadeInLoopingSoundBugFix { private static bool Prefix(UISoundController __instance, ref IEnumerator __result, ref RichAudioClip myRichClip, ref AudioSource mySource, ref float interpolaterScalar) { __result = FadeInLoopingSoundChanged(__instance, myRichClip, mySource, interpolaterScalar); return false; } private static IEnumerator FadeInLoopingSoundChanged(UISoundController __instance, RichAudioClip myRichClip, AudioSource mySource, float interpolaterScalar) { if ((Object)(object)mySource == (Object)null) { yield break; } if (!Object.op_Implicit((Object)(object)mySource)) { if (!((Object)(object)myRichClip.clip == (Object)null)) { __instance.myLoopingSource.clip = myRichClip.clip; __instance.myLoopingSource.volume = 0f; __instance.myLoopingSource.Play(); float interpolater = 0f; while (__instance.myLoopingSource.volume < myRichClip.volume) { __instance.myLoopingSource.volume = Mathf.Lerp(0f, myRichClip.volume, interpolater); interpolater += interpolaterScalar * Time.deltaTime; yield return null; } __instance.myLoopingSource.volume = myRichClip.volume; } } else { LoggingHelper.DebugLog($"[UNITY] {mySource} is fading in."); mySource.clip = myRichClip.clip; mySource.volume = 0f; mySource.Play(); float interpolater = 0f; while (mySource.volume < myRichClip.volume) { mySource.volume = Mathf.Lerp(0f, myRichClip.volume, interpolater); interpolater += interpolaterScalar * Time.deltaTime; yield return null; } mySource.volume = myRichClip.volume; } } } } } namespace NewSafetyHelp.LoggingSystem { public static class LoggingHelper { public enum LoggingCategory { NONE, SKIPPED_CALLER, THEME, RINGTONE, EMAIL, VIDEO, TEXT_FILE, ENTRY, CUTSCENE, MEMORY, LINK_APP } private enum LoggingLevel { ERROR, CRITICAL_ERROR, WARNING, INFO, DEBUG, DEBUG_WARNING } private static bool CheckLoggingCategory(LoggingCategory loggingCategory = LoggingCategory.NONE, bool checkDebugLog = false) { if (checkDebugLog && !GlobalPreferences.ShowDebugLogs.Value) { return false; } switch (loggingCategory) { case LoggingCategory.SKIPPED_CALLER: if (!GlobalPreferences.ShowSkippedCallerDebugLog.Value) { return false; } break; case LoggingCategory.THEME: if (!GlobalPreferences.ShowThemeDebugLog.Value) { return false; } break; case LoggingCategory.RINGTONE: if (!GlobalPreferences.ShowRingtoneDebugLog.Value) { return false; } break; case LoggingCategory.EMAIL: if (!GlobalPreferences.ShowEmailDebugLog.Value) { return false; } break; case LoggingCategory.VIDEO: if (!GlobalPreferences.ShowVideoDebugLog.Value) { return false; } break; case LoggingCategory.ENTRY: if (!GlobalPreferences.ShowEntryDebugLog.Value) { return false; } break; case LoggingCategory.TEXT_FILE: if (!GlobalPreferences.ShowTextFileDebugLog.Value) { return false; } break; case LoggingCategory.CUTSCENE: if (!GlobalPreferences.ShowDebugLogs.Value) { return false; } break; case LoggingCategory.MEMORY: if (!GlobalPreferences.ShowMemoryLog.Value) { return false; } break; case LoggingCategory.LINK_APP: if (!GlobalPreferences.ShowLinkAppLog.Value) { return false; } break; } return true; } private static void Log(string loggingMessage, LoggingLevel loggingLevel = LoggingLevel.INFO, ConsoleColor? consoleColor = null) { switch (loggingLevel) { case LoggingLevel.ERROR: MelonLogger.Error("ERROR: " + loggingMessage); break; case LoggingLevel.CRITICAL_ERROR: MelonLogger.Msg(ConsoleColor.Red, "CRITICAL ERROR: " + loggingMessage); break; case LoggingLevel.WARNING: MelonLogger.Warning("WARNING: " + loggingMessage); break; case LoggingLevel.INFO: if (consoleColor.HasValue) { MelonLogger.Msg(consoleColor.Value, "INFO: " + loggingMessage); } else { MelonLogger.Msg("INFO: " + loggingMessage); } break; case LoggingLevel.DEBUG: if (consoleColor.HasValue) { MelonLogger.Msg(consoleColor.Value, "DEBUG: " + loggingMessage); } else { MelonLogger.Msg("DEBUG: " + loggingMessage); } break; case LoggingLevel.DEBUG_WARNING: if (consoleColor.HasValue) { MelonLogger.Msg(consoleColor.Value, "DEBUG WARNING: " + loggingMessage); } else { MelonLogger.Msg("DEBUG WARNING: " + loggingMessage); } break; } } public static void InfoLog(string loggingMessage, LoggingCategory loggingCategory = LoggingCategory.NONE, ConsoleColor? consoleColor = null) { if (CheckLoggingCategory(loggingCategory)) { Log(loggingMessage, LoggingLevel.INFO, consoleColor); } } public static void InfoLog(Func<string> loggingMessageConstructor, LoggingCategory loggingCategory = LoggingCategory.NONE, ConsoleColor? consoleColor = null) { if (CheckLoggingCategory(loggingCategory)) { string loggingMessage = loggingMessageConstructor(); Log(loggingMessage, LoggingLevel.INFO, consoleColor); } } public static void DebugLog(string loggingMessage, LoggingCategory loggingCategory = LoggingCategory.NONE, ConsoleColor? consoleColor = null) { if (CheckLoggingCategory(loggingCategory, checkDebugLog: true)) { Log(loggingMessage, LoggingLevel.DEBUG, consoleColor); } } public static void DebugLog(Func<string> loggingMessageConstructor, LoggingCategory loggingCategory = LoggingCategory.NONE, ConsoleColor? consoleColor = null) { if (CheckLoggingCategory(loggingCategory, checkDebugLog: true)) { string loggingMessage = loggingMessageConstructor(); Log(loggingMessage, LoggingLevel.DEBUG, consoleColor); } } public static void TestLog(string loggingMessage, LoggingCategory loggingCategory = LoggingCategory.NONE) { if (CheckLoggingCategory(loggingCategory, checkDebugLog: true)) { Log(loggingMessage, LoggingLevel.DEBUG, ConsoleColor.Magenta); } } public static void ErrorLog(string loggingMessage, LoggingCategory loggingCategory = LoggingCategory.NONE) { if (CheckLoggingCategory(loggingCategory)) { Log(loggingMessage, LoggingLevel.ERROR); } } public static void CriticalErrorLog(string loggingMessage, LoggingCategory loggingCategory = LoggingCategory.NONE) { if (CheckLoggingCategory(loggingCategory)) { Log(loggingMessage, LoggingLevel.CRITICAL_ERROR); } } public static void WarningLog(string loggingMessage, LoggingCategory loggingCategory = LoggingCategory.NONE) { if (CheckLoggingCategory(loggingCategory)) { Log(loggingMessage, LoggingLevel.WARNING); } } public static void CampaignNullError() { ErrorLog("Custom Campaign is null, even though custom campaign is active. Calling either original function or cancelling the current operation."); } public static void ReflectionError(params string[] differentVariableNames) { string loggingMessage = "Method or Field reflection failed. Possible variables that failed: '" + string.Join("' '", differentVariableNames) + "'. Calling original function."; Log(loggingMessage, LoggingLevel.ERROR); } } } namespace NewSafetyHelp.JSONParsing { public static class GlobalParsingVariables { public static readonly List<EntryMetadata> EntriesMetadata = new List<EntryMetadata>(); public static readonly List<CustomTheme> MainGameThemes = new List<CustomTheme>(); public static readonly List<CustomEmail> MainCampaignEmails = new List<CustomEmail>(); public static readonly Dictionary<int, CustomCCaller> CustomCallersMainGame = new Dictionary<int, CustomCCaller>(); public static readonly List<CustomCCaller> PendingCustomCampaignCustomCallers = new List<CustomCCaller>(); public static List<EntryMetadata> PendingCustomCampaignEntries = new List<EntryMetadata>(); public static List<EntryMetadata> PendingCustomCampaignReplaceEntries = new List<EntryMetadata>(); public static List<CustomEmail> PendingCustomCampaignEmails = new List<CustomEmail>(); public static readonly List<CustomMusic> PendingCustomCampaignMusic = new List<CustomMusic>(); public static readonly List<CustomModifier> PendingCustomCampaignModifiers = new List<CustomModifier>(); public static readonly List<CustomTheme> PendingCustomCampaignThemes = new List<CustomTheme>(); public static List<CustomVideo> PendingCustomCampaignVideos = new List<CustomVideo>(); public static List<CustomRingtone> PendingCustomCampaignRingtones = new List<CustomRingtone>(); public static List<CustomTextFile> PendingCustomCampaignTextFile = new List<CustomTextFile>(); public static List<CustomCutscene> PendingCustomCampaignCutscenes = new List<CustomCutscene>(); public static List<Computer3DScreen> PendingCustomCampaign3DComputerScreens = new List<Computer3DScreen>(); public static List<LinkApp> PendingCustomCampaignLinkApps = new List<LinkApp>(); public static int CustomCampaignEntryIDOffset = 100000; public const int MainCampaignCallAmount = 116; } public static class ParseJSONFiles { public enum JSONParseTypes { Campaign, Call, Entry, Email, Video, Music, Modifier, Theme, Ringtone, TextProgram, Cutscene, Computer3DScreen, LinkApp, Invalid } public static void LoadAllJSON(EntryUnlockController __instance) { Time.timeScale = 0f; EmbeddedTimerData.Initialize(); string userDataFolderPath = FileImporter.GetUserDataFolderPath(); string[] directories = Directory.GetDirectories(userDataFolderPath); string[] array = directories; foreach (string modFolderPath in array) { LoadJsonFilesFromFolder(modFolderPath, __instance); } foreach (CustomCampaign item in CustomCampaignGlobal.CustomCampaignsAvailable) { if (item.Emails.Count > 0) { item.SortEmailsInCustomCampaign(); } if (item.CustomVideos.Count > 0) { item.SortCustomVideoFiles(); } if (item.CustomCutscenes.Count > 0) { item.SortCutsceneInCustomCampaign(); } if (item.CustomTextProgramFiles.Count > 0) { item.SortTextFiles(); } if (item.CustomCallersInCampaign.Count > 0) { item.SortCustomCallersInCustomCampaign(); } if (item.CustomComputer3DScreens.Count > 0) { item.SortComputer3DScreens(); } if (item.LinkApps.Count > 0) { item.SortLinkApps(); } } if (AudioImport.CurrentLoadingAudios.Count <= 0) { Time.timeScale = 1f; } } public static void LoadJsonFilesFromFolder(string modFolderPath, EntryUnlockController __instance) { string[] files = Directory.GetFiles(modFolderPath, "*.json", SearchOption.AllDirectories); string[] array = files; foreach (string text in array) { try { LoggingHelper.InfoLog("Found new JSON file at '" + text + "', attempting to parse it now."); string text2 = File.ReadAllText(text); string directoryName = Path.GetDirectoryName(text); JObject val = JObject.Parse(text2); switch (GetJSONParsingType(val, modFolderPath)) { case JSONParseTypes.Campaign: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a custom campaign."); CustomCampaignParsing.CreateCustomCampaign(val, modFolderPath, directoryName); break; case JSONParseTypes.Call: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a custom caller."); CustomCallerParsing.CreateCustomCaller(val, modFolderPath, directoryName); break; case JSONParseTypes.Entry: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as an entry (monster)."); NewSafetyHelp.JSONParsing.EntryParsing.EntryParsing.CreateEntryFromJSON(val, -1, modFolderPath, directoryName, __instance); break; case JSONParseTypes.Email: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a email."); EmailParsing.CreateEmail(val, modFolderPath, directoryName); break; case JSONParseTypes.Video: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a video."); VideoParsing.CreateVideo(val, modFolderPath, directoryName); break; case JSONParseTypes.Music: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a music file."); MusicParsing.CreateMusic(val, modFolderPath, directoryName); break; case JSONParseTypes.Modifier: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a modifier file."); ModifierParsing.CreateModifier(val, modFolderPath, directoryName); break; case JSONParseTypes.Theme: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a theme file."); ThemeParsing.CreateTheme(val, modFolderPath, directoryName); break; case JSONParseTypes.Ringtone: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a ringtone file."); RingtoneParsing.CreateRingtone(val, modFolderPath, directoryName); break; case JSONParseTypes.TextProgram: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a text file program."); TextProgramParsing.CreateTextProgram(val, modFolderPath); break; case JSONParseTypes.Cutscene: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a cutscene."); CutsceneParsing.CreateCutscene(val, modFolderPath, directoryName); break; case JSONParseTypes.Computer3DScreen: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a 3D Computer Screen."); Computer3DScreenParsing.Create3DComputerScreen(val, modFolderPath, directoryName); break; case JSONParseTypes.LinkApp: LoggingHelper.InfoLog("Provided JSON file at '" + text + "' has been interpreted as a link app."); LinkAppParsing.CreateLinkApp(val, modFolderPath, directoryName); break; case JSONParseTypes.Invalid: LoggingHelper.ErrorLog("ERROR: Provided JSON file parsing failed or is not any known provided format.\n(If this intended, you can ignore this, if not, check if you have written your JSON correctly).\nSkipping trying to read this file."); break; default: LoggingHelper.ErrorLog("This error should not happen. Possible file corruption."); break; } } catch (Exception ex) { LoggingHelper.ErrorLog("Failed reading the file '" + text + "'. \n---\nError message: '" + ex.Message + "'. \n---\nError Stacktrace: \n'\n" + ex.StackTrace + "\n'."); } } } public static JSONParseTypes GetJSONParsingType(JObject json, string filePath = "") { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if (json == null || (int)((JToken)json).Type != 1 || string.IsNullOrEmpty(filePath)) { return JSONParseTypes.Invalid; } if (ParsingHelper.ContainsKeys(new List<string> { "custom_campaign_name", "custom_campaign_days", "custom_campaign_icon_image_name" }, json)) { return JSONParseTypes.Campaign; } if (ParsingHelper.ContainsKeys(new List<string> { "custom_caller_transcript", "custom_caller_name", "order_in_campaign", "custom_caller_audio_clip_name" }, json)) { return JSONParseTypes.Call; } if (ParsingHelper.ContainsKeys(new List<string> { "monster_name", "replace_entry", "caller_name", "entry_name", "entry_description", "monster_description", "monster_portrait_image_name", "entry_portrait_image_name", "monster_audio_clip_name", "entry_audio_clip_name" }, json)) { return JSONParseTypes.Entry; } if (ParsingHelper.ContainsKeys(new List<string> { "email_subject", "email_in_main_campaign", "email_custom_campaign_name" }, json)) { return JSONParseTypes.Email; } if (ParsingHelper.ContainsKeys(new List<string> { "video_desktop_name", "video_file_name", "video_unlock_day" }, json)) { return JSONParseTypes.Video; } if (ParsingHelper.ContainsKeys(new List<string> { "music_audio_clip_name" }, json)) { return JSONParseTypes.Music; } if (!ParsingHelper.ContainsKeys(new List<string> { "custom_campaign_name", "custom_campaign_days", "custom_campaign_icon_image_name", "email_subject", "email_in_main_campaign", "email_custom_campaign_name" }, json) && ParsingHelper.ContainsKeys(new List<string> { "modifier_custom_campaign_attached" }, json)) { return JSONParseTypes.Modifier; } if (!ParsingHelper.ContainsKeys(new List<string> { "custom_campaign_name", "custom_campaign_days", "custom_campaign_icon_image_name", "email_subject", "email_in_main_campaign", "email_custom_campaign_name" }, json) && ParsingHelper.ContainsKeys(new List<string> { "theme_custom_campaign_attached", "theme_name", "title_bar_color", "theme_in_main_campaign" }, json)) { return JSONParseTypes.Theme; } if (ParsingHelper.ContainsKeys(new List<string> { "ringtone_audio_clip_name" }, json)) { return JSONParseTypes.Ringtone; } if (ParsingHelper.ContainsKeys(new List<string> { "text_file_desktop_name", "text_file_unlock_day", "text_file_contents", "text_file_unlock_when_game_finished" }, json)) { return JSONParseTypes.TextProgram; } if (ParsingHelper.ContainsKeys(new List<string> { "cutscene_custom_campaign_name", "custom_cutscene_video_file", "custom_cutscene_priority" }, json)) { return JSONParseTypes.Cutscene; } if (ParsingHelper.ContainsKeys(new List<string> { "computer_3D_screen_custom_campaign_attached", "computer_3D_screen_in_main_campaign", "computer_3D_screen_priority", "computer_3D_screen_skip_click_wait_time" }, json)) { return JSONParseTypes.Computer3DScreen; } if (ParsingHelper.ContainsKeys(new List<string> { "link_app_custom_campaign_name", "link_app_unlock_day", "link_app_unlock_when_game_finished", "link_app_priority", "link_app_click_url" }, json)) { return JSONParseTypes.LinkApp; } return JSONParseTypes.Invalid; } } public static class ParsingHelper { public static bool ContainsKeys(List<string> keys, JObject json) { return ((IEnumerable<string>)keys).Any((Func<string, bool>)json.ContainsKey); } public static void TryAssign<T>(JObject jObjectParsed, string key, ref T target) { JToken val = default(JToken); if (jObjectParsed.TryGetValue(key, ref val)) { target = Extensions.Value<T>((IEnumerable<JToken>)val); } } public static void TryAssign<T>(JObject jObjectParsed, List<string> key, ref T target) { JToken val = default(JToken); foreach (string item in key) { if (jObjectParsed.TryGetValue(item, ref val)) { target = Extensions.Value<T>((IEnumerable<JToken>)val); } } } public static void TryAssignWithBool<T>(JObject jObjectParsed, string key, ref T target, ref bool wasAssigned) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { wasAssigned = false; return; } wasAssigned = true; target = Extensions.Value<T>((IEnumerable<JToken>)val); } public static void TryAssignWithChangedBool<T>(JObject jObjectParsed, string key, ref VariableChanged<T> target, bool setHasChangedToFalseOnFail = true) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { if (setHasChangedToFalseOnFail) { target.HasChanged = false; } } else { target.HasChanged = true; target.Data = Extensions.Value<T>((IEnumerable<JToken>)val); } } public static void TryAssignWithChangedBool<T>(JObject jObjectParsed, List<string> keys, ref VariableChanged<T> target) { target.HasChanged = false; foreach (string key in keys) { TryAssignWithChangedBool(jObjectParsed, key, ref target, setHasChangedToFalseOnFail: false); } } public static bool? TryAssignListOrSingleElement<T>(JObject jObjectParsed, string key, ref List<T> target) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return null; } if (target == null) { target = new List<T>(); } if ((int)val.Type == 2) { foreach (JToken item3 in (IEnumerable<JToken>)val) { T item = Extensions.Value<T>((IEnumerable<JToken>)item3); target.Add(item); } return false; } try { T item2 = Extensions.Value<T>((IEnumerable<JToken>)val); target.Add(item2); return true; } catch { LoggingHelper.ErrorLog("For provided key '" + key + "' we were unable of assigning any value, as the wrong value was given."); return null; } } public static bool? TryAssignListOrSingleElementVariableChanged<T>(JObject jObjectParsed, string key, ref VariableChanged<List<T>> target) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return null; } if (target.Data == null) { target.Data = new List<T>(); } if ((int)val.Type == 2) { foreach (JToken item3 in (IEnumerable<JToken>)val) { T item = Extensions.Value<T>((IEnumerable<JToken>)item3); target.Data.Add(item); } target.HasChanged = true; return false; } try { T item2 = Extensions.Value<T>((IEnumerable<JToken>)val); target.Data.Add(item2); target.HasChanged = true; return true; } catch { LoggingHelper.ErrorLog("For provided key '" + key + "' we were unable of assigning any value, as the wrong value was given."); return null; } } public static void TryAssignList<T>(JObject jObjectParsed, string key, ref List<T> target) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return; } if (target == null) { target = new List<T>(); } if ((int)val.Type == 2) { foreach (JToken item2 in (IEnumerable<JToken>)val) { T item = Extensions.Value<T>((IEnumerable<JToken>)item2); target.Add(item); } return; } LoggingHelper.ErrorLog("Provided key '" + key + "' does not contain a list."); } } public static class ReloadJSONParsing { public static bool IsInHotReload; public static void ReloadAllJSONFiles(GameObject resetButton) { resetButton.SetActive(false); MelonCoroutines.Start(StartHotReloading()); } private static IEnumerator StartHotReloading() { string activeCustomCampaignName = null; bool wasInCustomCampaign = false; if (CustomCampaignGlobal.InCustomCampaign) { activeCustomCampaignName = CustomCampaignGlobal.GetActiveCustomCampaign().CampaignName; wasInCustomCampaign = true; MainClassForMonsterEntries.AddedEntriesToCustomCampaign = false; CustomCampaignSceneSwitcher.BackToMainGame(alsoLoadMainMenu: false); yield return null; } IsInHotReload = true; LoggingHelper.DebugLog($"Current allocated memory (before hot reload): Allocated: '{Profiler.GetTotalAllocatedMemoryLong()}'; " + $"Reserved: '{Profiler.GetTotalReservedMemoryLong()}'.", LoggingHelper.LoggingCategory.MEMORY); AudioSource[] audioSources = Object.FindObjectsOfType<AudioSource>(); AudioSource[] array = audioSources; foreach (AudioSource audioSource in array) { audioSource.Stop(); ((Behaviour)audioSource).enabled = false; audioSource.clip = null; } yield return null; AudioCache.RemoveEntireCache(); CustomCampaignGlobal.CustomCampaignsAvailable.Clear(); GlobalParsingVariables.EntriesMetadata.Clear(); GlobalParsingVariables.MainGameThemes.Clear(); GlobalParsingVariables.MainCampaignEmails.Clear(); GlobalParsingVariables.CustomCallersMainGame.Clear(); GlobalParsingVariables.PendingCustomCampaignCustomCallers.Clear(); GlobalParsingVariables.PendingCustomCampaignEntries.Clear(); GlobalParsingVariables.PendingCustomCampaignReplaceEntries.Clear(); GlobalParsingVariables.PendingCustomCampaignEmails.Clear(); GlobalParsingVariables.PendingCustomCampaignMusic.Clear(); GlobalParsingVariables.PendingCustomCampaignModifiers.Clear(); GlobalParsingVariables.PendingCustomCampaignThemes.Clear(); GlobalParsingVariables.PendingCustomCampaignVideos.Clear(); GlobalParsingVariables.PendingCustomCampaignRingtones.Clear(); GlobalParsingVariables.PendingCustomCampaignTextFile.Clear(); GlobalParsingVariables.PendingCustomCampaignCutscenes.Clear(); EntryUnlockerPatcher.FixPermissionOverride.EntriesReaddTierOne.Clear(); EntryUnlockerPatcher.FixPermissionOverride.EntriesReaddTierTwo.Clear(); EntryUnlockerPatcher.FixPermissionOverride.EntriesReaddTierThree.Clear(); EntryUnlockerPatcher.FixPermissionOverride.EntriesReaddTierFour.Clear(); EntryUnlockerPatcher.FixPermissionOverride.EntriesReaddTierFive.Clear(); EntryUnlockerPatcher.FixPermissionOverride.EntriesReaddTierSix.Clear(); GlobalVariables.entryUnlockScript.firstTierUnlocks.monsterProfiles = MainClassForMonsterEntries.CopyTierUnlocks[0]; GlobalVariables.entryUnlockScript.secondTierUnlocks.monsterProfiles = MainClassForMonsterEntries.CopyTierUnlocks[1]; GlobalVariables.entryUnlockScript.thirdTierUnlocks.monsterProfiles = MainClassForMonsterEntries.CopyTierUnlocks[2]; GlobalVariables.entryUnlockScript.fourthTierUnlocks.monsterProfiles = MainClassForMonsterEntries.CopyTierUnlocks[3]; GlobalVariables.entryUnlockScript.fifthTierUnlocks.monsterProfiles = MainClassForMonsterEntries.CopyTierUnlocks[4]; GlobalVariables.entryUnlockScript.sixthTierUnlocks.monsterProfiles = MainClassForMonsterEntries.CopyTierUnlocks[5]; GlobalVariables.entryUnlockScript.xmastFirstTier.monsterProfiles = MainClassForMonsterEntries.CopyXmasTier[0]; GlobalVariables.entryUnlockScript.xmasSecondTier.monsterProfiles = MainClassForMonsterEntries.CopyXmasTier[1]; GlobalVariables.entryUnlockScript.xmasThirdTier.monsterProfiles = MainClassForMonsterEntries.CopyXmasTier[2]; GlobalVariables.entryUnlockScript.xmasFourthTier.monsterProfiles = MainClassForMonsterEntries.CopyXmasTier[3]; GlobalParsingVariables.CustomCampaignEntryIDOffset = 100000; GlobalVariables.entryUnlockScript.allEntries.monsterProfiles = MainClassForMonsterEntries.CopyMonsterProfiles; yield return Resources.UnloadUnusedAssets(); GC.Collect(2, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced); yield return Resources.UnloadUnusedAssets(); yield return null; LoggingHelper.DebugLog($"Current allocated memory (after clear): Allocated: '{Profiler.GetTotalAllocatedMemoryLong()}'; " + $"Reserved: '{Profiler.GetTotalReservedMemoryLong()}'.", LoggingHelper.LoggingCategory.MEMORY); MainClassForMonsterEntries.StartingJSONParsing(GlobalVariables.entryUnlockScript); LoggingHelper.DebugLog($"Current allocated memory (after loading all JSON files): Allocated: '{Profiler.GetTotalAllocatedMemoryLong()}'; " + $"Reserved: '{Profiler.GetTotalReservedMemoryLong()}'.", LoggingHelper.LoggingCategory.MEMORY); if (wasInCustomCampaign && !string.IsNullOrEmpty(activeCustomCampaignName)) { MelonCoroutines.Start(LoadCustomCampaign(activeCustomCampaignName)); yield break; } SceneManager.LoadScene("MainMenuScene"); IsInHotReload = false; } private static IEnumerator LoadCustomCampaign(string activeCustomCampaignName) { SceneManager.LoadScene("MainMenuScene"); Scene activeScene; while (true) { activeScene = SceneManager.GetActiveScene(); int num; if (!(((Scene)(ref activeScene)).name != "MainMenuScene")) { activeScene = SceneManager.GetActiveScene(); num = ((!((Scene)(ref activeScene)).isLoaded) ? 1 : 0); } else { num = 1; } if (num == 0) { break; } yield return null; } for (int i = 0; i < 10; i++) { yield return null; } MelonCoroutines.Start(CustomCampaignSceneSwitcher.ChangeToCustomCampaignSettings(activeCustomCampaignName, inHotReload: true)); while (true) { activeScene = SceneManager.GetActiveScene(); int num2; if (!(((Scene)(ref activeScene)).name != "MainMenuScene")) { activeScene = SceneManager.GetActiveScene(); num2 = ((!((Scene)(ref activeScene)).isLoaded) ? 1 : 0); } else { num2 = 1; } if (num2 == 0) { break; } yield return null; } yield return null; IsInHotReload = false; } } } namespace NewSafetyHelp.JSONParsing.ParsingHelpers { public static class AccuracyParsingHelper { private const string AccuracyCheckTypeString = "accuracy_check_type"; private const string AccuracyRequiredString = "accuracy_required"; private const string TotalAccuracyString = "use_total_accuracy"; private static AccuracyHelper.CheckOptions TryAssignSingleAccuracyType(string accuracyCheckTypeString) { if (!string.IsNullOrEmpty(accuracyCheckTypeString)) { switch (accuracyCheckTypeString.ToLowerInvariant()) { case "equal": case "eq": return AccuracyHelper.CheckOptions.EqualTo; case "": case "no": case "n": case "none": return AccuracyHelper.CheckOptions.NoneSet; case "greaterorequal": case "geq": return AccuracyHelper.CheckOptions.GreaterThanOrEqualTo; case "lesserorequal": case "lessorequal": case "leq": return AccuracyHelper.CheckOptions.LessThanOrEqualTo; case "nequal": case "notequal": case "!equal": case "!eq": case "noteq": case "neq": return AccuracyHelper.CheckOptions.NotEqualTo; default: LoggingHelper.WarningLog("Provided accuracy check type '" + accuracyCheckTypeString + "' is not in any known format. Please double check."); return AccuracyHelper.CheckOptions.NoneSet; } } LoggingHelper.WarningLog("Unable of parsing accuracy check type. Possible syntax problem?"); return AccuracyHelper.CheckOptions.NoneSet; } public static bool TryAssignListAccuracyType(JObject jObjectParsed, ref List<CallerAccuracyType> target) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue("accuracy_check_type", ref val)) { return false; } if (target == null) { target = new List<CallerAccuracyType>(); } List<bool> target2 = new List<bool>(); bool? flag = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, "use_total_accuracy", ref target2); List<float> target3 = new List<float>(); ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, "accuracy_required", ref target3); List<string> target4 = new List<string>(); ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, "accuracy_check_type", ref target4); if (target4.Count < 1) { LoggingHelper.ErrorLog("Provided accuracy lists are empty or could not be parsed. Unable of parsing accuracy checks."); return false; } if (target3.Count != target4.Count) { LoggingHelper.ErrorLog("Provided accuracy lists must all have equal length. Unable of parsing accuracy checks."); return false; } if (target2.Count > target4.Count) { LoggingHelper.ErrorLog("Provided list of total accuracy is larger than available accuracy checks. Unable of parsing accuracy checks."); return false; } for (int i = 0; i < target4.Count; i++) { CallerAccuracyType callerAccuracyType = new CallerAccuracyType(); if (!string.IsNullOrEmpty(target4[i])) { callerAccuracyType.AccuracyCheck = TryAssignSingleAccuracyType(target4[i]); } else { LoggingHelper.WarningLog("Provided accuracy type is invalid. Defaulting to 'none'."); } if (flag.HasValue) { if (flag.Value && target2.Count > 0) { callerAccuracyType.UseTotalAccuracy = target2[0]; } else if (i < target2.Count) { callerAccuracyType.UseTotalAccuracy = target2[i]; } } callerAccuracyType.RequiredAccuracy = target3[i]; target.Add(callerAccuracyType); } return true; } public static void TryAssignListGeneralAccuracyType(JObject jObjectParsed, ref List<GeneralAccuracyType> target, ref bool isUsingOldSystem, string requiredAccuracyKey = "email_required_accuracy", string accuracyDaysKey = "email_accuracy_days", string accuracyCheckTypesKey = "email_accuracy_check_type") { isUsingOldSystem = true; JToken val = default(JToken); if (!jObjectParsed.TryGetValue(requiredAccuracyKey, ref val)) { return; } if (target == null) { target = new List<GeneralAccuracyType>(); } List<int> target2 = new List<int>(); bool? flag = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, accuracyDaysKey, ref target2); List<float> target3 = new List<float>(); ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, requiredAccuracyKey, ref target3); List<string> target4 = new List<string>(); bool? flag2 = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, accuracyCheckTypesKey, ref target4); if (flag2.HasValue && (!flag2).Value && target3.Count != target4.Count) { if (target3.Count < target4.Count) { LoggingHelper.ErrorLog("Provided accuracy lists must all should have equal length. Unable of parsing accuracy checks."); return; } if (target4.Count >= 1) { LoggingHelper.WarningLog("Provided accuracy lists must all should have equal length. Adding any missing accuracy checks with 'geq' (greater or equal)."); } while (target4.Count < target3.Count) { target4.Add("geq"); } } if (target4.Count > 0 || target4.Count > 0 || target2.Count > 0) { isUsingOldSystem = false; } for (int i = 0; i < target4.Count; i++) { GeneralAccuracyType generalAccuracyType = new GeneralAccuracyType(); if (flag2.HasValue) { if (flag2.Value && target4.Count > 0) { generalAccuracyType.AccuracyCheck = TryAssignSingleAccuracyType(target4[0]); } else if (i < target4.Count) { if (!string.IsNullOrEmpty(target4[i])) { generalAccuracyType.AccuracyCheck = TryAssignSingleAccuracyType(target4[i]); } else { LoggingHelper.WarningLog("Provided general accuracy type is invalid. Defaulting to 'greater or equal'."); generalAccuracyType.AccuracyCheck = AccuracyHelper.CheckOptions.GreaterThanOrEqualTo; } } } if (flag.HasValue) { if (flag.Value && target2.Count > 0) { generalAccuracyType.CheckDay = target2[0]; } else if (i < target2.Count) { generalAccuracyType.CheckDay = target2[i]; } } generalAccuracyType.RequiredAccuracy = target3[i]; target.Add(generalAccuracyType); } } } public static class ArtbookParsingHelper { public static void ParseArtbookPages(JObject jObjectParsed, ref List<ArtbookPage> target, string jsonFolderPath, string usermodFolderPath, string firstImageKey = "artbook_page_first_images", string secondImageKey = "artbook_page_second_images", string titleKey = "artbook_page_titles", string descriptionKey = "artbook_page_descriptions") { if (target == null) { target = new List<ArtbookPage>(); } List<Sprite> target2 = new List<Sprite>(); bool? flag = ImageParsingHelper.TryAssignSpriteListOrSingleSprite(jObjectParsed, firstImageKey, ref target2, jsonFolderPath, usermodFolderPath); List<Sprite> target3 = new List<Sprite>(); bool? flag2 = ImageParsingHelper.TryAssignSpriteListOrSingleSprite(jObjectParsed, secondImageKey, ref target3, jsonFolderPath, usermodFolderPath, ignoreIfNull: true); List<string> target4 = new List<string>(); bool? flag3 = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, titleKey, ref target4); List<string> target5 = new List<string>(); bool? flag4 = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, descriptionKey, ref target5); JToken val = default(JToken); if (target2.Count <= 0 && target3.Count <= 0 && target4.Count <= 0 && target5.Count <= 0 && (jObjectParsed.TryGetValue(firstImageKey, ref val) || jObjectParsed.TryGetValue(descriptionKey, ref val))) { LoggingHelper.WarningLog("Provided artbook pages are invalid or could not be parsed. No artbook pages will be updated."); return; } if (target2.Count < target3.Count) { LoggingHelper.WarningLog("Artbook second Images list is greater than the first artbook images. You need more or equal the amount of first images. No artbook pages will be updated."); return; } int num = new List<int> { target2.Count, target3.Count, target5.Count, target4.Count }.Max(); for (int i = 0; i < num; i++) { ArtbookPage val2 = ScriptableObject.CreateInstance<ArtbookPage>(); val2.title = ""; val2.description = ""; val2.image = null; val2.image2 = null; if (flag.HasValue) { if (flag.Value && target2.Count > 0) { val2.image = target2[0]; } else if (i < target2.Count) { val2.image = target2[i]; } } if (flag2.HasValue) { if (flag2.Value && target3.Count > 0) { val2.image2 = target3[0]; } else if (i < target3.Count) { val2.image2 = target3[i]; } } if (flag3.HasValue) { if (flag3.Value && target4.Count > 0) { val2.title = target4[0]; } else if (i < target4.Count) { val2.title = target4[i]; } } if (flag4.HasValue) { if (flag4.Value && target5.Count > 0) { val2.description = target5[0]; } else if (i < target5.Count) { val2.description = target5[i]; } } target.Add(val2); } } } public static class AudioParsingHelper { public static void UpdateAudioAtLocation(JObject jObjectParsed, string audioLocation, Action<RichAudioClip> setAudioClip, string jsonFolderPath, string key = "audio_clip_location") { if (setAudioClip == null) { LoggingHelper.ErrorLog("Provided lambda function was not set. Unable of updating the audio."); } else { if (!jObjectParsed.ContainsKey(key)) { return; } if (string.IsNullOrEmpty(audioLocation)) { LoggingHelper.WarningLog("No valid audio file given for file in " + jsonFolderPath + "."); return; } if (!File.Exists(audioLocation)) { LoggingHelper.ErrorLog("Location " + jsonFolderPath + " does not contain '" + audioLocation + "'. Unable of adding the audio."); return; } MelonCoroutines.Start(AudioImport.UpdateAudioClip(delegate(AudioClip myReturnValue) { if ((Object)(object)myReturnValue != (Object)null) { setAudioClip(AudioImport.CreateRichAudioClip(myReturnValue)); } else { LoggingHelper.ErrorLog("Failed to load audio clip '" + audioLocation + "'."); } }, audioLocation, (AudioType)20)); } } public static void UpdateAudioAtLocation(JObject jObjectParsed, VariableChanged<string> audioLocation, Action<RichAudioClip> setAudioClip, string jsonFolderPath, string key = "audio_clip_location") { if (audioLocation.HasChanged) { UpdateAudioAtLocation(jObjectParsed, audioLocation.Data, setAudioClip, jsonFolderPath, key); } } public static void UpdateAudioAtLocationNoKey(string audioLocation, Action<RichAudioClip> setAudioClip, string jsonFolderPath) { if (setAudioClip == null) { LoggingHelper.ErrorLog("Provided lambda function was not set. Unable of updating the audio."); return; } if (string.IsNullOrEmpty(audioLocation)) { LoggingHelper.WarningLog("No valid audio file given for file in " + jsonFolderPath + "."); return; } if (!File.Exists(audioLocation)) { LoggingHelper.ErrorLog("Location " + jsonFolderPath + " does not contain '" + audioLocation + "'. Unable of adding the audio."); return; } MelonCoroutines.Start(AudioImport.UpdateAudioClip(delegate(AudioClip myReturnValue) { if ((Object)(object)myReturnValue != (Object)null) { setAudioClip(AudioImport.CreateRichAudioClip(myReturnValue)); } else { LoggingHelper.ErrorLog("Failed to load audio clip '" + audioLocation + "'."); } }, audioLocation, (AudioType)20)); } public static void TryAssignAudioPath(JObject jObjectParsed, string key, ref string target, string jsonFolderPath, string usermodFolderPath, string nameOfTarget = null) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return; } string text = Extensions.Value<string>((IEnumerable<JToken>)val); if (File.Exists(text)) { target = text; } else if (!File.Exists(jsonFolderPath + "\\" + text)) { if (!File.Exists(usermodFolderPath + "\\" + text)) { LoggingHelper.WarningLog("Could not find provided audio file for key '" + key + "' at '" + jsonFolderPath + "' (For Audio '" + text + "')."); if (nameOfTarget != null) { LoggingHelper.WarningLog("For '" + nameOfTarget + "'."); } } else { target = usermodFolderPath + "\\" + text; } } else { target = jsonFolderPath + "\\" + text; } } public static void TryAssignAudioPathWithChangedBool(JObject jObjectParsed, string key, ref VariableChanged<string> target, string jsonFolderPath, string usermodFolderPath, string nameOfTarget = null) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return; } string text = Extensions.Value<string>((IEnumerable<JToken>)val); if (File.Exists(text)) { target.Data = text; target.HasChanged = true; } else if (!File.Exists(jsonFolderPath + "\\" + text)) { if (!File.Exists(usermodFolderPath + "\\" + text)) { LoggingHelper.WarningLog("Could not find provided audio file for key '" + key + "' at '" + jsonFolderPath + "' (For Audio '" + text + "')."); if (nameOfTarget != null) { LoggingHelper.WarningLog("For '" + nameOfTarget + "'."); } } else { target.Data = usermodFolderPath + "\\" + text; target.HasChanged = true; } } else { target.Data = jsonFolderPath + "\\" + text; target.HasChanged = true; } } } public static class CallerRequirementParsingHelper { public static void TryAssignCallerRequirement(JObject jObjectParsed, ref List<CallerRequirement> target, string callerRequirementIDKey = "email_caller_requirement_ids", string callerCorrectnessKey = "email_caller_requirement_should_be_correct") { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(callerRequirementIDKey, ref val)) { return; } if (target == null) { target = new List<CallerRequirement>(); } List<int> target2 = new List<int>(); ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, callerRequirementIDKey, ref target2); List<bool> target3 = new List<bool>(); bool? flag = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, callerCorrectnessKey, ref target3); if (target3.Count > target2.Count) { LoggingHelper.WarningLog("Too many caller correctness given, the given caller requirement will not use all elements.If this is intentional, then no action is required."); } for (int i = 0; i < target2.Count; i++) { CallerRequirement callerRequirement = new CallerRequirement { CallerID = target2[i] }; if (flag.HasValue) { if (flag.Value && target3.Count > 0) { callerRequirement.ShouldCallerBeCorrect = target3[0]; } else if (i < target3.Count) { callerRequirement.ShouldCallerBeCorrect = target3[i]; } } target.Add(callerRequirement); } } } public static class ColorParsingHelper { public static void SetColor(ref JToken jsonValue, ref ColorPalette themeColorPalette, int colorIndex) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if ((int)jsonValue.Type != 2) { return; } List<float> list = new List<float>(); foreach (JToken item in (JArray)jsonValue) { list.Add(Extensions.Value<float>((IEnumerable<JToken>)item)); } switch (list.Count) { case 3: themeColorPalette.colorSwatch[colorIndex] = new Color(ColorHelper.GetConvertedColorFloat(list[0]), ColorHelper.GetConvertedColorFloat(list[1]), ColorHelper.GetConvertedColorFloat(list[2])); break; case 4: themeColorPalette.colorSwatch[colorIndex] = new Color(ColorHelper.GetConvertedColorFloat(list[0]), ColorHelper.GetConvertedColorFloat(list[1]), ColorHelper.GetConvertedColorFloat(list[2]), ColorHelper.GetConvertedColorFloat(list[3])); break; default: LoggingHelper.ErrorLog("Provided color for setting color is invalid! Make sure it's 3 or 4 values."); break; } } public static void SetColor(ref JToken jsonValue, ref Color parsedColor) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if ((int)jsonValue.Type != 2) { return; } List<float> list = new List<float>(); foreach (JToken item in (JArray)jsonValue) { list.Add(Extensions.Value<float>((IEnumerable<JToken>)item)); } switch (list.Count) { case 3: parsedColor = new Color(ColorHelper.GetConvertedColorFloat(list[0]), ColorHelper.GetConvertedColorFloat(list[1]), ColorHelper.GetConvertedColorFloat(list[2])); break; case 4: parsedColor = new Color(ColorHelper.GetConvertedColorFloat(list[0]), ColorHelper.GetConvertedColorFloat(list[1]), ColorHelper.GetConvertedColorFloat(list[2]), ColorHelper.GetConvertedColorFloat(list[3])); break; default: LoggingHelper.ErrorLog("Provided color for setting color is invalid! Make sure it's 3 or 4 values."); break; } } public static void SetColor(ref JToken jsonValue, ref VariableChanged<Color> parsedColor) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if ((int)jsonValue.Type != 2) { return; } List<float> list = new List<float>(); foreach (JToken item in (JArray)jsonValue) { list.Add(Extensions.Value<float>((IEnumerable<JToken>)item)); } switch (list.Count) { case 3: parsedColor.Data = new Color(ColorHelper.GetConvertedColorFloat(list[0]), ColorHelper.GetConvertedColorFloat(list[1]), ColorHelper.GetConvertedColorFloat(list[2])); parsedColor.HasChanged = true; break; case 4: parsedColor.Data = new Color(ColorHelper.GetConvertedColorFloat(list[0]), ColorHelper.GetConvertedColorFloat(list[1]), ColorHelper.GetConvertedColorFloat(list[2]), ColorHelper.GetConvertedColorFloat(list[3])); parsedColor.HasChanged = true; break; default: LoggingHelper.ErrorLog("Provided color for setting color is invalid! Make sure it's 3 or 4 values."); break; } } public static void ParseColor(JObject jObjectParsed, string key, ref Color target) { JToken jsonValue = default(JToken); if (jObjectParsed.TryGetValue(key, ref jsonValue)) { SetColor(ref jsonValue, ref target); } } public static void ParseColor(JObject jObjectParsed, string key, ref VariableChanged<Color> target) { JToken jsonValue = default(JToken); if (jObjectParsed.TryGetValue(key, ref jsonValue)) { SetColor(ref jsonValue, ref target); } } } public static class IDParsingHelper { private static int GetNewEntryID(EntryUnlockController entryUnlocker, int type = 0) { return type switch { 0 => entryUnlocker.allEntries.monsterProfiles.Length, 1 => entryUnlocker.allXmasEntries.monsterProfiles.Length, _ => entryUnlocker.allEntries.monsterProfiles.Length, }; } public static void GenerateNewID(ref EntryMetadata newExtra, ref int newID, ref bool replaceEntry, ref string jsonFolderPath, ref bool onlyDlc, ref bool includeDlc, ref EntryUnlockController entryUnlockerInstance, ref bool inCustomCampaign) { if (newID == -1 && !replaceEntry && !inCustomCampaign) { int newEntryID = GetNewEntryID(entryUnlockerInstance); int newEntryID2 = GetNewEntryID(entryUnlockerInstance, 1); LoggingHelper.DebugLog($"Entries in Main Campaign: {newEntryID} and entries in DLC: {newEntryID2}."); if (onlyDlc) { newID = newEntryID2; } else if (includeDlc) { newID = ((newEntryID < newEntryID2) ? newEntryID2 : newEntryID); } else { newID = newEntryID; } } if ((newID == -1 && !replaceEntry) & inCustomCampaign) { int newEntryID3 = GetNewEntryID(entryUnlockerInstance); newEntryID3 += GlobalParsingVariables.CustomCampaignEntryIDOffset; GlobalParsingVariables.CustomCampaignEntryIDOffset++; newID = newEntryID3; } newExtra.ID = newID; LoggingHelper.InfoLog($"Defaulting to a new Monster ID {newExtra.ID} for file in {jsonFolderPath}."); LoggingHelper.InfoLog("(This is the intended and recommended way of providing the ID.)"); } } public static class ImageParsingHelper { public static bool TryAssignSprite(JObject jObjectParsed, string key, ref Sprite target, string jsonFolderPath, string usermodFolderPath, string customCampaignName = null) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return false; } string text = Extensions.Value<string>((IEnumerable<JToken>)val); if (string.IsNullOrEmpty(text)) { LoggingHelper.ErrorLog("Invalid file name given for '" + text + "' for key " + key + ". Not updating " + ((!string.IsNullOrEmpty(customCampaignName)) ? ("for " + customCampaignName + ".") : ".")); } else { target = ImageImport.LoadImage(jsonFolderPath + "\\" + text, usermodFolderPath + "\\" + text); } return true; } public static bool? TryAssignSpriteListOrSingleSprite(JObject jObjectParsed, string key, ref List<Sprite> target, string jsonFolderPath, string usermodFolderPath, bool ignoreIfNull = false) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return null; } if (target == null) { target = new List<Sprite>(); } if ((int)val.Type == 2) { TryAssignSpriteList(jObjectParsed, key, ref target, jsonFolderPath, usermodFolderPath, ignoreIfNull); return false; } try { Sprite item = null; string text = Extensions.Value<string>((IEnumerable<JToken>)val); if (string.IsNullOrEmpty(text)) { LoggingHelper.ErrorLog("Invalid file name given for '" + text + "' for key " + key + "."); } else { item = ImageImport.LoadImage(jsonFolderPath + "\\" + text, usermodFolderPath + "\\" + text); } target.Add(item); return true; } catch { LoggingHelper.ErrorLog("For provided key '" + key + "' we were unable of assigning any value, as the wrong value was given."); return null; } } public static bool TryAssignSpriteList(JObject jObjectParsed, string key, ref List<Sprite> target, string jsonFolderPath, string usermodFolderPath, bool ignoreIfNull = false) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return false; } JArray val2 = (JArray)val; foreach (JToken item in val2) { string text = Extensions.Value<string>((IEnumerable<JToken>)item); if (string.IsNullOrEmpty(text)) { if (ignoreIfNull) { target.Add(null); continue; } LoggingHelper.ErrorLog("Invalid file name given for '" + text + "' for key " + key + "."); } else { target.Add(ImageImport.LoadImage(jsonFolderPath + "\\" + text, usermodFolderPath + "\\" + text)); } } return true; } public static bool? TryAssignSpriteListOrSingleSpriteVariableChanged(JObject jObjectParsed, string key, ref VariableChanged<List<Sprite>> target, string jsonFolderPath, string usermodFolderPath, bool ignoreIfNull = false) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return null; } if (target.Data == null) { target.Data = new List<Sprite>(); } if ((int)val.Type == 2) { TryAssignSpriteList(jObjectParsed, key, ref target.Data, jsonFolderPath, usermodFolderPath, ignoreIfNull); if (target.Data.Count > 0) { target.HasChanged = true; } return false; } try { Sprite item = null; string text = Extensions.Value<string>((IEnumerable<JToken>)val); if (string.IsNullOrEmpty(text)) { LoggingHelper.ErrorLog("Invalid file name given for '" + text + "' for key " + key + "."); } else { item = ImageImport.LoadImage(jsonFolderPath + "\\" + text, usermodFolderPath + "\\" + text); } target.Data.Add(item); target.HasChanged = true; return true; } catch { LoggingHelper.ErrorLog("For provided key '" + key + "' we were unable of assigning any value, as the wrong value was given."); return null; } } public static bool TryAssignSpriteListVariableChanged(JObject jObjectParsed, string key, ref VariableChanged<List<Sprite>> target, string jsonFolderPath, string usermodFolderPath, bool ignoreIfNull = false) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return false; } if (target.Data == null) { target.Data = new List<Sprite>(); } JArray val2 = (JArray)val; foreach (JToken item in val2) { string text = Extensions.Value<string>((IEnumerable<JToken>)item); if (string.IsNullOrEmpty(text)) { if (ignoreIfNull) { target.Data.Add(null); continue; } LoggingHelper.ErrorLog("Invalid file name given for '" + text + "' for key " + key + "."); } else { target.Data.Add(ImageImport.LoadImage(jsonFolderPath + "\\" + text, usermodFolderPath + "\\" + text)); } } if (target.Data.Count > 0) { target.HasChanged = true; } return true; } public static void TryAssignSpriteChanged(JObject jObjectParsed, string key, ref VariableChanged<Sprite> target, string jsonFolderPath, string usermodFolderPath, string customCampaignName = null) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return; } string text = Extensions.Value<string>((IEnumerable<JToken>)val); target = new VariableChanged<Sprite>(); if (string.IsNullOrEmpty(text)) { LoggingHelper.ErrorLog("Invalid file name given for '" + text + "' for key " + key + ". Not updating " + ((!string.IsNullOrEmpty(customCampaignName)) ? ("for " + customCampaignName + ".") : ".")); } else { Sprite val2 = ImageImport.LoadImage(jsonFolderPath + "\\" + text, usermodFolderPath + "\\" + text); if ((Object)(object)val2 != (Object)null) { LoggingHelper.DebugLog("Loaded in sprite (image) '" + text + "' successfully."); target.HasChanged = true; target.Data = val2; } } } } public static class PendingParsingHelper { public static void AddPendingElementsToCampaign<T>(ref List<T> pendingList, ref List<T> listToBeAddedTo, string customCampaignName, string elementName = "NO_NAME_GIVEN") where T : CustomCampaignElementBase { if (pendingList.Count <= 0) { return; } List<T> list = new List<T>(pendingList); foreach (T item in list) { if (item.CustomCampaignName == customCampaignName) { LoggingHelper.DebugLog("Adding missing " + elementName + " to the custom campaign: " + customCampaignName + "."); listToBeAddedTo.Add(item); pendingList.Remove(item); } } } } public static class URLParsingHelper { public static bool TryAssignURL(JObject jObjectParsed, string key, ref Uri target) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return false; } string stringURL = Extensions.Value<string>((IEnumerable<JToken>)val); if (!URLVerification.SetClickURL(stringURL, ref target)) { LoggingHelper.WarningLog("Provided URL with the key '" + key + "' is invalid. Unable of setting url."); return false; } LoggingHelper.DebugLog("Found click URL: '" + target.AbsoluteUri.Substring(0, 10) + "[...]'. It has been marked as valid."); return true; } } public static class VideoParsingHelper { public enum VideoType { AVI, MOV, MP4, MPEG, ASF, NONE } public static bool IsKnownVideoExtension(string filePath) { if (!File.Exists(filePath)) { LoggingHelper.ErrorLog("Provided video '" + filePath + "' could not be found."); return false; } string text = Path.GetExtension(filePath).ToLowerInvariant().Trim(); if (string.IsNullOrEmpty(text)) { LoggingHelper.WarningLog("Provided video file extension for video '" + filePath + "' is empty. Will attempt to find correct format."); return false; } switch (text) { case ".asf": case ".avi": case ".dv": case ".m4v": case ".mov": case ".mp4": case ".mpg": case ".mpeg": case ".ogv": case ".vp8": case ".webm": case ".wmv": return true; default: LoggingHelper.InfoLog("Provided video file extension for video '" + filePath + "' is unknown. Will attempt to find correct format."); return false; } } public static VideoType TryFindingVideoType(string filePath) { using FileStream input = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); using BinaryReader binaryReader = new BinaryReader(input); byte[] array = binaryReader.ReadBytes(16); if (array.Length < 16) { LoggingHelper.ErrorLog("Provided video file at '" + filePath + "' is too small to be considered a video file. Unable of assigning video."); return VideoType.NONE; } return MatchSignature(array); } private static VideoType MatchSignature(byte[] headerByteArray) { if (headerByteArray.Length < 16) { LoggingHelper.ErrorLog("Provided header bytes are less than 16, unable of properly checking for video type."); return VideoType.NONE; } string text = Encoding.ASCII.GetString(headerByteArray, 4, 4).ToLower().Trim(); if (text == "ftyp") { string text2 = Encoding.ASCII.GetString(headerByteArray, 8, 4).ToLower().Trim(); if (text2 == "qt") { return VideoType.MOV; } return VideoType.MP4; } string text3 = Encoding.ASCII.GetString(headerByteArray, 0, 4).ToLower().Trim(); string text4 = Encoding.ASCII.GetString(headerByteArray, 8, 4).ToLower().Trim(); if (text3 == "riff" && text4 == "avi") { return VideoType.AVI; } if (headerByteArray[0] == 0 && headerByteArray[1] == 0 && headerByteArray[2] == 1 && (headerByteArray[3] == 186 || headerByteArray[3] == 179)) { return VideoType.MPEG; } byte[] second = new byte[16] { 48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108 }; if (headerByteArray.Take(16).SequenceEqual(second)) { return VideoType.ASF; } return VideoType.NONE; } [CanBeNull] public static string GetVideoTypeExtension(VideoType videoType) { switch (videoType) { case VideoType.AVI: return ".avi"; case VideoType.MOV: return ".mov"; case VideoType.MP4: return ".mp4"; case VideoType.MPEG: return ".mpeg"; case VideoType.ASF: return ".wmv"; default: LoggingHelper.ErrorLog("Unsupported video type '" + videoType.ToString() + "' provided. Could not get file extension."); return null; } } public static (bool createdTemptFile, string pathToTempFile) CreateTempVideoFile(string currentFilePath, VideoType videoType) { if (string.IsNullOrEmpty(currentFilePath)) { LoggingHelper.ErrorLog("Provided file path is empty. Unable of creating temporary copy."); return (createdTemptFile: false, pathToTempFile: ""); } if (videoType == VideoType.NONE) { LoggingHelper.ErrorLog("Video type is not known. Unable of creating temporary copy."); return (createdTemptFile: false, pathToTempFile: ""); } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(currentFilePath); string videoTypeExtension = GetVideoTypeExtension(videoType); if (string.IsNullOrEmpty(videoTypeExtension)) { LoggingHelper.ErrorLog("Failed getting a file extension. Unable of creating temporary copy."); return (createdTemptFile: false, pathToTempFile: ""); } if (string.IsNullOrEmpty(fileNameWithoutExtension)) { LoggingHelper.ErrorLog("Failed getting file path for '" + currentFilePath + "' without extension. Unable of creating temporary copy."); return (createdTemptFile: false, pathToTempFile: ""); } string text = Path.Combine(Path.GetTempPath(), string.Format("{0}{1}_{2}{3}", "NewSafetyHelp_", fileNameWithoutExtension, Guid.NewGuid(), videoTypeExtension)); try { File.Copy(currentFilePath, text, overwrite: true); LoggingHelper.DebugLog("Created copy of the video file at '" + text + "'."); } catch (Exception arg) { LoggingHelper.DebugLog($"Failec creating a copy at '{text}'. Reason: \n'\n{arg}\n'."); return (createdTemptFile: false, pathToTempFile: text); } return (createdTemptFile: true, pathToTempFile: text); } public static bool? TryAssignUrlListOrSingleUrl(JObject jObjectParsed, string key, ref List<string> target, string jsonFolderPath, string usermodFolderPath) { bool? result = ParsingHelper.TryAssignListOrSingleElement(jObjectParsed, key, ref target); for (int i = 0; i < target.Count; i++) { if (string.IsNullOrEmpty(target[i])) { LoggingHelper.WarningLog("Provided video path is empty. Unable to show video."); continue; } string text = jsonFolderPath + "\\" + target[i]; string text2 = usermodFolderPath + "\\" + target[i]; string text3 = ""; if (File.Exists(target[i])) { text3 = target[i]; } else if (File.Exists(text)) { text3 = text; } else if (File.Exists(text2)) { text3 = text2; } else if (!File.Exists(text) && !File.Exists(text2)) { LoggingHelper.ErrorLog("Could not find video '" + target[i] + "' in either: '" + text + "' or '" + text2 + "'."); text3 = ""; } if (IsKnownVideoExtension(text3)) { target[i] = text3; continue; } VideoType videoType = TryFindingVideoType(text3); bool flag = false; VideoType videoType2 = videoType; VideoType videoType3 = videoType2; if (videoType3 == VideoType.NONE) { LoggingHelper.ErrorLog("Provided video file at '" + text3 + "' could not be understood. Possible unsupported file format."); } else { flag = true; LoggingHelper.InfoLog("Provided video file '" + text3 + "' was interpreted as a '" + videoType.ToString() + "'."); } if (flag) { var (flag2, value) = CreateTempVideoFile(text3, videoType); if (flag2) { target[i] = value; continue; } LoggingHelper.ErrorLog("Failed creating a temporary copy of the video. Not showing video."); target[i] = ""; } else { LoggingHelper.InfoLog("Video type at '" + text3 + "' seems to be unsupported. Attempting to still use it."); target[i] = text3; } } return result; } public static bool TryAssignVideoPath(JObject jObjectParsed, string key, ref string target, string jsonFolderPath, string usermodFolderPath) { JToken val = default(JToken); if (!jObjectParsed.TryGetValue(key, ref val)) { return false; } string text = Extensions.Value<string>((IEnumerable<JToken>)val); string text2 = jsonFolderPath + "\\" + text; string text3 = usermodFolderPath + "\\" + text; if (string.IsNullOrEmpty(text)) { LoggingHelper.WarningLog("Provided video path is empty. Unable to show video."); target = ""; } else { string text4; if (File.Exists(text)) { text4 = text; } else if (File.Exists(text2)) { text4 = text2; } else { if (!File.Exists(text3)) { LoggingHelper.ErrorLog("Provided video '" + text + "' could not be found in either '" + text2 + "' or '" + text3 + "'."); target = ""; return true; } text4 = text3; } if (IsKnownVideoExtension(text4)) { target = text4; } else { VideoType videoType = TryFindingVideoType(text4); bool flag = false; VideoType videoType2 = videoType; VideoType videoType3 = videoType2; if (videoType3 == VideoType.NONE) { LoggingHelper.ErrorLog("Provided video file at '" + text4 + "' could not be understood. Possible unsupported file format."); } else { flag = true; LoggingHelper.InfoLog("Provided video file '" + text4 + "' was interpreted as a '" + videoType.ToString() + "'."); } if (flag) { var (flag2, text5) = CreateTempVideoFile(text4, videoType); if (flag2) { target = text5; } else { LoggingHelper.ErrorLog("Failed creating a temporary copy of the video. Not showing video."); target = ""; } } else { LoggingHelper.InfoLog("Video type at '" + text4 + "' seems to be unsupported. Attempting to still use it."); target = text4; } } } return true; } } } namespace NewSafetyHelp.JSONParsing.EntryParsing { public static class MainCampaignCallerParsing { public static void ParseCaller(ref JObject jsonObjectParsed, ref string usermodFolderPath, ref string jsonFolderPath, ref string callerName, ref string callerTranscript, ref string callerImageLocation, ref float callerReplaceChance, ref bool callerRestartCallAgain, ref Sprite callerPortrait) { ParsingHelper.TryAssign(jsonObjectParsed, "caller_name", ref callerName); ParsingHelper.TryAssign(jsonObjectParsed, "caller_transcript", ref callerTranscript); ParsingHelper.TryAssign(jsonObjectParsed, "caller_image_name", ref callerImageLocation); ImageParsingHelper.TryAssignSprite(jsonObjectParsed, "caller_image_name", ref callerPortrait, jsonFolderPath, usermodFolderPath, callerName); ParsingHelper.TryAssign(jsonObjectParsed, "caller_chance", ref callerReplaceChance); ParsingHelper.TryAssign(jsonObjectParsed, "allow_calling_again_over_restarts", ref callerRestartCallAgain); } public static void ParseConsequenceCaller(ref JObject jsonObjectParsed, ref string usermodFolderPath, ref string jsonFolderPath, ref string consequenceCallerName, ref string consequenceCallerTranscript, ref string consequenceCallerImageLocation, ref Sprite consequenceCallerPortrait) { ParsingHelper.TryAssign(jsonObjectParsed, "consequence_caller_name", ref consequenceCallerName); ParsingHelper.TryAssign(jsonObjectParsed, "consequence_caller_transcript", ref consequenceCallerTranscript); ParsingHelper.TryAssign(jsonObjectParsed, "consequence_caller_image_name", ref consequenceCallerImageLocation); ImageParsingHelper.TryAssignSprite(jsonObjectParsed, "caller_image_name", ref consequenceCallerPortrait, jsonFolderPath, usermodFolderPath, consequenceCallerName); } } public static class EntryParsing { private static void ParseEntry(ref JObject jsonObjectParsed, ref string usermodFolderPath, ref string jsonFolderPath, ref int accessLevel, ref bool accessLevelAdded, ref bool replaceEntry, ref bool onlyDLC, ref bool includeDLC, ref bool includeMainCampaign, ref string entryName, ref string entryDescription, ref List<string> arcadeCalls, ref Sprite entryPortrait, ref string entryPortraitLocation, ref string entryAudioClipLocation, ref bool deleteReplaceEntry, ref bool inCustomCampaign, ref string customCampaignName, ref string videoUrlPortrait, ref bool isVideoPortrait, ref VariableChanged<bool> videoPortraitShouldLoop) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown ParsingHelper.TryAssign(jsonObjectParsed, "replace_entry", ref replaceEntry); JToken val = default(JToken); JToken val2 = default(JToken); if (jsonObjectParsed.TryGetValue("monster_name", ref val)) { if (!string.IsNullOrEmpty((string)val)) { entryName = (string)val; } } else if (jsonObjectParsed.TryGetValue("entry_name", ref val2)) { if (!string.IsNullOrEmpty((string)val2)) { entryName = (string)val2; } } else if (!replaceEntry) { LoggingHelper.WarningLog("No entry name given for file in " + usermodFolderPath + ". Defaulting to NO_NAME."); } JToken val3 = default(JToken); JToken val4 = default(JToken); if (jsonObjectParsed.TryGetValue("monster_description", ref val3)) { entryDescription = Extensions.Value<string>((IEnumerable<JToken>)val3); } else if (jsonObjectParsed.TryGetValue("entry_description", ref val4)) { entryDescription = Extensions.Value<string>((IEnumerable<JToken>)val4); } else if (!replaceEntry) { LoggingHelper.WarningLog("No entry description given for file in " + usermodFolderPath + ". Defaulting to NO_DESCRIPTION."); } ParsingHelper.TryAssign(jsonObjectParsed, "only_dlc", ref onlyDLC); ParsingHelper.TryAssign(jsonObjectParsed, "include_dlc", ref includeDLC); ParsingHelper.TryAssign(jsonObjectParsed, "include_campaign", ref includeMainCampaign); ParsingHelper.TryAssignWithBool(jsonObjectParsed, "access_level", ref accessLevel, ref accessLevelAdded); JToken val5 = defaul