Decompiled source of ShopAPI v1.0.0

ShopAPI.dll

Decompiled 15 hours ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using ContentWarningShop;
using ContentWarningShop.Localisation;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("0Harmony")]
[assembly: IgnoresAccessChecksTo("Ashley.MeshSplitter")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")]
[assembly: IgnoresAccessChecksTo("Discord")]
[assembly: IgnoresAccessChecksTo("HBAO.Demo.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("HBAO.Runtime")]
[assembly: IgnoresAccessChecksTo("HBAO.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("LocalizationAssembly")]
[assembly: IgnoresAccessChecksTo("MeshSplit")]
[assembly: IgnoresAccessChecksTo("ModalAssembly")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Mdb")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Pdb")]
[assembly: IgnoresAccessChecksTo("Mono.Cecil.Rocks")]
[assembly: IgnoresAccessChecksTo("Mono.Security")]
[assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")]
[assembly: IgnoresAccessChecksTo("MonoMod.Utils")]
[assembly: IgnoresAccessChecksTo("mscorlib")]
[assembly: IgnoresAccessChecksTo("netstandard")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("pworld")]
[assembly: IgnoresAccessChecksTo("sc.posteffects.runtime")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("SteamManagerAssembly")]
[assembly: IgnoresAccessChecksTo("System.ComponentModel.Composition")]
[assembly: IgnoresAccessChecksTo("System.Configuration")]
[assembly: IgnoresAccessChecksTo("System.Core")]
[assembly: IgnoresAccessChecksTo("System.Data.DataSetExtensions")]
[assembly: IgnoresAccessChecksTo("System.Data")]
[assembly: IgnoresAccessChecksTo("System")]
[assembly: IgnoresAccessChecksTo("System.Drawing")]
[assembly: IgnoresAccessChecksTo("System.EnterpriseServices")]
[assembly: IgnoresAccessChecksTo("System.IO.Compression")]
[assembly: IgnoresAccessChecksTo("System.IO.Compression.FileSystem")]
[assembly: IgnoresAccessChecksTo("System.Net.Http")]
[assembly: IgnoresAccessChecksTo("System.Numerics")]
[assembly: IgnoresAccessChecksTo("System.Runtime")]
[assembly: IgnoresAccessChecksTo("System.Runtime.Serialization")]
[assembly: IgnoresAccessChecksTo("System.Security")]
[assembly: IgnoresAccessChecksTo("System.ServiceModel.Internals")]
[assembly: IgnoresAccessChecksTo("System.Transactions")]
[assembly: IgnoresAccessChecksTo("System.Xml")]
[assembly: IgnoresAccessChecksTo("System.Xml.Linq")]
[assembly: IgnoresAccessChecksTo("Tayx.Graphy")]
[assembly: IgnoresAccessChecksTo("Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.003")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")]
[assembly: IgnoresAccessChecksTo("Unity.Localization")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.PlayableGraphVisualizer")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Shaders")]
[assembly: IgnoresAccessChecksTo("Unity.ResourceManager")]
[assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")]
[assembly: IgnoresAccessChecksTo("Unity.Splines")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VectorGraphics")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AccessibilityModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AndroidJNIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AnimationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClothModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterInputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterRendererModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ContentLoadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CrashReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DirectorModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DSPGraphModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GameCenterModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ProfilerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SharedInternalsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteMaskModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteShapeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.StreamingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubstanceModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubsystemsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainPhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreFontEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreTextEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextRenderingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TilemapModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TLSModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIElementsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UmbraModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsCommonModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityConnectModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityCurlModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityTestProtocolModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestTextureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestWWWModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VehiclesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VFXModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VideoModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VirtualTexturingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VRModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.WindModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XRModule")]
[assembly: IgnoresAccessChecksTo("VerboseAssembly")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.AutoLOD")]
[assembly: IgnoresAccessChecksTo("Zorro.ControllerSupport")]
[assembly: IgnoresAccessChecksTo("Zorro.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.Localization")]
[assembly: IgnoresAccessChecksTo("Zorro.PhotonUtility")]
[assembly: IgnoresAccessChecksTo("Zorro.Recorder")]
[assembly: IgnoresAccessChecksTo("Zorro.Settings.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.UI.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ShopAPI")]
[assembly: AssemblyConfiguration("Modman (Release)")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+98101c04e3d1dc7aa71b33b09af1118d57397026")]
[assembly: AssemblyProduct("ShopAPI")]
[assembly: AssemblyTitle("ShopAPI")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ShopAPI.Patches
{
	[HarmonyPatch(typeof(Item))]
	internal class LocalisationPatches
	{
		private static MethodInfo __parseTip;

		private static string ParseTip(Item __instance, string tipStr, out IMKbPromptProvider provider, out List<GlyphType> glyphTypes)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if (__parseTip == null)
			{
				MethodInfo[] methods = typeof(Item).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
				__parseTip = Array.Find(methods, (MethodInfo m) => m.Name.Contains("ParseTip"));
			}
			object[] array = new object[3] { tipStr, null, null };
			string text = (string)__parseTip.Invoke(__instance, array);
			text = StringUtility.EnsureSpaceAfterPhrase(text, "{key}");
			provider = (IMKbPromptProvider)array[1];
			glyphTypes = (List<GlyphType>)array[2];
			return text;
		}

		[HarmonyPrefix]
		[HarmonyPatch("GetTootipData")]
		private static bool GetTootipData(Item __instance, ref IEnumerable<IHaveUIData> __result)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			if (!Shop.IsItemRegistered(__instance))
			{
				return true;
			}
			if (__instance.Tooltips.Count == 0)
			{
				return true;
			}
			string key = ((Object)__instance).name.Trim().Replace(" ", "") + "_ToolTips";
			IEnumerable<string> enumerable = __instance.Tooltips.Select((ItemKeyTooltip ikt) => ikt.m_text);
			List<ItemKeyTooltip> list = new List<ItemKeyTooltip>();
			if (ShopLocalisation.TryGetLocaleString(key, out string res))
			{
				enumerable = res.Split(";");
			}
			foreach (string item in enumerable)
			{
				IMKbPromptProvider provider;
				List<GlyphType> glyphTypes;
				string text = ParseTip(__instance, item, out provider, out glyphTypes);
				list.Add(new ItemKeyTooltip(text, provider, glyphTypes));
			}
			__result = (IEnumerable<IHaveUIData>)list;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("GetLocalizedDisplayName")]
		private static bool GetLocalizedDisplayName(Item __instance, ref string __result)
		{
			if (!Shop.IsItemRegistered(__instance))
			{
				return true;
			}
			string key = ((Object)__instance).name.Trim().Replace(" ", "");
			if (ShopLocalisation.TryGetLocaleString(key, out string res) && !string.IsNullOrEmpty(res))
			{
				__result = res;
				return false;
			}
			__result = __instance.displayName;
			return false;
		}
	}
}
namespace ContentWarningShop
{
	internal class PriceSynchroniser
	{
		private static Callback<LobbyCreated_t> cb_onLobbyCreated;

		private static Callback<LobbyEnter_t> cb_onLobbyEntered;

		private static bool IsHost => SteamMatchmaking.GetLobbyOwner(LobbyID) == SteamUser.GetSteamID();

		private static CSteamID LobbyID { get; set; }

		internal static void RegisterCallbacks()
		{
			cb_onLobbyCreated = Callback<LobbyCreated_t>.Create((DispatchDelegate<LobbyCreated_t>)OnLobbyCreated);
			cb_onLobbyEntered = Callback<LobbyEnter_t>.Create((DispatchDelegate<LobbyEnter_t>)OnLobbyEntered);
		}

		private static void OnLobbyCreated(LobbyCreated_t e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0017: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((int)e.m_eResult != 1)
			{
				return;
			}
			LobbyID = new CSteamID(e.m_ulSteamIDLobby);
			foreach (Item item in Shop._items)
			{
				string text = $"__{item.PersistentID}_price";
				SteamMatchmaking.SetLobbyData(LobbyID, text, $"{item.price}");
				Debug.Log((object)$"Item price registered: {((Object)item).name} ({text}) = {item.price}");
			}
		}

		private static void OnLobbyEntered(LobbyEnter_t e)
		{
			//IL_0010: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost)
			{
				return;
			}
			LobbyID = new CSteamID(e.m_ulSteamIDLobby);
			foreach (Item item in Shop._items)
			{
				string text = $"__{item.PersistentID}_price";
				string lobbyData = SteamMatchmaking.GetLobbyData(LobbyID, text);
				item.price = int.Parse(lobbyData);
				Debug.Log((object)$"Item price synchronised: {((Object)item).name} ({text}) = {item.price}");
			}
		}
	}
	public static class Shop
	{
		internal static byte _vanillaEntryCount;

		internal static List<Type> _customEntries;

		internal static List<Item> _items;

		public static ReadOnlyCollection<Item> CustomItems => _items.AsReadOnly();

		public static byte MaxUsedEntryID => (byte)(255 - (byte)_customEntries.Count);

		static Shop()
		{
			_vanillaEntryCount = 0;
			_customEntries = new List<Type>();
			_items = new List<Item>();
			GetVanillaItemDataEntryCount();
			PriceSynchroniser.RegisterCallbacks();
		}

		public static bool IsItemRegistered(Item item)
		{
			return _items.Contains(item);
		}

		public static void RegisterItem(Item item)
		{
			if (IsItemRegistered(item))
			{
				Debug.LogWarning((object)("Item " + item.displayName + " (" + item.persistentID + ") already registered."));
			}
			_items.Add(item);
			((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).AddRuntimeEntry(item);
			Debug.LogWarning((object)("Registered custom item: [" + Assembly.GetCallingAssembly().GetSimpleName() + "] " + item.displayName + " (" + item.persistentID + ")."));
		}

		public static void RegisterCustomDataEntries()
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			Type[] itemDataEntries = GetItemDataEntries(callingAssembly);
			Type[] array = itemDataEntries;
			foreach (Type type in array)
			{
				if (!_customEntries.Contains(type))
				{
					_customEntries.Add(type);
					Debug.Log((object)$"Added custom entry type: {type.Name} [{callingAssembly.GetSimpleName()}] - idx: {255 - (_customEntries.Count - 1)}");
				}
			}
		}

		internal static Type[] GetItemDataEntries(Assembly assembly)
		{
			List<Type> list = new List<Type>();
			Type[] array = Array.Empty<Type>();
			try
			{
				array = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				Debug.LogError((object)ex.Message);
				return Array.Empty<Type>();
			}
			Type typeFromHandle = typeof(ItemDataEntry);
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				if (type.IsSubclassOf(typeFromHandle) && !list.Contains(type))
				{
					list.Add(type);
				}
			}
			return list.ToArray();
		}

		internal static byte GetVanillaItemDataEntryCount()
		{
			if (_vanillaEntryCount == 0)
			{
				Type[] itemDataEntries = GetItemDataEntries(typeof(ItemDataEntry).Assembly);
				_vanillaEntryCount = (byte)itemDataEntries.Length;
				Debug.Log((object)$"Vanilla data entries found: {_vanillaEntryCount} -> max vanilla ID: {_vanillaEntryCount}");
			}
			return _vanillaEntryCount;
		}
	}
	[ContentWarningPlugin("xerren.cwshopapi", "1.0.0", false)]
	[BepInPlugin("xerren.cwshopapi", "ShopAPI", "1.0.0")]
	public class ShopApiPlugin : BaseUnityPlugin
	{
		public const string MOD_GUID = "xerren.cwshopapi";

		public const string MOD_NAME = "ShopAPI";

		public const string MOD_VER = "1.0.0";

		private Harmony harmony = new Harmony("xerren.cwshopapi");

		private void Awake()
		{
			harmony.PatchAll();
			Debug.Log((object)"xerren.cwshopapi initialised via BepInEx mod loader.");
		}
	}
	public class SynchronisedMetadata<T> where T : IConvertible, IComparable
	{
		private static Callback<LobbyChatUpdate_t> cb_onLobbyStatusUpdate;

		private static Callback<LobbyCreated_t> cb_onLobbyCreated;

		private static Callback<LobbyEnter_t> cb_onLobbyEntered;

		private static Callback<LobbyDataUpdate_t> cb_onLobbyDataUpdate;

		private static CSteamID _currentLobby;

		private T _value = default(T);

		public static bool InLobby => _currentLobby != default(CSteamID);

		public static bool IsHost => InLobby && SteamMatchmaking.GetLobbyOwner(_currentLobby) == SteamUser.GetSteamID();

		public string Key { get; protected set; } = string.Empty;


		public T Value => _value;

		public bool IsSynced
		{
			get
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if (!IsConnected)
				{
					return false;
				}
				return _currentLobby == default(CSteamID);
			}
		}

		public bool IsConnected { get; protected set; } = true;


		private static event Action? _onLobbyJoined;

		private static event Action? _onLobbyDataUpdate;

		public event Action<T>? ValueChanged;

		static SynchronisedMetadata()
		{
			cb_onLobbyStatusUpdate = Callback<LobbyChatUpdate_t>.Create((DispatchDelegate<LobbyChatUpdate_t>)Steam_LobbyLeft);
			cb_onLobbyCreated = Callback<LobbyCreated_t>.Create((DispatchDelegate<LobbyCreated_t>)Steam_LobbyCreated);
			cb_onLobbyEntered = Callback<LobbyEnter_t>.Create((DispatchDelegate<LobbyEnter_t>)Steam_LobbyEntered);
			cb_onLobbyDataUpdate = Callback<LobbyDataUpdate_t>.Create((DispatchDelegate<LobbyDataUpdate_t>)Steam_LobbyDataUpdated);
		}

		private static void Steam_LobbyCreated(LobbyCreated_t e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000f: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)e.m_eResult == 1)
			{
				_currentLobby = new CSteamID(e.m_ulSteamIDLobby);
				SynchronisedMetadata<T>._onLobbyJoined?.Invoke();
			}
		}

		private static void Steam_LobbyEntered(LobbyEnter_t e)
		{
			//IL_0001: 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_000e: 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)
			//IL_001f: 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 (_currentLobby == default(CSteamID))
			{
				_currentLobby = new CSteamID(e.m_ulSteamIDLobby);
				SynchronisedMetadata<T>._onLobbyJoined?.Invoke();
			}
		}

		private static void Steam_LobbyLeft(LobbyChatUpdate_t e)
		{
			//IL_0003: 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_000f: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			CSteamID val = default(CSteamID);
			((CSteamID)(ref val))..ctor(e.m_ulSteamIDUserChanged);
			if (!(val != SteamUser.GetSteamID()) && e.m_rgfChatMemberStateChange != 1)
			{
				_currentLobby = default(CSteamID);
			}
		}

		private static void Steam_LobbyDataUpdated(LobbyDataUpdate_t e)
		{
			//IL_0008: 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)
			if (InLobby && e.m_ulSteamIDLobby == e.m_ulSteamIDMember)
			{
				SynchronisedMetadata<T>._onLobbyDataUpdate?.Invoke();
			}
		}

		public SynchronisedMetadata(string key, T initialValue)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(key))
			{
				throw new ArgumentNullException("key");
			}
			if (key.Length > 255)
			{
				throw new ArgumentException(string.Format("Key length must not exceed {0} ({1}); was {2}", "k_nMaxLobbyKeyLength", byte.MaxValue, key.Length), "key");
			}
			_onLobbyDataUpdate += OnLobbyUpdate;
			_onLobbyJoined += OnLobbyJoin;
			Key = key;
			_value = initialValue;
			if (InLobby)
			{
				string lobbyData = SteamMatchmaking.GetLobbyData(_currentLobby, Key);
				if (string.IsNullOrEmpty(lobbyData))
				{
					SetValue(_value);
				}
				else
				{
					FetchValue();
				}
			}
			Debug.Log((object)("SynchronisedMetadata instance bound to lobby key: " + Key));
		}

		public bool CanSet()
		{
			return IsConnected && (!InLobby || IsHost);
		}

		public bool SetValue(T value)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!IsConnected)
			{
				return false;
			}
			if (!InLobby)
			{
				_value = value;
				this.ValueChanged?.Invoke(_value);
				return true;
			}
			bool flag = CanSet();
			if (flag)
			{
				SteamMatchmaking.SetLobbyData(_currentLobby, Key, ValToString(value));
			}
			return flag;
		}

		public void Disconnect()
		{
			IsConnected = false;
			_onLobbyDataUpdate -= OnLobbyUpdate;
			_onLobbyJoined -= OnLobbyJoin;
		}

		private void OnLobbyJoin()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost)
			{
				if (SteamMatchmaking.SetLobbyData(_currentLobby, Key, ValToString(_value)))
				{
					Debug.Log((object)$"Set join lobby metadata {Key} to {_value} as host.");
				}
			}
			else
			{
				FetchValue();
			}
		}

		private void OnLobbyUpdate()
		{
			FetchValue();
		}

		protected void FetchValue()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!InLobby)
			{
				return;
			}
			string lobbyData = SteamMatchmaking.GetLobbyData(_currentLobby, Key);
			if (!string.IsNullOrEmpty(lobbyData))
			{
				T val = StringToVal<T>(lobbyData);
				if (val != null && !val.Equals(_value))
				{
					Debug.Log((object)$"Synced from lobby metadata {Key}: {_value} -> {val}");
					_value = val;
					this.ValueChanged?.Invoke(_value);
				}
			}
		}

		private static string ValToString(object value)
		{
			return (string)Convert.ChangeType(value, typeof(string), CultureInfo.InvariantCulture);
		}

		private static TRes StringToVal<TRes>(string value)
		{
			return (TRes)Convert.ChangeType(value, typeof(TRes), CultureInfo.InvariantCulture);
		}
	}
}
namespace ContentWarningShop.Localisation
{
	public static class LocaleKeys
	{
		public const string English = "en";

		public const string Swedish = "sv";

		public const string French = "fr";

		public const string German = "de";

		public const string Italian = "it";

		public const string Portuguese = "pt-br";

		public const string Spanish = "es";

		public const string Ukrainian = "uk";

		public const string ChineseSimplified = "zh-hans";

		public const string ChineseTraditional = "zh-hant";

		public const string Japanese = "ja";

		public const string Korean = "ko";

		public const string Russian = "ru";
	}
	public static class ShopLocalisation
	{
		private static readonly Dictionary<Locale, Dictionary<string, string>> _localeStrings;

		public const string TooltipsSuffix = "_ToolTips";

		public const string UseGlyph = "{key_use}";

		public const string Use2Glyph = "{key_use2}";

		public const string SelfieGlyph = "{key_selfie}";

		public const string ZoomGlyph = "{key_zoom}";

		static ShopLocalisation()
		{
			_localeStrings = new Dictionary<Locale, Dictionary<string, string>>();
			foreach (Locale locale in LocalizationSettings.AvailableLocales.Locales)
			{
				if (!_localeStrings.ContainsKey(locale))
				{
					_localeStrings.Add(locale, new Dictionary<string, string>());
				}
			}
			Debug.Log((object)$"ShopLocalisation loaded {_localeStrings.Count} locales.");
		}

		public static Locale GetCurrentLocale()
		{
			return LocalizationSettings.SelectedLocale;
		}

		public static bool TryGetLocale(string locId, out Locale locale)
		{
			Locale val = null;
			foreach (Locale key in _localeStrings.Keys)
			{
				if (key.LocaleName.ToLower().Contains(locId))
				{
					val = key;
					break;
				}
			}
			locale = val;
			return (Object)(object)val != (Object)null;
		}

		public static void AddLocaleString(this Locale loc, string key, string str)
		{
			if (_localeStrings.ContainsKey(loc))
			{
				if (!_localeStrings[loc].ContainsKey(key))
				{
					_localeStrings[loc].Add(key, str);
				}
				else
				{
					_localeStrings[loc][key] = str;
				}
			}
		}

		public static bool TryGetLocaleString(string key, out string res)
		{
			Locale currentLocale = GetCurrentLocale();
			string value;
			bool result = _localeStrings[currentLocale].TryGetValue(key, out value);
			res = value;
			return result;
		}
	}
}
namespace ContentWarningShop.Patches
{
	[HarmonyPatch(typeof(ItemInstanceData))]
	internal class ItemInstanceDataPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("GetEntryIdentifier")]
		private static bool GetEntryIdentifier(ref byte __result, Type type)
		{
			if (!Shop._customEntries.Contains(type))
			{
				return true;
			}
			int num = Shop._customEntries.IndexOf(type);
			num = 255 - num;
			if (num < Shop._vanillaEntryCount)
			{
				throw new IndexOutOfRangeException(type.FullName + "'s entry ID overlaps with known vanilla entry ID.");
			}
			__result = (byte)num;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("GetEntryType")]
		private static bool GetEntryType(ref ItemDataEntry __result, byte identifier)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			if (Shop._customEntries.Count == 0)
			{
				return true;
			}
			if (identifier <= Shop._vanillaEntryCount)
			{
				return true;
			}
			int num = 255 - identifier;
			if (num < 0 || num > Shop._customEntries.Count - 1)
			{
				return true;
			}
			Type type = Shop._customEntries.ElementAtOrDefault(num);
			if (type == null)
			{
				Debug.LogWarning((object)$"Entry identifier {num} should be valid but resolved to null in ShopAPI database.");
				return true;
			}
			__result = (ItemDataEntry)type.GetConstructor(Array.Empty<Type>()).Invoke(null);
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}