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 <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;
}