Decompiled source of MimesisMods v1.0.2

MimesisMods.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using HarmonyLib;
using MelonLoader;
using Microsoft.CodeAnalysis;
using MimesisMods;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "MimesisMods", "1.0.2", "Hix", null)]
[assembly: MelonGame("ReLUGames", "MIMESIS")]
[assembly: AssemblyVersion("0.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 MimesisMods
{
	public class Core : MelonMod
	{
		private static readonly HashSet<string> _warned = new HashSet<string>();

		private static bool _equipDone;

		private static bool _consumableDone;

		public override void OnInitializeMelon()
		{
			((MelonBase)this).LoggerInstance.Msg("MimesisMods v1.0.2 초기화 중... (DualWield / InfiniteAmmo / NoWeight)");
			TryPatch();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!_equipDone || !_consumableDone)
			{
				TryPatch();
			}
		}

		private void TryPatch()
		{
			if (!_equipDone)
			{
				_equipDone = PatchLoad("Bifrost.ItemEquipment.ItemEquipment_MasterData", "EquipmentPostfix");
			}
			if (!_consumableDone)
			{
				_consumableDone = PatchLoad("Bifrost.ItemConsumable.ItemConsumable_MasterData", "ConsumablePostfix");
			}
			if (_equipDone && _consumableDone)
			{
				((MelonBase)this).LoggerInstance.Msg("모든 패치 적용 완료! (양손 소지 / 탄약 무한 / 무게 제거)");
			}
		}

		private bool PatchLoad(string typeName, string postfixName)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			Type type = FindType(typeName);
			if (type == null)
			{
				WarnOnce("type:" + typeName, typeName + " 타입을 아직 찾을 수 없음 — 씬 로드 시 재시도합니다.");
				return false;
			}
			MethodBase methodBase = AccessTools.Method(type, "Load", new Type[1] { typeof(BinaryReader) }, (Type[])null) ?? AccessTools.Method(type, "Load", (Type[])null, (Type[])null);
			if (methodBase == null)
			{
				((MelonBase)this).LoggerInstance.Error(typeName + ".Load 메서드를 찾을 수 없음 — 게임 업데이트로 구조가 바뀌었을 수 있습니다.");
				return true;
			}
			((MelonBase)this).HarmonyInstance.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(typeof(Core), postfixName, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			((MelonBase)this).LoggerInstance.Msg(typeName + ".Load 패치 완료");
			return true;
		}

		private static void EquipmentPostfix(object __instance)
		{
			SetValue(__instance, "is_two_hand", false);
			SetNumber(__instance, "weight", 0.0);
			if (GetNumber(__instance, "max_gauge", -1.0) > 0.0)
			{
				SetNumber(__instance, "dec_gauge_per_use", 0.0);
				SetNumber(__instance, "max_gauge", 9999.0);
			}
		}

		private static void ConsumablePostfix(object __instance)
		{
			SetNumber(__instance, "weight", 0.0);
			SetNumber(__instance, "max_stack_count", 9999.0);
		}

		private static Type FindType(string fullName)
		{
			Type type = AccessTools.TypeByName(fullName);
			if (type != null)
			{
				return type;
			}
			string[] array = new string[5] { "Bifrost.ItemEquipment", "Bifrost.ItemConsumable", "Bifrost", "Assembly-CSharp", "Shared" };
			foreach (string assemblyString in array)
			{
				try
				{
					Assembly.Load(assemblyString);
				}
				catch
				{
				}
			}
			return AccessTools.TypeByName(fullName);
		}

		private static void SetValue(object instance, string fieldName, object value)
		{
			FieldInfo fieldInfo = AccessTools.Field(instance.GetType(), fieldName);
			if (fieldInfo == null)
			{
				WarnOnce(instance.GetType().Name + "." + fieldName, instance.GetType().Name + "에 " + fieldName + " 필드가 없어 건너뜁니다.");
			}
			else
			{
				fieldInfo.SetValue(instance, value);
			}
		}

		private static void SetNumber(object instance, string fieldName, double value)
		{
			FieldInfo fieldInfo = AccessTools.Field(instance.GetType(), fieldName);
			if (fieldInfo == null)
			{
				WarnOnce(instance.GetType().Name + "." + fieldName, instance.GetType().Name + "에 " + fieldName + " 필드가 없어 건너뜁니다.");
			}
			else
			{
				fieldInfo.SetValue(instance, Convert.ChangeType(value, fieldInfo.FieldType));
			}
		}

		private static double GetNumber(object instance, string fieldName, double fallback)
		{
			FieldInfo fieldInfo = AccessTools.Field(instance.GetType(), fieldName);
			if (fieldInfo == null)
			{
				return fallback;
			}
			try
			{
				return Convert.ToDouble(fieldInfo.GetValue(instance));
			}
			catch
			{
				return fallback;
			}
		}

		private static void WarnOnce(string key, string message)
		{
			if (_warned.Add(key))
			{
				MelonLogger.Warning(message);
			}
		}
	}
}