Decompiled source of CrimsonStyle v0.1.5

CrimsonStyle.dll

Decompiled 4 hours 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 System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CrimsonStyle.Struct;
using CrimsonStyle.Structs;
using CrimsonStyle.Utilities;
using HarmonyLib;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Network;
using ProjectM.Scripting;
using ProjectM.Shared;
using Stunlock.Core;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;
using VAMP;
using VAMP.Models;
using VAMP.Services;
using VAMP.Utilities;
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("CrimsonStyle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Item based Cosmetic system")]
[assembly: AssemblyFileVersion("0.1.5.0")]
[assembly: AssemblyInformationalVersion("0.1.5+1.Branch.master.Sha.03e3240485a34bf86471afb98105b877b49afd29.03e3240485a34bf86471afb98105b877b49afd29")]
[assembly: AssemblyProduct("CrimsonStyle")]
[assembly: AssemblyTitle("CrimsonStyle")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CrimsonStyle
{
	[BepInPlugin("CrimsonStyle", "CrimsonStyle", "0.1.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		private Harmony _harmony;

		public static bool DisableAll;

		private List<Coroutine> _coroutines = new List<Coroutine>();

		internal static Plugin Instance { get; private set; }

		public static Harmony Harmony => Instance._harmony;

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

		public static Settings Settings { get; private set; }

		public static Database Database { get; internal set; }

		public static string ConfigFiles => Path.Combine(Paths.ConfigPath, "CrimsonStyle");

		public override void Load()
		{
			Settings = default(Settings);
			Instance = this;
			if (Settings.InitConfig())
			{
				_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
				CommandRegistry.RegisterAll();
				Events.OnCoreLoaded = (Action)Delegate.Combine(Events.OnCoreLoaded, new Action(Loaded));
			}
		}

		public override bool Unload()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			return true;
		}

		public void Loaded()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Database = new Database();
			_coroutines.Add(Core.StartCoroutine(CheckRemoval()));
			if (Settings.AutoToggle.Value)
			{
				_coroutines.Add(Core.StartCoroutine(AutoToggle()));
			}
			ManualLogSource logInstance = LogInstance;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("CrimsonStyle");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.5");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			logInstance.LogInfo(val);
		}

		public void StopLoops()
		{
			foreach (Coroutine coroutine in _coroutines)
			{
				Core.StopCoroutine(coroutine);
			}
		}

		private static IEnumerator AutoToggle()
		{
			while (!DisableAll)
			{
				yield return (object)new WaitForSeconds((float)Settings.UpdateRate.Value + 8.45f);
				foreach (Entity item in PlayerService.GetCachedUsersOnline())
				{
					User user = EntityUtil.Read<User>(item);
					if (Database.TrackedStyles.Exists((LastUsed x) => x.Character == ((FixedString64Bytes)(ref user.CharacterName)).Value) || Database.OptedOut.Contains(((FixedString64Bytes)(ref user.CharacterName)).Value))
					{
						continue;
					}
					foreach (Style style in Database.Styles)
					{
						if (InventoryUtility.CheckForItem(Core.EntityManager, user.LocalCharacter._Entity, style.Item))
						{
							Database.TrackedStyles.Add(new LastUsed(((FixedString64Bytes)(ref user.CharacterName)).Value, style.Name, isActive: true));
							BuffUtilities.ApplyCosmetic(user.LocalCharacter._Entity, new PrefabGUID(style.Buff));
							Database.SaveTracked();
							ChatUtil.SystemSendUser(user, "Auto Enabled " + style.Name + " Style. Toggle using \".style toggle\" command.");
							break;
						}
					}
				}
			}
		}

		private static IEnumerator CheckRemoval()
		{
			Entity val4 = default(Entity);
			while (!DisableAll)
			{
				yield return (object)new WaitForSeconds((float)Settings.UpdateRate.Value);
				foreach (LastUsed lastUsed in Database.TrackedStyles)
				{
					Style style = Database.Styles.FirstOrDefault((Style x) => x.Name == lastUsed.Style);
					if (!lastUsed.IsActive || style.Item == 0)
					{
						continue;
					}
					Entity val = PlayerService.GetCachedUsersOnline().FirstOrDefault((Func<Entity, bool>)delegate(Entity x)
					{
						//IL_0000: Unknown result type (might be due to invalid IL or missing references)
						//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)
						User val5 = EntityUtil.Read<User>(x);
						return ((FixedString64Bytes)(ref val5.CharacterName)).Value == lastUsed.Character;
					});
					if (((Entity)(ref val)).Equals(Entity.Null))
					{
						continue;
					}
					User val2 = EntityUtil.Read<User>(val);
					if (!InventoryUtility.CheckForItem(Core.EntityManager, val2.LocalCharacter._Entity, style.Item))
					{
						ServerGameManager serverGameManager = Core.ServerGameManager;
						Entity entity = val2.LocalCharacter._Entity;
						PrefabGUID val3 = new PrefabGUID(style.Buff);
						if (((ServerGameManager)(ref serverGameManager)).TryGetBuff(entity, ((PrefabGUID)(ref val3)).ToIdentifier(), ref val4))
						{
							DestroyUtility.Destroy(Core.EntityManager, val4, (DestroyDebugReason)13, (string)null, 0);
							lastUsed.destroyed = true;
						}
					}
				}
				Database.TrackedStyles = Database.TrackedStyles.Where((LastUsed x) => !x.destroyed).ToList();
				Database.SaveTracked();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "CrimsonStyle";

		public const string PLUGIN_NAME = "CrimsonStyle";

		public const string PLUGIN_VERSION = "0.1.5";
	}
}
namespace CrimsonStyle.Utilities
{
	internal static class BuffUtilities
	{
		public static void ApplyCosmetic(Entity entity, PrefabGUID visual)
		{
			//IL_0002: 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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0025: 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_002c: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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)
			ApplyBuffDebugEvent val = new ApplyBuffDebugEvent
			{
				BuffPrefabGUID = visual
			};
			FromCharacter val2 = new FromCharacter
			{
				Character = entity,
				User = entity
			};
			Core.SystemService.DebugEventsSystem.ApplyBuff(val2, val);
			ServerGameManager serverGameManager = Core.ServerGameManager;
			Entity val3 = default(Entity);
			if (((ServerGameManager)(ref serverGameManager)).TryGetBuff(entity, ((PrefabGUID)(ref val.BuffPrefabGUID)).ToIdentifier(), ref val3))
			{
				DevUtil.Dump(val3, "Buff_" + Extensions.LookupName(val.BuffPrefabGUID) + ".txt");
				HandleBuffComponent(val3);
				HandleLifetime(val3);
				if (!EntityUtil.Has<Buff_Persists_Through_Death>(val3))
				{
					EntityUtil.Add<Buff_Persists_Through_Death>(val3);
				}
				RemoveComponent<CreateGameplayEventsOnSpawn>(val3);
				RemoveComponent<CreateGameplayEventOnDeath>(val3);
				RemoveComponent<CreateGameplayEventsOnDestroy>(val3);
				RemoveComponent<HideWeapon>(val3);
				RemoveComponent<GameplayEventListeners>(val3);
				RemoveComponent<RemoveBuffOnGameplayEvent>(val3);
				RemoveComponent<RemoveBuffOnGameplayEventEntry>(val3);
				RemoveComponent<DealDamageOnGameplayEvent>(val3);
				RemoveComponent<HealOnGameplayEvent>(val3);
				RemoveComponent<BloodBuffScript_ChanceToResetCooldown>(val3);
				RemoveComponent<ModifyMovementSpeedBuff>(val3);
				RemoveComponent<ApplyBuffOnGameplayEvent>(val3);
				RemoveComponent<DestroyOnGameplayEvent>(val3);
				RemoveComponent<WeakenBuff>(val3);
				RemoveComponent<ReplaceAbilityOnSlotBuff>(val3);
				RemoveComponent<AmplifyBuff>(val3);
				RemoveComponent<GameplayEventIdMapping>(val3);
				RemoveComponent<AbsorbBuff>(val3);
				RemoveComponent<BuffModificationFlagData>(val3);
				EntityUtil.Add<Aggroable>(val3);
			}
		}

		private static void RemoveComponent<T>(Entity buff) where T : struct
		{
			//IL_0000: 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)
			if (EntityUtil.Has<T>(buff))
			{
				EntityUtil.Remove<T>(buff);
			}
		}

		private static void HandleBuffComponent(Entity buff)
		{
			//IL_0000: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			if (EntityUtil.Has<Buff>(buff))
			{
				BuffCategory val = EntityUtil.Read<BuffCategory>(buff);
				val.Groups = (BuffCategoryFlag)0;
				EntityUtil.Write<BuffCategory>(buff, val);
			}
		}

		private static void HandleLifetime(Entity buff)
		{
			//IL_0000: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			if (EntityUtil.Has<LifeTime>(buff))
			{
				LifeTime val = EntityUtil.Read<LifeTime>(buff);
				val.Duration = -1f;
				val.EndAction = (LifeTimeEndAction)0;
				EntityUtil.Write<LifeTime>(buff, val);
			}
		}
	}
	internal static class EntityUtilities
	{
		public static IEnumerable<Entity> GetEntitiesEnumerable(EntityQuery entityQuery)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			NativeArray<Entity> entities2;
			JobHandle entities = GetEntities(entityQuery, out entities2, (Allocator)3);
			((JobHandle)(ref entities)).Complete();
			try
			{
				Enumerator<Entity> enumerator = entities2.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Entity current = enumerator.Current;
					EntityManager entityManager = Core.EntityManager;
					if (((EntityManager)(ref entityManager)).Exists(current))
					{
						yield return current;
					}
				}
			}
			finally
			{
				entities2.Dispose();
			}
		}

		private static JobHandle GetEntities(EntityQuery entityQuery, out NativeArray<Entity> entities, Allocator allocator = (Allocator)3)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			entities = ((EntityQuery)(ref entityQuery)).ToEntityArray(AllocatorHandle.op_Implicit(allocator));
			return default(JobHandle);
		}
	}
	public static class InventoryUtility
	{
		public static bool CheckForItem(EntityManager entityManager, Entity playerEntity, int targetItem)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			return InventoryUtilities.HasItemInInventory<EntityManager>(entityManager, playerEntity, new PrefabGUID(targetItem), 1, default(Nullable_Unboxed<int>));
		}
	}
}
namespace CrimsonStyle.Structs
{
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public readonly struct Settings
	{
		public static ConfigEntry<bool> ToggleMod { get; private set; }

		public static ConfigEntry<bool> AutoToggle { get; private set; }

		public static ConfigEntry<int> UpdateRate { get; private set; }

		public static ConfigEntry<string> ListFormat { get; private set; }

		public static ConfigEntry<bool> LabelFreeStyles { get; private set; }

		public static bool InitConfig()
		{
			ToggleMod = InitConfigEntry("_Config", "ToggleMod", defaultValue: true, "Enable or disable the mod.");
			AutoToggle = InitConfigEntry("_Config", "AutoToggle", defaultValue: false, "When true, players will automatically toggle their first aura when attained.");
			UpdateRate = InitConfigEntry("_Config", "UpdateRate", 30, "The rate, in seconds, at which validation is made for active styles & auto toggle detection when enabled. This can be expensive to check at quick rates, adjust accordingly as needed. Note; picking up multiple style items between updates will AutoToggle according to order in json.");
			ListFormat = InitConfigEntry("_Config", "ListFormat", "<color=#9cb730>{styleName}</color> (<color=#309CB7>{itemName}</color>)", "This allows you to customize how .list shows buffs. Valid keywords are {styleName} and {itemName}. As well any Rich Text can be used.");
			LabelFreeStyles = InitConfigEntry("_Config", "LabelFreeStyles", defaultValue: true, "When enabled, Styles with an Item value of 0 will display \"Basic\" as their Item name; you can override this as normal.");
			if (UpdateRate.Value < 3)
			{
				UpdateRate.Value = 3;
			}
			return ToggleMod.Value;
		}

		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)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, description);
			string text = Path.Combine(Paths.ConfigPath, "CrimsonStyle.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;
		}
	}
}
namespace CrimsonStyle.Struct
{
	public class Database
	{
		private static readonly JsonSerializerOptions prettyJsonOptions = new JsonSerializerOptions
		{
			WriteIndented = true,
			IncludeFields = true
		};

		public static string StylesFile = Path.Combine(Plugin.ConfigFiles, "styles.json");

		public static string TrackFileOld = Path.Combine(Plugin.ConfigFiles, "DoNotTouch.json");

		public static string TrackFile = Path.Combine(FilePaths.WipeData, "cstyle_tracked.json");

		public static string OptFileOld = Path.Combine(Plugin.ConfigFiles, "Opt.json");

		public static string OptFile = Path.Combine(FilePaths.WipeData, "cstyle_opted.json");

		public static List<Style> Styles { get; set; }

		public static List<LastUsed> TrackedStyles { get; set; }

		public static List<string> OptedOut { get; set; }

		public Database()
		{
			CreateDatabaseFiles();
			LoadDatabase();
		}

		public static void SaveTracked()
		{
			string contents = JsonSerializer.Serialize(TrackedStyles);
			File.WriteAllText(TrackFile, contents);
		}

		private static void SaveOpted()
		{
			string contents = JsonSerializer.Serialize(OptedOut);
			File.WriteAllText(OptFile, contents);
		}

		public bool LoadDatabase()
		{
			try
			{
				LoadStyles();
				LoadTracked();
				if (Settings.AutoToggle.Value)
				{
					LoadOpted();
				}
				return true;
			}
			catch (Exception ex)
			{
				Plugin.LogInstance.LogError((object)ex);
				return false;
			}
		}

		private static void LoadStyles()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				Styles = JsonSerializer.Deserialize<List<Style>>(File.ReadAllText(StylesFile), prettyJsonOptions);
				ManualLogSource logInstance = Plugin.LogInstance;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded Styles Database: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Styles.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" entries");
				}
				logInstance.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource logInstance2 = Plugin.LogInstance;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(23, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load styles: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				logInstance2.LogError(val2);
				Styles = new List<Style>();
			}
		}

		private static void LoadTracked()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			try
			{
				TrackedStyles = JsonSerializer.Deserialize<List<LastUsed>>(File.ReadAllText(TrackFile));
			}
			catch (Exception ex)
			{
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to load tracked styles: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logInstance.LogError(val);
				TrackedStyles = new List<LastUsed>();
			}
		}

		private static void LoadOpted()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			try
			{
				OptedOut = JsonSerializer.Deserialize<List<string>>(File.ReadAllText(OptFile));
			}
			catch (Exception ex)
			{
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to load opted out list: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logInstance.LogError(val);
				OptedOut = new List<string>();
			}
		}

		public static void CreateDatabaseFiles()
		{
			if (!Directory.Exists(Plugin.ConfigFiles))
			{
				Directory.CreateDirectory(Plugin.ConfigFiles);
			}
			if (!File.Exists(StylesFile))
			{
				string contents = JsonSerializer.Serialize(new List<Style>
				{
					new Style("Chaos Burn", -1665010680, -21943750),
					new Style("Frozen", -1095284737, -1260254082),
					new Style("Green Flame", -1572696947, 0)
				}, prettyJsonOptions);
				File.WriteAllText(StylesFile, contents);
			}
			if (File.Exists(TrackFileOld))
			{
				File.Move(TrackFileOld, TrackFile);
			}
			if (File.Exists(OptFileOld))
			{
				File.Move(OptFileOld, OptFile);
			}
			if (!File.Exists(TrackFile))
			{
				string contents2 = JsonSerializer.Serialize(new List<LastUsed>());
				File.WriteAllText(TrackFile, contents2);
			}
			if (!File.Exists(OptFile) && Settings.AutoToggle.Value)
			{
				string contents3 = JsonSerializer.Serialize(new List<string>());
				File.WriteAllText(OptFile, contents3);
			}
		}

		public static bool AddToOptOut(string characterName, out string message)
		{
			if (!Settings.AutoToggle.Value)
			{
				message = "Auto enable is not allowed on this server.";
				return false;
			}
			if (OptedOut.Contains(characterName))
			{
				OptedOut.Remove(characterName);
				message = "Auto Enable on Pickup has been activated.";
				SaveOpted();
				return false;
			}
			OptedOut.Add(characterName);
			message = "Auto Enable on Pickup has been disabled.";
			SaveOpted();
			return true;
		}

		public static bool IsOptedIn(string characterName)
		{
			return !OptedOut.Contains(characterName);
		}
	}
	public class LastUsed
	{
		[JsonIgnore]
		public bool destroyed;

		public string Character { get; set; }

		public string Style { get; set; }

		public bool IsActive { get; set; }

		public LastUsed(string character, string style, bool isActive)
		{
			Character = character;
			Style = style;
			IsActive = isActive;
		}
	}
	public class Style
	{
		public string Name { get; set; }

		public int Buff { get; set; }

		public int Item { get; set; }

		public string OverrideItemName { get; set; } = string.Empty;

		public Style(string name, int buff, int item)
		{
			Name = name;
			Buff = buff;
			Item = item;
		}
	}
}
namespace CrimsonStyle.Commands
{
	[CommandGroup("style", null)]
	internal static class StyleCommands
	{
		[Command("List", "l", null, null, null, false)]
		public static void ListStyles(ChatCommandContext ctx)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.DisableAll)
			{
				return;
			}
			PrefabCollectionSystem existingSystemManaged = Core.Server.GetExistingSystemManaged<PrefabCollectionSystem>();
			string item = "\nYour Available Styles:";
			bool flag = false;
			List<string> list = new List<string> { item };
			int num = 0;
			foreach (Style style in Database.Styles)
			{
				if (style.Item != 0 && !InventoryUtility.CheckForItem(Core.EntityManager, ctx.Event.SenderCharacterEntity, style.Item))
				{
					continue;
				}
				flag = true;
				string value = Settings.ListFormat.Value;
				value = value.Replace("{styleName}", style.Name);
				if (style.Item != 0)
				{
					if (string.IsNullOrEmpty(style.OverrideItemName))
					{
						PrefabLookupMap prefabLookupMap = existingSystemManaged._PrefabLookupMap;
						string name = ((PrefabLookupMap)(ref prefabLookupMap)).GetName(new PrefabGUID(style.Item));
						if (!string.IsNullOrEmpty(name))
						{
							value = value.Replace("{itemName}", ItemUtil.CleanItemName(name));
						}
					}
					else
					{
						value = value.Replace("{itemName}", style.OverrideItemName);
					}
				}
				else if (Settings.LabelFreeStyles.Value)
				{
					string newValue = "Basic";
					if (!string.IsNullOrEmpty(style.OverrideItemName))
					{
						newValue = style.OverrideItemName;
					}
					value = value.Replace("{itemName}", newValue);
				}
				else
				{
					value = string.Join(" ", value.Split(" ").SkipLast(1));
				}
				string text = "\n" + value;
				if (list[num].Length + text.Length > 460)
				{
					num++;
					list.Add(text);
				}
				else
				{
					list[num] += text;
				}
			}
			if (!flag)
			{
				ctx.Reply("You have no styles available.");
				return;
			}
			foreach (string item2 in list)
			{
				ctx.Reply(item2);
			}
		}

		[Command("Switch", "s", null, null, null, false)]
		public unsafe static void Switch(ChatCommandContext ctx, string name)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.DisableAll)
			{
				return;
			}
			User user = ctx.Event.User;
			string playerName = ((object)(*(FixedString64Bytes*)(&user.CharacterName))/*cast due to .constrained prefix*/).ToString();
			Entity character = ctx.Event.SenderCharacterEntity;
			List<Style> list = Database.Styles.Where((Style style3) => style3.Item == 0 || InventoryUtility.CheckForItem(Core.EntityManager, character, style3.Item)).ToList();
			if (list.Count == 0)
			{
				ctx.Reply("You have no styles available.");
				return;
			}
			Entity val3 = default(Entity);
			foreach (Style style in Database.Styles)
			{
				ServerGameManager serverGameManager = Core.ServerGameManager;
				Entity val = character;
				PrefabGUID val2 = new PrefabGUID(style.Buff);
				if (!((ServerGameManager)(ref serverGameManager)).TryGetBuff(val, ((PrefabGUID)(ref val2)).ToIdentifier(), ref val3) || !EntityUtil.Has<Aggroable>(val3))
				{
					continue;
				}
				DestroyUtility.Destroy(Core.EntityManager, val3, (DestroyDebugReason)13, (string)null, 0);
				ctx.Reply("Toggled " + style.Name + " off.");
				LastUsed lastUsed = Database.TrackedStyles.FirstOrDefault((LastUsed x) => x.Character == playerName && x.Style == style.Name);
				if (lastUsed != null)
				{
					lastUsed.IsActive = false;
					Database.SaveTracked();
					if (string.IsNullOrEmpty(name))
					{
						return;
					}
				}
			}
			Style style2;
			if (string.IsNullOrEmpty(name))
			{
				LastUsed lastUsed2 = Database.TrackedStyles.FirstOrDefault((LastUsed x) => x.Character == playerName && !x.IsActive);
				if (lastUsed2 != null && list.Any((Style x) => x.Name == lastUsed2.Style))
				{
					style2 = list.First((Style x) => x.Name == lastUsed2.Style);
					lastUsed2.IsActive = true;
				}
				else
				{
					style2 = list[0];
				}
			}
			else
			{
				style2 = list.FirstOrDefault((Style s) => s.Name.ToLower().Replace(" ", "") == name.ToLower().Replace(" ", ""));
				if (style2 == null)
				{
					ctx.Reply("No style found. Use the list command to see available styles.");
					return;
				}
			}
			BuffUtilities.ApplyCosmetic(character, new PrefabGUID(style2.Buff));
			ctx.Reply("Style switched to " + style2.Name + ".");
			LastUsed lastUsed3 = Database.TrackedStyles.FirstOrDefault((LastUsed x) => x.Character == playerName);
			if (lastUsed3 != null)
			{
				lastUsed3.Style = style2.Name;
				lastUsed3.IsActive = true;
			}
			else
			{
				Database.TrackedStyles.Add(new LastUsed(playerName, style2.Name, isActive: true));
			}
			Database.SaveTracked();
		}

		[Command("Toggle", "t", null, null, null, false)]
		public static void ToggleEffect(ChatCommandContext ctx)
		{
			if (!Plugin.DisableAll)
			{
				Switch(ctx, "");
			}
		}

		[Command("ToggleAutoEnable", "tae", null, null, null, false)]
		public unsafe static void Opt(ChatCommandContext ctx)
		{
			//IL_000e: 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)
			if (!Plugin.DisableAll)
			{
				User user = ctx.Event.User;
				Database.AddToOptOut(((object)(*(FixedString64Bytes*)(&user.CharacterName))/*cast due to .constrained prefix*/).ToString(), out var message);
				ctx.Reply(message);
			}
		}

		[Command("Test", null, null, null, null, true)]
		public static void TestEffect(ChatCommandContext ctx, string name)
		{
			//IL_0022: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0045: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.DisableAll)
			{
				return;
			}
			Style style = null;
			Entity val2 = default(Entity);
			foreach (Style style2 in Database.Styles)
			{
				ServerGameManager serverGameManager = Core.ServerGameManager;
				Entity senderCharacterEntity = ctx.Event.SenderCharacterEntity;
				PrefabGUID val = new PrefabGUID(style2.Buff);
				if (((ServerGameManager)(ref serverGameManager)).TryGetBuff(senderCharacterEntity, ((PrefabGUID)(ref val)).ToIdentifier(), ref val2))
				{
					DestroyUtility.Destroy(Core.EntityManager, val2, (DestroyDebugReason)13, (string)null, 0);
				}
				if (style2.Name.ToLower().Replace(" ", "") == name.ToLower().Replace(" ", ""))
				{
					style = style2;
				}
			}
			BuffUtilities.ApplyCosmetic(ctx.Event.SenderCharacterEntity, new PrefabGUID(style.Buff));
		}

		[Command("ID", null, null, null, null, true)]
		public static void TestGUID(ChatCommandContext ctx, int id)
		{
			//IL_0008: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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)
			if (!Plugin.DisableAll)
			{
				ServerGameManager serverGameManager = Core.ServerGameManager;
				Entity senderCharacterEntity = ctx.Event.SenderCharacterEntity;
				PrefabGUID val = new PrefabGUID(id);
				Entity val2 = default(Entity);
				if (((ServerGameManager)(ref serverGameManager)).TryGetBuff(senderCharacterEntity, ((PrefabGUID)(ref val)).ToIdentifier(), ref val2))
				{
					DestroyUtility.Destroy(Core.EntityManager, val2, (DestroyDebugReason)13, (string)null, 0);
				}
				BuffUtilities.ApplyCosmetic(ctx.Event.SenderCharacterEntity, new PrefabGUID(id));
			}
		}

		[Command("RemovalPrepare", null, null, null, null, true)]
		public static void RemovalPrep(ChatCommandContext ctx)
		{
			Plugin.DisableAll = true;
			Plugin.Instance.StopLoops();
			List<Style> styles = Database.Styles.ToList();
			Database.Styles.Clear();
			Database.TrackedStyles.ForEach(delegate(LastUsed s)
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				Player player = default(Player);
				Entity val2 = default(Entity);
				if (PlayerService.TryFindByName(s.Character, ref player))
				{
					foreach (Style style in styles)
					{
						ServerGameManager serverGameManager = Core.ServerGameManager;
						Entity character = player.Character;
						PrefabGUID val = new PrefabGUID(style.Buff);
						if (((ServerGameManager)(ref serverGameManager)).TryGetBuff(character, ((PrefabGUID)(ref val)).ToIdentifier(), ref val2) && EntityUtil.Has<Aggroable>(val2))
						{
							DestroyUtility.Destroy(Core.EntityManager, val2, (DestroyDebugReason)13, (string)null, 0);
							LastUsed lastUsed = Database.TrackedStyles.FirstOrDefault((LastUsed x) => x.Character == player.Name && x.Style == style.Name);
							if (lastUsed != null)
							{
								lastUsed.IsActive = false;
							}
						}
					}
				}
			});
			File.Delete(Database.TrackFile);
			File.Delete(Database.OptFile);
		}
	}
}