Decompiled source of ProximityChat v0.5.0

ProximityChat.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Dissonance;
using Dissonance.Audio.Playback;
using Dissonance.Integrations.SteamworksP2P;
using Dissonance.Networking;
using Dissonance.Networking.Client;
using Dissonance.Networking.Server;
using GTFO.API;
using HarmonyLib;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Player;
using ProximityChat.Dissonance;
using ProximityChat.PlayerHandler;
using ProximityChat.SteamComms;
using ProximityChat.TalkState;
using SNetwork;
using Steamworks;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ProximityChat")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ProximityChat")]
[assembly: AssemblyTitle("ProximityChat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace ProximityChat
{
	public class ProximityConfig
	{
		public static ConfigEntry<float> changeMaxDistance;

		public static ConfigEntry<float> changeMinDistance;

		public static ConfigEntry<int> changePollingFrequency;

		public static ConfigEntry<bool> enableSleeperWake;

		public static ConfigEntry<bool> enableHardMode;
	}
	[BepInPlugin("net.devante.gtfo.proximitychat", "ProximityChat", "0.4")]
	public class MainPlugin : BasePlugin
	{
		private DissonanceUtils? dissonanceInstance;

		private SlotManager? slotManagerInstance;

		private SteamLink? steamLink;

		private PlayerManager? playerManager;

		private SleeperWake? sleeperWake;

		private static MainPlugin _instance;

		public static ManualLogSource SendLog;

		public GameObject? globalDS;

		public static MainPlugin Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new MainPlugin();
				}
				return _instance;
			}
		}

		public override void Load()
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			ProximityConfig.changeMaxDistance = ((BasePlugin)this).Config.Bind<float>("Proximity Settings", "Maximum Distance", 52f, "How far should you be able to hear other players?");
			ProximityConfig.changeMinDistance = ((BasePlugin)this).Config.Bind<float>("Proximity Settings", "Minimum Distance", 2f, "How close should other players have to be in order to be at full volume?");
			ProximityConfig.changePollingFrequency = ((BasePlugin)this).Config.Bind<int>("Proximity Settings", "Polling Rate", 50, "How fast Player Positions should be updated in milliseconds.");
			ProximityConfig.enableSleeperWake = ((BasePlugin)this).Config.Bind<bool>("SleeperWake", "Enabled", false, "Allows sleepers to wake up from talking near them. [HOST ONLY]");
			ProximityConfig.enableHardMode = ((BasePlugin)this).Config.Bind<bool>("SleeperWake", "Use Hard Mode?", false, "Makes sleepers instantly wake up from talking near them. (Requires base to be enabled)");
			dissonanceInstance = DissonanceUtils.Instance;
			slotManagerInstance = SlotManager.Instance;
			steamLink = SteamLink.Instance;
			playerManager = PlayerManager.Instance;
			sleeperWake = SleeperWake.Instance;
			SendLog = ((BasePlugin)this).Log;
			LevelAPI.OnBuildStart += sleeperWake.Init;
			dissonanceInstance.Init();
			steamLink.Init();
			playerManager.Init();
			Harmony val = new Harmony("net.devante.gtfo.proximitychat");
			val.PatchAll();
			SendLog.LogInfo((object)"Loaded plugin and utilities!");
		}

		public void UpdateGlobalDS()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			GameObject val = GameObject.Find("GLOBAL");
			ManualLogSource sendLog = SendLog;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[UpdateDS] Found GLOBAL GameObject: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)val).name);
			}
			sendLog.LogInfo(val2);
			GameObject gameObject = ((Component)val.transform.Find("Managers/Chat/DissonanceSetup")).gameObject;
			ManualLogSource sendLog2 = SendLog;
			val2 = new BepInExInfoLogInterpolatedStringHandler(45, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[UpdateDS] Found DissonanceSetup GameObject: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)gameObject).name);
			}
			sendLog2.LogInfo(val2);
			globalDS = gameObject;
		}
	}
}
namespace ProximityChat.TalkState
{
	public class SleeperWake
	{
		private MainPlugin rootInstance;

		private DissonanceUtils dissonanceInstance;

		private SteamLink steamLink;

		private SlotManager slotManager;

		private static SleeperWake _instance;

		public bool sleepWakeEnabled = false;

		public static SleeperWake Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new SleeperWake();
				}
				return _instance;
			}
		}

		public void Init()
		{
			if (ProximityConfig.enableSleeperWake.Value)
			{
				MainPlugin.SendLog.LogInfo((object)"[SleeperWake] Config is true, checking host...");
				if (!SNet.LocalPlayer.IsMaster)
				{
					MainPlugin.SendLog.LogError((object)"[SleeperWake] SleeperWake is enabled, but user is not the host. Disabling SleeperWake...");
					return;
				}
				MainPlugin.SendLog.LogInfo((object)"[SleeperWake] User is indeed the host, enabling SleeperWake functionality!");
				sleepWakeEnabled = true;
			}
		}

		public async void enableSleeperWake(PlayerAgent sourceAgent, VoicePlayback? sourceObject = null, VoicePlayerState? selfObject = null)
		{
			ManualLogSource sendLog = MainPlugin.SendLog;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SleeperWake] Starting listener for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(sourceAgent.PlayerName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("!");
			}
			sendLog.LogInfo(val);
			while ((Object)(object)sourceAgent != (Object)null)
			{
				eGameStateName currentStateName = GameStateManager.CurrentStateName;
				if (((object)(eGameStateName)(ref currentStateName)).ToString() != "InLevel")
				{
					ManualLogSource sendLog2 = MainPlugin.SendLog;
					val = new BepInExInfoLogInterpolatedStringHandler(53, 0, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SleeperWake] Supposedly exited level, shutting down!");
					}
					sendLog2.LogInfo(val);
					break;
				}
				await Task.Delay(12);
				if ((Object)(object)sourceObject == (Object)null && selfObject != null)
				{
					while (selfObject.IsSpeaking)
					{
						((Agent)sourceAgent).Noise = (NoiseType)3;
						await Task.Delay(12);
					}
				}
				else
				{
					while (sourceObject.IsSpeaking)
					{
						((Agent)sourceAgent).Noise = (NoiseType)3;
						await Task.Delay(12);
					}
				}
			}
			MainPlugin.SendLog.LogError((object)"[SleeperWake] Connection to player unexpectedly severed!");
		}
	}
}
namespace ProximityChat.SteamComms
{
	public class SteamLink
	{
		private MainPlugin rootInstance;

		private DissonanceUtils dissonanceInstance;

		private SlotManager slotManager;

		private PlayerManager playerManager;

		private SleeperWake sleeperWake;

		private static SteamLink _instance;

		public static SteamLink Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new SteamLink();
				}
				return _instance;
			}
		}

		public void Init()
		{
			rootInstance = MainPlugin.Instance;
			dissonanceInstance = DissonanceUtils.Instance;
			slotManager = SlotManager.Instance;
			playerManager = PlayerManager.Instance;
			sleeperWake = SleeperWake.Instance;
		}

		public void HostSteamP2P()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			GameObject globalDS = rootInstance.globalDS;
			SteamworksP2PServer server = ((BaseCommsNetwork<SteamworksP2PServer, SteamworksP2PClient, CSteamID, CSteamID, Unit>)(object)globalDS.GetComponent<SteamworksP2PCommsNetwork>()).Server;
			BroadcastingClientCollection<CSteamID> clients = ((BaseServer<SteamworksP2PServer, SteamworksP2PClient, CSteamID>)(object)server)._clients;
			Dictionary<string, ClientInfo<CSteamID>> clientsByName = ((BaseClientCollection<CSteamID>)(object)clients)._clientsByName;
			Dictionary<ushort, ClientInfo<CSteamID>> clientsByPlayerId = ((BaseClientCollection<CSteamID>)(object)clients)._clientsByPlayerId;
			ManualLogSource sendLog = MainPlugin.SendLog;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(56, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SteamP2PHost] Found ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(clientsByName.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clients by name and ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(clientsByPlayerId.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by player ID.");
			}
			sendLog.LogInfo(val);
			Enumerator<string, ClientInfo<CSteamID>> enumerator = clientsByName.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, ClientInfo<CSteamID>> current = enumerator.Current;
				try
				{
					string key = current.Key;
					ClientInfo<CSteamID> value = current.Value;
					CSteamID connection = value.Connection;
					Enumerator<ushort, ClientInfo<CSteamID>> enumerator2 = clientsByPlayerId.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						KeyValuePair<ushort, ClientInfo<CSteamID>> current2 = enumerator2.Current;
						ushort key2 = current2.Key;
						ClientInfo<CSteamID> value2 = current2.Value;
						CSteamID connection2 = value2.Connection;
						if (connection == connection2)
						{
							ManualLogSource sendLog2 = MainPlugin.SendLog;
							val = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SteamP2PHost] DUID ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is in player slot #");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ushort>(key2);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
							}
							sendLog2.LogInfo(val);
							dissonanceInstance.SetupIncomingAudio(key, key2);
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource sendLog3 = MainPlugin.SendLog;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SteamP2PClient] Inaccessible Object! Skipping... (Error: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
					}
					sendLog3.LogError(val2);
				}
			}
			MainPlugin.SendLog.LogInfo((object)"[SteamP2PHost] Player is Host! Using different linking method..");
			PlayerAgent playerAgentBySlot = slotManager.GetPlayerAgentBySlot(SNet.LocalPlayer.CharacterIndex);
			dissonanceInstance.LinkPositionUpdater(playerAgentBySlot, globalDS.gameObject);
			if (sleeperWake.sleepWakeEnabled)
			{
				sleeperWake.enableSleeperWake(playerAgentBySlot, null, globalDS.gameObject.GetComponent<DissonanceComms>().Players[0]);
			}
		}

		public void ClientSteamP2P()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			GameObject globalDS = rootInstance.globalDS;
			SteamworksP2PClient client = ((BaseCommsNetwork<SteamworksP2PServer, SteamworksP2PClient, CSteamID, CSteamID, Unit>)(object)globalDS.GetComponent<SteamworksP2PCommsNetwork>()).Client;
			BaseClient<SteamworksP2PServer, SteamworksP2PClient, CSteamID> val = (BaseClient<SteamworksP2PServer, SteamworksP2PClient, CSteamID>)(object)client;
			SlaveClientCollection<CSteamID> peers = val._peers;
			Dictionary<string, ClientInfo<Nullable<CSteamID>>> clientsByName = ((BaseClientCollection<Nullable<CSteamID>>)(object)peers)._clientsByName;
			Dictionary<ushort, ClientInfo<Nullable<CSteamID>>> clientsByPlayerId = ((BaseClientCollection<Nullable<CSteamID>>)(object)peers)._clientsByPlayerId;
			ManualLogSource sendLog = MainPlugin.SendLog;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SteamP2PClient] Found ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(clientsByName.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" clients by name and ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(clientsByPlayerId.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" by player ID.");
			}
			sendLog.LogInfo(val2);
			Enumerator<string, ClientInfo<Nullable<CSteamID>>> enumerator = clientsByName.GetEnumerator();
			CSteamID val3 = default(CSteamID);
			CSteamID val4 = default(CSteamID);
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, ClientInfo<Nullable<CSteamID>>> current = enumerator.Current;
				try
				{
					MainPlugin.SendLog.LogInfo((object)"[SteamP2PClient] Queued client.");
					string key = current.Key;
					ManualLogSource sendLog2 = MainPlugin.SendLog;
					val2 = new BepInExInfoLogInterpolatedStringHandler(46, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SteamP2PClient] Processing ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(key);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". Local DUID is '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(peers._playerName);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
					}
					sendLog2.LogInfo(val2);
					if (key == peers._playerName)
					{
						MainPlugin.SendLog.LogInfo((object)"[SteamP2PClient] Looped DUID matches local DUID! Redirecting...");
						dissonanceInstance.LinkPositionUpdater(slotManager.GetPlayerAgentBySlot(SNet.LocalPlayer.CharacterIndex), globalDS.gameObject);
						continue;
					}
					ClientInfo<Nullable<CSteamID>> value = current.Value;
					((CSteamID)(ref val3))..ctor(value.Connection.Value.m_SteamID);
					Enumerator<ushort, ClientInfo<Nullable<CSteamID>>> enumerator2 = clientsByPlayerId.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						KeyValuePair<ushort, ClientInfo<Nullable<CSteamID>>> current2 = enumerator2.Current;
						ushort key2 = current2.Key;
						ClientInfo<Nullable<CSteamID>> value2 = current2.Value;
						((CSteamID)(ref val4))..ctor(value2.Connection.Value.m_SteamID);
						if (val3 == val4)
						{
							ManualLogSource sendLog3 = MainPlugin.SendLog;
							val2 = new BepInExInfoLogInterpolatedStringHandler(43, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[SteamP2PClient] DUID ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(key);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is in player slot #");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<ushort>(key2);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
							}
							sendLog3.LogInfo(val2);
							dissonanceInstance.SetupIncomingAudio(key, key2);
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource sendLog4 = MainPlugin.SendLog;
					BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[SteamP2PClient] Inaccessible Object! Skipping... (Error: ");
						((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(")");
					}
					sendLog4.LogError(val5);
				}
			}
		}
	}
}
namespace ProximityChat.PlayerHandler
{
	public class SlotManager
	{
		private static SlotManager _instance;

		public Dictionary<int, PlayerAgent> playerAgentsBySlot = new Dictionary<int, PlayerAgent>();

		public static SlotManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new SlotManager();
				}
				return _instance;
			}
		}

		public void UpdatePlayerSlot(int slotNumber, PlayerAgent playerAgent)
		{
			if (playerAgentsBySlot.ContainsKey(slotNumber))
			{
				playerAgentsBySlot[slotNumber] = playerAgent;
			}
			else
			{
				playerAgentsBySlot.Add(slotNumber, playerAgent);
			}
		}

		public void RemovePlayerFromSlot(int slotNumber)
		{
			if (playerAgentsBySlot.ContainsKey(slotNumber))
			{
				playerAgentsBySlot[slotNumber] = null;
			}
		}

		public void ClearAllSlots()
		{
			playerAgentsBySlot.Clear();
			MainPlugin.SendLog.LogWarning((object)"[PlayerHandler] PlayerSlots Dictionary has been cleared.");
		}

		public PlayerAgent GetPlayerAgentBySlot(int slotNumber)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			if (playerAgentsBySlot.ContainsKey(slotNumber))
			{
				return playerAgentsBySlot[slotNumber];
			}
			ManualLogSource sendLog = MainPlugin.SendLog;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(49, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PlayerHandler] Slot ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(slotNumber);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" does not exist or is empty.");
			}
			sendLog.LogWarning(val);
			return null;
		}

		public int? GetSlotByPlayerAgent(PlayerAgent playerAgent)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			foreach (KeyValuePair<int, PlayerAgent> item in playerAgentsBySlot)
			{
				if ((Object)(object)item.Value == (Object)(object)playerAgent)
				{
					return item.Key;
				}
			}
			ManualLogSource sendLog = MainPlugin.SendLog;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(51, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PlayerHandler] PlayerAgent ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(playerAgent.PlayerName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found in any slot.");
			}
			sendLog.LogWarning(val);
			return null;
		}
	}
	public class PlayerManager
	{
		private MainPlugin rootInstance;

		private DissonanceUtils dissonanceInstance;

		private SteamLink steamLink;

		private SlotManager slotManager;

		private static PlayerManager _instance;

		public static PlayerManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new PlayerManager();
				}
				return _instance;
			}
		}

		public void Init()
		{
			rootInstance = MainPlugin.Instance;
			dissonanceInstance = DissonanceUtils.Instance;
			slotManager = SlotManager.Instance;
			steamLink = SteamLink.Instance;
		}

		public void RefreshDictionary()
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			if (slotManager.playerAgentsBySlot != null)
			{
				slotManager.ClearAllSlots();
			}
			Enumerator<SNet_Player> enumerator = SNet.LobbyPlayers.GetEnumerator();
			bool flag2 = default(bool);
			while (enumerator.MoveNext())
			{
				SNet_Player current = enumerator.Current;
				int characterIndex = current.CharacterIndex;
				PlayerAgent val = null;
				bool flag = PlayerManager.TryGetPlayerAgent(ref characterIndex, ref val);
				if ((Object)(object)val == (Object)null || !flag)
				{
					ManualLogSource sendLog = MainPlugin.SendLog;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(44, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Player '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(current.NickName);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' doesn't have a PlayerAgent Object!");
					}
					sendLog.LogError(val2);
					continue;
				}
				slotManager.UpdatePlayerSlot(characterIndex, val);
				ManualLogSource sendLog2 = MainPlugin.SendLog;
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(31, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Added ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(val.PlayerName);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" in slot #");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(characterIndex);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" to Dictionary!");
				}
				sendLog2.LogInfo(val3);
			}
		}

		public void RefreshPlayers()
		{
			if (dissonanceInstance.isInLevel)
			{
				MainPlugin.SendLog.LogInfo((object)"[PlayerManager] Refreshing...");
				RefreshDictionary();
				rootInstance.UpdateGlobalDS();
				if (SNet.LocalPlayer.IsMaster)
				{
					steamLink.HostSteamP2P();
				}
				else
				{
					steamLink.ClientSteamP2P();
				}
			}
		}
	}
}
namespace ProximityChat.Dissonance
{
	public class DissonanceUtils
	{
		private MainPlugin? rootInstance;

		private SlotManager slotManager;

		private SteamLink steamLink;

		private PlayerManager playerManager;

		private SleeperWake sleeperWake;

		public bool isInLevel = false;

		private static DissonanceUtils? _instance;

		private string lastState = null;

		private DateTime lastLogTime = DateTime.MinValue;

		public static DissonanceUtils Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new DissonanceUtils();
				}
				return _instance;
			}
		}

		public void Init()
		{
			rootInstance = MainPlugin.Instance;
			slotManager = SlotManager.Instance;
			steamLink = SteamLink.Instance;
			playerManager = PlayerManager.Instance;
			sleeperWake = SleeperWake.Instance;
			LevelAPI.OnEnterLevel += onEnterLevel;
			LevelAPI.OnLevelCleanup += OnExitLevel;
		}

		public void onEnterLevel()
		{
			MainPlugin.SendLog.LogInfo((object)"Entering Level!");
			isInLevel = true;
			playerManager.RefreshPlayers();
		}

		public void OnExitLevel()
		{
			MainPlugin.SendLog.LogInfo((object)"Exiting Level!");
			isInLevel = false;
		}

		public void SetupIncomingAudio(string targetDUID, int pSlot)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			GameObject globalDS = rootInstance.globalDS;
			string playerName = ((BaseCommsNetwork<SteamworksP2PServer, SteamworksP2PClient, CSteamID, CSteamID, Unit>)(object)globalDS.GetComponent<SteamworksP2PCommsNetwork>()).PlayerName;
			bool flag = default(bool);
			foreach (Transform componentsInChild in globalDS.GetComponentsInChildren<Transform>())
			{
				if (!((Object)componentsInChild).name.StartsWith("Player ") || !((Object)componentsInChild).name.Contains(" voice comms"))
				{
					continue;
				}
				string text = ((Object)componentsInChild).name.Substring(7, ((Object)componentsInChild).name.IndexOf(" voice comms") - 7);
				if (text == targetDUID)
				{
					GameObject gameObject = ((Component)componentsInChild).gameObject;
					ManualLogSource sendLog = MainPlugin.SendLog;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SetupAudio] Successfully extracted GameObject for DUID '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(targetDUID);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
					}
					sendLog.LogInfo(val);
					PlayerAgent playerAgentBySlot = slotManager.GetPlayerAgentBySlot(pSlot);
					LinkPositionUpdater(playerAgentBySlot, gameObject);
					AudioSource component = gameObject.GetComponent<AudioSource>();
					VoicePlayback component2 = gameObject.GetComponent<VoicePlayback>();
					if ((Object)(object)component != (Object)null)
					{
						OverrideBlend(component);
						component.spatialize = true;
						component.spatializePostEffects = true;
						component.maxDistance = ProximityConfig.changeMaxDistance.Value;
						component.minDistance = ProximityConfig.changeMinDistance.Value;
						component2._IsApplyingAudioSpatialization_k__BackingField = true;
						MainPlugin.SendLog.LogInfo((object)"[SetupAudio] Successfully enabled audio spatialization.");
					}
					if (sleeperWake.sleepWakeEnabled)
					{
						sleeperWake.enableSleeperWake(playerAgentBySlot, component2);
					}
				}
			}
		}

		public async void LinkPositionUpdater(PlayerAgent player, GameObject userObject)
		{
			string playerName = player.PlayerName;
			ManualLogSource sendLog = MainPlugin.SendLog;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PlayerLink] Linking ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(playerName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s position!");
			}
			sendLog.LogInfo(val);
			eGameStateName currentStateName;
			while (true)
			{
				int num;
				if (isInLevel)
				{
					currentStateName = GameStateManager.CurrentStateName;
					num = ((((object)(eGameStateName)(ref currentStateName)).ToString() == "InLevel") ? 1 : 0);
				}
				else
				{
					num = 0;
				}
				if (num == 0)
				{
					break;
				}
				if ((Object)(object)player == (Object)null || (Object)(object)userObject == (Object)null || !userObject.activeInHierarchy)
				{
					ManualLogSource sendLog2 = MainPlugin.SendLog;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(55, 0, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PlayerLink] Connection to player unexpectedly severed!");
					}
					sendLog2.LogError(val2);
					break;
				}
				userObject.transform.position = ((Agent)player).Position;
				userObject.transform.forward = ((Agent)player).Forward;
				await Task.Delay(ProximityConfig.changePollingFrequency.Value);
			}
			ManualLogSource sendLog3 = MainPlugin.SendLog;
			val = new BepInExInfoLogInterpolatedStringHandler(28, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PlayerLink] Unlinked ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(playerName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("! (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(isInLevel);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				BepInExInfoLogInterpolatedStringHandler obj = val;
				currentStateName = GameStateManager.CurrentStateName;
				((BepInExLogInterpolatedStringHandler)obj).AppendFormatted<string>(((object)(eGameStateName)(ref currentStateName)).ToString());
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
			}
			sendLog3.LogInfo(val);
		}

		public async void OverrideBlend(AudioSource audioSourceComponent)
		{
			while (isInLevel)
			{
				audioSourceComponent.spatialBlend = 1f;
				await Task.Delay(1000);
			}
		}

		public async void ReportGSM()
		{
			int logInterval = 10000;
			bool flag = default(bool);
			while (true)
			{
				eGameStateName currentStateName = GameStateManager.CurrentStateName;
				string cState = ((object)(eGameStateName)(ref currentStateName)).ToString();
				if (cState != lastState)
				{
					ManualLogSource sendLog = MainPlugin.SendLog;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Current Gamestate: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(cState);
					}
					sendLog.LogInfo(val);
					lastState = cState;
					lastLogTime = DateTime.Now;
				}
				else if ((DateTime.Now - lastLogTime).TotalMilliseconds >= (double)logInterval)
				{
					ManualLogSource sendLog2 = MainPlugin.SendLog;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Current Gamestate: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(cState);
					}
					sendLog2.LogInfo(val);
					lastLogTime = DateTime.Now;
				}
				await Task.Delay(50);
			}
		}
	}
	[HarmonyPatch(typeof(SNet_GlobalManager), "OnPlayerEvent")]
	internal class Patch_OnPlayerEvent
	{
		private static void Postfix(SNet_Player player, SNet_PlayerEvent playerEvent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			bool flag = default(bool);
			if ((int)playerEvent == 3)
			{
				ManualLogSource sendLog = MainPlugin.SendLog;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Player ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(player.NickName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has synced with the game.");
				}
				sendLog.LogInfo(val);
				PlayerManager.Instance.RefreshPlayers();
			}
			if ((int)playerEvent == 0)
			{
				ManualLogSource sendLog2 = MainPlugin.SendLog;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Player ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(player.NickName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has disconnected from the game.");
				}
				sendLog2.LogInfo(val);
			}
		}
	}
}