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)
{
}
}
}