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 LogItemThrower v1.0.1
LogItemThrower.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using SkillManager; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.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; } } } internal sealed class ConfigurationManagerAttributes { public int? Order { get; set; } public bool? Browsable { get; set; } = true; public string Category { get; set; } = string.Empty; public Action<ConfigEntryBase> CustomDrawer { get; set; } } namespace LogItemThrower { public class LogHoverText : MonoBehaviour, Hoverable { public string GetHoverText() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return ""; } if (Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)this).transform.position) > LogItemThrower.GrabRange.Value) { return ""; } KeyboardShortcut value = LogItemThrower.LaunchHotkey.Value; KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey; string text = ((object)(KeyCode)(ref mainKey)).ToString(); return "Log\n[<color=yellow>" + text + "</color>] Grab"; } public string GetHoverName() { return "Log"; } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetSceneAwakePatch { private static void Postfix(ZNetScene __instance) { foreach (GameObject prefab in __instance.m_prefabs) { if ((Object)(object)prefab.GetComponent<TreeLog>() != (Object)null && (Object)(object)prefab.GetComponent<LogHoverText>() == (Object)null) { prefab.AddComponent<LogHoverText>(); } } } } [HarmonyPatch(typeof(ItemDrop), "GetHoverText")] public static class ItemDropHoverPatch { private static void Postfix(ItemDrop __instance, ref string __result) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_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 (!((Object)(object)Player.m_localPlayer == (Object)null)) { Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>(); if (!((Object)(object)component == (Object)null) && !(Vector3.Distance(((Component)Player.m_localPlayer).transform.position, component.position) > LogItemThrower.GrabRange.Value)) { KeyboardShortcut value = LogItemThrower.LaunchHotkey.Value; KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey; string text = ((object)(KeyCode)(ref mainKey)).ToString(); __result = __result + "\n[" + text + "] Grab"; } } } } [BepInPlugin("com.custom.logitemthrower", "Log/Item Thrower", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LogItemThrower : BaseUnityPlugin { [CompilerGenerated] private sealed class <DelayedLaunch>d__61 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject obj; public Rigidbody rb; public LogItemThrower <>4__this; public Vector3 dir; public float force; public float originalDamping; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedLaunch>d__61(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown int num = <>1__state; LogItemThrower logItemThrower = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForFixedUpdate(); <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)obj == (Object)null || (Object)(object)rb == (Object)null) { return false; } Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = true; } logItemThrower.SetCollision(ignore: true, obj); rb.isKinematic = false; rb.useGravity = true; rb.AddForce(dir * force, (ForceMode)1); <>2__current = (object)new WaitForSeconds(0.6f); <>1__state = 2; return true; } case 2: <>1__state = -1; if ((Object)(object)rb != (Object)null) { rb.linearDamping = originalDamping; } if ((Object)(object)obj != (Object)null) { logItemThrower.SetCollision(ignore: false, obj); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static ConfigEntry<KeyboardShortcut> LaunchHotkey; public static ConfigEntry<KeyboardShortcut> RotationHotkey; public static ConfigEntry<KeyboardShortcut> DropHotkey; public static ConfigEntry<float> PctGrab; public static ConfigEntry<float> PctThrow; public static ConfigEntry<float> PctDrainStill; public static ConfigEntry<float> PctDrainMove; public static ConfigEntry<float> PctGrabItem; public static ConfigEntry<float> PctThrowItem; public static ConfigEntry<float> LogForce; public static ConfigEntry<float> ItemForce; public static ConfigEntry<float> LogHoldRotationX; public static ConfigEntry<float> LogHoldRotationZ; public static ConfigEntry<float> LogPushForce; public static ConfigEntry<float> LogAoeRadius; public static ConfigEntry<float> GrabRange; public static ConfigEntry<float> StrengthCoefficient; public static ConfigEntry<float> SkillForceBonus; public static ConfigEntry<float> LogDamageCoefficient; public static ConfigEntry<float> LogAoeDamageMultiplier; public static ConfigEntry<float> MaxChargeTime; public static ConfigEntry<float> MaxChargeMultiplier; public static ConfigEntry<float> MaxChargeStaminaMultiplier; private static Skill _throwingSkill; private static MethodInfo _hideHandItemsMethod; private static MethodInfo _showHandItemsMethod; private static bool _epicMmoReflectionInitialized; private static MethodInfo _epicGetAttributeMethod; private static object _epicStrengthValue; private static readonly ManualLogSource _staticLog = Logger.CreateLogSource("LogItemThrower"); private bool _isHolding; private bool _rotationMode; private bool _isHeldLog; private bool _isCharging; private bool _justGrabbed; private float _chargeTime; private GameObject _heldObject; private Rigidbody _heldRigidbody; private Quaternion _heldRotation = Quaternion.identity; private Vector3 _originalScale; private float _originalMass; private float _originalDamping; private GameObject _throwSoundPrefab; private readonly Harmony _harmony = new Harmony("com.custom.logitemthrower"); private void Awake() { _hideHandItemsMethod = typeof(Humanoid).GetMethod("HideHandItems", BindingFlags.Instance | BindingFlags.NonPublic); _showHandItemsMethod = typeof(Humanoid).GetMethod("ShowHandItems", BindingFlags.Instance | BindingFlags.NonPublic); SetupConfig(); SetupSkill(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Log/Item Thrower: Unity 6 Compatibility Mode Loaded."); _harmony.PatchAll(); } private void SetupConfig() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Expected O, but got Unknown //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Expected O, but got Unknown //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Expected O, but got Unknown //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Expected O, but got Unknown //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Expected O, but got Unknown //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Expected O, but got Unknown //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Expected O, but got Unknown //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Expected O, but got Unknown //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Expected O, but got Unknown //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Expected O, but got Unknown //IL_0648: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Expected O, but got Unknown //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_06a4: Expected O, but got Unknown //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_06f6: Expected O, but got Unknown //IL_073e: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Expected O, but got Unknown LaunchHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - General", "LaunchHotkey", new KeyboardShortcut((KeyCode)116, Array.Empty<KeyCode>()), new ConfigDescription("Key to grab and throw logs/items.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); DropHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - General", "DropHotkey", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), new ConfigDescription("Key to drop the held object.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 9 } })); RotationHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - General", "RotationHotkey", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), new ConfigDescription("Key to toggle rotation mode while holding.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 8 } })); GrabRange = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "GrabRange", 12f, new ConfigDescription("Max reach distance to grab an object.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); LogForce = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogForce", 2000f, new ConfigDescription("Launch force applied to logs.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 10000f), new object[1] { new ConfigurationManagerAttributes { Order = 9 } })); ItemForce = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "ItemForce", 150f, new ConfigDescription("Launch force applied to items.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 2000f), new object[1] { new ConfigurationManagerAttributes { Order = 8 } })); LogPushForce = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogPushForce", 80f, new ConfigDescription("Knockback force applied to enemies hit by a log.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[1] { new ConfigurationManagerAttributes { Order = 7 } })); LogDamageCoefficient = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogDamageCoefficient", 0.01f, new ConfigDescription("Damage dealt per unit of launch force.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), new object[1] { new ConfigurationManagerAttributes { Order = 6 } })); StrengthCoefficient = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "StrengthCoefficient", 0.002f, new ConfigDescription("Force bonus multiplier per Strength point (EpicMMO).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.05f), new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); SkillForceBonus = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "SkillForceBonus", 0.25f, new ConfigDescription("Max force bonus from max Throwing skill level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); LogHoldRotationX = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogHoldRotationX", 90f, new ConfigDescription("X-axis rotation of the log while held on shoulder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); LogHoldRotationZ = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogHoldRotationZ", 0f, new ConfigDescription("Z-axis rotation of the log while held on shoulder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); LogAoeRadius = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogAoeRadius", 3f, new ConfigDescription("Radius of AOE splash damage on log impact.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); LogAoeDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Physics", "LogAoeDamageMultiplier", 0.5f, new ConfigDescription("AOE damage as a fraction of direct hit damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 0 } })); PctGrab = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Stamina", "GrabCostPct", 0.12f, new ConfigDescription("Stamina cost to grab a log (% of max stamina).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); PctGrabItem = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Stamina", "ItemGrabCostPct", 0.02f, new ConfigDescription("Stamina cost to grab an item stack (% of max stamina).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); PctThrow = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Stamina", "ThrowCostPct", 0.15f, new ConfigDescription("Stamina cost to throw a log (% of max stamina).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); PctThrowItem = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Stamina", "ItemThrowCostPct", 0.05f, new ConfigDescription("Stamina cost to throw an item stack (% of max stamina).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); PctDrainStill = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Stamina", "PassiveDrainPct", 0.005f, new ConfigDescription("Stamina drained per second while holding still (% of max).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); PctDrainMove = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Stamina", "ActiveDrainPct", 0.015f, new ConfigDescription("Stamina drained per second while moving with a log (% of max).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); MaxChargeTime = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Charge", "MaxChargeTime", 2f, new ConfigDescription("Seconds to hold throw key for maximum charge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); MaxChargeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Charge", "MaxChargeMultiplier", 2f, new ConfigDescription("Force multiplier at full charge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); MaxChargeStaminaMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Charge", "MaxChargeStaminaMultiplier", 1.5f, new ConfigDescription("Stamina cost multiplier at full charge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); } private void SetupSkill() { try { _throwingSkill = new Skill("Throwing", "throwing.png"); _throwingSkill.Description.English("Improves log-throwing efficiency and power."); _throwingSkill.Configurable = true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("SkillManager icon failed: " + ex.Message)); _throwingSkill = null; } } private float GetEfficiencyMultiplier() { float skillLevel = GetSkillLevel(); float num = Mathf.Log(1f + skillLevel) / Mathf.Log(101f); return 1f - num * 0.5f; } private float GetSkillLevel() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return 0f; } if (_throwingSkill == null) { return 0f; } return ((Character)(object)Player.m_localPlayer).GetSkillFactor("Throwing") * 100f; } private static int GetEpicStrength() { if (!Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem")) { return 0; } if (!_epicMmoReflectionInitialized) { _epicMmoReflectionInitialized = true; try { Type type = Type.GetType("API.EpicMMOSystem_API, EpicMMOSystem"); if (type != null) { MethodInfo method = type.GetMethod("GetAttribute"); Type nestedType = type.GetNestedType("Attribut"); if (method != null && nestedType != null) { _epicGetAttributeMethod = method; _epicStrengthValue = Enum.Parse(nestedType, "Strength"); } } } catch (Exception ex) { _staticLog.LogWarning((object)("EpicMMOSystem reflection setup failed: " + ex.Message)); } } if (_epicGetAttributeMethod == null || _epicStrengthValue == null) { return 0; } try { object obj = _epicGetAttributeMethod.Invoke(null, new object[1] { _epicStrengthValue }); if (obj == null) { return 0; } if (obj is int result) { return result; } if (obj is float num) { return Mathf.RoundToInt(num); } return Convert.ToInt32(obj); } catch (Exception ex2) { _staticLog.LogWarning((object)("EpicMMOSystem strength lookup failed: " + ex2.Message)); return 0; } } private void Update() { //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Chat instance = Chat.instance; if ((instance != null && instance.HasFocus()) || Menu.IsVisible()) { return; } KeyboardShortcut value; if (_isHolding) { if ((Object)(object)_heldObject == (Object)null) { CancelHold(); return; } if (localPlayer.GetStamina() <= 0f) { ((Character)localPlayer).Message((MessageType)1, "Exhausted!", 0, (Sprite)null); CancelHold(); return; } HandleStaminaDrain(localPlayer); value = RotationHotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { _rotationMode = !_rotationMode; ((Character)localPlayer).Message((MessageType)1, _rotationMode ? "Rotation mode ON" : "Rotation mode OFF", 0, (Sprite)null); } if (_rotationMode) { float num = Input.GetAxis("Mouse X") * 5f; float num2 = Input.GetAxis("Mouse Y") * 5f; _heldRotation = Quaternion.AngleAxis(0f - num, Vector3.up) * Quaternion.AngleAxis(num2, ((Component)Utils.GetMainCamera()).transform.right) * _heldRotation; } value = DropHotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { CancelHold(); return; } } value = LaunchHotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey) && !_isHolding) { TryGrabHoverObject(localPlayer); _justGrabbed = _isHolding; } if (_isHolding) { value = LaunchHotkey.Value; if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey) && !_justGrabbed) { _isCharging = true; _chargeTime = Mathf.Min(_chargeTime + Time.deltaTime, MaxChargeTime.Value); } } if (!_isHolding) { return; } value = LaunchHotkey.Value; if (Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey)) { if (_justGrabbed) { _justGrabbed = false; _isCharging = false; _chargeTime = 0f; } else if (_isCharging) { TryLaunch(localPlayer); _isCharging = false; _chargeTime = 0f; } } } private void HandleStaminaDrain(Player p) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (_isHeldLog) { Vector3 velocity = ((Character)p).GetVelocity(); float num = ((((Vector3)(ref velocity)).magnitude > 0.1f) ? PctDrainMove.Value : PctDrainStill.Value); float num2 = ((Character)p).GetMaxStamina() * num * GetEfficiencyMultiplier(); ((Character)p).UseStamina(num2 * Time.deltaTime); } } private void TryGrabHoverObject(Player p) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) GameObject hoverObject = ((Humanoid)p).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return; } Rigidbody componentInParent = hoverObject.GetComponentInParent<Rigidbody>(); bool flag = (Object)(object)hoverObject.GetComponentInParent<TreeLog>() != (Object)null; bool flag2 = (Object)(object)hoverObject.GetComponentInParent<ItemDrop>() != (Object)null; if (!((Object)(object)componentInParent != (Object)null) || !(flag || flag2)) { return; } float num = (flag ? PctGrab.Value : PctGrabItem.Value); float num2 = ((Character)p).GetMaxStamina() * num * GetEfficiencyMultiplier(); if (((Character)p).HaveStamina(num2)) { if (Vector3.Distance(((Component)p).transform.position, componentInParent.position) <= GrabRange.Value) { ((Character)p).UseStamina(num2); BeginHold(((Component)componentInParent).gameObject, componentInParent); } } else { ((Character)p).Message((MessageType)1, "Not enough energy!", 0, (Sprite)null); } } private void BeginHold(GameObject obj, Rigidbody rb) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) _heldObject = obj; _isHeldLog = (Object)(object)obj.GetComponentInParent<TreeLog>() != (Object)null; _originalScale = obj.transform.localScale; if (_isHeldLog) { obj.transform.localScale = _originalScale * 0.35f; } _heldRigidbody = rb; _isHolding = true; _heldRotation = Quaternion.identity; ZNetView component = obj.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.ClaimOwnership(); } _hideHandItemsMethod?.Invoke(Player.m_localPlayer, new object[2] { false, false }); _originalMass = _heldRigidbody.mass; _originalDamping = _heldRigidbody.linearDamping; _heldRigidbody.mass = 0.1f; _heldRigidbody.useGravity = false; _heldRigidbody.isKinematic = true; Collider[] componentsInChildren = _heldObject.GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } ((Character)Player.m_localPlayer).Message((MessageType)1, "Target Secured.", 0, (Sprite)null); } private void FixedUpdate() { //IL_0049: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (_isHolding && (Object)(object)_heldObject != (Object)null && (Object)(object)_heldRigidbody != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null) { Transform transform = ((Component)Player.m_localPlayer).transform; Vector3 val = transform.position + Vector3.up * 1.8f + transform.right * 0.4f + transform.forward * -0.2f; _heldRigidbody.MovePosition(val); if (_isHeldLog && !_rotationMode) { Vector3 forward = transform.forward; forward.y = 0f; ((Vector3)(ref forward)).Normalize(); _heldRotation = Quaternion.LookRotation(forward) * Quaternion.Euler(LogHoldRotationX.Value, 0f, LogHoldRotationZ.Value); } _heldRigidbody.MoveRotation(_heldRotation); } } private void TryLaunch(Player p) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) float num = ((MaxChargeTime.Value > 0f) ? (_chargeTime / MaxChargeTime.Value) : 1f); bool isHeldLog = _isHeldLog; float num2 = (isHeldLog ? PctThrow.Value : PctThrowItem.Value); float num3 = 1f + num * (MaxChargeStaminaMultiplier.Value - 1f); float num4 = ((Character)p).GetMaxStamina() * num2 * GetEfficiencyMultiplier() * num3; if (((Character)p).HaveStamina(num4)) { ((Character)p).UseStamina(num4); if (_throwingSkill != null) { ((Character)(object)p).RaiseSkill("Throwing", isHeldLog ? 1f : 0.2f); } Launch(isHeldLog, num); } else { KeyboardShortcut value = DropHotkey.Value; ((Character)p).Message((MessageType)1, $"Too tired! Recover stamina or press [{((KeyboardShortcut)(ref value)).MainKey}] to drop.", 0, (Sprite)null); } } private void Launch(bool isLog, float chargeRatio = 1f) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) float skillLevel = GetSkillLevel(); float num = Mathf.Log(1f + skillLevel) / Mathf.Log(101f); float num2 = 1f + num * SkillForceBonus.Value; int epicStrength = GetEpicStrength(); float num3 = 1f + (float)epicStrength * StrengthCoefficient.Value; float num4 = (isLog ? LogForce.Value : ItemForce.Value); float num5 = (isLog ? 1f : Mathf.Clamp(_originalMass, 0.5f, 5f)); float num6 = 1f + chargeRatio * (MaxChargeMultiplier.Value - 1f); float num7 = num4 * num5 * num2 * num3 * num6; if (isLog) { _heldObject.AddComponent<ThrownProjectile>().damage = num7 * LogDamageCoefficient.Value; } _heldObject.transform.position = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2.2f + Vector3.up * 1.8f; _heldObject.transform.localScale = _originalScale; _heldRigidbody.mass = _originalMass; _heldRigidbody.linearDamping = 0.2f; _heldRigidbody.WakeUp(); Camera mainCamera = Utils.GetMainCamera(); Vector3 dir = ((Component)mainCamera).transform.forward; RaycastHit val = default(RaycastHit); if (Physics.Raycast(((Component)mainCamera).transform.position, ((Component)mainCamera).transform.forward, ref val, 200f)) { Vector3 val2 = ((RaycastHit)(ref val)).point - _heldObject.transform.position; Vector3 normalized = ((Vector3)(ref val2)).normalized; if (Vector3.Dot(normalized, ((Component)mainCamera).transform.forward) > 0.1f) { dir = normalized; } } if ((Object)(object)_throwSoundPrefab == (Object)null) { ZNetScene instance = ZNetScene.instance; _throwSoundPrefab = ((instance != null) ? instance.GetPrefab("sfx_warrior_attack") : null); } if ((Object)(object)_throwSoundPrefab != (Object)null) { Object.Instantiate<GameObject>(_throwSoundPrefab, _heldObject.transform.position, Quaternion.identity); } if (!isLog) { _heldObject.AddComponent<SkippingStone>(); } GameObject heldObject = _heldObject; Rigidbody heldRigidbody = _heldRigidbody; float originalDamping = _originalDamping; if ((Object)(object)Player.m_localPlayer != (Object)null) { _showHandItemsMethod?.Invoke(Player.m_localPlayer, new object[2] { false, true }); } ClearState(); ((MonoBehaviour)this).StartCoroutine(DelayedLaunch(heldObject, heldRigidbody, dir, num7, originalDamping)); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, isLog ? "YEET!" : "Tossed.", 0, (Sprite)null); } } private void OnGUI() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if (_isCharging && _isHolding) { float num = ((MaxChargeTime.Value > 0f) ? (_chargeTime / MaxChargeTime.Value) : 1f); float num2 = (float)Screen.width / 2f; float num3 = (float)Screen.height / 2f; float num4 = 30f; float num5 = 8f; GUI.color = Color.Lerp(Color.yellow, Color.red, num); int num6 = 32; for (int i = 0; i < num6; i++) { float num7 = (float)i / (float)num6 * MathF.PI * 2f * num; float num8 = num2 + Mathf.Sin(num7) * num4 - num5 / 2f; float num9 = num3 - Mathf.Cos(num7) * num4 - num5 / 2f; GUI.DrawTexture(new Rect(num8, num9, num5, num5), (Texture)(object)Texture2D.whiteTexture); } GUI.color = Color.white; } } private void SetCollision(bool ignore, GameObject target = null) { GameObject val = target ?? _heldObject; if ((Object)(object)val == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(); Collider[] componentsInChildren2 = ((Component)Player.m_localPlayer).GetComponentsInChildren<Collider>(); Collider[] array = componentsInChildren; foreach (Collider val2 in array) { Collider[] array2 = componentsInChildren2; foreach (Collider val3 in array2) { Physics.IgnoreCollision(val2, val3, ignore); } } } private void ClearState() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) _isHolding = false; _heldObject = null; _heldRigidbody = null; _heldRotation = Quaternion.identity; _rotationMode = false; _isHeldLog = false; _isCharging = false; _chargeTime = 0f; _justGrabbed = false; } private void CancelHold() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_heldObject == (Object)null) { ClearState(); return; } Collider[] componentsInChildren = _heldObject.GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = true; } if ((Object)(object)_heldRigidbody != (Object)null) { _heldObject.transform.localScale = _originalScale; _heldRigidbody.isKinematic = false; _heldRigidbody.useGravity = true; _heldRigidbody.mass = _originalMass; _heldRigidbody.linearDamping = _originalDamping; SetCollision(ignore: false); } if ((Object)(object)Player.m_localPlayer != (Object)null) { _showHandItemsMethod?.Invoke(Player.m_localPlayer, new object[2] { false, true }); } ClearState(); } [IteratorStateMachine(typeof(<DelayedLaunch>d__61))] private IEnumerator DelayedLaunch(GameObject obj, Rigidbody rb, Vector3 dir, float force, float originalDamping) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedLaunch>d__61(0) { <>4__this = this, obj = obj, rb = rb, dir = dir, force = force, originalDamping = originalDamping }; } } public class SkippingStone : MonoBehaviour { private Rigidbody rb; private int skipsRemaining = 5; private float lastSkipTime; private WaterVolume _waterVol; private int _waterLayer; private GameObject _splashPrefab; private void Start() { rb = ((Component)this).GetComponent<Rigidbody>(); _waterLayer = LayerMask.NameToLayer("Water"); ZNetScene instance = ZNetScene.instance; _splashPrefab = ((instance != null) ? instance.GetPrefab("vfx_water_hit") : null); Object.Destroy((Object)(object)this, 10f); } private void FixedUpdate() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rb == (Object)null || skipsRemaining <= 0) { return; } float waterLevel = Floating.GetWaterLevel(((Component)this).transform.position, ref _waterVol); if (!(((Component)this).transform.position.y <= waterLevel) || !(Time.time - lastSkipTime > 0.2f)) { return; } Vector3 linearVelocity = rb.linearVelocity; if (((Vector3)(ref linearVelocity)).magnitude > 5f) { Vector3 linearVelocity2 = rb.linearVelocity; float num = Mathf.Min(Mathf.Abs(linearVelocity2.y) * 0.5f + 2f, 8f); rb.linearVelocity = new Vector3(linearVelocity2.x, num, linearVelocity2.z); rb.AddForce(((Component)this).transform.forward * 2f, (ForceMode)2); skipsRemaining--; lastSkipTime = Time.time; if ((Object)(object)_splashPrefab != (Object)null) { Object.Instantiate<GameObject>(_splashPrefab, new Vector3(((Component)this).transform.position.x, waterLevel, ((Component)this).transform.position.z), Quaternion.identity); } } else { Object.Destroy((Object)(object)this); } } private void OnCollisionEnter(Collision collision) { if (skipsRemaining < 5 && collision.gameObject.layer != _waterLayer) { Object.Destroy((Object)(object)this); } } } public class ThrownProjectile : MonoBehaviour { private static readonly ManualLogSource _log = Logger.CreateLogSource("LogItemThrower"); public float damage; private Rigidbody rb; private bool _hasHit; private GameObject _hitVfxPrefab; private void Start() { rb = ((Component)this).GetComponent<Rigidbody>(); ZNetScene instance = ZNetScene.instance; _hitVfxPrefab = ((instance != null) ? instance.GetPrefab("vfx_clubhit") : null); Object.Destroy((Object)(object)this, 10f); } private void FixedUpdate() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) if (_hasHit || (Object)(object)rb == (Object)null) { return; } Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 0.8f); foreach (Collider val in array) { Character componentInParent = ((Component)val).GetComponentInParent<Character>(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent == (Object)(object)Player.m_localPlayer)) { _hasHit = true; HitData val2 = new HitData(); val2.m_damage.m_blunt = damage; val2.m_point = val.ClosestPoint(((Component)this).transform.position); Vector3 linearVelocity = rb.linearVelocity; val2.m_dir = ((Vector3)(ref linearVelocity)).normalized; val2.m_skill = (SkillType)3; val2.m_pushForce = LogItemThrower.LogPushForce.Value; val2.m_attacker = ((Character)Player.m_localPlayer).GetZDOID(); componentInParent.Damage(val2); _log.LogInfo((object)$"Hit {((Object)componentInParent).name} for {val2.m_damage.m_blunt}"); if ((Object)(object)DamageText.instance != (Object)null) { DamageText.instance.ShowText((TextType)0, val2.m_point, val2.m_damage.m_blunt, false); } if ((Object)(object)_hitVfxPrefab != (Object)null) { Object.Instantiate<GameObject>(_hitVfxPrefab, val2.m_point, Quaternion.identity); } ApplyAoe(val2.m_point, damage, componentInParent); Object.Destroy((Object)(object)this); break; } } } private void ApplyAoe(Vector3 point, float directDamage, Character directHit) { //IL_0000: 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_004f: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(point, LogItemThrower.LogAoeRadius.Value); for (int i = 0; i < array.Length; i++) { Character componentInParent = ((Component)array[i]).GetComponentInParent<Character>(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent == (Object)(object)Player.m_localPlayer) && !((Object)(object)componentInParent == (Object)(object)directHit)) { HitData val = new HitData(); val.m_damage.m_blunt = directDamage * LogItemThrower.LogAoeDamageMultiplier.Value; val.m_point = point; Vector3 val2 = ((Component)componentInParent).transform.position - point; val.m_dir = ((Vector3)(ref val2)).normalized; val.m_skill = (SkillType)3; val.m_pushForce = LogItemThrower.LogPushForce.Value * 0.5f; val.m_attacker = ((Character)Player.m_localPlayer).GetZDOID(); componentInParent.Damage(val); if ((Object)(object)DamageText.instance != (Object)null) { DamageText.instance.ShowText((TextType)0, val.m_point, val.m_damage.m_blunt, false); } if ((Object)(object)_hitVfxPrefab != (Object)null) { Object.Instantiate<GameObject>(_hitVfxPrefab, point, Quaternion.identity); } } } } } } namespace API { public static class EpicMMOSystem_API { private enum API_State { NotReady, NotInstalled, Ready } public enum Attribut { Strength, Agility, Intellect, Body, Vigour, Special } private static API_State state; private static MethodInfo eGetLevel; private static MethodInfo eAddExp; private static MethodInfo eGetAttribute; private static MethodInfo eGetAttributeRusty; private static MethodInfo eSetSingleRate; public static int GetLevel() { int result = 0; Init(); if (eGetLevel != null) { result = (int)eGetLevel.Invoke(null, null); } return result; } public static int GetAttribute(Attribut attribute) { int result = 0; Init(); if (eGetAttribute != null) { result = (int)eGetAttribute.Invoke(null, new object[1] { attribute }); } return result; } public static int GetAttributeRusty(string attribute) { int result = 0; Init(); if (eGetAttributeRusty != null) { result = (int)eGetAttributeRusty.Invoke(null, new object[1] { attribute }); } return result; } public static void AddExp(int value) { Init(); eAddExp?.Invoke(null, new object[1] { value }); } public static void SetSingleRate(float rate) { Init(); eSetSingleRate?.Invoke(null, new object[1] { rate }); } private static void Init() { API_State aPI_State = state; if ((uint)(aPI_State - 1) > 1u) { if (Type.GetType("EpicMMOSystem.EpicMMOSystem, EpicMMOSystem") == null) { state = API_State.NotInstalled; return; } state = API_State.Ready; Type? type = Type.GetType("API.EMMOS_API, EpicMMOSystem"); eGetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public); eAddExp = type.GetMethod("AddExp", BindingFlags.Static | BindingFlags.Public); eGetAttribute = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public); eGetAttributeRusty = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public); eSetSingleRate = type.GetMethod("SetSingleRate", BindingFlags.Static | BindingFlags.Public); } } } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace SkillManager { [PublicAPI] internal class Skill { public static class LocalizationCache { private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>(); internal static void LocalizationPostfix(Localization __instance, string language) { Localization __instance2 = __instance; string key = Enumerable.FirstOrDefault<KeyValuePair<string, Localization>>(localizations, (KeyValuePair<string, Localization> l) => l.Value == __instance2).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance2); } } public static Localization ForLanguage(string? language = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out Localization value)) { return value; } value = new Localization(); if (language != null) { value.SetupLanguage(language); } return value; } } [PublicAPI] public class LocalizeKey { private static readonly List<LocalizeKey> keys = new List<LocalizeKey>(); public readonly string Key; public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>(); public LocalizeKey(string key) { Key = key.Replace("$", ""); keys.Add(this); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out string value) || key.Localizations.TryGetValue("English", out value)) { __instance.AddWord(key.Key, value); } else if (key.Localizations.TryGetValue("alias", out value2)) { __instance.AddWord(key.Key, Localization.instance.Localize(value2)); } } } } private class ConfigurationManagerAttributes { [UsedImplicitly] public string? Category; } [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static class Patch_Skills_IsSkillValid { private static void Postfix(SkillType type, ref bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!__result && skills.ContainsKey(type)) { __result = true; } } } private static readonly Dictionary<SkillType, Skill> skills; internal static readonly Dictionary<string, Skill> skillByName; private readonly string skillName; private readonly string internalSkillName; private readonly SkillDef skillDef; public readonly LocalizeKey Name; public readonly LocalizeKey Description; private float skillEffectFactor = 1f; private int skillLoss = 5; public bool Configurable; private static bool InitializedTerminal; private static Localization? _english; private static BaseUnityPlugin? _plugin; private static bool hasConfigSync; private static object? _configSync; public float SkillGainFactor { get { return skillDef.m_increseStep; } set { skillDef.m_increseStep = value; this.SkillGainFactorChanged?.Invoke(value); } } public float SkillEffectFactor { get { return skillEffectFactor; } set { skillEffectFactor = value; this.SkillEffectFactorChanged?.Invoke(value); } } public int SkillLoss { get { return skillLoss; } set { skillLoss = value; this.SkillLossChanged?.Invoke(value); } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_0041: 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 O, but got Unknown object obj = _plugin; if (obj == null) { BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Enumerable.First(Assembly.GetExecutingAssembly().DefinedTypes, (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } private static object? configSync { get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public event Action<float>? SkillGainFactorChanged; public event Action<float>? SkillEffectFactorChanged; public event Action<float>? SkillLossChanged; public Skill(string englishName, string icon) : this(englishName, loadSprite(icon, 64, 64)) { } public Skill(string englishName, Sprite icon) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0064: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0082: Expected O, but got Unknown SkillType val = fromName(englishName); string text = new Regex("[^a-zA-Z]").Replace(englishName, "_"); skills[val] = this; skillByName[englishName] = this; skillDef = new SkillDef { m_description = "$skilldesc_" + text, m_icon = icon, m_increseStep = 1f, m_skill = val }; internalSkillName = text; skillName = englishName; Name = new LocalizeKey("skill_" + ((object)(SkillType)(ref val)).ToString()).English(englishName); Description = new LocalizeKey("skilldesc_" + text); } public static SkillType fromName(string englishName) { return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName)); } static Skill() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0065: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01ab: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_023c: Expected O, but got Unknown skills = new Dictionary<SkillType, Skill>(); skillByName = new Dictionary<string, Skill>(); InitializedTerminal = false; hasConfigSync = true; Harmony val = new Harmony("org.bepinex.helpers.skillmanager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); } private static void Patch_FejdStartup() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown foreach (Skill skill in skills.Values) { if (skill.Configurable) { string key = skill.Name.Key; string group = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim(); string category = Localization.instance.Localize(key).Trim(); ConfigEntry<float> skillGain = config(group, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillGainFactor = skillGain.Value; skillGain.SettingChanged += delegate { skill.SkillGainFactor = skillGain.Value; }; ConfigEntry<float> skillEffect = config(group, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillEffectFactor = skillEffect.Value; skillEffect.SettingChanged += delegate { skill.SkillEffectFactor = skillEffect.Value; }; ConfigEntry<int> skillLoss = config(group, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.skillLoss = skillLoss.Value; skillLoss.SettingChanged += delegate { skill.skillLoss = skillLoss.Value; }; } } } private static void Patch_Skills_GetSkillDef(ref SkillDef? __result, List<SkillDef> ___m_skills, SkillType type) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (__result == null) { SkillDef val = GetSkillDef(type); if (val != null) { ___m_skills.Add(val); __result = val; } } } private static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) foreach (SkillType key in skills.Keys) { SkillType current = key; Skill skill = skills[current]; if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase)) { Skill skill2 = __instance.GetSkill(current); skill2.m_level += value; skill2.m_level = Mathf.Clamp(skill2.m_level, 0f, 100f); ((Character)___m_player).Message((MessageType)1, "Skill increased " + Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref current)).ToString()) + ": " + (int)skill2.m_level, 0, skill2.m_info.m_icon); Console.instance.Print("Skill " + skill.internalSkillName + " = " + skill2.m_level); return false; } } return true; } private static bool Patch_Skills_CheatResetSkill(Skills __instance, string name) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) foreach (SkillType key in skills.Keys) { Skill skill = skills[key]; if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase)) { __instance.ResetSkill(key); Console.instance.Print("Skill " + skill.internalSkillName + " reset"); return false; } } return true; } private static void Patch_Skills_OnDeath_Prefix(Skills __instance, ref Dictionary<SkillType, Skill>? __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { __state = new Dictionary<SkillType, Skill>(); } foreach (KeyValuePair<SkillType, Skill> skill in skills) { if (__instance.m_skillData.TryGetValue(skill.Key, out var value)) { __state[skill.Key] = value; if (skill.Value.skillLoss > 0) { Skill obj = value; obj.m_level -= value.m_level * (float)skill.Value.SkillLoss / 100f; value.m_accumulator = 0f; } __instance.m_skillData.Remove(skill.Key); } } } private static void Patch_Skills_OnDeath_Finalizer(Skills __instance, ref Dictionary<SkillType, Skill>? __state) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } foreach (KeyValuePair<SkillType, Skill> item in __state) { __instance.m_skillData[item.Key] = item.Value; } __state = null; } private static void Patch_Terminal_InitTerminal_Prefix() { InitializedTerminal = Terminal.m_terminalInitialized; } private static void Patch_Terminal_InitTerminal() { if (!InitializedTerminal) { AddSkill(Terminal.commands["raiseskill"]); AddSkill(Terminal.commands["resetskill"]); } static void AddSkill(ConsoleCommand command) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher; command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)delegate { List<string> list = fetcher.Invoke(); list.AddRange(Enumerable.Select(skills.Values, (Skill skill) => skill.internalSkillName)); return list; }; } } private static SkillDef? GetSkillDef(SkillType skillType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!skills.ContainsKey(skillType)) { return null; } return skills[skillType].skillDef; } private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream); return memoryStream.ToArray(); } private static Texture2D loadTexture(string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name)); return val; } private static Sprite loadSprite(string name, int width, int height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero); } private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description) { ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry<T> config<T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } } [PublicAPI] internal static class SkillExtensions { public static float GetSkillFactor(this Character character, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static float GetSkillFactor(this Skills skills, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static void RaiseSkill(this Character character, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) character.RaiseSkill(Skill.fromName(name), value); } public static void RaiseSkill(this Skills skill, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) skill.RaiseSkill(Skill.fromName(name), value); } public static void LowerSkill(this Character character, string name, float factor = 1f) { character.GetSkills().LowerSkill(name, factor); } public static void LowerSkill(this Skills skills, string name, float factor) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (factor > 0f && skills.m_skillData.TryGetValue(Skill.fromName(name), out var value)) { Skill obj = value; obj.m_level -= value.m_level * factor; value.m_accumulator = 0f; } } } } namespace ServerSync { [PublicAPI] internal abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] internal class SyncedConfigEntry<T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] internal class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = Enumerable.First(configSyncs); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!Enumerable.SequenceEqual(adminList.GetList(), CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = Enumerable.ToList(Enumerable.Where(ZNet.instance.GetPeers(), delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); })); List<ZNetPeer> nonAdminPeer = Enumerable.ToList(Enumerable.Except(ZNet.instance.GetPeers(), adminPeer)); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>(); public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPriority(800)] [HarmonyPrefix] private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (__instance.IsServer()) { BufferingSocket value = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = value; } } [HarmonyPostfix] private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary<Assembly, BufferingSocket> __state2 = __state; ZNetPeer peer; if (__instance2.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance2).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc2.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List<PackageEntry> entries = new List<PackageEntry>(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc2.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(Enumerable.Select(configSync.allConfigs, (OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package)); } SendBufferedData(); } } } private class PackageEntry { public string section = null; public string key = null; public Type type = null; public object? value; } [HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")] private static class PreventSavingServerInfo { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, ref string __result) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase)) { return true; } __result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType); return false; } } [HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")] private static class PreventConfigRereadChangingValues { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, string value) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null) { return true; } try { ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType); } catch (Exception ex) { Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}"); } return false; } } private class InvalidDeserializationTypeException : Exception { public string expected = null; public string received = null; public string field = ""; } public static bool ProcessingServerUpdate; public readonly string Name; public string? DisplayName; public string? CurrentVersion; public string? MinimumRequiredVersion; public bool ModRequired = false; private bool? forceConfigLocking; private bool isSourceOfTruth = true; private static readonly HashSet<ConfigSync> configSyncs; private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>(); private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>(); private static bool isServer; private static bool lockExempt; private OwnConfigEntryBase? lockedConfig = null; private const byte PARTIAL_CONFIGS = 1; private const byte FRAGMENTED_CONFIG = 2; private const byte COMPRESSED_CONFIG = 4; private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>(); private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>(); private static long packageCounter; public bool IsLocked { get { bool? flag = forceConfigLocking; bool num; if (!flag.HasValue) { if (lockedConfig == null) { goto IL_0052; } num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0; } else { num = flag.GetValueOrDefault(); } if (!num) { goto IL_0052; } int result = ((!lockExempt) ? 1 : 0); goto IL_0053; IL_0053: return (byte)result != 0; IL_0052: result = 0; goto IL_0053; } set { forceConfigLocking = value; } } public bool IsAdmin => lockExempt || isSourceOfTruth; public bool IsSourceOfTruth { get { return isSourceOfTruth; } private set { if (value != isSourceOfTruth) { isSourceOfTruth = value; this.SourceOfTruthChanged?.Invoke(value); } } } public bool InitialSyncDone { get; private set; } = false; public event Action<bool>? SourceOfTruthChanged; private event Action? lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet<ConfigSync>(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry) { ConfigEntry<T> configEntry2 = configEntry; OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2); SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry<T>(configEntry2); AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, Enumerable.ToArray(Enumerable.Concat(Enumerable.Concat(new object[1] { new ConfigurationManagerAttributes() }, ((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()), new SyncedConfigEntry<T>[1] { syncedEntry }))); configEntry2.SettingChanged += delegate { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry<T>(lockingConfig); lockingConfig.SettingChanged += delegate { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry<T>)lockedConfig; } internal void AddCustomValue(CustomSyncedValueBase customValue) { CustomSyncedValueBase customValue2 = customValue; if (Enumerable.Contains(Enumerable.Concat(Enumerable.Select(allCustomValues, (CustomSyncedValueBase v) => v.Identifier), new string[1] { "serverversion" }), customValue2.Identifier)) { throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)"); } allCustomValues.Add(customValue2); allCustomValues = new HashSet<CustomSyncedValueBase>(Enumerable.OrderByDescending(allCustomValues, (CustomSyncedValueBase v) => v.Priority)); customValue2.ValueChanged += delegate { if (!ProcessingServerUpdate) { Broadcast(ZRoutedRpc.Everybody, customValue2); } }; } private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package) { lockedConfigChanged += serverLockedSettingChanged; IsSourceOfTruth = false; if (HandleConfigSyncRPC(0L, package, clientUpdate: false)) { InitialSyncDone = true; } } private void RPC_FromOtherClientConfigSync(long sender, ZPackage package) { HandleConfigSyncRPC(sender, package, clientUpdate: true); } private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown try { if (isServer && IsLocked) { ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc; object obj; if (currentRpc == null) { obj = null; } else { ISocket socket = currentRpc.GetSocket(); obj = ((socket != null) ? socket.GetHostName() : null); } string text = (string)obj; if (text != null) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2