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 LoudVoiceBoom v1.0.0
Zichen-LoudVoiceBoom.dll
Decompiled 9 hours agousing 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 <ArmGrenadeNextFrame>d__91 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public GameObject grenade; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ArmGrenadeNextFrame>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<ItemToggle>(); 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 <TriggerExplosion>d__88 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PlayerAvatar explosionTarget; public LoudVoiceBoomPlugin <>4__this; public PlayerAvatar speakerAvatar; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TriggerExplosion>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<int, VoiceState> voiceStates = new Dictionary<int, VoiceState>(); private readonly List<int> hudOrderBottomToTop = new List<int>(); private readonly List<int> remoteHudKeys = new List<int>(); private int hudPlayerListSignature; private bool gameplayActivePrevious; private bool gameplayActiveCurrent; private float syncTimer; private int syncedServerTimestamp; private GUIStyle hudLabelStyle; private Harmony harmony; private ConfigEntry<string> moduleNameInfo; private ConfigEntry<string> moduleVersionInfo; private ConfigEntry<string> contactInfo; private ConfigEntry<bool> featureEnabled; private ConfigEntry<int> explosionTriggerThreshold; private ConfigEntry<int> loudnessThreshold; private ConfigEntry<int> explosionCooldownSeconds; private ConfigEntry<string> explosionTargetMode; private ConfigEntry<bool> 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<string>("模组信息", "模组名称", "大声说话就爆炸", new ConfigDescription("当前模组的名称。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000, CustomDrawer = DrawInfo, ReadOnly = true } })); moduleNameInfo.Value = "大声说话就爆炸"; moduleVersionInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组版本号", "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<string>("模组信息", "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<bool>("A.大声说话就爆炸", "启用", true, ConfigDescriptionWithOrder("只需要主机安装即可生效。玩家语音过大时会在自己位置爆炸。", 900)); explosionTargetMode = ((BaseUnityPlugin)this).Config.Bind<string>("A.大声说话就爆炸", "爆炸目标", "自己爆炸", new ConfigDescription("谁来承受爆炸。选择最近或随机时,只会从其他存活玩家中选。没有其他存活玩家时回退为自己爆炸。", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "自己爆炸", "最近玩家爆炸", "随机玩家爆炸" }), new object[1] { new ConfigurationManagerAttributes { Order = 895 } })); showProgressHud = ((BaseUnityPlugin)this).Config.Bind<bool>("A.大声说话就爆炸", "左下角显示进度条", true, ConfigDescriptionWithOrder("开启后,屏幕左下角会显示每个玩家的语音响度和爆炸能量进度。", 890)); explosionTriggerThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("A.大声说话就爆炸", "爆炸触发阈值", 10, new ConfigDescription("说话能量达到这个阈值时触发爆炸。单位为 1,值越高需要说话更久才会爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), new object[1] { new ConfigurationManagerAttributes { Order = 885 } })); loudnessThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("A.大声说话就爆炸", "爆炸加速响度", 2, new ConfigDescription("调整多大的声音会被当成大声说话。数字越小越灵敏,更容易爆炸;数字越大越不容易爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), new object[1] { new ConfigurationManagerAttributes { Order = 880 } })); explosionCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("A.大声说话就爆炸", "爆炸后暂停秒数", 1, new ConfigDescription("爆炸后先停止计算几秒。这段时间内继续说话也不会立刻再次爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(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<PlayerAvatar>(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<object, object>)val).Add((object)"zichen.loudvoiceboom.sync", (object)text); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } private void ReadVoiceStateSync() { if (PhotonNetwork.CurrentRoom == null || !((Dictionary<object, object>)(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(<TriggerExplosion>d__88))] private IEnumerator TriggerExplosion(PlayerAvatar speakerAvatar, PlayerAvatar explosionTarget) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TriggerExplosion>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<GameObject>("Items/Item Grenade Explosive"); if ((Object)(object)val2 != (Object)null) { val = Object.Instantiate<GameObject>(val2, position, Quaternion.identity); } } if (!((Object)(object)val == (Object)null)) { ItemGrenade component = val.GetComponent<ItemGrenade>(); 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(<ArmGrenadeNextFrame>d__91))] private static IEnumerator ArmGrenadeNextFrame(GameObject grenade) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ArmGrenadeNextFrame>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<T>(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<ConfigEntryBase> 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; }