Decompiled source of Sanguis v1.0.0

Sanguis.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Network;
using ProjectM.Physics;
using ProjectM.Scripting;
using Sanguis.Services;
using Stunlock.Core;
using Stunlock.Localization;
using Stunlock.Network;
using Unity.Collections;
using Unity.Entities;
using Unity.Scenes;
using UnityEngine;
using VampireCommandFramework;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Sanguis")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Sanguis")]
[assembly: AssemblyTitle("Sanguis")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Sanguis
{
	internal static class Core
	{
		public class DataStructures
		{
			private static readonly JsonSerializerOptions prettyJsonOptions = new JsonSerializerOptions
			{
				WriteIndented = true,
				IncludeFields = true
			};

			private static Dictionary<ulong, (int Tokens, (DateTime Start, DateTime DailyLogin) TimeData)> playerTokens = new Dictionary<ulong, (int, (DateTime, DateTime))>();

			private static readonly Dictionary<string, string> filePaths = new Dictionary<string, string> { 
			{
				"Tokens",
				JsonFiles.PlayerTokenJsons
			} };

			public static Dictionary<ulong, (int Tokens, (DateTime Start, DateTime DailyLogin) TimeData)> PlayerTokens
			{
				get
				{
					return playerTokens;
				}
				set
				{
					playerTokens = value;
				}
			}

			public static void LoadData<T>(ref Dictionary<ulong, T> dataStructure, string key)
			{
				string path = filePaths[key];
				if (!File.Exists(path))
				{
					File.Create(path).Dispose();
					dataStructure = new Dictionary<ulong, T>();
					return;
				}
				try
				{
					string text = File.ReadAllText(path);
					if (string.IsNullOrWhiteSpace(text))
					{
						dataStructure = new Dictionary<ulong, T>();
						return;
					}
					Dictionary<ulong, T> dictionary = JsonSerializer.Deserialize<Dictionary<ulong, T>>(text, prettyJsonOptions);
					dataStructure = dictionary ?? new Dictionary<ulong, T>();
				}
				catch (IOException)
				{
					dataStructure = new Dictionary<ulong, T>();
				}
				catch (JsonException)
				{
					dataStructure = new Dictionary<ulong, T>();
				}
			}

			public static void LoadPlayerTokens()
			{
				LoadData(ref playerTokens, "Tokens");
			}

			public static void SaveData<T>(Dictionary<ulong, T> data, string key)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Expected O, but got Unknown
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Expected O, but got Unknown
				string path = filePaths[key];
				bool flag = default(bool);
				try
				{
					string contents = JsonSerializer.Serialize(data, prettyJsonOptions);
					File.WriteAllText(path, contents);
				}
				catch (IOException ex)
				{
					ManualLogSource log = Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to write ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" data to file: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log.LogError(val);
				}
				catch (JsonException ex2)
				{
					ManualLogSource log2 = Log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(44, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("JSON serialization error when saving ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" data: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
					}
					log2.LogError(val);
				}
			}

			public static void SavePlayerTokens()
			{
				SaveData(PlayerTokens, "Tokens");
			}
		}

		private static class JsonFiles
		{
			public static readonly string PlayerTokenJsons = Plugin.PlayerTokensPath;
		}

		public static bool hasInitialized;

		public static World Server { get; } = GetWorld("Server") ?? throw new Exception("There is no Server world (yet)...");


		public static EntityManager EntityManager { get; } = Server.EntityManager;


		public static ServerScriptMapper ServerScriptMapper { get; internal set; }

		public static ServerGameManager ServerGameManager => ServerScriptMapper.GetServerGameManager();

		public static PrefabCollectionSystem PrefabCollectionSystem { get; internal set; }

		public static LocalizationService Localization { get; } = new LocalizationService();


		public static SanguisService SanguisService { get; internal set; }

		public static ManualLogSource Log => Plugin.LogInstance;

		public static void Initialize()
		{
			if (!hasInitialized)
			{
				ServerScriptMapper = Server.GetExistingSystemManaged<ServerScriptMapper>();
				PrefabCollectionSystem = Server.GetExistingSystemManaged<PrefabCollectionSystem>();
				SanguisService = new SanguisService();
				hasInitialized = true;
			}
		}

		private static World GetWorld(string name)
		{
			Enumerator<World> enumerator = World.s_AllWorlds.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current.Name == name)
				{
					return current;
				}
			}
			return null;
		}
	}
	public static class ECSExtensions
	{
		private static EntityManager EntityManager { get; } = Core.Server.EntityManager;


		public unsafe static void Write<T>(this Entity entity, T componentData) where T : struct
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte[] array = StructureToByteArray(componentData);
			int num = Marshal.SizeOf<T>();
			fixed (byte* ptr = array)
			{
				EntityManager entityManager = EntityManager;
				((EntityManager)(ref entityManager)).SetComponentDataRaw(entity, val.TypeIndex, (void*)ptr, num);
			}
		}

		public static byte[] StructureToByteArray<T>(T structure) where T : struct
		{
			int num = Marshal.SizeOf(structure);
			byte[] array = new byte[num];
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.StructureToPtr(structure, intPtr, fDeleteOld: true);
			Marshal.Copy(intPtr, array, 0, num);
			Marshal.FreeHGlobal(intPtr);
			return array;
		}

		public unsafe static T Read<T>(this Entity entity) where T : struct
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = EntityManager;
			return Marshal.PtrToStructure<T>(new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, val.TypeIndex)));
		}

		public static DynamicBuffer<T> ReadBuffer<T>(this Entity entity) where T : struct
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.Server.EntityManager;
			return ((EntityManager)(ref entityManager)).GetBuffer<T>(entity, false);
		}

		public static bool Has<T>(this Entity entity)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = EntityManager;
			return ((EntityManager)(ref entityManager)).HasComponent(entity, val);
		}

		public static string LookupName(this PrefabGUID prefabGuid)
		{
			//IL_0011: 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_0031: 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)
			PrefabCollectionSystem existingSystemManaged = Core.Server.GetExistingSystemManaged<PrefabCollectionSystem>();
			object obj;
			if (!existingSystemManaged.PrefabGuidToNameDictionary.ContainsKey(prefabGuid))
			{
				obj = "GUID Not Found";
			}
			else
			{
				string text = existingSystemManaged.PrefabGuidToNameDictionary[prefabGuid];
				PrefabGUID val = prefabGuid;
				obj = text + " " + ((object)(PrefabGUID)(ref val)).ToString();
			}
			return obj.ToString();
		}

		public static void LogComponentTypes(this Entity entity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			Enumerator<ComponentType> enumerator = ((EntityManager)(ref entityManager)).GetComponentTypes(entity, (Allocator)2).GetEnumerator();
			Core.Log.LogInfo((object)"===");
			bool flag = default(bool);
			while (enumerator.MoveNext())
			{
				ComponentType current = enumerator.Current;
				ManualLogSource log = Core.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(0, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ComponentType>(current);
				}
				log.LogInfo(val);
			}
			Core.Log.LogInfo((object)"===");
		}

		public static void Add<T>(this Entity entity)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = EntityManager;
			((EntityManager)(ref entityManager)).AddComponent(entity, val);
		}

		public static void Remove<T>(this Entity entity)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = EntityManager;
			((EntityManager)(ref entityManager)).RemoveComponent(entity, val);
		}
	}
	[BepInPlugin("io.zfolmt.Sanguis", "Sanguis", "1.0.0")]
	public class Plugin : BasePlugin
	{
		private Harmony _harmony;

		public static readonly string ConfigPath = Path.Combine(Paths.ConfigPath, "Sanguis");

		public static readonly string PlayerTokensPath = Path.Combine(ConfigPath, "PlayerSanguis");

		private static ConfigEntry<bool> _Sanguisystem;

		private static ConfigEntry<bool> _dailyLogin;

		private static ConfigEntry<int> _dailyReward;

		private static ConfigEntry<int> _dailyQuantity;

		private static ConfigEntry<int> _SanguisReward;

		private static ConfigEntry<int> _SanguisRewardRatio;

		private static ConfigEntry<int> _SanguisPerMinute;

		private static ConfigEntry<int> _updateInterval;

		internal static Plugin Instance { get; private set; }

		public static Harmony Harmony => Instance._harmony;

		public static ManualLogSource LogInstance => ((BasePlugin)Instance).Log;

		public static bool TokenSystem => _Sanguisystem.Value;

		public static bool DailyLogin => _dailyLogin.Value;

		public static int DailyReward => _dailyReward.Value;

		public static int DailyQuantity => _dailyQuantity.Value;

		public static int TokenReward => _SanguisReward.Value;

		public static int TokenRewardRatio => _SanguisRewardRatio.Value;

		public static int TokensPerMinute => _SanguisPerMinute.Value;

		public static int UpdateInterval => _updateInterval.Value;

		public override void Load()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Instance = this;
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			InitConfig();
			CommandRegistry.RegisterAll();
			LoadAllData();
			ManualLogSource log = Core.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Sanguis");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] loaded!");
			}
			log.LogInfo(val);
		}

		private static void InitConfig()
		{
			CreateDirectories(ConfigPath);
			_Sanguisystem = InitConfigEntry("Config", "Sanguis", defaultValue: false, "Enable or disable Sanguis.");
			_dailyLogin = InitConfigEntry("Config", "DailyLogin", defaultValue: false, "Enable or disable daily login rewards.");
			_SanguisReward = InitConfigEntry("Config", "SanguisItemReward", 576389135, "Item prefab for Sanguis redeeming (crystals default).");
			_dailyReward = InitConfigEntry("Config", "DailyItemReward", -257494203, "Item prefab for daily login (crystals default).");
			_dailyQuantity = InitConfigEntry("Config", "DailyItemQuantity", 50, "Amount rewarded for daily login.");
			_SanguisRewardRatio = InitConfigEntry("Config", "SanguisRewardFactor", 6, "Sanguis/reward when redeeming.");
			_SanguisPerMinute = InitConfigEntry("Config", "SanguisPerMinute", 5, "Sanguis/minute spent online.");
			_updateInterval = InitConfigEntry("Config", "SanguisUpdateInterval", 30, "Interval in minutes to update player Sanguis.");
		}

		private static ConfigEntry<T> InitConfigEntry<T>(string section, string key, T defaultValue, string description)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<T> val = ((BasePlugin)Instance).Config.Bind<T>(section, key, defaultValue, description);
			string text = Path.Combine(ConfigPath, "io.zfolmt.Sanguis.cfg");
			ConfigEntry<T> val2 = default(ConfigEntry<T>);
			if (File.Exists(text) && new ConfigFile(text, true).TryGetEntry<T>(section, key, ref val2))
			{
				val.Value = val2.Value;
			}
			return val;
		}

		private static void CreateDirectories(string path)
		{
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
			}
		}

		public override bool Unload()
		{
			((BasePlugin)this).Config.Clear();
			_harmony.UnpatchSelf();
			return true;
		}

		private static void LoadAllData()
		{
			if (_Sanguisystem.Value)
			{
				Core.DataStructures.LoadPlayerTokens();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "io.zfolmt.Sanguis";

		public const string PLUGIN_NAME = "Sanguis";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Sanguis.Services
{
	internal class LocalizationService
	{
		private struct Code
		{
			public string Key { get; set; }

			public string Value { get; set; }

			public string Description { get; set; }
		}

		private struct Node
		{
			public string Guid { get; set; }

			public string Text { get; set; }
		}

		private struct LocalizationFile
		{
			public Code[] Codes { get; set; }

			public Node[] Nodes { get; set; }
		}

		private Dictionary<string, string> localization = new Dictionary<string, string>();

		private Dictionary<int, string> prefabNames = new Dictionary<int, string>();

		public LocalizationService()
		{
			LoadLocalization();
			LoadPrefabNames();
		}

		private void LoadLocalization()
		{
			string name = "Sanguis.Localization.English.json";
			using StreamReader streamReader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(name));
			localization = JsonSerializer.Deserialize<LocalizationFile>(streamReader.ReadToEnd()).Nodes.ToDictionary((Node x) => x.Guid, (Node x) => x.Text);
		}

		private void LoadPrefabNames()
		{
			string name = "Sanguis.Localization.Prefabs.json";
			using StreamReader streamReader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(name));
			string json = streamReader.ReadToEnd();
			prefabNames = JsonSerializer.Deserialize<Dictionary<int, string>>(json);
		}

		public string GetLocalization(string guid)
		{
			if (localization.TryGetValue(guid, out var value))
			{
				return value;
			}
			return "<Localization not found for " + guid + ">";
		}

		public string GetLocalization(LocalizationKey key)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Guid val = ((AssetGuid)(ref key.Key)).ToGuid();
			string guid = ((object)(Guid)(ref val)).ToString();
			return GetLocalization(guid);
		}

		public string GetPrefabName(PrefabGUID itemPrefabGUID)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			if (!prefabNames.TryGetValue(itemPrefabGUID._Value, out var value))
			{
				return null;
			}
			string text = GetLocalization(value);
			PrefabLookupMap prefabLookupMap = Core.PrefabCollectionSystem._PrefabLookupMap;
			Entity entity = default(Entity);
			if (((PrefabLookupMap)(ref prefabLookupMap)).TryGetValue(itemPrefabGUID, ref entity) && entity.Has<ItemData>() && (int)entity.Read<ItemData>().ItemType == 5)
			{
				text = "Book " + text;
			}
			return text;
		}
	}
	internal class SanguisService
	{
		private static readonly ComponentType[] UserComponent = (ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly(Il2CppType.Of<User>()) };

		private static readonly int intervalMinutes = Plugin.UpdateInterval;

		private static readonly int tokensPerMinute = Plugin.TokensPerMinute;

		private static readonly bool TokenSystem = Plugin.TokenSystem;

		public static string tokenReward;

		public static string dailyReward;

		private static EntityQuery UserQuery;

		private readonly IgnorePhysicsDebugSystem tokenMonoBehaviour;

		public SanguisService()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			UserQuery = ((EntityManager)(ref entityManager)).CreateEntityQuery(UserComponent);
			tokenReward = Core.Localization.GetPrefabName(new PrefabGUID(Plugin.TokenReward));
			dailyReward = Core.Localization.GetPrefabName(new PrefabGUID(Plugin.DailyReward));
			tokenMonoBehaviour = new GameObject("SanguisService").AddComponent<IgnorePhysicsDebugSystem>();
			if (TokenSystem)
			{
				((MonoBehaviour)tokenMonoBehaviour).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(UpdateLoop()));
			}
		}

		private static IEnumerator UpdateLoop()
		{
			WaitForSeconds waitForSeconds = new WaitForSeconds((float)(intervalMinutes * 60));
			while (true)
			{
				NativeArray<Entity> userEntities = ((EntityQuery)(ref UserQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3));
				DateTime now = DateTime.Now;
				try
				{
					Dictionary<ulong, (int Tokens, (DateTime Start, DateTime End) TimeData)> updatedTokens = new Dictionary<ulong, (int, (DateTime, DateTime))>();
					Enumerator<Entity> enumerator = userEntities.GetEnumerator();
					while (enumerator.MoveNext())
					{
						User val = enumerator.Current.Read<User>();
						if (val.IsConnected)
						{
							ulong platformId = val.PlatformId;
							if (Core.DataStructures.PlayerTokens.TryGetValue(platformId, out (int, (DateTime, DateTime)) value))
							{
								TimeSpan timeSpan = now - value.Item2.Item1;
								int item = value.Item1 + timeSpan.Minutes * tokensPerMinute;
								updatedTokens[platformId] = (item, (now, value.Item2.Item2));
							}
							yield return null;
						}
					}
					foreach (KeyValuePair<ulong, (int, (DateTime, DateTime))> item2 in updatedTokens)
					{
						Core.DataStructures.PlayerTokens[item2.Key] = item2.Value;
					}
					Core.DataStructures.SavePlayerTokens();
				}
				finally
				{
					userEntities.Dispose();
				}
				ServerChatUtils.SendSystemMessageToAllClients(Core.EntityManager, "<color=red>Sanguis</color> have been updated, don't forget to redeem them! (.sanguis r)");
				yield return waitForSeconds;
			}
		}
	}
}
namespace Sanguis.Patches
{
	[HarmonyPatch]
	internal static class InitializationPatch
	{
		[HarmonyPatch(typeof(SceneSystem), "ShutdownStreamingSupport")]
		[HarmonyPostfix]
		private static void ShutdownStreamingSupportPostfix()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				Core.Initialize();
				if (Core.hasInitialized)
				{
					ManualLogSource log = Core.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("|");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Sanguis");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] initialized|");
					}
					log.LogInfo(val);
					Plugin.Harmony.Unpatch((MethodBase)typeof(SceneSystem).GetMethod("ShutdownStreamingSupport"), typeof(InitializationPatch).GetMethod("ShutdownStreamingSupportPostfix"));
				}
			}
			catch
			{
				ManualLogSource log2 = Core.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(48, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Sanguis");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] failed to initialize, exiting on try-catch...");
				}
				log2.LogError(val2);
			}
		}
	}
	[HarmonyPatch]
	public class ServerBootstrapPatches
	{
		private static readonly PrefabGUID dailyReward = new PrefabGUID(Plugin.DailyReward);

		private static readonly int dailyQuantity = Plugin.DailyQuantity;

		private static readonly bool dailyLogin = Plugin.DailyLogin;

		private static readonly int tokensPerMinute = Plugin.TokensPerMinute;

		private static readonly bool tokenSystem = Plugin.TokenSystem;

		[HarmonyPatch(typeof(ServerBootstrapSystem), "OnUserConnected")]
		[HarmonyPostfix]
		private static void OnUserConnectedPostix(ServerBootstrapSystem __instance, NetConnectionId netConnectionId)
		{
			//IL_0019: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: 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_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			int num = __instance._NetEndPointToApprovedUserIndex[netConnectionId];
			Entity userEntity = ((Il2CppArrayBase<ServerClient>)(object)__instance._ApprovedUsersLookup)[num].UserEntity;
			EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager;
			User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(userEntity);
			ulong platformId = componentData.PlatformId;
			if (!tokenSystem)
			{
				return;
			}
			ServerGameManager serverGameManager;
			if (!Core.DataStructures.PlayerTokens.TryGetValue(platformId, out (int, (DateTime, DateTime)) value))
			{
				DateTime now = DateTime.Now;
				value = (0, (now, now));
				Core.DataStructures.PlayerTokens.Add(platformId, value);
				Core.DataStructures.SavePlayerTokens();
				if (!dailyLogin)
				{
					return;
				}
				entityManager = Core.EntityManager;
				if (((EntityManager)(ref entityManager)).Exists(componentData.LocalCharacter._Entity))
				{
					serverGameManager = Core.ServerGameManager;
					if (AddItemResponse.op_Implicit(((ServerGameManager)(ref serverGameManager)).TryAddInventoryItem(componentData.LocalCharacter._Entity, dailyReward, dailyQuantity)))
					{
						string text = $"You've received <color=#00FFFF>{SanguisService.dailyReward}</color>x<color=white>{dailyQuantity}</color> for logging in today!";
						ServerChatUtils.SendSystemMessageToClient(((ComponentSystemBase)__instance).EntityManager, componentData, text);
					}
					else
					{
						InventoryUtilitiesServer.CreateDropItem(Core.EntityManager, componentData.LocalCharacter._Entity, dailyReward, dailyQuantity, default(Entity));
						string text2 = $"You've received <color=#00FFFF>{SanguisService.dailyReward}</color>x<color=white>{dailyQuantity}</color> for logging in today! It dropped on the ground because your inventory was full.";
						ServerChatUtils.SendSystemMessageToClient(((ComponentSystemBase)__instance).EntityManager, componentData, text2);
					}
				}
				return;
			}
			if (dailyLogin && DateTime.Now.Subtract(value.Item2.Item2).Days >= 1)
			{
				serverGameManager = Core.ServerGameManager;
				if (AddItemResponse.op_Implicit(((ServerGameManager)(ref serverGameManager)).TryAddInventoryItem(componentData.LocalCharacter._Entity, dailyReward, dailyQuantity)))
				{
					string text3 = $"You've received <color=#00FFFF>{SanguisService.dailyReward}</color>x<color=white>{dailyQuantity}</color> for logging in today!";
					ServerChatUtils.SendSystemMessageToClient(((ComponentSystemBase)__instance).EntityManager, componentData, text3);
				}
				else
				{
					InventoryUtilitiesServer.CreateDropItem(Core.EntityManager, componentData.LocalCharacter._Entity, dailyReward, dailyQuantity, default(Entity));
					string text4 = $"You've received <color=#00FFFF>{SanguisService.dailyReward}</color>x<color=white>{dailyQuantity}</color> for logging in today!";
					ServerChatUtils.SendSystemMessageToClient(((ComponentSystemBase)__instance).EntityManager, componentData, text4);
				}
				value = (value.Item1, (value.Item2.Item1, DateTime.Now));
				Core.DataStructures.PlayerTokens[platformId] = value;
				Core.DataStructures.SavePlayerTokens();
			}
			value = (value.Item1, (DateTime.Now, value.Item2.Item2));
			Core.DataStructures.PlayerTokens[platformId] = value;
			Core.DataStructures.SavePlayerTokens();
		}

		[HarmonyPatch(typeof(ServerBootstrapSystem), "OnUserDisconnected")]
		[HarmonyPrefix]
		private static void OnUserDisconnectedPreix(ServerBootstrapSystem __instance, NetConnectionId netConnectionId)
		{
			//IL_0019: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			int num = __instance._NetEndPointToApprovedUserIndex[netConnectionId];
			Entity userEntity = ((Il2CppArrayBase<ServerClient>)(object)__instance._ApprovedUsersLookup)[num].UserEntity;
			EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager;
			ulong platformId = ((EntityManager)(ref entityManager)).GetComponentData<User>(userEntity).PlatformId;
			if (tokenSystem && Core.DataStructures.PlayerTokens.TryGetValue(platformId, out (int, (DateTime, DateTime)) value))
			{
				TimeSpan timeSpan = DateTime.Now - value.Item2.Item1;
				value = (value.Item1 + timeSpan.Minutes * tokensPerMinute, (DateTime.Now, value.Item2.Item2));
				Core.DataStructures.PlayerTokens[platformId] = value;
				Core.DataStructures.SavePlayerTokens();
			}
		}
	}
}
namespace Sanguis.Commands
{
	[CommandGroup("sanguis", null)]
	public static class SanguisCommands
	{
		private static readonly PrefabGUID tokenReward = new PrefabGUID(Plugin.TokenReward);

		private static readonly int tokenRewardRatio = Plugin.TokenRewardRatio;

		private static readonly int tokensPerMinute = Plugin.TokensPerMinute;

		private static readonly PrefabGUID dailyReward = new PrefabGUID(Plugin.DailyReward);

		private static readonly int dailyQuantity = Plugin.DailyQuantity;

		[Command("redeem", "r", ".sanguis r", "Redeems Sanguis.", null, false)]
		public static void RedeemSanguisCommand(ChatCommandContext ctx)
		{
			//IL_0019: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.TokenSystem)
			{
				ctx.Reply("<color=red>Sanguis</color> are currently disabled.");
				return;
			}
			ulong platformId = ctx.Event.User.PlatformId;
			if (!Core.DataStructures.PlayerTokens.TryGetValue(platformId, out (int, (DateTime, DateTime)) value))
			{
				return;
			}
			if (value.Item1 < tokenRewardRatio)
			{
				ctx.Reply($"You don't have enough <color=red>Sanguis</color> to redeem. (<color=#FFC0CB>{tokenRewardRatio}</color> minimum)");
				return;
			}
			int num = value.Item1 / tokenRewardRatio;
			int num2 = num * tokenRewardRatio;
			ServerGameManager serverGameManager = Core.ServerGameManager;
			if (AddItemResponse.op_Implicit(((ServerGameManager)(ref serverGameManager)).TryAddInventoryItem(ctx.Event.SenderCharacterEntity, tokenReward, num)))
			{
				value = (value.Item1 - num2, value.Item2);
				Core.DataStructures.PlayerTokens[platformId] = value;
				Core.DataStructures.SavePlayerTokens();
				ctx.Reply($"You've received <color=#00FFFF>{SanguisService.tokenReward}</color>x<color=white>{num}</color> for redeeming <color=#FFC0CB>{num2}</color> <color=red>Sanguis</color>!");
			}
			else
			{
				value = (value.Item1 - num2, value.Item2);
				Core.DataStructures.PlayerTokens[platformId] = value;
				Core.DataStructures.SavePlayerTokens();
				InventoryUtilitiesServer.CreateDropItem(Core.EntityManager, ctx.Event.SenderCharacterEntity, tokenReward, num, default(Entity));
				ctx.Reply($"You've received <color=#00FFFF>{SanguisService.tokenReward}</color>x<color=white>{num}</color> for redeeming <color=#FFC0CB>{num2}</color> <color=red>Sanguis</color>! It dropped on the ground because your inventory was full.");
			}
		}

		[Command("get", "g", ".sanguis g", "Shows earned Sanguis, also updates them.", null, false)]
		public static void GetSanguisCommand(ChatCommandContext ctx)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.TokenSystem)
			{
				ctx.Reply("<color=red>Sanguis</color> are currently disabled.");
				return;
			}
			ulong platformId = ctx.Event.User.PlatformId;
			if (Core.DataStructures.PlayerTokens.TryGetValue(platformId, out (int, (DateTime, DateTime)) value))
			{
				TimeSpan timeSpan = DateTime.Now - value.Item2.Item1;
				value = (value.Item1 + timeSpan.Minutes * tokensPerMinute, (DateTime.Now, value.Item2.Item2));
				Core.DataStructures.PlayerTokens[platformId] = value;
				Core.DataStructures.SavePlayerTokens();
				ctx.Reply($"You have <color=#FFC0CB>{value.Item1}</color> <color=red>Sanguis</color>.");
			}
		}

		[Command("daily", "d", ".sanguis d", "Time left until eligible for daily login. Awards daily if eligible.", null, false)]
		public static void GetDailyCommand(ChatCommandContext ctx)
		{
			//IL_0019: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DailyLogin)
			{
				ctx.Reply("<color=#CBC3E3>Daily</color> reward is currently disabled.");
				return;
			}
			ulong platformId = ctx.Event.User.PlatformId;
			if (!Core.DataStructures.PlayerTokens.TryGetValue(platformId, out (int, (DateTime, DateTime)) value))
			{
				return;
			}
			DateTime item = value.Item2.Item2;
			DateTime dateTime = item.AddDays(1.0);
			DateTime now = DateTime.Now;
			if (now >= dateTime)
			{
				ServerGameManager serverGameManager = Core.ServerGameManager;
				if (AddItemResponse.op_Implicit(((ServerGameManager)(ref serverGameManager)).TryAddInventoryItem(ctx.Event.SenderCharacterEntity, dailyReward, dailyQuantity)))
				{
					string text = $"You've received <color=#00FFFF>{SanguisService.dailyReward}</color>x<color=white>{dailyQuantity}</color> for logging in today!";
					ctx.Reply(text);
				}
				else
				{
					InventoryUtilitiesServer.CreateDropItem(Core.EntityManager, ctx.Event.SenderCharacterEntity, dailyReward, dailyQuantity, default(Entity));
					string text2 = $"You've received <color=#00FFFF>{SanguisService.dailyReward}</color>x<color=white>{dailyQuantity}</color> for logging in today! It dropped on the ground because your inventory was full.";
					ctx.Reply(text2);
				}
				value = (value.Item1, (value.Item2.Item1, DateTime.Now));
				Core.DataStructures.PlayerTokens[platformId] = value;
				Core.DataStructures.SavePlayerTokens();
			}
			else
			{
				TimeSpan timeSpan = dateTime - now;
				string text3 = $"{timeSpan.Hours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}";
				ctx.Reply("Time until daily reward: <color=yellow>" + text3 + "</color>.");
			}
		}
	}
}