Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of WeatherReroll v1.0.0
WeatherReroll.dll
Decompiled 2 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WeatherReroll")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WeatherReroll")] [assembly: AssemblyTitle("WeatherReroll")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WeatherReroll { [HarmonyPatch] internal static class GamePatches { [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void StartOfRound_Start_Postfix() { RerollService.ResetDailyUses(); RerollService.RegisterMessageHandlers(); } [HarmonyPatch(typeof(TimeOfDay), "OnDayChanged")] [HarmonyPostfix] private static void TimeOfDay_OnDayChanged_Postfix() { RerollService.ResetDailyUses(); } } [BepInPlugin("BLUJAY.WeatherReroll", "Weather Reroll", "1.0.0")] public class WeatherRerollPlugin : BaseUnityPlugin { public const string Guid = "BLUJAY.WeatherReroll"; public const string Name = "Weather Reroll"; public const string Version = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry<int> StartingCost; internal static ConfigEntry<int> CostIncrease; private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; StartingCost = ((BaseUnityPlugin)this).Config.Bind<int>("Pricing", "StartingCost", 1000, "Cost of the first weather reroll of the day. The host's settings are authoritative in multiplayer."); CostIncrease = ((BaseUnityPlugin)this).Config.Bind<int>("Pricing", "CostIncrease", 2000, "How much the price goes up with each reroll purchased that day (1000 -> 3000 -> 5000 -> ...). Resets when the day ends."); Harmony val = new Harmony("BLUJAY.WeatherReroll"); val.PatchAll(typeof(TerminalPatches)); val.PatchAll(typeof(GamePatches)); Log.LogInfo((object)"Weather Reroll v1.0.0 loaded. Type REROLL in the terminal while in orbit."); } } internal static class RerollService { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestReceived; public static HandleNamedMessageDelegate <1>__OnSyncReceived; public static HandleNamedMessageDelegate <2>__OnDeniedReceived; } private const string MsgRequest = "WeatherReroll.Request"; private const string MsgSync = "WeatherReroll.Sync"; private const string MsgDenied = "WeatherReroll.Denied"; internal static int RerollsUsedToday; internal static int CurrentCost => CostFor(RerollsUsedToday); internal static bool InOrbit { get { if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.inShipPhase) { return !StartOfRound.Instance.travellingToNewLevel; } return false; } } internal static int CostFor(int usedCount) { return Mathf.Max(1, WeatherRerollPlugin.StartingCost.Value + usedCount * WeatherRerollPlugin.CostIncrease.Value); } internal static string FormatMoney(int amount) { return "$" + amount.ToString("N0"); } internal static void ResetDailyUses() { RerollsUsedToday = 0; } internal static void RegisterMessageHandlers() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null) { CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; object obj = <>O.<0>__OnRequestReceived; if (obj == null) { HandleNamedMessageDelegate val = OnRequestReceived; <>O.<0>__OnRequestReceived = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("WeatherReroll.Request", (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager; object obj2 = <>O.<1>__OnSyncReceived; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnSyncReceived; <>O.<1>__OnSyncReceived = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("WeatherReroll.Sync", (HandleNamedMessageDelegate)obj2); CustomMessagingManager customMessagingManager3 = singleton.CustomMessagingManager; object obj3 = <>O.<2>__OnDeniedReceived; if (obj3 == null) { HandleNamedMessageDelegate val3 = OnDeniedReceived; <>O.<2>__OnDeniedReceived = val3; obj3 = (object)val3; } customMessagingManager3.RegisterNamedMessageHandler("WeatherReroll.Denied", (HandleNamedMessageDelegate)obj3); } } internal unsafe static void PurchaseReroll(Terminal terminal) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { return; } if (singleton.IsServer) { ServerPerformReroll(terminal, singleton.LocalClientId); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref RerollsUsedToday, default(ForPrimitives)); singleton.CustomMessagingManager.SendNamedMessage("WeatherReroll.Request", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private unsafe static void OnRequestReceived(ulong senderClientId, FastBufferReader reader) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer) { return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); Terminal val = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val == (Object)null) { return; } if (num != RerollsUsedToday || !InOrbit || val.groupCredits < CurrentCost) { FastBufferWriter val2 = default(FastBufferWriter); ((FastBufferWriter)(ref val2))..ctor(1, (Allocator)2, -1); try { byte b = 0; ((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(ref b, default(ForPrimitives)); singleton.CustomMessagingManager.SendNamedMessage("WeatherReroll.Denied", senderClientId, val2, (NetworkDelivery)3); return; } finally { ((IDisposable)(*(FastBufferWriter*)(&val2))/*cast due to .constrained prefix*/).Dispose(); } } ServerPerformReroll(val, senderClientId); } private unsafe static void ServerPerformReroll(Terminal terminal, ulong purchaserClientId) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (!InOrbit || terminal.groupCredits < CurrentCost) { return; } int currentCost = CurrentCost; int num = new Random().Next(2, 100000000); int num2 = RerollsUsedToday + 1; int newCredits = Mathf.Clamp(terminal.groupCredits - currentCost, 0, 10000000); WeatherRerollPlugin.Log.LogInfo((object)$"Weather reroll #{num2} purchased for {FormatMoney(currentCost)} by client {purchaserClientId}; new seed {num}."); Apply(terminal, num, num2, newCredits, purchaserClientId); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(20, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num2, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref newCredits, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref purchaserClientId, default(ForPrimitives)); foreach (ulong connectedClientsId in singleton.ConnectedClientsIds) { if (connectedClientsId != singleton.LocalClientId) { singleton.CustomMessagingManager.SendNamedMessage("WeatherReroll.Sync", connectedClientsId, val, (NetworkDelivery)3); } } } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private static void OnSyncReceived(ulong senderClientId, FastBufferReader reader) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) int newSeed = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref newSeed, default(ForPrimitives)); int newCount = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref newCount, default(ForPrimitives)); int newCredits = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref newCredits, default(ForPrimitives)); ulong purchaserClientId = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref purchaserClientId, default(ForPrimitives)); Terminal val = Object.FindObjectOfType<Terminal>(); if (!((Object)(object)val == (Object)null)) { Apply(val, newSeed, newCount, newCredits, purchaserClientId); } } private static void OnDeniedReceived(ulong senderClientId, FastBufferReader reader) { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("Weather reroll failed", "The transaction was rejected by the server. Check the moons catalogue and try again.", true, false, "LC_Tip1"); } } private static void Apply(Terminal terminal, int newSeed, int newCount, int newCredits, ulong purchaserClientId) { StartOfRound instance = StartOfRound.Instance; if (!((Object)(object)instance == (Object)null)) { RerollsUsedToday = newCount; terminal.groupCredits = newCredits; instance.randomMapSeed = newSeed; instance.SetPlanetsWeather(0); instance.SetMapScreenInfoToCurrentLevel(); NetworkManager singleton = NetworkManager.Singleton; if ((!((Object)(object)singleton != (Object)null) || singleton.LocalClientId != purchaserClientId) && (Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("Weather rerolled", "A crewmate purchased a weather reroll for " + FormatMoney(CostFor(newCount - 1)) + ". All forecasts have been updated.", false, false, "LC_Tip1"); } } } } [HarmonyPatch] internal static class TerminalPatches { private static TerminalKeyword rerollKeyword; private static TerminalNode promptNode; private static TerminalNode successNode; private static TerminalNode cancelNode; private static TerminalNode errorNode; [HarmonyPatch(typeof(Terminal), "Awake")] [HarmonyPostfix] private static void Terminal_Awake_Postfix(Terminal __instance) { TerminalNodesList terminalNodes = __instance.terminalNodes; if ((Object)(object)terminalNodes == (Object)null || terminalNodes.allKeywords == null) { return; } TerminalKeyword val = FindKeyword(terminalNodes.allKeywords, "confirm"); TerminalKeyword val2 = FindKeyword(terminalNodes.allKeywords, "deny"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { WeatherRerollPlugin.Log.LogError((object)"Could not find the vanilla CONFIRM/DENY keywords; REROLL command not registered."); return; } EnsureNodesExist(val, val2); if ((Object)(object)FindKeyword(terminalNodes.allKeywords, "reroll") == (Object)null) { terminalNodes.allKeywords = CollectionExtensions.AddToArray<TerminalKeyword>(terminalNodes.allKeywords, rerollKeyword); WeatherRerollPlugin.Log.LogInfo((object)"REROLL terminal command registered."); } } private static void EnsureNodesExist(TerminalKeyword confirmKeyword, TerminalKeyword denyKeyword) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown if (!((Object)(object)promptNode != (Object)null)) { successNode = CreateNode("WeatherRerollSuccess"); successNode.playSyncedClip = 0; cancelNode = CreateNode("WeatherRerollCancel"); cancelNode.displayText = "Cancelled weather reroll.\n\n"; errorNode = CreateNode("WeatherRerollError"); promptNode = CreateNode("WeatherRerollPrompt"); promptNode.overrideOptions = true; promptNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { new CompatibleNoun(confirmKeyword, successNode), new CompatibleNoun(denyKeyword, cancelNode) }; rerollKeyword = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)rerollKeyword).hideFlags = (HideFlags)61; ((Object)rerollKeyword).name = "WeatherRerollKeyword"; rerollKeyword.word = "reroll"; rerollKeyword.isVerb = false; rerollKeyword.specialKeywordResult = promptNode; } } private static TerminalNode CreateNode(string nodeName) { TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)obj).hideFlags = (HideFlags)61; ((Object)obj).name = nodeName; obj.clearPreviousText = true; obj.maxCharactersToType = 50; obj.buyItemIndex = -1; obj.buyVehicleIndex = -1; obj.buyRerouteToMoon = -1; obj.displayPlanetInfo = -1; obj.shipUnlockableID = -1; obj.creatureFileID = -1; obj.storyLogFileID = -1; obj.playSyncedClip = -1; return obj; } private static TerminalKeyword FindKeyword(TerminalKeyword[] keywords, string word) { foreach (TerminalKeyword val in keywords) { if ((Object)(object)val != (Object)null && val.word == word) { return val; } } return null; } [HarmonyPatch(typeof(Terminal), "LoadNewNode")] [HarmonyPrefix] private static void Terminal_LoadNewNode_Prefix(Terminal __instance, ref TerminalNode node) { if ((Object)(object)promptNode == (Object)null || (Object)(object)node == (Object)null) { return; } if ((Object)(object)node == (Object)(object)promptNode) { if (IsBlocked(__instance, out var reason)) { errorNode.displayText = reason; node = errorNode; } else { promptNode.displayText = "You have requested to reroll the weather conditions of all moons.\nTotal cost of this service: " + RerollService.FormatMoney(RerollService.CurrentCost) + ".\n\nPlease CONFIRM or DENY.\n\n"; } } else if ((Object)(object)node == (Object)(object)successNode) { if (IsBlocked(__instance, out var reason2)) { errorNode.displayText = reason2; node = errorNode; return; } int currentCost = RerollService.CurrentCost; int amount = Mathf.Max(0, __instance.groupCredits - currentCost); int amount2 = RerollService.CostFor(RerollService.RerollsUsedToday + 1); successNode.displayText = "Weather systems rerolled. Your new balance is " + RerollService.FormatMoney(amount) + ".\n\nUpdated forecasts are available in the moons catalogue.\nThe next reroll today will cost " + RerollService.FormatMoney(amount2) + ".\n\n"; RerollService.PurchaseReroll(__instance); } } private static bool IsBlocked(Terminal terminal, out string reason) { if (!RerollService.InOrbit) { reason = "Weather can only be rerolled while the ship is in orbit.\n\n"; return true; } if (terminal.groupCredits < RerollService.CurrentCost) { reason = "You do not have enough credits to reroll the weather.\nCost: " + RerollService.FormatMoney(RerollService.CurrentCost) + " // Your balance: " + RerollService.FormatMoney(terminal.groupCredits) + ".\n\n"; return true; } reason = null; return false; } [HarmonyPatch(typeof(Terminal), "TextPostProcess")] [HarmonyPostfix] private static void Terminal_TextPostProcess_Postfix(Terminal __instance, TerminalNode node, ref string __result) { if (!((Object)(object)node == (Object)null) && !((Object)(object)__instance.terminalNodes == (Object)null)) { TerminalKeyword val = FindKeyword(__instance.terminalNodes.allKeywords, "moons"); if (!((Object)(object)val == (Object)null) && !((Object)(object)node != (Object)(object)val.specialKeywordResult)) { int rerollsUsedToday = RerollService.RerollsUsedToday; string text = rerollsUsedToday switch { 0 => "The price rises with each use and resets daily.", 1 => "Rerolled 1 time today. Prices reset at the end of the day.", _ => $"Rerolled {rerollsUsedToday} times today. Prices reset at the end of the day.", }; __result = __result + "\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\n\n* Weather reroll // Price: " + RerollService.FormatMoney(RerollService.CurrentCost) + "\nType REROLL to randomize the weather of all moons.\n" + text + "\n"; } } } } }