using System; using System.Collections; 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.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; [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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPOJP.AlwaysWingsView { [BepInPlugin("REPOJP.AlwaysWingsView", "AlwaysWingsView", "2.1.1")] public sealed class AlwaysWingsViewPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(ItemUpgradePlayerTumbleWingsLogic), "Start")] private static class ItemUpgradePlayerTumbleWingsLogic_Start_Patch { private static void Postfix(ItemUpgradePlayerTumbleWingsLogic __instance) { RequestDelayedReapplyStatic("wingsLogicStart"); } } [HarmonyPatch(typeof(ItemUpgradePlayerTumbleWingsLogic), "LoopSound")] private static class ItemUpgradePlayerTumbleWingsLogic_LoopSound_Patch { private static void Postfix(ItemUpgradePlayerTumbleWingsLogic __instance) { if ((Object)(object)Instance == (Object)null) { return; } string text = "off"; try { text = NormalizeMode(Instance._mode.Value); } catch { text = "off"; } if (text == "off" || IsNullUnity(__instance)) { return; } PlayerAvatar localAvatar = GetLocalAvatar(); if (IsNullUnity(localAvatar)) { return; } try { if (IsNullUnity(__instance.playerAvatar) || (Object)(object)__instance.playerAvatar != (Object)(object)localAvatar) { return; } } catch { return; } ApplyWingAudioMuteState(__instance, text); } } [HarmonyPatch(typeof(ItemUpgradePlayerTumbleWingsLogic), "FixedUpdate")] private static class ItemUpgradePlayerTumbleWingsLogic_FixedUpdate_Patch { private static void Prefix(ItemUpgradePlayerTumbleWingsLogic __instance, ref float __state) { __state = -1f; if (!ShouldAllowHostPinkFlight(__instance)) { return; } try { __state = __instance.tumbleWingPinkTimer; if (__instance.tumbleWingPinkTimer > 0f) { __instance.tumbleWingPinkTimer = 0f; } if (__instance.tumbleWingTimer < 1.15f) { __instance.tumbleWingTimer = 1.15f; } if (!IsNullUnity(__instance.playerAvatar)) { __instance.playerAvatar.upgradeTumbleWingsVisualsActive = true; } } catch (Exception ex) { LogWarn("Host pink flight prefix failed\n" + ex); } } private static void Postfix(ItemUpgradePlayerTumbleWingsLogic __instance, float __state) { if (__state < 0f) { return; } try { if (__state > 0f) { __instance.tumbleWingPinkTimer = Mathf.Max(__state, 1.15f); } if (!IsNullUnity(__instance.playerAvatar)) { __instance.playerAvatar.upgradeTumbleWingsVisualsActive = true; } __instance.WingsSetPinkColors(); } catch (Exception ex) { LogWarn("Host pink flight postfix failed\n" + ex); } } } [HarmonyPatch(typeof(ItemUpgradePlayerTumbleWingsLogic), "TurnOffWings")] private static class ItemUpgradePlayerTumbleWingsLogic_TurnOffWings_Patch { private static bool Prefix(ItemUpgradePlayerTumbleWingsLogic __instance) { if (!ShouldAllowHostPinkFlight(__instance)) { return true; } try { __instance.tumbleWingTimer = 1.15f; if (!IsNullUnity(__instance.playerAvatar)) { __instance.playerAvatar.upgradeTumbleWingsVisualsActive = true; } __instance.WingsSetPinkColors(); } catch (Exception ex) { LogWarn("Host pink TurnOff suppression failed\n" + ex); } return false; } } [HarmonyPatch(typeof(PlayerAvatar), "UpgradeTumbleWingsVisualsActiveRPC")] private static class PlayerAvatar_UpgradeTumbleWingsVisualsActiveRPC_Patch { private static void Postfix(PlayerAvatar __instance) { if ((Object)(object)Instance == (Object)null) { return; } PlayerAvatar localAvatar = GetLocalAvatar(); if (!IsNullUnity(localAvatar) && !((Object)(object)__instance != (Object)(object)localAvatar)) { string text = NormalizeMode(Instance._mode.Value); if (!(text == "off")) { RequestDelayedReapplyStatic("wingsRpc"); } } } } [CompilerGenerated] private sealed class d__25 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string reason; public AlwaysWingsViewPlugin <>4__this; private float 5__1; private PlayerAvatar 5__2; private ItemUpgradePlayerTumbleWingsLogic 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = Time.realtimeSinceStartup + 20f; break; case 1: <>1__state = -1; 5__2 = null; break; } if (Time.realtimeSinceStartup < 5__1) { 5__2 = GetLocalAvatar(); if (!IsNullUnity(5__2)) { 5__3 = GetLocalWingsLogic(5__2); if (!IsNullUnity(5__3)) { <>4__this.ApplyModeBestEffort(reason); return false; } 5__3 = null; } <>2__current = null; <>1__state = 1; return true; } LogWarn("Apply skipped timeout reason=" + reason); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__52 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string reason; public AlwaysWingsViewPlugin <>4__this; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__52(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = 0.15f; try { 5__1 = Mathf.Clamp(<>4__this._reapplyAfterVisualRefreshSeconds.Value, 0f, 2f); } catch { 5__1 = 0.15f; } if (5__1 > 0f) { <>2__current = (object)new WaitForSeconds(5__1); <>1__state = 1; return true; } <>2__current = null; <>1__state = 2; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } <>4__this.ApplyModeBestEffort("delayedReapply:" + reason); <>4__this._delayedReapplyCo = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__26 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AlwaysWingsViewPlugin <>4__this; private WaitForSeconds 5__1; private Exception 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = new WaitForSeconds(1f); break; case 1: <>1__state = -1; break; } try { <>4__this.ResetHostSupportConfirmationForCurrentState(); <>4__this.SyncHostSupportRoomProperty(); <>4__this.SyncPhotonPinkRequestProperty(); } catch (Exception ex) { 5__2 = ex; LogWarn("Photon state sync failed\n" + 5__2); } <>2__current = 5__1; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__29 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string mode; public AlwaysWingsViewPlugin <>4__this; private PlayerAvatar 5__1; private float 5__2; private ItemUpgradePlayerTumbleWingsLogic 5__3; private string 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__3 = null; 5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; 5__1 = null; break; } 5__1 = GetLocalAvatar(); if (!IsNullUnity(5__1)) { 5__3 = GetLocalWingsLogic(5__1); if (!IsNullUnity(5__3)) { 5__4 = NormalizeMode(<>4__this._mode.Value); ApplyWingAudioMuteState(5__3, 5__4); if (5__4 != mode && 5__4 != "off") { mode = 5__4; <>4__this._activeMode = 5__4; } <>4__this.ApplyWingsNow(5__1, mode, "loopTick"); 5__4 = null; } 5__3 = null; } 5__2 = 0.35f; try { 5__2 = Mathf.Clamp(<>4__this._keepAliveIntervalSeconds.Value, 0.1f, 2f); } catch { 5__2 = 0.35f; } <>2__current = (object)new WaitForSeconds(5__2); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "REPOJP.AlwaysWingsView"; public const string PluginName = "AlwaysWingsView"; public const string PluginVersion = "2.1.1"; private const string RoomPropertyHostPinkFlightSupport = "REPOJP_AWV_HostPinkFlight"; private const string PlayerPropertyPinkRequested = "REPOJP_AWV_PinkRequested"; private static ManualLogSource Log; private static AlwaysWingsViewPlugin Instance; private ConfigEntry _mode; private ConfigEntry _muteWingLoopSound; private ConfigEntry _keepAliveIntervalSeconds; private ConfigEntry _reapplyAfterVisualRefreshSeconds; private Harmony _harmony; private Coroutine _wingsLoopCo; private Coroutine _networkSyncCo; private Coroutine _delayedReapplyCo; private string _activeMode = "off"; private bool _pinkFallbackUsingBlue; private bool _hostPinkFlightSupportConfirmedThisRoom; private string _hostPinkFlightSupportConfirmedRoomName = string.Empty; private float _nextHostSupportCheckTime; private void Awake() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; try { ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } catch (Exception ex) { LogWarn("Persist setup failed\n" + ex); } _mode = ((BaseUnityPlugin)this).Config.Bind("General", "TumbleWingsMode", "blue", new ConfigDescription("Auto tumble wings mode. Values: off, blue, pink. 自動翼モード off blue pink のみ", (AcceptableValueBase)(object)new AcceptableValueList(new string[3] { "off", "blue", "pink" }), Array.Empty())); _muteWingLoopSound = ((BaseUnityPlugin)this).Config.Bind("General", "MuteWingLoopSound", true, "Mute blue and pink wing loop sound without changing the display flow. 既存の羽表示処理を変えずに青羽とピンク羽のループ音のみ無音化"); _keepAliveIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind("Runtime", "KeepAliveIntervalSeconds", 0.35f, new ConfigDescription("Wing visual reapply interval seconds. 羽表示再適用間隔秒数", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 2f), Array.Empty())); _reapplyAfterVisualRefreshSeconds = ((BaseUnityPlugin)this).Config.Bind("Runtime", "ReapplyAfterVisualRefreshSeconds", 0.15f, new ConfigDescription("Delay before reapplying after cosmetic or visual refresh. コスメや表示更新後の再適用遅延秒数", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); _harmony = new Harmony("REPOJP.AlwaysWingsView"); _harmony.PatchAll(typeof(AlwaysWingsViewPlugin).Assembly); PatchOptionalVisualRefreshMethods(); _mode.SettingChanged += OnConfigChanged; _muteWingLoopSound.SettingChanged += OnConfigChanged; _keepAliveIntervalSeconds.SettingChanged += OnConfigChanged; _reapplyAfterVisualRefreshSeconds.SettingChanged += OnConfigChanged; SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.activeSceneChanged += OnActiveSceneChanged; _networkSyncCo = ((MonoBehaviour)this).StartCoroutine(CoNetworkStateSync()); ((MonoBehaviour)this).StartCoroutine(CoApplyWhenReady("initial")); LogInfo("Loaded v2.1.1"); } private void OnDestroy() { try { SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.activeSceneChanged -= OnActiveSceneChanged; } catch { } try { _mode.SettingChanged -= OnConfigChanged; _muteWingLoopSound.SettingChanged -= OnConfigChanged; _keepAliveIntervalSeconds.SettingChanged -= OnConfigChanged; _reapplyAfterVisualRefreshSeconds.SettingChanged -= OnConfigChanged; } catch { } StopWingsLoop(); if (_networkSyncCo != null) { ((MonoBehaviour)this).StopCoroutine(_networkSyncCo); _networkSyncCo = null; } if (_delayedReapplyCo != null) { ((MonoBehaviour)this).StopCoroutine(_delayedReapplyCo); _delayedReapplyCo = null; } try { ClearPhotonPinkRequestProperty(); } catch { } try { if (_harmony != null) { _harmony.UnpatchSelf(); } } catch { } } private void OnConfigChanged(object sender, EventArgs args) { SyncPhotonPinkRequestProperty(); ApplyModeBestEffort("configChanged"); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ResetHostSupportConfirmationForCurrentState(); SyncPhotonPinkRequestProperty(); ((MonoBehaviour)this).StartCoroutine(CoApplyWhenReady("sceneLoaded:" + ((Scene)(ref scene)).name)); } private void OnActiveSceneChanged(Scene from, Scene to) { ResetHostSupportConfirmationForCurrentState(); SyncPhotonPinkRequestProperty(); ((MonoBehaviour)this).StartCoroutine(CoApplyWhenReady("activeSceneChanged:" + ((Scene)(ref to)).name)); } [IteratorStateMachine(typeof(d__25))] private IEnumerator CoApplyWhenReady(string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__25(0) { <>4__this = this, reason = reason }; } [IteratorStateMachine(typeof(d__26))] private IEnumerator CoNetworkStateSync() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__26(0) { <>4__this = this }; } private void ApplyModeBestEffort(string reason) { string text = NormalizeMode(_mode.Value); PlayerAvatar localAvatar = GetLocalAvatar(); if (IsNullUnity(localAvatar)) { return; } ItemUpgradePlayerTumbleWingsLogic localWingsLogic = GetLocalWingsLogic(localAvatar); if (!IsNullUnity(localWingsLogic)) { ResetHostSupportConfirmationForCurrentState(); SyncHostSupportRoomProperty(); SyncPhotonPinkRequestProperty(); ApplyWingAudioMuteState(localWingsLogic, text); switch (text) { case "off": StopWingsLoop(); TrySetWings(localAvatar, visualsActive: false, pink: true, "mode=off " + reason); ForceWingVisualFields(localWingsLogic, visualsActive: false, pink: false, "mode=off " + reason); _activeMode = "off"; break; case "blue": StartWingsLoop(localAvatar, "blue", reason); break; case "pink": StartWingsLoop(localAvatar, "pink", reason); break; } } } private void StartWingsLoop(PlayerAvatar local, string mode, string reason) { StopWingsLoop(); _activeMode = mode; ApplyWingsNow(local, mode, "oneshot " + reason); _wingsLoopCo = ((MonoBehaviour)this).StartCoroutine(CoWingsKeepAlive(mode)); } [IteratorStateMachine(typeof(d__29))] private IEnumerator CoWingsKeepAlive(string mode) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0) { <>4__this = this, mode = mode }; } private void ApplyWingsNow(PlayerAvatar local, string mode, string reason) { if (IsNullUnity(local)) { return; } ItemUpgradePlayerTumbleWingsLogic localWingsLogic = GetLocalWingsLogic(local); if (IsNullUnity(localWingsLogic)) { return; } switch (mode) { case "off": _pinkFallbackUsingBlue = false; TrySetWings(local, visualsActive: false, pink: true, "mode=off " + reason); ForceWingVisualFields(localWingsLogic, visualsActive: false, pink: false, "mode=off " + reason); break; case "blue": _pinkFallbackUsingBlue = false; TrySetWings(local, visualsActive: true, pink: false, "mode=blue " + reason); ForceWingVisualFields(localWingsLogic, visualsActive: true, pink: false, "mode=blue " + reason); break; case "pink": { bool flag = HasHostPinkFlightSupport(); if (!flag && IsLocalPinkFlightFallbackBlueActive(local)) { _pinkFallbackUsingBlue = true; TrySetWings(local, visualsActive: true, pink: false, "mode=pink blueFallback " + reason); ForceWingVisualFields(localWingsLogic, visualsActive: true, pink: false, "mode=pink blueFallback " + reason); } else { _pinkFallbackUsingBlue = false; TrySetWings(local, visualsActive: true, pink: true, flag ? ("mode=pink hostSupport " + reason) : ("mode=pink fallbackIdle " + reason)); ForceWingVisualFields(localWingsLogic, visualsActive: true, pink: true, "mode=pink " + reason); } break; } } } private void StopWingsLoop() { if (_wingsLoopCo != null) { ((MonoBehaviour)this).StopCoroutine(_wingsLoopCo); _wingsLoopCo = null; } _pinkFallbackUsingBlue = false; } private static void TrySetWings(PlayerAvatar avatar, bool visualsActive, bool pink, string reason) { if (IsNullUnity(avatar)) { return; } try { avatar.UpgradeTumbleWingsVisualsActive(visualsActive, pink); } catch (Exception ex) { LogError("Wings apply failed reason=" + reason + "\n" + ex); } } private static void ForceWingVisualFields(ItemUpgradePlayerTumbleWingsLogic logic, bool visualsActive, bool pink, string reason) { if (IsNullUnity(logic)) { return; } try { PlayerAvatar playerAvatar = logic.playerAvatar; if (!IsNullUnity(playerAvatar)) { playerAvatar.upgradeTumbleWingsVisualsActive = visualsActive; } if (visualsActive) { if (logic.tumbleWingTimer < 1.15f) { logic.tumbleWingTimer = 1.15f; } if (pink) { logic.tumbleWingPinkTimer = Mathf.Max(logic.tumbleWingPinkTimer, 1.15f); logic.WingsSetPinkColors(); } else { logic.tumbleWingPinkTimer = 0f; logic.WingsSetOriginalColors(); } } else { logic.tumbleWingPinkTimer = 0f; } } catch (Exception ex) { LogWarn("Force wing fields failed reason=" + reason + "\n" + ex); } } private static PlayerAvatar GetLocalAvatar() { try { return PlayerAvatar.instance; } catch { return null; } } private static ItemUpgradePlayerTumbleWingsLogic GetLocalWingsLogic(PlayerAvatar avatar) { if (IsNullUnity(avatar)) { return null; } try { if (!IsNullUnity(avatar.upgradeTumbleWingsLogic)) { return avatar.upgradeTumbleWingsLogic; } } catch { } try { return ((Component)avatar).GetComponentInChildren(true); } catch { return null; } } private static bool IsLocalPinkFlightFallbackBlueActive(PlayerAvatar avatar) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance == (Object)null) { return false; } if (NormalizeMode(Instance._mode.Value) != "pink") { return false; } if (IsNullUnity(avatar)) { return false; } PlayerAvatar localAvatar = GetLocalAvatar(); if (IsNullUnity(localAvatar) || (Object)(object)avatar != (Object)(object)localAvatar) { return false; } try { if (avatar.upgradeTumbleWings <= 0f) { return false; } } catch { return false; } PlayerTumble val = null; try { val = avatar.tumble; } catch { val = null; } if (IsNullUnity(val)) { return false; } try { if (!val.isTumbling) { return false; } if (!val.isPlayerInputTriggered && val.tumbleOverride) { return false; } if ((Object)(object)val.physGrabObject == (Object)null) { return false; } if (val.physGrabObject.playerGrabbing.Count > 0) { return false; } if (SemiFunc.OnGroundCheck(((Component)val).transform.position, 1f, val.physGrabObject)) { return false; } } catch { return false; } return true; } private static bool ShouldAllowHostPinkFlight(ItemUpgradePlayerTumbleWingsLogic logic) { //IL_012f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance == (Object)null) { return false; } if (IsNullUnity(logic)) { return false; } PlayerAvatar val = null; try { val = logic.playerAvatar; } catch { val = null; } if (IsNullUnity(val)) { return false; } try { if (val.upgradeTumbleWings <= 0f) { return false; } } catch { return false; } if (!HasPinkFlightAuthorityForAvatar(val)) { return false; } PlayerTumble val2 = null; try { val2 = val.tumble; } catch { val2 = null; } if (IsNullUnity(val2)) { return false; } try { if (!val2.isTumbling) { return false; } if (!val2.isPlayerInputTriggered && val2.tumbleOverride) { return false; } if ((Object)(object)val2.physGrabObject == (Object)null) { return false; } if (val2.physGrabObject.playerGrabbing.Count > 0) { return false; } if (SemiFunc.OnGroundCheck(((Component)val2).transform.position, 1f, val2.physGrabObject)) { return false; } } catch { return false; } return true; } private static bool HasPinkFlightAuthorityForAvatar(PlayerAvatar avatar) { if ((Object)(object)Instance == (Object)null) { return false; } if (IsNullUnity(avatar)) { return false; } if (!SemiFunc.IsMultiplayer()) { return NormalizeMode(Instance._mode.Value) == "pink"; } if (!PhotonNetwork.InRoom) { return false; } if (!PhotonNetwork.IsMasterClient) { return false; } return GetAvatarPinkRequested(avatar); } private static bool GetAvatarPinkRequested(PlayerAvatar avatar) { if (IsNullUnity(avatar)) { return false; } PhotonView val = null; try { val = ((Component)avatar).GetComponent(); } catch { val = null; } if ((Object)(object)val == (Object)null || val.Owner == null) { return false; } return TryGetBoolProperty(val.Owner.CustomProperties, "REPOJP_AWV_PinkRequested"); } private void ResetHostSupportConfirmationForCurrentState() { if (!SemiFunc.IsMultiplayer() || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { _hostPinkFlightSupportConfirmedThisRoom = false; _hostPinkFlightSupportConfirmedRoomName = string.Empty; _nextHostSupportCheckTime = 0f; return; } string text = PhotonNetwork.CurrentRoom.Name ?? string.Empty; if (!string.Equals(_hostPinkFlightSupportConfirmedRoomName, text, StringComparison.Ordinal)) { _hostPinkFlightSupportConfirmedThisRoom = false; _hostPinkFlightSupportConfirmedRoomName = text; _nextHostSupportCheckTime = 0f; } } private static bool HasHostPinkFlightSupport() { if ((Object)(object)Instance == (Object)null) { return false; } if (!SemiFunc.IsMultiplayer()) { return true; } if (!PhotonNetwork.InRoom) { Instance._hostPinkFlightSupportConfirmedThisRoom = false; Instance._hostPinkFlightSupportConfirmedRoomName = string.Empty; Instance._nextHostSupportCheckTime = 0f; return false; } if (PhotonNetwork.IsMasterClient) { return true; } Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom == null) { Instance._hostPinkFlightSupportConfirmedThisRoom = false; Instance._hostPinkFlightSupportConfirmedRoomName = string.Empty; Instance._nextHostSupportCheckTime = 0f; return false; } string text = currentRoom.Name ?? string.Empty; if (!string.Equals(Instance._hostPinkFlightSupportConfirmedRoomName, text, StringComparison.Ordinal)) { Instance._hostPinkFlightSupportConfirmedThisRoom = false; Instance._hostPinkFlightSupportConfirmedRoomName = text; Instance._nextHostSupportCheckTime = 0f; } if (Instance._hostPinkFlightSupportConfirmedThisRoom) { return true; } if (Time.realtimeSinceStartup < Instance._nextHostSupportCheckTime) { return false; } Instance._nextHostSupportCheckTime = Time.realtimeSinceStartup + 3f; bool flag = TryGetBoolProperty(((RoomInfo)currentRoom).CustomProperties, "REPOJP_AWV_HostPinkFlight"); if (flag) { Instance._hostPinkFlightSupportConfirmedThisRoom = true; Instance._hostPinkFlightSupportConfirmedRoomName = text; } return flag; } private void SyncHostSupportRoomProperty() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom != null && !TryGetBoolProperty(((RoomInfo)currentRoom).CustomProperties, "REPOJP_AWV_HostPinkFlight")) { Hashtable val = new Hashtable(); val[(object)"REPOJP_AWV_HostPinkFlight"] = true; currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } } private void SyncPhotonPinkRequestProperty() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown if (!SemiFunc.IsMultiplayer() || !PhotonNetwork.InRoom) { return; } Player localPlayer = PhotonNetwork.LocalPlayer; if (localPlayer != null) { bool flag = NormalizeMode(_mode.Value) == "pink"; bool flag2 = TryGetBoolProperty(localPlayer.CustomProperties, "REPOJP_AWV_PinkRequested"); if (flag2 != flag) { Hashtable val = new Hashtable(); val[(object)"REPOJP_AWV_PinkRequested"] = flag; localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } } private void ClearPhotonPinkRequestProperty() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom) { Player localPlayer = PhotonNetwork.LocalPlayer; if (localPlayer != null && TryGetBoolProperty(localPlayer.CustomProperties, "REPOJP_AWV_PinkRequested")) { Hashtable val = new Hashtable(); val[(object)"REPOJP_AWV_PinkRequested"] = false; localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } } private static bool TryGetBoolProperty(Hashtable props, string key) { if (props == null || string.IsNullOrEmpty(key) || !((Dictionary)(object)props).ContainsKey((object)key)) { return false; } object obj = props[(object)key]; if (obj == null) { return false; } if (!(obj is bool result)) { if (obj is byte) { return (byte)obj != 0; } if (obj is int) { return (int)obj != 0; } if (obj is string && bool.TryParse((string)obj, out var result2)) { return result2; } return false; } return result; } private static void ApplyWingAudioMuteState(ItemUpgradePlayerTumbleWingsLogic logic, string mode) { if (!((Object)(object)Instance == (Object)null)) { bool flag = false; try { flag = Instance._muteWingLoopSound.Value && mode != "off"; } catch { flag = false; } if (flag) { MuteWingLoopAudio(logic); } else { UnmuteWingLoopAudio(logic); } } } private static void MuteWingLoopAudio(ItemUpgradePlayerTumbleWingsLogic logic) { if (IsNullUnity(logic)) { return; } try { if ((Object)(object)logic.localAudioSource != (Object)null) { logic.localAudioSource.mute = true; logic.localAudioSource.volume = 0f; if (logic.localAudioSource.isPlaying) { logic.localAudioSource.Stop(); } } } catch (Exception ex) { LogWarn("localAudioSource mute failed\n" + ex); } try { if (logic.soundWingsLoop != null && (Object)(object)logic.soundWingsLoop.Source != (Object)null) { logic.soundWingsLoop.Source.mute = true; logic.soundWingsLoop.Source.volume = 0f; if (logic.soundWingsLoop.Source.isPlaying) { logic.soundWingsLoop.Source.Stop(); } } } catch (Exception ex2) { LogWarn("soundWingsLoop mute failed\n" + ex2); } } private static void UnmuteWingLoopAudio(ItemUpgradePlayerTumbleWingsLogic logic) { if (IsNullUnity(logic)) { return; } try { if ((Object)(object)logic.localAudioSource != (Object)null) { logic.localAudioSource.mute = false; if (logic.localAudioSource.volume <= 0f) { logic.localAudioSource.volume = 1f; } } } catch (Exception ex) { LogWarn("localAudioSource unmute failed\n" + ex); } try { if (logic.soundWingsLoop != null && (Object)(object)logic.soundWingsLoop.Source != (Object)null) { logic.soundWingsLoop.Source.mute = false; if (logic.soundWingsLoop.Source.volume <= 0f) { logic.soundWingsLoop.Source.volume = 1f; } } } catch (Exception ex2) { LogWarn("soundWingsLoop unmute failed\n" + ex2); } } private static string NormalizeMode(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return "blue"; } return raw.Trim().ToLowerInvariant() switch { "off" => "off", "blue" => "blue", "pink" => "pink", _ => "blue", }; } private static bool IsNullUnity(object obj) { if (obj == null) { return true; } Object val = (Object)((obj is Object) ? obj : null); if (val != null) { return val == (Object)null; } return false; } private void RequestDelayedReapply(string reason) { if (_delayedReapplyCo != null) { ((MonoBehaviour)this).StopCoroutine(_delayedReapplyCo); _delayedReapplyCo = null; } _delayedReapplyCo = ((MonoBehaviour)this).StartCoroutine(CoDelayedReapply(reason)); } [IteratorStateMachine(typeof(d__52))] private IEnumerator CoDelayedReapply(string reason) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__52(0) { <>4__this = this, reason = reason }; } private static void RequestDelayedReapplyStatic(string reason) { if ((Object)(object)Instance == (Object)null) { return; } try { Instance.RequestDelayedReapply(reason); } catch (Exception ex) { LogWarn("Delayed reapply request failed reason=" + reason + "\n" + ex); } } private void PatchOptionalVisualRefreshMethods() { PatchOptionalMethod("PlayerCosmetics", "SetupCosmeticsLogic", "OptionalSetupCosmeticsLogicPostfix"); PatchOptionalMethod("PlayerCosmetics", "SetupColorsLogic", "OptionalSetupColorsLogicPostfix"); PatchOptionalMethod("PlayerAvatarVisuals", "ApplyLocalVisibilityBody", "OptionalApplyLocalVisibilityBodyPostfix"); } private void PatchOptionalMethod(string typeName, string methodName, string postfixName) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown try { Type type = AccessTools.TypeByName(typeName); if (type == null) { LogInfo("Optional patch skipped. type=" + typeName + " method=" + methodName); return; } MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null); if (methodInfo == null) { LogInfo("Optional patch skipped. type=" + typeName + " method=" + methodName); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(AlwaysWingsViewPlugin), postfixName, (Type[])null, (Type[])null); if (methodInfo2 == null) { LogInfo("Optional patch skipped. postfix=" + postfixName); return; } _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); LogInfo("Optional patch applied. type=" + typeName + " method=" + methodName); } catch (Exception ex) { LogWarn("Optional patch failed. type=" + typeName + " method=" + methodName + "\n" + ex); } } private static void OptionalSetupCosmeticsLogicPostfix(object __instance) { if (!((Object)(object)Instance == (Object)null) && IsComponentOnLocalAvatar(__instance)) { RequestDelayedReapplyStatic("setupCosmeticsLogic"); } } private static void OptionalSetupColorsLogicPostfix(object __instance) { if (!((Object)(object)Instance == (Object)null) && IsComponentOnLocalAvatar(__instance)) { RequestDelayedReapplyStatic("setupColorsLogic"); } } private static void OptionalApplyLocalVisibilityBodyPostfix(object __instance) { if (!((Object)(object)Instance == (Object)null) && IsComponentOnLocalAvatar(__instance)) { RequestDelayedReapplyStatic("applyLocalVisibilityBody"); } } private static bool IsComponentOnLocalAvatar(object componentObject) { if (IsNullUnity(componentObject)) { return false; } PlayerAvatar localAvatar = GetLocalAvatar(); if (IsNullUnity(localAvatar)) { return false; } Component val = (Component)((componentObject is Component) ? componentObject : null); if ((Object)(object)val == (Object)null) { return false; } try { if ((Object)(object)val.gameObject == (Object)(object)((Component)localAvatar).gameObject) { return true; } if ((Object)(object)val.transform != (Object)null && (Object)(object)((Component)localAvatar).transform != (Object)null) { if ((Object)(object)val.transform == (Object)(object)((Component)localAvatar).transform) { return true; } if (val.transform.IsChildOf(((Component)localAvatar).transform)) { return true; } } } catch { return false; } return false; } private static void LogInfo(string message) { Debug.Log((object)("[AlwaysWingsView] " + message)); if (Log != null) { Log.LogInfo((object)message); } } private static void LogWarn(string message) { Debug.LogWarning((object)("[AlwaysWingsView] " + message)); if (Log != null) { Log.LogWarning((object)message); } } private static void LogError(string message) { Debug.LogError((object)("[AlwaysWingsView] " + message)); if (Log != null) { Log.LogError((object)message); } } } }