Decompiled source of SynergyGungeon v1.0.3

SynergySpawnMod.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SynergyGungeon;

[BepInPlugin("Th3FlyingSharkTeam.etg.synergygungeon", "SynergyGungeon", "1.0.2")]
public class SynergyGungeon : BaseUnityPlugin
{
	private ConfigEntry<float> _chance;

	private void Awake()
	{
		_chance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SynergyChestChance", 0.75f, "Chance (0..1) to convert a reward chest into a Synergy Chest. Default 0.75 (75%).");
		TryApply("Awake");
		((MonoBehaviour)this).InvokeRepeating("TickApply", 1f, 3f);
	}

	private void OnDestroy()
	{
		((MonoBehaviour)this).CancelInvoke("TickApply");
	}

	private void TickApply()
	{
		TryApply("Timer");
	}

	private void TryApply(string reason)
	{
		try
		{
			if (IsRainbowRun())
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[" + reason + "] Rainbow mode detected → leaving chest logic untouched."));
				return;
			}
			int num = ApplySynergyChance(_chance.Value);
			if (num > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[" + reason + $"] Set synergy-chest chance to {_chance.Value:P0} on {num} member(s)."));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[" + reason + "] Could not find a synergy-chance member. Dumping numeric members of RewardManager for reference…"));
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)ex);
		}
	}

	private bool IsRainbowRun()
	{
		Assembly assembly = FindGameAssembly();
		if ((object)assembly == null)
		{
			return false;
		}
		Type type = assembly.GetType("GameStatsManager");
		if ((object)type == null)
		{
			return false;
		}
		object obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null);
		if (obj == null)
		{
			return false;
		}
		PropertyInfo propertyInfo = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((PropertyInfo p) => (object)p.PropertyType == typeof(bool) && p.Name.ToLower().Contains("rainbow"));
		if ((object)propertyInfo != null)
		{
			try
			{
				return (bool)propertyInfo.GetValue(obj, null);
			}
			catch
			{
			}
		}
		FieldInfo fieldInfo = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => (object)f.FieldType == typeof(bool) && f.Name.ToLower().Contains("rainbow"));
		if ((object)fieldInfo != null)
		{
			try
			{
				return (bool)fieldInfo.GetValue(obj);
			}
			catch
			{
			}
		}
		return false;
	}

	private int ApplySynergyChance(float value)
	{
		int num = 0;
		Assembly assembly = FindGameAssembly();
		if ((object)assembly == null)
		{
			return 0;
		}
		Type type = assembly.GetType("GameManager") ?? assembly.GetType("Gungeon.GameManager");
		if ((object)type == null)
		{
			return 0;
		}
		object obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null);
		if (obj == null)
		{
			return 0;
		}
		Type rmType = assembly.GetType("RewardManager") ?? assembly.GetType("Gungeon.RewardManager") ?? assembly.GetTypes().FirstOrDefault((Type t) => t.Name == "RewardManager");
		if ((object)rmType == null)
		{
			return 0;
		}
		object obj2 = null;
		PropertyInfo propertyInfo = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((PropertyInfo p) => (object)p.PropertyType == rmType);
		if ((object)propertyInfo != null)
		{
			try
			{
				obj2 = propertyInfo.GetValue(obj, null);
			}
			catch
			{
			}
		}
		if (obj2 == null)
		{
			FieldInfo fieldInfo = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => (object)f.FieldType == rmType);
			if ((object)fieldInfo != null)
			{
				try
				{
					obj2 = fieldInfo.GetValue(obj);
				}
				catch
				{
				}
			}
		}
		if (obj2 == null)
		{
			PropertyInfo property = rmType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
			if ((object)property != null)
			{
				try
				{
					obj2 = property.GetValue(null, null);
				}
				catch
				{
				}
			}
		}
		if (obj2 == null)
		{
			return 0;
		}
		FieldInfo[] array = (from f in rmType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
			where ((object)f.FieldType == typeof(float) || (object)f.FieldType == typeof(double)) && NameLooksLikeSynergyChance(f.Name)
			orderby f.Name.ToLower().Contains("chest") descending
			select f).ToArray();
		foreach (FieldInfo fieldInfo2 in array)
		{
			try
			{
				if (!fieldInfo2.IsInitOnly && !fieldInfo2.IsLiteral)
				{
					if ((object)fieldInfo2.FieldType == typeof(float))
					{
						fieldInfo2.SetValue(obj2, value);
					}
					else
					{
						fieldInfo2.SetValue(obj2, (double)value);
					}
					num++;
				}
			}
			catch
			{
			}
		}
		PropertyInfo[] array2 = (from p in rmType.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
			where p.CanWrite && ((object)p.PropertyType == typeof(float) || (object)p.PropertyType == typeof(double)) && NameLooksLikeSynergyChance(p.Name)
			orderby p.Name.ToLower().Contains("chest") descending
			select p).ToArray();
		foreach (PropertyInfo propertyInfo2 in array2)
		{
			try
			{
				if ((object)propertyInfo2.PropertyType == typeof(float))
				{
					propertyInfo2.SetValue(obj2, value, null);
				}
				else
				{
					propertyInfo2.SetValue(obj2, (double)value, null);
				}
				num++;
			}
			catch
			{
			}
		}
		if (num == 0)
		{
			string[] value2 = (from m in rmType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where (m is FieldInfo && ((object)((FieldInfo)m).FieldType == typeof(float) || (object)((FieldInfo)m).FieldType == typeof(double))) || (m is PropertyInfo && ((object)((PropertyInfo)m).PropertyType == typeof(float) || (object)((PropertyInfo)m).PropertyType == typeof(double)))
				select m.MemberType.ToString() + ":" + m.Name).ToArray();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[Debug] RewardManager numeric members: " + string.Join(", ", value2)));
		}
		return num;
	}

	private static bool NameLooksLikeSynergyChance(string name)
	{
		string text = name.ToLower();
		if (text.Contains("synergy") || text.Contains("syn"))
		{
			if (!text.Contains("chance") && !text.Contains("prob") && !text.Contains("percent"))
			{
				return text.Contains("pct");
			}
			return true;
		}
		return false;
	}

	private static Assembly FindGameAssembly()
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			if (assembly.GetName().Name == "Assembly-CSharp")
			{
				return assembly;
			}
		}
		return null;
	}
}