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 Rewards v1.0.0
plugins/Rewards.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Buffers.Binary; using System.Buffers.Text; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Numerics.Hashing; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BiomeLockAPI; using FxResources.System.Buffers; using FxResources.System.Memory; using FxResources.System.Numerics.Vectors; using HarmonyLib; using JetBrains.Annotations; using LiteDB; using LiteDB.Client.Shared; using LiteDB.Engine; using LiteDB.Utils; using LiteDB.Utils.Extensions; using LiteDB.Vector; using LocalizationManager; using Microsoft.CodeAnalysis; using Microsoft.Win32.SafeHandles; using ServerSync; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyProduct("Rewards")] [assembly: AssemblyCompany("radamanto")] [assembly: AssemblyDescription("Recompensas por tempo de jogo ativo para Valheim.")] [assembly: AssemblyTitle("Rewards")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: <f054822c-6861-4e8c-93d2-160cfbebcb0b>RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<0fcf8a3a-6581-4007-998b-549f183b241f>Embedded] internal sealed class <0fcf8a3a-6581-4007-998b-549f183b241f>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [<0fcf8a3a-6581-4007-998b-549f183b241f>Embedded] [CompilerGenerated] internal sealed class <708e428e-57cb-4a78-8091-80df3604fcfc>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <708e428e-57cb-4a78-8091-80df3604fcfc>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <708e428e-57cb-4a78-8091-80df3604fcfc>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [<0fcf8a3a-6581-4007-998b-549f183b241f>Embedded] internal sealed class <9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContextAttribute : Attribute { public readonly byte Flag; public <9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContextAttribute(byte P_0) { Flag = P_0; } } [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [<0fcf8a3a-6581-4007-998b-549f183b241f>Embedded] [CompilerGenerated] internal sealed class <f054822c-6861-4e8c-93d2-160cfbebcb0b>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <f054822c-6861-4e8c-93d2-160cfbebcb0b>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LocalizationManager { [PublicAPI] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private static BaseUnityPlugin _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] [method: <9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(2)] [field: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] public static event Action OnLocalizationComplete; private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null) { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] (object _, EventArgs _) => { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static void Load() { _ = plugin; } public static void LoadLocalizationLater(Localization __instance) { LoadLocalization(Localization.instance, __instance.GetSelectedLanguage()); } public static void SafeCallLocalizeComplete() { Localizer.OnLocalizationComplete?.Invoke(); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string[] array = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' }); if (array.Length >= 2) { string text = array[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } } byte[] array2 = LoadTranslationFromAssembly("English"); if (array2 == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.TryGetValue(language, out var value)) { text2 = File.ReadAllText(value); } else { byte[] array3 = LoadTranslationFromAssembly(language); if (array3 != null) { text2 = Encoding.UTF8.GetString(array3); } } } if (text2 == null && dictionary.TryGetValue("English", out var value2)) { text2 = File.ReadAllText(value2); } if (text2 != null) { foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair<string, string> item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_008e: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string>(2) { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private static byte[] LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(2)] public static byte[] ReadEmbeddedFileBytes([<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(1)] string resourceFileName, Assembly containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } public static class LocalizationManagerVersion { [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(1)] public const string Version = "1.4.1"; } } namespace Rewards { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal static class RewardsActivity { private const float ReportInterval = 60f; private static readonly ActivityWindow Window = new ActivityWindow(); private static float _nextReport = -1f; private static Vector3 _lastPosition; private static bool _hasPosition; private static Quaternion _lastRotation; private static bool _hasRotation; private static bool LocalReady { get { if ((Object)(object)Player.m_localPlayer != (Object)null && !((Character)Player.m_localPlayer).IsDead()) { return RewardsClient.Connected; } return false; } } internal static void Action(ActivityKind kind) { if (LocalReady) { Window.AddAction(kind); Window.MarkInput(Time.realtimeSinceStartupAsDouble); } } internal static void Target(Object target) { if (LocalReady && Object.op_Implicit(target)) { Window.AddTarget(target.GetInstanceID()); } } internal static bool FromLocal(HitData hit) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer != (Object)null && hit != null) { return hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID(); } return false; } internal static void Tick() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (!LocalReady) { _hasPosition = false; _hasRotation = false; _nextReport = -1f; Window.Reset(); return; } double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; Vector2 mouseDelta = ZInput.GetMouseDelta(); if (((Vector2)(ref mouseDelta)).sqrMagnitude > 0f) { Window.MarkInput(realtimeSinceStartupAsDouble); } Player localPlayer = Player.m_localPlayer; Vector3 position = ((Component)localPlayer).transform.position; if (_hasPosition) { float num = Vector3.Distance(position, _lastPosition); if (num < 20f) { Window.AddMove(num); bool flag = ((Character)localPlayer).IsAttachedToShip() || (Object)(object)((Character)localPlayer).GetStandingOnShip() != (Object)null; if (num > 0.01f && !flag) { Window.AddAction(ActivityKind.Move); Window.MarkInput(realtimeSinceStartupAsDouble); } } } _lastPosition = position; _hasPosition = true; GameCamera instance = GameCamera.instance; if (Object.op_Implicit((Object)(object)instance)) { Quaternion rotation = ((Component)instance).transform.rotation; if (_hasRotation) { Window.AddCameraTurn(Quaternion.Angle(rotation, _lastRotation)); } _lastRotation = rotation; _hasRotation = true; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (_nextReport < 0f) { _nextReport = realtimeSinceStartup + 60f; } if (!(realtimeSinceStartup < _nextReport)) { _nextReport = realtimeSinceStartup + 60f; bool flag2 = Window.IsValid(RewardsPlugin.CE_ActivityMinCriteria.Value, realtimeSinceStartupAsDouble, (double)RewardsPlugin.CE_IdleMinutes.Value * 60.0) && !RewardsClient.TimeLocked; Window.Reset(); RewardsRpc.ToServer("Rewards_Minute", flag2); } } } internal struct Vector3Like { public float X; public float Y; public float Z; } internal sealed class MinuteGate { private const double MinInterval = 55.0; private const double StillRadius = 2.0; private double _lastAccepted = double.NegativeInfinity; private double _anchorSince; private Vector3Like _anchor; private bool _hasAnchor; internal bool Accept(double now, Vector3Like position, int stillMinutes) { if (!_hasAnchor || Distance(_anchor, position) >= 2.0) { _anchor = position; _anchorSince = now; _hasAnchor = true; } if (now - _lastAccepted < 55.0) { return false; } if (now - _anchorSince >= (double)stillMinutes * 60.0) { return false; } _lastAccepted = now; return true; } private static double Distance(Vector3Like a, Vector3Like b) { double num = a.X - b.X; double num2 = a.Y - b.Y; double num3 = a.Z - b.Z; return Math.Sqrt(num * num + num2 * num2 + num3 * num3); } } [HarmonyPatch(typeof(Character), "Jump")] internal static class Character_Jump_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Character __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { RewardsActivity.Action(ActivityKind.Jump); } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] internal static class Humanoid_StartAttack_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Humanoid __instance, bool __result) { if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { RewardsActivity.Action(ActivityKind.Attack); } } } [HarmonyPatch(typeof(Humanoid), "BlockAttack")] internal static class Humanoid_BlockAttack_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Humanoid __instance, bool __result) { if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { RewardsActivity.Action(ActivityKind.Block); } } } [HarmonyPatch(typeof(Humanoid), "Pickup")] internal static class Humanoid_Pickup_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Humanoid __instance, GameObject go, bool __result) { if (__result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { RewardsActivity.Action(ActivityKind.Pickup); RewardsActivity.Target((Object)(object)go); } } } [HarmonyPatch(typeof(Player), "PlacePiece")] internal static class Player_PlacePiece_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { RewardsActivity.Action(ActivityKind.Build); } } } [HarmonyPatch(typeof(Player), "Interact")] internal static class Player_Interact_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Player __instance, GameObject go) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)go)) { RewardsActivity.Action(ActivityKind.Interact); RewardsActivity.Target((Object)(object)go); } } } [HarmonyPatch(typeof(Player), "EatFood")] internal static class Player_EatFood_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Player __instance, bool __result) { if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { RewardsActivity.Action(ActivityKind.Eat); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] internal static class InventoryGui_Show_Activity { private static void Postfix() { RewardsActivity.Action(ActivityKind.Inventory); } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] internal static class InventoryGui_DoCrafting_Activity { private static void Postfix() { RewardsActivity.Action(ActivityKind.Craft); } } [HarmonyPatch(typeof(ShipControlls), "ApplyControlls")] internal static class ShipControlls_ApplyControlls_Activity { private static void Postfix(Vector3 moveDir) { //IL_0000: 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) if (Mathf.Abs(moveDir.x) > 0.1f) { RewardsActivity.Action(ActivityKind.Steer); } if (Mathf.Abs(moveDir.z) > 0.1f) { RewardsActivity.Action(ActivityKind.Sail); } } } [HarmonyPatch(typeof(Chat), "SendText")] internal static class Chat_SendText_Activity { private static void Postfix() { RewardsActivity.Action(ActivityKind.Chat); } } [HarmonyPatch(typeof(Character), "Damage")] internal static class Character_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Character __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [HarmonyPatch(typeof(WearNTear), "Damage")] internal static class WearNTear_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(WearNTear __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [HarmonyPatch(typeof(Destructible), "Damage")] internal static class Destructible_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(Destructible __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [HarmonyPatch(typeof(TreeBase), "Damage")] internal static class TreeBase_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(TreeBase __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [HarmonyPatch(typeof(TreeLog), "Damage")] internal static class TreeLog_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(TreeLog __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [HarmonyPatch(typeof(MineRock), "Damage")] internal static class MineRock_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(MineRock __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [HarmonyPatch(typeof(MineRock5), "Damage")] internal static class MineRock5_Damage_Activity { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(MineRock5 __instance, HitData hit) { if (RewardsActivity.FromLocal(hit)) { RewardsActivity.Target((Object)(object)__instance); } } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal sealed class PresenceState { private readonly Random _random; private long _nextToken; internal double NextAt { get; private set; } internal long? Token { get; private set; } internal double Deadline { get; private set; } internal PresenceState(Random random) { _random = random; _nextToken = random.Next(1, int.MaxValue); } internal void Start(double now, int minMinutes, int maxMinutes) { Token = null; Deadline = 0.0; int num = Math.Max(1, Math.Min(minMinutes, maxMinutes)); int num2 = Math.Max(1, Math.Max(minMinutes, maxMinutes)); NextAt = now + ((double)num + _random.NextDouble() * (double)(num2 - num)) * 60.0; } internal long? Due(double now, int responseMinutes) { if (Token.HasValue || now < NextAt) { return null; } Token = (_nextToken += 1L); Deadline = now + (double)Math.Max(1, responseMinutes) * 60.0; return Token; } internal bool Ack(long token, double now, int minMinutes, int maxMinutes) { if (!Token.HasValue || Token.Value != token) { return false; } Start(now, minMinutes, maxMinutes); return true; } internal bool Counts(double now) { if (Token.HasValue) { return now <= Deadline; } return true; } } internal enum ActivityKind { Move, Jump, Attack, Block, Build, Pickup, Interact, Inventory, Chat, Eat, Craft, Sail, Steer } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal sealed class ActivityWindow { private const float MinMove = 8f; private const float MinTurn = 90f; private readonly HashSet<ActivityKind> _kinds = new HashSet<ActivityKind>(); private readonly HashSet<int> _targets = new HashSet<int>(); private float _moved; private float _turned; private double _lastInput = double.NegativeInfinity; internal void AddMove(float meters) { _moved += meters; } internal void AddCameraTurn(float degrees) { _turned += degrees; } internal void AddAction(ActivityKind kind) { _kinds.Add(kind); } internal void AddTarget(int instanceId) { _targets.Add(instanceId); } internal void MarkInput(double time) { _lastInput = time; } internal bool IsValid(int minCriteria, double now, double idleSeconds) { if (now - _lastInput >= idleSeconds) { return false; } int num = 0; if (_moved >= 8f) { num++; } if (_turned >= 90f) { num++; } if (_kinds.Count >= 2) { num++; } if (_targets.Count >= 2) { num++; } return num >= minCriteria; } internal void Reset() { _kinds.Clear(); _targets.Clear(); _moved = 0f; _turned = 0f; } } internal static class RewardsBiomeLock { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static bool Has(string key) { return API.HasProgressionKey(key); } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static class RewardsDatabase { private const string Collection = "players"; [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private static LiteDatabase _database; private static readonly BsonMapper Mapper = new BsonMapper { EmptyStringToNull = false, TrimWhitespace = false }; private static LiteDatabase Open() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { throw new InvalidOperationException("Database access requires an active server."); } if (_database != null) { return _database; } Directory.CreateDirectory(RewardsPaths.SavedDataFolder); if (File.Exists(RewardsPaths.DatabaseFile) && new FileInfo(RewardsPaths.DatabaseFile).Length < 8192) { throw new InvalidDataException("Existing database is empty or truncated."); } _database = new LiteDatabase(new ConnectionString { Filename = RewardsPaths.DatabaseFile }, Mapper); return _database; } [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] internal static PlayerRecord Load(string id) { try { return Open().GetCollection<PlayerRecord>("players").FindById(new BsonValue(id)) ?? new PlayerRecord { Id = id }; } catch (Exception ex) { RewardsPlugin.Log.LogError((object)("[Database] Failed to load " + id + ": " + ex.Message)); Close(); return null; } } internal static bool Save(PlayerRecord record) { try { Open().GetCollection<PlayerRecord>("players").Upsert(record); return true; } catch (Exception ex) { RewardsPlugin.Log.LogError((object)("[Database] Failed to save " + record.Id + ": " + ex.Message)); Close(); return false; } } internal static void Close() { LiteDatabase database = _database; _database = null; try { database?.Dispose(); } catch (Exception ex) { RewardsPlugin.Log.LogError((object)("[Database] Failed to close: " + ex.Message)); } } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static class RewardsPaths { internal static string DataFolder => Path.Combine(Paths.ConfigPath, "Rewards"); internal static string SavedDataFolder => Path.Combine(DataFolder, "SavedData"); internal static string LevelsFolder => Path.Combine(DataFolder, "Levels"); internal static string DatabaseFile => Path.Combine(SavedDataFolder, "Rewards.db"); } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] public sealed class PlayerRecord { public string Id { get; set; } = ""; public string LastName { get; set; } = ""; public int ActiveMinutes { get; set; } public int ClaimedLevel { get; set; } public int Cycle { get; set; } = 1; public long NextGrantId { get; set; } public List<PendingGrant> PendingGrants { get; set; } = new List<PendingGrant>(); } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] public sealed class PendingGrant { public long Id { get; set; } public List<GrantItem> Items { get; set; } = new List<GrantItem>(); } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] public sealed class GrantItem { public string Prefab { get; set; } = ""; public int Amount { get; set; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class ZNet_Awake_Reset { private static void Postfix() { RewardsDatabase.Close(); RewardsConfig.Reset(); RewardsServer.Reset(); RewardsClient.Reset(); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] internal static class ZNet_OnNewConnection_Register { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { RewardsServer.Register(peer.m_rpc); } else { RewardsClient.Register(peer.m_rpc); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] internal static class ZNet_RPC_PeerInfo_Join { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(ZNet __instance, ZRpc rpc) { if (__instance.IsServer()) { ZNetPeer peer = __instance.GetPeer(rpc); if (peer != null && peer.IsReady()) { RewardsServer.OnJoined(peer); } } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] internal static class ZNet_Disconnect_Save { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Prefix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { RewardsServer.OnLeft(peer); } } } [HarmonyPatch(typeof(ZNet), "Shutdown")] internal static class ZNet_Shutdown_Save { private static void Prefix() { if (RewardsRpc.IsServer) { RewardsServer.SaveAll(); } } private static void Finalizer() { RewardsDatabase.Close(); } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static class RewardsRpc { internal const string Levels = "Rewards_Levels"; internal const string State = "Rewards_State"; internal const string Presence = "Rewards_Presence"; internal const string Grant = "Rewards_Grant"; internal const string Message = "Rewards_Message"; internal const string Minute = "Rewards_Minute"; internal const string PresenceAck = "Rewards_PresenceAck"; internal const string Claim = "Rewards_Claim"; internal const string GrantAck = "Rewards_GrantAck"; internal const string Admin = "Rewards_Admin"; internal static bool IsServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } internal static void ToServer(string name, params object[] args) { ZRpc obj = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerRPC() : null); if (obj != null) { obj.Invoke(name, args); } } internal static void WriteItems(ZPackage pkg, List<GrantItem> items) { pkg.Write(items.Count); foreach (GrantItem item in items) { pkg.Write(item.Prefab); pkg.Write(item.Amount); } } internal static List<GrantItem> ReadItems(ZPackage pkg) { int num = pkg.ReadInt(); List<GrantItem> list = new List<GrantItem>(num); for (int i = 0; i < num; i++) { list.Add(new GrantItem { Prefab = pkg.ReadString(), Amount = pkg.ReadInt() }); } return list; } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal sealed class RewardsSession { internal ZNetPeer Peer; internal PlayerRecord Record; internal PresenceState Presence; internal MinuteGate Gate = new MinuteGate(); internal bool SentPaused; internal bool Dirty; } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static class RewardsServer { private const double SaveInterval = 300.0; private static readonly Dictionary<long, RewardsSession> Sessions = new Dictionary<long, RewardsSession>(); private static readonly Dictionary<string, PresenceState> Presences = new Dictionary<string, PresenceState>(); private static readonly Random Random = new Random(); private static readonly Platform SteamPlatform = new Platform("Steam"); private static double _lastSave; private static bool _subscribed; private static bool _presenceWasOn = true; private static double Now => Time.realtimeSinceStartupAsDouble; private static bool Restart => RewardsPlugin.CE_RestartAfterLastLevel.Value; private static bool PresenceOn => RewardsPlugin.CE_PresenceEnabled.Value; internal unsafe static string NormalizeId(string raw) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) PlatformUserID val = default(PlatformUserID); if (!PlatformUserID.TryParse(raw, ref val)) { ((PlatformUserID)(ref val))..ctor(SteamPlatform, raw); } return ((object)(*(PlatformUserID*)(&val))/*cast due to .constrained prefix*/).ToString(); } internal static void Reset() { Sessions.Clear(); Presences.Clear(); _lastSave = Now; if (!_subscribed) { _subscribed = true; RewardsConfig.Changed += OnLevelsChanged; } } internal static void Register(ZRpc rpc) { rpc.Register<bool>("Rewards_Minute", (Action<ZRpc, bool>)RPC_Minute); rpc.Register<long>("Rewards_PresenceAck", (Action<ZRpc, long>)RPC_PresenceAck); rpc.Register<int>("Rewards_Claim", (Action<ZRpc, int>)RPC_Claim); rpc.Register<long>("Rewards_GrantAck", (Action<ZRpc, long>)RPC_GrantAck); rpc.Register<string>("Rewards_Admin", (Action<ZRpc, string>)RewardsAdmin.RPC_Admin); } internal static void OnJoined(ZNetPeer peer) { if (peer.m_socket == null) { return; } RewardsConfig.Tick(); string text = NormalizeId(peer.m_socket.GetHostName()); PlayerRecord playerRecord = RewardsDatabase.Load(text); if (playerRecord == null) { return; } playerRecord.LastName = peer.m_playerName; RewardProgress.Normalize(playerRecord, RewardsConfig.Levels, Restart); if (!Presences.TryGetValue(text, out var value)) { value = new PresenceState(Random); value.Start(Now, RewardsPlugin.CE_PresenceMinMinutes.Value, RewardsPlugin.CE_PresenceMaxMinutes.Value); Presences[text] = value; } RewardsSession rewardsSession = new RewardsSession { Peer = peer, Record = playerRecord, Presence = value }; Sessions[peer.m_uid] = rewardsSession; peer.m_rpc.Invoke("Rewards_Levels", new object[1] { RewardsConfig.SyncText }); SendState(rewardsSession); if (PresenceOn && value.Token.HasValue) { peer.m_rpc.Invoke("Rewards_Presence", new object[2] { value.Token.Value, Mathf.Max(0, Mathf.CeilToInt((float)(value.Deadline - Now))) }); } foreach (PendingGrant pendingGrant in playerRecord.PendingGrants) { SendGrant(rewardsSession, pendingGrant); } } internal static void OnLeft(ZNetPeer peer) { if (Sessions.TryGetValue(peer.m_uid, out var value)) { RewardsDatabase.Save(value.Record); Sessions.Remove(peer.m_uid); } } internal static void SaveAll() { foreach (RewardsSession value in Sessions.Values) { if (value.Dirty && RewardsDatabase.Save(value.Record)) { value.Dirty = false; } } _lastSave = Now; } internal static void Tick() { if (!RewardsRpc.IsServer) { return; } RewardsConfig.Tick(); double now = Now; foreach (RewardsSession value in Sessions.Values) { if (value.Peer.m_rpc == null) { continue; } if (!PresenceOn) { if (value.Presence.Token.HasValue) { value.Presence.Start(now, RewardsPlugin.CE_PresenceMinMinutes.Value, RewardsPlugin.CE_PresenceMaxMinutes.Value); SendState(value); } continue; } if (!_presenceWasOn) { value.Presence.Start(now, RewardsPlugin.CE_PresenceMinMinutes.Value, RewardsPlugin.CE_PresenceMaxMinutes.Value); } long? num = value.Presence.Due(now, RewardsPlugin.CE_PresenceResponseMinutes.Value); if (num.HasValue) { value.Peer.m_rpc.Invoke("Rewards_Presence", new object[2] { num.Value, RewardsPlugin.CE_PresenceResponseMinutes.Value * 60 }); } if (!value.Presence.Counts(now) != value.SentPaused) { SendState(value); } } _presenceWasOn = PresenceOn; if (now - _lastSave >= 300.0) { SaveAll(); } } [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] internal static RewardsSession FindOnline(string name) { foreach (RewardsSession value in Sessions.Values) { if (string.Equals(value.Peer.m_playerName, name, StringComparison.OrdinalIgnoreCase)) { return value; } } return null; } internal static void SendState(RewardsSession session) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if (session.Peer.m_rpc != null) { session.SentPaused = PresenceOn && !session.Presence.Counts(Now); ZPackage val = new ZPackage(); val.Write(session.Record.ActiveMinutes); val.Write(session.Record.ClaimedLevel); val.Write(session.Record.Cycle); val.Write(session.SentPaused); val.Write(PresenceOn && session.Presence.Token.HasValue); session.Peer.m_rpc.Invoke("Rewards_State", new object[1] { val }); } } internal static void MarkChanged(RewardsSession session) { session.Dirty = true; SendState(session); } private static void SendGrant(RewardsSession session, PendingGrant grant) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); RewardsRpc.WriteItems(val, grant.Items); session.Peer.m_rpc.Invoke("Rewards_Grant", new object[2] { grant.Id, val }); } private static void OnLevelsChanged() { foreach (RewardsSession value in Sessions.Values) { if (value.Peer.m_rpc != null) { value.Peer.m_rpc.Invoke("Rewards_Levels", new object[1] { RewardsConfig.SyncText }); SendState(value); } } } [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private static RewardsSession From(ZRpc rpc) { ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetPeer(rpc) : null); if (val == null || !Sessions.TryGetValue(val.m_uid, out var value)) { return null; } return value; } private static bool Alive(ZNetPeer peer, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; if (((ZDOID)(ref peer.m_characterID)).IsNone()) { return false; } ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO == null || zDO.GetBool(ZDOVars.s_dead, false) || zDO.GetFloat(ZDOVars.s_health, 1f) <= 0f) { return false; } position = zDO.GetPosition(); return true; } private static void RPC_Minute(ZRpc rpc, bool valid) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) RewardsSession rewardsSession = From(rpc); if (rewardsSession == null || !valid || !Alive(rewardsSession.Peer, out var position)) { return; } double now = Now; if (rewardsSession.Gate.Accept(now, new Vector3Like { X = position.x, Y = position.y, Z = position.z }, RewardsPlugin.CE_ServerStillMinutes.Value)) { if (RewardProgress.Normalize(rewardsSession.Record, RewardsConfig.Levels, Restart)) { MarkChanged(rewardsSession); } if ((!PresenceOn || rewardsSession.Presence.Counts(now)) && RewardProgress.CanAccrue(rewardsSession.Record, RewardsConfig.Levels, Restart)) { rewardsSession.Record.ActiveMinutes++; MarkChanged(rewardsSession); } } } private static void RPC_PresenceAck(ZRpc rpc, long token) { RewardsSession rewardsSession = From(rpc); if (rewardsSession != null && rewardsSession.Presence.Ack(token, Now, RewardsPlugin.CE_PresenceMinMinutes.Value, RewardsPlugin.CE_PresenceMaxMinutes.Value)) { SendState(rewardsSession); } } private static void RPC_Claim(ZRpc rpc, int expected) { RewardsSession rewardsSession = From(rpc); if (rewardsSession != null) { PendingGrant pendingGrant = RewardProgress.Claim(rewardsSession.Record, RewardsConfig.Levels, Restart, expected); if (pendingGrant == null) { SendState(rewardsSession); return; } rewardsSession.Dirty = true; RewardsDatabase.Save(rewardsSession.Record); SendState(rewardsSession); SendGrant(rewardsSession, pendingGrant); } } private static void RPC_GrantAck(ZRpc rpc, long id) { RewardsSession rewardsSession = From(rpc); if (rewardsSession != null && rewardsSession.Record.PendingGrants.RemoveAll((PendingGrant g) => g.Id == id) > 0) { RewardsDatabase.Save(rewardsSession.Record); } } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal static class RewardsAdmin { internal static void RPC_Admin(ZRpc rpc, string line) { string text = (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.ListContainsId(ZNet.instance.m_adminList, rpc.GetSocket().GetHostName())) ? Execute(line) : "$rw_cmd_denied"); rpc.Invoke("Rewards_Message", new object[1] { text }); } internal static string Execute(string line) { string[] array = line.Trim().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return "$rw_cmd_usage"; } switch (array[0].ToLowerInvariant()) { case "rewards_reload": RewardsConfig.Tick(force: true); return "$rw_cmd_reloaded"; case "rewards_add": { if (array.Length < 3 || !int.TryParse(array[^1], out var minutes)) { return "$rw_cmd_usage"; } return Apply(string.Join(" ", array, 1, array.Length - 2), delegate(PlayerRecord r) { r.ActiveMinutes = Math.Max(0, r.ActiveMinutes + minutes); }); } case "rewards_reset": if (array.Length < 2) { return "$rw_cmd_usage"; } return Apply(string.Join(" ", array, 1, array.Length - 1), delegate(PlayerRecord r) { r.ActiveMinutes = 0; r.ClaimedLevel = 0; r.Cycle = 1; }); default: return "$rw_cmd_usage"; } } private static string Apply(string name, Action<PlayerRecord> change) { RewardsSession rewardsSession = RewardsServer.FindOnline(name); if (rewardsSession == null) { return "$rw_cmd_notfound"; } change(rewardsSession.Record); rewardsSession.Dirty = true; RewardsDatabase.Save(rewardsSession.Record); RewardsServer.SendState(rewardsSession); return "$rw_cmd_done"; } internal static void Run(ConsoleEventArgs args) { if (!((Object)(object)ZNet.instance == (Object)null)) { if (ZNet.instance.IsServer()) { args.Context.AddString(RewardsText.L(Execute(args.FullLine))); return; } RewardsRpc.ToServer("Rewards_Admin", args.FullLine); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class Terminal_InitTerminal_Commands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; internal void <Postfix>b__0_0(ConsoleEventArgs args) { RewardsAdmin.Run(args); } internal void <Postfix>b__0_1(ConsoleEventArgs args) { RewardsAdmin.Run(args); } internal void <Postfix>b__0_2(ConsoleEventArgs args) { RewardsAdmin.Run(args); } } private static void Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { RewardsAdmin.Run(args); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("rewards_reload", "Reloads the Levels folder (admin)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { RewardsAdmin.Run(args); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("rewards_add", "<player> <minutes> adds active minutes (admin)", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { RewardsAdmin.Run(args); }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } new ConsoleCommand("rewards_reset", "<player> resets progress (admin)", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("radamanto.Rewards", "Rewards", "1.0.0")] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] public sealed class RewardsPlugin : BaseUnityPlugin { internal static ConfigSync ConfigSync = null; internal static ConfigEntry<bool> CE_LockConfiguration = null; internal static ConfigEntry<int> CE_IdleMinutes = null; internal static ConfigEntry<int> CE_ActivityMinCriteria = null; internal static ConfigEntry<int> CE_ServerStillMinutes = null; internal static ConfigEntry<bool> CE_PresenceEnabled = null; internal static ConfigEntry<int> CE_PresenceMinMinutes = null; internal static ConfigEntry<int> CE_PresenceMaxMinutes = null; internal static ConfigEntry<int> CE_PresenceResponseMinutes = null; internal static ConfigEntry<bool> CE_RestartAfterLastLevel = null; internal static ConfigEntry<Vector2> CE_ButtonPosition = null; public const string ModGuid = "radamanto.Rewards"; public const string ModName = "Rewards"; public const string ModVersion = "1.0.0"; internal static RewardsPlugin Instance = null; internal static readonly ManualLogSource Log = Logger.CreateLogSource("Rewards"); private readonly Harmony _harmony = new Harmony("radamanto.Rewards"); private void SetupConfig() { //IL_0196: Unknown result type (might be due to invalid IL or missing references) ConfigSync = new ConfigSync("radamanto.Rewards") { DisplayName = "Rewards", CurrentVersion = "1.0.0", MinimumRequiredVersion = "1.0.0", ModRequired = true }; CE_LockConfiguration = ((BaseUnityPlugin)this).Config.Bind<bool>("01 - General", "LockConfiguration", true, "Locks synchronized configuration to server authority."); ConfigSync.AddLockingConfigEntry<bool>(CE_LockConfiguration); CE_IdleMinutes = Bind("02 - Activity", "IdleMinutes", 3, "Minutes without any input before time stops counting.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60)); CE_ActivityMinCriteria = Bind("02 - Activity", "ActivityMinCriteria", 2, "How many of the 4 activity criteria a player must meet in each minute for that minute to count.\n1 - Movement: moved at least 8 meters (being carried by a ship also counts).\n2 - Camera: turned the camera at least 90 degrees in total.\n3 - Action variety: did at least 2 different kinds of action. Kinds: walk, jump, attack, block, build, pick up, interact, open inventory, chat, eat, craft, ship sails, ship rudder.\n4 - Target variety: hit or interacted with at least 2 different objects or creatures.\nExample: holding attack on the same rock meets only 1 criterion. Lower values are easier, 4 is the strictest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 4)); CE_ServerStillMinutes = Bind("02 - Activity", "ServerStillMinutes", 5, "Minutes standing on the same spot after which time stops counting.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60)); CE_PresenceEnabled = Bind("03 - Presence", "PresenceEnabled", value: true, "Enables the periodic presence check (the \"Are you still there?\" prompt). When disabled, only the activity checks apply."); CE_PresenceMinMinutes = Bind("03 - Presence", "PresenceMinMinutes", 20, "Minimum minutes between presence checks.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 600)); CE_PresenceMaxMinutes = Bind("03 - Presence", "PresenceMaxMinutes", 40, "Maximum minutes between presence checks.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 600)); CE_PresenceResponseMinutes = Bind("03 - Presence", "PresenceResponseMinutes", 10, "Minutes the player has to answer a presence check before time stops counting.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 120)); CE_RestartAfterLastLevel = Bind("04 - Levels", "RestartAfterLastLevel", value: true, "After claiming the last level, start again from level 1 in a new cycle."); CE_ButtonPosition = Bind<Vector2>("05 - Interface", "ButtonPosition", new Vector2(20f, 72f), "Position of the rewards button (pixels from the left edge, vertical offset from the center). Changed in game with Ctrl + drag.", null, synced: false); CE_ButtonPosition.SettingChanged += [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] (object _, EventArgs _) => { RewardsAccessButton.ApplyPosition(); }; } private ConfigEntry<T> Bind<[<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] T>(string section, string key, T value, string description, [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] AcceptableValueBase range = null, bool synced = true) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description + (synced ? " [Synced with server]" : " [Local]"), range, Array.Empty<object>())); if (synced) { ConfigSync.AddConfigEntry<T>(val).SynchronizedConfig = true; } return val; } private void Awake() { Instance = this; Localizer.Load(); SetupConfig(); RewardsAssets.Load(); _harmony.PatchAll(); ((MonoBehaviour)this).InvokeRepeating("TickServer", 1f, 1f); Log.LogInfo((object)"Rewards 1.0.0 loaded."); } private void TickServer() { RewardsServer.Tick(); } private void Update() { if (!RewardsRpc.IsServer || !ZNet.instance.IsDedicated()) { RewardsClient.Tick(); RewardsActivity.Tick(); } } private void OnDestroy() { ((MonoBehaviour)this).CancelInvoke(); RewardsUI.Dispose(); _harmony.UnpatchSelf(); RewardsAssets.Dispose(); } } internal static class RewardsText { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static string L(string text, params string[] args) { if (Localization.instance == null) { return text; } if (args.Length != 0) { return Localization.instance.Localize(text, args); } return Localization.instance.Localize(text); } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal static class RewardsClient { private const float DeliveryDelay = 3f; private static bool _claiming; private static float _readySince = -1f; [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(new byte[] { 1, 0, 1, 1 })] private static readonly List<(long Id, List<GrantItem> Items)> Incoming = new List<(long, List<GrantItem>)>(); internal static List<RewardLevel> Levels { get; private set; } = new List<RewardLevel>(); internal static PlayerRecord State { get; private set; } = new PlayerRecord(); internal static bool Paused { get; private set; } internal static bool Connected { get; private set; } internal static long? PresenceToken { get; private set; } internal static float PresenceDeadline { get; private set; } internal static int Unlocked => RewardProgress.Unlocked(State, Levels); internal static bool TimeLocked => RewardProgress.TimeLocked(State, Levels, RewardsBiomeLock.Has); [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] internal static RewardLevel Next { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(2)] get { if (State.ClaimedLevel >= Levels.Count) { return null; } return Levels[State.ClaimedLevel]; } } internal static int ReadyCount { get { int unlocked = Unlocked; int num = 0; for (int i = State.ClaimedLevel; i < unlocked && i < Levels.Count; i++) { RewardLevel rewardLevel = Levels[i]; if (RewardProgress.LockApplies(State, rewardLevel) && !RewardsBiomeLock.Has(rewardLevel.RequiredKey)) { break; } num++; } return num; } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] [method: <9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(2)] [field: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] internal static event Action Changed; internal static void Reset() { Levels = new List<RewardLevel>(); State = new PlayerRecord(); Paused = false; Connected = false; PresenceToken = null; _claiming = false; _readySince = -1f; Incoming.Clear(); RewardsClient.Changed?.Invoke(); } internal static void Register(ZRpc rpc) { rpc.Register<string>("Rewards_Levels", (Action<ZRpc, string>)RPC_Levels); rpc.Register<ZPackage>("Rewards_State", (Action<ZRpc, ZPackage>)RPC_State); rpc.Register<long, int>("Rewards_Presence", (Action<ZRpc, long, int>)RPC_Presence); rpc.Register<long, ZPackage>("Rewards_Grant", (Action<ZRpc, long, ZPackage>)RPC_Grant); rpc.Register<string>("Rewards_Message", (Action<ZRpc, string>)RPC_Message); } internal static bool CanClaimNext(out string reasonToken) { reasonToken = ""; RewardLevel next = Next; if (next == null || State.ClaimedLevel >= Unlocked) { reasonToken = "$rw_reason_time"; return false; } if (RewardProgress.LockApplies(State, next) && !RewardsBiomeLock.Has(next.RequiredKey)) { reasonToken = "$rw_reason_boss"; return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !HasSpace(localPlayer, next.Items.ConvertAll([<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] ([<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(1)] RewardItem i) => new GrantItem { Prefab = i.Prefab, Amount = i.Amount }))) { reasonToken = "$rw_reason_space"; return false; } return true; } internal static bool HasSpace(Player player, List<GrantItem> items) { Inventory inventory = ((Humanoid)player).GetInventory(); Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (GrantItem item in items) { dictionary[item.Prefab] = (dictionary.TryGetValue(item.Prefab, out var value) ? value : 0) + item.Amount; } int num = inventory.GetEmptySlots(); foreach (KeyValuePair<string, int> item2 in dictionary) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(item2.Key) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 == (Object)null)) { SharedData shared = val2.m_itemData.m_shared; int freeInStacks = ((shared.m_maxStackSize > 1) ? inventory.FindFreeStackSpace(shared.m_name, (float)Game.m_worldLevel) : 0); num -= RewardProgress.SlotsNeeded(item2.Value, freeInStacks, shared.m_maxStackSize); if (num < 0) { return false; } } } return true; } internal static void ClaimNext() { if (!CanClaimNext(out var reasonToken)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, RewardsText.L(reasonToken), 0, (Sprite)null, false); } } else if (!_claiming) { _claiming = true; RewardsRpc.ToServer("Rewards_Claim", State.ClaimedLevel); } } internal static void AnswerPresence() { if (PresenceToken.HasValue) { RewardsRpc.ToServer("Rewards_PresenceAck", PresenceToken.Value); PresenceToken = null; RewardsClient.Changed?.Invoke(); } } internal static void Tick() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting()) { _readySince = -1f; return; } if (_readySince < 0f) { _readySince = Time.realtimeSinceStartup; } if (Incoming.Count == 0 || Time.realtimeSinceStartup - _readySince < 3f) { return; } while (Incoming.Count > 0) { var (id, items) = Incoming[0]; if (!HasSpace(localPlayer, items)) { break; } Incoming.RemoveAt(0); Deliver(localPlayer, id, items); } } private static void RPC_Levels(ZRpc rpc, string raw) { Connected = true; Levels = RewardLevels.Parse(raw, (string _) => true, delegate(string w) { RewardsPlugin.Log.LogWarning((object)("[Levels] " + w)); }); RewardsClient.Changed?.Invoke(); } private static void RPC_State(ZRpc rpc, ZPackage pkg) { Connected = true; _claiming = false; int unlocked = Unlocked; State = new PlayerRecord { ActiveMinutes = pkg.ReadInt(), ClaimedLevel = pkg.ReadInt(), Cycle = pkg.ReadInt() }; Paused = pkg.ReadBool(); if (!pkg.ReadBool()) { PresenceToken = null; } if (Unlocked > unlocked && Unlocked > State.ClaimedLevel) { RewardsAudio.Play("SkillNode_Select"); } RewardsClient.Changed?.Invoke(); } private static void RPC_Presence(ZRpc rpc, long token, int seconds) { PresenceToken = token; PresenceDeadline = Time.realtimeSinceStartup + (float)seconds; RewardsAudio.Play("SkillTree_Click"); RewardsClient.Changed?.Invoke(); } private static void RPC_Grant(ZRpc rpc, long id, ZPackage pkg) { List<GrantItem> item = RewardsRpc.ReadItems(pkg); if (!Incoming.Exists(([<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(new byte[] { 0, 1, 1 })] (long Id, List<GrantItem> Items) i) => i.Id == id)) { Incoming.Add((id, item)); Tick(); } } private static void RPC_Message(ZRpc rpc, string text) { string text2 = RewardsText.L(text); Console instance = Console.instance; if (instance != null) { instance.Print(text2); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, text2, 0, (Sprite)null, false); } } private static void Deliver(Player player, long id, List<GrantItem> items) { Inventory inventory = ((Humanoid)player).GetInventory(); foreach (GrantItem item in items) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(item.Prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null) { RewardsPlugin.Log.LogWarning((object)("[Grant] Unknown item '" + item.Prefab + "' skipped.")); continue; } int num = item.Amount; while (num > 0) { ItemData val3 = val2.m_itemData.Clone(); val3.m_dropPrefab = val; val3.m_stack = Mathf.Min(num, Mathf.Max(1, val3.m_shared.m_maxStackSize)); val3.m_worldLevel = (byte)Game.m_worldLevel; num -= val3.m_stack; inventory.AddItem(val3); } ((Character)player).Message((MessageType)1, "$msg_added " + val2.m_itemData.m_shared.m_name, item.Amount, val2.m_itemData.GetIcon(), false); } RewardsAudio.PlayReward(); RewardsRpc.ToServer("Rewards_GrantAck", id); } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal static class RewardsConfig { private static string _stamp = ""; private static bool _loaded; internal static List<RewardLevel> Levels { get; private set; } = new List<RewardLevel>(); internal static string SyncText { get; private set; } = ""; [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] [method: <9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(2)] [field: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] internal static event Action Changed; internal static bool PrefabExists(string name) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(name) : null); if ((Object)(object)val != (Object)null) { return (Object)(object)val.GetComponent<ItemDrop>() != (Object)null; } return false; } internal static void Reset() { Levels = new List<RewardLevel>(); SyncText = ""; _loaded = false; _stamp = ""; } internal static void Tick(bool force = false) { if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || ObjectDB.instance.m_items.Count == 0) { return; } try { Directory.CreateDirectory(RewardsPaths.LevelsFolder); string[] files = Directory.GetFiles(RewardsPaths.LevelsFolder, "*.cfg", SearchOption.AllDirectories); StringBuilder stringBuilder = new StringBuilder(); string[] array = files; foreach (string text in array) { FileInfo fileInfo = new FileInfo(text); stringBuilder.Append(text).Append('|').Append(fileInfo.Length) .Append('|') .Append(fileInfo.LastWriteTimeUtc.Ticks) .Append(';'); } if (!_loaded || force || !(stringBuilder.ToString() == _stamp)) { _stamp = stringBuilder.ToString(); _loaded = true; List<(string, string)> list = new List<(string, string)>(); array = files; foreach (string text2 in array) { list.Add((text2.Substring(RewardsPaths.LevelsFolder.Length).TrimStart('\\', '/'), File.ReadAllText(text2))); } Levels = RewardLevels.Merge(list, PrefabExists, delegate(string w) { RewardsPlugin.Log.LogWarning((object)("[Levels] " + w)); }); SyncText = RewardLevels.Serialize(Levels); RewardsPlugin.Log.LogInfo((object)("[Levels] Loaded " + Levels.Count + " levels.")); RewardsConfig.Changed?.Invoke(); } } catch (Exception ex) { RewardsPlugin.Log.LogError((object)("[Levels] Failed to read " + RewardsPaths.LevelsFolder + ": " + ex.Message)); } } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal sealed class RewardItem { public string Prefab { get; set; } = ""; public int Amount { get; set; } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal sealed class RewardLevel { public int Number { get; set; } public int Minutes { get; set; } public List<RewardItem> Items { get; set; } = new List<RewardItem>(); public string RequiredKey { get; set; } = ""; } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static class RewardLevels { internal static List<RewardLevel> Parse(string text, Func<string, bool> prefabExists, Action<string> warn) { List<(int, Dictionary<string, string>)> list = new List<(int, Dictionary<string, string>)>(); Dictionary<string, string> dictionary = null; string[] array = text.Replace("\r", "").Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0 || text2.StartsWith("#") || text2.StartsWith(";")) { continue; } if (text2.StartsWith("[") && text2.EndsWith("]")) { dictionary = null; if (int.TryParse(text2.Substring(1, text2.Length - 2).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && result > 0) { dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); list.Add((result, dictionary)); } else { warn("Invalid level section " + text2 + "."); } } else { int num = text2.IndexOf('='); if (dictionary != null && num > 0) { dictionary[text2.Substring(0, num).Trim()] = text2.Substring(num + 1).Trim(); } } } List<RewardLevel> list2 = new List<RewardLevel>(); HashSet<int> hashSet = new HashSet<int>(); foreach (var (num2, values) in list) { if (!hashSet.Add(num2)) { warn("Level " + num2 + " is duplicated; keeping the first one."); continue; } RewardLevel rewardLevel = Build(num2, values, prefabExists, warn); if (rewardLevel != null) { list2.Add(rewardLevel); } } list2.Sort((RewardLevel a, RewardLevel b) => a.Number.CompareTo(b.Number)); return list2; } internal static List<RewardLevel> Merge([<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(new byte[] { 1, 0, 1, 1 })] IEnumerable<(string Name, string Text)> files, Func<string, bool> prefabExists, Action<string> warn) { List<(string, string)> list = new List<(string, string)>(files); list.Sort(([<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(new byte[] { 0, 1, 1 })] (string Name, string Text) a, [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(new byte[] { 0, 1, 1 })] (string Name, string Text) b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); List<RewardLevel> list2 = new List<RewardLevel>(); Dictionary<int, string> dictionary = new Dictionary<int, string>(); foreach (var item in list) { var (name, _) = item; foreach (RewardLevel item2 in Parse(item.Item2, prefabExists, delegate(string w) { warn(name + ": " + w); })) { if (dictionary.TryGetValue(item2.Number, out var value)) { warn(name + ": level " + item2.Number + " already defined in " + value + "; ignored."); } else { dictionary[item2.Number] = name; list2.Add(item2); } } } list2.Sort((RewardLevel a, RewardLevel b) => a.Number.CompareTo(b.Number)); return list2; } internal static string Serialize(IEnumerable<RewardLevel> levels) { StringBuilder stringBuilder = new StringBuilder(); foreach (RewardLevel level in levels) { stringBuilder.Append('[').Append(level.Number.ToString(CultureInfo.InvariantCulture)).Append("]\n"); stringBuilder.Append("Minutes = ").Append(level.Minutes.ToString(CultureInfo.InvariantCulture)).Append('\n'); stringBuilder.Append("Items = "); for (int i = 0; i < level.Items.Count; i++) { if (i > 0) { stringBuilder.Append(", "); } stringBuilder.Append(level.Items[i].Prefab).Append(':').Append(level.Items[i].Amount.ToString(CultureInfo.InvariantCulture)); } stringBuilder.Append('\n'); if (level.RequiredKey.Length > 0) { stringBuilder.Append("RequiredKey = ").Append(level.RequiredKey).Append('\n'); } } return stringBuilder.ToString(); } [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private static RewardLevel Build(int number, Dictionary<string, string> values, Func<string, bool> prefabExists, Action<string> warn) { if (!values.TryGetValue("Minutes", out var value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 0) { warn("Level " + number + " has an invalid Minutes value."); return null; } RewardLevel rewardLevel = new RewardLevel { Number = number, Minutes = result }; if (values.TryGetValue("RequiredKey", out var value2)) { rewardLevel.RequiredKey = value2; } if (!values.TryGetValue("Items", out var value3) || value3.Length == 0) { warn("Level " + number + " has no Items."); return null; } string[] array = value3.Split(new char[1] { ',' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); string text2 = array2[0].Trim(); if (array2.Length != 2 || text2.Length == 0 || !int.TryParse(array2[1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) || result2 <= 0) { warn("Level " + number + " has an invalid item entry '" + text.Trim() + "'."); return null; } if (!prefabExists(text2)) { warn("Level " + number + " uses unknown item '" + text2 + "'."); return null; } rewardLevel.Items.Add(new RewardItem { Prefab = text2, Amount = result2 }); } return rewardLevel; } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal static class RewardProgress { internal static int Unlocked(PlayerRecord r, IReadOnlyList<RewardLevel> levels) { int i; for (i = 0; i < levels.Count && levels[i].Minutes <= r.ActiveMinutes; i++) { } return i; } internal static bool LockApplies(PlayerRecord r, RewardLevel level) { if (level.RequiredKey.Length > 0) { return r.Cycle == 1; } return false; } internal static bool TimeLocked(PlayerRecord r, IReadOnlyList<RewardLevel> levels, Func<string, bool> hasKey) { for (int i = Math.Max(0, r.ClaimedLevel); i < levels.Count; i++) { RewardLevel rewardLevel = levels[i]; if (LockApplies(r, rewardLevel) && !hasKey(rewardLevel.RequiredKey)) { return r.ActiveMinutes >= rewardLevel.Minutes; } } return false; } [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] internal static PendingGrant Claim(PlayerRecord r, IReadOnlyList<RewardLevel> levels, bool restart, int expected) { if (expected != r.ClaimedLevel || r.ClaimedLevel < 0 || r.ClaimedLevel >= Unlocked(r, levels)) { return null; } RewardLevel rewardLevel = levels[r.ClaimedLevel]; PendingGrant pendingGrant = new PendingGrant { Id = ++r.NextGrantId }; foreach (RewardItem item in rewardLevel.Items) { pendingGrant.Items.Add(new GrantItem { Prefab = item.Prefab, Amount = item.Amount }); } r.PendingGrants.Add(pendingGrant); r.ClaimedLevel++; if (restart && r.ClaimedLevel >= levels.Count) { r.ActiveMinutes = 0; r.ClaimedLevel = 0; r.Cycle++; } return pendingGrant; } internal static bool CanAccrue(PlayerRecord r, IReadOnlyList<RewardLevel> levels, bool restart) { if (levels.Count == 0) { return false; } if (!restart) { return r.ClaimedLevel < levels.Count; } return true; } internal static int SlotsNeeded(int amount, int freeInStacks, int maxStack) { int num = amount - Math.Max(0, freeInStacks); if (num <= 0) { return 0; } int num2 = Math.Max(1, maxStack); return (num + num2 - 1) / num2; } internal static bool Normalize(PlayerRecord r, IReadOnlyList<RewardLevel> levels, bool restart) { if (!restart || levels.Count == 0 || r.ClaimedLevel < levels.Count) { return false; } r.ActiveMinutes = 0; r.ClaimedLevel = 0; r.Cycle++; return true; } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(0)] internal static (int First, int Last) Window(int current, int total, int visible = 6) { if (total <= visible) { return (First: 0, Last: Math.Max(0, total - 1)); } int num = Math.Max(0, Math.Min(current - 2, total - visible)); return (First: num, Last: num + visible - 1); } internal static float Fill(PlayerRecord r, IReadOnlyList<RewardLevel> levels, int index) { if (index < 0 || index >= levels.Count) { return 0f; } int num = ((index != 0) ? levels[index - 1].Minutes : 0); int minutes = levels[index].Minutes; if (r.ActiveMinutes >= minutes) { return 1f; } if (r.ActiveMinutes <= num || minutes <= num) { return 0f; } return (float)(r.ActiveMinutes - num) / (float)(minutes - num); } } [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(2)] internal static class RewardsAccessButton { [Serializable] [CompilerGenerated] private sealed class <>c { [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] public static readonly <>c <>9 = new <>c(); [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] public static UnityAction <>9__19_0; internal void <Create>b__19_0() { if (!CtrlHeld) { RewardsWindow.Toggle(); } } } private const float IconSize = 64f; private static readonly Color NormalTint = Color.white; private static readonly Color HoverTint = new Color(0.68f, 0.68f, 0.68f, 1f); private static readonly Color PressedTint = new Color(0.45f, 0.45f, 0.45f, 1f); private static GameObject _root; private static RectTransform _button; private const float BadgeSize = 20f; private static readonly Color BadgeGreen = new Color(0.3f, 0.78f, 0.5f, 1f); private static readonly Color BadgeAlert = new Color(0.86f, 0.33f, 0.16f, 1f); private static Image _glow; private static Image _badgeBody; private static RectTransform _badge; private static TMP_Text _badgeText; private static bool _warned; internal static RectTransform Button => _button; internal static bool CtrlHeld { get { if (!ZInput.GetKey((KeyCode)306, false)) { return ZInput.GetKey((KeyCode)305, false); } return true; } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] internal static void Ensure(InventoryGui gui) { if (!((Object)(object)_root != (Object)null)) { _root = Create(gui); if ((Object)(object)_root == (Object)null && !_warned) { _warned = true; RewardsPlugin.Log.LogWarning((object)"[Rewards] Could not create the rewards button."); } } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [return: <708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private static GameObject Create(InventoryGui gui) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Expected O, but got Unknown Canvas componentInParent = ((Component)gui).GetComponentInParent<Canvas>(); Sprite val = RewardsAssets.Optional("ico_rewards_menu"); if ((Object)(object)componentInParent == (Object)null || (Object)(object)val == (Object)null) { return null; } RewardsArt.Create(); RectTransform obj = RewardsKit.Stretch(RewardsKit.Rect(((Component)componentInParent.rootCanvas).transform, "RW_AccessButtonRoot"), 0f); ((Component)obj).gameObject.AddComponent<Canvas>().overrideSorting = false; ((Component)obj).gameObject.AddComponent<GraphicRaycaster>(); RectTransform val2 = RewardsKit.Rect((Transform)(object)obj, "RW_AccessButton"); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 0.5f); val2.sizeDelta = new Vector2(64f, 64f); val2.anchoredPosition = RewardsPlugin.CE_ButtonPosition.Value; Image val4 = ((Component)val2).gameObject.AddComponent<Image>(); val4.sprite = val; val4.preserveAspect = true; _badge = RewardsKit.Rect((Transform)(object)val2, "Badge", new Vector2(20f, 20f), Vector2.zero); RectTransform badge = _badge; RectTransform badge2 = _badge; ((Vector2)(ref val3))..ctor(1f, 1f); badge2.anchorMax = val3; badge.anchorMin = val3; _badge.anchoredPosition = new Vector2(-8f, -8f); _glow = RewardsKit.Image((Transform)(object)_badge, "Glow", RewardsArt.Glow, Color.clear, new Vector2(40f, 40f), Vector2.zero); RewardsKit.Image((Transform)(object)_badge, "Shadow", RewardsArt.Rounded, new Color(0f, 0f, 0f, 0.6f), new Vector2(23f, 23f), new Vector2(0f, -1f)).pixelsPerUnitMultiplier = 1.7f; _badgeBody = RewardsKit.Image((Transform)(object)_badge, "Ring", RewardsArt.Rounded, BadgeGreen, new Vector2(20f, 20f), Vector2.zero); _badgeBody.pixelsPerUnitMultiplier = 2f; RewardsKit.Image((Transform)(object)_badge, "Body", RewardsArt.Rounded, new Color(0.07f, 0.055f, 0.04f, 1f), new Vector2(16f, 16f), Vector2.zero).pixelsPerUnitMultiplier = 2.5f; _badgeText = RewardsKit.Text((Transform)(object)_badge, "Count", "", 11f, RewardsArt.Parchment, (TextAlignmentOptions)514, new Vector2(26f, 20f), new Vector2(0f, 0.5f)); if ((Object)(object)gui.m_containerName != (Object)null && (Object)(object)gui.m_containerName.font != (Object)null) { _badgeText.font = gui.m_containerName.font; } _badgeText.fontStyle = (FontStyles)1; _badgeText.textWrappingMode = (TextWrappingModes)0; ((Component)_badge).gameObject.SetActive(false); Button obj2 = ((Component)val2).gameObject.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)val4; ColorBlock colors = ((Selectable)obj2).colors; ((ColorBlock)(ref colors)).normalColor = NormalTint; ((ColorBlock)(ref colors)).selectedColor = NormalTint; ((ColorBlock)(ref colors)).highlightedColor = HoverTint; ((ColorBlock)(ref colors)).pressedColor = PressedTint; ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((ColorBlock)(ref colors)).fadeDuration = 0.08f; ((Selectable)obj2).colors = colors; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj2).navigation = navigation; ButtonClickedEvent onClick = obj2.onClick; object obj3 = <>c.<>9__19_0; if (obj3 == null) { UnityAction val5 = delegate { if (!CtrlHeld) { RewardsWindow.Toggle(); } }; <>c.<>9__19_0 = val5; obj3 = (object)val5; } ((UnityEvent)onClick).AddListener((UnityAction)obj3); ((Component)val2).gameObject.AddComponent<RewardsAccessButtonDrag>(); AddTooltip(gui, ((Component)val2).gameObject); _button = val2; return ((Component)obj).gameObject; } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void AddTooltip(InventoryGui gui, GameObject go) { //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) UITooltip componentInChildren = ((Component)gui).GetComponentInChildren<UITooltip>(true); if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.m_tooltipPrefab == (Object)null)) { UITooltip obj = go.AddComponent<UITooltip>(); obj.m_tooltipPrefab = componentInChildren.m_tooltipPrefab; obj.Set("", "$rw_title", (RectTransform)null, default(Vector2)); } } internal static void Tick() { //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || (Object)(object)_button == (Object)null) { return; } bool flag = (Object)(object)Player.m_localPlayer != (Object)null && !Hud.IsUserHidden() && RewardsClient.Connected; if (((Component)_button).gameObject.activeSelf != flag) { ((Component)_button).gameObject.SetActive(flag); } if (!flag || (Object)(object)_badge == (Object)null || (Object)(object)_glow == (Object)null || (Object)(object)_badgeBody == (Object)null || (Object)(object)_badgeText == (Object)null) { return; } bool hasValue = RewardsClient.PresenceToken.HasValue; int num = ((!hasValue) ? RewardsClient.ReadyCount : 0); bool flag2 = hasValue || num > 0; if (((Component)_badge).gameObject.activeSelf != flag2) { ((Component)_badge).gameObject.SetActive(flag2); } if (flag2) { string text = (hasValue ? "!" : ((num > 99) ? "99+" : num.ToString())); if (_badgeText.text != text) { _badgeText.text = text; } _badgeText.fontSize = ((text.Length > 2) ? 8 : ((text.Length > 1) ? 10 : 11)); ((Graphic)_badgeBody).color = (hasValue ? BadgeAlert : BadgeGreen); float num2 = 0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * 6f); ((Graphic)_glow).color = (Color)(hasValue ? new Color(BadgeAlert.r, BadgeAlert.g, BadgeAlert.b, 0.25f + 0.35f * num2) : Color.clear); ((Transform)_badge).localScale = Vector3.one * (hasValue ? (1f + 0.08f * num2) : 1f); } } internal static void SavePosition(Vector2 position) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) RewardsPlugin.CE_ButtonPosition.Value = position; } internal static void ApplyPosition() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_button != (Object)null) { _button.anchoredPosition = RewardsPlugin.CE_ButtonPosition.Value; } } internal static void Dispose() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _button = null; _glow = null; _badge = null; _badgeBody = null; _badgeText = null; } } public class RewardsAccessButtonDrag : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler { [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(1)] private RectTransform _rect; [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(2)] private Canvas _canvas; private bool _dragging; private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _rect = (RectTransform)((Component)this).transform; _canvas = ((Component)this).GetComponentInParent<Canvas>(); } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] public void OnBeginDrag(PointerEventData eventData) { _dragging = RewardsAccessButton.CtrlHeld; if (!_dragging) { eventData.pointerDrag = null; } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] public void OnDrag(PointerEventData eventData) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (_dragging) { float num = (((Object)(object)_canvas != (Object)null) ? _canvas.rootCanvas.scaleFactor : 1f); _rect.anchoredPosition = Clamp(_rect.anchoredPosition + eventData.delta / Mathf.Max(0.01f, num)); } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] public void OnEndDrag(PointerEventData eventData) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (_dragging) { _dragging = false; RewardsAccessButton.SavePosition(_rect.anchoredPosition); } } private Vector2 Clamp(Vector2 position) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Transform parent = ((Transform)_rect).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return position; } Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; rect = _rect.rect; Vector2 size2 = ((Rect)(ref rect)).size; float num = Mathf.Clamp(position.x, 0f, Mathf.Max(0f, size.x - size2.x)); float num2 = Mathf.Clamp(position.y, (0f - size.y) * 0.5f + size2.y * 0.5f, size.y * 0.5f - size2.y * 0.5f); return new Vector2(num, num2); } } [HarmonyPatch(typeof(InventoryGui), "Awake")] internal static class InventoryGui_Awake_AccessButton { [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] private static void Postfix(InventoryGui __instance) { RewardsAccessButton.Ensure(__instance); } } [<9ceecfe7-7ce3-4635-930c-f9946001ebbf>NullableContext(1)] [<708e428e-57cb-4a78-8091-80df3604fcfc>Nullable(0)] internal static class RewardsArt { internal static readonly Color Gold = new Color(50f / 51f, 63f / 85f, 0.36078432f); internal static readonly Color GoldDim = new Color(Gold.r * 0.63f, Gold.g * 0.61f, Gold.b * 0.66f); internal static readonly Color Parchment = new Color(0.96f, 0.9f, 0.78f); internal static readonly Color Grey = new Color(0.7f, 0.64f, 0.55f); internal static readonly Color Refund = new Color(0.98f, 0.42f, 0.33f); internal static readonly Color Locked = new Color(0.32f, 0.29f, 0.26f); internal static Sprite Glow = null; internal static Sprite Haze = null; internal static Sprite Rounded = null; internal static Sprite Diamond = null; internal static Sprite Fade = null; internal static Sprite Sheen = null; internal static Sprite ThinRing = null; internal static Sprite Vignette = null; internal static Sprite Panel = null; internal static Sprite Frame = null; internal static Sprite FrameInner = null; internal static Sprite InnerShadow = null; internal static Sprite Corner = null; internal static Texture2D Grain = null; internal static readonly Color Iron = new Color(0.27f, 0.25f, 0.23f); internal static readonly Color Plate = new Color(0.06f, 0.05f, 0.042f, 0.95f); private static readonly List<Object> Owned = new List<Object>(); private static readonly List<Image> NightLayers = new List<Image>(); private static float _night; private static float _applied = -1f; internal static string Hex(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(color); } internal static Image Night(Transform parent, float roundness) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) Image val = RewardsKit.Fill(parent, "Night", Rounded, new Color(0f, 0f, 0f, Mathf.Max(0f, _applied) * 0.45f), 0f); val.pixelsPerUnitMultiplier = roundness; NightLayers.Add(val); return val; } internal static void TickNight() { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if (Object.op_Implicit((Object)(object)EnvMan.instance)) { float dayFraction = EnvMan.instance.GetDayFraction(); num = 1f - Mathf.Clamp01((Mathf.Sin((dayFraction - 0.25f) * 2f * (float)Math.PI) + 0.3f) / 0.6f); } _night = Mathf.MoveTowards(_night, num, Time.unscaledDeltaTime * 0.25f); if (Mathf.Abs(_night - _applied) < 0.01f) { return; } _applied = _night; NightLayers.RemoveAll((Image layer) => !Object.op_Implicit((Object)(object)layer)); foreach (Image nightLayer in NightLayers) { ((Graphic)nightLayer).color = new Color(0f, 0f, 0f, _applied * 0.45f); } } internal static void Create() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Glow)) { Glow = Build(128, 128, delegate(int x, int y) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(Vector2.Distance(new Vector2((float)x, (float)y), new Vector2(64f, 64f)) / 64f); return Mathf.Pow(1f - num, 2.2f); }, Vector4.zero); Random grain = new Random(7); Haze = Build(1024, 1024, delegate(int x, int y) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(Vector2.Distance(new Vector2((float)x, (float)y), new Vector2(511.5f, 511.5f)) / 512f); float num2 = (float)(grain.NextDouble() - grain.NextDouble()) * 0.12f * (1f - num); return Mathf.Exp((0f - num) * num * 5f) * (1f - num * num) + num2; }, Vector4.zero); Rounded = Build(64, 64, (int x, int y) => Mathf.Clamp01(0.5f - Box(x, y, 64, 16f)), new Vector4(20f, 20f, 20f, 20f)); Diamond = Build(32, 32, (int x, int y) => Mathf.Clamp01(15.5f - Mathf.Abs((float)x - 15.5f) - Mathf.Abs((float)y - 15.5f)), Vector4.zero); Fade = Build(128, 4, (int x, int y) => Mathf.Sin((float)Math.PI * (float)x / 127f), Vector4.zero); Sheen = Build(4, 64, (int x, int y) => Mathf.Pow((float)y / 63f, 2f), Vector4.zero); ThinRing = Build(256, 256, delegate(int x, int y) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Abs(Vector2.Distance(new Vector2((float)x, (float)y), new Vector2(127.5f, 127.5f)) - 126f); return Mathf.Clamp01(1.2f - num); }, Vector4.zero); Panel = Build(64, 64, (int x, int y) => Mathf.Clamp01(0.5f - Box(x, y, 64, 6f)), new Vector4(12f, 12f, 12f, 12f)); Frame = Build(64, 64, delegate(int x, int y) { float num = Box(x, y, 64, 6f); return Mathf.Clamp01(0.5f - num) * Mathf.Clamp01(num + 2.5f); }, new Vector4(12f, 12f, 12f, 12f)); FrameInner = Build(64, 64, delegate(int x, int y) { float num = Box(x, y, 64, 6f) + 5f; return Mathf.Clamp01(0.5f - num) * Mathf.Clamp01(num + 1.5f); }, new Vector4(14f, 14f, 14f, 14f)); InnerShadow = Build(64, 64, delegate(int x, int y) { float num = Box(x, y, 64, 6f); return Mathf.Clamp01(0.5f - num) * Mathf.Pow(Mathf.Clamp01(1f + num / 22f), 2.2f); }, new Vector4(26f, 26f, 26f, 26f)); Corner = Build(48, 48, delegate(int x, int y) { float num = (float)x + 0.5f; float nu