using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Zichen-LoudVoiceBoom")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Zichen-LoudVoiceBoom")] [assembly: AssemblyTitle("Zichen-LoudVoiceBoom")] [assembly: AssemblyVersion("1.0.0.0")] [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; } } } [BepInPlugin("zichen.loudvoiceboom", "A.Loud Voice Boom", "1.0.0")] public sealed class LoudVoiceBoomPlugin : BaseUnityPlugin { private sealed class VoiceState { public string PlayerName = "Player"; public PlayerAvatar PlayerAvatar; public bool IsLocal; public float ExplosionEnergy; public float Loudness; public float LoudnessProgress; public float DurationProgress; public float Cooldown; public float LastSeenTime; } [CompilerGenerated] private sealed class d__91 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public GameObject grenade; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__91(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)grenade == (Object)null) { return false; } ItemToggle component = grenade.GetComponent(); if ((Object)(object)component != (Object)null) { component.ToggleItem(true, -1); } 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__88 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PlayerAvatar explosionTarget; public LoudVoiceBoomPlugin <>4__this; public PlayerAvatar speakerAvatar; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__88(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; LoudVoiceBoomPlugin loudVoiceBoomPlugin = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; if ((Object)(object)explosionTarget == (Object)null) { return false; } Vector3 explosionPosition = GetExplosionPosition(explosionTarget); loudVoiceBoomPlugin.SpawnGrenadeExplosion(speakerAvatar ?? explosionTarget, explosionPosition); <>2__current = (object)new WaitForSeconds(0.15f); <>1__state = 1; return true; } case 1: <>1__state = -1; if ((Object)(object)explosionTarget != (Object)null && (Object)(object)explosionTarget.playerHealth != (Object)null && !IsPlayerDeadSet(explosionTarget)) { explosionTarget.playerHealth.HurtOther(100, Vector3.zero, false, -1, false); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "zichen.loudvoiceboom"; public const string PluginName = "A.Loud Voice Boom"; public const string PluginVersion = "1.0.0"; private const string InfoSection = "模组信息"; private const string MainSection = "A.大声说话就爆炸"; private const float DefaultSoftVoiceGain = 0.08f; private const float DefaultLoudVoiceFillSeconds = 0.25f; private const float DefaultEnergyDecayPerSecond = 0.22f; private const int DefaultExplosionTriggerThreshold = 10; private const float LoudnessThresholdScale = 0.1f; private const int DefaultExplosionDamage = 100; private const float SilenceLoudness = 0.002f; private const string TargetSelf = "自己爆炸"; private const string TargetNearest = "最近玩家爆炸"; private const string TargetRandom = "随机玩家爆炸"; private const string ModuleNameChinese = "大声说话就爆炸"; private const string ModuleNameEnglish = "Loud Voice Boom"; private const string SyncPropertyKey = "zichen.loudvoiceboom.sync"; private const float SyncIntervalSeconds = 0.1f; private const int SyncFreshMilliseconds = 1500; private static readonly Color LoudnessBarColor = new Color(1f, 0.72f, 0.15f, 0.95f); private static readonly Color EnergyBarColor = new Color(1f, 0.18f, 0.12f, 0.95f); private static readonly Color BarBackgroundColor = new Color(0.04f, 0.04f, 0.04f, 0.32f); private static readonly Color BarBorderColor = new Color(1f, 1f, 1f, 0.48f); private static readonly Color BarHighlightColor = new Color(1f, 1f, 1f, 0.18f); private static readonly FieldInfo ClipLoudnessNoTtsField = typeof(PlayerVoiceChat).GetField("clipLoudnessNoTTS", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerAvatarField = typeof(PlayerVoiceChat).GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerNameField = typeof(PlayerAvatar).GetField("playerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerWorldSpaceUIPlayerNameField = typeof(PlayerAvatar).GetField("worldSpaceUIPlayerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerAvatarIsDisabledField = typeof(PlayerAvatar).GetField("isDisabled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerAvatarDeadSetField = typeof(PlayerAvatar).GetField("deadSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo GameDirectorCurrentStateField = typeof(GameDirector).GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo RunManagerLevelIsShopField = typeof(RunManager).GetField("levelIsShop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private readonly Dictionary voiceStates = new Dictionary(); private readonly List hudOrderBottomToTop = new List(); private readonly List remoteHudKeys = new List(); private int hudPlayerListSignature; private bool gameplayActivePrevious; private bool gameplayActiveCurrent; private float syncTimer; private int syncedServerTimestamp; private GUIStyle hudLabelStyle; private Harmony harmony; private ConfigEntry moduleNameInfo; private ConfigEntry moduleVersionInfo; private ConfigEntry contactInfo; private ConfigEntry featureEnabled; private ConfigEntry explosionTriggerThreshold; private ConfigEntry loudnessThreshold; private ConfigEntry explosionCooldownSeconds; private ConfigEntry explosionTargetMode; private ConfigEntry showProgressHud; public static LoudVoiceBoomPlugin Instance { get; private set; } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown Instance = this; BindConfig(); harmony = new Harmony("zichen.loudvoiceboom.patch"); harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerVoiceChat), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(LoudVoiceBoomPlugin), "PlayerVoiceChatUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"zichen-loud-voice-boom loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; voiceStates.Clear(); if (Instance == this) { Instance = null; } } private void BindConfig() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Expected O, but got Unknown moduleNameInfo = ((BaseUnityPlugin)this).Config.Bind("模组信息", "模组名称", "大声说话就爆炸", new ConfigDescription("当前模组的名称。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000, CustomDrawer = DrawInfo, ReadOnly = true } })); moduleNameInfo.Value = "大声说话就爆炸"; moduleVersionInfo = ((BaseUnityPlugin)this).Config.Bind("模组信息", "模组版本号", "1.0.0", new ConfigDescription("当前模组版本号。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 990, CustomDrawer = DrawInfo, ReadOnly = true } })); moduleVersionInfo.Value = "1.0.0"; contactInfo = ((BaseUnityPlugin)this).Config.Bind("模组信息", "REPO交流QQ群", "824639225", new ConfigDescription("REPO 游戏交流、BUG 反馈、优化建议、功能请求请加 QQ 群。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 980, CustomDrawer = DrawInfo, ReadOnly = true } })); contactInfo.Value = "824639225"; featureEnabled = ((BaseUnityPlugin)this).Config.Bind("A.大声说话就爆炸", "启用", true, ConfigDescriptionWithOrder("只需要主机安装即可生效。玩家语音过大时会在自己位置爆炸。", 900)); explosionTargetMode = ((BaseUnityPlugin)this).Config.Bind("A.大声说话就爆炸", "爆炸目标", "自己爆炸", new ConfigDescription("谁来承受爆炸。选择最近或随机时,只会从其他存活玩家中选。没有其他存活玩家时回退为自己爆炸。", (AcceptableValueBase)(object)new AcceptableValueList(new string[3] { "自己爆炸", "最近玩家爆炸", "随机玩家爆炸" }), new object[1] { new ConfigurationManagerAttributes { Order = 895 } })); showProgressHud = ((BaseUnityPlugin)this).Config.Bind("A.大声说话就爆炸", "左下角显示进度条", true, ConfigDescriptionWithOrder("开启后,屏幕左下角会显示每个玩家的语音响度和爆炸能量进度。", 890)); explosionTriggerThreshold = ((BaseUnityPlugin)this).Config.Bind("A.大声说话就爆炸", "爆炸触发阈值", 10, new ConfigDescription("说话能量达到这个阈值时触发爆炸。单位为 1,值越高需要说话更久才会爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange(1, 30), new object[1] { new ConfigurationManagerAttributes { Order = 885 } })); loudnessThreshold = ((BaseUnityPlugin)this).Config.Bind("A.大声说话就爆炸", "爆炸加速响度", 2, new ConfigDescription("调整多大的声音会被当成大声说话。数字越小越灵敏,更容易爆炸;数字越大越不容易爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange(1, 5), new object[1] { new ConfigurationManagerAttributes { Order = 880 } })); explosionCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind("A.大声说话就爆炸", "爆炸后暂停秒数", 1, new ConfigDescription("爆炸后先停止计算几秒。这段时间内继续说话也不会立刻再次爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange(0, 30), new object[1] { new ConfigurationManagerAttributes { Order = 870 } })); } private void DrawInfo(ConfigEntryBase entry) { GUILayout.Label(entry.BoxedValue?.ToString() ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) }); } private static ConfigDescription ConfigDescriptionWithOrder(string description, int order) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = order } }); } private static void PlayerVoiceChatUpdatePostfix(PlayerVoiceChat __instance) { Instance?.CheckVoice(__instance); } private void Update() { gameplayActiveCurrent = ShouldRunGameplay(); if (gameplayActivePrevious && !gameplayActiveCurrent) { ResetVoiceEnergies(); } gameplayActivePrevious = gameplayActiveCurrent; if (!gameplayActiveCurrent) { return; } if (IsHostAuthority()) { syncTimer -= Time.deltaTime; if (syncTimer <= 0f) { syncTimer = 0.1f; PublishVoiceStateSync(); } } else { ReadVoiceStateSync(); } } private void CheckVoice(PlayerVoiceChat voiceChat) { if ((Object)(object)voiceChat == (Object)null || !gameplayActiveCurrent || !IsHostAuthority()) { return; } PlayerAvatar fieldValue = GetFieldValue(PlayerAvatarField, voiceChat, null); if ((Object)(object)fieldValue == (Object)null || (Object)(object)fieldValue.playerHealth == (Object)null || IsPlayerDisabled(fieldValue) || IsPlayerDeadSet(fieldValue)) { return; } int playerKey = GetPlayerKey(fieldValue); if (!voiceStates.TryGetValue(playerKey, out var value)) { value = new VoiceState(); voiceStates[playerKey] = value; } value.PlayerName = GetPlayerName(fieldValue); value.PlayerAvatar = fieldValue; value.IsLocal = IsLocalPlayer(fieldValue); value.LastSeenTime = Time.time; if (IsPlayerDisabled(fieldValue) || IsPlayerDeadSet(fieldValue)) { ClearVoiceStateProgress(value); return; } if (value.Cooldown > 0f) { value.Cooldown -= Time.deltaTime; value.LoudnessProgress = 0f; value.DurationProgress = 0f; return; } float num = (value.Loudness = GetFieldValue(ClipLoudnessNoTtsField, voiceChat, 0f)); value.LoudnessProgress = Mathf.Clamp01(num / GetEffectiveLoudnessThreshold()); UpdateExplosionEnergy(value, num); if (!(value.Cooldown > 0f) && !(value.ExplosionEnergy < GetExplosionTriggerThreshold())) { value.ExplosionEnergy = 0f; value.Cooldown = Mathf.Max(0f, (float)explosionCooldownSeconds.Value); ((MonoBehaviour)this).StartCoroutine(TriggerExplosion(fieldValue, ResolveExplosionTarget(fieldValue))); } } private PlayerAvatar ResolveExplosionTarget(PlayerAvatar speaker) { if ((Object)(object)speaker == (Object)null) { return null; } string a = ((explosionTargetMode == null) ? "自己爆炸" : explosionTargetMode.Value); if (string.Equals(a, "最近玩家爆炸", StringComparison.Ordinal)) { PlayerAvatar nearestAliveOtherPlayer = GetNearestAliveOtherPlayer(speaker); if (!((Object)(object)nearestAliveOtherPlayer != (Object)null)) { return speaker; } return nearestAliveOtherPlayer; } if (string.Equals(a, "随机玩家爆炸", StringComparison.Ordinal)) { PlayerAvatar randomAliveOtherPlayer = GetRandomAliveOtherPlayer(speaker); if (!((Object)(object)randomAliveOtherPlayer != (Object)null)) { return speaker; } return randomAliveOtherPlayer; } return speaker; } private static PlayerAvatar GetNearestAliveOtherPlayer(PlayerAvatar speaker) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null) { return null; } PlayerAvatar result = null; float num = float.MaxValue; Vector3 position = ((Component)speaker).transform.position; foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (IsAliveOtherPlayer(player, speaker)) { Vector3 val = ((Component)player).transform.position - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = player; } } } return result; } private static PlayerAvatar GetRandomAliveOtherPlayer(PlayerAvatar speaker) { if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null) { return null; } PlayerAvatar result = null; int num = 0; foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (IsAliveOtherPlayer(player, speaker)) { num++; if (Random.Range(0, num) == 0) { result = player; } } } return result; } private static bool IsAliveOtherPlayer(PlayerAvatar player, PlayerAvatar speaker) { if ((Object)(object)player != (Object)null && (Object)(object)player != (Object)(object)speaker && (Object)(object)player.playerHealth != (Object)null && !IsPlayerDisabled(player)) { return !IsPlayerDeadSet(player); } return false; } private void PublishVoiceStateSync() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_011f: Expected O, but got Unknown if (PhotonNetwork.CurrentRoom == null) { return; } RefreshHudOrderIfNeeded(); string text = PhotonNetwork.ServerTimestamp.ToString(); foreach (int item in hudOrderBottomToTop) { if (voiceStates.TryGetValue(item, out var value)) { if ((Object)(object)value.PlayerAvatar != (Object)null && (IsPlayerDisabled(value.PlayerAvatar) || IsPlayerDeadSet(value.PlayerAvatar))) { ClearVoiceStateProgress(value); } text = text + ";" + item + "," + Mathf.RoundToInt(value.LoudnessProgress * 1000f) + "," + Mathf.RoundToInt(value.DurationProgress * 1000f); } } Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"zichen.loudvoiceboom.sync", (object)text); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } private void ReadVoiceStateSync() { if (PhotonNetwork.CurrentRoom == null || !((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"zichen.loudvoiceboom.sync", out object value) || !(value is string text)) { syncedServerTimestamp = 0; return; } string[] array = text.Split(new char[1] { ';' }); if (array.Length == 0 || !int.TryParse(array[0], out syncedServerTimestamp)) { syncedServerTimestamp = 0; return; } RefreshHudOrderIfNeeded(); for (int i = 1; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ',' }); if (array2.Length >= 3 && int.TryParse(array2[0], out var result) && int.TryParse(array2[1], out var result2) && int.TryParse(array2[2], out var result3)) { if (!voiceStates.TryGetValue(result, out var value2)) { value2 = new VoiceState(); voiceStates[result] = value2; } value2.LoudnessProgress = Mathf.Clamp01((float)result2 * 0.001f); value2.DurationProgress = Mathf.Clamp01((float)result3 * 0.001f); value2.ExplosionEnergy = value2.DurationProgress; value2.LastSeenTime = Time.time; } } } private bool HasFreshVoiceStateSync() { if (syncedServerTimestamp == 0) { return false; } int num = PhotonNetwork.ServerTimestamp - syncedServerTimestamp; if (num >= 0) { return num <= 1500; } return false; } private void UpdateExplosionEnergy(VoiceState state, float loudness) { float effectiveLoudnessThreshold = GetEffectiveLoudnessThreshold(); float num = GetExplosionTriggerThreshold(); float num2 = Mathf.Clamp01(loudness / effectiveLoudnessThreshold); float num3 = Mathf.Lerp(0.08f, 1f, num2 * num2) / 0.25f; if (loudness <= 0.002f) { num3 = 0f; } state.ExplosionEnergy += num3 * 10f * Time.deltaTime; if (num2 < 0.05f) { state.ExplosionEnergy -= 2.2f * Time.deltaTime; } state.ExplosionEnergy = Mathf.Clamp(state.ExplosionEnergy, 0f, num); state.DurationProgress = Mathf.Clamp01(state.ExplosionEnergy / num); } private float GetExplosionTriggerThreshold() { return Mathf.Clamp((float)((explosionTriggerThreshold == null) ? 10 : explosionTriggerThreshold.Value), 1f, 30f); } private float GetEffectiveLoudnessThreshold() { float num = Mathf.Clamp((float)((loudnessThreshold == null) ? 2 : loudnessThreshold.Value), 1f, 5f); return Mathf.Max(0.001f, num * 0.1f); } private void OnGUI() { if (showProgressHud == null || !showProgressHud.Value || !gameplayActiveCurrent || (!IsHostAuthority() && !HasFreshVoiceStateSync())) { return; } float width = 174f; float x = 24f; float num = (float)Screen.height - 246f; RefreshHudOrderIfNeeded(); for (int i = 0; i < hudOrderBottomToTop.Count; i++) { int key = hudOrderBottomToTop[i]; if (voiceStates.TryGetValue(key, out var value)) { if ((Object)(object)value.PlayerAvatar != (Object)null && (IsPlayerDisabled(value.PlayerAvatar) || IsPlayerDeadSet(value.PlayerAvatar))) { ClearVoiceStateProgress(value); } DrawPlayerProgress(x, num - (float)i * 64f, width, value); } } } private void RefreshHudOrderIfNeeded() { int playerListSignature = GetPlayerListSignature(); if (playerListSignature == hudPlayerListSignature) { return; } hudPlayerListSignature = playerListSignature; hudOrderBottomToTop.Clear(); remoteHudKeys.Clear(); int num = 0; if ((Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList != null) { foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (!((Object)(object)player == (Object)null)) { int playerKey = GetPlayerKey(player); if (IsLocalPlayer(player)) { num = playerKey; } else { remoteHudKeys.Add(playerKey); } if (!voiceStates.TryGetValue(playerKey, out var value)) { value = new VoiceState(); voiceStates[playerKey] = value; } value.PlayerName = GetPlayerName(player); value.PlayerAvatar = player; value.IsLocal = IsLocalPlayer(player); value.LastSeenTime = Time.time; } } } if (num != 0) { hudOrderBottomToTop.Add(num); } foreach (int remoteHudKey in remoteHudKeys) { hudOrderBottomToTop.Add(remoteHudKey); } } private static int GetPlayerListSignature() { if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null) { return 0; } int num = 17; foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (!((Object)(object)player == (Object)null)) { num = num * 31 + GetPlayerKey(player); num = num * 31 + (IsLocalPlayer(player) ? 1 : 0); } } return num; } private void DrawPlayerProgress(float x, float y, float width, VoiceState state) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0092: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0035: Expected O, but got Unknown if (hudLabelStyle == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 16 }; val.normal.textColor = Color.white; hudLabelStyle = val; } GUI.Label(new Rect(x, y, width, 22f), state.PlayerName, hudLabelStyle); DrawBar(new Rect(x, y + 27f, width, 15f), state.LoudnessProgress, LoudnessBarColor); DrawBar(new Rect(x, y + 48f, width, 15f), state.DurationProgress, EnergyBarColor); } private static void DrawBar(Rect rect, float progress, Color fillColor) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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) Color color = GUI.color; DrawRoundedBar(rect, BarBackgroundColor); GUI.color = fillColor; float num = ((Rect)(ref rect)).width * Mathf.Clamp01(progress); if (num > 0f) { DrawRoundedBar(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, num, ((Rect)(ref rect)).height), fillColor); GUI.color = BarHighlightColor; DrawRoundedBar(new Rect(((Rect)(ref rect)).x + 2f, ((Rect)(ref rect)).y + 2f, Mathf.Max(0f, num - 4f), ((Rect)(ref rect)).height * 0.32f), BarHighlightColor); } DrawRoundedBorder(rect); GUI.color = color; } private static void DrawRoundedBar(Rect rect, Color color) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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) if (!(((Rect)(ref rect)).width <= 0f) && !(((Rect)(ref rect)).height <= 0f)) { float num = ((Rect)(ref rect)).height * 0.5f; GUI.color = color; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + num, ((Rect)(ref rect)).y, Mathf.Max(0f, ((Rect)(ref rect)).width - ((Rect)(ref rect)).height), ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + num * 0.5f, ((Rect)(ref rect)).width, num), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + num * 0.5f, ((Rect)(ref rect)).y + num * 0.2f, Mathf.Max(0f, ((Rect)(ref rect)).width - num), ((Rect)(ref rect)).height * 0.6f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + num * 0.2f, ((Rect)(ref rect)).y + num * 0.35f, Mathf.Max(0f, ((Rect)(ref rect)).width - num * 0.4f), ((Rect)(ref rect)).height * 0.3f), (Texture)(object)Texture2D.whiteTexture); } } private static void DrawRoundedBorder(Rect rect) { //IL_0000: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_0141: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) GUI.color = BarBorderColor; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 7f, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width - 14f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 7f, ((Rect)(ref rect)).yMax - 1f, ((Rect)(ref rect)).width - 14f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 7f, 1f, ((Rect)(ref rect)).height - 14f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 1f, ((Rect)(ref rect)).y + 7f, 1f, ((Rect)(ref rect)).height - 14f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 3f, ((Rect)(ref rect)).y + 3f, 5f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 1f, ((Rect)(ref rect)).y + 5f, 1f, 5f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 8f, ((Rect)(ref rect)).y + 3f, 5f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 2f, ((Rect)(ref rect)).y + 5f, 1f, 5f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 3f, ((Rect)(ref rect)).yMax - 4f, 5f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 1f, ((Rect)(ref rect)).yMax - 10f, 1f, 5f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 8f, ((Rect)(ref rect)).yMax - 4f, 5f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - 2f, ((Rect)(ref rect)).yMax - 10f, 1f, 5f), (Texture)(object)Texture2D.whiteTexture); } private bool ShouldRunGameplay() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Invalid comparison between Unknown and I4 if (featureEnabled == null || !featureEnabled.Value || !SemiFunc.IsMultiplayer()) { return false; } if (!SemiFunc.RunIsLevel() || SemiFunc.RunIsShop() || SemiFunc.RunIsArena()) { return false; } if ((Object)(object)RunManager.instance != (Object)null && GetFieldValue(RunManagerLevelIsShopField, RunManager.instance, fallback: false)) { return false; } if ((Object)(object)GameDirector.instance == (Object)null) { return false; } if (GameDirectorCurrentStateField?.GetValue(GameDirector.instance) is gameState val) { return (int)val == 2; } return false; } private void ResetVoiceEnergies() { foreach (VoiceState value in voiceStates.Values) { ClearVoiceStateProgress(value); value.Cooldown = 0f; } } private static void ClearVoiceStateProgress(VoiceState state) { state.ExplosionEnergy = 0f; state.Loudness = 0f; state.LoudnessProgress = 0f; state.DurationProgress = 0f; } private static string GetPlayerName(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return "Player"; } if (PlayerNameField?.GetValue(playerAvatar) is string text && !string.IsNullOrWhiteSpace(text)) { return text.Trim(); } string worldSpacePlayerNameText = GetWorldSpacePlayerNameText(PlayerWorldSpaceUIPlayerNameField?.GetValue(playerAvatar)); if (!string.IsNullOrWhiteSpace(worldSpacePlayerNameText)) { return worldSpacePlayerNameText.Trim(); } try { string text2 = SemiFunc.PlayerGetName(playerAvatar); if (!string.IsNullOrEmpty(text2)) { return text2; } } catch { } if (!string.IsNullOrWhiteSpace(((Object)playerAvatar).name)) { return ((Object)playerAvatar).name.Replace("(Clone)", string.Empty).Trim(); } return "Player"; } private static string GetWorldSpacePlayerNameText(object worldSpaceName) { if (worldSpaceName == null) { return null; } try { object obj = worldSpaceName.GetType().GetField("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(worldSpaceName); if (obj == null) { return null; } if (obj.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj, null) is string text && !string.IsNullOrWhiteSpace(text)) { return text; } return obj.GetType().GetField("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) as string; } catch { return null; } } private static int GetPlayerKey(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return 0; } if ((Object)(object)playerAvatar.photonView != (Object)null && playerAvatar.photonView.ViewID != 0) { return playerAvatar.photonView.ViewID; } return ((Object)playerAvatar).GetInstanceID(); } private static bool IsLocalPlayer(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return false; } if ((Object)(object)playerAvatar.photonView != (Object)null) { return playerAvatar.photonView.IsMine; } return (Object)(object)PlayerAvatar.instance == (Object)(object)playerAvatar; } [IteratorStateMachine(typeof(d__88))] private IEnumerator TriggerExplosion(PlayerAvatar speakerAvatar, PlayerAvatar explosionTarget) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__88(0) { <>4__this = this, speakerAvatar = speakerAvatar, explosionTarget = explosionTarget }; } private static Vector3 GetExplosionPosition(PlayerAvatar playerAvatar) { //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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)playerAvatar != (Object)null && (Object)(object)playerAvatar.PlayerVisionTarget != (Object)null && (Object)(object)playerAvatar.PlayerVisionTarget.VisionTransform != (Object)null) { return playerAvatar.PlayerVisionTarget.VisionTransform.position; } if (!((Object)(object)playerAvatar != (Object)null)) { return Vector3.zero; } return ((Component)playerAvatar).transform.position + Vector3.up * 0.7f; } private void SpawnGrenadeExplosion(PlayerAvatar playerAvatar, Vector3 position) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = null; if (SemiFunc.IsMultiplayer()) { val = PhotonNetwork.InstantiateRoomObject("Items/Item Grenade Explosive", position, Quaternion.identity, (byte)0, (object[])null); } else { GameObject val2 = Resources.Load("Items/Item Grenade Explosive"); if ((Object)(object)val2 != (Object)null) { val = Object.Instantiate(val2, position, Quaternion.identity); } } if (!((Object)(object)val == (Object)null)) { ItemGrenade component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.tickTime = 0.05f; component.SetActivator(playerAvatar); } ((MonoBehaviour)this).StartCoroutine(ArmGrenadeNextFrame(val)); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to spawn loud voice explosion: " + ex.GetType().Name + ": " + ex.Message)); } } [IteratorStateMachine(typeof(d__91))] private static IEnumerator ArmGrenadeNextFrame(GameObject grenade) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__91(0) { grenade = grenade }; } private static bool IsHostAuthority() { try { return SemiFunc.IsMasterClientOrSingleplayer(); } catch { return !GameManager.Multiplayer() || PhotonNetwork.IsMasterClient; } } private static bool IsPlayerDisabled(PlayerAvatar playerAvatar) { return GetFieldValue(PlayerAvatarIsDisabledField, playerAvatar, fallback: false); } private static bool IsPlayerDeadSet(PlayerAvatar playerAvatar) { return GetFieldValue(PlayerAvatarDeadSetField, playerAvatar, fallback: false); } private static T GetFieldValue(FieldInfo field, object instance, T fallback) { try { if (field != null) { object value = field.GetValue(instance); if (value is T) { return (T)value; } } } catch { } return fallback; } } internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; }