using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using DeadAndBored.Configuration;
using DeadAndBored.Patches;
using Dissonance.Audio.Playback;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using SpectateEnemy;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("DeadAndBored")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("DeadAndBored")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DeadAndBored")]
[assembly: AssemblyTitle("DeadAndBored")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace DeadAndBored
{
internal class BroadcastParameters
{
public string controllerName;
public string enemyName;
public float x;
public float y;
public float z;
}
internal class DeadAndBoredObject : MonoBehaviour
{
public static DeadAndBoredObject Instance = null;
private bool wasSpectatingEnemies = false;
private GameObject oldSpectatingEnemy = null;
public bool isDeadAndTalking = false;
private bool wasPushToTalk = false;
private static string deadAndTalkingUniqueName = "TheDeadTalk";
private static string deadAndStopTalkingUniqueName = "TheDeadStopTalk";
public static void DABLogging(string logString)
{
if (Config.enableDebugLogging)
{
Debug.Log((object)("DEAD AND BORED: " + logString));
}
}
public static bool IsInputUtilsInstalled()
{
return Chainloader.PluginInfos.ContainsKey("com.rune580.LethalCompanyInputUtils");
}
private void Awake()
{
if ((Object)(object)Instance != (Object)null)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
Init();
SceneManager.activeSceneChanged += OnSceneChanged;
Debug.Log((object)$"DeadAndBored Debugger: {Config.enableDebugLogging}");
}
private void OnSceneChanged(Scene old, Scene newScene)
{
Reset();
}
private void Update()
{
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
if (IsInputUtilsInstalled() && Plugin.inputActions.ResetAudio.triggered)
{
Reset();
}
if (!SpectateEnemiesAPI.IsLoaded)
{
return;
}
if ((Object)(object)oldSpectatingEnemy != (Object)(object)SpectateEnemiesAPI.CurrentEnemySpectating())
{
oldSpectatingEnemy = SpectateEnemiesAPI.CurrentEnemySpectating();
if (isDeadAndTalking)
{
StopTalk(((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).NetworkObjectId);
}
}
if (wasSpectatingEnemies != SpectateEnemiesAPI.IsSpectatingEnemies)
{
wasSpectatingEnemies = SpectateEnemiesAPI.IsSpectatingEnemies;
if (isDeadAndTalking)
{
StopTalk(((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).NetworkObjectId);
}
}
if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || !GameNetworkManager.Instance.localPlayerController.isPlayerDead)
{
return;
}
if (SpectateEnemiesAPI.IsSpectatingEnemies)
{
bool flag = false;
if (IsInputUtilsInstalled() && Plugin.inputActions.TalkKey.triggered && !isDeadAndTalking)
{
flag = true;
}
if (flag)
{
BroadcastParameters broadcastParameters = new BroadcastParameters();
broadcastParameters.controllerName = ((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).NetworkObjectId.ToString();
GameObject val = SpectateEnemiesAPI.CurrentEnemySpectating();
if ((Object)(object)val != (Object)null)
{
broadcastParameters.enemyName = ((Object)val).name;
broadcastParameters.x = val.transform.position.x;
broadcastParameters.y = val.transform.position.y;
broadcastParameters.z = val.transform.position.z;
Talk(broadcastParameters);
}
}
}
bool flag2 = false;
if (IsInputUtilsInstalled() && !Plugin.inputActions.TalkKey.IsPressed() && isDeadAndTalking)
{
flag2 = true;
}
if (flag2)
{
StopTalk(((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).NetworkObjectId);
}
}
private void Talk(BroadcastParameters param)
{
if (IngamePlayerSettings.Instance.settings.pushToTalk)
{
IngamePlayerSettings.Instance.settings.pushToTalk = false;
wasPushToTalk = true;
}
isDeadAndTalking = true;
string s = JsonUtility.ToJson((object)param);
byte[] bytes = Encoding.UTF8.GetBytes(s);
NetworkUtils.instance.SendToAll(deadAndTalkingUniqueName, bytes);
DABLogging("Begin talk for player: " + param.controllerName);
StartOfRound.Instance.UpdatePlayerVoiceEffects();
}
private void StopTalk(ulong controllerName)
{
if (wasPushToTalk)
{
IngamePlayerSettings.Instance.settings.pushToTalk = true;
wasPushToTalk = false;
}
isDeadAndTalking = false;
byte[] bytes = Encoding.UTF8.GetBytes(controllerName.ToString());
NetworkUtils.instance.SendToAll(deadAndStopTalkingUniqueName, bytes);
DABLogging($"Stop talk for player: {controllerName}");
StartOfRound.Instance.UpdatePlayerVoiceEffects();
}
public void Init()
{
NetworkUtils.Init();
NetworkUtils.instance.OnNetworkData = OnRecieveData;
Reset();
}
private void OnRecieveData(string type, byte[] message)
{
string @string = Encoding.Default.GetString(message, 0, message.Length);
DABLogging("Recieved Message: " + @string);
if (type == deadAndTalkingUniqueName)
{
BroadcastParameters param = JsonUtility.FromJson<BroadcastParameters>(@string);
TheDeadTalk(param);
}
else if (type == deadAndStopTalkingUniqueName)
{
TheDeadStopTalk(@string);
}
else if (type == NetworkUtils.HostRelayID)
{
DABLogging("Host recieved relay message");
if (NetworkManager.Singleton.IsHost)
{
NetworkUtils.RelayObject relayObject = JsonUtility.FromJson<NetworkUtils.RelayObject>(@string);
string tag = relayObject.tag;
byte[] data = relayObject.data;
NetworkUtils.instance.SendToAll(tag, data);
}
else
{
DABLogging("Error: Sent host relay to non-host");
}
}
else
{
DABLogging("Invalid message type");
}
}
public void Reset()
{
DABLogging("CALLING RESET");
if (isDeadAndTalking && (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
{
StopTalk(((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).NetworkObjectId);
}
isDeadAndTalking = false;
if (UpdatePlayerVoiceEffectsPatch.Configs != null)
{
UpdatePlayerVoiceEffectsPatch.Configs.Clear();
}
if ((Object)(object)StartOfRound.Instance != (Object)null)
{
StartOfRound.Instance.UpdatePlayerVoiceEffects();
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if (!((Object)(object)val != (Object)null) || !((Object)(object)val.currentVoiceChatAudioSource != (Object)null))
{
continue;
}
if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
{
if ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)(object)val)
{
val.currentVoiceChatAudioSource.volume = 1f;
}
}
else
{
val.currentVoiceChatAudioSource.volume = 1f;
}
}
}
if (SpectateEnemiesAPI.IsLoaded)
{
wasSpectatingEnemies = SpectateEnemiesAPI.IsSpectatingEnemies;
}
else
{
wasSpectatingEnemies = false;
}
wasPushToTalk = false;
oldSpectatingEnemy = null;
}
private void TheDeadTalk(BroadcastParameters param)
{
PlayerControllerB val = FindPlayerByNetworkID(param.controllerName);
DABLogging("--------------- Talking Player recieved: " + param.controllerName);
if ((Object)(object)val == (Object)null)
{
return;
}
DABLogging($"UpdatePlayerVoiceEffects Contains Player: {UpdatePlayerVoiceEffectsPatch.Configs.ContainsKey(val)}");
if (UpdatePlayerVoiceEffectsPatch.Configs.ContainsKey(val))
{
AudioConfig audioConfig = UpdatePlayerVoiceEffectsPatch.Configs[val];
GameObject val2 = FindEnemyByNameAndPos(param);
if ((Object)(object)val2 != (Object)null)
{
audioConfig.EnemyT = val2.transform;
}
else
{
DABLogging("Could not find enemy from name and position");
}
UpdatePlayerVoiceEffectsPatch.Configs[val] = audioConfig;
}
DABLogging("-------------- Finishing The Dead Talk");
StartOfRound.Instance.UpdatePlayerVoiceEffects();
}
private void TheDeadStopTalk(string controllerID)
{
DABLogging("-------------- Start The Dead Stop Talk");
PlayerControllerB val = FindPlayerByNetworkID(controllerID);
DABLogging($"Found Player: {(Object)(object)val != (Object)null}");
if (!((Object)(object)val == (Object)null))
{
DABLogging($"Config Contains Player: {UpdatePlayerVoiceEffectsPatch.Configs.ContainsKey(val)}");
if (UpdatePlayerVoiceEffectsPatch.Configs.ContainsKey(val))
{
AudioConfig audioConfig = UpdatePlayerVoiceEffectsPatch.Configs[val];
audioConfig.EnemyT = null;
UpdatePlayerVoiceEffectsPatch.Configs[val] = audioConfig;
StartOfRound.Instance.UpdatePlayerVoiceEffects();
DABLogging("-------------- Finish The Dead Stop Talk");
}
}
}
private PlayerControllerB FindPlayerByNetworkID(string networkID)
{
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
foreach (PlayerControllerB val in array)
{
if (ulong.TryParse(networkID, out var result))
{
if (((NetworkBehaviour)val).NetworkObjectId == result)
{
return val;
}
}
else
{
DABLogging("Invalid format: " + networkID);
}
}
return null;
}
private GameObject FindEnemyByNameAndPos(BroadcastParameters bParams)
{
//IL_005a: 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_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(bParams.x, bParams.y, bParams.z);
GameObject[] array = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0);
float num = float.PositiveInfinity;
GameObject result = null;
GameObject[] array2 = array;
foreach (GameObject val2 in array2)
{
if (((Object)val2).name == bParams.enemyName)
{
float num2 = Vector3.Distance(val2.transform.position, val);
if (Vector3.Distance(val2.transform.position, val) < num)
{
result = val2;
num = num2;
}
}
}
return result;
}
}
public class DeadAndBoredAPI
{
public static bool IsLoaded => (Object)(object)DeadAndBoredObject.Instance != (Object)null;
public static bool IsDeadAndTalking => DeadAndBoredObject.Instance.isDeadAndTalking;
}
public class InputActions : LcInputActions
{
[InputAction("<Keyboard>/y", Name = "Key To Talk")]
public InputAction TalkKey { get; set; }
[InputAction("<Keyboard>/u", Name = "Reset Audio Data (Failsafe, should only use if can't hear other people)")]
public InputAction ResetAudio { get; set; }
}
public struct NetworkMessage
{
public string MessageTag;
public ulong TargetId;
public Hash128 Checksum;
public byte[] Data;
}
public class NetworkUtils : MonoBehaviour
{
public class RelayObject
{
public string tag;
public byte[] data;
}
public static NetworkUtils instance;
public Action<string, byte[]> OnNetworkData;
public Action OnDisconnect;
public Action OnConnect;
private bool _initialized;
private bool _connected;
public static string HostRelayID = "HOST_RELAY";
public bool IsConnected => _connected;
public static void Init()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
if ((Object)(object)instance == (Object)null)
{
GameObject val = new GameObject();
((Object)val).name = "DeadAndBored Network Util";
NetworkUtils networkUtils = val.AddComponent<NetworkUtils>();
instance = networkUtils;
Object.DontDestroyOnLoad((Object)(object)val);
DeadAndBoredObject.DABLogging("Init Network Utils");
}
}
private void Initialize()
{
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.CustomMessagingManager != null)
{
_initialized = true;
DeadAndBoredObject.DABLogging("[Network Transport] Initialized");
}
}
private void UnInitialize()
{
if (_connected)
{
Disconnected();
}
_initialized = false;
}
private void Connected()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
NetworkManager.Singleton.CustomMessagingManager.OnUnnamedMessage += new UnnamedMessageDelegate(OnMessageEvent);
OnConnect?.Invoke();
_connected = true;
DeadAndBoredObject.DABLogging("[Network Transport] Connected");
}
private void Disconnected()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
NetworkManager singleton = NetworkManager.Singleton;
if ((((Object)(object)singleton != (Object)null) ? singleton.CustomMessagingManager : null) != null)
{
NetworkManager.Singleton.CustomMessagingManager.OnUnnamedMessage -= new UnnamedMessageDelegate(OnMessageEvent);
}
OnDisconnect?.Invoke();
_connected = false;
DeadAndBoredObject.DABLogging("[Network Transport] Disconnected");
}
public void Update()
{
if (!_initialized)
{
Initialize();
}
else if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
UnInitialize();
}
else if (!_connected && NetworkManager.Singleton.IsConnectedClient)
{
Connected();
}
else if (_connected && !NetworkManager.Singleton.IsConnectedClient)
{
Disconnected();
}
}
private void OnMessageEvent(ulong clientId, FastBufferReader reader)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
Hash128 val = default(Hash128);
string text = "";
NetworkMessage networkMessage = default(NetworkMessage);
try
{
((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
DeadAndBoredObject.DABLogging($"[Network Transport] Incoming message from {clientId} {text}");
networkMessage = JsonUtility.FromJson<NetworkMessage>(text);
val = Hash128.Compute<byte>(networkMessage.Data);
}
catch (Exception ex)
{
Debug.LogException(ex);
}
if (val != default(Hash128) && ((Hash128)(ref val)).CompareTo(val) == 0)
{
OnNetworkData?.Invoke(networkMessage.MessageTag, networkMessage.Data);
}
}
public void RelayToHost(string tag, byte[] data)
{
if (!NetworkManager.Singleton.IsHost)
{
ulong num = 0uL;
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if (((NetworkBehaviour)val).IsHost)
{
num = val.actualClientId;
}
}
RelayObject relayObject = new RelayObject();
relayObject.tag = tag;
relayObject.data = data;
string s = JsonUtility.ToJson((object)relayObject);
byte[] bytes = Encoding.UTF8.GetBytes(s);
DeadAndBoredObject.DABLogging($"Relay message from to host {num}");
SendTo(num, HostRelayID, bytes);
}
else
{
DeadAndBoredObject.DABLogging("Error: Trying to relay when already host");
}
}
public void SendToAll(string tag, byte[] data)
{
if (!_initialized)
{
return;
}
if (NetworkManager.Singleton.IsHost)
{
foreach (var (num2, val2) in NetworkManager.Singleton.ConnectedClients)
{
SendTo(val2.ClientId, tag, data);
}
return;
}
RelayToHost(tag, data);
}
public void SendTo(ulong clientId, string tag, byte[] data)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
if (!_initialized)
{
return;
}
NetworkMessage networkMessage = default(NetworkMessage);
networkMessage.MessageTag = tag;
networkMessage.TargetId = clientId;
networkMessage.Data = data;
networkMessage.Checksum = Hash128.Compute<byte>(data);
string text = JsonUtility.ToJson((object)networkMessage);
int writeSize = FastBufferWriter.GetWriteSize(text, false);
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(writeSize, (Allocator)2, -1);
try
{
DeadAndBoredObject.DABLogging($"Send To: Write Size{writeSize}");
((FastBufferWriter)(ref val)).WriteValue(text, false);
NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, val, (NetworkDelivery)4);
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
}
[BepInPlugin("DeadAndBored", "DeadAndBored", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private Harmony harmony;
public static InputActions inputActions = new InputActions();
private void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
harmony = new Harmony("DeadAndBored");
Config.Init();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Dead And Bored loaded!");
harmony.PatchAll();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "DeadAndBored";
public const string PLUGIN_NAME = "DeadAndBored";
public const string PLUGIN_VERSION = "1.1.0";
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "DeadAndBored";
public const string PLUGIN_NAME = "DeadAndBored";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace DeadAndBored.Patches
{
internal class AudioConfig
{
private PlayerControllerB playerControllerB;
private Transform enemyTransform;
private bool lowPassFilter = false;
private bool highPassFilter = false;
private float panStereo = 0f;
private float playerVoicePitchTargets = 0f;
private float playerPitch = 0f;
private float spatialBlend = 0f;
private bool set2D = false;
private float volume = 0f;
public bool LowPassFilter => lowPassFilter;
public bool HighPassFilter => highPassFilter;
public float PanStereo => panStereo;
public float PlayerVoicePitchTargets => playerVoicePitchTargets;
public float PlayerPitch => playerPitch;
public float SpatialBlend => spatialBlend;
public bool Set2D => set2D;
public float Volume => volume;
public Transform EnemyT
{
get
{
return ((Object)(object)enemyTransform == (Object)null) ? null : enemyTransform;
}
set
{
enemyTransform = value;
}
}
public Transform AudioSourceT => ((Component)playerControllerB.currentVoiceChatAudioSource).transform;
public AudioConfig(PlayerControllerB playerControllerB, bool lowPassFilter, bool highPassFilter, float panStereo, float playerVoicePitchTargets, float playerPitch, float spatialBlend, bool set2D, float volume)
{
this.playerControllerB = playerControllerB;
enemyTransform = null;
this.lowPassFilter = lowPassFilter;
this.highPassFilter = highPassFilter;
this.panStereo = panStereo;
this.playerVoicePitchTargets = playerVoicePitchTargets;
this.playerPitch = playerPitch;
this.spatialBlend = spatialBlend;
this.set2D = set2D;
this.volume = volume;
}
}
[HarmonyPatch]
internal class DissonancePatch
{
public static MethodBase TargetMethod()
{
return AccessTools.FirstMethod(typeof(VoicePlayback), (Func<MethodInfo, bool>)((MethodInfo method) => method.Name.Contains("SetTransform")));
}
private static bool Prefix(object __instance)
{
foreach (AudioConfig value in UpdatePlayerVoiceEffectsPatch.Configs.Values)
{
if ((Object)(object)value.EnemyT == (Object)null || !((object)((Component)((__instance is VoicePlayback) ? __instance : null)).transform).Equals((object?)value.AudioSourceT))
{
continue;
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(HUDManager), "Update")]
internal class HUDManagerPatch
{
private static void Postfix(HUDManager __instance)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: 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_0033: Unknown result type (might be due to invalid IL or missing references)
if (SpectateEnemiesAPI.IsSpectatingEnemies && Config.enableTooltip)
{
InputBinding val = Plugin.inputActions.TalkKey.bindings[0];
string buttonString = GetButtonString(((InputBinding)(ref val)).effectivePath);
if (DeadAndBoredObject.Instance.isDeadAndTalking)
{
TextMeshProUGUI holdButtonToEndGameEarlyText = __instance.holdButtonToEndGameEarlyText;
((TMP_Text)holdButtonToEndGameEarlyText).text = ((TMP_Text)holdButtonToEndGameEarlyText).text + "\n\n<color=#1c73ff>Talk As Enemy: [" + buttonString + "]</color>";
}
else
{
TextMeshProUGUI holdButtonToEndGameEarlyText2 = __instance.holdButtonToEndGameEarlyText;
((TMP_Text)holdButtonToEndGameEarlyText2).text = ((TMP_Text)holdButtonToEndGameEarlyText2).text + "\n\nTalk As Enemy: [" + buttonString + "]";
}
}
}
private static string GetButtonString(string path)
{
string result = "";
if (DeadAndBoredObject.IsInputUtilsInstalled())
{
result = InputControlPath.ToHumanReadableString(path, (HumanReadableStringOptions)2, (InputControl)null);
}
return result;
}
}
[HarmonyPatch(typeof(QuickMenuManager), "Start")]
internal class QuickMenuManager_Patches
{
private static void Postfix(QuickMenuManager __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
if ((Object)(object)DeadAndBoredObject.Instance == (Object)null)
{
GameObject val = new GameObject("DeadAndBoredObject");
val.AddComponent<DeadAndBoredObject>();
}
}
}
[HarmonyPatch(typeof(StartOfRound), "Start")]
internal class StartOfRoundPatch
{
private static void Postfix()
{
DeadAndBoredObject.DABLogging($"PostFix Start: {(Object)(object)DeadAndBoredObject.Instance != (Object)null}");
if ((Object)(object)DeadAndBoredObject.Instance != (Object)null)
{
DeadAndBoredObject.Instance.Reset();
}
}
}
[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
internal class ShipLeavePatch
{
private static void Postfix()
{
DeadAndBoredObject.DABLogging($"Postfix Leave: {(Object)(object)DeadAndBoredObject.Instance != (Object)null}");
if ((Object)(object)DeadAndBoredObject.Instance != (Object)null)
{
DeadAndBoredObject.Instance.Reset();
}
}
}
[HarmonyPatch(typeof(StartOfRound), "UpdatePlayerVoiceEffects")]
internal class UpdatePlayerVoiceEffectsPatch
{
private static bool updateStarted = false;
private static Dictionary<PlayerControllerB, AudioConfig> configs = new Dictionary<PlayerControllerB, AudioConfig>();
public static Dictionary<PlayerControllerB, AudioConfig> Configs => configs;
[HarmonyBefore(new string[] { "BiggerLobby" })]
private static void Prefix()
{
if (configs == null)
{
configs = new Dictionary<PlayerControllerB, AudioConfig>();
}
if (!updateStarted)
{
((MonoBehaviour)HUDManager.Instance).StartCoroutine(UpdateNumerator());
updateStarted = true;
}
if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null)
{
return;
}
for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
{
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
if (!((Object)(object)val == (Object)null) && (val.isPlayerControlled || val.isPlayerDead) && (Object)(object)val != (Object)(object)GameNetworkManager.Instance.localPlayerController)
{
AudioSource currentVoiceChatAudioSource = val.currentVoiceChatAudioSource;
if (!((Object)(object)currentVoiceChatAudioSource == (Object)null) && val.isPlayerDead && !configs.ContainsKey(val))
{
DeadAndBoredObject.DABLogging($"------- -- - -- ADD Player to configs: {((NetworkBehaviour)val).NetworkObjectId}");
DeadAndBoredObject.DABLogging("-------------------------------");
Dictionary<PlayerControllerB, AudioConfig> dictionary = configs;
float panStereo = (currentVoiceChatAudioSource.panStereo = 0f);
dictionary.Add(val, new AudioConfig(val, lowPassFilter: true, highPassFilter: false, panStereo, 1f, 1f, 1f, set2D: false, 1f));
}
}
}
}
private static void Postfix()
{
//IL_0285: Unknown result type (might be due to invalid IL or missing references)
if (configs == null)
{
configs = new Dictionary<PlayerControllerB, AudioConfig>();
}
if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
{
return;
}
PlayerControllerB[] array = configs.Keys.ToArray();
foreach (PlayerControllerB val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
AudioConfig audioConfig = configs[val];
if (audioConfig == null)
{
continue;
}
DeadAndBoredObject.DABLogging($"PlayerControllerB: {((NetworkBehaviour)val).NetworkObjectId}");
if (GameNetworkManager.Instance.localPlayerController.isPlayerDead && val.isPlayerDead && (Object)(object)configs[val].EnemyT != (Object)null && !Config.hearOtherDeadTeammates)
{
val.currentVoiceChatAudioSource.spatialBlend = 1f;
val.currentVoiceChatIngameSettings.set2D = false;
val.voicePlayerState.Volume = 0f;
DeadAndBoredObject.DABLogging($"Stopping volume of Player {((NetworkBehaviour)val).NetworkObjectId}");
continue;
}
DeadAndBoredObject.DABLogging("---------------------------------------------------------");
DeadAndBoredObject.DABLogging($"Player Controlled: {val.isPlayerControlled}");
DeadAndBoredObject.DABLogging($"Is Player Dead: {val.isPlayerDead}");
DeadAndBoredObject.DABLogging($"Local Player: {GameNetworkManager.Instance.localPlayerController}");
DeadAndBoredObject.DABLogging("---------------------------------------------------------");
if ((val.isPlayerControlled || val.isPlayerDead) && !((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController))
{
DeadAndBoredObject.DABLogging($"Current Voice Chat Audio Source: {(Object)(object)val.currentVoiceChatAudioSource != (Object)null}");
if ((Object)(object)val.currentVoiceChatAudioSource == (Object)null)
{
continue;
}
AudioSource currentVoiceChatAudioSource = val.currentVoiceChatAudioSource;
DeadAndBoredObject.DABLogging($"Enemy Voice Chat Audio Source: {(Object)(object)configs[val].EnemyT != (Object)null}");
if ((Object)(object)configs[val].EnemyT != (Object)null)
{
((Component)currentVoiceChatAudioSource).transform.position = configs[val].EnemyT.position;
currentVoiceChatAudioSource.panStereo = audioConfig.PanStereo;
currentVoiceChatAudioSource.spatialBlend = audioConfig.SpatialBlend;
AudioLowPassFilter component = ((Component)currentVoiceChatAudioSource).GetComponent<AudioLowPassFilter>();
AudioHighPassFilter component2 = ((Component)currentVoiceChatAudioSource).GetComponent<AudioHighPassFilter>();
if ((Object)(object)component != (Object)null)
{
((Behaviour)component).enabled = audioConfig.LowPassFilter;
}
if ((Object)(object)component2 != (Object)null)
{
((Behaviour)component2).enabled = audioConfig.HighPassFilter;
}
if ((Object)(object)SoundManager.Instance != (Object)null)
{
SoundManager.Instance.playerVoicePitchTargets[(int)(IntPtr)(long)val.playerClientId] = audioConfig.PlayerVoicePitchTargets;
SoundManager.Instance.SetPlayerPitch(audioConfig.PlayerPitch, (int)val.playerClientId);
}
val.currentVoiceChatIngameSettings.set2D = audioConfig.Set2D;
val.voicePlayerState.Volume = audioConfig.Volume;
val.currentVoiceChatAudioSource.volume = audioConfig.Volume;
}
}
else if (!val.isPlayerDead)
{
configs.Remove(val);
}
}
}
private static IEnumerator UpdateNumerator()
{
yield return 0;
while (true)
{
UpdatePlayersStatus();
yield return (object)new WaitForFixedUpdate();
}
}
private static void UpdatePlayersStatus()
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
if (configs == null)
{
return;
}
bool flag = false;
KeyValuePair<PlayerControllerB, AudioConfig>[] array = configs.ToArray();
for (int i = 0; i < array.Length; i++)
{
KeyValuePair<PlayerControllerB, AudioConfig> keyValuePair = array[i];
if (!((Object)(object)keyValuePair.Key == (Object)null))
{
if (!keyValuePair.Key.isPlayerDead)
{
configs.Remove(keyValuePair.Key);
flag = true;
}
else if ((Object)(object)keyValuePair.Value.EnemyT != (Object)null && (Object)(object)keyValuePair.Value.AudioSourceT != (Object)null)
{
keyValuePair.Value.AudioSourceT.position = keyValuePair.Value.EnemyT.position;
}
}
}
if (flag)
{
StartOfRound.Instance.UpdatePlayerVoiceEffects();
}
}
private static float GetPitch(PlayerControllerB playerControllerB)
{
int num = (int)playerControllerB.playerClientId;
float result = default(float);
SoundManager.Instance.diageticMixer.GetFloat($"PlayerPitch{num}", ref result);
return result;
}
}
}
namespace DeadAndBored.Configuration
{
internal static class Config
{
private const string CONFIG_FILE_NAME = "DeadAndBored.cfg";
private static ConfigFile config;
private static ConfigEntry<bool> enableTooltipConfig;
private static ConfigEntry<bool> hearOtherTeammates;
private static ConfigEntry<bool> enableLogging;
public static bool enableTooltip => enableTooltipConfig.Value;
public static bool hearOtherDeadTeammates => hearOtherTeammates.Value;
public static bool enableDebugLogging => enableLogging.Value;
public static void Init()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
string text = Path.Combine(Paths.ConfigPath, "DeadAndBored.cfg");
config = new ConfigFile(text, true);
enableTooltipConfig = config.Bind<bool>("Config", "Enable Tooltip", true, "Enable the tooltip menu");
hearOtherTeammates = config.Bind<bool>("Config", "Hear Other Dead Teammates While They Are Talking As An Enemy", false, "With this set to False, you will not hear your other dead teammates when they are talking as an enemy. You will hear them again when they stop talking as an enemy. Note there is a delay so you may still hear/not hear them for a brief period of time.");
enableLogging = config.Bind<bool>("Config", "Enable Debug Logging", false, "Set to true for debugging");
}
}
}