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() : "-"));
}
}
}
}