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 Tied Together v1.0.1
TiedTogether.dll
Decompiled 11 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Omniscye")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TiedTogether")] [assembly: AssemblyTitle("TiedTogether")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Empress.TiedTogether { [BepInPlugin("Omniscye.TiedTogether", "TiedTogether", "1.0.7")] public class TiedTogether : BaseUnityPlugin { public const string PluginGuid = "Omniscye.TiedTogether"; public const string PluginName = "TiedTogether"; public const string PluginVersion = "1.0.7"; internal static ConfigEntry<bool> C_Enable; internal static ConfigEntry<float> C_LinkLength; internal static ConfigEntry<bool> C_DrawChain; internal static ConfigEntry<float> C_LineWidth; internal static ConfigEntry<float> C_LineYOffset; internal static ConfigEntry<float> C_PullHardness; internal static ConfigEntry<bool> C_HardStopCC; internal static ConfigEntry<bool> C_UseLateUpdate; internal static ConfigEntry<bool> C_UseFixedUpdate; internal static ConfigEntry<bool> C_BlockOutward; internal static ConfigEntry<float> C_ReturnSpeed; internal static ConfigEntry<float> C_ReturnAccel; internal static ConfigEntry<bool> C_SyncLineFromMaster; internal static ConfigEntry<int> C_SamplesPerLink; internal static ConfigEntry<float> C_SagAmount; internal static ConfigEntry<float> C_HardClampMultiplier; internal static TiedTogether Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown //IL_028f: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; C_Enable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable", true, "Master switch for the mod."); C_LinkLength = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LinkLength", 4f, "Maximum distance between chained neighbors (HOST ONLY)."); C_DrawChain = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "DrawChain", true, "Render visible line between players."); C_LineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "LineWidth", 0.06f, "LineRenderer width."); C_LineYOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "LineYOffset", 0.8f, "Vertical offset for line."); C_PullHardness = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "PullHardness", 1f, "Used for non-RB fallback corrections (HOST ONLY)."); C_HardStopCC = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "HardStopCC", true, "Allow CC toggle teleport as last resort."); C_UseLateUpdate = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "UseLateUpdate", true, "Also enforce in LateUpdate."); C_UseFixedUpdate = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "UseFixedUpdate", true, "Also enforce in FixedUpdate."); C_BlockOutward = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "BlockOutward", true, "At max range, remove outward input."); C_ReturnSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "ReturnSpeed", 12f, "Target inward speed when outside (HOST ONLY)."); C_ReturnAccel = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "ReturnAccel", 60f, "Accel to reach inward target speed (HOST ONLY)."); C_SyncLineFromMaster = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "SyncLineFromMaster", true, "Master publishes polyline; clients render exactly that."); C_SamplesPerLink = ((BaseUnityPlugin)this).Config.Bind<int>("Visual", "SamplesPerLink", 6, "Polyline samples per link."); C_SagAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "SagAmount", 0.6f, "Sag when slack."); C_HardClampMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Advanced", "HardClampMultiplier", 2.5f, "Failsafe snap threshold multiplier (HOST ONLY)."); GameObject val = new GameObject("__TiedTogether_Manager") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<TiedTogetherManager>(); if (Harmony == null) { Harmony val2 = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val3 = val2; Harmony = val2; } Harmony.PatchAll(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded."); } private void OnDestroy() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal class TiedTogetherManager : MonoBehaviour { private const string PROP_ORDER = "TT_ORDER"; private const string PROP_ANCHOR = "TT_ANCHOR"; private const string PROP_LEN = "TT_LEN"; private const string PROP_POINTS = "TT_PTS"; private const string PROP_PTREV = "TT_PTSR"; private const string PROP_CFG = "TT_CFG"; private const int CFG_LINK = 0; private const int CFG_RETSPD = 1; private const int CFG_RETACC = 2; private const int CFG_BLOCK = 3; private const int CFG_PULLHARD = 4; private const int CFG_CLAMPMUL = 5; private const int CFG_SAG = 6; private const int CFG_SAMPLES = 7; private const int CFG_LINEY = 8; private readonly List<int> orderViewIds = new List<int>(); private int anchorViewId = -1; private float linkLength = 0.5f; private float authReturnSpeed = 12f; private float authReturnAccel = 60f; private bool authBlockOutward = true; private float authPullHard = 1f; private float authClampMul = 2.5f; private float authSag = 0.6f; private int authSamples = 6; private float authLineY = 0.8f; private LineRenderer? line; private Material? lineMat; private float masterTick; private bool wasActive; private readonly List<Vector3> syncedPoints = new List<Vector3>(); private object[]? lastSentPackedPoints; private object[]? lastSentPackedCfg; private float pointsTick; private readonly List<Vector3> scratchPts = new List<Vector3>(128); internal static TiedTogetherManager Instance { get; private set; } internal static bool BlockOutward => Instance?.authBlockOutward ?? true; internal static float ReturnSpeed => Instance?.authReturnSpeed ?? 12f; internal static float ReturnAccel => Instance?.authReturnAccel ?? 60f; internal static float ClampMul => Instance?.authClampMul ?? 2.5f; private void Awake() { Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Instance = this; } private void OnDisable() { Deactivate(); } private void Update() { try { if (!TiedTogether.C_Enable.Value) { if (wasActive) { Deactivate(); } return; } if (!RuntimeReady()) { if (wasActive) { Deactivate(); } return; } if (!wasActive) { wasActive = true; if (PhotonNetwork.IsMasterClient) { ApplyHostConfigLocallyFromBepInEx(); } else { ApplyStrictClientFallback(); } } EnsureOrderLocalFallback(); masterTick -= Time.deltaTime; if (masterTick <= 0f) { masterTick = 0.5f; if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom) { TryMasterSync(); TryMasterPublishConfig(); } } TryMasterPublishPoints(); if (PhotonNetwork.InRoom) { Room currentRoom = PhotonNetwork.CurrentRoom; PullRoomProps((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null); } UpdateLine(); EnforceLocalTether(); } catch (Exception ex) { TiedTogether.Logger.LogWarning((object)("Update loop exception: " + ex.Message)); } } private void LateUpdate() { if (TiedTogether.C_Enable.Value && TiedTogether.C_UseLateUpdate.Value && RuntimeReady()) { EnforceLocalTether(); } } private void FixedUpdate() { if (TiedTogether.C_Enable.Value && TiedTogether.C_UseFixedUpdate.Value && RuntimeReady()) { EnforceLocalTether(physicsStep: true); } } internal static bool RuntimeReady() { if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom) { return false; } if (SemiFunc.MenuLevel()) { return false; } if (!Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated) { return false; } if (!Object.op_Implicit((Object)(object)PlayerAvatar.instance)) { return false; } return true; } private void Deactivate() { wasActive = false; orderViewIds.Clear(); anchorViewId = -1; syncedPoints.Clear(); lastSentPackedPoints = null; lastSentPackedCfg = null; HideLine(); } private void ApplyHostConfigLocallyFromBepInEx() { linkLength = Mathf.Max(0.05f, TiedTogether.C_LinkLength.Value); authReturnSpeed = Mathf.Max(0.1f, TiedTogether.C_ReturnSpeed.Value); authReturnAccel = Mathf.Max(0.1f, TiedTogether.C_ReturnAccel.Value); authBlockOutward = TiedTogether.C_BlockOutward.Value; authPullHard = Mathf.Clamp01(TiedTogether.C_PullHardness.Value); authClampMul = Mathf.Max(1f, TiedTogether.C_HardClampMultiplier.Value); authSag = Mathf.Max(0f, TiedTogether.C_SagAmount.Value); authSamples = Mathf.Max(1, TiedTogether.C_SamplesPerLink.Value); authLineY = Mathf.Max(0f, TiedTogether.C_LineYOffset.Value); } private void ApplyStrictClientFallback() { linkLength = 0.5f; authReturnSpeed = 12f; authReturnAccel = 60f; authBlockOutward = true; authPullHard = 1f; authClampMul = 2.5f; authSag = 0.6f; authSamples = 6; authLineY = 0.8f; } private object[] PackHostCfg() { return new object[9] { linkLength, authReturnSpeed, authReturnAccel, authBlockOutward ? 1 : 0, authPullHard, authClampMul, authSag, authSamples, authLineY }; } private void TryMasterPublishConfig() { //IL_0028: 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_0039: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0052: Expected O, but got Unknown ApplyHostConfigLocallyFromBepInEx(); object[] array = PackHostCfg(); if (!PackedEquals(lastSentPackedCfg, array)) { lastSentPackedCfg = array; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"TT_CFG", (object)array); ((Dictionary<object, object>)val).Add((object)"TT_LEN", (object)linkLength); Hashtable val2 = val; PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } } private void PullCfgFromProps(object obj) { if (obj is object[] array && array.Length >= 9) { linkLength = Mathf.Max(0.05f, Convert.ToSingle(array[0])); authReturnSpeed = Mathf.Max(0.1f, Convert.ToSingle(array[1])); authReturnAccel = Mathf.Max(0.1f, Convert.ToSingle(array[2])); authBlockOutward = Convert.ToInt32(array[3]) != 0; authPullHard = Mathf.Clamp01(Convert.ToSingle(array[4])); authClampMul = Mathf.Max(1f, Convert.ToSingle(array[5])); authSag = Mathf.Max(0f, Convert.ToSingle(array[6])); authSamples = Mathf.Max(1, Convert.ToInt32(array[7])); authLineY = Mathf.Max(0f, Convert.ToSingle(array[8])); } } private void TryMasterSync() { //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_00fd: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0112: Expected O, but got Unknown List<PlayerAvatar> list = SafePlayerList(); if (list.Count >= 2) { List<PlayerAvatar> source = (from a in list where Object.op_Implicit((Object)(object)a) && Object.op_Implicit((Object)(object)a.photonView) orderby a.photonView.OwnerActorNr select a).ToList(); int[] array = source.Select((PlayerAvatar a) => a.photonView.ViewID).ToArray(); int num = ((array.Length != 0) ? array[0] : (-1)); if (!orderViewIds.SequenceEqual(array) || anchorViewId != num) { orderViewIds.Clear(); orderViewIds.AddRange(array); anchorViewId = num; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"TT_ORDER", (object)array); ((Dictionary<object, object>)val).Add((object)"TT_ANCHOR", (object)num); Hashtable val2 = val; PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } } } private void TryMasterPublishPoints() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00ce: Expected O, but got Unknown if (!TiedTogether.C_SyncLineFromMaster.Value || !PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || orderViewIds.Count < 2) { return; } pointsTick -= Time.deltaTime; if (pointsTick > 0f) { return; } pointsTick = 0.1f; if (BuildPolylinePoints(scratchPts)) { object[] array = PackPoints(scratchPts); if (!PackedEquals(lastSentPackedPoints, array)) { lastSentPackedPoints = array; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"TT_PTS", (object)array); Hashtable val2 = val; PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } } } private void PullRoomProps(Hashtable props) { if (props == null || ((Dictionary<object, object>)(object)props).Count == 0) { return; } bool flag = false; if (((Dictionary<object, object>)(object)props).ContainsKey((object)"TT_ORDER")) { orderViewIds.Clear(); if (props[(object)"TT_ORDER"] is int[] collection) { orderViewIds.AddRange(collection); } else if (props[(object)"TT_ORDER"] is object[] source) { orderViewIds.AddRange(source.Select((object o) => Convert.ToInt32(o))); } flag = true; } if (((Dictionary<object, object>)(object)props).ContainsKey((object)"TT_ANCHOR")) { anchorViewId = Convert.ToInt32(props[(object)"TT_ANCHOR"]); flag = true; } if (((Dictionary<object, object>)(object)props).ContainsKey((object)"TT_LEN")) { linkLength = Mathf.Max(0.05f, Convert.ToSingle(props[(object)"TT_LEN"])); flag = true; } if (((Dictionary<object, object>)(object)props).ContainsKey((object)"TT_CFG")) { PullCfgFromProps(props[(object)"TT_CFG"]); flag = true; } if (((Dictionary<object, object>)(object)props).ContainsKey((object)"TT_PTS") && UnpackPoints(props[(object)"TT_PTS"], syncedPoints)) { flag = true; } if (flag) { EnsureLine(); } } private void EnsureLine() { //IL_006b: 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_007a: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown if (!TiedTogether.C_DrawChain.Value) { HideLine(); return; } if ((Object)(object)line == (Object)null) { if (!Object.op_Implicit((Object)(object)lineMat)) { lineMat = new Material(Shader.Find("Sprites/Default")) { renderQueue = 3000 }; } GameObject val = new GameObject("__TiedTogether_Line") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)val); line = val.AddComponent<LineRenderer>(); line.useWorldSpace = true; ((Renderer)line).receiveShadows = false; ((Renderer)line).shadowCastingMode = (ShadowCastingMode)0; line.alignment = (LineAlignment)1; line.textureMode = (LineTextureMode)0; ((Renderer)line).material = lineMat; line.startColor = new Color(0.9f, 0.9f, 1f, 0.65f); line.endColor = new Color(0.9f, 0.9f, 1f, 0.65f); } line.widthMultiplier = Mathf.Max(0.005f, TiedTogether.C_LineWidth.Value); ((Renderer)line).enabled = true; } private void HideLine() { if (Object.op_Implicit((Object)(object)line)) { ((Renderer)line).enabled = false; } } private void UpdateLine() { //IL_0076: 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_00fd: 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_010d: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)line == (Object)null || !TiedTogether.C_DrawChain.Value) { return; } if (TiedTogether.C_SyncLineFromMaster.Value && syncedPoints.Count >= 2) { line.positionCount = syncedPoints.Count; for (int i = 0; i < syncedPoints.Count; i++) { line.SetPosition(i, syncedPoints[i]); } return; } if (orderViewIds.Count < 2) { line.positionCount = 0; return; } line.positionCount = orderViewIds.Count; for (int j = 0; j < orderViewIds.Count; j++) { Transform val = ResolveNodeTransform(orderViewIds[j]); Vector3 val2 = (Object.op_Implicit((Object)(object)val) ? val.position : Vector3.zero); val2 += Vector3.up * Mathf.Max(0f, authLineY); line.SetPosition(j, val2); } } private bool BuildPolylinePoints(List<Vector3> outPts) { //IL_007d: 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_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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00d9: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) outPts.Clear(); if (orderViewIds.Count < 2) { return false; } int num = Mathf.Max(1, authSamples); float num2 = Mathf.Max(0f, authLineY); float num3 = Mathf.Max(0f, authSag); Transform val = ResolveNodeTransform(orderViewIds[0]); if (!Object.op_Implicit((Object)(object)val)) { return false; } Vector3 val2 = val.position + Vector3.up * num2; outPts.Add(val2); for (int i = 1; i < orderViewIds.Count; i++) { Transform val3 = ResolveNodeTransform(orderViewIds[i]); if (!Object.op_Implicit((Object)(object)val3)) { return false; } Vector3 val4 = val3.position + Vector3.up * num2; Vector3 val5 = val4 - val2; float magnitude = ((Vector3)(ref val5)).magnitude; float num4 = 1f - Mathf.Clamp01(magnitude / Mathf.Max(0.001f, linkLength)); float num5 = num3 * num4; for (int j = 1; j <= num; j++) { float num6 = (float)j / (float)num; Vector3 val6 = Vector3.Lerp(val2, val4, num6); if (num5 > 0f) { val6 += Vector3.down * (Mathf.Sin(MathF.PI * num6) * num5); } outPts.Add(val6); } val2 = val4; } if (outPts.Count > 256) { outPts.RemoveRange(256, outPts.Count - 256); } return outPts.Count >= 2; } private static object[] PackPoints(List<Vector3> pts) { //IL_001a: 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_0027: 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_004d: Unknown result type (might be due to invalid IL or missing references) int count = pts.Count; object[] array = new object[count * 3]; int num = 0; for (int i = 0; i < count; i++) { Vector3 val = pts[i]; array[num++] = val.x; array[num++] = val.y; array[num++] = val.z; } return array; } private static bool UnpackPoints(object obj, List<Vector3> outPts) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) outPts.Clear(); if (obj is object[] array) { int num = array.Length - array.Length % 3; num = Mathf.Min(num, 768); for (int i = 0; i < num; i += 3) { float num2 = Convert.ToSingle(array[i]); float num3 = Convert.ToSingle(array[i + 1]); float num4 = Convert.ToSingle(array[i + 2]); outPts.Add(new Vector3(num2, num3, num4)); } return outPts.Count >= 2; } return false; } private static bool PackedEquals(object[]? a, object[] b) { if (a == null || a.Length != b.Length) { return false; } for (int i = 0; i < a.Length; i++) { float num = Convert.ToSingle(a[i]); float num2 = Convert.ToSingle(b[i]); if (Mathf.Abs(num - num2) > 0.01f) { return false; } } return true; } internal bool TryGetLocalChainContext(out Vector3 neighborPos, out Vector3 myPos, out float maxDist) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) //IL_00e6: 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) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) neighborPos = Vector3.zero; myPos = Vector3.zero; maxDist = Mathf.Max(0.05f, linkLength); PlayerAvatar instance = PlayerAvatar.instance; if (!Object.op_Implicit((Object)(object)instance) || instance.deadSet) { return false; } if (orderViewIds.Count < 2 || anchorViewId < 0) { return false; } int item = (((Object)(object)instance.photonView != (Object)null) ? instance.photonView.ViewID : (-1)); int num = orderViewIds.IndexOf(item); if (num <= 0) { return false; } int viewId = orderViewIds[num - 1]; Transform val = ResolveNodeTransform(viewId); if (!Object.op_Implicit((Object)(object)val)) { return false; } neighborPos = val.position; myPos = CurrentNodePosition(instance); return true; } private void EnforceLocalTether(bool physicsStep = false, bool forceHard = false) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_004d: 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) //IL_007f: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: 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_02c8: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar instance = PlayerAvatar.instance; if (!Object.op_Implicit((Object)(object)instance) || instance.deadSet || !TryGetLocalChainContext(out var neighborPos, out var myPos, out var maxDist)) { return; } Vector3 val = myPos - neighborPos; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= maxDist) { return; } Vector3 val2 = ((magnitude > 0.0001f) ? (val / magnitude) : Vector3.forward); float num = magnitude - maxDist; if (instance.isTumbling && Object.op_Implicit((Object)(object)instance.tumble)) { Transform transform = ((Component)instance.tumble).transform; Rigidbody component = ((Component)instance.tumble).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null && !component.isKinematic) { float num2 = Vector3.Dot(component.velocity, val2); float num3 = 0f - Mathf.Max(authReturnSpeed, num * 4f); component.velocity += val2 * (num3 - num2); } else { transform.position = Vector3.MoveTowards(transform.position, neighborPos + val2 * maxDist, authReturnSpeed * Time.deltaTime); } return; } CharacterController component2 = ((Component)instance).GetComponent<CharacterController>(); if ((Object)(object)component2 != (Object)null && ((Collider)component2).enabled) { float num4 = Mathf.Max(0f, Mathf.Min(authReturnSpeed * Time.deltaTime, num)); if (num4 > 0f) { component2.Move(-val2 * num4); } if (magnitude > maxDist * authClampMul) { bool enabled = ((Collider)component2).enabled; if (enabled) { ((Collider)component2).enabled = false; } ((Component)instance).transform.position = neighborPos + val2 * maxDist; if (enabled) { ((Collider)component2).enabled = true; } } return; } Rigidbody component3 = ((Component)instance).GetComponent<Rigidbody>(); if ((Object)(object)component3 != (Object)null && !component3.isKinematic) { float num5 = Vector3.Dot(component3.velocity, val2); float num6 = 0f - Mathf.Max(authReturnSpeed, num * 4f); component3.velocity += val2 * (num6 - num5); if (magnitude > maxDist * authClampMul) { component3.position = neighborPos + val2 * maxDist; ((Component)instance).transform.position = component3.position; } } else { ((Component)instance).transform.position = Vector3.MoveTowards(((Component)instance).transform.position, neighborPos + val2 * maxDist, authReturnSpeed * Time.deltaTime); } } private static List<PlayerAvatar> SafePlayerList() { List<PlayerAvatar> list = SemiFunc.PlayerGetList(); if (list == null) { return new List<PlayerAvatar>(); } return list.Where((PlayerAvatar p) => (Object)(object)p != (Object)null).ToList(); } private static Vector3 CurrentNodePosition(PlayerAvatar av) { //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_007e: 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_0040: 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_007b: 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_006d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)av)) { return Vector3.zero; } if (av.deadSet && Object.op_Implicit((Object)(object)av.playerDeathHead)) { return ((Component)av.playerDeathHead).transform.position; } if (av.isTumbling && Object.op_Implicit((Object)(object)av.tumble)) { return ((Component)av.tumble).transform.position; } return ((Component)av).transform.position; } private static Transform? ResolveNodeTransform(int viewId) { PhotonView val = PhotonView.Find(viewId); if (!Object.op_Implicit((Object)(object)val)) { return null; } PlayerAvatar component = ((Component)val).GetComponent<PlayerAvatar>(); if (Object.op_Implicit((Object)(object)component)) { if (component.deadSet && Object.op_Implicit((Object)(object)component.playerDeathHead)) { return ((Component)component.playerDeathHead).transform; } if (component.isTumbling && Object.op_Implicit((Object)(object)component.tumble)) { return ((Component)component.tumble).transform; } return ((Component)component).transform; } PlayerDeathHead component2 = ((Component)val).GetComponent<PlayerDeathHead>(); if (Object.op_Implicit((Object)(object)component2)) { return ((Component)component2).transform; } return ((Component)val).transform; } private void EnsureOrderLocalFallback() { if (orderViewIds.Count >= 2 && anchorViewId >= 0) { return; } List<PlayerAvatar> list = SafePlayerList(); if (list.Count >= 2) { List<int> list2 = (from a in list where Object.op_Implicit((Object)(object)a) && Object.op_Implicit((Object)(object)a.photonView) orderby a.photonView.OwnerActorNr select a.photonView.ViewID).ToList(); if (list2.Count >= 2) { orderViewIds.Clear(); orderViewIds.AddRange(list2); anchorViewId = list2[0]; } } } } [HarmonyPatch(typeof(PlayerController), "FixedUpdate")] internal static class Patch_PlayerController_FixedUpdate_Tether { [HarmonyPostfix] private static void Postfix(PlayerController __instance) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_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) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_0197: Unknown result type (might be due to invalid IL or missing references) if (!TiedTogether.C_Enable.Value || !TiedTogetherManager.RuntimeReady() || __instance != PlayerController.instance) { return; } TiedTogetherManager instance = TiedTogetherManager.Instance; if ((Object)(object)instance == (Object)null || !instance.TryGetLocalChainContext(out var neighborPos, out var myPos, out var maxDist)) { return; } Vector3 val = myPos - neighborPos; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < maxDist - 0.001f) { return; } Vector3 val2 = ((magnitude > 0.0001f) ? (val / magnitude) : Vector3.forward); if (TiedTogetherManager.BlockOutward) { Vector3 inputDirection = __instance.InputDirection; float num = Vector3.Dot(inputDirection, val2); if (num > 0f) { __instance.InputDirection = inputDirection - val2 * num; } } Rigidbody rb = __instance.rb; if ((Object)(object)rb != (Object)null) { float num2 = magnitude - maxDist; float num3 = Vector3.Dot(rb.velocity, val2); float num4 = 0f - Mathf.Max(TiedTogetherManager.ReturnSpeed, num2 * 4f); rb.velocity += val2 * (num4 - num3); float num5 = Mathf.Max(1f, TiedTogetherManager.ClampMul); if (magnitude > maxDist * num5) { Vector3 position = (rb.position = neighborPos + val2 * maxDist); ((Component)__instance).transform.position = position; } } } } [HarmonyPatch] internal static class HarmonyAnchors { } }