Please disclose if your mod was created primarily 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 QuotaMoonUnlocker v0.0.1
QuotaMoonUnlocker.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using HarmonyLib; using Microsoft.CodeAnalysis; using MoonProgression.Helpers; using MoonProgression.Main; using MoonProgression.Patches; using QuotaMoonUnlocker.NetcodePatcher; using Unity.Collections; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("QuotaMoonUnlocker")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.0.1.0")] [assembly: AssemblyInformationalVersion("0.0.1")] [assembly: AssemblyProduct("QuotaMoonUnlocker")] [assembly: AssemblyTitle("QuotaMoonUnlocker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 MoonProgression { [BepInPlugin("MrHat.QuotaMoonUnlocker", "QuotaMoonUnlocker", "0.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string modGUID = "MrHat.QuotaMoonUnlocker"; internal const string modName = "QuotaMoonUnlocker"; internal const string modVersion = "0.0.1"; internal static Harmony _harmony; internal static ManualLogSource mls; internal static Plugin Instance; internal static ConfigEntry<bool> DebugEnabled { get; private set; } internal static ConfigEntry<string> UnlockPlan { get; private set; } private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Instance = this; mls = Logger.CreateLogSource("MrHat.QuotaMoonUnlocker"); _harmony = new Harmony("MrHat.QuotaMoonUnlocker"); DebugEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enabled", false, "Enables debug logging."); UnlockPlan = ((BaseUnityPlugin)this).Config.Bind<string>("Moon Unlocking", "Unlock Plan", "0:Experimentation;Assurance,1:Vow;Offense,2:March;Rend;Dine,4:Titan", "Format: QuotaCount:Moon1;Moon3,QuotaCount:Moon2"); MoonUnlocker.UpdateConfig(UnlockPlan.Value); _harmony.PatchAll(typeof(HarmonyPatches)); } internal static void LogDebug(string message) { if (DebugEnabled.Value) { mls.LogDebug((object)message); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "QuotaMoonUnlocker"; public const string PLUGIN_NAME = "QuotaMoonUnlocker"; public const string PLUGIN_VERSION = "0.0.1"; } } namespace MoonProgression.Patches { internal static class HarmonyPatches { [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPrefix] private static void StartOfRoundAwakePrefix() { MoonUnlocker.EnsureQuotaMessageRegistered(); } [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void StartOfRoundStartPostfix() { MoonUnlocker.ApplyPredicatesToAllLevels(); if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { MoonUnlocker.BroadcastQuota(); } } [HarmonyPatch(typeof(StartOfRound), "PlayerLoadedServerRpc")] [HarmonyPostfix] private static void PlayerLoadedServerRpcPostfix(ulong clientId) { if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { MoonUnlocker.SyncQuota(clientId); } } [HarmonyPatch(typeof(StartOfRound), "OnDestroy")] [HarmonyPostfix] private static void StartOfRoundOnDestroyPostfix() { MoonUnlocker.ResetQuotaSync(); } [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] [HarmonyPostfix] private static void SetNewProfitQuotaPostfix() { MoonUnlocker.OnNewQuotaSet(); } } } namespace MoonProgression.Main { internal static class MoonUnlocker { private readonly struct UnlockGroup { public readonly int RequiredCompletedQuotas; public readonly string[] Moons; public UnlockGroup(int requiredCompletedQuotas, string[] moons) { RequiredCompletedQuotas = requiredCompletedQuotas; Moons = moons; } } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnQuotaSyncMessage; } private static readonly Dictionary<string, int> moonUnlockQuotaByKey = new Dictionary<string, int>(); private static readonly Dictionary<string, string> originalMoonNameByKey = new Dictionary<string, string>(); private const string QuotaSyncMessage = "MrHat.QuotaMoonUnlocker.Sync"; private static NetworkManager registeredNetworkManager; private static readonly bool quotaMessageRegistered; private static int syncedCompletedQuotas = -1; private static int lastSeenCompletedQuotas = 0; private static bool loggedInitialSync; internal static void UpdateConfig(string unlockPlanText) { moonUnlockQuotaByKey.Clear(); originalMoonNameByKey.Clear(); List<UnlockGroup> list = ParseUnlockPlan(unlockPlanText); foreach (UnlockGroup item in list) { string[] moons = item.Moons; foreach (string text in moons) { string key = NormaliseKey(text); if (moonUnlockQuotaByKey.TryGetValue(key, out var value)) { if (item.RequiredCompletedQuotas < value) { moonUnlockQuotaByKey[key] = item.RequiredCompletedQuotas; } } else { moonUnlockQuotaByKey[key] = item.RequiredCompletedQuotas; originalMoonNameByKey[key] = text; } } } Plugin.LogDebug($"Unlock plan entries: {moonUnlockQuotaByKey.Count}"); } internal static void ApplyPredicatesToAllLevels() { SelectableLevel[] levels = StartOfRound.Instance.levels; int num = 0; SelectableLevel[] array = levels; foreach (SelectableLevel val in array) { string key = NormaliseKey(val.PlanetName); if (moonUnlockQuotaByKey.TryGetValue(key, out var value)) { DawnMoonInfo dawnInfo = DawnHelper.GetDawnInfo(val); DawnPurchaseInfo dawnPurchaseInfo = dawnInfo.DawnPurchaseInfo; ITerminalPurchasePredicate purchasePredicate = dawnPurchaseInfo.PurchasePredicate; if (!(purchasePredicate is QuotaUnlockPredicate)) { string planetName = val.PlanetName; QuotaUnlockPredicate predicate = new QuotaUnlockPredicate(val.PlanetName, purchasePredicate, value); DawnHelper.SetPurchasePredicate(dawnPurchaseInfo, (ITerminalPurchasePredicate)(object)predicate); num++; } } } Plugin.LogDebug($"Applied predicates: {num}"); } internal static void OnNewQuotaSet() { int timesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota; if (!NetworkManager.Singleton.IsServer && syncedCompletedQuotas >= 0 && timesFulfilledQuota > syncedCompletedQuotas) { syncedCompletedQuotas = timesFulfilledQuota; } if (timesFulfilledQuota != lastSeenCompletedQuotas) { lastSeenCompletedQuotas = timesFulfilledQuota; Plugin.LogDebug($"Quota now: {timesFulfilledQuota}"); if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { BroadcastQuota(); } } } internal static void EnsureQuotaMessageRegistered() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (!((Object)(object)singleton == (Object)null) && !((Object)(object)registeredNetworkManager == (Object)(object)singleton)) { NetworkManager obj = registeredNetworkManager; if (obj != null) { obj.CustomMessagingManager.UnregisterNamedMessageHandler("MrHat.QuotaMoonUnlocker.Sync"); } registeredNetworkManager = singleton; CustomMessagingManager customMessagingManager = registeredNetworkManager.CustomMessagingManager; object obj2 = <>O.<0>__OnQuotaSyncMessage; if (obj2 == null) { HandleNamedMessageDelegate val = OnQuotaSyncMessage; <>O.<0>__OnQuotaSyncMessage = val; obj2 = (object)val; } customMessagingManager.RegisterNamedMessageHandler("MrHat.QuotaMoonUnlocker.Sync", (HandleNamedMessageDelegate)obj2); } } private static void OnQuotaSyncMessage(ulong senderClientId, FastBufferReader reader) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (num > syncedCompletedQuotas) { syncedCompletedQuotas = num; } if (!loggedInitialSync) { loggedInitialSync = true; Plugin.LogDebug($"Synced quota from host: {syncedCompletedQuotas}"); } } internal static int GetCompletedQuotas() { if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer) { return TimeOfDay.Instance.timesFulfilledQuota; } if (syncedCompletedQuotas >= 0) { return syncedCompletedQuotas; } return ((Object)(object)TimeOfDay.Instance != (Object)null) ? TimeOfDay.Instance.timesFulfilledQuota : 0; } internal static void SyncQuota(ulong clientId) { //IL_0032: 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_004f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkManager.Singleton.IsServer) { return; } EnsureQuotaMessageRegistered(); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref TimeOfDay.Instance.timesFulfilledQuota, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("MrHat.QuotaMoonUnlocker.Sync", clientId, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } internal static void BroadcastQuota() { if (NetworkManager.Singleton.IsServer) { IReadOnlyList<ulong> connectedClientsIds = NetworkManager.Singleton.ConnectedClientsIds; for (int i = 0; i < connectedClientsIds.Count; i++) { SyncQuota(connectedClientsIds[i]); } } } internal static void ResetQuotaSync() { syncedCompletedQuotas = -1; lastSeenCompletedQuotas = 0; loggedInitialSync = false; registeredNetworkManager = null; } private static string NormaliseKey(string raw) { StringBuilder stringBuilder = new StringBuilder(raw.Length); foreach (char c in raw) { if (char.IsLetter(c)) { stringBuilder.Append(char.ToUpperInvariant(c)); } } return stringBuilder.ToString(); } private static List<UnlockGroup> ParseUnlockPlan(string text) { List<UnlockGroup> list = new List<UnlockGroup>(); if (string.IsNullOrWhiteSpace(text)) { return list; } int num = text.IndexOf(':'); if (num < 0) { return list; } int num2 = text.IndexOf(',', num + 1); int num3 = text.IndexOf(';', num + 1); bool flag = num3 != -1 && (num2 == -1 || num3 < num2); char c = (flag ? ',' : ';'); char c2 = (flag ? ';' : ','); string[] array = text.Split(new char[1] { c }, StringSplitOptions.RemoveEmptyEntries); string[] array2 = array; foreach (string text2 in array2) { string[] array3 = text2.Split(new char[1] { ':' }, 2); if (array3.Length == 2 && int.TryParse(array3[0].Trim(), out var result)) { string[] array4 = (from m in array3[1].Split(new char[1] { c2 }, StringSplitOptions.RemoveEmptyEntries) select m.Trim() into m where m.Length > 0 select m).ToArray(); if (array4.Length != 0) { list.Add(new UnlockGroup(result, array4)); } } } return list; } } internal sealed class QuotaUnlockPredicate : ITerminalPurchasePredicate { private readonly string moonNameForLogs; private readonly ITerminalPurchasePredicate basePredicate; private readonly int requiredCompletedQuotas; private readonly TerminalNode lockedNode; private int lastSeenQuotas = 0; private bool lastSeenUnlocked; internal QuotaUnlockPredicate(string moonNameForLogs, ITerminalPurchasePredicate basePredicate, int requiredCompletedQuotas) { this.moonNameForLogs = moonNameForLogs; this.basePredicate = basePredicate; this.requiredCompletedQuotas = requiredCompletedQuotas; lockedNode = ScriptableObject.CreateInstance<TerminalNode>(); lockedNode.clearPreviousText = true; } private static string BuildLockedText(int requiredQuota, int currentQuota) { return $"This moon is locked until quota {requiredQuota}, you are currently on quota {currentQuota}. Back to work, you slacker!"; } public TerminalPurchaseResult CanPurchase() { TerminalPurchaseResult val = basePredicate.CanPurchase(); if (val is HiddenPurchaseResult) { return val; } if (val is FailedPurchaseResult) { return val; } int completedQuotas = MoonUnlocker.GetCompletedQuotas(); bool flag = completedQuotas >= requiredCompletedQuotas; if (completedQuotas != lastSeenQuotas || flag != lastSeenUnlocked) { Plugin.LogDebug($"Predicate check '{moonNameForLogs}': CompletedQuotas={completedQuotas}, Required={requiredCompletedQuotas}, Unlocked={flag}"); lastSeenQuotas = completedQuotas; lastSeenUnlocked = flag; } if (flag) { return (TerminalPurchaseResult)(object)TerminalPurchaseResult.Success(); } lockedNode.displayText = BuildLockedText(requiredCompletedQuotas, completedQuotas); HiddenPurchaseResult val2 = TerminalPurchaseResult.Hidden(); val2.SetFailure(true); val2.SetFailNode(lockedNode); return (TerminalPurchaseResult)(object)val2; } } } namespace MoonProgression.Helpers { internal static class DawnHelper { private static readonly MethodInfo setPurchasePredicate = AccessTools.PropertySetter(typeof(DawnPurchaseInfo), "PurchasePredicate"); private static bool reportedMissingSetter; internal static DawnMoonInfo GetDawnInfo(SelectableLevel level) { return SelectableLevelExtensions.GetDawnInfo(level); } internal static bool SetPurchasePredicate(DawnPurchaseInfo purchaseInfo, ITerminalPurchasePredicate predicate) { if (setPurchasePredicate == null) { if (!reportedMissingSetter) { reportedMissingSetter = true; Plugin.LogDebug("DawnHelper: PurchasePredicate setter not found. Predicate cannot be replaced."); } return false; } setPurchasePredicate.Invoke(purchaseInfo, new object[1] { predicate }); return true; } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace QuotaMoonUnlocker.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }