Decompiled source of CarryWeightSkill v1.0.2

plugins\CarrySkill.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using CarrySkill.Patches;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Carry Skill")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Carry Skill")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e6b72c5a-9fe8-49d7-855e-8165656a6777")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[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 CarrySkill
{
	[BepInPlugin("shadymods.carryskill.carry_weight", "Carry Weight Skill", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class CarrySkillPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "shadymods.carryskill.carry_weight";

		public const string PluginName = "Carry Weight Skill";

		public const string PluginVersion = "1.0.2";

		public const string SkillIdentifier = "com.shadymods.carryskill.carry_weight_v1";

		public static SkillType CarrySkillType { get; private set; }

		internal static ManualLogSource CarrySkillLog { get; private set; }

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			CarrySkillLog = ((BaseUnityPlugin)this).Logger;
			CarrySkillType = SkillManager.Instance.AddSkill(new SkillConfig
			{
				Identifier = "com.shadymods.carryskill.carry_weight_v1",
				Name = "Carry Weight",
				Description = "Gain skill while sprinting or swimming with a heavy load (50%+ of max weight). No XP while over-encumbered. Heavier loads train faster. Each level adds +3 carry weight (up to +300 at level 100).",
				IncreaseStep = 1f
			});
			Harmony val = new Harmony("shadymods.carryskill.carry_weight");
			TryPatchGetMaxCarryWeight(val);
			TryPatchUpdateWalking(val);
			TryPatchSwimming(val);
			try
			{
				val.PatchAll();
			}
			catch (Exception ex)
			{
				CarrySkillLog.LogError((object)("CarrySkill: PatchAll failed: " + ex));
			}
			Game.isModded = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Carry Weight Skill loaded.");
		}

		private static void TryPatchSwimming(Harmony harmony)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			Type[] array = new Type[2]
			{
				typeof(Vector3),
				typeof(float)
			};
			MethodBase methodBase = AccessTools.DeclaredMethod(typeof(Player), "OnSwimming", array, (Type[])null) ?? AccessTools.DeclaredMethod(typeof(Character), "OnSwimming", array, (Type[])null) ?? AccessTools.DeclaredMethod(typeof(Humanoid), "OnSwimming", array, (Type[])null);
			if (methodBase != null)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(CarrySkillPatches), "OnSwimming_Postfix", new Type[3]
				{
					typeof(Character),
					typeof(Vector3),
					typeof(float)
				}, (Type[])null);
				if (methodInfo == null)
				{
					CarrySkillLog.LogError((object)"CarrySkill: Could not resolve OnSwimming_Postfix — swim carry XP will not apply.");
					return;
				}
				try
				{
					harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					return;
				}
				catch (Exception ex)
				{
					CarrySkillLog.LogError((object)("CarrySkill: Manual OnSwimming patch failed: " + ex));
					return;
				}
			}
			MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(Character), "UpdateSwimming", new Type[1] { typeof(float) }, (Type[])null);
			if (methodInfo2 == null)
			{
				CarrySkillLog.LogError((object)"CarrySkill: Could not resolve Player/Character.OnSwimming or Character.UpdateSwimming — swim carry XP will not apply.");
				return;
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(CarrySkillPatches), "UpdateSwimming_Postfix", new Type[2]
			{
				typeof(Character),
				typeof(float)
			}, (Type[])null);
			if (methodInfo3 == null)
			{
				CarrySkillLog.LogError((object)"CarrySkill: Could not resolve UpdateSwimming_Postfix — swim carry XP will not apply.");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex2)
			{
				CarrySkillLog.LogError((object)("CarrySkill: Manual UpdateSwimming patch failed: " + ex2));
			}
		}

		private static void TryPatchGetMaxCarryWeight(Harmony harmony)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Player), "GetMaxCarryWeight", Type.EmptyTypes, (Type[])null) ?? AccessTools.Method(typeof(Player), "GetMaxCarryWeight", Type.EmptyTypes, (Type[])null);
			if (methodInfo == null)
			{
				CarrySkillLog.LogError((object)"CarrySkill: Could not resolve Player.GetMaxCarryWeight() — carry weight bonus will not apply.");
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(CarrySkillPatches), "GetMaxCarryWeight_Postfix", new Type[2]
			{
				typeof(Player),
				typeof(float).MakeByRefType()
			}, (Type[])null);
			if (methodInfo2 == null)
			{
				CarrySkillLog.LogError((object)"CarrySkill: Could not resolve GetMaxCarryWeight_Postfix — carry weight bonus will not apply.");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				CarrySkillLog.LogError((object)("CarrySkill: Manual GetMaxCarryWeight patch failed: " + ex));
			}
		}

		private static void TryPatchUpdateWalking(Harmony harmony)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Character), "UpdateWalking", new Type[1] { typeof(float) }, (Type[])null) ?? AccessTools.Method(typeof(Character), "UpdateWalking", new Type[1] { typeof(float) }, (Type[])null);
			if (methodInfo == null)
			{
				CarrySkillLog.LogError((object)"CarrySkill: Could not resolve Character.UpdateWalking(float) — run/sprint carry XP will not apply.");
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(CarrySkillPatches), "UpdateWalking_Postfix", new Type[2]
			{
				typeof(Character),
				typeof(float)
			}, (Type[])null);
			if (methodInfo2 == null)
			{
				CarrySkillLog.LogError((object)"CarrySkill: Could not resolve UpdateWalking_Postfix — run/sprint carry XP will not apply.");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				CarrySkillLog.LogError((object)("CarrySkill: Manual UpdateWalking patch failed: " + ex));
			}
		}
	}
}
namespace CarrySkill.Patches
{
	public static class CarrySkillPatches
	{
		private const float MinFill = 0.5f;

		private const float MaxLerpFill = 1f;

		private const float SwimVelThreshold = 0.1f;

		private const float SwimVelThresholdHeavy = 0.001f;

		private static float _lastZeroGainWarningTime = -1000f;

		private static bool _loggedMissingSkillsGetSkill;

		private static readonly MethodInfo SkillsGetSkill = AccessTools.Method(typeof(Skills), "GetSkill", new Type[1] { typeof(SkillType) }, (Type[])null);

		internal static void GetMaxCarryWeight_Postfix(Player __instance, ref float __result)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance == (Object)null) && ((Character)__instance).IsPlayer())
			{
				Skills skills = ((Character)__instance).GetSkills();
				if (!((Object)(object)skills == (Object)null))
				{
					float skillLevel = skills.GetSkillLevel(CarrySkillPlugin.CarrySkillType);
					__result += skillLevel * 3f;
				}
			}
		}

		internal static void UpdateWalking_Postfix(Character __instance, float dt)
		{
			if (!(dt <= 0f))
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !((Character)val).IsDead() && !((Character)val).IsSwimming() && !((Character)val).IsEncumbered() && Traverse.Create((object)__instance).Field("m_running").GetValue<bool>())
				{
					TryApplyRunCarryXp(val, dt);
				}
			}
		}

		internal static void OnSwimming_Postfix(Character __instance, Vector3 targetVel, float dt)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !((Character)val).IsDead() && !((Character)val).IsEncumbered() && TryGetFill(val, out var fill))
			{
				float num = ((fill >= 0.5f) ? 0.001f : 0.1f);
				bool flag = ((Vector3)(ref targetVel)).magnitude > num;
				if (!flag && fill >= 0.5f && TryGetSwimMoveSpeed(val, out var horizontalSpeed))
				{
					flag = horizontalSpeed > num;
				}
				if (flag)
				{
					TryApplySwimCarryXp(val, dt);
				}
			}
		}

		internal static void UpdateSwimming_Postfix(Character __instance, float dt)
		{
			if (dt <= 0f)
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !((Character)val).IsDead() && ((Character)val).IsSwimming() && !((Character)val).IsEncumbered() && TryGetSwimMoveSpeed(val, out var horizontalSpeed))
			{
				float fill;
				float num = ((TryGetFill(val, out fill) && fill >= 0.5f) ? 0.001f : 0.1f);
				if (!(horizontalSpeed <= num))
				{
					TryApplySwimCarryXp(val, dt);
				}
			}
		}

		private static bool TryGetSwimMoveSpeed(Player player, out float horizontalSpeed)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			horizontalSpeed = 0f;
			Rigidbody value = Traverse.Create((object)player).Field("m_body").GetValue<Rigidbody>();
			if ((Object)(object)value == (Object)null)
			{
				return false;
			}
			Vector3 linearVelocity = value.linearVelocity;
			linearVelocity.y = 0f;
			horizontalSpeed = ((Vector3)(ref linearVelocity)).magnitude;
			return true;
		}

		private static void TryApplyRunCarryXp(Player player, float dt)
		{
			Skills skills = ((Character)player).GetSkills();
			if (!((Object)(object)skills == (Object)null) && !(dt <= 0f) && TryGetFill(player, out var fill) && !(fill < 0.5f))
			{
				float num = WeightFillMultiplier(fill);
				float raiseFactor = GetIncreaseStep(skills, (SkillType)102) * num * dt;
				ApplyCarrySkillXp(player, skills, raiseFactor);
			}
		}

		private static void TryApplySwimCarryXp(Player player, float dt)
		{
			Skills skills = ((Character)player).GetSkills();
			if (!((Object)(object)skills == (Object)null) && !(dt <= 0f) && TryGetFill(player, out var fill) && !(fill < 0.5f))
			{
				float num = WeightFillMultiplier(fill);
				float raiseFactor = GetIncreaseStep(skills, (SkillType)103) * num * dt;
				ApplyCarrySkillXp(player, skills, raiseFactor);
			}
		}

		private static bool TryGetFill(Player player, out float fill)
		{
			fill = 0f;
			float maxCarryWeight = player.GetMaxCarryWeight();
			if (maxCarryWeight <= 0f)
			{
				return false;
			}
			float totalWeight = ((Humanoid)player).GetInventory().GetTotalWeight();
			fill = Mathf.Clamp01(totalWeight / maxCarryWeight);
			return true;
		}

		private static void ApplyCarrySkillXp(Player player, Skills skills, float raiseFactor)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Skill orCreateCarrySkill = GetOrCreateCarrySkill(skills);
			if (orCreateCarrySkill == null)
			{
				if (!_loggedMissingSkillsGetSkill && CarrySkillPlugin.CarrySkillLog != null)
				{
					_loggedMissingSkillsGetSkill = true;
					CarrySkillPlugin.CarrySkillLog.LogError((object)"CarrySkill: Skills.GetSkill reflection failed — carry XP may not apply correctly.");
				}
				((Character)player).RaiseSkill(CarrySkillPlugin.CarrySkillType, raiseFactor);
				return;
			}
			float nextLevelRequirement = GetNextLevelRequirement(orCreateCarrySkill);
			float accumulator = orCreateCarrySkill.m_accumulator;
			float level = orCreateCarrySkill.m_level;
			((Character)player).RaiseSkill(CarrySkillPlugin.CarrySkillType, raiseFactor);
			float num = ComputeAccumulatorGain(accumulator, level, nextLevelRequirement, orCreateCarrySkill.m_accumulator, orCreateCarrySkill.m_level);
			if (raiseFactor > 1E-08f && num <= 0f && CarrySkillPlugin.CarrySkillLog != null && Time.time - _lastZeroGainWarningTime > 30f)
			{
				_lastZeroGainWarningTime = Time.time;
				CarrySkillPlugin.CarrySkillLog.LogWarning((object)($"CarryWeight: RaiseSkill had no accumulator gain (factor={raiseFactor:E3}). " + "At skill 100, or if a status blocks skill XP, this is normal."));
			}
		}

		internal static Skill GetOrCreateCarrySkill(Skills skills)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Skill val = TryGetCarrySkillInstance(skills);
			if (val != null)
			{
				return val;
			}
			if (SkillsGetSkill == null)
			{
				return null;
			}
			object? obj = SkillsGetSkill.Invoke(skills, new object[1] { CarrySkillPlugin.CarrySkillType });
			return (Skill)((obj is Skill) ? obj : null);
		}

		internal static Skill TryGetCarrySkillInstance(Skills skills)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected I4, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<SkillType, Skill> value = Traverse.Create((object)skills).Field("m_skillData").GetValue<Dictionary<SkillType, Skill>>();
			if (value == null)
			{
				return null;
			}
			SkillType carrySkillType = CarrySkillPlugin.CarrySkillType;
			if (value.TryGetValue(carrySkillType, out var value2))
			{
				return value2;
			}
			int num = (int)carrySkillType;
			if (num != 0 && num != int.MinValue)
			{
				SkillType val = (SkillType)Math.Abs(num);
				if (val != carrySkillType && value.TryGetValue(val, out value2))
				{
					return value2;
				}
				SkillType val2 = (SkillType)(-num);
				if (val2 != carrySkillType && value.TryGetValue(val2, out value2))
				{
					return value2;
				}
			}
			return null;
		}

		private static float GetNextLevelRequirement(Skill skill)
		{
			return Traverse.Create((object)skill).Method("GetNextLevelRequirement", Array.Empty<object>()).GetValue<float>();
		}

		private static float ComputeAccumulatorGain(float accBefore, float levelBefore, float nextReqBefore, float accAfter, float levelAfter)
		{
			if (levelAfter > levelBefore)
			{
				return nextReqBefore - accBefore + accAfter;
			}
			return accAfter - accBefore;
		}

		private static float WeightFillMultiplier(float fillClamped01)
		{
			if (fillClamped01 >= 1f)
			{
				return 2f;
			}
			float num = (fillClamped01 - 0.5f) / 0.5f;
			return Mathf.Lerp(1f, 2f, num);
		}

		private static float GetIncreaseStep(Skills skills, SkillType type)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (skills?.m_skills == null)
			{
				return 1f;
			}
			foreach (SkillDef skill in skills.m_skills)
			{
				if (skill.m_skill == type)
				{
					return skill.m_increseStep;
				}
			}
			return 1f;
		}
	}
	[HarmonyPatch(typeof(Character), "Jump")]
	internal static class CharacterJumpMessageCompatPatch
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo shim = AccessTools.Method(typeof(PlayerMessageCompat), "ShowFromCharacter", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (shim != null && instruction.opcode == OpCodes.Callvirt && instruction.operand is MethodInfo { Name: "Message" } methodInfo && methodInfo.DeclaringType == typeof(Character))
				{
					yield return new CodeInstruction(OpCodes.Call, (object)shim);
				}
				else
				{
					yield return instruction;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnTabCraftPressed")]
	internal static class InventoryGuiTabCraftGuardPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(InventoryGui __instance)
		{
			if (__instance.InCraftTab())
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnTabUpgradePressed")]
	internal static class InventoryGuiTabUpgradeGuardPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(InventoryGui __instance)
		{
			if (!__instance.InCraftTab())
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnCraftPressed")]
	internal static class MultiCraftInputFixPatch
	{
		private static FieldRef<InventoryGui, bool> _multiCrafting;

		private static FieldRef<InventoryGui, ItemData> _craftUpgradeItem;

		[HarmonyPostfix]
		private static void Postfix(InventoryGui __instance)
		{
			EnsureFields();
			if (_craftUpgradeItem.Invoke(__instance) == null)
			{
				bool button = ZInput.GetButton("AltPlace");
				bool num = ZInput.IsGamepadActive();
				bool flag = _multiCrafting.Invoke(__instance);
				if (!num && flag && !button)
				{
					_multiCrafting.Invoke(__instance) = false;
				}
			}
		}

		private static void EnsureFields()
		{
			if (_multiCrafting == null)
			{
				_multiCrafting = AccessTools.FieldRefAccess<InventoryGui, bool>("m_multiCrafting");
				_craftUpgradeItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("m_craftUpgradeItem");
			}
		}
	}
	internal static class PlayerMessageCompat
	{
		internal static void ShowFromCharacter(Character character, MessageType type, string msg, int amount = 0, Sprite icon = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Show((Player)(object)((character is Player) ? character : null), type, msg, amount, icon);
		}

		internal static void Show(Player player, MessageType type, string msg, int amount = 0, Sprite icon = null)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected I4, but got Unknown
			if ((Object)(object)player == (Object)null || (Object)(object)MessageHud.instance == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				if (!component.IsOwner())
				{
					component.InvokeRPC("Message", new object[3]
					{
						(int)type,
						msg,
						amount
					});
				}
				else
				{
					MessageHud.instance.ShowMessage(type, msg, amount, icon, false, true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Message")]
	internal static class PlayerMessageCompatPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Player __instance, MessageType type, string msg, int amount, Sprite icon)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayerMessageCompat.Show(__instance, type, msg, amount, icon);
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
	internal static class RepairOneItemCompatPatch
	{
		private static FieldRef<InventoryGui, List<ItemData>> _tempWornItems;

		private static MethodInfo _canRepair;

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(InventoryGui __instance)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return true;
			}
			try
			{
				return RunRepair(__instance, localPlayer);
			}
			catch (Exception ex)
			{
				ManualLogSource carrySkillLog = CarrySkillPlugin.CarrySkillLog;
				if (carrySkillLog != null)
				{
					carrySkillLog.LogWarning((object)("RepairOneItemCompatPatch: " + ex.Message));
				}
				return false;
			}
		}

		private static bool RunRepair(InventoryGui __instance, Player player)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			EnsureReflection(__instance);
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			if (((Object)(object)currentCraftingStation == (Object)null && !player.NoCostCheat()) || ((Object)(object)currentCraftingStation != (Object)null && !currentCraftingStation.CheckUsable(player, false)))
			{
				return false;
			}
			List<ItemData> list = _tempWornItems.Invoke(__instance);
			list.Clear();
			((Humanoid)player).GetInventory().GetWornItems(list);
			foreach (ItemData item in list)
			{
				if ((bool)_canRepair.Invoke(__instance, new object[1] { item }))
				{
					((Character)player).RaiseSkill((SkillType)107, 1f - item.m_durability / item.GetMaxDurability());
					item.m_durability = item.GetMaxDurability();
					if ((Object)(object)currentCraftingStation != (Object)null)
					{
						currentCraftingStation.m_repairItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
					}
					PlayerMessageCompat.Show(player, (MessageType)2, LocalizeRepaired(item.m_shared.m_name));
					return false;
				}
			}
			PlayerMessageCompat.Show(player, (MessageType)2, "No more item to repair");
			return false;
		}

		private static void EnsureReflection(InventoryGui gui)
		{
			if (_tempWornItems == null)
			{
				_tempWornItems = AccessTools.FieldRefAccess<InventoryGui, List<ItemData>>("m_tempWornItems");
			}
			if (_canRepair == null)
			{
				_canRepair = AccessTools.Method(typeof(InventoryGui), "CanRepair", new Type[1] { typeof(ItemData) }, (Type[])null);
			}
		}

		private static string LocalizeRepaired(string itemName)
		{
			Type type = AccessTools.TypeByName("Localization");
			object obj = (type?.GetProperty("instance", BindingFlags.Static | BindingFlags.Public))?.GetValue(null, null);
			MethodInfo methodInfo = type?.GetMethod("Localize", new Type[2]
			{
				typeof(string),
				typeof(string)
			});
			if (obj != null && methodInfo != null)
			{
				return (string)methodInfo.Invoke(obj, new object[2] { "$msg_repaired", itemName });
			}
			return "$msg_repaired " + itemName;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
	internal static class RepairOneItemMessageCompatPatch
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo shim = AccessTools.Method(typeof(PlayerMessageCompat), "ShowFromCharacter", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (shim != null && instruction.opcode == OpCodes.Callvirt && instruction.operand is MethodInfo { Name: "Message" } methodInfo && typeof(Character).IsAssignableFrom(methodInfo.DeclaringType))
				{
					yield return new CodeInstruction(OpCodes.Call, (object)shim);
				}
				else
				{
					yield return instruction;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Skills), "RaiseSkill")]
	internal static class SkillsRaiseSkillCompatPatch
	{
		private static MethodInfo _rebalanceSkills;

		private static MethodInfo _getSkill;

		private static MethodInfo _goganLogEvent;

		[HarmonyPrefix]
		private static bool Prefix(Skills __instance, SkillType skillType, float factor)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if ((int)skillType == 0)
			{
				return true;
			}
			try
			{
				EnsureReflection();
				if (_getSkill == null)
				{
					return true;
				}
				Skill val = ResolveSkill(__instance, skillType);
				if (val == null)
				{
					return true;
				}
				float level = val.m_level;
				if (val.Raise(factor))
				{
					if (Traverse.Create((object)__instance).Field("m_useSkillCap").GetValue<bool>() && _rebalanceSkills != null)
					{
						_rebalanceSkills.Invoke(__instance, new object[1] { skillType });
					}
					Player value = Traverse.Create((object)__instance).Field("m_player").GetValue<Player>();
					if (value != null)
					{
						value.OnSkillLevelup(skillType, val.m_level);
					}
					MessageType type = (MessageType)(((int)level != 0) ? 1 : 2);
					string msg = "$msg_skillup $skill_" + ((object)Unsafe.As<SkillType, SkillType>(ref val.m_info.m_skill)/*cast due to .constrained prefix*/).ToString().ToLower() + ": " + (int)val.m_level;
					ShowSkillMessage(value, type, msg, val.m_info.m_icon);
					TryGoganLogEvent(skillType, val.m_level);
				}
				return false;
			}
			catch (Exception ex)
			{
				ManualLogSource carrySkillLog = CarrySkillPlugin.CarrySkillLog;
				if (carrySkillLog != null)
				{
					carrySkillLog.LogWarning((object)("SkillsRaiseSkillCompatPatch: " + ex.Message));
				}
				return true;
			}
		}

		private static Skill ResolveSkill(Skills __instance, SkillType skillType)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected I4, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected I4, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			EnsureReflection();
			if (_getSkill == null)
			{
				return null;
			}
			Skill val = (Skill)_getSkill.Invoke(__instance, new object[1] { skillType });
			if (val != null)
			{
				return val;
			}
			int num = (int)skillType;
			if (num != 0 && num != int.MinValue)
			{
				SkillType val2 = (SkillType)Math.Abs(num);
				if (val2 != skillType)
				{
					val = (Skill)_getSkill.Invoke(__instance, new object[1] { val2 });
					if (val != null)
					{
						return val;
					}
				}
				SkillType val3 = (SkillType)(-num);
				if (val3 != skillType)
				{
					val = (Skill)_getSkill.Invoke(__instance, new object[1] { val3 });
					if (val != null)
					{
						return val;
					}
				}
			}
			if (skillType == CarrySkillPlugin.CarrySkillType || Math.Abs(num) == Math.Abs((int)CarrySkillPlugin.CarrySkillType))
			{
				return CarrySkillPatches.GetOrCreateCarrySkill(__instance);
			}
			return null;
		}

		private static void EnsureReflection()
		{
			if (!(_getSkill != null))
			{
				_getSkill = AccessTools.DeclaredMethod(typeof(Skills), "GetSkill", new Type[1] { typeof(SkillType) }, (Type[])null);
				_rebalanceSkills = AccessTools.DeclaredMethod(typeof(Skills), "RebalanceSkills", new Type[1] { typeof(SkillType) }, (Type[])null);
				_goganLogEvent = AccessTools.TypeByName("Gogan")?.GetMethod("LogEvent", BindingFlags.Static | BindingFlags.Public, null, new Type[4]
				{
					typeof(string),
					typeof(string),
					typeof(string),
					typeof(int)
				}, null);
			}
		}

		private static void ShowSkillMessage(Player player, MessageType type, string msg, Sprite icon)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected I4, but got Unknown
			if ((Object)(object)player == (Object)null || (Object)(object)MessageHud.instance == (Object)null)
			{
				return;
			}
			ZNetView value = Traverse.Create((object)player).Field("m_nview").GetValue<ZNetView>();
			if (!((Object)(object)value == (Object)null) && value.IsValid())
			{
				if (!value.IsOwner())
				{
					value.InvokeRPC("Message", new object[3]
					{
						(int)type,
						msg,
						0
					});
				}
				else
				{
					MessageHud.instance.ShowMessage(type, msg, 0, icon, false, true);
				}
			}
		}

		private unsafe static void TryGoganLogEvent(SkillType skillType, float level)
		{
			if (_goganLogEvent == null)
			{
				return;
			}
			try
			{
				_goganLogEvent.Invoke(null, new object[4]
				{
					"Game",
					"Levelup",
					((object)(*(SkillType*)(&skillType))/*cast due to .constrained prefix*/).ToString(),
					(int)level
				});
			}
			catch
			{
			}
		}
	}
}