Decompiled source of SimpleLunarCoins v1.3.0

SimpleLunarCoins.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour.HookGen;
using Newtonsoft.Json;
using On.RoR2;
using ProperSave;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ContentManagement;
using RoR2BepInExPack.GameAssetPaths.Version_1_39_0;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[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("SimpleLunarCoins")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2dcd0afd73ae585b6dc04749b4fd690612d25cc1")]
[assembly: AssemblyProduct("SimpleLunarCoins")]
[assembly: AssemblyTitle("SimpleLunarCoins")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SimpleLunarCoins
{
	public static class Assets
	{
		private static AssetBundle assetBundle;

		public static GameObject coinEmitterPrefab;

		public static Sprite icon;

		internal static string assetBundleName = "mwmwsimplelunarcoinsbundle";

		internal static string assemblyDir => Path.GetDirectoryName(SimpleLunarCoins.pluginInfo.Location);

		private static void TryBuildAsset(string assetName, Action buildAction)
		{
			try
			{
				buildAction();
			}
			catch (Exception arg)
			{
				Log.Warning($"Failed to complete building asset {assetName}!\n\n{arg}");
			}
		}

		private static void GetAssetBundle()
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("SimpleLunarCoins.mwmwsimplelunarcoinsbundle");
			if (stream != null)
			{
				assetBundle = AssetBundle.LoadFromStream(stream);
			}
		}

		public static void Init()
		{
			GetAssetBundle();
			CreateCoinEmitter();
			icon = assetBundle.LoadAsset<Sprite>("icon");
		}

		private static void CreateCoinEmitter()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			coinEmitterPrefab = assetBundle.LoadAsset<GameObject>("LunarCoinEmitter");
			TryBuildAsset("Lunar Coin Emitter", delegate
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				ParticleSystemRenderer component = ((Component)coinEmitterPrefab.transform.Find("LunarCoin")).GetComponent<ParticleSystemRenderer>();
				component.mesh = Addressables.LoadAssetAsync<Mesh>((object)RoR2_Base_Common_VFX.mdlLunarCoinWithHole_fbx).WaitForCompletion();
				((Renderer)component).sharedMaterial = Addressables.LoadAssetAsync<Material>((object)RoR2_Base_Common_VFX.matLunarCoinPlaceholder_mat).WaitForCompletion();
			});
			EffectDef item = new EffectDef(coinEmitterPrefab);
			ContentPacks.effectDefs.Add(item);
		}
	}
	internal class ContentPacks : IContentPackProvider
	{
		internal ContentPack contentPack = new ContentPack();

		public static List<EffectDef> effectDefs = new List<EffectDef>();

		public string identifier => "Miyowi.SimpleLunarCoins";

		public void Init()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(ContentManager_collectContentPackProviders);
		}

		private void ContentManager_collectContentPackProviders(AddContentPackProviderDelegate addContentPackProvider)
		{
			addContentPackProvider.Invoke((IContentPackProvider)(object)this);
		}

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			contentPack.identifier = identifier;
			contentPack.effectDefs.Add(effectDefs.ToArray());
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(contentPack, args.output);
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			args.ReportProgress(1f);
			yield break;
		}
	}
	public class Events
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__InitialCoinChance;

			public static Action<ILContext> <1>__CoinDropHook;

			public static hook_Start <2>__StartingCoins;

			public static hook_GrantPickup <3>__RegularCoinDistribute;

			public static Action<Dictionary<string, object>> <4>__SaveCoins;
		}

		public static void Init()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			object obj = <>O.<0>__InitialCoinChance;
			if (obj == null)
			{
				hook_Awake val = InitialCoinChance;
				<>O.<0>__InitialCoinChance = val;
				obj = (object)val;
			}
			PlayerCharacterMasterController.Awake += (hook_Awake)obj;
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			MethodInfo methodInfo = typeof(PlayerCharacterMasterController).GetNestedTypes(bindingAttr)[0].GetMethods(bindingAttr).FirstOrDefault((MethodInfo method) => method.Name.Contains("<Init>b__"));
			if (methodInfo != null)
			{
				HookEndpointManager.Modify((MethodBase)methodInfo, (Delegate)new Action<ILContext>(CoinDropHook));
			}
			else
			{
				Log.Error("Failed to find method for CoinDropHook! Mod is mostly broken!");
			}
			object obj2 = <>O.<2>__StartingCoins;
			if (obj2 == null)
			{
				hook_Start val2 = StartingCoins;
				<>O.<2>__StartingCoins = val2;
				obj2 = (object)val2;
			}
			Run.Start += (hook_Start)obj2;
			object obj3 = <>O.<3>__RegularCoinDistribute;
			if (obj3 == null)
			{
				hook_GrantPickup val3 = RegularCoinDistribute;
				<>O.<3>__RegularCoinDistribute = val3;
				obj3 = (object)val3;
			}
			LunarCoinDef.GrantPickup += (hook_GrantPickup)obj3;
			if (ProperSaveCompat.enabled)
			{
				ProperSaveCompat.AddEvent(SaveCoins);
			}
		}

		private static void InitialCoinChance(orig_Awake orig, PlayerCharacterMasterController self)
		{
			orig.Invoke(self);
			self.lunarCoinChanceMultiplier = Options.coinChance.Value;
		}

		private static void CoinDropHook(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(MiscPickups).FullName, "LunarCoin")
			}))
			{
				ILLabel val2 = val.DefineLabel();
				val.EmitDelegate<Func<bool>>((Func<bool>)(() => Options.noCoinDroplet.Value));
				val.Emit(OpCodes.Brtrue, (object)val2);
				val.MarkLabel(val2);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<PickupDropletController>(x, "CreatePickupDroplet")
				}))
				{
					val.MarkLabel(val2);
					val.Emit(OpCodes.Ldarg_1);
					val.EmitDelegate<Action<DamageReport>>((Action<DamageReport>)delegate(DamageReport damageReport)
					{
						//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
						//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
						//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
						//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
						//IL_0102: Expected O, but got Unknown
						if (Options.noCoinDroplet.Value)
						{
							if (Options.teamCoins.Value)
							{
								foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
								{
									if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.resolvedNetworkUserInstance))
									{
										instance.resolvedNetworkUserInstance.AwardLunarCoins(1u);
									}
								}
							}
							else if (Object.op_Implicit((Object)(object)damageReport.attackerMaster) && Object.op_Implicit((Object)(object)damageReport.attackerMaster.playerCharacterMasterController))
							{
								damageReport.attackerMaster.playerCharacterMasterController.resolvedNetworkUserInstance.AwardLunarCoins(1u);
							}
							if (Object.op_Implicit((Object)(object)damageReport.victimBody))
							{
								EffectManager.SpawnEffect(Assets.coinEmitterPrefab, new EffectData
								{
									origin = damageReport.victimBody.corePosition,
									scale = damageReport.victimBody.radius
								}, true);
							}
						}
					});
				}
				else
				{
					Log.Error("Part 2 of CoinDropHook failed! No coin droplet and distribute coins will not work!");
				}
			}
			else
			{
				Log.Error("Part 1 of CoinDropHook failed! No coin droplet and distribute coins will not work!");
			}
			float num = default(float);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<PlayerCharacterMasterController>(x, "lunarCoinChanceMultiplier")
			}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num)
			}))
			{
				val.Emit(OpCodes.Pop);
				val.EmitDelegate<Func<float>>((Func<float>)(() => Options.coinMultiplier.Value));
			}
			else
			{
				Log.Warning("Part 3 of CoinDropHook failed! Coin chance multiplier override will not work!");
			}
		}

		private static void StartingCoins(orig_Start orig, Run self)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				orig.Invoke(self);
				return;
			}
			bool flag = false;
			if (ProperSaveCompat.enabled && ProperSaveCompat.IsLoading)
			{
				flag = true;
			}
			if (!flag && Options.resetCoins.Value)
			{
				foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
				{
					readOnlyInstances.DeductLunarCoins(readOnlyInstances.lunarCoins);
					readOnlyInstances.AwardLunarCoins((uint)Options.startingCoins.Value);
				}
			}
			else if (flag)
			{
				string moddedData = ProperSaveCompat.GetModdedData("SimpleLunarCoinsObj");
				Dictionary<string, uint> dictionary = JsonConvert.DeserializeObject<Dictionary<string, uint>>(moddedData);
				foreach (NetworkUser readOnlyInstances2 in NetworkUser.readOnlyInstancesList)
				{
					NetworkPlayerName networkPlayerName = readOnlyInstances2.GetNetworkPlayerName();
					if (dictionary.ContainsKey(((NetworkPlayerName)(ref networkPlayerName)).GetResolvedName()))
					{
						readOnlyInstances2.DeductLunarCoins(readOnlyInstances2.lunarCoins);
						networkPlayerName = readOnlyInstances2.GetNetworkPlayerName();
						readOnlyInstances2.AwardLunarCoins(dictionary[((NetworkPlayerName)(ref networkPlayerName)).GetResolvedName()]);
					}
				}
			}
			orig.Invoke(self);
		}

		private static void SaveCoins(Dictionary<string, object> dict)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, uint> dictionary = new Dictionary<string, uint>();
			foreach (NetworkUser instances in NetworkUser.instancesList)
			{
				NetworkPlayerName networkPlayerName = instances.GetNetworkPlayerName();
				dictionary.Add(((NetworkPlayerName)(ref networkPlayerName)).GetResolvedName(), instances.lunarCoins);
			}
			string value = JsonConvert.SerializeObject((object)dictionary);
			dict.Add("SimpleLunarCoinsObj", value);
		}

		private static void RegularCoinDistribute(orig_GrantPickup orig, LunarCoinDef self, ref GrantContext context)
		{
			if (Options.teamCoins.Value)
			{
				NetworkUser val = Util.LookUpBodyNetworkUser(context.body);
				foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
				{
					if (Object.op_Implicit((Object)(object)Reflection.GetFieldValue<NetworkUser>((object)instance, "resolvedNetworkUserInstance")) && (Object)(object)Reflection.GetFieldValue<NetworkUser>((object)instance, "resolvedNetworkUserInstance") != (Object)(object)val)
					{
						Reflection.GetFieldValue<NetworkUser>((object)instance, "resolvedNetworkUserInstance").AwardLunarCoins(1u);
					}
				}
			}
			orig.Invoke(self, ref context);
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	public static class Options
	{
		private static bool? _rooEnabled;

		public static bool rooEnabled
		{
			get
			{
				if (!_rooEnabled.HasValue)
				{
					_rooEnabled = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
				}
				return _rooEnabled.Value;
			}
		}

		public static ConfigEntry<float> coinChance { get; set; }

		public static ConfigEntry<float> coinMultiplier { get; set; }

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

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

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

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

		public static void Init()
		{
			coinChance = SimpleLunarCoins.config.Bind<float>("Lunar Coin Adjustments", "Initial Coin Chance", 0.5f, "Chance for first lunar coin to be dropped.");
			coinMultiplier = SimpleLunarCoins.config.Bind<float>("Lunar Coin Adjustments", "Coin Chance Multiplier", 0.5f, "Value that chance is multiplied by after a coin is dropped.");
			startingCoins = SimpleLunarCoins.config.Bind<int>("Lunar Coin Adjustments", "Starting Coins", 5, "Coins that each player has at the start of a run, if 'Reset Coins Each Run' is enabled.");
			teamCoins = SimpleLunarCoins.config.Bind<bool>("Lunar Coin Adjustments", "Distribute Coins", true, "All allies receive a lunar coin when one is dropped.");
			noCoinDroplet = SimpleLunarCoins.config.Bind<bool>("Lunar Coin Adjustments", "No Coin Droplets", true, "Enemies emit a lunar coin effect instead of the regular droplet that is manually picked up.");
			resetCoins = SimpleLunarCoins.config.Bind<bool>("Lunar Coin Adjustments", "Reset Coins Each Run", false, "Lunar coins are reset at the start of a run to the value determined by 'Starting Coins'.");
			if (rooEnabled)
			{
				RoOInit();
			}
		}

		public static void RoOInit()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(coinChance, new StepSliderConfig
			{
				min = 0f,
				max = 100f,
				increment = 0.01f
			}));
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(coinMultiplier, new StepSliderConfig
			{
				min = 0f,
				max = 1f,
				increment = 0.01f
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(startingCoins, new IntSliderConfig
			{
				min = 0,
				max = 10000
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(teamCoins));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(noCoinDroplet));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(resetCoins));
			ModSettingsManager.SetModDescription("Provides simple customisation of the lunar coins behaviour, without interfering with the balance of lunar items themselves.");
			ModSettingsManager.SetModIcon(Assets.icon);
		}
	}
	public static class ProperSaveCompat
	{
		private static bool? _enabled;

		public static bool enabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					_enabled = Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.ProperSave");
				}
				return _enabled.Value;
			}
		}

		public static bool IsLoading => Loading.IsLoading;

		public static void AddEvent(Action<Dictionary<string, object>> action)
		{
			SaveFile.OnGatherSaveData += action;
		}

		public static string GetModdedData(string name)
		{
			return Loading.CurrentSave.GetModdedData<string>(name);
		}
	}
	public class SimpleLunarCoins_ProperSaveObj
	{
		public Dictionary<ulong, uint> playerCoins;

		public SimpleLunarCoins_ProperSaveObj(Dictionary<ulong, uint> playerCoins)
		{
			this.playerCoins = playerCoins;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Miyowi.SimpleLunarCoins", "SimpleLunarCoins", "1.3.0")]
	public class SimpleLunarCoins : BaseUnityPlugin
	{
		public const string PluginGUID = "Miyowi.SimpleLunarCoins";

		public const string PluginAuthor = "Miyowi";

		public const string PluginName = "SimpleLunarCoins";

		public const string PluginVersion = "1.3.0";

		public static PluginInfo pluginInfo;

		public static ConfigFile config;

		public void Awake()
		{
			pluginInfo = ((BaseUnityPlugin)this).Info;
			config = ((BaseUnityPlugin)this).Config;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Assets.Init();
			Events.Init();
			Options.Init();
			new ContentPacks().Init();
		}
	}
}