Decompiled source of GunsmithPersist v1.1.1

Mods/GunsmithPersist.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using GunsmithPersist;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "GunsmithPersist", "1.1.1", "Isaac", null)]
[assembly: MelonGame(null, null)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GunsmithPersist")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GunsmithPersist")]
[assembly: AssemblyTitle("GunsmithPersist")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 GunsmithPersist
{
	public class Mod : MelonMod
	{
		private MelonPreferences_Entry<bool> _debug;

		private Type _core;

		private MethodInfo _getPlayer;

		private MethodInfo _getHandler;

		private MethodInfo _getKey;

		private MethodInfo _getPick;

		private MethodInfo _applyScope;

		private MethodInfo _applyColor;

		private FieldInfo _store;

		private FieldInfo _wfield;

		private FieldInfo _htypeField;

		private Component _fp;

		private float _nextFp;

		private float _next;

		private int _lastPlayer = int.MinValue;

		private int _lastHandler = int.MinValue;

		private int _lastPick = int.MinValue;

		private string _lastKey = "";

		private readonly List<float> _due = new List<float>();

		private bool _ready;

		public override void OnInitializeMelon()
		{
			MelonPreferences_Category val = MelonPreferences.CreateCategory("GunsmithPersist");
			_debug = val.CreateEntry<bool>("Debug", false, "Log what happens around death/respawn", (string)null, false, false, (ValueValidator)null, (string)null);
			((MelonBase)this).LoggerInstance.Msg("GunsmithPersist ready.");
		}

		private void Bind()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name != "CubsGunsmith"))
				{
					_core = assembly.GetType("WeaponCustomization.Core");
					break;
				}
			}
			if (!(_core == null))
			{
				BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
				_getPlayer = _core.GetMethod("GetLocalPlayer", bindingAttr);
				_getHandler = _core.GetMethod("GetWeaponCosmeticsHandler", bindingAttr);
				_getKey = _core.GetMethod("GetModuleKey", bindingAttr);
				_getPick = _core.GetMethod("GetPersistentPickupable", bindingAttr);
				_applyScope = _core.GetMethod("ApplyScopeIndex", bindingAttr);
				_applyColor = _core.GetMethod("ApplyColorIndex", bindingAttr);
				_store = _core.GetField("weaponCosmetics", bindingAttr);
				_wfield = _core.GetField("weaponHandler", bindingAttr);
				_htypeField = _core.GetField("cosmeticsHandlerType", bindingAttr);
				_ready = _getPlayer != null && _getHandler != null && _getKey != null && _getPick != null && _applyScope != null && _applyColor != null && _store != null && _wfield != null && _htypeField != null;
				((MelonBase)this).LoggerInstance.Msg("Bound to Cub's Gunsmith: " + _ready);
			}
		}

		private static int Id(object o)
		{
			Object val = (Object)((o is Object) ? o : null);
			if (val == (Object)null)
			{
				return -1;
			}
			try
			{
				return val.GetInstanceID();
			}
			catch
			{
				return -1;
			}
		}

		public override void OnUpdate()
		{
			try
			{
				if (_core == null)
				{
					if (Time.frameCount % 120 == 0)
					{
						Bind();
					}
					if (_core == null)
					{
						return;
					}
				}
				if (!_ready)
				{
					return;
				}
				float unscaledTime = Time.unscaledTime;
				if (unscaledTime >= _next)
				{
					_next = unscaledTime + 0.1f;
					bool refresh = false;
					if (_getPlayer.Invoke(null, null) != null)
					{
						PinFirstPerson(refresh);
					}
					object obj = _getPlayer.Invoke(null, null);
					int num = ((obj == null) ? (-1) : Id(obj));
					int num2 = -1;
					int num3 = -1;
					string text = null;
					if (obj != null)
					{
						object obj2 = _getHandler.Invoke(null, new object[1] { obj });
						num2 = ((obj2 == null) ? (-1) : Id(obj2));
						object obj3 = _getPick.Invoke(null, new object[1] { obj });
						num3 = ((obj3 == null) ? (-1) : Id(obj3));
						text = ((num3 == _lastPick && _lastKey.Length > 0) ? _lastKey : (_getKey.Invoke(null, new object[1] { obj }) as string));
					}
					text = text ?? "";
					if (num != _lastPlayer || num2 != _lastHandler || num3 != _lastPick || text != _lastKey)
					{
						_ = _debug.Value;
						bool num4 = (num != _lastPlayer || (num2 != _lastHandler && num2 != -1)) && num != -1;
						_lastPlayer = num;
						_lastHandler = num2;
						_lastPick = num3;
						_lastKey = text;
						if (num4)
						{
							_due.Clear();
							float[] array = new float[5] { 0.15f, 0.5f, 1.2f, 2.5f, 5f };
							foreach (float num5 in array)
							{
								_due.Add(unscaledTime + num5);
							}
						}
					}
				}
				if (_due.Count > 0 && unscaledTime >= _due[0])
				{
					_due.RemoveAt(0);
					Reapply();
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("update: " + (ex.InnerException ?? ex).Message);
			}
		}

		private static bool IsFirstPerson(Transform t)
		{
			int num = 0;
			Transform val = t;
			while ((Object)(object)val != (Object)null && num++ < 14)
			{
				string name = ((Object)val).name;
				if (name.IndexOf("FirstPerson", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("1stPerson", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private void PinFirstPerson(bool refresh)
		{
			if (refresh || (Object)(object)_fp == (Object)null || !Object.op_Implicit((Object)(object)_fp) || !_fp.gameObject.activeInHierarchy)
			{
				_fp = null;
				Type type = _htypeField.GetValue(null) as Type;
				if (type != null)
				{
					foreach (Object item in (Il2CppArrayBase<Object>)(object)Object.FindObjectsOfType(Il2CppType.From(type), false))
					{
						Component val = ((Il2CppObjectBase)item).TryCast<Component>();
						if ((Object)(object)val != (Object)null && val.gameObject.activeInHierarchy && IsFirstPerson(val.transform))
						{
							_fp = val;
							break;
						}
					}
				}
			}
			if (!((Object)(object)_fp == (Object)null) && Object.op_Implicit((Object)(object)_fp))
			{
				object? value = _wfield.GetValue(null);
				Component val2 = (Component)((value is Component) ? value : null);
				if ((Object)(object)val2 == (Object)null || !Object.op_Implicit((Object)(object)val2) || ((Object)val2).GetInstanceID() != ((Object)_fp).GetInstanceID())
				{
					_wfield.SetValue(null, _fp);
				}
			}
		}

		private static string PathOf(Transform t)
		{
			string text = ((Object)t).name;
			Transform parent = t.parent;
			int num = 0;
			while ((Object)(object)parent != (Object)null && num++ < 7)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private void Reapply()
		{
			object obj = _getPlayer.Invoke(null, null);
			if (obj == null)
			{
				return;
			}
			PinFirstPerson(refresh: true);
			if (!(_getKey.Invoke(null, new object[1] { obj }) is string key))
			{
				return;
			}
			if (!(_store.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(key))
			{
				if (_debug.Value)
				{
					((MelonBase)this).LoggerInstance.Msg("reapply: nothing saved for this weapon");
				}
				return;
			}
			object obj2 = dictionary[key];
			Type type = obj2.GetType();
			bool flag = (bool)type.GetField("HasScope").GetValue(obj2);
			bool flag2 = (bool)type.GetField("HasColor").GetValue(obj2);
			int num = (int)type.GetField("ScopeIndex").GetValue(obj2);
			int num2 = (int)type.GetField("ColorIndex").GetValue(obj2);
			if (flag)
			{
				_applyScope.Invoke(null, new object[2] { obj, num });
			}
			if (flag2)
			{
				_applyColor.Invoke(null, new object[2] { obj, num2 });
			}
			if (_debug.Value)
			{
				((MelonBase)this).LoggerInstance.Msg("reapplied scope=" + (flag ? num.ToString() : "-") + " color=" + (flag2 ? num2.ToString() : "-"));
			}
		}
	}
}