Decompiled source of Duplicate Heroes v1.0.0

BepInEx/plugins/com.binbin.DuplicateHeroes.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DuplicateHeroes;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Obeliskial_Essentials;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.binbin.DuplicateHeroes")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8d9a0efbf0ff612261f84c9f2ddf8dc48da0ba5d")]
[assembly: AssemblyProduct("DuplicateHeroes")]
[assembly: AssemblyTitle("com.binbin.DuplicateHeroes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class EssentialsCompatibility
{
	private static bool? _enabled;

	public static bool Enabled
	{
		get
		{
			bool valueOrDefault = _enabled.GetValueOrDefault();
			if (!_enabled.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.stiffmeds.obeliskialessentials");
				_enabled = valueOrDefault;
			}
			return _enabled.Value;
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	public static void EssentialsRegister()
	{
		Essentials.RegisterMod(Plugin.PluginName, "binbin", "Duplicate Heroes", Plugin.PluginVersion, Plugin.ModDate, "https://github.com/binbinmods/DuplicateHeroes", (string[])null, "", 1, (string[])null, "", true);
		Plugin.LogInfo(Plugin.PluginGUID + " " + Plugin.PluginVersion + " has loaded with Essentials!");
	}
}
namespace DuplicateHeroes
{
	[HarmonyPatch]
	public class AntiCheat
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetObeliskScore")]
		public static bool SetObeliskScorePrefix(ref SteamManager __instance, int score, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetScore")]
		public static bool SetScorePrefix(ref SteamManager __instance, int score, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetSingularityScore")]
		public static bool SetSingularityScorePrefix(ref SteamManager __instance, int score, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetObeliskScoreLeaderboard")]
		public static bool SetObeliskScoreLeaderboardPrefix(ref SteamManager __instance, int score, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetScoreLeaderboard")]
		public static bool SetScoreLeaderboardPrefix(ref SteamManager __instance, int score, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetSingularityScoreLeaderboard")]
		public static bool SetSingularityScoreLeaderboardPrefix(ref SteamManager __instance, int score, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetWeeklyScore")]
		public static bool SetWeeklyScorePrefix(ref SteamManager __instance, int score, int week, string nick, string nickgroup, bool singleplayer = true)
		{
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamManager), "SetWeeklyScoreLeaderboard")]
		public static bool SetWeeklyScoreLeaderboardPrefix(ref SteamManager __instance, int score, int week, string nick, string nickgroup, bool singleplayer = true)
		{
			return false;
		}
	}
	public class DuplicateHeroesFunctions
	{
		public static void DuplicateCardbacks()
		{
			Plugin.LogDebug("DUPLICATECARDBACKS START");
			Dictionary<string, CardbackData> value = Traverse.Create((object)Globals.Instance).Field("_CardbackDataSource").GetValue<Dictionary<string, CardbackData>>();
			Dictionary<string, CardbackData> dictionary = new Dictionary<string, CardbackData>(value);
			foreach (KeyValuePair<string, CardbackData> item in value)
			{
				string key = item.Key;
				CardbackData value2 = item.Value;
				try
				{
					for (int i = 2; i <= Plugin.NumberOfCopies.Value + 1; i++)
					{
						CardbackData val = Object.Instantiate<CardbackData>(value2);
						val.CardbackId = key + i;
						if (!((Object)(object)value2.CardbackSubclass == (Object)null))
						{
							if (Globals.Instance.SubClass.TryGetValue(value2.CardbackSubclass.Id + i, out var value3))
							{
								val.CardbackSubclass = value3;
							}
							dictionary[val.CardbackId] = val;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.LogError("Error duplicating cardback " + key + ": " + ex.Message);
				}
			}
			Traverse.Create((object)Globals.Instance).Field("_CardbackDataSource").SetValue((object)dictionary);
			Plugin.LogDebug("DUPLICATECARDBACKS END");
		}

		public static void DuplicateSkins()
		{
			Dictionary<string, SkinData> value = Traverse.Create((object)Globals.Instance).Field("_SkinDataSource").GetValue<Dictionary<string, SkinData>>();
			Dictionary<string, SkinData> dictionary = new Dictionary<string, SkinData>(value);
			Plugin.LogDebug("DUPLICATESKINS START");
			foreach (KeyValuePair<string, SkinData> item in value)
			{
				string key = item.Key;
				SkinData value2 = item.Value;
				if ((Object)(object)value2.SkinSubclass == (Object)null)
				{
					continue;
				}
				try
				{
					for (int i = 2; i <= Plugin.NumberOfCopies.Value + 1; i++)
					{
						SkinData val = Object.Instantiate<SkinData>(value2);
						val.SkinId = key + i;
						if (Globals.Instance.SubClass.TryGetValue(value2.SkinSubclass.Id + i, out var value3))
						{
							val.SkinSubclass = value3;
						}
						dictionary[val.SkinId] = val;
					}
				}
				catch (Exception ex)
				{
					Plugin.LogError("Error duplicating skin " + key + ": " + ex.Message);
				}
			}
			Traverse.Create((object)Globals.Instance).Field("_SkinDataSource").SetValue((object)dictionary);
			Plugin.LogDebug("DUPLICATESKINS END");
		}

		public static void DuplicateSubclasses()
		{
			Plugin.LogDebug("CREATECLONES START");
			string text = "";
			Dictionary<string, SubClassData> value = Traverse.Create((object)Globals.Instance).Field("_SubClassSource").GetValue<Dictionary<string, SubClassData>>();
			Dictionary<string, SubClassData> dictionary = new Dictionary<string, SubClassData>(value);
			foreach (KeyValuePair<string, SubClassData> item in value)
			{
				string key = item.Key;
				SubClassData value2 = item.Value;
				if (!value2.MainCharacter)
				{
					continue;
				}
				try
				{
					for (int i = 2; i <= Plugin.NumberOfCopies.Value + 1; i++)
					{
						SubClassData val = Object.Instantiate<SubClassData>(value2);
						val.Id = value2.Id + i;
						val.SubClassName = value2.SubClassName + i;
						val.OrderInList = value2.OrderInList + 1000 + i;
						text = value2.Id + i;
						Globals.Instance.SubClass[text] = Object.Instantiate<SubClassData>(val);
						dictionary[text] = val;
					}
				}
				catch (Exception ex)
				{
					Plugin.LogError("Error duplicating subclass " + value2.Id + ": " + ex.Message);
				}
			}
			Globals.Instance.SubClass = dictionary;
			Traverse.Create((object)Globals.Instance).Field("_SubClassSource").SetValue((object)dictionary);
			Plugin.LogDebug("CREATECLONES END");
		}

		public static bool IsDuplicateHero(string subclassId)
		{
			return subclassId.Length > 1 && (subclassId.EndsWith("2") || subclassId.EndsWith("3") || subclassId.EndsWith("4"));
		}
	}
	[HarmonyPatch]
	public class DuplicateHeroesPatches
	{
		public static bool devMode;

		public static bool bSelectingPerk;

		public static bool IsHost()
		{
			return GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.IsMaster();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(EventManager), "SetEvent")]
		public static void SetEventPrefix(ref EventData _eventData)
		{
			Dictionary<string, EventData> value = Traverse.Create((object)Globals.Instance).Field("_Events").GetValue<Dictionary<string, EventData>>();
			if (!((Object)(object)_eventData != (Object)null) || !value.ContainsKey(_eventData.EventId))
			{
				return;
			}
			bool flag = false;
			EventReplyData[] array = value[_eventData.EventId].Replys;
			for (int i = 0; i < value[_eventData.EventId].Replys.Length; i++)
			{
				EventReplyData val = value[_eventData.EventId].Replys[i];
				if (!((Object)(object)val.RequiredClass != (Object)null) || val.RepeatForAllCharacters)
				{
					continue;
				}
				Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
				foreach (string key in dictionary.Keys)
				{
					List<string> list = dictionary[key];
					foreach (string item in list)
					{
						if (!(val.RequiredClass.Id != item))
						{
							EventReplyData val2 = val.ShallowCopy();
							val2.RequiredClass = Globals.Instance.GetSubClassData(item);
							Array.Resize(ref array, array.Length + 1);
							array[^1] = val2;
							flag = true;
						}
					}
				}
			}
			if (flag)
			{
				value[_eventData.EventId].Replys = array;
				Traverse.Create((object)Globals.Instance).Field("_Events").SetValue((object)value);
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(Globals), "CreateGameContent")]
		public static void CreateGameContentPostfix()
		{
			Plugin.LogDebug("CreateGameContentPostfix");
			DuplicateHeroesFunctions.DuplicateSubclasses();
			DuplicateHeroesFunctions.DuplicateSkins();
			DuplicateHeroesFunctions.DuplicateCardbacks();
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(EventData), "Init")]
		public static void InitPostfix(ref EventData __instance, ref EventReplyData[] ___replys)
		{
			List<EventReplyData> list = new List<EventReplyData>();
			if (___replys == null || (Object)(object)__instance == (Object)null)
			{
				Plugin.LogError("InitPostfix: ___replys or __instance is null, cannot modify event replies for " + __instance.EventName);
				return;
			}
			for (int i = 0; i < ___replys.Length; i++)
			{
				EventReplyData val = ___replys[i];
				if (val == null)
				{
					continue;
				}
				list.Add(val);
				if (!((Object)(object)val.RequiredClass != (Object)null))
				{
					continue;
				}
				EventReplyData val2 = val.ShallowCopy();
				for (int j = 2; j <= Plugin.NumberOfCopies.Value + 1; j++)
				{
					string text = val.RequiredClass.Id + j;
					if (Globals.Instance.SubClass.TryGetValue(text.ToLower(), out var _))
					{
						val2.RequiredClass = Globals.Instance.SubClass[text.ToLower()];
						SubClassData requiredClass = val2.RequiredClass;
						Plugin.LogDebug("New Class ID: " + (((requiredClass != null) ? requiredClass.Id : null) ?? "null"));
						val2.IndexForAnswerTranslation = 24678 + i;
					}
				}
			}
			___replys = list.ToArray();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerManager), "GetProgress")]
		public static bool GetProgressPrefix(ref int __result, string _subclassId)
		{
			try
			{
				if (_subclassId.EndsWith("2") || _subclassId.EndsWith("3") || _subclassId.EndsWith("4"))
				{
					__result = PlayerManager.Instance.GetProgress(Regex.Replace(_subclassId, "\\d+$", ""));
					return false;
				}
			}
			catch (Exception ex)
			{
				Plugin.LogError("Error in ModifyProgressPrefix for subclass " + _subclassId + ": " + ex.Message);
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerManager), "ModifyProgress")]
		public static bool ModifyProgressPrefix(string _subclassId, int _quantity, int _index, Dictionary<string, int> ___heroProgress)
		{
			try
			{
				if (_subclassId.EndsWith("2") || _subclassId.EndsWith("3") || _subclassId.EndsWith("4"))
				{
					PlayerManager.Instance.ModifyProgress(Regex.Replace(_subclassId, "\\d+$", ""), _quantity, _index);
					return false;
				}
			}
			catch (Exception ex)
			{
				Plugin.LogError("Error in ModifyProgressPrefix for subclass " + _subclassId + ": " + ex.Message);
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerManager), "IsHeroUnlocked")]
		public static bool IsHeroUnlockedPrefix(string subclass, ref bool __result)
		{
			try
			{
				if (subclass.EndsWith("2") || subclass.EndsWith("3") || subclass.EndsWith("4"))
				{
					__result = PlayerManager.Instance.IsHeroUnlocked(Regex.Replace(subclass, "\\d+$", ""));
					return false;
				}
			}
			catch (Exception ex)
			{
				Plugin.LogError("Error in IsHeroUnlockedPrefix for subclass " + subclass + ": " + ex.Message);
			}
			return true;
		}

		public static void CreateCharClonesPostfix(ref string ___classText)
		{
			Plugin.LogDebug("CreateCharClonesPostfix");
			Dictionary<string, SubClassData> value = Traverse.Create((object)Globals.Instance).Field("_SubClassSource").GetValue<Dictionary<string, SubClassData>>();
			Dictionary<string, SubClassData> value2 = Traverse.Create((object)Globals.Instance).Field("_SubClassSource").GetValue<Dictionary<string, SubClassData>>();
			foreach (string key in value.Keys)
			{
				if (DuplicateHeroesFunctions.IsDuplicateHero(key))
				{
					string text = Regex.Replace(key, "\\d+$", "");
					value2[key].CharacterName = Texts.Instance.GetText(text + "_name", "class");
					value2[key].CharacterDescription = Texts.Instance.GetText(text + "_description", "class");
					value2[key].CharacterDescriptionStrength = Texts.Instance.GetText(text + "_strength", "class");
				}
			}
			Traverse.Create((object)Globals.Instance).Field("_SubClassSource").SetValue((object)value);
			Traverse.Create((object)Globals.Instance).Field("_SubClass").SetValue((object)value2);
		}
	}
	[BepInPlugin("com.binbin.DuplicateHeroes", "DuplicateHeroes", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("AcrossTheObelisk.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public static string PluginName;

		public static string PluginVersion;

		public static string PluginGUID;

		internal static int ModDate = int.Parse(DateTime.Today.ToString("yyyyMMdd"));

		private readonly Harmony harmony = new Harmony("com.binbin.DuplicateHeroes");

		internal static ManualLogSource Log;

		public static string debugBase = "com.binbin.DuplicateHeroes ";

		public static ConfigEntry<bool> EnableMod { get; set; }

		public static ConfigEntry<bool> EnableDebugging { get; set; }

		public static ConfigEntry<int> NumberOfCopies { get; set; }

		private void Awake()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0039: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0066: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_009b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			string text = "DuplicateHeroes";
			EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "EnableMod"), true, new ConfigDescription("Enables the mod. If false, the mod will not work then next time you load the game.", (AcceptableValueBase)null, Array.Empty<object>()));
			EnableDebugging = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "EnableDebugging"), false, new ConfigDescription("Enables the debugging", (AcceptableValueBase)null, Array.Empty<object>()));
			AcceptableValueRange<int> val = new AcceptableValueRange<int>(0, 3);
			NumberOfCopies = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "NumberOfCopies"), 3, new ConfigDescription("The number of copies to make of each hero. Max 3 (so total of 4). Decrease this value if you run into IndexOutOfBounds errors. Requires restart or reloading of content to take effect.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			NumberOfCopies.Value = Math.Clamp(NumberOfCopies.Value, 0, 3);
			PluginName = "DuplicateHeroes";
			PluginVersion = "1.0.0";
			PluginGUID = "com.binbin.DuplicateHeroes";
			if (EnableMod.Value)
			{
				if (EssentialsCompatibility.Enabled)
				{
					EssentialsCompatibility.EssentialsRegister();
				}
				else
				{
					LogInfo(PluginGUID + " " + PluginVersion + " has loaded!");
				}
				harmony.PatchAll();
			}
		}

		internal static void LogDebug(string msg)
		{
			if (EnableDebugging.Value)
			{
				Log.LogDebug((object)(debugBase + msg));
			}
		}

		internal static void LogInfo(string msg)
		{
			Log.LogInfo((object)(debugBase + msg));
		}

		internal static void LogError(string msg)
		{
			Log.LogError((object)(debugBase + msg));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.binbin.DuplicateHeroes";

		public const string PLUGIN_NAME = "DuplicateHeroes";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}