Decompiled source of CardKit v1.1.0

SlipSkid.CardKit.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.Mono;
using Game;
using HarmonyLib;
using Menus.UI;
using Obstacles;
using Obstacles.ObstacleAffixes;
using Obstacles.ObstacleGameModifiers;
using Player;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Localization;
using Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SlipSkid.CardKit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+70443946d9a466de93d71710a8884f99307e19a4")]
[assembly: AssemblyProduct("SlipSkid.CardKit")]
[assembly: AssemblyTitle("SlipSkid.CardKit")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SlipSkid.CardKit;

public enum CardRarity
{
	Common,
	Uncommon,
	Rare,
	UltraRare,
	Legendary,
	Unique,
	Off
}
public enum CardKind
{
	Modifier,
	Prop
}
public sealed class Card
{
	public string Guid;

	public string Name;

	public string Description;

	public CardKind Kind;

	public CardRarity Rarity;

	public int MaxQuantity = -1;

	public string Carrier;

	public byte[] ThumbnailPng;

	public byte[] FullArtNormalPng;

	public Action<CardContext> OnApply;

	public Action<Obstacle, CardContext> OnSpawn;

	public ObstacleDescription Asset { get; internal set; }
}
public sealed class CardContext
{
	public Card Card { get; internal set; }

	public PlayerData Owner { get; internal set; }

	public IReadOnlyList<PlayerData> Players { get; internal set; }

	public bool IsServer { get; internal set; }

	public Obstacle Obstacle { get; internal set; }
}
public static class CardKitApi
{
	private static readonly List<Card> Cards = new List<Card>();

	private static Card[] _ordered;

	private static Texture2D _flat;

	public static IReadOnlyList<Card> All => Ordered;

	internal static Card[] Ordered => _ordered ?? (_ordered = Cards.OrderBy<Card, string>((Card c) => c.Guid.ToLowerInvariant(), StringComparer.Ordinal).ToArray());

	public static void Register(Card card)
	{
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Expected O, but got Unknown
		if (card == null)
		{
			throw new ArgumentNullException("card");
		}
		if (!Guid.TryParse(card.Guid, out var _))
		{
			throw new ArgumentException("Card '" + card.Name + "' needs a valid Guid.");
		}
		if (string.IsNullOrEmpty(card.Name))
		{
			throw new ArgumentException("Card needs a Name.");
		}
		if (card.Kind == CardKind.Modifier && card.OnApply == null && card.OnSpawn == null)
		{
			throw new ArgumentException("Modifier card '" + card.Name + "' needs OnApply.");
		}
		if (Cards.Any((Card c) => string.Equals(c.Guid, card.Guid, StringComparison.OrdinalIgnoreCase)))
		{
			throw new ArgumentException("Card Guid " + card.Guid + " is registered twice.");
		}
		if (_ordered != null)
		{
			ManualLogSource log = CardKitPlugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(77, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Card '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(card.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' registered after the deck was built; it joins on the next level load.");
			}
			log.LogWarning(val);
		}
		Cards.Add(card);
		_ordered = null;
	}

	public static byte[] EmbeddedPng(string fileName)
	{
		Assembly callingAssembly = Assembly.GetCallingAssembly();
		string text = callingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(fileName, StringComparison.OrdinalIgnoreCase));
		if (text == null)
		{
			return null;
		}
		using Stream stream = callingAssembly.GetManifestResourceStream(text);
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		return memoryStream.ToArray();
	}

	public static PlayerData FindPlayer(int playerIndex)
	{
		List<PlayerData> players = GameManager.Players;
		if (players == null)
		{
			return null;
		}
		foreach (PlayerData item in players)
		{
			if ((Object)(object)item != (Object)null && item.playerIndex.Value == playerIndex)
			{
				return item;
			}
		}
		return null;
	}

	internal static int SlotOf(ObstacleDescription d)
	{
		if ((Object)(object)d == (Object)null)
		{
			return -1;
		}
		Card[] ordered = Ordered;
		for (int i = 0; i < ordered.Length; i++)
		{
			if ((Object)(object)ordered[i].Asset == (Object)(object)d)
			{
				return i;
			}
		}
		return -1;
	}

	internal static Card At(int slot)
	{
		if (slot < 0 || slot >= Ordered.Length)
		{
			return null;
		}
		return Ordered[slot];
	}

	internal static void BuildDeck(ObstacleManager manager)
	{
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Expected O, but got Unknown
		ObstacleDescription[] allowedObstacleDescriptions = manager.allowedObstacleDescriptions;
		if (allowedObstacleDescriptions == null)
		{
			return;
		}
		CardKitPlugin.LogCatalogOnce(allowedObstacleDescriptions);
		List<ObstacleDescription> list = allowedObstacleDescriptions.ToList();
		int num = 0;
		Card[] ordered = Ordered;
		foreach (Card card in ordered)
		{
			if ((Object)(object)card.Asset == (Object)null)
			{
				card.Asset = CreateDescription(card, allowedObstacleDescriptions);
			}
			if (!((Object)(object)card.Asset == (Object)null) && !list.Contains(card.Asset))
			{
				list.Add(card.Asset);
				num++;
			}
		}
		if (num != 0)
		{
			manager.allowedObstacleDescriptions = list.ToArray();
			ManualLogSource log = CardKitPlugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Deck: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" CardKit card(s) added, ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" cards in total.");
			}
			log.LogInfo(val);
		}
	}

	private static ObstacleDescription CreateDescription(Card card, ObstacleDescription[] catalog)
	{
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Expected O, but got Unknown
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Expected O, but got Unknown
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		ObstacleDescription val = FindCarrier(card, catalog);
		bool flag = default(bool);
		if ((Object)(object)val == (Object)null)
		{
			ManualLogSource log = CardKitPlugin.Log;
			BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(37, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("No carrier for '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(card.Name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<CardKind>(card.Kind);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("); card not added.");
			}
			log.LogError(val2);
			return null;
		}
		ObstacleDescription val3 = Object.Instantiate<ObstacleDescription>(val);
		((Object)val3).name = "CardKit_" + new string(card.Name.Where(char.IsLetterOrDigit).ToArray());
		((Object)val3).hideFlags = (HideFlags)32;
		val3.id = new SerializableGuid(new Guid(card.Guid));
		if (card.Rarity == CardRarity.Off)
		{
			val3.maxQuantity = 0;
		}
		else
		{
			val3.rarity = (ObstacleRarity)card.Rarity;
			val3.maxQuantity = card.MaxQuantity;
		}
		CardText.Register(val3.displayName, card.Name);
		CardText.Register(val3.description, card.Description ?? "");
		if (card.ThumbnailPng != null)
		{
			Texture2D val4 = LoadPng(card.ThumbnailPng);
			if ((Object)(object)val4 != (Object)null)
			{
				val3.thumbnail = val4;
				if ((Object)(object)val.overrideBackGroundMaterialTexture != (Object)null)
				{
					Sprite val5 = Sprite.Create(val4, new Rect(0f, 0f, (float)((Texture)val4).width, (float)((Texture)val4).height), new Vector2(0.5f, 0.5f), 100f);
					((Object)val5).hideFlags = (HideFlags)32;
					val3.overrideBackGroundMaterialTexture = val5;
					val3.overrideBackGroundMaterialNormalMap = (Texture)(object)(((card.FullArtNormalPng != null) ? LoadPng(card.FullArtNormalPng) : null) ?? FlatMask());
				}
			}
		}
		if (card.Kind == CardKind.Modifier)
		{
			ModifierHook.Ensure(((object)val.prefab).GetType());
		}
		ManualLogSource log2 = CardKitPlugin.Log;
		BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(27, 4, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Card '");
			((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(card.Name);
			((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("' (");
			((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<CardKind>(card.Kind);
			((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", ");
			((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<CardRarity>(card.Rarity);
			((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(") carried by '");
			((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(((Object)val).name);
			((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("'.");
		}
		log2.LogInfo(val6);
		return val3;
	}

	private static Texture2D LoadPng(byte[] png)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
		if (!ImageConversion.LoadImage(val, png))
		{
			return null;
		}
		((Object)val).hideFlags = (HideFlags)32;
		return val;
	}

	private static Texture2D FlatMask()
	{
		//IL_0017: 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_0029: Expected O, but got Unknown
		//IL_0042: 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)
		if ((Object)(object)_flat != (Object)null)
		{
			return _flat;
		}
		_flat = new Texture2D(4, 4, (TextureFormat)4, false)
		{
			hideFlags = (HideFlags)32
		};
		Color32[] array = (Color32[])(object)new Color32[16];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = new Color32((byte)40, (byte)40, (byte)40, byte.MaxValue);
		}
		_flat.SetPixels32(array);
		_flat.Apply();
		return _flat;
	}

	private static ObstacleDescription FindCarrier(Card card, ObstacleDescription[] catalog)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		if (!string.IsNullOrEmpty(card.Carrier))
		{
			ObstacleDescription val = ((IEnumerable<ObstacleDescription>)catalog).FirstOrDefault((Func<ObstacleDescription, bool>)((ObstacleDescription d) => (Object)(object)d != (Object)null && (Object)(object)d.prefab != (Object)null && (((Object)d.prefab).name == card.Carrier || ((Object)d).name == card.Carrier)));
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			ManualLogSource log = CardKitPlugin.Log;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(41, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Carrier '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(card.Carrier);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' for '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(card.Name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' not found; picking one.");
			}
			log.LogWarning(val2);
		}
		if (card.Kind != CardKind.Modifier)
		{
			return ((IEnumerable<ObstacleDescription>)catalog).FirstOrDefault((Func<ObstacleDescription, bool>)IsPropCarrier);
		}
		return ((IEnumerable<ObstacleDescription>)catalog).FirstOrDefault((Func<ObstacleDescription, bool>)((ObstacleDescription d) => (Object)(object)d != (Object)null && (Object)(object)d.prefab != (Object)null && (int)d.type == 4 && d.prefab is ObstacleGameModifier));
	}

	private static bool IsPropCarrier(ObstacleDescription d)
	{
		//IL_0018: 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 ((Object)(object)d == (Object)null || (Object)(object)d.prefab == (Object)null || (int)d.type != 0 || (int)d.bodyBodyType != 0)
		{
			return false;
		}
		if (((object)d.prefab).GetType() != typeof(Obstacle))
		{
			return false;
		}
		GameObject gameObject = ((Component)d.prefab).gameObject;
		if (gameObject.GetComponentsInChildren<NetworkAnimatedTransformation>(true).Length != 0)
		{
			return false;
		}
		if (gameObject.GetComponentsInChildren<ScorePointZone>(true).Length != 0 || gameObject.GetComponentsInChildren<SpeedCamera>(true).Length != 0)
		{
			return false;
		}
		return gameObject.GetComponentsInChildren<Collider>(true).Any((Collider c) => !c.isTrigger);
	}
}
[BepInPlugin("slipskid.cardkit", "Slip & Skid - CardKit", "1.1.0")]
public sealed class CardKitPlugin : BaseUnityPlugin
{
	public const string Guid = "slipskid.cardkit";

	public const string Version = "1.1.0";

	internal static ManualLogSource Log;

	internal static Harmony Harmony;

	private static bool _catalogLogged;

	private void Awake()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Harmony = new Harmony("slipskid.cardkit");
		Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(CardKitPlugin).Assembly);
		bool flag = default(bool);
		foreach (Type type in typesFromAssembly)
		{
			try
			{
				Harmony.CreateClassProcessor(type).Patch();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(15, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patch ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogError(val);
			}
		}
		Log.LogInfo((object)"CardKit ready.");
	}

	internal static void LogCatalogOnce(ObstacleDescription[] catalog)
	{
		if (!_catalogLogged)
		{
			_catalogLogged = true;
			Log.LogInfo((object)("Catalog (asset / prefab / type / body / rarity): " + string.Join("; ", from d in catalog
				where (Object)(object)d != (Object)null
				select string.Format("{0}/{1}/{2}/{3}/{4}", ((Object)d).name, ((Object)(object)d.prefab != (Object)null) ? ((Object)d.prefab).name : "-", d.type, d.bodyBodyType, d.rarity))));
		}
	}
}
[HarmonyPatch(typeof(ObstacleManager), "Awake")]
internal static class DeckPatch
{
	private static void Postfix(ObstacleManager __instance)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		if ((Object)(object)ObstacleManager.instance != (Object)(object)__instance)
		{
			return;
		}
		try
		{
			CardKitApi.BuildDeck(__instance);
		}
		catch (Exception ex)
		{
			ManualLogSource log = CardKitPlugin.Log;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Building the deck failed: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
			}
			log.LogError(val);
		}
	}
}
[HarmonyPatch(typeof(ObstacleDescription), "Spawn", new Type[]
{
	typeof(PlayerData),
	typeof(Vector3),
	typeof(Quaternion),
	typeof(Vector3),
	typeof(bool),
	typeof(int)
})]
internal static class SpawnMarkPatch
{
	private static void Prefix(ObstacleDescription __instance, ref int affixIndex)
	{
		int num = CardKitApi.SlotOf(__instance);
		if (num >= 0)
		{
			affixIndex = CardMarker.Encode(num, affixIndex);
		}
	}
}
[HarmonyPatch(typeof(Obstacle), "OnNetworkSpawn")]
internal static class SpawnBuildPatch
{
	private static void Postfix(Obstacle __instance)
	{
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).GetComponent<CardKitTag>() != (Object)null || !CardMarker.TryDecode(__instance.affixIndex.Value, out var slot, out var _))
		{
			return;
		}
		Card card = CardKitApi.At(slot);
		bool flag = default(bool);
		if (card == null)
		{
			ManualLogSource log = CardKitPlugin.Log;
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(75, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unknown CardKit card #");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(slot);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Does everyone have the same card mods and versions?");
			}
			log.LogWarning(val);
			return;
		}
		((Component)__instance).gameObject.AddComponent<CardKitTag>().Slot = slot;
		if (card.OnSpawn == null)
		{
			return;
		}
		try
		{
			card.OnSpawn(__instance, CardRuntime.Context(card, __instance));
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = CardKitPlugin.Log;
			BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Card '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(card.Name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' OnSpawn failed: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
			}
			log2.LogError(val2);
		}
	}
}
[HarmonyPatch(typeof(Obstacle), "ApplyAffix")]
internal static class AffixPatch
{
	private static bool Prefix(Obstacle __instance)
	{
		if (!CardMarker.TryDecode(__instance.affixIndex.Value, out var _, out var affixIndex))
		{
			return true;
		}
		if (affixIndex > 0)
		{
			ObstacleAffixDescription affixByIndex = ObstacleAffixManager.GetAffixByIndex(affixIndex);
			if ((Object)(object)affixByIndex != (Object)null && affixByIndex.IsValid && (Object)(object)affixByIndex.callbacks != (Object)null)
			{
				affixByIndex.callbacks.Apply(__instance);
			}
		}
		return false;
	}
}
[HarmonyPatch(typeof(LocalizedString), "GetLocalizedString", new Type[] { })]
internal static class TextPatch
{
	private static bool Prefix(LocalizedString __instance, ref string __result)
	{
		if (!CardText.TryGet(__instance, out var text))
		{
			return true;
		}
		__result = text;
		return false;
	}
}
[HarmonyPatch(typeof(ObstacleSelectionElement), "Init")]
internal static class CardUiPatch
{
	private static void Postfix(ObstacleSelectionElement __instance, ObstacleDescription obstacleDescription)
	{
		Card card = CardKitApi.At(CardKitApi.SlotOf(obstacleDescription));
		if (card != null)
		{
			if ((Object)(object)__instance.nameLabel != (Object)null)
			{
				__instance.nameLabel.text = card.Name;
			}
			if ((Object)(object)__instance.descriptionLabel != (Object)null)
			{
				__instance.descriptionLabel.text = card.Description ?? "";
			}
		}
	}
}
internal static class CardMarker
{
	private const int Base = 1000;

	private const int AffixSlots = 100;

	private const int SlotOffset = 1000000;

	public static int Encode(int slot, int affixIndex)
	{
		int num = ((affixIndex >= 0 && affixIndex < 100) ? affixIndex : 0);
		return -(1000 + (1000000 + slot) * 100 + num);
	}

	public static bool TryDecode(int value, out int slot, out int affixIndex)
	{
		slot = -1;
		affixIndex = 0;
		if (value > -100001000)
		{
			return false;
		}
		int num = -value - 1000;
		slot = num / 100 - 1000000;
		affixIndex = num % 100;
		return slot >= 0;
	}
}
internal static class CardText
{
	private sealed class ByReference : IEqualityComparer<LocalizedString>
	{
		public bool Equals(LocalizedString a, LocalizedString b)
		{
			return a == b;
		}

		public int GetHashCode(LocalizedString s)
		{
			return RuntimeHelpers.GetHashCode(s);
		}
	}

	private static readonly Dictionary<LocalizedString, string> Texts = new Dictionary<LocalizedString, string>(new ByReference());

	public static void Register(LocalizedString key, string text)
	{
		if (key != null)
		{
			Texts[key] = text;
		}
	}

	public static bool TryGet(LocalizedString key, out string text)
	{
		return Texts.TryGetValue(key, out text);
	}
}
internal sealed class CardKitTag : MonoBehaviour
{
	public int Slot = -1;
}
internal static class CardRuntime
{
	public static Card CardOf(Obstacle obstacle, out int slot)
	{
		slot = -1;
		if ((Object)(object)obstacle == (Object)null || obstacle.affixIndex == null)
		{
			return null;
		}
		CardKitTag component = ((Component)obstacle).GetComponent<CardKitTag>();
		if ((Object)(object)component != (Object)null)
		{
			slot = component.Slot;
			return CardKitApi.At(slot);
		}
		if (!CardMarker.TryDecode(obstacle.affixIndex.Value, out slot, out var _))
		{
			return null;
		}
		return CardKitApi.At(slot);
	}

	public static CardContext Context(Card card, Obstacle obstacle)
	{
		CardContext obj = new CardContext
		{
			Card = card,
			Obstacle = obstacle,
			Owner = (((Object)(object)obstacle != (Object)null && obstacle.playerInfosIndex != null) ? CardKitApi.FindPlayer(obstacle.playerInfosIndex.Value) : null)
		};
		IReadOnlyList<PlayerData> players = GameManager.Players;
		obj.Players = players ?? Array.Empty<PlayerData>();
		obj.IsServer = (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer;
		return obj;
	}
}
internal static class ModifierHook
{
	private static readonly HashSet<Type> Patched = new HashSet<Type>();

	public static void Ensure(Type modifierType)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Expected O, but got Unknown
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		if (modifierType == null || !Patched.Add(modifierType))
		{
			return;
		}
		MethodInfo methodInfo = AccessTools.Method(modifierType, "ApplyModifier", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			ManualLogSource log = CardKitPlugin.Log;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(modifierType.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has no ApplyModifier; its CardKit cards won't do anything.");
			}
			log.LogError(val);
		}
		else
		{
			CardKitPlugin.Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ModifierHook), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}

	private static bool Prefix(Obstacle __instance)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		int slot;
		Card card = CardRuntime.CardOf(__instance, out slot);
		if (card == null)
		{
			return true;
		}
		try
		{
			card.OnApply?.Invoke(CardRuntime.Context(card, __instance));
		}
		catch (Exception ex)
		{
			ManualLogSource log = CardKitPlugin.Log;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Card '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(card.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' OnApply failed: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
			}
			log.LogError(val);
		}
		return false;
	}
}