using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Mirror; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("BigWalkLeash")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BigWalkLeash")] [assembly: AssemblyTitle("BigWalkLeash")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace BigWalkLeash; internal static class LeashConfig { private static ConfigFile file; internal static ConfigEntry ToggleKey; internal static ConfigEntry EmergencyReleaseKey; internal static ConfigEntry DebugPreviewKey; internal static ConfigEntry DebugFirstPersonPreviewKey; internal static ConfigEntry ColourMenuKey; internal static ConfigEntry LeashLength; internal static ConfigEntry AttachRange; internal static ConfigEntry PullStrength; internal static ConfigEntry RopeWidth; internal static ConfigEntry ShowCollar; internal static ConfigEntry CollarRadius; internal static ConfigEntry CollarHeightOffset; internal static ConfigEntry CollarDepthOffset; internal static ConfigEntry CollarDepthFineTune; internal static ConfigEntry CrouchHorizontalFollow; internal static ConfigEntry JumpHorizontalFollow; internal static ConfigEntry CrouchTiltDegrees; internal static ConfigEntry CollarTiltFollow; internal static ConfigEntry LeashColourRed; internal static ConfigEntry LeashColourGreen; internal static ConfigEntry LeashColourBlue; internal static ConfigEntry LocalFirstPersonCollarScale; internal static ConfigEntry ColourMenuScale; internal static ConfigEntry LocalFirstPersonAnchorHeight; internal static ConfigEntry LocalFirstPersonAnchorBehind; internal static Color LeashColour => new Color(LeashColourRed.Value, LeashColourGreen.Value, LeashColourBlue.Value, 1f); internal static void Bind(ConfigFile config) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Expected O, but got Unknown //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Expected O, but got Unknown //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Expected O, but got Unknown //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Expected O, but got Unknown //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Expected O, but got Unknown //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Expected O, but got Unknown //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Expected O, but got Unknown file = config; ToggleKey = config.Bind("Controls", "AttachOrRelease", (KeyCode)108, "Look at a nearby friend and press this key to attach a leash. Press it again to release your leash."); EmergencyReleaseKey = config.Bind("Controls", "EmergencyRelease", (KeyCode)8, "The leashed player can always press this key to immediately remove their leash."); DebugPreviewKey = config.Bind("Debug", "ToggleSelfPreview", (KeyCode)289, "Toggles a local-only preview rope between your right hand and your own neck. It does not affect movement or other players."); DebugFirstPersonPreviewKey = config.Bind("Debug", "ToggleFirstPersonPreview", (KeyCode)290, "Toggles a local-only preview using the same hidden first-person rope endpoint."); ColourMenuKey = config.Bind("Controls", "OpenColourMenu", (KeyCode)288, "Opens the in-game leash colour panel."); LeashLength = config.Bind("Host settings", "LeashLengthMetres", 5f, new ConfigDescription("Maximum separation. The host's value is used for the whole walk.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f), Array.Empty())); AttachRange = config.Bind("Host settings", "AttachRangeMetres", 4f, new ConfigDescription("How close a player must be before a leash can be attached.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 8f), Array.Empty())); PullStrength = config.Bind("Host settings", "PullBackStrength", 18f, new ConfigDescription("How quickly the leashed player is corrected when reaching the end.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 60f), Array.Empty())); RopeWidth = config.Bind("Visuals", "RopeWidth", 0.045f, new ConfigDescription("Thickness of the visible rope.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 0.2f), Array.Empty())); ShowCollar = config.Bind("Visuals", "ShowCollar", true, "Show a soft orange collar on the leashed player."); CollarRadius = config.Bind("Visuals", "CollarRadius", 0.11f, new ConfigDescription("Radius of the visible neck collar.", (AcceptableValueBase)(object)new AcceptableValueRange(0.06f, 0.35f), Array.Empty())); CollarHeightOffset = config.Bind("Visuals", "CollarHeightOffset", -0.005f, new ConfigDescription("Fine-tunes the collar height. Zero is the tested neck position.", (AcceptableValueBase)(object)new AcceptableValueRange(-0.5f, 1.5f), Array.Empty())); CollarDepthOffset = config.Bind("Visuals", "CollarDepthOffset", 0.02f, new ConfigDescription("Moves the collar forward (positive) or backward (negative).", (AcceptableValueBase)(object)new AcceptableValueRange(-0.5f, 0.5f), Array.Empty())); CollarDepthFineTune = config.Bind("Visuals", "CollarDepthFineTune", 0f, new ConfigDescription("Extra depth adjustment in tiny 0.001-unit steps. Keep the main depth value as your working baseline.", (AcceptableValueBase)(object)new AcceptableValueRange(-50f, 50f), Array.Empty())); CrouchHorizontalFollow = config.Bind("Visuals", "CrouchHorizontalFollow", 0.5f, new ConfigDescription("How much the collar follows the head's forward/back movement while crouching. 0 locks it to the neck; 1 fully follows the head.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); JumpHorizontalFollow = config.Bind("Visuals", "JumpHorizontalFollow", 0.5f, new ConfigDescription("How much the collar follows the head's forward/back movement while jumping. 0 locks it to the neck; 1 fully follows the head.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); CrouchTiltDegrees = config.Bind("Visuals", "CrouchTiltDegrees", 12f, new ConfigDescription("Extra forward tilt applied at a full crouch, because the crouch pose does not rotate the head bone.", (AcceptableValueBase)(object)new AcceptableValueRange(-45f, 45f), Array.Empty())); CollarTiltFollow = config.Bind("Visuals", "CollarTiltFollow", 0.5f, new ConfigDescription("How much the collar tilts with the head. 0 stays level; 1 fully follows the head tilt.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); LeashColourRed = config.Bind("Colour", "Red", 0.95f, new ConfigDescription("Leash colour red component.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); LeashColourGreen = config.Bind("Colour", "Green", 0.45f, new ConfigDescription("Leash colour green component.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); LeashColourBlue = config.Bind("Colour", "Blue", 0.08f, new ConfigDescription("Leash colour blue component.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); LocalFirstPersonCollarScale = config.Bind("Visuals", "LocalFirstPersonCollarScale", 0.5f, new ConfigDescription("Scale of your own collar in first-person view. Other players always see the normal size.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f), Array.Empty())); ColourMenuScale = config.Bind("Colour", "MenuScale", 1.6f, new ConfigDescription("Scale of the in-game F7 colour panel.", (AcceptableValueBase)(object)new AcceptableValueRange(0.75f, 3f), Array.Empty())); LocalFirstPersonAnchorHeight = config.Bind("Visuals", "LocalFirstPersonAnchorHeight", -0.3f, new ConfigDescription("Moves only your own first-person rope endpoint up or down from the camera.", (AcceptableValueBase)(object)new AcceptableValueRange(-1f, 1f), Array.Empty())); LocalFirstPersonAnchorBehind = config.Bind("Visuals", "LocalFirstPersonAnchorBehind", 1.2f, new ConfigDescription("Moves only your own first-person rope endpoint behind the camera.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1.5f), Array.Empty())); } internal static void ReloadFromDisk() { file.Reload(); } internal static void SetLeashColour(float red, float green, float blue) { LeashColourRed.Value = Mathf.Clamp01(red); LeashColourGreen.Value = Mathf.Clamp01(green); LeashColourBlue.Value = Mathf.Clamp01(blue); } } public sealed class LeashController : MonoBehaviour { private sealed class RopeVisual { private const float NeckHeightBaseline = -0.19f; private readonly GameObject ropeObject; private readonly LineRenderer rope; private readonly GameObject collarObject; private readonly LineRenderer collar; private Transform collarBone; private PlayerCharacter holder; private Vector3 end; private Vector3 collarOffsetFromBone; private bool hasStandingBonePosition; private Vector3 standingBoneLocalPosition; private float standingCalibrationTime; private Vector3 standingOffsetTotal; private int standingOffsetSamples; internal RopeVisual() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown ropeObject = new GameObject("Big Walk Leash Rope"); Object.DontDestroyOnLoad((Object)(object)ropeObject); rope = ropeObject.AddComponent(); rope.positionCount = 20; rope.numCapVertices = 3; rope.widthMultiplier = LeashConfig.RopeWidth.Value; ((Renderer)rope).material = new Material(Shader.Find("Sprites/Default")); collarObject = new GameObject("Big Walk Leash Collar"); Object.DontDestroyOnLoad((Object)(object)collarObject); collar = collarObject.AddComponent(); collar.positionCount = 20; collar.loop = true; collar.useWorldSpace = false; collar.numCapVertices = 3; collar.widthMultiplier = 0.035f; ((Renderer)collar).material = new Material(Shader.Find("Sprites/Default")); } internal void Draw(PlayerCharacter holder, PlayerCharacter target, Color colour, bool useFirstPersonAnchor, bool forceFirstPersonAnchor) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_002d: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_036f: 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_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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_01d8: 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_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) this.holder = holder; bool flag = forceFirstPersonAnchor || (useFirstPersonAnchor && IsLocalFirstPerson(target)); Transform hand = GetHand(holder); Vector3 start = (((Object)(object)hand == (Object)null) ? (holder.kernal.position + Vector3.up * 0.8f) : hand.position); Transform val = ((target.head == null) ? null : target.head.cameraUprighter); float num = ((target.croucher == null) ? 0f : (target.croucher.smoothedCrouchness * target.croucher.crouchCameraOffset)); float num2 = ((target.croucher == null) ? 0f : target.croucher.smoothedCrouchness); float num3 = -0.19f + LeashConfig.CollarHeightOffset.Value - num; Vector3 val2 = (((Object)(object)val == (Object)null) ? (target.kernal.position + Vector3.up * (1.7f - num)) : (val.position + Vector3.up * num3)); Transform val3 = ((target.registry == null) ? null : target.registry.headBone); Transform kernal = target.kernal; Vector3 val4 = val2; if ((Object)(object)val3 != (Object)null) { if ((Object)(object)collarBone != (Object)(object)val3) { hasStandingBonePosition = false; standingCalibrationTime = 0f; standingOffsetTotal = Vector3.zero; standingOffsetSamples = 0; } Vector3 val5 = target.kernal.InverseTransformPoint(val3.position); bool flag2 = target.ground != null && target.ground.isGrounded; if (!hasStandingBonePosition && num2 < 0.01f && flag2) { collarBone = val3; collarOffsetFromBone = Quaternion.Inverse(LevelRotation(target.kernal)) * (val2 - val3.position); standingBoneLocalPosition = val5; hasStandingBonePosition = true; } if (hasStandingBonePosition && num2 < 0.01f && flag2 && standingCalibrationTime < 1f) { Vector3 val6 = Quaternion.Inverse(LevelRotation(target.kernal)) * (val2 - val3.position); standingOffsetTotal += val6; standingOffsetSamples++; collarOffsetFromBone = standingOffsetTotal / (float)standingOffsetSamples; standingCalibrationTime += Time.deltaTime; } val4 = (((Object)(object)collarBone == (Object)(object)val3 && hasStandingBonePosition) ? (val3.position + LevelRotation(target.kernal) * collarOffsetFromBone) : val2); if (hasStandingBonePosition && !(num2 < 0.01f && flag2)) { Vector3 val7 = val5 - standingBoneLocalPosition; val7.y = 0f; float num4 = ((num2 >= 0.01f) ? LeashConfig.CrouchHorizontalFollow.Value : ((!flag2) ? LeashConfig.JumpHorizontalFollow.Value : 1f)); val4 -= LevelRotation(target.kernal) * val7 * (1f - num4); } } Quaternion val8 = LevelRotation(kernal); Quaternion val9 = (((Object)(object)val3 == (Object)null) ? val8 : Quaternion.Slerp(val8, val3.rotation, LeashConfig.CollarTiltFollow.Value)); if (num2 > 0.01f) { val9 = Quaternion.AngleAxis(LeashConfig.CrouchTiltDegrees.Value * num2, val8 * Vector3.right) * val9; } if (flag) { val4 = ViewTransform(target).position + Vector3.up * LeashConfig.LocalFirstPersonAnchorHeight.Value - LevelRotation(target.kernal) * Vector3.forward * LeashConfig.LocalFirstPersonAnchorBehind.Value; } else { float num5 = LeashConfig.CollarDepthOffset.Value + LeashConfig.CollarDepthFineTune.Value * 0.001f; val4 += val9 * Vector3.forward * num5; } Vector3 val10 = -(val9 * Vector3.forward); float num6 = (flag ? LeashConfig.LocalFirstPersonCollarScale.Value : 1f); float num7 = LeashConfig.CollarRadius.Value * num6; end = (flag ? val4 : (val4 + val10 * num7)); rope.widthMultiplier = LeashConfig.RopeWidth.Value; rope.startColor = colour; rope.endColor = colour; collar.startColor = colour; collar.endColor = colour; DrawRope(start); bool flag3 = LeashConfig.ShowCollar.Value && !flag; collarObject.SetActive(flag3); if (flag3) { collarObject.transform.SetPositionAndRotation(val4, val9); collar.widthMultiplier = 0.035f * num6; float num8 = num7; for (int i = 0; i < collar.positionCount; i++) { float num9 = (float)i / (float)collar.positionCount * (float)Math.PI * 2f; collar.SetPosition(i, new Vector3(Mathf.Cos(num9), 0f, Mathf.Sin(num9)) * num8); } } } internal void RefreshHandAnchor(PlayerCharacter player) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)holder != (Object)(object)player)) { Transform hand = GetHand(holder); if ((Object)(object)hand != (Object)null) { DrawRope(hand.position); } } } internal void Dispose() { Object.Destroy((Object)(object)ropeObject); Object.Destroy((Object)(object)collarObject); } private void DrawRope(Vector3 start) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < rope.positionCount; i++) { float num = (float)i / (float)(rope.positionCount - 1); float num2 = Mathf.Sin(num * (float)Math.PI) * 0.13f; rope.SetPosition(i, Vector3.Lerp(start, end, num) + Vector3.down * num2); } } private static Quaternion LevelRotation(Transform body) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(body.forward, Vector3.up); if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f)) { return Quaternion.identity; } return Quaternion.LookRotation(val, Vector3.up); } private static bool IsLocalFirstPerson(PlayerCharacter target) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)target).isLocalPlayer) { return false; } Transform val = ViewTransform(target); if ((Object)(object)val == (Object)null) { return false; } Transform val2 = ((target.registry == null) ? null : target.registry.headBone); Vector3 val3 = (((Object)(object)val2 == (Object)null) ? (target.kernal.position + Vector3.up * 1.5f) : val2.position); return Vector3.Distance(val.position, val3) < 1.1f; } private static Transform ViewTransform(PlayerCharacter target) { if (!((Object)(object)Camera.main == (Object)null)) { return ((Component)Camera.main).transform; } return target.cameraTransform; } private static Transform GetHand(PlayerCharacter holder) { if (holder.arms == null) { return null; } if (((NetworkBehaviour)holder).isLocalPlayer) { LimbSpline localRightArmSpline = holder.arms.localRightArmSpline; return ((localRightArmSpline != null) ? localRightArmSpline.endTransform : null) ?? holder.arms.localRightHand ?? holder.arms.rightHand; } LimbSpline rightArmLimbSpline = holder.arms.rightArmLimbSpline; return ((rightArmLimbSpline != null) ? rightArmLimbSpline.endTransform : null) ?? holder.arms.rightHand ?? holder.arms.localRightHand; } } private const uint DebugPreviewId = uint.MaxValue; private static LeashController instance; private readonly Dictionary visuals = new Dictionary(); private float nextStateBroadcast; private bool debugPreview; private bool firstPersonPreview; private bool showColourMenu; private float colourRed; private float colourGreen; private float colourBlue; private float leashLimit; private bool wasNetworkActive; public LeashController(IntPtr pointer) : base(pointer) { } private void Awake() { instance = this; } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } private void Update() { HandleControls(); if (NetworkClient.active || NetworkServer.active) { wasNetworkActive = true; } else if (wasNetworkActive) { LeashState.Clear(); wasNetworkActive = false; } if (NetworkServer.active && Time.unscaledTime >= nextStateBroadcast) { nextStateBroadcast = Time.unscaledTime + 5f; LeashNet.RebroadcastCurrentLinks(); } } private void LateUpdate() { UpdateVisuals(); } internal static void RefreshHandAnchor(PlayerArms arms) { if ((Object)(object)instance == (Object)null || arms == null || (Object)(object)arms.playerCharacter == (Object)null) { return; } foreach (RopeVisual value in instance.visuals.Values) { value.RefreshHandAnchor(arms.playerCharacter); } } private void OnGUI() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (!showColourMenu) { return; } Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.Scale(Vector3.one * LeashConfig.ColourMenuScale.Value); GUILayout.BeginArea(new Rect(20f, 20f, 290f, 270f), "Big Walk Leash — Colour", GUI.skin.window); GUILayout.Label("Red", (Il2CppReferenceArray)null); colourRed = GUILayout.HorizontalSlider(colourRed, 0f, 1f, Array.Empty()); GUILayout.Label("Green", (Il2CppReferenceArray)null); colourGreen = GUILayout.HorizontalSlider(colourGreen, 0f, 1f, Array.Empty()); GUILayout.Label("Blue", (Il2CppReferenceArray)null); colourBlue = GUILayout.HorizontalSlider(colourBlue, 0f, 1f, Array.Empty()); GUILayout.Space(6f); GUILayout.Label($"Max leash length: {leashLimit:0.0}m", (Il2CppReferenceArray)null); leashLimit = GUILayout.HorizontalSlider(leashLimit, 1f, 20f, Array.Empty()); GUILayout.Space(8f); if (GUILayout.Button("Apply colour", (Il2CppReferenceArray)null)) { LeashConfig.SetLeashColour(colourRed, colourGreen, colourBlue); LeashConfig.LeashLength.Value = leashLimit; if (TryGetLocalNetId(out var netId)) { LeashNet.RequestColourUpdate(netId); LeashNet.RequestLengthUpdate(netId, leashLimit); } } if (GUILayout.Button("Close", (Il2CppReferenceArray)null)) { showColourMenu = false; } GUILayout.EndArea(); GUI.matrix = matrix; } private void HandleControls() { //IL_0019: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) if (!TryFindLocalPlayer(out var player) || !TryGetNetId(player, out var netId)) { return; } LeashLink link; LeashLink link2; LeashLink link3; if (Input.GetKeyDown(LeashConfig.ColourMenuKey.Value)) { LeashConfig.ReloadFromDisk(); showColourMenu = !showColourMenu; colourRed = LeashConfig.LeashColourRed.Value; colourGreen = LeashConfig.LeashColourGreen.Value; colourBlue = LeashConfig.LeashColourBlue.Value; leashLimit = LeashConfig.LeashLength.Value; } else if (Input.GetKeyDown(LeashConfig.DebugPreviewKey.Value)) { LeashConfig.ReloadFromDisk(); debugPreview = !debugPreview; if (debugPreview) { firstPersonPreview = false; } Plugin.Log.LogInfo((object)(debugPreview ? "Self-preview leash enabled." : "Self-preview leash disabled.")); } else if (Input.GetKeyDown(LeashConfig.DebugFirstPersonPreviewKey.Value)) { LeashConfig.ReloadFromDisk(); firstPersonPreview = !firstPersonPreview; if (firstPersonPreview) { debugPreview = false; } Plugin.Log.LogInfo((object)(firstPersonPreview ? "First-person preview leash enabled." : "First-person preview leash disabled.")); } else if (Input.GetKeyDown(LeashConfig.EmergencyReleaseKey.Value) && LeashState.TryGetForTarget(netId, out link)) { LeashNet.RequestRelease(link.HolderId, link.TargetId); } else if (LeashState.TryGetForTarget(netId, out link2)) { if (Input.GetKeyDown(LeashConfig.ToggleKey.Value)) { Plugin.Log.LogInfo((object)"Leashed players cannot hold a leash."); } } else if (LeashState.TryGetForHolder(netId, out link3)) { if (!showColourMenu) { float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.001f) { float length = Mathf.Clamp(link3.Length + y * 0.25f, 1f, LeashConfig.LeashLength.Value); LeashNet.RequestLengthUpdate(netId, length); } } if (Input.GetKeyDown(LeashConfig.ToggleKey.Value)) { LeashNet.RequestRelease(link3.HolderId, link3.TargetId); } } else if (Input.GetKeyDown(LeashConfig.ToggleKey.Value)) { PlayerCharacter val = FindPlayerYouAreLookingAt(player); if ((Object)(object)val == (Object)null || !TryGetNetId(val, out var netId2)) { Plugin.Log.LogInfo((object)"No nearby player in view to leash."); } else { LeashNet.RequestAttach(netId, netId2); } } } private static PlayerCharacter FindPlayerYouAreLookingAt(PlayerCharacter local) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0093: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)local.cameraTransform == (Object)null || (Object)(object)local.kernal == (Object)null || PlayerCharacter.allPlayerCharacters == null) { return null; } Vector3 position = local.cameraTransform.position; Vector3 forward = local.cameraTransform.forward; float num = 0.8f; PlayerCharacter result = null; List allPlayerCharacters = PlayerCharacter.allPlayerCharacters; for (int i = 0; i < allPlayerCharacters.Count; i++) { PlayerCharacter val = allPlayerCharacters[i]; if (!IsAlive(val) || (Object)(object)val == (Object)(object)local || (Object)(object)val.kernal == (Object)null) { continue; } Vector3 val2 = val.kernal.position - position; float magnitude = ((Vector3)(ref val2)).magnitude; if (!(magnitude > LeashConfig.AttachRange.Value) && !(magnitude < 0.01f)) { float num2 = Vector3.Dot(forward, val2 / magnitude); if (num2 > num) { num = num2; result = val; } } } return result; } private void UpdateVisuals() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); foreach (LeashLink item in LeashState.All) { hashSet.Add(item.TargetId); if (TryFindPlayer(item.HolderId, out var player) && TryFindPlayer(item.TargetId, out var player2)) { if (!visuals.TryGetValue(item.TargetId, out var value)) { value = new RopeVisual(); visuals.Add(item.TargetId, value); } value.Draw(player, player2, item.Colour, useFirstPersonAnchor: true, forceFirstPersonAnchor: false); } } PlayerCharacter player4; if (debugPreview && TryFindLocalPlayer(out var player3)) { hashSet.Add(uint.MaxValue); if (!visuals.TryGetValue(uint.MaxValue, out var value2)) { value2 = new RopeVisual(); visuals.Add(uint.MaxValue, value2); } value2.Draw(player3, player3, LeashConfig.LeashColour, useFirstPersonAnchor: false, forceFirstPersonAnchor: false); } else if (firstPersonPreview && TryFindLocalPlayer(out player4)) { hashSet.Add(uint.MaxValue); if (!visuals.TryGetValue(uint.MaxValue, out var value3)) { value3 = new RopeVisual(); visuals.Add(uint.MaxValue, value3); } value3.Draw(player4, player4, LeashConfig.LeashColour, useFirstPersonAnchor: true, forceFirstPersonAnchor: true); } List list = new List(); foreach (KeyValuePair visual in visuals) { if (!hashSet.Contains(visual.Key)) { visual.Value.Dispose(); list.Add(visual.Key); } } foreach (uint item2 in list) { visuals.Remove(item2); } } internal static void EnforceDistance(PlayerMover mover) { //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_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_0081: 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) //IL_00a5: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) PlayerCharacter pc = mover.pc; if (!IsAlive(pc) || !((NetworkBehaviour)pc).isLocalPlayer || !TryGetNetId(pc, out var netId) || !LeashState.TryGetForTarget(netId, out var link) || !TryFindPlayer(link.HolderId, out var player) || (Object)(object)pc.kernal == (Object)null || (Object)(object)player.kernal == (Object)null || (Object)(object)pc.rb == (Object)null) { return; } Vector3 position = player.kernal.position; Vector3 val = pc.kernal.position - position; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude <= link.Length) && !(magnitude < 0.001f)) { Vector3 val2 = val / magnitude; Vector3 val3 = pc.rb.linearVelocity; float num = Vector3.Dot(val3, val2); if (num > 0f) { val3 -= val2 * num; } float num2 = Mathf.Min((magnitude - link.Length) * LeashConfig.PullStrength.Value, LeashConfig.PullStrength.Value); pc.rb.linearVelocity = val3 - val2 * num2; } } internal static bool TryFindPlayer(uint netId, out PlayerCharacter player) { player = null; List allPlayerCharacters = PlayerCharacter.allPlayerCharacters; if (allPlayerCharacters == null) { return false; } for (int i = 0; i < allPlayerCharacters.Count; i++) { PlayerCharacter val = allPlayerCharacters[i]; if (IsAlive(val) && TryGetNetId(val, out var netId2) && netId2 == netId) { player = val; return true; } } return false; } private static bool TryFindLocalPlayer(out PlayerCharacter player) { player = null; List allPlayerCharacters = PlayerCharacter.allPlayerCharacters; if (allPlayerCharacters == null) { return false; } for (int i = 0; i < allPlayerCharacters.Count; i++) { PlayerCharacter val = allPlayerCharacters[i]; if (IsAlive(val) && ((NetworkBehaviour)val).isLocalPlayer) { player = val; return true; } } return false; } internal static bool TryGetLocalNetId(out uint netId) { netId = 0u; if (TryFindLocalPlayer(out var player)) { return TryGetNetId(player, out netId); } return false; } internal static bool IsLeashed(PlayerCharacter player) { LeashLink link; if (TryGetNetId(player, out var netId)) { return LeashState.TryGetForTarget(netId, out link); } return false; } private static bool TryGetNetId(PlayerCharacter player, out uint netId) { netId = 0u; if (!IsAlive(player) || (Object)(object)player.playerNetworking == (Object)null) { return false; } netId = ((NetworkBehaviour)player.playerNetworking).netId; return netId != 0; } private static bool IsAlive(PlayerCharacter player) { return (Object)(object)player != (Object)null; } } [HarmonyPatch(typeof(PlayerTexter), "CompleteInput")] internal static class LeashedChatPatch { private static bool barkNext; [HarmonyPrefix] private static void BeforeSend(PlayerTexter __instance, ref string message) { if (!((Object)(object)__instance.playerCharacter == (Object)null) && LeashController.IsLeashed(__instance.playerCharacter)) { message = (barkNext ? "bark" : "woof"); barkNext = !barkNext; } } } internal static class LeashNet { private const ushort FunctionHash = 52193; private const uint Magic = 1280526385u; private const byte Protocol = 3; private const byte AttachRequest = 1; private const byte ReleaseRequest = 2; private const byte SyncAttach = 3; private const byte SyncRelease = 4; private const byte ColourRequest = 5; private const byte LengthRequest = 6; private const int PayloadSize = 21; private static MethodInfo bufferRpc; internal static void Install(Harmony harmony) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkServer), "OnCommandMessage", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LeashNet), "OnCommandMessage", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(NetworkClient), "OnRPCMessage", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LeashNet), "OnRpcMessage", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); bufferRpc = AccessTools.Method(typeof(NetworkConnectionToClient), "BufferRpc", new Type[2] { typeof(RpcMessage), typeof(int) }, (Type[])null); if (bufferRpc == null) { Plugin.Log.LogError((object)"Could not access Mirror's RPC relay; leash links will not synchronize."); } } internal static void RequestAttach(uint holderId, uint targetId) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { AttachOnServer(holderId, targetId, LeashConfig.LeashColour, LeashConfig.LeashLength.Value); } else { SendCommand(1, holderId, targetId, LeashConfig.LeashLength.Value, LeashConfig.LeashColour); } } internal static void RequestRelease(uint holderId, uint targetId) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { ReleaseOnServer(holderId, targetId); } else { SendCommand(2, holderId, targetId, 0f, Color.white); } } internal static void RequestColourUpdate(uint holderId) { //IL_0031: 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) if (LeashState.TryGetForHolder(holderId, out var link)) { if (NetworkServer.active) { UpdateColourOnServer(holderId, link.TargetId, LeashConfig.LeashColour); } else { SendCommand(5, holderId, link.TargetId, 0f, LeashConfig.LeashColour); } } } internal static void RequestLengthUpdate(uint holderId, float length) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (LeashState.TryGetForHolder(holderId, out var link)) { if (NetworkServer.active) { UpdateLengthOnServer(holderId, link.TargetId, length); } else { SendCommand(6, holderId, link.TargetId, length, Color.white); } } } internal static void RebroadcastCurrentLinks() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } foreach (LeashLink item in LeashState.All) { Relay(3, item.HolderId, item.TargetId, item.Length, item.Colour); } } private static void SendCommand(byte packetType, uint holderId, uint targetId, float length, Color colour) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!NetworkClient.active || NetworkClient.connection == null) { return; } NetworkWriterPooled val = NetworkWriterPool.Get(); try { NetworkWriterExtensions.WriteUShort((NetworkWriter)(object)val, NetworkMessages.GetId()); NetworkWriterExtensions.WriteUInt((NetworkWriter)(object)val, holderId); ((NetworkWriter)val).WriteByte((byte)0); NetworkWriterExtensions.WriteUShort((NetworkWriter)(object)val, (ushort)52193); NetworkWriterExtensions.WriteBytesAndSize((NetworkWriter)(object)val, BuildPayload(packetType, holderId, targetId, length, colour)); NetworkClient.connection.Send(((NetworkWriter)val).ToArraySegment(), Channels.Reliable); } finally { NetworkWriterPool.Return(val); } } private static Il2CppStructArray BuildPayload(byte packetType, uint holderId, uint targetId, float length, Color colour) { //IL_0035: 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_0071: Unknown result type (might be due to invalid IL or missing references) NetworkWriterPooled val = NetworkWriterPool.Get(); try { NetworkWriterExtensions.WriteUInt((NetworkWriter)(object)val, 1280526385u); ((NetworkWriter)val).WriteByte((byte)3); ((NetworkWriter)val).WriteByte(packetType); NetworkWriterExtensions.WriteUInt((NetworkWriter)(object)val, holderId); NetworkWriterExtensions.WriteUInt((NetworkWriter)(object)val, targetId); NetworkWriterExtensions.WriteFloat((NetworkWriter)(object)val, length); ((NetworkWriter)val).WriteByte((byte)Mathf.RoundToInt(Mathf.Clamp01(colour.r) * 255f)); ((NetworkWriter)val).WriteByte((byte)Mathf.RoundToInt(Mathf.Clamp01(colour.g) * 255f)); ((NetworkWriter)val).WriteByte((byte)Mathf.RoundToInt(Mathf.Clamp01(colour.b) * 255f)); return ((NetworkWriter)val).ToArray(); } finally { NetworkWriterPool.Return(val); } } private static bool TryRead(ArraySegment payload, out NetworkReader reader, out byte packetType, out uint holderId, out uint targetId, out float length, out Color colour) { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) reader = null; packetType = 0; holderId = 0u; targetId = 0u; length = 0f; colour = Color.white; if (payload.Count < 21) { return false; } reader = new NetworkReader(payload); if (NetworkReaderExtensions.ReadUInt(reader) != 1280526385 || reader.ReadByte() != 3) { return false; } packetType = reader.ReadByte(); holderId = NetworkReaderExtensions.ReadUInt(reader); targetId = NetworkReaderExtensions.ReadUInt(reader); length = NetworkReaderExtensions.ReadFloat(reader); colour = new Color((float)(int)reader.ReadByte() / 255f, (float)(int)reader.ReadByte() / 255f, (float)(int)reader.ReadByte() / 255f, 1f); return float.IsFinite(length); } private static bool OnCommandMessage(NetworkConnectionToClient conn, CommandMessage msg, int channelId) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (msg.functionHash != 52193) { return true; } if (!TryRead(msg.payload, out var _, out var packetType, out var holderId, out var targetId, out var length, out var colour)) { return false; } NetworkIdentity identity = ((NetworkConnection)conn).identity; if ((Object)(object)identity == (Object)null || identity.netId != msg.netId) { return false; } switch (packetType) { case 1: if (identity.netId != holderId) { return false; } AttachOnServer(holderId, targetId, colour, length); return false; case 2: if (identity.netId != holderId && identity.netId != targetId) { return false; } ReleaseOnServer(holderId, targetId); return false; case 5: if (identity.netId != holderId) { return false; } UpdateColourOnServer(holderId, targetId, colour); return false; case 6: if (identity.netId != holderId) { return false; } UpdateLengthOnServer(holderId, targetId, length); return false; default: return false; } } private static bool OnRpcMessage(RpcMessage message) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (message.functionHash != 52193) { return true; } if (!TryRead(message.payload, out var _, out var packetType, out var holderId, out var targetId, out var length, out var colour)) { return false; } switch (packetType) { case 3: LeashState.Set(holderId, targetId, length, colour); return false; case 4: LeashState.Remove(holderId, targetId); return false; default: return false; } } private static void AttachOnServer(uint holderId, uint targetId, Color colour, float requestedLength) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (holderId != 0 && holderId != targetId && LeashController.TryFindPlayer(holderId, out var player) && LeashController.TryFindPlayer(targetId, out var player2)) { Transform kernal = player.kernal; Transform kernal2 = player2.kernal; if (!((Object)(object)kernal == (Object)null) && !((Object)(object)kernal2 == (Object)null) && !(Vector3.Distance(kernal.position, kernal2.position) > LeashConfig.AttachRange.Value)) { float length = Mathf.Clamp(requestedLength, 1f, 20f); LeashState.Set(holderId, targetId, length, colour); Relay(3, holderId, targetId, length, colour); } } } private static void ReleaseOnServer(uint holderId, uint targetId) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (LeashState.TryGetForTarget(targetId, out var link) && link.HolderId == holderId) { LeashState.Remove(holderId, targetId); Relay(4, holderId, targetId, 0f, Color.white); } } private static void UpdateColourOnServer(uint holderId, uint targetId, Color colour) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (LeashState.TryGetForTarget(targetId, out var link) && link.HolderId == holderId) { LeashState.Set(holderId, targetId, link.Length, colour); Relay(3, holderId, targetId, link.Length, colour); } } private static void UpdateLengthOnServer(uint holderId, uint targetId, float length) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (LeashState.TryGetForTarget(targetId, out var link) && link.HolderId == holderId) { float length2 = Mathf.Clamp(length, 1f, 20f); LeashState.Set(holderId, targetId, length2, link.Colour); Relay(3, holderId, targetId, length2, link.Colour); } } private static void Relay(byte packetType, uint holderId, uint targetId, float length, Color colour) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (bufferRpc == null) { return; } RpcMessage val = new RpcMessage { netId = targetId, componentIndex = 0, functionHash = 52193, payload = new ArraySegment((Il2CppArrayBase)(object)BuildPayload(packetType, holderId, targetId, length, colour)) }; Enumerator enumerator = NetworkServer.connections.Values.GetEnumerator(); bool flag = default(bool); while (enumerator.MoveNext()) { NetworkConnectionToClient current = enumerator.Current; if (!((NetworkConnection)current).isReady) { continue; } try { bufferRpc.Invoke(current, new object[2] { val, Channels.Reliable }); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not synchronize leash state: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } if (NetworkClient.active) { if (packetType == 3) { LeashState.Set(holderId, targetId, length, colour); } else { LeashState.Remove(holderId, targetId); } } } } internal readonly struct LeashLink { internal readonly uint HolderId; internal readonly uint TargetId; internal readonly float Length; internal readonly Color Colour; internal LeashLink(uint holderId, uint targetId, float length, Color colour) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) HolderId = holderId; TargetId = targetId; Length = length; Colour = colour; } } internal static class LeashState { private static readonly Dictionary ByTarget = new Dictionary(); internal static IEnumerable All => ByTarget.Values; internal static bool TryGetForTarget(uint targetId, out LeashLink link) { return ByTarget.TryGetValue(targetId, out link); } internal static bool TryGetForHolder(uint holderId, out LeashLink link) { foreach (LeashLink value in ByTarget.Values) { if (value.HolderId == holderId) { link = value; return true; } } link = default(LeashLink); return false; } internal static void Set(uint holderId, uint targetId, float length, Color colour) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) RemoveWhere(holderId, targetId); ByTarget[targetId] = new LeashLink(holderId, targetId, length, colour); } internal static void Remove(uint holderId, uint targetId) { if (ByTarget.TryGetValue(targetId, out var value) && value.HolderId == holderId) { ByTarget.Remove(targetId); } } internal static void RemoveWhere(uint holderId, uint targetId) { List list = new List(); foreach (KeyValuePair item in ByTarget) { if (item.Value.HolderId == holderId || item.Value.TargetId == targetId) { list.Add(item.Key); } } foreach (uint item2 in list) { ByTarget.Remove(item2); } } internal static void Clear() { ByTarget.Clear(); } } [HarmonyPatch(typeof(PlayerArms), "LateUpdate")] internal static class PlayerArmsPatch { [HarmonyPostfix] private static void AfterArms(PlayerArms __instance) { LeashController.RefreshHandAnchor(__instance); } } [HarmonyPatch(typeof(PlayerMover), "FixedUpdate")] internal static class PlayerMoverPatch { [HarmonyPostfix] private static void AfterMovement(PlayerMover __instance) { LeashController.EnforceDistance(__instance); } } [BepInPlugin("com.henssler.bigwalk.leash", "Big Walk Leash", "1.1.13")] public sealed class Plugin : BasePlugin { public const string PluginGuid = "com.henssler.bigwalk.leash"; public const string PluginName = "Big Walk Leash"; public const string PluginVersion = "1.1.13"; internal static ManualLogSource Log; public override void Load() { //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_002b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Log = ((BasePlugin)this).Log; LeashConfig.Bind(((BasePlugin)this).Config); ClassInjector.RegisterTypeInIl2Cpp(); GameObject val = new GameObject("BigWalkLeash_Controller"); Object.DontDestroyOnLoad((Object)val); val.AddComponent(); Harmony val2 = new Harmony("com.henssler.bigwalk.leash"); val2.PatchAll(); LeashNet.Install(val2); Log.LogInfo((object)"Big Walk Leash loaded. Everyone in the walk needs this mod for a shared leash."); } }