Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PickaxeMaster v6.0.0
PickaxeMaster.dll
Decompiled 7 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ServerSync; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("OreDamageDistributor")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OreDamageDistributor")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("2ec3237c-551f-4847-a11f-2a1b277a5c42")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace PickaxeMaster; [BepInPlugin("com.mysteryuniverse.valheim.PickaxeMaster", "Pickaxe Master", "6.0.0")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class PickaxeMaster : BaseUnityPlugin { private static ManualLogSource log; private static PickaxeMaster instance; private static FieldInfo nviewFieldInfo; private static Type znetViewType; private static MethodInfo znetIsValidMethod; private static MethodInfo znetIsOwnerMethod; private static ConfigSync configSync; private static SyncedConfigEntry<KeyboardShortcut> disableKey; private static SyncedConfigEntry<float> damageMultiplier; private static SyncedConfigEntry<float> minSegmentDamage; private static SyncedConfigEntry<bool> scaleToolDamage; private static SyncedConfigEntry<bool> enableAOEMode; private static SyncedConfigEntry<float> minAOEDistance; private static SyncedConfigEntry<float> maxAOEDistance; public static SyncedConfigEntry<string> language; private static bool disablePressed; private static bool isProcessing; public static string CurrentLang { get { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 if (language != null && (language.Value == "en" || language.Value == "ru")) { return language.Value; } return ((int)Application.systemLanguage == 30) ? "ru" : "en"; } } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0056: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown instance = this; log = ((BaseUnityPlugin)this).Logger; configSync = new ConfigSync("com.mysteryuniverse.valheim.PickaxeMaster") { DisplayName = Localization.Get("MOD_NAME"), CurrentVersion = "6.0.0", MinimumRequiredVersion = "5.9.8", ModRequired = true, IsLocked = true }; language = configSync.AddConfigEntry<string>(((BaseUnityPlugin)this).Config.Bind<string>("General", "Language", "en", Localization.Get("CONFIG_LANGUAGE"))); disableKey = configSync.AddConfigEntry<KeyboardShortcut>(((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "DisableKey", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), new ConfigDescription(Localization.Get("CONFIG_DISABLE_KEY"), (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } }))); damageMultiplier = configSync.AddConfigEntry<float>(((BaseUnityPlugin)this).Config.Bind<float>("General", "DamageMultiplier", 1f, Localization.Get("CONFIG_DAMAGE_MULTIPLIER"))); minSegmentDamage = configSync.AddConfigEntry<float>(((BaseUnityPlugin)this).Config.Bind<float>("General", "MinSegmentDamage", 0f, Localization.Get("CONFIG_MIN_SEGMENT_DAMAGE"))); scaleToolDamage = configSync.AddConfigEntry<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("General", "ScaleToolDamage", false, Localization.Get("CONFIG_SCALE_TOOL_DAMAGE"))); enableAOEMode = configSync.AddConfigEntry<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("AOE", "EnableLevelMode", true, Localization.Get("CONFIG_ENABLE_AOE"))); minAOEDistance = configSync.AddConfigEntry<float>(((BaseUnityPlugin)this).Config.Bind<float>("AOE", "MinDistance", 1f, Localization.Get("CONFIG_MIN_DISTANCE"))); maxAOEDistance = configSync.AddConfigEntry<float>(((BaseUnityPlugin)this).Config.Bind<float>("AOE", "MaxDistance", 10f, Localization.Get("CONFIG_MAX_DISTANCE"))); nviewFieldInfo = typeof(MineRock5).GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (nviewFieldInfo != null) { znetViewType = nviewFieldInfo.FieldType; znetIsValidMethod = znetViewType?.GetMethod("IsValid", BindingFlags.Instance | BindingFlags.Public); znetIsOwnerMethod = znetViewType?.GetMethod("IsOwner", BindingFlags.Instance | BindingFlags.Public); } Harmony.CreateAndPatchAll(typeof(PickaxeMaster), (string)null); } private static float GetAOERadius(Player player) { if ((Object)(object)player == (Object)null) { return minAOEDistance.Value; } float skillFactor = ((Character)player).GetSkillFactor((SkillType)12); return Mathf.Lerp(minAOEDistance.Value, maxAOEDistance.Value, skillFactor); } private static Collider[] GetAOESegments(MineRock5 rock, Vector3 hitPoint, Player player) { //IL_0042: 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_004a: 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_0053: 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) if (!enableAOEMode.Value) { return ((Component)rock).GetComponentsInChildren<Collider>(); } float aOERadius = GetAOERadius(player); float num = aOERadius * aOERadius; List<Collider> list = new List<Collider>(); Collider[] componentsInChildren = ((Component)rock).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { Bounds bounds = val.bounds; Vector3 val2 = hitPoint - ((Bounds)(ref bounds)).center; if (((Vector3)(ref val2)).sqrMagnitude <= num) { list.Add(val); } } return list.ToArray(); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = disableKey.Value; disablePressed = ((KeyboardShortcut)(ref value)).IsDown(); } [HarmonyPatch(typeof(MineRock5), "Damage")] [HarmonyPrefix] public static bool Prefix(MineRock5 __instance, HitData hit) { //IL_0112: 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_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Expected O, but got Unknown if (!((Object)(object)__instance == (Object)null) && hit != null && !disablePressed) { _ = hit.m_attacker; if (0 == 0) { if (isProcessing) { return true; } isProcessing = true; try { ZNetScene obj = ZNetScene.instance; GameObject val = ((obj != null) ? obj.FindInstance(hit.m_attacker) : null); Player val2 = ((val != null) ? val.GetComponent<Player>() : null); if ((Object)(object)val2 == (Object)null) { return true; } if (nviewFieldInfo != null && znetIsValidMethod != null && znetIsOwnerMethod != null) { try { object value = nviewFieldInfo.GetValue(__instance); if (value != null) { bool flag = (bool)znetIsValidMethod.Invoke(value, null); bool flag2 = (bool)znetIsOwnerMethod.Invoke(value, null); if (flag && !flag2) { return true; } } } catch { } } Collider[] aOESegments = GetAOESegments(__instance, hit.m_point, val2); if (aOESegments.Length == 0) { return true; } int num = aOESegments.Length; float pickaxe = hit.m_damage.m_pickaxe; float num2 = Mathf.Max(Mathf.Round(pickaxe / (float)num * 10f) / 10f, minSegmentDamage.Value); float num3 = pickaxe - num2 * (float)num; int num4 = Mathf.RoundToInt(num3 * 10f); float[] array = new float[num]; for (int i = 0; i < num; i++) { array[i] = num2; } List<int> list = new List<int>(); for (int j = 0; j < num; j++) { list.Add(j); } for (int k = 0; k < num; k++) { int num5 = Random.Range(k, num); List<int> list2 = list; int index = k; int index2 = num5; int value2 = list[num5]; int value3 = list[k]; list2[index] = value2; list[index2] = value3; } for (int l = 0; l < num4 && l < num; l++) { array[list[l]] += 0.1f; } for (int m = 0; m < array.Length; m++) { array[m] *= damageMultiplier.Value; } ItemData val3 = null; try { MethodInfo method = typeof(Humanoid).GetMethod("GetRightItem", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { val3 = (ItemData)method.Invoke(val2, null); } } catch { } float num6 = 0f; for (int n = 0; n < num; n++) { try { HitData val4 = new HitData { m_damage = new DamageTypes { m_damage = array[n] }, m_point = hit.m_point, m_hitCollider = aOESegments[n], m_dir = hit.m_dir, m_attacker = hit.m_attacker, m_pushForce = hit.m_pushForce, m_toolTier = hit.m_toolTier }; Destructible componentInParent = ((Component)aOESegments[n]).GetComponentInParent<Destructible>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)__instance) { componentInParent.Damage(val4); } else { __instance.Damage(val4); } num6 += array[n]; } catch { } } if (val3 != null) { SharedData shared = val3.m_shared; if (shared != null && shared.m_useDurability && num6 > 0f && scaleToolDamage.Value) { float value4 = damageMultiplier.Value; float num7 = Mathf.Max(0f, value4 - 1f); val3.m_durability = Mathf.Max(0f, val3.m_durability - num7); } } } finally { isProcessing = false; } return false; } } return true; } } public static class Localization { private static readonly Dictionary<string, string> en = new Dictionary<string, string> { { "MOD_NAME", "PickaxeMaster" }, { "MOD_DESCRIPTION", "Distributes ore damage across segments and scales tool wear." }, { "CONFIG_DISABLE_KEY", "Temporary Disable Key" }, { "CONFIG_DAMAGE_MULTIPLIER", "Damage Multiplier" }, { "CONFIG_MIN_SEGMENT_DAMAGE", "Minimum Segment Damage" }, { "CONFIG_SCALE_TOOL_DAMAGE", "Scale Tool Durability" }, { "CONFIG_ENABLE_AOE", "Scale AOE Radius by Pickaxe Skill" }, { "CONFIG_MIN_DISTANCE", "Min AOE Distance" }, { "CONFIG_MAX_DISTANCE", "Max AOE Distance" }, { "CONFIG_LANGUAGE", "Language. en/ru" } }; private static readonly Dictionary<string, string> ru = new Dictionary<string, string> { { "MOD_NAME", "Мастер Кирки" }, { "MOD_DESCRIPTION", "Распределяет урон по сегментам руды и масштабирует износ инструментов." }, { "CONFIG_DISABLE_KEY", "Клавиша временного отключения" }, { "CONFIG_DAMAGE_MULTIPLIER", "Множитель урона" }, { "CONFIG_MIN_SEGMENT_DAMAGE", "Минимальный урон сегмента" }, { "CONFIG_SCALE_TOOL_DAMAGE", "Масштабировать износ инструмента" }, { "CONFIG_ENABLE_AOE", "Масштабировать радиус AOE по уровню владения киркой" }, { "CONFIG_MIN_DISTANCE", "Минимальная дистанция AOE" }, { "CONFIG_MAX_DISTANCE", "Максимальная дистанция AOE" }, { "CONFIG_LANGUAGE", "Language. en, ru" } }; public static string Get(string key) { string currentLang = PickaxeMaster.CurrentLang; return (!(currentLang == "ru")) ? (en.ContainsKey(key) ? en[key] : key) : (ru.ContainsKey(key) ? ru[key] : key); } } internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public int? Order; public bool? IsAdminOnly; public string Category; public string DispName; public string Description; public object DefaultValue; public AcceptableValueBase AcceptableValues; public bool? HideSettingName; public bool? ReadOnly; }