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>.");
}
}
}
}