Decompiled source of Relationship Mod v1.0.0

MmmCandy.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2667d7348b9a5084e21e8119e14f0bee1e04b816")]
[assembly: AssemblyProduct("MmmCandy")]
[assembly: AssemblyTitle("MmmCandy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.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;
		}
	}
	[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 Empress.Relationships
{
	[BepInPlugin("Empress.REL", "Empress Relationship Mod", "1.2.6")]
	public class RelationshipPlugin : BaseUnityPlugin
	{
		private ConfigEntry<float> _distanceMeters = null;

		private ConfigEntry<float> _bindSeconds = null;

		private ConfigEntry<int> _healthBoostLevels = null;

		private ConfigEntry<int> _strengthBoostLevels = null;

		private ConfigEntry<float> _lineWidth = null;

		private ConfigEntry<bool> _showMessages = null;

		private ConfigEntry<bool> _heartsEnabled = null;

		private ConfigEntry<float> _heartsPerSecond = null;

		private ConfigEntry<float> _heartSize = null;

		private readonly Dictionary<string, float> _proximityTimers = new Dictionary<string, float>();

		private readonly Dictionary<string, string> _partnerOfMaster = new Dictionary<string, string>();

		private readonly Dictionary<string, RelationshipLine> _lines = new Dictionary<string, RelationshipLine>();

		private int _lastLocalHpUpgradeLevel = -1;

		private float _reassertTimer;

		private float _syncCooldown;

		internal static Material HeartMaterial;

		internal static RelationshipPlugin Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal static bool HeartReady { get; private set; }

		internal static bool HeartsEnabled => Instance?._heartsEnabled.Value ?? false;

		internal static float HeartsPerSecond => Instance?._heartsPerSecond.Value ?? 6f;

		internal static float HeartSize => Instance?._heartSize.Value ?? 0.16f;

		private void Awake()
		{
			Instance = this;
			((Component)this).transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			_distanceMeters = ((BaseUnityPlugin)this).Config.Bind<float>("Relationship", "DistanceMeters", 3f, "");
			_bindSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Relationship", "BindSeconds", 8f, "");
			_healthBoostLevels = ((BaseUnityPlugin)this).Config.Bind<int>("Relationship", "HealthBoostLevels", 5, "");
			_strengthBoostLevels = ((BaseUnityPlugin)this).Config.Bind<int>("Relationship", "StrengthBoostLevels", 2, "");
			_lineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "LineWidth", 0.06f, "");
			_showMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowMessages", true, "");
			_heartsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "HeartsEnabled", true, "");
			_heartsPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "HeartsPerSecond", 6f, "");
			_heartSize = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "HeartSize", 0.16f, "");
			TryLoadHeartTexture();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded.");
		}

		private void TryLoadHeartTexture()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			HeartReady = false;
			try
			{
				string path = Path.GetDirectoryName(typeof(RelationshipPlugin).Assembly.Location) ?? Paths.PluginPath;
				string text = Path.Combine(path, "heart.png");
				if (!File.Exists(text))
				{
					Logger.LogWarning((object)("heart.png not found next to DLL: " + text));
					return;
				}
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, true);
				if (!ImageConversion.LoadImage(val, array, false))
				{
					Logger.LogWarning((object)"heart.png failed to load.");
					Object.Destroy((Object)(object)val);
					return;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				((Object)val).name = "EmpressREL_Heart";
				Shader val2 = Shader.Find("Unlit/Transparent") ?? Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard");
				HeartMaterial = new Material(val2);
				if (HeartMaterial.HasProperty("_MainTex"))
				{
					HeartMaterial.SetTexture("_MainTex", (Texture)(object)val);
				}
				if (HeartMaterial.HasProperty("_Color"))
				{
					HeartMaterial.SetColor("_Color", Color.white);
				}
				if (HeartMaterial.HasProperty("_SrcBlend"))
				{
					HeartMaterial.SetInt("_SrcBlend", 5);
				}
				if (HeartMaterial.HasProperty("_DstBlend"))
				{
					HeartMaterial.SetInt("_DstBlend", 10);
				}
				if (HeartMaterial.HasProperty("_ZWrite"))
				{
					HeartMaterial.SetInt("_ZWrite", 0);
				}
				HeartMaterial.DisableKeyword("_ALPHATEST_ON");
				HeartMaterial.EnableKeyword("_ALPHABLEND_ON");
				HeartMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				HeartMaterial.renderQueue = 3000;
				HeartReady = true;
				Logger.LogInfo((object)"Loaded heart.png for particle emitters with transparent blending.");
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Heart load failed: {arg}");
				HeartReady = false;
			}
		}

		private void OnEnable()
		{
			SceneManager.activeSceneChanged += OnSceneChanged;
		}

		private void OnDisable()
		{
			SceneManager.activeSceneChanged -= OnSceneChanged;
		}

		private void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			try
			{
				Logger.LogInfo((object)("Scene changed: " + ((Scene)(ref oldScene)).name + " -> " + ((Scene)(ref newScene)).name));
			}
			catch
			{
			}
			ResetTransientRuntime();
			_reassertTimer = 8f;
			_syncCooldown = 0.1f;
		}

		private void OnDestroy()
		{
			ResetTransientRuntime();
			_partnerOfMaster.Clear();
		}

		private void ResetTransientRuntime()
		{
			try
			{
				foreach (KeyValuePair<string, RelationshipLine> line in _lines)
				{
					if (Object.op_Implicit((Object)(object)line.Value))
					{
						Object.Destroy((Object)(object)((Component)line.Value).gameObject);
					}
				}
			}
			catch
			{
			}
			_lines.Clear();
			_proximityTimers.Clear();
			_lastLocalHpUpgradeLevel = -1;
			_syncCooldown = 0f;
		}

		private void Update()
		{
			try
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					TickRelationshipsMaster();
					TickDeathLinksMaster();
					bool flag = EnsureBuffsForKnownPairs();
					if (_syncCooldown > 0f)
					{
						_syncCooldown -= Time.deltaTime;
					}
					if ((flag || _reassertTimer > 0f) && _syncCooldown <= 0f)
					{
						try
						{
							PunManager.instance.SyncAllDictionaries();
							if (_reassertTimer > 0f)
							{
								Logger.LogInfo((object)"Pushed dictionary sync to clients.");
							}
						}
						catch (Exception arg)
						{
							Logger.LogWarning((object)$"SyncAllDictionaries failed: {arg}");
						}
						_syncCooldown = 0.75f;
					}
					if (_reassertTimer > 0f)
					{
						_reassertTimer -= Time.deltaTime;
					}
				}
				TickLinesLocal();
				TickLocalAutoHeal();
			}
			catch (Exception arg2)
			{
				Logger.LogError((object)$"Update error: {arg2}");
			}
		}

		private void TickRelationshipsMaster()
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerAvatar> livePlayers = GetLivePlayers();
			int count = livePlayers.Count;
			if (count < 2)
			{
				return;
			}
			float num = Mathf.Max(0.25f, _distanceMeters.Value);
			float deltaTime = Time.deltaTime;
			for (int i = 0; i < count; i++)
			{
				PlayerAvatar val = livePlayers[i];
				string text = SafeSteamID(val);
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				for (int j = i + 1; j < count; j++)
				{
					PlayerAvatar val2 = livePlayers[j];
					string text2 = SafeSteamID(val2);
					if (string.IsNullOrEmpty(text2))
					{
						continue;
					}
					if (IsCommittedToOtherMaster(text, text2))
					{
						ResetTimer(text, text2);
						continue;
					}
					if (IsAlreadyPaired(text, text2))
					{
						ResetTimer(text, text2);
						continue;
					}
					Vector3 val3 = ((Component)val).transform.position + Vector3.up * 0.9f;
					Vector3 val4 = ((Component)val2).transform.position + Vector3.up * 0.9f;
					float num2 = Vector3.Distance(val3, val4);
					string key = PairKey(text, text2);
					if (num2 <= num)
					{
						_proximityTimers.TryGetValue(key, out var value);
						value += deltaTime;
						_proximityTimers[key] = value;
						if (value >= _bindSeconds.Value && !_partnerOfMaster.ContainsKey(text) && !_partnerOfMaster.ContainsKey(text2))
						{
							FormRelationshipMaster(val, val2, text, text2);
						}
					}
					else
					{
						ResetTimer(text, text2);
					}
				}
			}
		}

		private void TickDeathLinksMaster()
		{
			HashSet<string> hashSet = new HashSet<string>();
			foreach (KeyValuePair<string, string> item2 in _partnerOfMaster)
			{
				string key = item2.Key;
				string value = item2.Value;
				string item = PairKey(key, value);
				if (!hashSet.Add(item))
				{
					continue;
				}
				PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(key);
				PlayerAvatar val2 = SemiFunc.PlayerAvatarGetFromSteamID(value);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
				{
					int playerHealth = StatsManager.instance.GetPlayerHealth(key);
					int playerHealth2 = StatsManager.instance.GetPlayerHealth(value);
					if (playerHealth <= 0 && playerHealth2 > 0)
					{
						TrySmitePartner(val, val2);
					}
					else if (playerHealth2 <= 0 && playerHealth > 0)
					{
						TrySmitePartner(val2, val);
					}
				}
			}
		}

		private void TrySmitePartner(PlayerAvatar dead, PlayerAvatar partnerAlive)
		{
			//IL_0027: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Object.op_Implicit((Object)(object)partnerAlive) && Object.op_Implicit((Object)(object)partnerAlive.playerHealth))
				{
					Vector3 position = ((Component)partnerAlive).transform.position;
					partnerAlive.playerHealth.HurtOther(9999, position, false, -1);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Smite failed: {arg}");
			}
		}

		private void FormRelationshipMaster(PlayerAvatar A, PlayerAvatar B, string aID, string bID)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			string text = PairKey(aID, bID);
			_partnerOfMaster[aID] = bID;
			_partnerOfMaster[bID] = aID;
			bool flag = ApplyBuffDelta(aID);
			bool flag2 = ApplyBuffDelta(bID);
			try
			{
				if (flag || flag2)
				{
					PunManager.instance.SyncAllDictionaries();
					Logger.LogInfo((object)"Synced dictionaries after forming relationship.");
					_syncCooldown = 0.5f;
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"SyncAllDictionaries (on bind) failed: {arg}");
			}
			try
			{
				if (_showMessages.Value)
				{
					string text2 = SemiFunc.PlayerGetName(A);
					string text3 = SemiFunc.PlayerGetName(B);
					Color val = default(Color);
					((Color)(ref val))..ctor(1f, 0.4f, 0.8f, 1f);
					BigMessageUI instance = BigMessageUI.instance;
					if (instance != null)
					{
						instance.BigMessage(text2 + " has begun a relationship with " + text3, "", 1f, val, Color.white);
					}
				}
			}
			catch
			{
			}
			Logger.LogInfo((object)("Relationship formed: " + Short(aID) + " <3 " + Short(bID)));
		}

		private bool EnsureBuffsForKnownPairs()
		{
			bool result = false;
			if (_partnerOfMaster.Count == 0)
			{
				return false;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (KeyValuePair<string, string> item2 in _partnerOfMaster)
			{
				string key = item2.Key;
				string value = item2.Value;
				string item = PairKey(key, value);
				if (hashSet.Add(item) && Object.op_Implicit((Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(key)) && Object.op_Implicit((Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(value)))
				{
					if (ApplyBuffDelta(key))
					{
						result = true;
					}
					if (ApplyBuffDelta(value))
					{
						result = true;
					}
				}
			}
			return result;
		}

		private bool ApplyBuffDelta(string steamId)
		{
			bool result = false;
			try
			{
				int num = Mathf.Max(0, _healthBoostLevels.Value);
				int num2 = Mathf.Max(0, _strengthBoostLevels.Value);
				int num3 = Mathf.Max(0, SafeGetHpLevel(steamId));
				int num4 = Mathf.Max(0, SafeGetStrengthLevel(steamId));
				int num5 = Mathf.Max(0, num - num3);
				int num6 = Mathf.Max(0, num2 - num4);
				if (num5 > 0)
				{
					PunManager.instance.UpgradePlayerHealth(steamId, num5);
					result = true;
				}
				if (num6 > 0)
				{
					PunManager.instance.UpgradePlayerGrabStrength(steamId, num6);
					result = true;
				}
				if (_reassertTimer > 0f && (num5 > 0 || num6 > 0))
				{
					Logger.LogInfo((object)$"Reasserted upgrades for {Short(steamId)}: +HP Lv{num5}, +STR Lv{num6}.");
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"ApplyBuffDelta failed for {Short(steamId)}: {arg}");
			}
			return result;
		}

		private void TickLinesLocal()
		{
			List<PlayerAvatar> livePlayers = GetLivePlayers();
			HashSet<string> hashSet = new HashSet<string>();
			int num = Mathf.Max(0, _healthBoostLevels.Value);
			int num2 = num * 20;
			for (int i = 0; i < livePlayers.Count; i++)
			{
				PlayerAvatar val = livePlayers[i];
				string text = SafeSteamID(val);
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				int num3 = SafeGetMaxBoost(text);
				for (int j = i + 1; j < livePlayers.Count; j++)
				{
					PlayerAvatar val2 = livePlayers[j];
					string text2 = SafeSteamID(val2);
					if (!string.IsNullOrEmpty(text2))
					{
						int num4 = SafeGetMaxBoost(text2);
						if (num3 >= num2 && num4 >= num2)
						{
							string text3 = PairKey(text, text2);
							hashSet.Add(text3);
							EnsureLine(text3, val, val2);
						}
					}
				}
			}
			_cleanupLinesNotIn(hashSet);
		}

		private void TickLocalAutoHeal()
		{
			try
			{
				PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.playerHealth))
				{
					return;
				}
				string text = SafeSteamID(val);
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				int num = SafeGetHpLevel(text);
				if (num < 0)
				{
					return;
				}
				int num2 = 100 + num * 20;
				PlayerHealth playerHealth = val.playerHealth;
				if (playerHealth.maxHealth < num2)
				{
					int maxHealth = playerHealth.maxHealth;
					playerHealth.maxHealth = num2;
					int num3 = Mathf.Max(0, num2 - playerHealth.health);
					if (num3 > 0)
					{
						playerHealth.Heal(num3, false);
						Logger.LogInfo((object)$"Local forced max sync {maxHealth}->{num2} and healed +{num3}.");
					}
					_lastLocalHpUpgradeLevel = num;
				}
				else if (_lastLocalHpUpgradeLevel < 0)
				{
					_lastLocalHpUpgradeLevel = num;
				}
				else if (num > _lastLocalHpUpgradeLevel)
				{
					int num4 = num - _lastLocalHpUpgradeLevel;
					int num5 = 20 * num4;
					playerHealth.Heal(num5, false);
					Logger.LogInfo((object)$"Local auto-heal +{num5} (levels +{num4}).");
					_lastLocalHpUpgradeLevel = num;
				}
				else if (num < _lastLocalHpUpgradeLevel)
				{
					_lastLocalHpUpgradeLevel = num;
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"TickLocalAutoHeal failed: {arg}");
			}
		}

		private int SafeGetHpLevel(string steamId)
		{
			try
			{
				if (StatsManager.instance.playerUpgradeHealth.TryGetValue(steamId, out var value))
				{
					return value;
				}
			}
			catch
			{
			}
			return -1;
		}

		private int SafeGetStrengthLevel(string steamId)
		{
			try
			{
				if (StatsManager.instance.playerUpgradeStrength.TryGetValue(steamId, out var value))
				{
					return value;
				}
			}
			catch
			{
			}
			return -1;
		}

		private int SafeGetMaxBoost(string steamId)
		{
			try
			{
				return StatsManager.instance.GetPlayerMaxHealth(steamId);
			}
			catch
			{
				return 0;
			}
		}

		private void _cleanupLinesNotIn(HashSet<string> desired)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, RelationshipLine> line in _lines)
			{
				if (!desired.Contains(line.Key) || !Object.op_Implicit((Object)(object)line.Value) || !Object.op_Implicit((Object)(object)line.Value.PlayerA) || !Object.op_Implicit((Object)(object)line.Value.PlayerB))
				{
					if (Object.op_Implicit((Object)(object)line.Value))
					{
						Object.Destroy((Object)(object)((Component)line.Value).gameObject);
					}
					list.Add(line.Key);
				}
			}
			foreach (string item in list)
			{
				_lines.Remove(item);
			}
		}

		private void EnsureLine(string key, PlayerAvatar A, PlayerAvatar B)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if (!_lines.ContainsKey(key))
			{
				GameObject val = new GameObject("RelationshipLine_" + key);
				val.transform.parent = ((Component)this).transform;
				RelationshipLine relationshipLine = val.AddComponent<RelationshipLine>();
				relationshipLine.Setup(A, B, _lineWidth.Value);
				_lines[key] = relationshipLine;
			}
		}

		private static List<PlayerAvatar> GetLivePlayers()
		{
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			if (!Object.op_Implicit((Object)(object)GameDirector.instance))
			{
				return list;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!Object.op_Implicit((Object)(object)player))
				{
					continue;
				}
				try
				{
					string text = SemiFunc.PlayerGetSteamID(player);
					if (!string.IsNullOrEmpty(text))
					{
						int playerHealth = StatsManager.instance.GetPlayerHealth(text);
						if (playerHealth > 0)
						{
							list.Add(player);
						}
					}
				}
				catch
				{
				}
			}
			return list;
		}

		private static string PairKey(string a, string b)
		{
			return (string.CompareOrdinal(a, b) <= 0) ? (a + "|" + b) : (b + "|" + a);
		}

		private static void ResetTimer(string a, string b)
		{
			string key = PairKey(a, b);
			if (Instance._proximityTimers.ContainsKey(key))
			{
				Instance._proximityTimers[key] = 0f;
			}
		}

		private static bool IsCommittedToOtherMaster(string a, string b)
		{
			if (Instance._partnerOfMaster.TryGetValue(a, out string value) && value != b)
			{
				return true;
			}
			if (Instance._partnerOfMaster.TryGetValue(b, out string value2) && value2 != a)
			{
				return true;
			}
			return false;
		}

		private static bool IsAlreadyPaired(string a, string b)
		{
			string value;
			string value2;
			return (Instance._partnerOfMaster.TryGetValue(a, out value) && value == b) || (Instance._partnerOfMaster.TryGetValue(b, out value2) && value2 == a);
		}

		private static string SafeSteamID(PlayerAvatar p)
		{
			try
			{
				return SemiFunc.PlayerGetSteamID(p) ?? string.Empty;
			}
			catch
			{
				return string.Empty;
			}
		}

		private static string Short(string s)
		{
			object result;
			if (!string.IsNullOrEmpty(s))
			{
				if (s.Length > 6)
				{
					int length = s.Length;
					int num = length - 6;
					result = s.Substring(num, length - num);
				}
				else
				{
					result = s;
				}
			}
			else
			{
				result = "?";
			}
			return (string)result;
		}
	}
	internal class RelationshipLine : MonoBehaviour
	{
		private LineRenderer _lr = null;

		private Transform _ta = null;

		private Transform _tb = null;

		private ParticleSystem _psA = null;

		private ParticleSystem _psB = null;

		public PlayerAvatar PlayerA { get; private set; } = null;


		public PlayerAvatar PlayerB { get; private set; } = null;


		public void Setup(PlayerAvatar a, PlayerAvatar b, float width)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			PlayerA = a;
			PlayerB = b;
			_ta = ((Component)a).transform;
			_tb = ((Component)b).transform;
			_lr = ((Component)this).gameObject.AddComponent<LineRenderer>();
			_lr.positionCount = 2;
			_lr.useWorldSpace = true;
			_lr.startWidth = width;
			_lr.endWidth = width;
			_lr.numCornerVertices = 4;
			_lr.numCapVertices = 4;
			_lr.alignment = (LineAlignment)0;
			((Renderer)_lr).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)_lr).receiveShadows = false;
			((Renderer)_lr).allowOcclusionWhenDynamic = true;
			Shader val = Shader.Find("Unlit/Color") ?? Shader.Find("Standard");
			Material val2 = new Material(val);
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", new Color(1f, 0.4f, 0.8f, 1f));
			}
			((Renderer)_lr).material = val2;
			_lr.startColor = new Color(1f, 0.4f, 0.8f, 1f);
			_lr.endColor = new Color(1f, 0.4f, 0.8f, 1f);
			if (RelationshipPlugin.HeartReady && RelationshipPlugin.HeartsEnabled)
			{
				_psA = CreateHeartEmitter("REL_Hearts_A");
				_psB = CreateHeartEmitter("REL_Hearts_B");
			}
		}

		private ParticleSystem CreateHeartEmitter(string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: 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_01d9: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.parent = ((Component)this).transform;
			ParticleSystem val2 = val.AddComponent<ParticleSystem>();
			MainModule main = val2.main;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.9f, 1.5f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.3f, 0.9f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(RelationshipPlugin.HeartSize * 0.8f, RelationshipPlugin.HeartSize * 1.25f);
			((MainModule)(ref main)).maxParticles = 128;
			((MainModule)(ref main)).playOnAwake = true;
			EmissionModule emission = val2.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(RelationshipPlugin.HeartsPerSecond);
			ShapeModule shape = val2.shape;
			((ShapeModule)(ref shape)).enabled = true;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
			((ShapeModule)(ref shape)).angle = 15f;
			((ShapeModule)(ref shape)).radius = 0.05f;
			((ShapeModule)(ref shape)).position = Vector3.zero;
			VelocityOverLifetimeModule velocityOverLifetime = val2.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(0f, 0f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(0.6f, 1.4f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(0f, 0f);
			RotationOverLifetimeModule rotationOverLifetime = val2.rotationOverLifetime;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(-MathF.PI / 2f, MathF.PI / 2f);
			SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
			AnimationCurve val3 = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
			{
				new Keyframe(0f, 0.9f),
				new Keyframe(0.7f, 1f),
				new Keyframe(1f, 0.2f)
			});
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val3);
			ParticleSystemRenderer component = ((Component)val2).GetComponent<ParticleSystemRenderer>();
			((Renderer)component).material = RelationshipPlugin.HeartMaterial;
			component.renderMode = (ParticleSystemRenderMode)0;
			component.alignment = (ParticleSystemRenderSpace)0;
			component.sortingFudge = 2f;
			component.enableGPUInstancing = true;
			val2.Play();
			return val2;
		}

		private void LateUpdate()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00fd: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_lr) || !Object.op_Implicit((Object)(object)_ta) || !Object.op_Implicit((Object)(object)_tb))
			{
				if (Object.op_Implicit((Object)(object)_psA))
				{
					Object.Destroy((Object)(object)((Component)_psA).gameObject);
				}
				if (Object.op_Implicit((Object)(object)_psB))
				{
					Object.Destroy((Object)(object)((Component)_psB).gameObject);
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Vector3 val = _ta.position + Vector3.up * 0.9f;
			Vector3 val2 = _tb.position + Vector3.up * 0.9f;
			_lr.SetPosition(0, val);
			_lr.SetPosition(1, val2);
			if (Object.op_Implicit((Object)(object)_psA))
			{
				((Component)_psA).transform.position = val + Vector3.up * 0.15f;
			}
			if (Object.op_Implicit((Object)(object)_psB))
			{
				((Component)_psB).transform.position = val2 + Vector3.up * 0.15f;
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (Object.op_Implicit((Object)(object)_psA))
				{
					Object.Destroy((Object)(object)((Component)_psA).gameObject);
				}
			}
			catch
			{
			}
			try
			{
				if (Object.op_Implicit((Object)(object)_psB))
				{
					Object.Destroy((Object)(object)((Component)_psB).gameObject);
				}
			}
			catch
			{
			}
		}
	}
}