using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Laserflare")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A skill-based carry weight mod for Valheim")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BeastOfBurden")]
[assembly: AssemblyTitle("BeastOfBurden")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 BeastOfBurden
{
[BepInPlugin("com.laserflare.beastofburden", "Beast of Burden", "1.0.8")]
public class BeastOfBurdenPlugin : BaseUnityPlugin
{
public const string PluginGUID = "com.laserflare.beastofburden";
public const string PluginName = "Beast of Burden";
public const string PluginVersion = "1.0.8";
private static BeastOfBurdenPlugin _instance;
private Harmony _harmony;
public static ConfigEntry<float> CarryWeightPerSkillLevel;
public static ConfigEntry<float> SkillGainRate;
public static ConfigEntry<float> MinimumLoadPercentage;
public static ConfigEntry<bool> EnableMod;
private static float _skillExperience;
private static float _skillLevel;
private static float _lastSkillGainTime;
private static Type _playerType;
private static Type _znetViewType;
private static FieldInfo _localPlayerField;
private static FieldInfo _nviewField;
private static MethodInfo _getComponentMethod;
private static MethodInfo _getInventoryMethod;
private static MethodInfo _getVelocityMethod;
private static MethodInfo _getTotalWeightMethod;
private static MethodInfo _getMaxCarryWeightMethod;
private static MethodInfo _getZDOMethod;
private static MethodInfo _zdoSetFloatMethod;
private static MethodInfo _zdoGetFloatMethod;
private static MethodInfo _isValidMethod;
private static MethodInfo _messageMethod;
private void Awake()
{
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Expected O, but got Unknown
_instance = this;
EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable the Beast of Burden mod");
CarryWeightPerSkillLevel = ((BaseUnityPlugin)this).Config.Bind<float>("CarryWeight", "CarryWeightPerSkillLevel", 3f, "Additional carry weight per skill level (max level 100 = +300 weight at default)");
SkillGainRate = ((BaseUnityPlugin)this).Config.Bind<float>("Skill", "SkillGainRate", 0.5f, "Rate at which Beast of Burden skill increases when carrying heavy loads (experience per second)");
MinimumLoadPercentage = ((BaseUnityPlugin)this).Config.Bind<float>("Skill", "MinimumLoadPercentage", 0.9f, "Minimum percentage of carry capacity that must be filled to gain skill (0.9 = 90%)");
if (!InitializeReflection())
{
((BaseUnityPlugin)this).Logger.LogError((object)"Failed to initialize reflection. Mod will not function.");
return;
}
_harmony = new Harmony("com.laserflare.beastofburden");
ApplyPatches();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Beast of Burden v1.0.8 loaded!");
}
private bool InitializeReflection()
{
try
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
_playerType = assemblies[i].GetType("Player");
if (_playerType != null)
{
break;
}
}
if (_playerType == null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"Could not find Player type");
return false;
}
_localPlayerField = _playerType.GetField("m_localPlayer", BindingFlags.Static | BindingFlags.Public);
_nviewField = _playerType.GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
if (_nviewField == null)
{
Type type = _playerType;
while (type != null && _nviewField == null)
{
_nviewField = type.GetField("m_nview", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
type = type.BaseType;
}
}
assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
_znetViewType = assemblies[i].GetType("ZNetView");
if (_znetViewType != null)
{
break;
}
}
if (_znetViewType != null)
{
MethodInfo method = typeof(Component).GetMethod("GetComponent", Type.EmptyTypes);
if (method != null)
{
_getComponentMethod = method.MakeGenericMethod(_znetViewType);
}
}
_getInventoryMethod = _playerType.GetMethod("GetInventory");
_getVelocityMethod = _playerType.GetMethod("GetVelocity");
_getMaxCarryWeightMethod = _playerType.GetMethod("GetMaxCarryWeight");
Type type2 = _getInventoryMethod?.ReturnType;
if (type2 != null)
{
_getTotalWeightMethod = type2.GetMethod("GetTotalWeight");
}
if (_znetViewType != null)
{
_isValidMethod = _znetViewType.GetMethod("IsValid");
_getZDOMethod = _znetViewType.GetMethod("GetZDO");
}
Type type3 = _getZDOMethod?.ReturnType;
if (type3 != null)
{
_zdoSetFloatMethod = type3.GetMethod("Set", new Type[2]
{
typeof(string),
typeof(float)
});
_zdoGetFloatMethod = type3.GetMethod("GetFloat", new Type[2]
{
typeof(string),
typeof(float)
});
}
_messageMethod = _playerType.GetMethod("Message");
return true;
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Reflection initialization failed: {arg}");
return false;
}
}
private void ApplyPatches()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Expected O, but got Unknown
try
{
MethodInfo method = _playerType.GetMethod("GetMaxCarryWeight");
if (method != null)
{
MethodInfo method2 = typeof(BeastOfBurdenPlugin).GetMethod("GetMaxCarryWeight_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
_harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo method3 = _playerType.GetMethod("FixedUpdate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method3 != null)
{
MethodInfo method4 = typeof(BeastOfBurdenPlugin).GetMethod("FixedUpdate_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
_harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo method5 = _playerType.GetMethod("OnSpawned");
if (method5 != null)
{
MethodInfo method6 = typeof(BeastOfBurdenPlugin).GetMethod("OnSpawned_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
_harmony.Patch((MethodBase)method5, (HarmonyMethod)null, new HarmonyMethod(method6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo method7 = _playerType.GetMethod("Save");
if (method7 != null)
{
MethodInfo method8 = typeof(BeastOfBurdenPlugin).GetMethod("Save_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
_harmony.Patch((MethodBase)method7, (HarmonyMethod)null, new HarmonyMethod(method8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to apply patches: {arg}");
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
public static float GetSkillLevel()
{
return _skillLevel;
}
public static void SetSkillLevel(float level)
{
_skillLevel = Mathf.Clamp(level, 0f, 100f);
}
public static void AddExperience(object player, float amount)
{
_skillExperience += amount;
float num = 100f;
float num2 = _skillExperience / num;
num2 = Mathf.Clamp(num2, 0f, 100f);
if (!(num2 > _skillLevel))
{
return;
}
float skillLevel = _skillLevel;
SetSkillLevel(num2);
if (Mathf.Floor(num2) > Mathf.Floor(skillLevel) && _messageMethod != null)
{
try
{
_messageMethod.Invoke(player, new object[4]
{
1,
$"Beast of Burden: {Mathf.Floor(num2)}",
0,
null
});
}
catch
{
}
BeastOfBurdenPlugin instance = _instance;
if (instance != null)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)$"Beast of Burden skill increased to {Mathf.Floor(num2)}");
}
}
}
public static float GetCarryWeightBonus()
{
if (!EnableMod.Value)
{
return 0f;
}
return _skillLevel * CarryWeightPerSkillLevel.Value;
}
public static void SaveSkillData(object nview)
{
if (nview == null || _getZDOMethod == null)
{
return;
}
try
{
object obj = _getZDOMethod.Invoke(nview, null);
if (obj != null && _zdoSetFloatMethod != null)
{
_zdoSetFloatMethod.Invoke(obj, new object[2] { "beastofburden_skill", _skillLevel });
_zdoSetFloatMethod.Invoke(obj, new object[2] { "beastofburden_exp", _skillExperience });
}
}
catch
{
}
}
public static void LoadSkillData(object nview)
{
if (nview == null || _getZDOMethod == null)
{
return;
}
try
{
object obj = _getZDOMethod.Invoke(nview, null);
if (obj == null || !(_zdoGetFloatMethod != null))
{
return;
}
_skillLevel = (float)_zdoGetFloatMethod.Invoke(obj, new object[2] { "beastofburden_skill", 0f });
_skillExperience = (float)_zdoGetFloatMethod.Invoke(obj, new object[2] { "beastofburden_exp", 0f });
if (_skillLevel > 0f)
{
BeastOfBurdenPlugin instance = _instance;
if (instance != null)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)$"Loaded Beast of Burden skill: {_skillLevel:F1}");
}
}
}
catch
{
}
}
private static void GetMaxCarryWeight_Postfix(ref float __result)
{
__result += GetCarryWeightBonus();
}
private static void FixedUpdate_Postfix(object __instance)
{
//IL_00cc: 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)
if (!EnableMod.Value)
{
return;
}
try
{
object obj = _localPlayerField?.GetValue(null);
if (obj == null || __instance != obj)
{
return;
}
object obj2 = _nviewField?.GetValue(__instance);
if (obj2 == null && _getComponentMethod != null)
{
obj2 = _getComponentMethod.Invoke(__instance, null);
}
if (obj2 == null)
{
return;
}
object obj3 = _isValidMethod?.Invoke(obj2, null);
if (obj3 == null || !(bool)obj3 || Time.time - _lastSkillGainTime < 1f)
{
return;
}
Vector3 val = (Vector3)(((??)(Vector3?)_getVelocityMethod?.Invoke(__instance, null)) ?? Vector3.zero);
if (((Vector3)(ref val)).magnitude < 0.1f)
{
return;
}
object obj4 = _getInventoryMethod?.Invoke(__instance, null);
if (obj4 != null)
{
float valueOrDefault = ((float?)_getTotalWeightMethod?.Invoke(obj4, null)).GetValueOrDefault();
float num = ((float?)_getMaxCarryWeightMethod?.Invoke(__instance, null)) ?? 300f;
if (valueOrDefault / num >= MinimumLoadPercentage.Value)
{
_lastSkillGainTime = Time.time;
AddExperience(__instance, SkillGainRate.Value);
}
}
}
catch
{
}
}
private static void OnSpawned_Postfix(object __instance)
{
try
{
object obj = _localPlayerField?.GetValue(null);
if (__instance == obj)
{
object obj2 = _nviewField?.GetValue(__instance);
if (obj2 == null && _getComponentMethod != null)
{
obj2 = _getComponentMethod.Invoke(__instance, null);
}
LoadSkillData(obj2);
}
}
catch
{
}
}
private static void Save_Postfix(object __instance)
{
try
{
object obj = _localPlayerField?.GetValue(null);
if (__instance == obj)
{
object obj2 = _nviewField?.GetValue(__instance);
if (obj2 == null && _getComponentMethod != null)
{
obj2 = _getComponentMethod.Invoke(__instance, null);
}
SaveSkillData(obj2);
}
}
catch
{
}
}
}
}