Decompiled source of Atlyss DPSUI v1.1.1

Atlyss_DPSUI.dll

Decompiled 3 weeks ago
using System;
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 BepInEx.Logging;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Nessie.ATLYSS.EasySettings;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Soggy_Pancake")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+6a2ffa3f62b458016972f6937690faf45f0cc5d9")]
[assembly: AssemblyProduct("Atlyss_DPSUI")]
[assembly: AssemblyTitle("Atlyss_DPSUI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
namespace Atlyss_DPSUI
{
	internal class ClientPatches
	{
		internal static int _helloRetryCount;

		internal static float _helloRetryLast;

		private static float clientRetryDelay = 6f;

		internal static void ClientSendHello(bool force = false)
		{
			if (force || (!Player._mainPlayer._isHostPlayer && !(_helloRetryLast > Time.time - clientRetryDelay)))
			{
				_helloRetryCount++;
				Plugin.logger.LogDebug((object)$"Sending hello packet (Attempt {_helloRetryCount})");
				BinaryClientHelloPacket binaryClientHelloPacket = new BinaryClientHelloPacket
				{
					nickname = Player._mainPlayer._nickname
				};
				_helloRetryLast = Time.time;
				CodeTalkerNetwork.SendBinaryNetworkPacket((BinaryPacketBase)(object)binaryClientHelloPacket);
			}
		}

		internal static void Client_RecieveHello(PacketHeader header, BinaryPacketBase packet)
		{
			if (packet is BinaryServerHelloPacket binaryServerHelloPacket)
			{
				Plugin.logger.LogInfo((object)("Client recieved binary hello. Server DPSUI version is " + binaryServerHelloPacket.version));
				if (binaryServerHelloPacket.version != "1.1.1")
				{
					Plugin.logger.LogWarning((object)"Server version mismatch!");
					Player._mainPlayer._chatBehaviour.New_ChatMessage("<color=#fce75d>Server AtlyssDPSUI Version mismatch! (Server version: " + binaryServerHelloPacket.version + ")</color>");
				}
				Plugin._serverSupport = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AtlyssNetworkManager), "OnStartClient")]
		[HarmonyPatch(typeof(AtlyssNetworkManager), "OnStopClient")]
		internal static void ServerChange()
		{
			_helloRetryCount = 0;
			Plugin._serverSupport = false;
			DPSUI_GUI.createdUI = false;
			DPSUI_GUI._UI = null;
			Plugin.player = null;
			DPSUI_GUI.showPartyUI = false;
			Plugin.logger.LogInfo((object)"Server status change, server support false");
		}

		[HarmonyPatch(typeof(Player), "OnPlayerMapInstanceChange")]
		[HarmonyPostfix]
		internal static void OnMapChanged(MapInstance _old, MapInstance _new)
		{
			if ((Object)(object)_new != (Object)(object)_old)
			{
				Plugin.player = Player._mainPlayer;
				Plugin._AmServer = Player._mainPlayer.Network_isHostPlayer;
				DPSUI_GUI.showPartyUI = false;
				Plugin.shownDungeonClearText = false;
				Plugin.localDamage?.Clear();
				if (DPSUI_GUI.createdUI)
				{
					DPSUI_GUI._UI?.UpdateDPS(0f);
					DPSUI_GUI._UI?.clearDamageValues();
					DPSUI_GUI.resetPartyAnim();
				}
			}
		}

		[HarmonyPatch(typeof(StatusEntityGUI), "UserCode_Target_Display_FloatingNumber__StatusEntity__FloatTextColor__Int32__Int32__Int32")]
		[HarmonyPostfix]
		private static void TrackOwnDamage(StatusEntity _followObj, FloatTextColor _floatTextColor, int _value, int _combatElementID, int _conditionGroupID)
		{
			//IL_0030: 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_0035: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)Player._mainPlayer) || (Object)(object)_followObj == (Object)(object)Player._mainPlayer.NC<Player>()?._statusEntity || (int)_floatTextColor == 0 || (int)_floatTextColor == 4 || (int)_floatTextColor == 5)
			{
				return;
			}
			float currentTime = Time.unscaledTime;
			DamageHistory damageHistory = default(DamageHistory);
			damageHistory.time = currentTime;
			damageHistory.damage = _value;
			DamageHistory item = damageHistory;
			List<DamageHistory> localDamage = Plugin.localDamage;
			if (DPSUI_Config.keepDamageUntilPause.Value)
			{
				if (localDamage.Count > 0 && currentTime - localDamage[localDamage.Count - 1].time >= DPSUI_Config.damageHoldTime.Value)
				{
					localDamage.Clear();
				}
				localDamage.Add(item);
			}
			else
			{
				localDamage.RemoveAll((DamageHistory hit) => currentTime - hit.time >= DPSUI_Config.damageHoldTime.Value);
				localDamage.Add(item);
			}
			float num = localDamage[0].time;
			int num2 = 0;
			foreach (DamageHistory item2 in localDamage)
			{
				num2 += item2.damage;
			}
			if (currentTime == num)
			{
				num -= 1f;
			}
			float dps = (float)num2 / Mathf.Max(0.5f, currentTime - num);
			Plugin.logger.LogDebug((object)$"Hits tracked: {localDamage.Count} Current hit dmg value: {_value} total time between last valid hit and current: {currentTime - num}");
			DPSUI_GUI._UI.UpdateDPS(dps);
		}

		[HarmonyPatch(typeof(PlayerInteract), "Cmd_InteractWithPortal")]
		[HarmonyPrefix]
		private static void ClientPortalInteraction(Portal _portal, ZoneDifficulty _setDifficulty)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			Plugin.logger.LogDebug((object)("Portal interaction! portal tag: " + _portal.NC<Portal>()._scenePortal?._spawnPointTag));
			if (_portal.NC<Portal>()?._scenePortal == null)
			{
				return;
			}
			Player val = Player._mainPlayer.NC<Player>();
			if ((Object)(object)val != (Object)null && (int)val.Network_playerZoneType == 2 && _portal._scenePortal._spawnPointTag == "fortSpawn")
			{
				BinaryDPSPacket lastDPSPacket = Plugin.lastDPSPacket;
				if (lastDPSPacket != null && lastDPSPacket.bossFightEndTime == 0L)
				{
					Plugin.logger.LogDebug((object)"Portaled out of finished dungeon!");
				}
				Plugin.logger.LogDebug((object)"Portaled out of dungeon early?");
			}
		}
	}
	internal static class DPSUI_Config
	{
		internal static ConfigFile config;

		internal static ConfigEntry<KeyCode> togglePartyUIBind;

		internal static ConfigEntry<KeyCode> toggleLocalUIBind;

		internal static ConfigEntry<KeyCode> switchPartyUITypeBind;

		internal static ConfigEntry<float> transitionTime;

		internal static ConfigEntry<float> damageHoldTime;

		internal static ConfigEntry<bool> keepDamageUntilPause;

		internal static ConfigEntry<bool> showFullDungeonDamage;

		internal static ConfigEntry<bool> showLocalUI;

		internal static ConfigEntry<bool> showPartyUI;

		internal static ConfigEntry<bool> speedyBoiMode;

		internal static ConfigEntry<string> backgroundImage;

		internal static ConfigEntry<string> textFont;

		internal static ConfigEntry<float> clientUpdateRate;

		public static void init(ConfigFile _config)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			config = _config;
			togglePartyUIBind = config.Bind<KeyCode>("KeyBinds", "partyUIToggleKey", (KeyCode)91, (ConfigDescription)null);
			switchPartyUITypeBind = config.Bind<KeyCode>("KeyBinds", "partyUITypeKey", (KeyCode)93, (ConfigDescription)null);
			toggleLocalUIBind = config.Bind<KeyCode>("KeyBinds", "localToggleKey", (KeyCode)44, (ConfigDescription)null);
			ConfigDescription val = new ConfigDescription("Time it takes to slide in party ui in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>());
			transitionTime = config.Bind<float>("General", "transitionTime", 0.25f, val);
			ConfigDescription val2 = new ConfigDescription("Total time in seconds to keep track of damage for when calculating local DPS (Becomes time gap required to reset if keepDamageUntilPause is true)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 120f), Array.Empty<object>());
			damageHoldTime = config.Bind<float>("General", "damageHoldTime", 10f, val2);
			showLocalUI = config.Bind<bool>("General", "showLocalUI", true, (ConfigDescription)null);
			showPartyUI = config.Bind<bool>("General", "showPartyUI", true, (ConfigDescription)null);
			keepDamageUntilPause = config.Bind<bool>("General", "keepDamageUntilPause", false, "Keep track of all of the damage since you started attacking until you stop instead of the last x seconds");
			showFullDungeonDamage = config.Bind<bool>("General", "showFullDungeonDamage", true, "Show damage totals while in the dungeon instead of just the boss");
			speedyBoiMode = config.Bind<bool>("General", "speedyBoiMode", false, "Display dungeon split times.");
			backgroundImage = config.Bind<string>("General", "backgroundImage", "_graphic/_ui/bk_06", "Background image to use for the party damage UI");
			textFont = config.Bind<string>("General", "textFont", "", "Path of the font to use");
			ConfigDescription val3 = new ConfigDescription("Minimum time in seconds between updates to clients", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>());
			clientUpdateRate = config.Bind<float>("Host", "clientUpdateRate", 1f, val3);
			if (Chainloader.PluginInfos.ContainsKey("EasySettings"))
			{
				addEasySettings();
			}
			else
			{
				Plugin.logger.LogWarning((object)"Soft dependency EasySettings not found!");
			}
			Plugin.logger.LogInfo((object)"Config initalized!");
			DPSUI_GUI.userShowPartyUI = showPartyUI.Value;
			DPSUI_GUI.userShowLocalUI = showLocalUI.Value;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void addEasySettings()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Settings.OnInitialized.AddListener(new UnityAction(ActuallyAdd));
			static void ActuallyAdd()
			{
				SettingsTab modTab = Settings.ModTab;
				modTab.AddHeader("Atlyss DPSUI");
				modTab.AddToggle(showPartyUI);
				modTab.AddToggle(showLocalUI);
				modTab.AddToggle(speedyBoiMode);
				modTab.AddKeyButton(togglePartyUIBind);
				modTab.AddKeyButton(toggleLocalUIBind);
				modTab.AddKeyButton("Switch UI Mode", switchPartyUITypeBind);
				modTab.AddAdvancedSlider(transitionTime, false);
				modTab.AddAdvancedSlider(damageHoldTime, true);
				modTab.AddToggle(keepDamageUntilPause);
				modTab.AddToggle(showFullDungeonDamage);
				modTab.AddAdvancedSlider("[Host] Client update rate", clientUpdateRate, false);
			}
		}
	}
	public class DPSValues : Boolable
	{
		public uint netId;

		public uint color;

		public uint totalDamage;

		public string nickname;

		public string classIcon;

		public DPSValues()
		{
		}

		public DPSValues(Player player, uint initialDamage)
		{
			//IL_00f9: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			netId = ((NetworkBehaviour)player).netId;
			nickname = player._nickname;
			totalDamage = initialDamage;
			classIcon = "_clsIco_novice";
			ScriptablePlayerBaseClass @class = player._pStats._class;
			if (player._pStats.Network_syncClassTier != 0)
			{
				int num = player._pStats.Network_syncClassTier - 1;
				if (@class._playerClassTiers.Length > num)
				{
					Sprite classTierIcon = @class._playerClassTiers[num]._classTierIcon;
					if ((Object)(object)classTierIcon != (Object)null)
					{
						classIcon = ((Object)classTierIcon).name;
					}
					else
					{
						classIcon = "Null";
					}
				}
			}
			else
			{
				object obj;
				if (@class == null)
				{
					obj = null;
				}
				else
				{
					Sprite obj2 = @class._classIcon;
					obj = ((obj2 != null) ? ((Object)obj2).name : null);
				}
				classIcon = (string)obj;
			}
			if (player._pStats.Network_syncClass == "")
			{
				classIcon = "_clsIco_novice";
			}
			Color32 val;
			try
			{
				val = Color32.op_Implicit(((Renderer)player._pVisual._blockOrbRender).material.GetColor("_EmissionColor"));
			}
			catch
			{
				val = Color32.op_Implicit(@class._blockEmissionColor);
			}
			color = (uint)((val.r << 24) | (val.g << 16) | (val.b << 8) | val.a);
		}

		internal DPSValues(PacketPlayer player, uint damage)
		{
			netId = player.netId;
			nickname = player.nickname;
			classIcon = player.icon;
			totalDamage = damage;
		}
	}
	internal class DungeonInstance
	{
		public MapInstance map;

		public PatternInstanceManager patternManager;

		public List<CreepSpawner> bossSpawners;

		public CreepSpawner bossSpawner;

		public Creep bossEntity;

		public uint mapNetID;

		public uint bossEntityNetID;

		public long dungeonStartTime;

		public long dungeonClearTime;

		public long bossTeleportTime;

		public long bossFightStartTime;

		public long bossFightEndTime;

		public float lastSentUpdate;

		public List<DPSValues> bossDamage;

		public List<DPSValues> totalDungeonDamage;

		private bool haveLoadedPlayer;

		private bool Dirty;

		public DungeonInstance(MapInstance newMap)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			map = newMap;
			patternManager = map._patternInstance;
			bossSpawners = new List<CreepSpawner>();
			if (Object.op_Implicit((Object)(object)patternManager))
			{
				bossSpawner = patternManager._bossSpawner;
			}
			mapNetID = ((NetworkBehaviour)newMap).netId;
			if ((int)newMap._zoneType != 2)
			{
				haveLoadedPlayer = true;
			}
			bossDamage = new List<DPSValues>();
			totalDungeonDamage = new List<DPSValues>();
		}

		public void markDirty()
		{
			Dirty = true;
		}

		private void sendPacket()
		{
			CodeTalkerNetwork.SendBinaryNetworkPacket((BinaryPacketBase)(object)new BinaryDPSPacket(this));
			Plugin.logger.LogDebug((object)$"Sent update packet for dungeon instance {mapNetID}");
			lastSentUpdate = Time.time;
			Dirty = false;
		}

		public void Print()
		{
			try
			{
				Plugin.logger.LogInfo((object)$"Dungeon instance ({map._mapName}) [netId: {mapNetID}] Dirty? {Dirty} LastUpdate: {lastSentUpdate}");
				Plugin.logger.LogInfo((object)$"Pattern manager: {patternManager}");
				if (Object.op_Implicit((Object)(object)patternManager))
				{
					Plugin.logger.LogInfo((object)$"PatternInstance state: isBossEngaged {patternManager._isBossEngaged} netowrkversion {patternManager.Network_isBossEngaged}");
					Plugin.logger.LogInfo((object)$"Boss entity: {bossEntity}");
				}
				Plugin.logger.LogInfo((object)("Dungeon cleared? " + ((dungeonClearTime != 0L) ? "Yes" : "No")));
				string text = "Dormant";
				if (bossFightStartTime != 0L)
				{
					text = "In battle";
				}
				if (bossFightEndTime != 0L)
				{
					text = "Defeated";
				}
				Plugin.logger.LogInfo((object)("Boss status: (" + text + ")"));
				if (Object.op_Implicit((Object)(object)bossEntity))
				{
					Plugin.logger.LogInfo((object)$"Boss max hp: {bossEntity._statStruct._maxHealth}");
				}
				Plugin.logger.LogInfo((object)$"Dungeon start time: {dungeonStartTime}");
				Plugin.logger.LogInfo((object)$"Dungeon clear time: {dungeonClearTime}");
				Plugin.logger.LogInfo((object)$"Fight start time: {bossFightStartTime}");
				Plugin.logger.LogInfo((object)$"Fight end time: {bossFightEndTime}");
				if (text == "Defeated")
				{
					Plugin.logger.LogInfo((object)$"Boss defeated in {(float)(bossFightEndTime - bossFightStartTime) / 1000f} seconds");
				}
				Plugin.logger.LogInfo((object)"Current player boss damage totals: ");
				foreach (DPSValues item in bossDamage)
				{
					Plugin.logger.LogInfo((object)$"{item.nickname} ({item.netId}): {item.totalDamage} damage");
				}
				Plugin.logger.LogInfo((object)"Current player damage totals: ");
				foreach (DPSValues item2 in totalDungeonDamage)
				{
					Plugin.logger.LogInfo((object)$"{item2.nickname} ({item2.netId}): {item2.totalDamage} damage");
				}
			}
			catch (Exception ex)
			{
				Plugin.logger.LogError((object)("Error printing dungeon instance info: " + ex));
			}
		}

		public void Update()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			if (!haveLoadedPlayer)
			{
				foreach (Player item in map._peersInInstance)
				{
					if (Object.op_Implicit((Object)(object)item) && (int)item.Network_currentGameCondition == 1)
					{
						haveLoadedPlayer = true;
						dungeonStartTime = DateTime.UtcNow.Ticks / 10000;
						Dirty = true;
					}
				}
			}
			if (!haveLoadedPlayer)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)patternManager))
			{
				if (dungeonClearTime == 0L && patternManager.Network_allArenasBeaten)
				{
					dungeonClearTime = DateTime.UtcNow.Ticks / 10000;
					if (Plugin._SoloMode && DPSUI_Config.speedyBoiMode.Value)
					{
						Plugin.AddChatMessage($"[DPSUI] Dungeon cleared in {(float)(dungeonClearTime - dungeonStartTime) / 1000f} seconds! (all arenas beaten)");
					}
					Dirty = true;
				}
				if (Object.op_Implicit((Object)(object)patternManager._bossRoomTeleporter) && bossTeleportTime == 0L && patternManager._bossRoomTeleporter.Network_allPlayersInTeleporter && map._peersInInstance.Count > 0)
				{
					bossTeleportTime = DateTime.UtcNow.Ticks / 10000;
					if (Plugin._SoloMode && DPSUI_Config.speedyBoiMode.Value)
					{
						Plugin.AddChatMessage($"[DPSUI] Boss reached in {(float)(bossTeleportTime - dungeonStartTime) / 1000f} seconds!");
					}
					Dirty = true;
				}
				if (!patternManager.Network_isBossDefeated && patternManager.Network_isBossEngaged && bossFightStartTime == 0L)
				{
					bossFightStartTime = DateTime.UtcNow.Ticks / 10000;
					Plugin.logger.LogInfo((object)$"boss engaged {mapNetID}: {bossFightStartTime}");
					if (Object.op_Implicit((Object)(object)bossSpawner) && bossSpawner._spawnedCreeps.Count > 0)
					{
						bossEntity = bossSpawner._spawnedCreeps[0];
						bossEntityNetID = ((NetworkBehaviour)bossEntity).netId;
						if (Object.op_Implicit((Object)(object)bossEntity.Network_aggroedEntity._isPlayer))
						{
							RecordDamage(bossEntity.Network_aggroedEntity._isPlayer, 0, isBossDamage: true);
						}
						foreach (Player item2 in bossSpawner._playersWithinSpawnerRadius)
						{
							if (Object.op_Implicit((Object)(object)item2))
							{
								RecordDamage(item2, 0, isBossDamage: true);
							}
						}
						Dirty = true;
					}
					else
					{
						Plugin.logger.LogError((object)"Boss is engaged but boss not found!");
					}
				}
				if (patternManager.Network_isBossDefeated && bossFightStartTime > 0 && bossFightEndTime == 0L)
				{
					bossFightEndTime = DateTime.UtcNow.Ticks / 10000;
					Plugin.logger.LogInfo((object)"Dungeon Boss Beaten!");
					Print();
					Plugin.logger.LogInfo((object)" ");
					if (!Plugin._SoloMode && Plugin._AmServer)
					{
						sendPacket();
						Plugin.logger.LogDebug((object)"Sent final update packet");
					}
					if (Plugin._SoloMode && DPSUI_Config.speedyBoiMode.Value)
					{
						Plugin.AddChatMessage($"[DPSUI] Boss beaten in {(float)(bossFightEndTime - bossFightStartTime) / 1000f} seconds!");
						Plugin.AddChatMessage($"[DPSUI] Dungeon finished in {(float)(bossFightEndTime - dungeonStartTime) / 1000f} seconds!");
					}
				}
			}
			else if (bossSpawners.Count == 0)
			{
				ManualLogSource logger = Plugin.logger;
				if (logger != null)
				{
					logger.LogDebug((object)("Looking for boss spawner in " + map._mapName + "..."));
				}
				GameObject? obj = ((IEnumerable<GameObject>)((Scene)(ref map._loadedScene)).GetRootGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject o) => ((Object)o).name == "_CREEPSPAWNER" || ((Object)o).name == "_CREEPSPAWNERS"));
				CreepSpawner[] array = ((obj != null) ? obj.GetComponentsInChildren<CreepSpawner>() : null) ?? Array.Empty<CreepSpawner>();
				CreepSpawner[] array2 = array;
				foreach (CreepSpawner val in array2)
				{
					ManualLogSource logger2 = Plugin.logger;
					if (logger2 != null)
					{
						logger2.LogDebug((object)(((Object)val).name + " spawn count: " + val._creepCount));
					}
					if (((Object)(object)val._creepToSpawn != (Object)null && val._isSpecialSpawn) || val._creepToSpawn?._creepName == "Slime Diva")
					{
						ManualLogSource logger3 = Plugin.logger;
						if (logger3 != null)
						{
							logger3.LogDebug((object)("Found elite spawn? " + ((Object)val).name));
						}
						bossSpawners.Add(val);
					}
				}
				if (!Object.op_Implicit((Object)(object)bossSpawner) && bossSpawners.Count == 0)
				{
					Plugin.dungeonInstances.Remove(this);
					ManualLogSource logger4 = Plugin.logger;
					if (logger4 != null)
					{
						logger4.LogDebug((object)("Could not find boss/elite spawner in " + map._mapName + ", not a dungeon instance"));
					}
					return;
				}
			}
			if (bossFightStartTime == 0L)
			{
				if (!Object.op_Implicit((Object)(object)bossSpawner) && bossSpawners.Count > 0)
				{
					foreach (CreepSpawner bossSpawner in bossSpawners)
					{
						if (Object.op_Implicit((Object)(object)bossSpawner) && bossSpawner._spawnedCreeps.Count > 0)
						{
							this.bossSpawner = bossSpawner;
							ManualLogSource logger5 = Plugin.logger;
							if (logger5 != null)
							{
								logger5.LogDebug((object)("Set boss spawner to " + ((Object)this.bossSpawner).name + " in " + map._mapName));
							}
							break;
						}
					}
				}
				if (Object.op_Implicit((Object)(object)this.bossSpawner) && this.bossSpawner._spawnedCreeps.Count != 0 && (Object)(object)this.bossSpawner._spawnedCreeps[0] != (Object)null)
				{
					if ((Object)(object)bossEntity == (Object)null)
					{
						bossEntity = this.bossSpawner._spawnedCreeps[0];
						bossEntityNetID = ((NetworkBehaviour)bossEntity).netId;
					}
					if ((Object)(object)bossEntity._aggroedEntity != (Object)null)
					{
						bossFightStartTime = DateTime.UtcNow.Ticks / 10000;
						Plugin.logger.LogInfo((object)$"field boss engaged {bossFightStartTime}");
						if (Object.op_Implicit((Object)(object)bossEntity.Network_aggroedEntity._isPlayer))
						{
							RecordDamage(bossEntity.Network_aggroedEntity._isPlayer, 0, isBossDamage: true);
						}
						foreach (Player item3 in this.bossSpawner._playersWithinSpawnerRadius)
						{
							RecordDamage(item3, 0, isBossDamage: true);
						}
						Dirty = true;
					}
				}
			}
			if (bossFightStartTime > 0 && bossFightEndTime == 0L && bossEntity._statusEntity._currentHealth <= 0)
			{
				bossFightEndTime = DateTime.UtcNow.Ticks / 10000;
				Plugin.logger.LogInfo((object)"Field boss killed!");
				Print();
				Plugin.logger.LogInfo((object)" ");
				if (!Plugin._SoloMode && Plugin._AmServer)
				{
					sendPacket();
					Plugin.logger.LogDebug((object)"Sent final update packet");
				}
				if (Plugin._SoloMode && DPSUI_Config.speedyBoiMode.Value)
				{
					Plugin.AddChatMessage($"[DPSUI] Boss beaten in {(float)(bossFightEndTime - bossFightStartTime) / 1000f} seconds!");
				}
				bossFightStartTime = 0L;
				bossFightEndTime = 0L;
				bossDamage.Clear();
			}
			if (!Plugin._SoloMode && Dirty && Time.time >= lastSentUpdate + DPSUI_Config.clientUpdateRate.Value && (dungeonStartTime > 0 || (bossFightEndTime == 0L && bossFightStartTime > 0)))
			{
				sendPacket();
			}
		}

		public void RecordDamage(Player player, int damage, bool isBossDamage)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)player))
			{
				return;
			}
			if (isBossDamage)
			{
				bool flag = false;
				for (int i = 0; i < bossDamage.Count; i++)
				{
					if (bossDamage[i].netId == ((NetworkBehaviour)player).netId)
					{
						flag = true;
						bossDamage[i].totalDamage = bossDamage[i].totalDamage + (uint)damage;
					}
				}
				if (!flag)
				{
					bossDamage.Add(new DPSValues(player, (uint)damage));
				}
			}
			else
			{
				if ((int)player.Network_playerMapInstance._zoneType != 2)
				{
					return;
				}
				bool flag2 = false;
				for (int j = 0; j < totalDungeonDamage.Count; j++)
				{
					if (totalDungeonDamage[j].netId == ((NetworkBehaviour)player).netId)
					{
						flag2 = true;
						totalDungeonDamage[j].totalDamage = totalDungeonDamage[j].totalDamage + (uint)damage;
					}
				}
				if (!flag2)
				{
					totalDungeonDamage.Add(new DPSValues(player, (uint)damage));
				}
			}
			Dirty = true;
		}
	}
	public enum UIMode
	{
		Auto,
		Boss,
		Party
	}
	public class DPSUI_GUI : Boolable
	{
		internal class PartyMemberBar
		{
			internal GameObject self;

			private Text memberInfo;

			private Text damageText;

			private RectTransform background;

			private RectTransform fillBar;

			private Image classImg;

			public Color fillColor;

			private float dataUpdateTime;

			internal PartyMemberBar(GameObject self)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Expected O, but got Unknown
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: Expected O, but got Unknown
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: 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: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01eb: Expected O, but got Unknown
				//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_024f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0256: Expected O, but got Unknown
				//IL_0262: Unknown result type (might be due to invalid IL or missing references)
				//IL_0191: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				this.self = self;
				fillColor = new Color(Random.value, Random.value, Random.value);
				AddBackground(self);
				Texture2D val = new Texture2D(1, 1);
				val.SetPixel(0, 0, Color.white);
				GameObject val2 = AddBackground(self, val);
				((Object)val2).name = "Fillbar";
				fillBar = val2.GetComponent<RectTransform>();
				fillBar.sizeDelta = new Vector2(-3f, -2f);
				((Graphic)((Component)fillBar).GetComponent<Image>()).color = fillColor;
				GameObject val3 = new GameObject("ClassImage", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				classImg = val3.GetComponent<Image>();
				setParent(val3, self);
				self.GetComponent<RectTransform>();
				RectTransform component = val3.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.01f, 0.3f);
				component.anchorMax = new Vector2(0.09f, 0.7f);
				component.sizeDelta = Vector2.zero;
				component.pivot = component.anchorMin;
				component.anchoredPosition = Vector2.zero;
				int num = 0;
				while (classImages != null && num < classImages.Length)
				{
					if (Object.op_Implicit((Object)(object)classImages[num]) && ((Object)classImages[num]).name == "_clsIco_novice")
					{
						classImg.sprite = Sprite.Create(classImages[num], new Rect(0f, 0f, (float)((Texture)classImages[num]).width, (float)((Texture)classImages[num]).height), new Vector2(0.5f, 0.5f));
						break;
					}
					num++;
				}
				GameObject val4 = new GameObject("MemberName", new Type[1] { typeof(Text) });
				setupRectTransform(val4, new Vector2(0.16f, 0.5f), self, ignoreParentRect: true);
				memberInfo = setupText(val4, 20);
				val4.AddComponent<Shadow>();
				memberInfo.alignment = (TextAnchor)3;
				memberInfo.text = "Dumbass";
				val4 = new GameObject("DamageText", new Type[1] { typeof(Text) });
				setupRectTransform(val4, new Vector2(0.97f, 0.5f), self, ignoreParentRect: true);
				damageText = setupText(val4, 20);
				val4.AddComponent<Shadow>();
				damageText.alignment = (TextAnchor)5;
				damageText.text = "Fuck all";
			}

			internal void UpdateInfo(DPSValues info, float barFillPercent)
			{
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				memberInfo.text = info.nickname;
				if (info.netId == ((NetworkBehaviour)Player._mainPlayer).netId)
				{
					Text obj = memberInfo;
					obj.text += " (You)";
				}
				string text = info.totalDamage.ToString("n1");
				if (text.EndsWith(".0"))
				{
					text = text.Substring(0, text.Length - 2);
				}
				damageText.text = text;
				barFillPercent = Mathf.Max(barFillPercent, 1E-05f);
				fillBar.anchorMax = new Vector2(barFillPercent, 1f);
				self.SetActive(true);
				if (info.classIcon != ((Object)classImg.sprite.texture).name)
				{
					for (int i = 0; i < classImages.Length; i++)
					{
						if (Object.op_Implicit((Object)(object)classImages[i]) && ((Object)classImages[i]).name == info.classIcon)
						{
							classImg.sprite = Sprite.Create(classImages[i], new Rect(0f, 0f, (float)((Texture)classImages[i]).width, (float)((Texture)classImages[i]).height), new Vector2(0.5f, 0.5f));
							break;
						}
					}
				}
				try
				{
					uint color = info.color;
					if (color != 0)
					{
						Color32 val = default(Color32);
						val.r = (byte)((color >> 24) & 0xFFu);
						val.g = (byte)((color >> 16) & 0xFFu);
						val.b = (byte)((color >> 8) & 0xFFu);
						val.a = byte.MaxValue;
						Color32 val2 = val;
						((Graphic)((Component)fillBar).GetComponent<Image>()).color = Color32.op_Implicit(val2);
					}
				}
				catch
				{
				}
			}
		}

		public static DPSUI_GUI _UI;

		internal static InGameUI gameUI;

		public static UIMode _UIMode;

		public static bool showUI;

		private static bool _userShowPartyUI;

		private static bool _userShowLocalUI;

		private static bool _showPartyUI;

		private static bool _showLocalUI = true;

		private static float partyAnimPos;

		public static Font UI_font;

		public static Vector2 DPS_Pos = new Vector2(0.61f, 0.14f);

		public static Vector2 PartyDPS_MinPos = new Vector2(0.85f, 0.35f);

		public static Vector2 PartyDPS_MaxPos = new Vector2(1f, 0.65f);

		public static Vector2 PartyDPS_TotalPos = new Vector2(0.05f, 0.95f);

		public static Vector2 PartyDPS_DPSPos = new Vector2(0.95f, 0.95f);

		public static int MaxShownPartyMembers = 5;

		public static float topTextSpace = 0.13f;

		public static float edgePadding = 0.03f;

		public static float memberSpacing = 0.01f;

		public static int topTextSize = 20;

		internal static GameObject partyDpsContainer;

		internal static GameObject localDpsContainer;

		internal static RectTransform partyDpsTransform;

		internal static RectTransform localDpsTransform;

		internal static AnimationCurve partyAnimCurve;

		internal static GameObject partyDpsLabelRoot;

		internal Canvas rootCanvas;

		internal Text localDpsText;

		internal Text partyTotalText;

		internal Text partyDpsText;

		internal Text partyDpsLabelText;

		internal static Texture2D[] classImages;

		internal PartyMemberBar[] memberBars;

		internal static bool createdUI;

		public static bool userShowPartyUI
		{
			get
			{
				return _userShowPartyUI;
			}
			set
			{
				_userShowPartyUI = value;
				_UI?.Update();
			}
		}

		public static bool userShowLocalUI
		{
			get
			{
				return _userShowLocalUI;
			}
			set
			{
				_userShowLocalUI = value;
				_UI?.UpdateVisibility();
			}
		}

		public static bool showPartyUI
		{
			get
			{
				return _showPartyUI;
			}
			set
			{
				if (!_showPartyUI && value)
				{
					partyAnimPos = 0f;
				}
				_showPartyUI = value;
				_UI?.Update();
			}
		}

		public static bool showLocalUI
		{
			get
			{
				return _showLocalUI;
			}
			set
			{
				_showLocalUI = value;
				if ((bool)_UI)
				{
					_UI.UpdateVisibility();
				}
			}
		}

		public static void setParent(GameObject child, GameObject parent)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			child.transform.SetParent(parent.transform, false);
			child.transform.localPosition = Vector3.zero;
			child.transform.localScale = Vector3.one;
		}

		public static void resetPartyAnim()
		{
			partyDpsContainer.SetActive(false);
			partyAnimPos = 0f;
		}

		public static RectTransform setupRectTransform(GameObject obj, Vector2 anchor, GameObject parent = null, bool ignoreParentRect = false)
		{
			//IL_0008: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = obj.GetComponent<RectTransform>();
			component.pivot = anchor;
			component.anchorMin = anchor;
			component.anchorMax = anchor;
			if (Object.op_Implicit((Object)(object)parent))
			{
				setParent(obj, parent);
				if (!ignoreParentRect)
				{
					RectTransform component2 = parent.GetComponent<RectTransform>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						component.sizeDelta = component2.sizeDelta;
					}
				}
			}
			component.anchoredPosition = Vector2.zero;
			return component;
		}

		public static Text setupText(GameObject textObj, int fontSize = 10)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			Text component = textObj.GetComponent<Text>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			RectTransform component2 = ((Component)textObj.transform.parent).GetComponent<RectTransform>();
			if (Object.op_Implicit((Object)(object)component2) && component2.sizeDelta != Vector2.zero)
			{
				textObj.GetComponent<RectTransform>().sizeDelta = component2.sizeDelta;
			}
			((Component)component).gameObject.layer = LayerMask.NameToLayer("UI");
			component.font = UI_font;
			component.font.material.mainTexture.filterMode = (FilterMode)0;
			component.horizontalOverflow = (HorizontalWrapMode)1;
			component.alignment = (TextAnchor)8;
			component.fontSize = fontSize;
			((Component)component).transform.localPosition = Vector3.zero;
			RectTransform component3 = ((Component)component).GetComponent<RectTransform>();
			if (Object.op_Implicit((Object)(object)component3))
			{
				component3.anchoredPosition = Vector2.zero;
			}
			return component;
		}

		public static GameObject AddBackground(GameObject uiObjt, Texture2D image = null, Sprite sprite = null)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Background", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			setParent(val, uiObjt);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			val.gameObject.layer = LayerMask.NameToLayer("UI");
			Image component2 = val.GetComponent<Image>();
			if (Object.op_Implicit((Object)(object)image))
			{
				component2.sprite = Sprite.Create(image, new Rect(0f, 0f, (float)((Texture)image).width, (float)((Texture)image).height), new Vector2(0.5f, 0.5f));
				component2.type = (Type)1;
			}
			else if (Object.op_Implicit((Object)(object)sprite))
			{
				component2.sprite = sprite;
				component2.type = (Type)1;
			}
			else
			{
				((Graphic)component2).color = Color.black;
			}
			return val;
		}

		internal DPSUI_GUI()
		{
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Expected O, but got Unknown
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Expected O, but got Unknown
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Expected O, but got Unknown
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Expected O, but got Unknown
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Expected O, but got Unknown
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Expected O, but got Unknown
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			if (classImages == null || classImages.Length == 0)
			{
				Texture2D[] array = Resources.LoadAll<Texture2D>("_graphic/_ui/_classicons/");
				Texture2D val = Resources.Load<Texture2D>("_graphic/_ui/_ico_caution_lv");
				((Object)val).name = "Null";
				classImages = (Texture2D[])(object)new Texture2D[array.Length + 1];
				classImages[0] = val;
				Array.Copy(array, 0, classImages, 1, array.Length);
				Plugin.logger.LogDebug((object)$"Loaded {classImages.Length} class icons");
				Texture2D[] array2 = classImages;
				foreach (Texture2D val2 in array2)
				{
					Plugin.logger.LogDebug((object)("Loaded class " + ((Object)val2).name));
				}
			}
			if (!Object.op_Implicit((Object)(object)InGameUI._current))
			{
				return;
			}
			UI_font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			GameObject val3 = new GameObject("DPSUI", new Type[3]
			{
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			setupMainCanvas(val3);
			Plugin.logger.LogInfo((object)$"root {val3}");
			GameObject val4 = new GameObject("localDPS", new Type[1] { typeof(RectTransform) });
			RectTransform val5 = setupRectTransform(val4, DPS_Pos, val3);
			val5.sizeDelta = new Vector2(150f, 50f);
			val5.anchoredPosition = Vector2.zero;
			localDpsTransform = val5;
			GameObject val6 = new GameObject("DpsText", new Type[1] { typeof(Text) });
			setupRectTransform(val6, Vector2.right, val4);
			localDpsText = setupText(val6, 25);
			localDpsText.text = "0 DPS";
			Texture2D val7 = null;
			Sprite val8 = null;
			try
			{
				Object val9 = (Object)(object)Resources.Load<Sprite>(DPSUI_Config.backgroundImage.Value);
				if (val9 != (Object)null)
				{
					val8 = (Sprite)(object)((val9 is Sprite) ? val9 : null);
				}
				else
				{
					Object obj = Resources.Load(DPSUI_Config.backgroundImage.Value);
					val7 = (Texture2D)(object)((obj is Texture2D) ? obj : null);
				}
			}
			catch
			{
				Object obj2 = Resources.Load("_graphic/_ui/bk_06");
				val8 = (Sprite)(object)((obj2 is Sprite) ? obj2 : null);
			}
			if ((Object)(object)val7 != (Object)null)
			{
				((Texture)val7).filterMode = (FilterMode)0;
			}
			GameObject val10 = new GameObject("partyDPS", new Type[1] { typeof(RectTransform) });
			RectTransform val11 = setupRectTransform(val10, Vector2.zero, val3, ignoreParentRect: true);
			val11.anchorMin = PartyDPS_MinPos;
			val11.anchorMax = PartyDPS_MaxPos;
			val11.sizeDelta = Vector2.zero;
			partyDpsTransform = val11;
			if ((Object)(object)val8 != (Object)null)
			{
				AddBackground(val10, null, val8);
			}
			else if ((Object)(object)val7 != (Object)null)
			{
				AddBackground(val10, val7);
			}
			((Graphic)val10.GetComponentInChildren<Image>()).color = new Color(0.9f, 0.9f, 0.9f);
			partyAnimCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
			{
				new Keyframe(0f, 0f, 0f, 1f),
				new Keyframe(1f, 1f, 0f, 0f)
			});
			GameObject val12 = new GameObject("DPS Label", new Type[1] { typeof(RectTransform) });
			RectTransform val13 = setupRectTransform(val12, new Vector2(0f, 1f), val3, ignoreParentRect: true);
			val13.anchorMin = new Vector2(PartyDPS_MinPos.x, PartyDPS_MaxPos.y);
			val13.anchorMax = new Vector2(PartyDPS_MaxPos.x, PartyDPS_MaxPos.y + 0.04f);
			val13.sizeDelta = Vector2.zero;
			Object obj4 = Resources.Load("_graphic/_ui/bk_04");
			val7 = (Texture2D)(object)((obj4 is Texture2D) ? obj4 : null);
			((Graphic)AddBackground(val12, val7).GetComponent<Image>()).color = Color32.op_Implicit(new Color32((byte)133, (byte)94, (byte)83, byte.MaxValue));
			partyDpsLabelRoot = val12;
			GameObject val14 = new GameObject("PartyLabelText", new Type[1] { typeof(Text) });
			setupRectTransform(val14, new Vector2(0.5f, 0.5f), val12, ignoreParentRect: true);
			partyDpsLabelText = setupText(val14, 20);
			partyDpsLabelText.alignment = (TextAnchor)4;
			GameObject val15 = new GameObject("PartyTotalText", new Type[1] { typeof(Text) });
			RectTransform val16 = setupRectTransform(val15, PartyDPS_TotalPos, val10, ignoreParentRect: true);
			partyTotalText = setupText(val15, topTextSize);
			val15.AddComponent<Shadow>();
			partyTotalText.alignment = (TextAnchor)0;
			val16.anchoredPosition = Vector2.zero;
			partyTotalText.text = "Total: 8000";
			GameObject val17 = new GameObject("PartyDPSText", new Type[1] { typeof(Text) });
			RectTransform val18 = setupRectTransform(val17, PartyDPS_DPSPos, val10, ignoreParentRect: true);
			partyDpsText = setupText(val17, topTextSize);
			val17.AddComponent<Shadow>();
			partyDpsText.alignment = (TextAnchor)2;
			val18.anchoredPosition = Vector2.zero;
			partyDpsText.text = "8000 DPS";
			float num = (1f - topTextSpace - (float)(MaxShownPartyMembers - 1) * memberSpacing - edgePadding) / (float)MaxShownPartyMembers;
			memberBars = new PartyMemberBar[MaxShownPartyMembers];
			Vector2 val19 = default(Vector2);
			Vector2 anchorMax = default(Vector2);
			for (int num2 = MaxShownPartyMembers - 1; num2 >= 0; num2--)
			{
				float num3 = edgePadding + memberSpacing * (float)num2 + num * (float)num2;
				float num4 = num3 + num;
				((Vector2)(ref val19))..ctor(edgePadding, num3);
				((Vector2)(ref anchorMax))..ctor(1f - edgePadding, num4);
				GameObject val20 = new GameObject($"member{num2}", new Type[1] { typeof(RectTransform) });
				RectTransform val21 = setupRectTransform(val20, val19, val10);
				val21.anchorMin = val19;
				val21.anchorMax = anchorMax;
				val21.pivot = Vector2.zero;
				val21.anchoredPosition = Vector2.zero;
				memberBars[MaxShownPartyMembers - 1 - num2] = new PartyMemberBar(val20);
			}
			partyDpsContainer = val10;
			localDpsContainer = val4;
			createdUI = true;
			gameUI = InGameUI._current;
			partyDpsContainer.SetActive(false);
			localDpsContainer.SetActive(false);
			UpdateVisibility();
			Plugin.logger.LogInfo((object)"Created dps ui!");
			void setupMainCanvas(GameObject canvasObj)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				setupRectTransform(canvasObj, Vector2.zero, ((Component)InGameUI._current).gameObject, ignoreParentRect: true);
				Canvas component = canvasObj.GetComponent<Canvas>();
				component.renderMode = (RenderMode)0;
				canvasObj.GetComponent<CanvasScaler>().uiScaleMode = (ScaleMode)0;
				rootCanvas = component;
			}
		}

		internal void UpdateVisibility()
		{
			if (!Plugin._AmHeadless && createdUI)
			{
				localDpsContainer.SetActive(showLocalUI && _userShowLocalUI && showUI);
				partyDpsLabelRoot.SetActive(false);
			}
		}

		public void UpdateDPS(float dps)
		{
			if (createdUI)
			{
				string text = dps.ToString("n1");
				if (text.EndsWith(".0"))
				{
					text = text.Substring(0, text.IndexOf('.'));
				}
				string text2 = text + " DPS";
				localDpsText.text = text2;
			}
		}

		public void UpdatePartyDamageValues(BinaryDPSPacket packet)
		{
			if (!createdUI || packet == null)
			{
				return;
			}
			List<DPSValues> list = packet.partyDamageValues;
			long num = packet.dungeonStartTime;
			long num2 = packet.bossFightEndTime;
			if (_UIMode == UIMode.Auto)
			{
				List<DPSValues> bossDamageValues = packet.bossDamageValues;
				if (bossDamageValues != null && bossDamageValues.Count > 0)
				{
					list = packet.bossDamageValues;
					num = packet.bossFightStartTime;
					num2 = packet.bossFightEndTime;
				}
			}
			else if (_UIMode == UIMode.Boss)
			{
				list = packet.bossDamageValues;
				num = packet.bossFightStartTime;
				num2 = packet.bossFightEndTime;
			}
			if (list != null && list.Count == 0)
			{
				showPartyUI = false;
				return;
			}
			list.Sort((DPSValues b, DPSValues a) => a.totalDamage.CompareTo(b.totalDamage));
			int num3 = -1;
			uint num4 = 0u;
			uint netId = ((NetworkBehaviour)Player._mainPlayer).netId;
			for (int i = 0; i < list.Count; i++)
			{
				DPSValues dPSValues = list[i];
				num4 += dPSValues.totalDamage;
				if (dPSValues.netId == netId)
				{
					num3 = i;
				}
			}
			if (num3 == -1)
			{
				return;
			}
			if (num2 == 0L)
			{
				num2 = DateTime.UtcNow.Ticks / 10000;
			}
			float num5 = (float)(num2 - num) / 1000f;
			float num6 = (float)num4 / num5;
			partyTotalText.text = "Total: " + num4;
			string text = num6.ToString("n1");
			if (text.EndsWith(".0"))
			{
				text = text.Substring(0, text.Length - 2);
			}
			partyDpsText.text = text + " DPS";
			for (int j = 0; j < memberBars.Length; j++)
			{
				memberBars[j].self.SetActive(false);
			}
			showPartyUI = true;
			bool flag = false;
			for (int k = 0; k < list.Count; k++)
			{
				DPSValues dPSValues = list[k];
				if (dPSValues.netId == netId)
				{
					flag = true;
				}
				if (k < 4 || flag || dPSValues.netId == netId)
				{
					float num7 = (float)dPSValues.totalDamage / Mathf.Max((float)list[0].totalDamage, 1f);
					Plugin.logger.LogDebug((object)$"{dPSValues.nickname} dmg: {dPSValues.totalDamage} UpdatePartyValues  percent fill: {num7 * 100f / 1f}");
					memberBars[Math.Min(4, k)].UpdateInfo(dPSValues, num7);
					if (k >= 4 && flag)
					{
						break;
					}
				}
			}
		}

		internal void clearDamageValues()
		{
			partyTotalText.text = "Total: 0";
			partyDpsText.text = "0 DPS";
			PartyMemberBar[] array = memberBars;
			foreach (PartyMemberBar partyMemberBar in array)
			{
				partyMemberBar.UpdateInfo(new DPSValues(), 0f);
				partyMemberBar.self.SetActive(false);
			}
		}

		public void Update()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			if (!createdUI || Plugin._AmHeadless)
			{
				return;
			}
			if ((gameUI._displayUI && !Player._mainPlayer._inUI) != showUI)
			{
				showUI = gameUI._displayUI && (!Plugin.player._inUI || (int)Plugin.player._currentPlayerCondition == 3);
				localDpsContainer.SetActive(showLocalUI && _userShowLocalUI && showUI);
			}
			Rect rect;
			if (showUI && _showPartyUI && _userShowPartyUI && partyAnimPos < 1f)
			{
				if (!partyDpsContainer.activeSelf)
				{
					partyDpsContainer.SetActive(true);
				}
				if (DPSUI_Config.transitionTime.Value == 0f)
				{
					partyDpsTransform.anchoredPosition = Vector2.zero;
					partyAnimPos = 1f;
				}
				else
				{
					partyAnimPos += Time.deltaTime / DPSUI_Config.transitionTime.Value;
					if (partyAnimPos > 1f)
					{
						partyAnimPos = 1f;
					}
					Vector2 zero = Vector2.zero;
					rect = partyDpsTransform.rect;
					zero.x = ((Rect)(ref rect)).width * (1f - partyAnimCurve.Evaluate(partyAnimPos));
					partyDpsTransform.anchoredPosition = zero;
				}
			}
			if ((showUI && _showPartyUI && _userShowPartyUI) || !(partyAnimPos > 0f))
			{
				return;
			}
			if (DPSUI_Config.transitionTime.Value == 0f)
			{
				partyDpsContainer.SetActive(false);
				partyAnimPos = 0f;
				return;
			}
			partyAnimPos -= Time.deltaTime / DPSUI_Config.transitionTime.Value;
			if (partyAnimPos < 0f)
			{
				partyAnimPos = 0f;
				partyDpsContainer.SetActive(false);
			}
			Vector2 zero2 = Vector2.zero;
			rect = partyDpsTransform.rect;
			zero2.x = ((Rect)(ref rect)).width * (1f - partyAnimCurve.Evaluate(partyAnimPos));
			partyDpsTransform.anchoredPosition = zero2;
		}
	}
	internal class PluginInfo
	{
		public const string GUID = "Soggy_Pancake.AtlyssDPSUI";

		public const string NAME = "AtlyssDPSUI";

		public const string VERSION = "1.1.1";

		public const int MAX_HELLO_RETRY = 5;

		public const int FIELD_BOSS_TIMEOUT_MS = 30000;
	}
	public class Boolable
	{
		public static implicit operator bool(Boolable obj)
		{
			return obj != null;
		}
	}
	public static class UnityNullFix
	{
		public static T NC<T>(this T obj) where T : Object
		{
			if (!Object.op_Implicit((Object)(object)obj))
			{
				return default(T);
			}
			return obj;
		}
	}
	public struct DamageHistory
	{
		public float time;

		public int damage;
	}
	public struct PacketPlayer
	{
		public uint netId;

		public uint color;

		public string nickname;

		public string icon;

		public PacketPlayer()
		{
			netId = 0u;
			color = 0u;
			nickname = null;
			icon = null;
		}

		public PacketPlayer(DPSValues ogValue)
		{
			netId = ogValue.netId;
			color = ogValue.color;
			nickname = ogValue.nickname;
			icon = ogValue.classIcon;
		}
	}
	public struct PacketDPSValue
	{
		public byte playerIndex;

		public uint value;

		public PacketDPSValue()
		{
			playerIndex = 0;
			value = 0u;
		}

		public PacketDPSValue(int index, uint _value)
		{
			playerIndex = (byte)index;
			value = _value;
		}
	}
	public class BinaryDPSPacket : BinaryPacketBase
	{
		public uint mapNetID;

		public long dungeonStartTime;

		public long dungeonClearTime;

		public long bossTeleportTime;

		public long bossFightStartTime;

		public long bossFightEndTime;

		public List<PacketPlayer> players;

		public List<DPSValues> bossDamageValues;

		public List<DPSValues> partyDamageValues;

		public override string PacketSignature => "DPSPkt";

		public BinaryDPSPacket()
		{
		}

		internal BinaryDPSPacket(DungeonInstance instance)
		{
			mapNetID = instance.mapNetID;
			dungeonStartTime = instance.dungeonStartTime;
			dungeonClearTime = instance.dungeonClearTime;
			bossTeleportTime = instance.bossTeleportTime;
			bossFightStartTime = instance.bossFightStartTime;
			bossFightEndTime = instance.bossFightEndTime;
			bossDamageValues = instance.bossDamage;
			partyDamageValues = instance.totalDungeonDamage;
			players = new List<PacketPlayer>();
			Dictionary<uint, DPSValues> dictionary = new Dictionary<uint, DPSValues>();
			foreach (DPSValues item in bossDamageValues.Concat(partyDamageValues))
			{
				if (!dictionary.ContainsKey(item.netId))
				{
					dictionary[item.netId] = item;
				}
			}
			DPSValues[] array = dictionary.Values.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				players.Add(new PacketPlayer(array[i]));
			}
		}

		public override void Deserialize(byte[] data)
		{
			MemoryStream input = new MemoryStream(data);
			BinaryReader binaryReader = new BinaryReader(input);
			mapNetID = binaryReader.ReadUInt32();
			dungeonStartTime = binaryReader.ReadInt64();
			dungeonClearTime = binaryReader.ReadInt64();
			bossTeleportTime = binaryReader.ReadInt64();
			bossFightStartTime = binaryReader.ReadInt64();
			bossFightEndTime = binaryReader.ReadInt64();
			byte b = binaryReader.ReadByte();
			players = new List<PacketPlayer>(b);
			for (int i = 0; i < b; i++)
			{
				uint netId = binaryReader.ReadUInt32();
				uint color = binaryReader.ReadUInt32();
				List<byte> list = new List<byte>();
				byte item;
				while ((item = binaryReader.ReadByte()) != 0)
				{
					list.Add(item);
				}
				string @string = Encoding.UTF8.GetString(list.ToArray());
				list.Clear();
				while ((item = binaryReader.ReadByte()) != 0)
				{
					list.Add(item);
				}
				string string2 = Encoding.UTF8.GetString(list.ToArray());
				PacketPlayer packetPlayer = new PacketPlayer();
				packetPlayer.netId = netId;
				packetPlayer.color = color;
				packetPlayer.nickname = @string;
				packetPlayer.icon = string2;
				PacketPlayer item2 = packetPlayer;
				players.Add(item2);
			}
			byte b2 = binaryReader.ReadByte();
			bossDamageValues = new List<DPSValues>(b2);
			for (int j = 0; j < b2; j++)
			{
				PacketPlayer player = players[binaryReader.ReadByte()];
				uint damage = binaryReader.ReadUInt32();
				bossDamageValues.Add(new DPSValues(player, damage));
			}
			byte b3 = binaryReader.ReadByte();
			partyDamageValues = new List<DPSValues>(b3);
			for (int k = 0; k < b3; k++)
			{
				PacketPlayer player = players[binaryReader.ReadByte()];
				uint damage = binaryReader.ReadUInt32();
				partyDamageValues.Add(new DPSValues(player, damage));
			}
		}

		public override byte[] Serialize()
		{
			MemoryStream memoryStream = new MemoryStream();
			BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(mapNetID);
			binaryWriter.Write(dungeonStartTime);
			binaryWriter.Write(dungeonClearTime);
			binaryWriter.Write(bossTeleportTime);
			binaryWriter.Write(bossFightStartTime);
			binaryWriter.Write(bossFightEndTime);
			binaryWriter.Write((byte)players.Count);
			foreach (PacketPlayer player in players)
			{
				binaryWriter.Write(player.netId);
				binaryWriter.Write(player.color);
				binaryWriter.Write(Encoding.UTF8.GetBytes(player.nickname));
				binaryWriter.Write((byte)0);
				binaryWriter.Write(Encoding.UTF8.GetBytes(player.icon));
				binaryWriter.Write((byte)0);
			}
			binaryWriter.Write((byte)bossDamageValues.Count);
			foreach (DPSValues dmg in bossDamageValues)
			{
				binaryWriter.Write((byte)players.FindIndex((PacketPlayer p) => p.netId == dmg.netId));
				binaryWriter.Write(dmg.totalDamage);
			}
			binaryWriter.Write((byte)partyDamageValues.Count);
			foreach (DPSValues dmg2 in partyDamageValues)
			{
				binaryWriter.Write((byte)players.FindIndex((PacketPlayer p) => p.netId == dmg2.netId));
				binaryWriter.Write(dmg2.totalDamage);
			}
			return memoryStream.ToArray();
		}
	}
	public class BinaryClientHelloPacket : BinaryPacketBase
	{
		public string version = "1.1.1";

		public string nickname = "null";

		public override string PacketSignature => "DPSCH";

		public override void Deserialize(byte[] data)
		{
			int num = 0;
			for (num = 0; num < data.Length && data[num] != 0; num++)
			{
			}
			version = Encoding.ASCII.GetString(data, 0, num);
			nickname = Encoding.ASCII.GetString(data, ++num, data.Length - num - 1);
		}

		public override byte[] Serialize()
		{
			int num = "1.1.1".Length + 1 + nickname.Length + 1;
			byte[] array = new byte[num];
			Array.Copy(Encoding.ASCII.GetBytes("1.1.1"), 0, array, 0, "1.1.1".Length);
			Array.Copy(Encoding.ASCII.GetBytes(nickname), 0, array, "1.1.1".Length + 1, nickname.Length);
			return array;
		}
	}
	public class BinaryServerHelloPacket : BinaryPacketBase
	{
		public string version = "1.1.1";

		public override string PacketSignature => "DPSSH";

		public override void Deserialize(byte[] data)
		{
			Encoding.ASCII.GetString(data);
		}

		public override byte[] Serialize()
		{
			return Encoding.ASCII.GetBytes(version);
		}
	}
	[BepInDependency("CodeTalker", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Soggy_Pancake.atlyssDPSUI", "AtlyssDPSUI", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static BinaryPacketListener <0>__Server_RecieveBinaryHello;

			public static BinaryPacketListener <1>__Client_RecieveHello;

			public static BinaryPacketListener <2>__Client_ParseDungeonPartyDamage;
		}

		public static Plugin AtlyssDPSUI;

		internal static Harmony _harmony;

		internal static ManualLogSource logger;

		internal static Player player;

		internal static InGameUI GameUI;

		public static Text localDpsText;

		internal static bool _serverSupport;

		internal static bool _AmServer;

		internal static bool _AmHeadless;

		internal static bool _SoloMode;

		internal static bool shownDungeonClearText;

		internal static List<DungeonInstance> dungeonInstances = new List<DungeonInstance>();

		internal static List<DamageHistory> localDamage = new List<DamageHistory>();

		internal static BinaryDPSPacket lastDPSPacket;

		internal static void Client_ParseDungeonPartyDamage(PacketHeader header, BinaryPacketBase packet)
		{
			if (!(packet is BinaryDPSPacket binaryDPSPacket))
			{
				return;
			}
			Player obj = Player._mainPlayer.NC<Player>();
			if (Object.op_Implicit((Object)(object)((obj != null) ? obj.Network_playerMapInstance : null)) && binaryDPSPacket.mapNetID == ((NetworkBehaviour)Player._mainPlayer.Network_playerMapInstance).netId)
			{
				if (lastDPSPacket == null)
				{
					lastDPSPacket = binaryDPSPacket;
				}
				if (DPSUI_Config.speedyBoiMode.Value && lastDPSPacket.dungeonClearTime == 0L && binaryDPSPacket.dungeonClearTime > 0)
				{
					AddChatMessage($"[DPSUI] Dungeon cleared in {(float)(binaryDPSPacket.dungeonClearTime - binaryDPSPacket.dungeonStartTime) / 1000f} seconds!(arenas only)");
				}
				if (DPSUI_Config.speedyBoiMode.Value && lastDPSPacket.bossTeleportTime == 0L && binaryDPSPacket.bossTeleportTime > 0)
				{
					AddChatMessage($"[DPSUI] Boss reached in {(float)(binaryDPSPacket.bossTeleportTime - binaryDPSPacket.dungeonStartTime) / 1000f} seconds!");
				}
				if (DPSUI_Config.speedyBoiMode.Value && lastDPSPacket.bossFightEndTime == 0L && binaryDPSPacket.bossFightEndTime > 0 && binaryDPSPacket.dungeonStartTime > 0)
				{
					AddChatMessage($"[DPSUI] Boss beaten in {(float)(binaryDPSPacket.bossFightEndTime - binaryDPSPacket.bossFightStartTime) / 1000f} seconds!");
					AddChatMessage($"[DPSUI] Dungeon finished in {(float)(binaryDPSPacket.bossFightEndTime - binaryDPSPacket.dungeonStartTime) / 1000f} seconds!");
				}
				DPSUI_GUI._UI.UpdatePartyDamageValues(binaryDPSPacket);
				lastDPSPacket = binaryDPSPacket;
			}
		}

		internal static void AddChatMessage(string msg)
		{
			Player obj = Player._mainPlayer.NC<Player>();
			if (obj != null)
			{
				ChatBehaviour obj2 = obj._chatBehaviour.NC<ChatBehaviour>();
				if (obj2 != null)
				{
					obj2.New_ChatMessage(msg);
				}
			}
		}

		internal static void AddGameFeedMessage(string msg)
		{
			Player obj = Player._mainPlayer.NC<Player>();
			if (obj != null)
			{
				ChatBehaviour obj2 = obj._chatBehaviour.NC<ChatBehaviour>();
				if (obj2 != null)
				{
					obj2.Init_GameLogicMessage(msg);
				}
			}
		}

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_009a: 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_00a5: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			AtlyssDPSUI = this;
			logger = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("Soggy_Pancake.AtlyssDPSUI");
			DPSUI_Config.init(((BaseUnityPlugin)this).Config);
			localDamage = new List<DamageHistory>();
			logger.LogInfo((object)"Patch successful! Registering network listeners...");
			object obj = <>O.<0>__Server_RecieveBinaryHello;
			if (obj == null)
			{
				BinaryPacketListener val = ServerPatches.Server_RecieveBinaryHello;
				<>O.<0>__Server_RecieveBinaryHello = val;
				obj = (object)val;
			}
			CodeTalkerNetwork.RegisterBinaryListener<BinaryClientHelloPacket>((BinaryPacketListener)obj);
			if (!Environment.GetCommandLineArgs().Contains("-server"))
			{
				_harmony.PatchAll(typeof(ClientPatches));
				object obj2 = <>O.<1>__Client_RecieveHello;
				if (obj2 == null)
				{
					BinaryPacketListener val2 = ClientPatches.Client_RecieveHello;
					<>O.<1>__Client_RecieveHello = val2;
					obj2 = (object)val2;
				}
				CodeTalkerNetwork.RegisterBinaryListener<BinaryServerHelloPacket>((BinaryPacketListener)obj2);
				object obj3 = <>O.<2>__Client_ParseDungeonPartyDamage;
				if (obj3 == null)
				{
					BinaryPacketListener val3 = Client_ParseDungeonPartyDamage;
					<>O.<2>__Client_ParseDungeonPartyDamage = val3;
					obj3 = (object)val3;
				}
				CodeTalkerNetwork.RegisterBinaryListener<BinaryDPSPacket>((BinaryPacketListener)obj3);
			}
			else
			{
				logger.LogWarning((object)"Headless mode detected!");
				_serverSupport = (_AmHeadless = true);
			}
			_harmony.PatchAll(typeof(ServerPatches));
		}

		private void Update()
		{
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			if (_AmHeadless || !Object.op_Implicit((Object)(object)player))
			{
				return;
			}
			if (!DPSUI_GUI.createdUI && Object.op_Implicit((Object)(object)InGameUI._current))
			{
				DPSUI_GUI._UI = new DPSUI_GUI();
				_SoloMode = AtlyssNetworkManager._current._soloMode;
			}
			if ((Object)(object)GameUI == (Object)null)
			{
				GameUI = InGameUI._current;
			}
			DPSUI_GUI._UI.Update();
			if (Input.GetKey((KeyCode)306) && Input.GetKeyDown((KeyCode)303))
			{
				logger.LogInfo((object)("main player: " + (object)Player._mainPlayer));
				logger.LogInfo((object)$"Slide in time: {DPSUI_Config.transitionTime.Value}");
				logger.LogInfo((object)$"UI Mode: {DPSUI_GUI._UIMode}");
				logger.LogInfo((object)$"Update rate: {DPSUI_Config.clientUpdateRate.Value}");
				ScriptablePlayerBaseClass val = player.NC<Player>()?._pStats.NC<PlayerStats>()?._class;
				logger.LogInfo((object)("Player base class name " + val.NC<ScriptablePlayerBaseClass>()?._className));
				Player obj = player;
				if (obj == null || obj._pStats?._syncClassTier != 0)
				{
					logger.LogInfo((object)"Has subclass!");
					try
					{
						logger.LogInfo((object)("Player base class name " + ((Object)val._playerClassTiers[Player._mainPlayer._pStats._syncClassTier - 1]._classTierIcon).name));
					}
					catch
					{
					}
				}
				logger.LogError((object)$"Dungeon instances tracked: {dungeonInstances.Count}");
				foreach (DungeonInstance dungeonInstance in dungeonInstances)
				{
					dungeonInstance.Print();
				}
			}
			if (player._inChat || player._inUI)
			{
				return;
			}
			if (Input.GetKeyDown(DPSUI_Config.togglePartyUIBind.Value))
			{
				DPSUI_Config.showPartyUI.Value = (DPSUI_GUI.userShowPartyUI = !DPSUI_GUI.userShowPartyUI);
				AddGameFeedMessage((DPSUI_GUI.userShowPartyUI ? "Enabled" : "Disabled") + " party UI");
			}
			if (Input.GetKeyDown(DPSUI_Config.toggleLocalUIBind.Value))
			{
				DPSUI_Config.showLocalUI.Value = (DPSUI_GUI.userShowLocalUI = !DPSUI_GUI.userShowLocalUI);
				AddGameFeedMessage((DPSUI_GUI.userShowLocalUI ? "Enabled" : "Disabled") + " local UI");
			}
			if (Input.GetKeyDown(DPSUI_Config.switchPartyUITypeBind.Value))
			{
				if (DPSUI_GUI._UIMode == UIMode.Auto)
				{
					DPSUI_GUI._UIMode = UIMode.Party;
				}
				else if (DPSUI_GUI._UIMode == UIMode.Party)
				{
					DPSUI_GUI._UIMode = UIMode.Boss;
				}
				else if (DPSUI_GUI._UIMode == UIMode.Boss)
				{
					DPSUI_GUI._UIMode = UIMode.Auto;
				}
				AddGameFeedMessage($"Set UI Mode to {DPSUI_GUI._UIMode}");
				DPSUI_GUI._UI?.UpdatePartyDamageValues(lastDPSPacket);
			}
		}

		private void FixedUpdate()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Invalid comparison between Unknown and I4
			if ((Object)(object)player != (Object)(object)Player._mainPlayer)
			{
				player = Player._mainPlayer;
			}
			if (_AmServer)
			{
				for (int num = dungeonInstances.Count - 1; num >= 0; num--)
				{
					DungeonInstance dungeonInstance = dungeonInstances[num];
					if (!Object.op_Implicit((Object)(object)dungeonInstances[num].map))
					{
						dungeonInstances.RemoveAt(num);
						logger.LogDebug((object)"Dungeon was unloaded!");
					}
					else
					{
						dungeonInstance.Update();
					}
				}
			}
			else if (!_serverSupport)
			{
				Player obj = player.NC<Player>();
				if (obj != null && (int)obj.Network_currentGameCondition == 1 && ClientPatches._helloRetryCount < 5)
				{
					ClientPatches.ClientSendHello();
				}
			}
			if (_AmHeadless || !DPSUI_GUI.showPartyUI)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)player))
			{
				DPSUI_GUI.showPartyUI = false;
				return;
			}
			MapInstance val = player.Network_playerMapInstance.NC<MapInstance>();
			if (Object.op_Implicit((Object)(object)val) && (int)val._zoneType == 1)
			{
				BinaryDPSPacket binaryDPSPacket = lastDPSPacket;
				if (binaryDPSPacket != null && binaryDPSPacket.bossFightEndTime > 0 && lastDPSPacket.bossFightEndTime < DateTime.UtcNow.Ticks / 10000 - 30000)
				{
					DPSUI_GUI.showPartyUI = false;
					logger.LogInfo((object)"Stopped showing field boss info after 30 seconds!");
				}
			}
		}

		private static void LogFullHierarchy()
		{
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			Player mainPlayer = Player._mainPlayer;
			ManualLogSource obj;
			object obj3;
			if (SceneManager.sceneCount >= 2)
			{
				ClientPatches.ClientSendHello(force: true);
				obj = logger;
				Player obj2 = mainPlayer.NC<Player>();
				if (obj2 != null)
				{
					_ = obj2.Network_isHostPlayer;
					if (true)
					{
						obj3 = "yes";
						goto IL_0043;
					}
				}
				obj3 = "nah";
				goto IL_0043;
			}
			goto IL_015b;
			IL_015b:
			ManualLogSource obj4 = logger;
			Player obj5 = mainPlayer.NC<Player>();
			object obj6;
			if (obj5 == null)
			{
				obj6 = null;
			}
			else
			{
				MapInstance obj7 = obj5._playerMapInstance.NC<MapInstance>();
				obj6 = ((obj7 != null) ? ((Object)obj7).name : null);
			}
			obj4.LogInfo(obj6);
			logger.LogInfo((object)mainPlayer.NC<Player>()?._playerMapInstance.NC<MapInstance>()?._zoneType);
			logger.LogInfo((object)$"Loaded scenes: {SceneManager.sceneCount}");
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				logger.LogInfo((object)("Loaded scene: " + ((Scene)(ref sceneAt)).name));
			}
			return;
			IL_0043:
			obj.LogInfo((object)("Am host: " + (string?)obj3));
			logger.LogInfo((object)("_AmHeadless " + _AmHeadless));
			logger.LogInfo((object)("Server support " + _serverSupport));
			logger.LogInfo((object)("AmServer " + _serverSupport));
			logger.LogInfo((object)("last dps packet " + (object)lastDPSPacket));
			logger.LogInfo((object)$"Show partyUI: {DPSUI_GUI.showPartyUI}; Show localUI: {DPSUI_GUI.showLocalUI}; Player in ui: {player._inUI}");
			if (_AmServer)
			{
				logger.LogInfo((object)"\nSpawners:");
				CreepSpawner[] array = Resources.FindObjectsOfTypeAll<CreepSpawner>();
				CreepSpawner[] array2 = array;
				foreach (CreepSpawner val in array2)
				{
					logger.LogInfo((object)(((Object)val).name + " spawn count: " + val._creepCount));
				}
			}
			goto IL_015b;
		}
	}
	internal class ServerPatches
	{
		internal static void Server_RecieveBinaryHello(PacketHeader header, BinaryPacketBase packet)
		{
			if (packet is BinaryClientHelloPacket binaryClientHelloPacket)
			{
				Player obj = Player._mainPlayer.NC<Player>();
				if (obj != null && obj.Network_isHostPlayer && !header.SenderIsLobbyOwner)
				{
					Plugin.logger.LogDebug((object)("Server replying to client! BINARY (" + binaryClientHelloPacket.nickname + ")"));
					CodeTalkerNetwork.SendBinaryNetworkPacket((BinaryPacketBase)(object)new BinaryServerHelloPacket());
				}
			}
		}

		[HarmonyPatch(typeof(StatusEntity), "Take_Damage")]
		[HarmonyPostfix]
		internal static void TrackDamage(StatusEntity __instance, DamageStruct _dmgStruct)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)__instance.NC<StatusEntity>()?._isCreep))
			{
				return;
			}
			foreach (DungeonInstance dungeonInstance in Plugin.dungeonInstances)
			{
				try
				{
					MapInstance map = dungeonInstance.map;
					StatusEntity obj = _dmgStruct._statusEntity.NC<StatusEntity>();
					object obj2;
					if (obj == null)
					{
						obj2 = null;
					}
					else
					{
						Player obj3 = obj._isPlayer.NC<Player>();
						obj2 = ((obj3 != null) ? obj3.Network_playerMapInstance : null);
					}
					if ((Object)(object)map == (Object)obj2)
					{
						dungeonInstance.RecordDamage(_dmgStruct._statusEntity?._isPlayer, _dmgStruct._damageValue, (Object)(object)__instance._isCreep == (Object)(object)dungeonInstance.bossEntity);
						break;
					}
				}
				catch (Exception ex)
				{
					Plugin.logger.LogError((object)("Exception while recording damage: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(MapInstance), "Apply_InstanceData")]
		[HarmonyPostfix]
		internal static void OnMapLoad(MapInstance __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__instance._zoneType != 0)
			{
				DungeonInstance item = new DungeonInstance(__instance);
				Plugin.dungeonInstances.Add(item);
			}
		}
	}
}