Decompiled source of Ampil PVPmod v1.3.0

RoR2PvPMode.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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 On.RoR2;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.CharacterAI;
using RoR2.Navigation;
using RoR2.Projectile;
using RoR2.SurvivorMannequins;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RoR2PvPMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RoR2PvPMode")]
[assembly: AssemblyTitle("RoR2PvPMode")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 RoR2PvPMode
{
	public enum MonsterChestRarity
	{
		Capsule,
		SmallChest,
		LargeChest,
		LegendaryChest
	}
	public struct MonsterSpawnEntry
	{
		public string DisplayName;

		public string[] MasterCandidateNames;

		public int SpawnCount;

		public MonsterSpawnEntry(string displayName, int spawnCount, params string[] masterCandidateNames)
		{
			DisplayName = displayName;
			SpawnCount = spawnCount;
			MasterCandidateNames = masterCandidateNames;
		}
	}
	public class MercenaryChestContract : MonoBehaviour
	{
		public MonsterChestRarity Rarity;

		public bool IsEliteContract;

		public GameObject LastActivator;
	}
	public class MercenaryEliteAuraOrbiter : MonoBehaviour
	{
		private Transform _orbitRoot;

		private void Start()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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)
			_orbitRoot = new GameObject("ElitePurpleAuraRoot").transform;
			_orbitRoot.SetParent(((Component)this).transform, false);
			_orbitRoot.localPosition = new Vector3(0f, 1.3f, 0f);
			Color color = default(Color);
			((Color)(ref color))..ctor(0.68f, 0.15f, 1f, 0.9f);
			for (int i = 0; i < 3; i++)
			{
				GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0);
				Object.Destroy((Object)(object)obj.GetComponent<Collider>());
				obj.transform.SetParent(_orbitRoot, false);
				float num = (float)i * 120f * (MathF.PI / 180f);
				obj.transform.localPosition = new Vector3(Mathf.Cos(num) * 1.35f, 0f, Mathf.Sin(num) * 1.35f);
				obj.transform.localScale = Vector3.one * 0.26f;
				MeshRenderer component = obj.GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).material != (Object)null)
				{
					((Renderer)component).material.color = color;
				}
				Light obj2 = obj.AddComponent<Light>();
				obj2.color = color;
				obj2.range = 4.5f;
				obj2.intensity = 2.2f;
			}
		}

		private void Update()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_orbitRoot != (Object)null)
			{
				_orbitRoot.Rotate(Vector3.up, 160f * Time.deltaTime, (Space)1);
				float num = 1.25f + Mathf.Sin(Time.time * 3.5f) * 0.25f;
				_orbitRoot.localPosition = new Vector3(0f, num, 0f);
			}
		}
	}
	public class AlliedMonsterAIController : MonoBehaviour
	{
		public CharacterMaster OwnerPlayerMaster;

		private CharacterMaster _monsterMaster;

		private BaseAI _baseAI;

		private float _retargetTimer;

		private void Awake()
		{
			_monsterMaster = ((Component)this).GetComponent<CharacterMaster>();
			_baseAI = ((Component)this).GetComponent<BaseAI>();
		}

		private void FixedUpdate()
		{
			if (NetworkServer.active && !((Object)(object)_monsterMaster == (Object)null) && !((Object)(object)_baseAI == (Object)null))
			{
				_retargetTimer -= Time.fixedDeltaTime;
				if (_retargetTimer <= 0f)
				{
					_retargetTimer = 0.4f;
					UpdateEnemyPlayerTarget();
				}
			}
		}

		private void UpdateEnemyPlayerTarget()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody body = _monsterMaster.GetBody();
			if ((Object)(object)body == (Object)null)
			{
				return;
			}
			CharacterBody val = null;
			float num = float.MaxValue;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				if ((Object)(object)instance == (Object)null || (Object)(object)instance.master == (Object)null || PvPBalanceEngine.ArePlayersOnSameTeam(OwnerPlayerMaster, instance.master))
				{
					continue;
				}
				CharacterBody body2 = instance.master.GetBody();
				if ((Object)(object)body2 != (Object)null && (Object)(object)body2.healthComponent != (Object)null && body2.healthComponent.alive)
				{
					float num2 = Vector3.Distance(body.corePosition, body2.corePosition);
					if (num2 < num)
					{
						num = num2;
						val = body2;
					}
				}
			}
			if ((Object)(object)val == (Object)null && (Object)(object)PvPGameController.Instance != (Object)null && (Object)(object)PvPGameController.Instance.ActiveSoloBotMaster != (Object)null)
			{
				CharacterMaster activeSoloBotMaster = PvPGameController.Instance.ActiveSoloBotMaster;
				if (!PvPBalanceEngine.ArePlayersOnSameTeam(OwnerPlayerMaster, activeSoloBotMaster))
				{
					CharacterBody body3 = activeSoloBotMaster.GetBody();
					if ((Object)(object)body3 != (Object)null && (Object)(object)body3.healthComponent != (Object)null && body3.healthComponent.alive)
					{
						val = body3;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				_baseAI.currentEnemy.gameObject = ((Component)val).gameObject;
				_baseAI.currentEnemy.bestHurtBox = val.mainHurtBox;
				_baseAI.enemyAttention = _baseAI.enemyAttentionDuration;
			}
		}
	}
	public class MercenaryChestManager : MonoBehaviour
	{
		private GameObject _capsulePrefab;

		private GameObject _smallChestPrefab;

		private GameObject _largeChestPrefab;

		private GameObject _legendaryChestPrefab;

		private readonly MonsterSpawnEntry[] _capsulePool = new MonsterSpawnEntry[5]
		{
			new MonsterSpawnEntry("Beetle", 1, "BeetleMaster"),
			new MonsterSpawnEntry("Alpha Construct", 1, "MinorConstructMaster"),
			new MonsterSpawnEntry("Blind Vermin", 1, "VerminMaster", "BlindVerminMaster"),
			new MonsterSpawnEntry("Gip", 1, "GipMaster"),
			new MonsterSpawnEntry("Lemurian", 1, "LemurianMaster")
		};

		private readonly MonsterSpawnEntry[] _smallChestPool = new MonsterSpawnEntry[6]
		{
			new MonsterSpawnEntry("Blind Pest", 1, "FlyingVerminMaster"),
			new MonsterSpawnEntry("Brass Contraption", 1, "BellMaster"),
			new MonsterSpawnEntry("Geep", 1, "GeepMaster"),
			new MonsterSpawnEntry("Imp", 1, "ImpMaster"),
			new MonsterSpawnEntry("Jellyfish", 1, "JellyfishMaster"),
			new MonsterSpawnEntry("Alloy Vulture", 1, "VultureMaster")
		};

		private readonly MonsterSpawnEntry[] _largeChestPool = new MonsterSpawnEntry[5]
		{
			new MonsterSpawnEntry("Bighorn Bison", 1, "BisonMaster"),
			new MonsterSpawnEntry("3x Child", 3, "ChildMaster"),
			new MonsterSpawnEntry("Greater Wisp", 1, "GreaterWispMaster"),
			new MonsterSpawnEntry("Lesser Wisp", 1, "WispMaster"),
			new MonsterSpawnEntry("Solus Probe", 1, "RoboBallMiniMaster")
		};

		private readonly MonsterSpawnEntry[] _legendaryChestPool = new MonsterSpawnEntry[4]
		{
			new MonsterSpawnEntry("Parent", 1, "ParentMaster"),
			new MonsterSpawnEntry("Scorch Worm", 1, "ScorchlingMaster"),
			new MonsterSpawnEntry("3x Stone Golem", 3, "GolemMaster"),
			new MonsterSpawnEntry("Void Reaver", 1, "NullifierMaster")
		};

		public static MercenaryChestManager Instance { get; private set; }

		public float SpawnTimer { get; private set; }

		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			Instance = this;
			_capsulePrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/EquipmentBarrel/EquipmentBarrel.prefab").WaitForCompletion();
			_smallChestPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Chest1/Chest1.prefab").WaitForCompletion();
			_largeChestPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Chest2/Chest2.prefab").WaitForCompletion();
			_legendaryChestPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/GoldChest/GoldChest.prefab").WaitForCompletion();
			PurchaseInteraction.OnInteractionBegin += new hook_OnInteractionBegin(OnPurchaseInteractionBegin);
			ChestBehavior.ItemDrop += new hook_ItemDrop(OnChestBehaviorItemDrop);
		}

		public void ResetTimer()
		{
			SpawnTimer = Mathf.Max(10f, RoR2PvPPlugin.CfgMercChestInterval.Value);
		}

		public void SetClientTimer(float syncedTimer)
		{
			SpawnTimer = syncedTimer;
		}

		private void Update()
		{
			if (NetworkServer.active && RoR2PvPPlugin.CfgEnablePvPMode.Value && !((Object)(object)PvPGameController.Instance == (Object)null) && PvPGameController.Instance.IsMatchActive)
			{
				SpawnTimer -= Time.deltaTime;
				if (SpawnTimer <= 0f)
				{
					SpawnTimer = Mathf.Max(15f, RoR2PvPPlugin.CfgMercChestInterval.Value);
					SpawnRandomMonsterChest();
				}
			}
		}

		private void SpawnRandomMonsterChest()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SceneInfo.instance == (Object)null || (Object)(object)SceneInfo.instance.groundNodes == (Object)null)
			{
				return;
			}
			Vector3 enemyPosition = Vector3.zero;
			if (PlayerCharacterMasterController.instances.Count > 0)
			{
				PlayerCharacterMasterController val = PlayerCharacterMasterController.instances[Random.Range(0, PlayerCharacterMasterController.instances.Count)];
				object obj;
				if (val == null)
				{
					obj = null;
				}
				else
				{
					CharacterMaster master = val.master;
					obj = ((master != null) ? master.GetBody() : null);
				}
				if ((Object)obj != (Object)null)
				{
					enemyPosition = val.master.GetBody().corePosition;
				}
			}
			Vector3 position = PvPGameController.Instance.FindSafeRespawnPosition(enemyPosition);
			float num = Random.Range(0f, 100f);
			MonsterChestRarity rarity = ((!(num < 50f)) ? ((num < 80f) ? MonsterChestRarity.SmallChest : ((!(num < 95f)) ? MonsterChestRarity.LegendaryChest : MonsterChestRarity.LargeChest)) : MonsterChestRarity.Capsule);
			bool isElite = Random.Range(0f, 100f) < RoR2PvPPlugin.CfgEliteChestChancePercent.Value;
			CreateMercenaryContainer(position, rarity, isElite);
		}

		private void CreateMercenaryContainer(Vector3 position, MonsterChestRarity rarity, bool isElite)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			GameObject prefabForRarity = GetPrefabForRarity(rarity);
			if (!((Object)(object)prefabForRarity == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(prefabForRarity, position, Quaternion.identity);
				MercenaryChestContract mercenaryChestContract = val.AddComponent<MercenaryChestContract>();
				mercenaryChestContract.Rarity = rarity;
				mercenaryChestContract.IsEliteContract = isElite;
				if (isElite)
				{
					val.AddComponent<MercenaryEliteAuraOrbiter>();
				}
				int num = GetBaseCostForRarity(rarity);
				if (isElite)
				{
					num = Mathf.RoundToInt((float)num * Mathf.Max(1f, RoR2PvPPlugin.CfgEliteCostMultiplier.Value));
				}
				string russianNameForRarity = GetRussianNameForRarity(rarity);
				string text = (isElite ? " <color=#CC66FF>[ЭЛИТНЫЙ 2%]</color>" : "");
				PurchaseInteraction component = val.GetComponent<PurchaseInteraction>();
				if ((Object)(object)component != (Object)null)
				{
					component.costType = (CostTypeIndex)1;
					component.Networkcost = (((Object)(object)Run.instance != (Object)null) ? Run.instance.GetDifficultyScaledCost(num) : num);
					component.contextToken = "Призвать монстра-союзника (" + russianNameForRarity + ")" + text;
					component.displayNameToken = russianNameForRarity + text;
				}
				NetworkServer.Spawn(val);
				GameObject val2 = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/TeleportOutBoom");
				if ((Object)(object)val2 != (Object)null)
				{
					EffectManager.SpawnEffect(val2, new EffectData
					{
						origin = position
					}, true);
				}
				SimpleChatMessage val3 = new SimpleChatMessage();
				val3.baseToken = "<color=#FFA500>[ПРИЗЫВ МОНСТРА]</color> На арене появился объект: <b>" + russianNameForRarity + "</b>" + text + "!";
				Chat.SendBroadcastChat((ChatMessageBase)(object)val3);
			}
		}

		private GameObject GetPrefabForRarity(MonsterChestRarity rarity)
		{
			return (GameObject)(rarity switch
			{
				MonsterChestRarity.Capsule => _capsulePrefab ?? _smallChestPrefab, 
				MonsterChestRarity.SmallChest => _smallChestPrefab, 
				MonsterChestRarity.LargeChest => _largeChestPrefab, 
				MonsterChestRarity.LegendaryChest => _legendaryChestPrefab ?? _largeChestPrefab, 
				_ => _smallChestPrefab, 
			});
		}

		private int GetBaseCostForRarity(MonsterChestRarity rarity)
		{
			return rarity switch
			{
				MonsterChestRarity.Capsule => RoR2PvPPlugin.CfgCostCapsule.Value, 
				MonsterChestRarity.SmallChest => RoR2PvPPlugin.CfgCostSmallChest.Value, 
				MonsterChestRarity.LargeChest => RoR2PvPPlugin.CfgCostLargeChest.Value, 
				MonsterChestRarity.LegendaryChest => RoR2PvPPlugin.CfgCostLegendaryChest.Value, 
				_ => 50, 
			};
		}

		private string GetRussianNameForRarity(MonsterChestRarity rarity)
		{
			return rarity switch
			{
				MonsterChestRarity.Capsule => "Капсула монстра", 
				MonsterChestRarity.SmallChest => "Обычный сундук монстра", 
				MonsterChestRarity.LargeChest => "Большой сундук монстра", 
				MonsterChestRarity.LegendaryChest => "Легендарный сундук монстра", 
				_ => "Сундук монстра", 
			};
		}

		private void OnPurchaseInteractionBegin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor activator)
		{
			MercenaryChestContract mercenaryChestContract = (((Object)(object)self != (Object)null) ? ((Component)self).GetComponent<MercenaryChestContract>() : null);
			if ((Object)(object)mercenaryChestContract != (Object)null && (Object)(object)activator != (Object)null)
			{
				mercenaryChestContract.LastActivator = ((Component)activator).gameObject;
			}
			orig.Invoke(self, activator);
		}

		private void OnChestBehaviorItemDrop(orig_ItemDrop orig, ChestBehavior self)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			MercenaryChestContract mercenaryChestContract = (((Object)(object)self != (Object)null) ? ((Component)self).GetComponent<MercenaryChestContract>() : null);
			if ((Object)(object)mercenaryChestContract != (Object)null)
			{
				if (NetworkServer.active)
				{
					SummonMonsterFromContract(mercenaryChestContract, ((Component)self).transform.position);
					Object.Destroy((Object)(object)((Component)self).gameObject, 1.5f);
				}
			}
			else
			{
				orig.Invoke(self);
			}
		}

		private void SummonMonsterFromContract(MercenaryChestContract contract, Vector3 spawnPos)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody val = (Object.op_Implicit((Object)(object)contract.LastActivator) ? contract.LastActivator.GetComponent<CharacterBody>() : null);
			CharacterMaster val2 = (Object.op_Implicit((Object)(object)val) ? val.master : null);
			MonsterSpawnEntry[] poolForRarity = GetPoolForRarity(contract.Rarity);
			MonsterSpawnEntry monsterSpawnEntry = poolForRarity[Random.Range(0, poolForRarity.Length)];
			GameObject val3 = FindMasterPrefabByCandidates(monsterSpawnEntry.MasterCandidateNames);
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = MasterCatalog.FindMasterPrefab("LemurianMaster");
			}
			if ((Object)(object)val3 == (Object)null)
			{
				return;
			}
			int num = Mathf.Max(1, monsterSpawnEntry.SpawnCount);
			Vector3 val4 = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				((Vector3)(ref val4))..ctor(((float)i - (float)(num - 1) * 0.5f) * 2.5f, 1.5f, 0f);
				CharacterMaster val5 = new MasterSummon
				{
					masterPrefab = val3,
					position = spawnPos + val4,
					rotation = Quaternion.identity,
					summonerBodyObject = (Object.op_Implicit((Object)(object)val) ? ((Component)val).gameObject : null),
					ignoreTeamMemberLimit = true,
					useAmbientLevel = true,
					teamIndexOverride = (TeamIndex)1
				}.Perform();
				if ((Object)(object)val5 == (Object)null)
				{
					continue;
				}
				((Component)val5).gameObject.AddComponent<AlliedMonsterAIController>().OwnerPlayerMaster = val2;
				if (!((Object)(object)val5.inventory != (Object)null))
				{
					continue;
				}
				val5.inventory.GiveItem(Items.Hoof, 3);
				if (contract.IsEliteContract)
				{
					val5.inventory.GiveItem(Items.BoostHp, 15);
					val5.inventory.GiveItem(Items.BoostDamage, 8);
					EquipmentDef[] array = (EquipmentDef[])(object)new EquipmentDef[3]
					{
						Elites.Fire?.eliteEquipmentDef,
						Elites.Lightning?.eliteEquipmentDef,
						Elites.Ice?.eliteEquipmentDef
					};
					EquipmentDef val6 = array[Random.Range(0, array.Length)];
					if ((Object)(object)val6 != (Object)null)
					{
						val5.inventory.SetEquipmentIndex(val6.equipmentIndex);
					}
				}
			}
			string text = (Object.op_Implicit((Object)(object)((val2 != null) ? val2.playerCharacterMasterController : null)) ? val2.playerCharacterMasterController.GetDisplayName() : "Игрок");
			string text2 = (contract.IsEliteContract ? " <color=#CC66FF><b>[ЭЛИТНЫЙ]</b></color>" : "");
			SimpleChatMessage val7 = new SimpleChatMessage();
			val7.baseToken = "<color=#55FF55>[НАЁМНИК]</color> <b>" + text + "</b> открыл " + GetRussianNameForRarity(contract.Rarity) + " и призвал: <b>" + monsterSpawnEntry.DisplayName + "</b>" + text2 + "!";
			Chat.SendBroadcastChat((ChatMessageBase)(object)val7);
		}

		private MonsterSpawnEntry[] GetPoolForRarity(MonsterChestRarity rarity)
		{
			return rarity switch
			{
				MonsterChestRarity.Capsule => _capsulePool, 
				MonsterChestRarity.SmallChest => _smallChestPool, 
				MonsterChestRarity.LargeChest => _largeChestPool, 
				MonsterChestRarity.LegendaryChest => _legendaryChestPool, 
				_ => _capsulePool, 
			};
		}

		private GameObject FindMasterPrefabByCandidates(string[] candidateNames)
		{
			if (candidateNames == null)
			{
				return null;
			}
			for (int i = 0; i < candidateNames.Length; i++)
			{
				GameObject val = MasterCatalog.FindMasterPrefab(candidateNames[i]);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	public class PvPDummyBotComponent : MonoBehaviour
	{
		public PvPTeam AssignedTeam = PvPTeam.Red;

		private CharacterMaster _master;

		private BaseAI _ai;

		private float _aiUpdateTimer;

		private void Awake()
		{
			_master = ((Component)this).GetComponent<CharacterMaster>();
			_ai = ((Component)this).GetComponent<BaseAI>();
		}

		private void FixedUpdate()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || (Object)(object)_master == (Object)null)
			{
				return;
			}
			CharacterBody body = _master.GetBody();
			if ((Object)(object)body == (Object)null)
			{
				return;
			}
			bool flag = RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value && (Object)(object)PvPGameController.Instance != (Object)null && PvPGameController.Instance.IsMatchActive;
			if ((Object)(object)_ai != (Object)null)
			{
				((Behaviour)_ai).enabled = flag;
			}
			if (!flag)
			{
				if ((Object)(object)body.inputBank != (Object)null)
				{
					body.inputBank.moveVector = Vector3.zero;
					((ButtonState)(ref body.inputBank.skill1)).PushState(false);
					((ButtonState)(ref body.inputBank.skill2)).PushState(false);
					((ButtonState)(ref body.inputBank.skill3)).PushState(false);
					((ButtonState)(ref body.inputBank.skill4)).PushState(false);
				}
				return;
			}
			_aiUpdateTimer -= Time.fixedDeltaTime;
			if (!(_aiUpdateTimer <= 0f) || !((Object)(object)_ai != (Object)null))
			{
				return;
			}
			_aiUpdateTimer = 0.4f;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				if (!((Object)(object)((instance != null) ? instance.master : null) == (Object)null))
				{
					CharacterBody body2 = instance.master.GetBody();
					if ((Object)(object)body2 != (Object)null && (Object)(object)body2.healthComponent != (Object)null && body2.healthComponent.alive)
					{
						_ai.currentEnemy.gameObject = ((Component)body2).gameObject;
						_ai.currentEnemy.bestHurtBox = body2.mainHurtBox;
						_ai.enemyAttention = _ai.enemyAttentionDuration;
						break;
					}
				}
			}
		}
	}
	public static class PvPBalanceEngine
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static StatHookEventHandler <0>__OnGetStatCoefficients;

			public static hook_TakeDamage <1>__OnHealthComponentTakeDamage;

			public static hook_InflictDot_refInflictDotInfo <2>__OnInflictDot;

			public static hook_CollectHits <3>__OnBlastAttackCollectHits;

			public static hook_RefreshCandidates <4>__OnBullseyeRefreshCandidates;
		}

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0070: 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_007b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			object obj = <>O.<0>__OnGetStatCoefficients;
			if (obj == null)
			{
				StatHookEventHandler val = OnGetStatCoefficients;
				<>O.<0>__OnGetStatCoefficients = val;
				obj = (object)val;
			}
			RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj;
			object obj2 = <>O.<1>__OnHealthComponentTakeDamage;
			if (obj2 == null)
			{
				hook_TakeDamage val2 = OnHealthComponentTakeDamage;
				<>O.<1>__OnHealthComponentTakeDamage = val2;
				obj2 = (object)val2;
			}
			HealthComponent.TakeDamage += (hook_TakeDamage)obj2;
			object obj3 = <>O.<2>__OnInflictDot;
			if (obj3 == null)
			{
				hook_InflictDot_refInflictDotInfo val3 = OnInflictDot;
				<>O.<2>__OnInflictDot = val3;
				obj3 = (object)val3;
			}
			DotController.InflictDot_refInflictDotInfo += (hook_InflictDot_refInflictDotInfo)obj3;
			object obj4 = <>O.<3>__OnBlastAttackCollectHits;
			if (obj4 == null)
			{
				hook_CollectHits val4 = OnBlastAttackCollectHits;
				<>O.<3>__OnBlastAttackCollectHits = val4;
				obj4 = (object)val4;
			}
			BlastAttack.CollectHits += (hook_CollectHits)obj4;
			object obj5 = <>O.<4>__OnBullseyeRefreshCandidates;
			if (obj5 == null)
			{
				hook_RefreshCandidates val5 = OnBullseyeRefreshCandidates;
				<>O.<4>__OnBullseyeRefreshCandidates = val5;
				obj5 = (object)val5;
			}
			BullseyeSearch.RefreshCandidates += (hook_RefreshCandidates)obj5;
		}

		private static void OnGetStatCoefficients(CharacterBody sender, StatHookEventArgs args)
		{
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value && !((Object)(object)sender == (Object)null) && IsPlayerControlledSurvivor(sender))
			{
				float num = Mathf.Max(1f, RoR2PvPPlugin.CfgPlayerHealthMult.Value);
				float num2 = Mathf.Max(1f, RoR2PvPPlugin.CfgPlayerRegenMult.Value);
				args.healthMultAdd += num - 1f;
				args.regenMultAdd += num2 - 1f;
				args.moveSpeedMultAdd += 0.15f;
			}
		}

		private static HitPoint[] OnBlastAttackCollectHits(orig_CollectHits orig, BlastAttack self)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			HitPoint[] array = orig.Invoke(self);
			if (!RoR2PvPPlugin.CfgEnablePvPMode.Value || self == null || array == null || array.Length == 0)
			{
				return array;
			}
			CharacterMaster val = ResolveOwnerMasterFromGameObject(self.attacker) ?? ResolveOwnerMasterFromGameObject(self.inflictor);
			if ((Object)(object)val == (Object)null)
			{
				return array;
			}
			List<HitPoint> list = new List<HitPoint>(array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				HurtBox hurtBox = array[i].hurtBox;
				CharacterBody val2 = (((Object)(object)hurtBox != (Object)null && (Object)(object)hurtBox.healthComponent != (Object)null) ? hurtBox.healthComponent.body : null);
				if ((Object)(object)val2 != (Object)null)
				{
					CharacterMaster rootPlayerOwner = GetRootPlayerOwner(val2);
					if ((Object)(object)rootPlayerOwner != (Object)null && ArePlayersOnSameTeam(val, rootPlayerOwner))
					{
						continue;
					}
				}
				list.Add(array[i]);
			}
			return list.ToArray();
		}

		private static void OnInflictDot(orig_InflictDot_refInflictDotInfo orig, ref InflictDotInfo inflictDotInfo)
		{
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value)
			{
				CharacterMaster val = ResolveOwnerMasterFromGameObject(inflictDotInfo.victimObject);
				CharacterMaster val2 = ResolveOwnerMasterFromGameObject(inflictDotInfo.attackerObject);
				if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && ArePlayersOnSameTeam(val, val2))
				{
					return;
				}
			}
			orig.Invoke(ref inflictDotInfo);
		}

		private static void OnBullseyeRefreshCandidates(orig_RefreshCandidates orig, BullseyeSearch self)
		{
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value && (Object)(object)PvPGameController.Instance != (Object)null && PvPGameController.Instance.IsMatchActive)
			{
				((TeamMask)(ref self.teamMaskFilter)).AddTeam((TeamIndex)1);
			}
			orig.Invoke(self);
			if (!RoR2PvPPlugin.CfgEnablePvPMode.Value || !((Object)(object)self.viewer != (Object)null))
			{
				return;
			}
			CharacterMaster viewerOwner = GetRootPlayerOwner(self.viewer);
			if (!((Object)(object)viewerOwner != (Object)null))
			{
				return;
			}
			self.candidatesEnumerable = self.candidatesEnumerable.Where(delegate(CandidateInfo c)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)c.hurtBox == (Object)null || (Object)(object)c.hurtBox.healthComponent == (Object)null)
				{
					return true;
				}
				CharacterBody body = c.hurtBox.healthComponent.body;
				if ((Object)(object)body == (Object)null)
				{
					return true;
				}
				CharacterMaster rootPlayerOwner = GetRootPlayerOwner(body);
				return (Object)(object)rootPlayerOwner == (Object)null || !ArePlayersOnSameTeam(viewerOwner, rootPlayerOwner);
			}).ToList();
		}

		private static void OnHealthComponentTakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			if (!RoR2PvPPlugin.CfgEnablePvPMode.Value || (Object)(object)PvPGameController.Instance == (Object)null || (Object)(object)self == (Object)null || (Object)(object)self.body == (Object)null || damageInfo == null)
			{
				orig.Invoke(self, damageInfo);
				return;
			}
			if ((PvPGameController.Instance.IsWarmupActive || PvPGameController.Instance.IsMatchFinished) && IsPlayerControlledSurvivor(self.body))
			{
				damageInfo.rejected = true;
				return;
			}
			CharacterBody body = self.body;
			CharacterBody killerBody = (Object.op_Implicit((Object)(object)damageInfo.attacker) ? damageInfo.attacker.GetComponent<CharacterBody>() : null);
			CharacterMaster rootPlayerOwner = GetRootPlayerOwner(body);
			CharacterMaster val = ResolveOwnerMasterFromGameObject(damageInfo.attacker) ?? ResolveOwnerMasterFromGameObject(damageInfo.inflictor);
			if ((Object)(object)rootPlayerOwner != (Object)null && (Object)(object)val != (Object)null && ArePlayersOnSameTeam(rootPlayerOwner, val))
			{
				damageInfo.damage = 0f;
				damageInfo.rejected = true;
				return;
			}
			if ((Object)(object)damageInfo.attacker == (Object)(object)((Component)body).gameObject || (Object)(object)damageInfo.inflictor == (Object)(object)((Component)body).gameObject)
			{
				damageInfo.damage = 0f;
				damageInfo.rejected = true;
				return;
			}
			if (IsSummonedChestMonster(body))
			{
				float num = Mathf.Max(0.1f, RoR2PvPPlugin.CfgSummonedMonsterDamageTakenMult.Value);
				damageInfo.damage *= num;
			}
			bool flag = IsPlayerControlledSurvivor(body);
			bool flag2 = (Object)(object)val != (Object)null;
			if (flag && flag2 && !ArePlayersOnSameTeam(rootPlayerOwner, val))
			{
				if ((int)DamageTypeCombo.op_Implicit(damageInfo.damageType & DamageTypeCombo.op_Implicit((DamageType)256)) != 0)
				{
					damageInfo.damageType &= DamageTypeCombo.op_Implicit((DamageType)(-257));
					body.AddTimedBuff(Buffs.Slow80, 1.5f);
				}
				damageInfo.damageType &= DamageTypeCombo.op_Implicit((DamageType)(-262145));
				damageInfo.damageType &= DamageTypeCombo.op_Implicit((DamageType)(-65537));
				float num2 = damageInfo.damage * RoR2PvPPlugin.CfgPvPDamageScale.Value;
				float num3 = Mathf.Max(100f, self.fullCombinedHealth);
				float num4 = num3 * RoR2PvPPlugin.CfgSoftCapThresholdPercent.Value;
				if (num2 > num4)
				{
					float num5 = num2 - num4;
					num2 = num4 + num5 / (1f + num5 / num4);
				}
				float num6 = num3 * RoR2PvPPlugin.CfgHardCapMaxHitPercent.Value;
				num2 = Mathf.Min(num2, num6);
				damageInfo.damage = Mathf.Max(1f, num2);
			}
			orig.Invoke(self, damageInfo);
			if (NetworkServer.active && flag && self.health <= 0f)
			{
				PvPGameController.Instance.HandlePlayerDefeated(body, val, killerBody);
			}
		}

		public static CharacterMaster ResolveOwnerMasterFromGameObject(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return null;
			}
			CharacterBody component = obj.GetComponent<CharacterBody>();
			if ((Object)(object)component != (Object)null)
			{
				return GetRootPlayerOwner(component);
			}
			ProjectileController component2 = obj.GetComponent<ProjectileController>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)component2.owner != (Object)null && (Object)(object)component2.owner != (Object)(object)obj)
			{
				CharacterMaster val = ResolveOwnerMasterFromGameObject(component2.owner);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			GenericOwnership component3 = obj.GetComponent<GenericOwnership>();
			if ((Object)(object)component3 != (Object)null && (Object)(object)component3.ownerObject != (Object)null && (Object)(object)component3.ownerObject != (Object)(object)obj)
			{
				CharacterMaster val2 = ResolveOwnerMasterFromGameObject(component3.ownerObject);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			CharacterMaster component4 = obj.GetComponent<CharacterMaster>();
			if ((Object)(object)component4 != (Object)null && ((Object)(object)component4.playerCharacterMasterController != (Object)null || (Object)(object)((Component)component4).GetComponent<PvPDummyBotComponent>() != (Object)null))
			{
				return component4;
			}
			return null;
		}

		public static bool ArePlayersOnSameTeam(CharacterMaster masterA, CharacterMaster masterB)
		{
			if ((Object)(object)masterA == (Object)null || (Object)(object)masterB == (Object)null)
			{
				return false;
			}
			if ((Object)(object)masterA == (Object)(object)masterB)
			{
				return true;
			}
			if ((Object)(object)PvPGameController.Instance != (Object)null)
			{
				PvPTeam playerTeam = PvPGameController.Instance.GetPlayerTeam(masterA);
				PvPTeam playerTeam2 = PvPGameController.Instance.GetPlayerTeam(masterB);
				if (playerTeam != PvPTeam.None && playerTeam == playerTeam2)
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsPlayerControlledSurvivor(CharacterBody body)
		{
			if ((Object)(object)body == (Object)null || (Object)(object)body.master == (Object)null)
			{
				return false;
			}
			if ((Object)(object)body.master.playerCharacterMasterController != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)body.master).GetComponent<PvPDummyBotComponent>() != (Object)null)
			{
				return true;
			}
			return false;
		}

		public static bool IsSummonedChestMonster(CharacterBody body)
		{
			if ((Object)(object)body == (Object)null || (Object)(object)body.master == (Object)null)
			{
				return false;
			}
			return (Object)(object)((Component)body.master).GetComponent<AlliedMonsterAIController>() != (Object)null;
		}

		public static CharacterMaster GetRootPlayerOwner(CharacterBody body)
		{
			if ((Object)(object)body == (Object)null || (Object)(object)body.master == (Object)null)
			{
				return null;
			}
			if ((Object)(object)body.master.playerCharacterMasterController != (Object)null)
			{
				return body.master;
			}
			if ((Object)(object)((Component)body.master).GetComponent<PvPDummyBotComponent>() != (Object)null)
			{
				return body.master;
			}
			AlliedMonsterAIController component = ((Component)body.master).GetComponent<AlliedMonsterAIController>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.OwnerPlayerMaster != (Object)null)
			{
				return component.OwnerPlayerMaster;
			}
			CharacterMaster val = (Object.op_Implicit((Object)(object)body.master.minionOwnership) ? body.master.minionOwnership.ownerMaster : null);
			if ((Object)(object)val != (Object)null && ((Object)(object)val.playerCharacterMasterController != (Object)null || (Object)(object)((Component)val).GetComponent<PvPDummyBotComponent>() != (Object)null))
			{
				return val;
			}
			return null;
		}
	}
	public class PlayerPvPStats
	{
		public CharacterMaster Master;

		public string PlayerName;

		public PvPTeam Team;

		public int Kills;

		public int Deaths;

		public int KillStreak;
	}
	public class PvPGameController : MonoBehaviour
	{
		public Dictionary<NetworkInstanceId, PlayerPvPStats> Scoreboard = new Dictionary<NetworkInstanceId, PlayerPvPStats>();

		public Dictionary<NetworkInstanceId, PvPTeam> LobbyTeamsByNetUser = new Dictionary<NetworkInstanceId, PvPTeam>();

		private float _passiveGoldTimer;

		private float _networkSyncTimer;

		private float _mannequinOutlineTimer;

		private float _soloBotDelayedSpawnTimer;

		private bool _soloBotSpawnedForStage;

		private bool _warmupAnnouncedEnd;

		public static PvPGameController Instance { get; private set; }

		public float WarmupTimer { get; private set; }

		public bool IsWarmupActive
		{
			get
			{
				if (WarmupTimer > 0f)
				{
					return !IsMatchFinished;
				}
				return false;
			}
		}

		public bool IsMatchActive
		{
			get
			{
				if (WarmupTimer <= 0f && !IsMatchFinished)
				{
					return (Object)(object)Run.instance != (Object)null;
				}
				return false;
			}
		}

		public bool IsMatchFinished { get; private set; }

		public string WinnerName { get; private set; } = "";

		public bool LocalLobbyTeamLocked { get; set; }

		public CharacterMaster ActiveSoloBotMaster { get; private set; }

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			Instance = this;
			PreGameController.Start += new hook_Start(OnPreGameControllerStart);
			Run.PickNextStageScene += new hook_PickNextStageScene(OnRunPickNextStageScene);
			SceneDirector.Start += new hook_Start(OnSceneDirectorStart);
			CombatDirector.Simulate += new hook_Simulate(OnCombatDirectorSimulate);
			Run.BeginGameOver += new hook_BeginGameOver(OnRunBeginGameOver);
			CharacterMaster.OnBodyDeath += new hook_OnBodyDeath(OnCharacterMasterBodyDeath);
		}

		public bool IsSingleplayerSession()
		{
			if (!RoR2Application.isInSinglePlayer)
			{
				return NetworkUser.readOnlyInstancesList.Count <= 1;
			}
			return true;
		}

		private void OnPreGameControllerStart(orig_Start orig, PreGameController self)
		{
			orig.Invoke(self);
			LobbyTeamsByNetUser.Clear();
			LocalLobbyTeamLocked = false;
		}

		public void ServerSetPlayerLobbyTeam(NetworkInstanceId netUserId, PvPTeam team)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && !((Object)(object)Run.instance != (Object)null) && (!LobbyTeamsByNetUser.TryGetValue(netUserId, out var value) || value == PvPTeam.None))
			{
				LobbyTeamsByNetUser[netUserId] = team;
				BroadcastLobbyTeamsToAll();
			}
		}

		public void BroadcastLobbyTeamsToAll()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				List<KeyValuePair<NetworkInstanceId, PvPTeam>> list = LobbyTeamsByNetUser.ToList();
				BroadcastLobbyTeamsMessage broadcastLobbyTeamsMessage = new BroadcastLobbyTeamsMessage
				{
					Count = list.Count,
					UserNetIds = (NetworkInstanceId[])(object)new NetworkInstanceId[list.Count],
					TeamValues = new int[list.Count]
				};
				for (int i = 0; i < list.Count; i++)
				{
					broadcastLobbyTeamsMessage.UserNetIds[i] = list[i].Key;
					broadcastLobbyTeamsMessage.TeamValues[i] = (int)list[i].Value;
				}
				NetMessageExtensions.Send((INetMessage)(object)broadcastLobbyTeamsMessage, (NetworkDestination)1);
			}
		}

		public void ClientApplyLobbyTeam(NetworkInstanceId netUserId, PvPTeam team)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			LobbyTeamsByNetUser[netUserId] = team;
			UpdateLobbyMannequinOutlines();
		}

		public PvPTeam GetLobbyTeamForUser(NetworkUser user)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)user == (Object)null)
			{
				return PvPTeam.None;
			}
			if (!LobbyTeamsByNetUser.TryGetValue(((NetworkBehaviour)user).netId, out var value))
			{
				return PvPTeam.None;
			}
			return value;
		}

		public PvPTeam GetPlayerTeam(CharacterMaster master)
		{
			//IL_0029: 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)(object)master == (Object)null)
			{
				return PvPTeam.None;
			}
			PvPDummyBotComponent component = ((Component)master).GetComponent<PvPDummyBotComponent>();
			if ((Object)(object)component != (Object)null)
			{
				return component.AssignedTeam;
			}
			if (Scoreboard.TryGetValue(((NetworkBehaviour)master).netId, out var value) && value.Team != PvPTeam.None)
			{
				return value.Team;
			}
			if ((Object)(object)master.playerCharacterMasterController != (Object)null && (Object)(object)master.playerCharacterMasterController.networkUser != (Object)null)
			{
				NetworkUser networkUser = master.playerCharacterMasterController.networkUser;
				if (LobbyTeamsByNetUser.TryGetValue(((NetworkBehaviour)networkUser).netId, out var value2))
				{
					return value2;
				}
			}
			return PvPTeam.None;
		}

		private void UpdateLobbyMannequinOutlines()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PreGameController.instance == (Object)null)
			{
				return;
			}
			SurvivorMannequinSlotController[] array = Object.FindObjectsOfType<SurvivorMannequinSlotController>();
			foreach (SurvivorMannequinSlotController val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.networkUser == (Object)null || (Object)(object)val.mannequinInstanceTransform == (Object)null)
				{
					continue;
				}
				PvPTeam lobbyTeamForUser = GetLobbyTeamForUser(val.networkUser);
				if (lobbyTeamForUser == PvPTeam.None)
				{
					continue;
				}
				Color teamColor = RoR2PvPPlugin.GetTeamColor(lobbyTeamForUser, 0.75f);
				Renderer[] componentsInChildren = ((Component)val.mannequinInstanceTransform).GetComponentsInChildren<Renderer>(true);
				if (componentsInChildren.Length != 0)
				{
					Renderer targetRenderer = componentsInChildren[0];
					Highlight val2 = ((Component)val.mannequinInstanceTransform).GetComponent<Highlight>();
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = ((Component)val.mannequinInstanceTransform).gameObject.AddComponent<Highlight>();
					}
					val2.targetRenderer = targetRenderer;
					val2.strength = 0.85f;
					val2.isOn = true;
					val2.highlightColor = (HighlightColor)(lobbyTeamForUser == PvPTeam.Blue);
					Transform val3 = val.mannequinInstanceTransform.Find("PvPLobbyTeamRimLight");
					Light val5;
					if ((Object)(object)val3 == (Object)null)
					{
						GameObject val4 = new GameObject("PvPLobbyTeamRimLight");
						val4.transform.SetParent(val.mannequinInstanceTransform, false);
						val4.transform.localPosition = new Vector3(0f, 1.2f, 0.6f);
						val5 = val4.AddComponent<Light>();
						val5.type = (LightType)2;
						val5.range = 3.5f;
						val5.intensity = 2.6f;
					}
					else
					{
						val5 = ((Component)val3).GetComponent<Light>();
					}
					if ((Object)(object)val5 != (Object)null)
					{
						val5.color = teamColor;
					}
				}
			}
		}

		private void OnRunPickNextStageScene(orig_PickNextStageScene orig, Run self, WeightedSelection<SceneDef> choices)
		{
			orig.Invoke(self, choices);
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value)
			{
				SceneDef val = PickConfiguredArenaScene();
				if ((Object)(object)val != (Object)null)
				{
					self.nextStageScene = val;
					RoR2PvPPlugin.Log.LogInfo((object)("[PvP] Выбрана арена для матча: " + val.baseSceneName));
				}
			}
		}

		public SceneDef PickConfiguredArenaScene()
		{
			string text = "habitat";
			switch (RoR2PvPPlugin.CfgArenaMap.Value)
			{
			case PvPArenaMap.GoldenDieback:
				text = "habitatfall";
				break;
			case PvPArenaMap.RandomBoth:
				text = ((Random.value < 0.5f) ? "habitat" : "habitatfall");
				break;
			}
			SceneDef val = SceneCatalog.GetSceneDefFromSceneName(text);
			if ((Object)(object)val == (Object)null)
			{
				val = SceneCatalog.GetSceneDefFromSceneName("habitat") ?? SceneCatalog.GetSceneDefFromSceneName("habitatfall");
			}
			return val;
		}

		private void OnSceneDirectorStart(orig_Start orig, SceneDirector self)
		{
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value)
			{
				self.interactableCredit = 0;
				self.teleporterSpawnCard = null;
				if (!RoR2PvPPlugin.CfgAllowAmbientMonsters.Value)
				{
					self.monsterCredit = 0;
				}
			}
			orig.Invoke(self);
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value)
			{
				CleanMapInteractables();
				StartNewPvPMatch();
			}
		}

		private void CleanMapInteractables()
		{
			PurchaseInteraction[] array = Object.FindObjectsOfType<PurchaseInteraction>();
			foreach (PurchaseInteraction val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && !((Object)(object)((Component)val).GetComponent<MercenaryChestContract>() != (Object)null))
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			BarrelInteraction[] array2 = Object.FindObjectsOfType<BarrelInteraction>();
			foreach (BarrelInteraction val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
		}

		private void OnCombatDirectorSimulate(orig_Simulate orig, CombatDirector self, float deltaTime)
		{
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value && !RoR2PvPPlugin.CfgAllowAmbientMonsters.Value)
			{
				self.monsterCredit = 0f;
			}
			else
			{
				orig.Invoke(self, deltaTime);
			}
		}

		private void OnRunBeginGameOver(orig_BeginGameOver orig, Run self, GameEndingDef gameEndingDef)
		{
			if (!RoR2PvPPlugin.CfgEnablePvPMode.Value || IsMatchFinished)
			{
				orig.Invoke(self, gameEndingDef);
			}
		}

		public void StartNewPvPMatch()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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)
			//IL_012b: Expected O, but got Unknown
			Scoreboard.Clear();
			PvPUIManager.Instance?.ClearLocalDrafts();
			IsMatchFinished = false;
			WinnerName = "";
			WarmupTimer = Mathf.Max(1f, RoR2PvPPlugin.CfgWarmupDuration.Value);
			_warmupAnnouncedEnd = false;
			_soloBotDelayedSpawnTimer = 2f;
			_soloBotSpawnedForStage = false;
			FriendlyFireManager.friendlyFireMode = (FriendlyFireMode)2;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				RegisterPlayerIfNeeded(instance.master);
				CharacterBody val = (Object.op_Implicit((Object)(object)instance.master) ? instance.master.GetBody() : null);
				if ((Object)(object)val != (Object)null && NetworkServer.active)
				{
					val.AddTimedBuff(Buffs.HiddenInvincibility, WarmupTimer);
				}
			}
			MercenaryChestManager.Instance?.ResetTimer();
			if (NetworkServer.active)
			{
				int num = Mathf.Max(1, RoR2PvPPlugin.CfgTargetKills.Value);
				Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
				{
					baseToken = $"<color=#FFD700>[PVP АРЕНА]</color> Разминка <color=#00FFCC>{WarmupTimer:0} сек.</color>! Игра идёт до <color=#FF5555>{num}</color> убийств."
				});
				BroadcastMatchStateToClients();
			}
		}

		public void SpawnOrTeleportSoloBot(bool forceSpawnEvenIfDisabled = false)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0155: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_0105: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Expected O, but got Unknown
			if (!NetworkServer.active || !IsSingleplayerSession() || (Object)(object)Run.instance == (Object)null || (!RoR2PvPPlugin.CfgEnableSoloBot.Value && !forceSpawnEvenIfDisabled))
			{
				return;
			}
			CharacterMaster val = ((PlayerCharacterMasterController.instances.Count > 0) ? PlayerCharacterMasterController.instances[0].master : null);
			CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetBody() : null);
			Vector3 val3 = (((Object)(object)val2 != (Object)null) ? val2.corePosition : Vector3.zero);
			PvPTeam pvPTeam = ((GetPlayerTeam(val) == PvPTeam.Red) ? PvPTeam.Blue : PvPTeam.Red);
			if ((Object)(object)ActiveSoloBotMaster != (Object)null && (Object)(object)ActiveSoloBotMaster.GetBody() != (Object)null)
			{
				Vector3 val4 = val3 + (Vector3)(((Object)(object)val2 != (Object)null) ? (val2.transform.forward * 18f) : new Vector3(18f, 2f, 0f)) + Vector3.up * 1.5f;
				TeleportHelper.TeleportBody(ActiveSoloBotMaster.GetBody(), val4);
				Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
				{
					baseToken = "<color=#00FFCC>[ТЕСТОВЫЙ БОТ]</color> Бот-противник телепортирован к вам!"
				});
				return;
			}
			GameObject val5 = MasterCatalog.FindMasterPrefab("CommandoMonsterMaster") ?? MasterCatalog.FindMasterPrefab("LoaderMonsterMaster") ?? MasterCatalog.FindMasterPrefab("MercMonsterMaster");
			if ((Object)(object)val5 == (Object)null)
			{
				return;
			}
			Vector3 position = val3 + new Vector3(22f, 2f, 10f);
			if ((Object)(object)SceneInfo.instance != (Object)null && (Object)(object)SceneInfo.instance.groundNodes != (Object)null)
			{
				position = FindSafeRespawnPosition(val3);
			}
			MasterSummon val6 = new MasterSummon
			{
				masterPrefab = val5,
				position = position,
				rotation = Quaternion.identity,
				ignoreTeamMemberLimit = true,
				useAmbientLevel = true,
				teamIndexOverride = (TeamIndex)1
			};
			ActiveSoloBotMaster = val6.Perform();
			if ((Object)(object)ActiveSoloBotMaster == (Object)null)
			{
				return;
			}
			((Component)ActiveSoloBotMaster).gameObject.AddComponent<PvPDummyBotComponent>().AssignedTeam = pvPTeam;
			PlayerPvPStats playerPvPStats = RegisterPlayerIfNeeded(ActiveSoloBotMaster);
			if (playerPvPStats != null)
			{
				playerPvPStats.PlayerName = (RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value ? "\ud83e\udd16 Бот-Противник" : "\ud83c\udfaf Кукла-Манекен");
				playerPvPStats.Team = pvPTeam;
			}
			CharacterBody body = ActiveSoloBotMaster.GetBody();
			if ((Object)(object)body != (Object)null)
			{
				body.RecalculateStats();
				if (IsWarmupActive)
				{
					body.AddTimedBuff(Buffs.HiddenInvincibility, WarmupTimer);
				}
			}
			string text = (RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value ? "Боевой ИИ" : "Стоячая Кукла");
			SimpleChatMessage val7 = new SimpleChatMessage();
			val7.baseToken = "<color=#00FFCC>[ОДИНОЧНЫЙ ТЕСТ]</color> Создан соперник: <b>" + playerPvPStats?.PlayerName + "</b> (" + text + "). Клавиши: <b>[F7]</b> — призвать к себе, <b>[F9]</b> — переключить ИИ/Кукла.";
			Chat.SendBroadcastChat((ChatMessageBase)(object)val7);
		}

		public void ToggleSoloBotMode()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (IsSingleplayerSession())
			{
				RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value = !RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value;
				bool value = RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value;
				if ((Object)(object)ActiveSoloBotMaster != (Object)null && Scoreboard.TryGetValue(((NetworkBehaviour)ActiveSoloBotMaster).netId, out var value2))
				{
					value2.PlayerName = (value ? "\ud83e\udd16 Бот-Противник" : "\ud83c\udfaf Кукла-Манекен");
				}
				string text = (value ? "<color=#FF5555>БОЕВОЙ ИИ (Атакует)</color>" : "<color=#55FF55>КУКЛА-МАНЕКЕН (Стоит на месте)</color>");
				Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
				{
					baseToken = "<color=#00FFCC>[ТЕСТОВЫЙ БОТ]</color> Режим переключён: " + text
				});
			}
		}

		private void Update()
		{
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			if (!RoR2PvPPlugin.CfgEnablePvPMode.Value)
			{
				return;
			}
			if ((Object)(object)PreGameController.instance != (Object)null && (Object)(object)Run.instance == (Object)null)
			{
				_mannequinOutlineTimer -= Time.deltaTime;
				if (_mannequinOutlineTimer <= 0f)
				{
					_mannequinOutlineTimer = 0.4f;
					UpdateLobbyMannequinOutlines();
				}
			}
			else
			{
				if ((Object)(object)Run.instance == (Object)null)
				{
					return;
				}
				if (NetworkServer.active)
				{
					if (!_soloBotSpawnedForStage && IsSingleplayerSession() && RoR2PvPPlugin.CfgEnableSoloBot.Value)
					{
						_soloBotDelayedSpawnTimer -= Time.deltaTime;
						if (_soloBotDelayedSpawnTimer <= 0f && PlayerCharacterMasterController.instances.Count > 0)
						{
							CharacterMaster master = PlayerCharacterMasterController.instances[0].master;
							if ((Object)(object)master != (Object)null && (Object)(object)master.GetBody() != (Object)null)
							{
								_soloBotSpawnedForStage = true;
								SpawnOrTeleportSoloBot();
							}
						}
					}
					if (IsSingleplayerSession())
					{
						if (Input.GetKeyDown((KeyCode)288))
						{
							SpawnOrTeleportSoloBot(forceSpawnEvenIfDisabled: true);
						}
						if (Input.GetKeyDown((KeyCode)290))
						{
							ToggleSoloBotMode();
						}
					}
					foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
					{
						if (!((Object)(object)instance != (Object)null) || !((Object)(object)instance.master != (Object)null))
						{
							continue;
						}
						RegisterPlayerIfNeeded(instance.master);
						if (IsWarmupActive)
						{
							CharacterBody body = instance.master.GetBody();
							if ((Object)(object)body != (Object)null && !body.HasBuff(Buffs.HiddenInvincibility))
							{
								body.AddTimedBuff(Buffs.HiddenInvincibility, WarmupTimer);
							}
						}
					}
					if (WarmupTimer > 0f)
					{
						WarmupTimer -= Time.deltaTime;
						if (WarmupTimer <= 0f && !_warmupAnnouncedEnd)
						{
							_warmupAnnouncedEnd = true;
							FriendlyFireManager.friendlyFireMode = (FriendlyFireMode)2;
							Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
							{
								baseToken = "<color=#FF3333><b>[PVP НАЧАЛСЯ!]</b></color> Неуязвимость снята — в бой!"
							});
						}
					}
					if (IsMatchActive)
					{
						_passiveGoldTimer += Time.deltaTime;
						if (_passiveGoldTimer >= 1f)
						{
							_passiveGoldTimer -= 1f;
							uint num = (uint)Mathf.Max(0, RoR2PvPPlugin.CfgPassiveGoldPerSec.Value);
							if (num != 0)
							{
								foreach (PlayerCharacterMasterController instance2 in PlayerCharacterMasterController.instances)
								{
									if ((Object)(object)((instance2 != null) ? instance2.master : null) != (Object)null)
									{
										instance2.master.GiveMoney(num);
									}
								}
							}
						}
					}
					_networkSyncTimer -= Time.deltaTime;
					if (_networkSyncTimer <= 0f)
					{
						_networkSyncTimer = 0.5f;
						BroadcastMatchStateToClients();
					}
				}
				if (Input.GetKeyDown((KeyCode)289))
				{
					if (NetworkServer.active)
					{
						RestartRoundClean();
					}
					else
					{
						NetMessageExtensions.Send((INetMessage)(object)new ClientRequestRestartMessage(), (NetworkDestination)2);
					}
				}
			}
		}

		public void BroadcastMatchStateToClients()
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				List<PlayerPvPStats> list = Scoreboard.Values.ToList();
				SyncMatchStateMessage syncMatchStateMessage = new SyncMatchStateMessage
				{
					TargetKills = Mathf.Max(1, RoR2PvPPlugin.CfgTargetKills.Value),
					WarmupTimer = WarmupTimer,
					ChestSpawnTimer = (((Object)(object)MercenaryChestManager.Instance != (Object)null) ? MercenaryChestManager.Instance.SpawnTimer : 60f),
					IsMatchFinished = IsMatchFinished,
					WinnerName = WinnerName,
					PlayerCount = list.Count,
					NetIds = (NetworkInstanceId[])(object)new NetworkInstanceId[list.Count],
					Names = new string[list.Count],
					Teams = new int[list.Count],
					Kills = new int[list.Count],
					Deaths = new int[list.Count],
					Streaks = new int[list.Count]
				};
				for (int i = 0; i < list.Count; i++)
				{
					syncMatchStateMessage.NetIds[i] = (((Object)(object)list[i].Master != (Object)null) ? ((NetworkBehaviour)list[i].Master).netId : NetworkInstanceId.Invalid);
					syncMatchStateMessage.Names[i] = list[i].PlayerName;
					syncMatchStateMessage.Teams[i] = (int)list[i].Team;
					syncMatchStateMessage.Kills[i] = list[i].Kills;
					syncMatchStateMessage.Deaths[i] = list[i].Deaths;
					syncMatchStateMessage.Streaks[i] = list[i].KillStreak;
				}
				NetMessageExtensions.Send((INetMessage)(object)syncMatchStateMessage, (NetworkDestination)1);
			}
		}

		public void ApplySyncedStateFromHost(SyncMatchStateMessage msg)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			WarmupTimer = msg.WarmupTimer;
			IsMatchFinished = msg.IsMatchFinished;
			WinnerName = msg.WinnerName;
			FriendlyFireManager.friendlyFireMode = (FriendlyFireMode)2;
			if ((Object)(object)MercenaryChestManager.Instance != (Object)null)
			{
				MercenaryChestManager.Instance.SetClientTimer(msg.ChestSpawnTimer);
			}
			Scoreboard.Clear();
			for (int i = 0; i < msg.PlayerCount; i++)
			{
				Scoreboard[msg.NetIds[i]] = new PlayerPvPStats
				{
					PlayerName = msg.Names[i],
					Team = (PvPTeam)msg.Teams[i],
					Kills = msg.Kills[i],
					Deaths = msg.Deaths[i],
					KillStreak = msg.Streaks[i]
				};
			}
		}

		public PlayerPvPStats RegisterPlayerIfNeeded(CharacterMaster master)
		{
			//IL_0012: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)master == (Object)null)
			{
				return null;
			}
			if (!Scoreboard.TryGetValue(((NetworkBehaviour)master).netId, out var value))
			{
				PvPDummyBotComponent component = ((Component)master).GetComponent<PvPDummyBotComponent>();
				PvPTeam value2 = PvPTeam.None;
				string text;
				if ((Object)(object)component != (Object)null)
				{
					text = (RoR2PvPPlugin.CfgSoloBotAggressiveAI.Value ? "\ud83e\udd16 Бот-Противник" : "\ud83c\udfaf Кукла-Манекен");
					value2 = component.AssignedTeam;
				}
				else
				{
					text = (Object.op_Implicit((Object)(object)master.playerCharacterMasterController) ? master.playerCharacterMasterController.GetDisplayName() : ((Object)master).name);
					if ((Object)(object)master.playerCharacterMasterController != (Object)null && (Object)(object)master.playerCharacterMasterController.networkUser != (Object)null)
					{
						LobbyTeamsByNetUser.TryGetValue(((NetworkBehaviour)master.playerCharacterMasterController.networkUser).netId, out value2);
					}
				}
				value = new PlayerPvPStats
				{
					Master = master,
					PlayerName = (string.IsNullOrEmpty(text) ? $"Игрок #{Scoreboard.Count + 1}" : text),
					Team = value2,
					Kills = 0,
					Deaths = 0,
					KillStreak = 0
				};
				Scoreboard[((NetworkBehaviour)master).netId] = value;
			}
			return value;
		}

		public void HandlePlayerDefeated(CharacterBody victimBody, CharacterMaster killerMaster, CharacterBody killerBody)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00b1: 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_00b9: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected I4, but got Unknown
			if (!NetworkServer.active || (Object)(object)victimBody == (Object)null || (Object)(object)victimBody.master == (Object)null)
			{
				return;
			}
			PlayerPvPStats playerPvPStats = RegisterPlayerIfNeeded(victimBody.master);
			playerPvPStats.Deaths++;
			playerPvPStats.KillStreak = 0;
			HealthComponent healthComponent = victimBody.healthComponent;
			if ((Object)(object)healthComponent != (Object)null)
			{
				healthComponent.Networkhealth = healthComponent.fullHealth;
				healthComponent.Networkshield = healthComponent.fullShield;
				healthComponent.Networkbarrier = 0f;
			}
			DotController.RemoveAllDots(((Component)victimBody).gameObject);
			if ((Object)(object)victimBody.skillLocator != (Object)null)
			{
				victimBody.skillLocator.ApplyAmmoPack();
			}
			Vector3 enemyPosition = (((Object)(object)killerBody != (Object)null) ? killerBody.corePosition : victimBody.corePosition);
			Vector3 val = FindSafeRespawnPosition(enemyPosition);
			TeleportHelper.TeleportBody(victimBody, val);
			float num = Mathf.Max(0.5f, RoR2PvPPlugin.CfgRespawnInvulnDuration.Value);
			victimBody.AddTimedBuff(Buffs.HiddenInvincibility, num);
			victimBody.AddTimedBuff(Buffs.CloakSpeed, num);
			GameObject val2 = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/HippoRezEffect");
			if ((Object)(object)val2 != (Object)null)
			{
				EffectManager.SpawnEffect(val2, new EffectData
				{
					origin = val
				}, true);
			}
			if (!((Object)(object)killerMaster != (Object)null) || !((Object)(object)killerMaster != (Object)(object)victimBody.master))
			{
				return;
			}
			PlayerPvPStats playerPvPStats2 = RegisterPlayerIfNeeded(killerMaster);
			playerPvPStats2.Kills++;
			playerPvPStats2.KillStreak++;
			uint difficultyScaledCost = (uint)Run.instance.GetDifficultyScaledCost(RoR2PvPPlugin.CfgKillGoldReward.Value);
			killerMaster.GiveMoney(difficultyScaledCost);
			bool hasBonusEquipment;
			List<PickupIndex> list = RollRandomItemsWithOptionalEquipment(5, out hasBonusEquipment);
			if (list.Count > 0)
			{
				if ((Object)(object)((Component)killerMaster).GetComponent<PvPDummyBotComponent>() != (Object)null)
				{
					GiveBotRandomPicks(killerMaster, list, 2);
				}
				else
				{
					NetMessageExtensions.Send((INetMessage)(object)new SyncDraftOfferMessage(((NetworkBehaviour)killerMaster).netId, 2, isKillerReward: true, hasBonusEquipment, list), (NetworkDestination)1);
				}
			}
			bool hasBonusEquipment2;
			List<PickupIndex> list2 = RollRandomItemsWithOptionalEquipment(3, out hasBonusEquipment2);
			if (list2.Count > 0)
			{
				if ((Object)(object)((Component)victimBody.master).GetComponent<PvPDummyBotComponent>() != (Object)null)
				{
					GiveBotRandomPicks(victimBody.master, list2, 1);
				}
				else
				{
					NetMessageExtensions.Send((INetMessage)(object)new SyncDraftOfferMessage(((NetworkBehaviour)victimBody.master).netId, 1, isKillerReward: false, hasBonusEquipment2, list2), (NetworkDestination)1);
				}
			}
			int num2 = Mathf.Max(1, RoR2PvPPlugin.CfgTargetKills.Value);
			CharacterBody val3 = killerMaster.GetBody() ?? killerBody;
			NetMessageExtensions.Send((INetMessage)(object)new BroadcastKillFeedMessage
			{
				KillerName = playerPvPStats2.PlayerName,
				KillerTeam = (int)playerPvPStats2.Team,
				KillerBodyIndex = ((!((Object)(object)val3 != (Object)null)) ? (-1) : ((int)val3.bodyIndex)),
				VictimName = playerPvPStats.PlayerName,
				VictimTeam = (int)playerPvPStats.Team,
				VictimBodyIndex = (int)victimBody.bodyIndex,
				KillerTotalKills = playerPvPStats2.Kills,
				TargetKills = num2
			}, (NetworkDestination)1);
			if (playerPvPStats2.Kills >= num2)
			{
				DeclareWinner(playerPvPStats2);
			}
			BroadcastMatchStateToClients();
		}

		private void GiveBotRandomPicks(CharacterMaster botMaster, List<PickupIndex> pool, int picks)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((botMaster != null) ? botMaster.inventory : null) == (Object)null || pool == null)
			{
				return;
			}
			for (int i = 0; i < picks; i++)
			{
				if (pool.Count <= 0)
				{
					break;
				}
				int index = Random.Range(0, pool.Count);
				PickupDef pickupDef = PickupCatalog.GetPickupDef(pool[index]);
				pool.RemoveAt(index);
				if (pickupDef != null && (int)pickupDef.itemIndex != -1)
				{
					botMaster.inventory.GiveItem(pickupDef.itemIndex, 1);
				}
			}
		}

		private void OnCharacterMasterBodyDeath(orig_OnBodyDeath orig, CharacterMaster self, CharacterBody body)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (Object)(object)self.playerCharacterMasterController != (Object)null || (Object)(object)((Component)self).GetComponent<PvPDummyBotComponent>() != (Object)null;
			if (RoR2PvPPlugin.CfgEnablePvPMode.Value && !IsMatchFinished && flag)
			{
				if (NetworkServer.active)
				{
					Vector3 val = FindSafeRespawnPosition(((Object)(object)body != (Object)null) ? body.corePosition : Vector3.zero);
					self.Respawn(val, Quaternion.identity, false);
					CharacterBody body2 = self.GetBody();
					if ((Object)(object)body2 != (Object)null)
					{
						body2.AddTimedBuff(Buffs.HiddenInvincibility, RoR2PvPPlugin.CfgRespawnInvulnDuration.Value);
					}
				}
			}
			else
			{
				orig.Invoke(self, body);
			}
		}

		public Vector3 FindSafeRespawnPosition(Vector3 enemyPosition)
		{
			//IL_00f7: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_0111: 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)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_004f: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SceneInfo.instance != (Object)null && (Object)(object)SceneInfo.instance.groundNodes != (Object)null)
			{
				NodeGraph groundNodes = SceneInfo.instance.groundNodes;
				List<NodeIndex> activeNodesForHullMaskWithFlagConditions = groundNodes.GetActiveNodesForHullMaskWithFlagConditions((HullMask)1, (NodeFlags)0, (NodeFlags)4);
				Vector3 result = enemyPosition + new Vector3(35f, 5f, 35f);
				float num = -1f;
				int num2 = Mathf.Min(40, activeNodesForHullMaskWithFlagConditions.Count);
				Vector3 val2 = default(Vector3);
				for (int i = 0; i < num2; i++)
				{
					NodeIndex val = activeNodesForHullMaskWithFlagConditions[Random.Range(0, activeNodesForHullMaskWithFlagConditions.Count)];
					if (groundNodes.GetNodePosition(val, ref val2))
					{
						float num3 = Vector3.Distance(val2, enemyPosition);
						float num4 = ((num3 >= 45f && num3 <= 110f) ? (1000f - Mathf.Abs(num3 - 75f)) : num3);
						if (num4 > num)
						{
							num = num4;
							result = val2 + Vector3.up * 1.5f;
						}
					}
				}
				return result;
			}
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 val3 = ((Vector2)(ref insideUnitCircle)).normalized * 50f;
			return enemyPosition + new Vector3(val3.x, 8f, val3.y);
		}

		public List<PickupIndex> RollRandomItemsWithOptionalEquipment(int baseCount, out bool hasBonusEquipment)
		{
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			hasBonusEquipment = false;
			List<PickupIndex> list = new List<PickupIndex>(baseCount + 1);
			if ((Object)(object)Run.instance == (Object)null)
			{
				return list;
			}
			WeightedSelection<List<PickupIndex>> val = new WeightedSelection<List<PickupIndex>>(8);
			List<PickupIndex> availableTier1DropList = Run.instance.availableTier1DropList;
			if (availableTier1DropList != null && availableTier1DropList.Count > 0)
			{
				val.AddChoice(Run.instance.availableTier1DropList, Mathf.Max(0.1f, RoR2PvPPlugin.CfgWeightWhite.Value));
			}
			List<PickupIndex> availableTier2DropList = Run.instance.availableTier2DropList;
			if (availableTier2DropList != null && availableTier2DropList.Count > 0)
			{
				val.AddChoice(Run.instance.availableTier2DropList, Mathf.Max(0f, RoR2PvPPlugin.CfgWeightGreen.Value));
			}
			List<PickupIndex> availableTier3DropList = Run.instance.availableTier3DropList;
			if (availableTier3DropList != null && availableTier3DropList.Count > 0)
			{
				val.AddChoice(Run.instance.availableTier3DropList, Mathf.Max(0f, RoR2PvPPlugin.CfgWeightRed.Value));
			}
			List<PickupIndex> availableBossDropList = Run.instance.availableBossDropList;
			if (availableBossDropList != null && availableBossDropList.Count > 0)
			{
				val.AddChoice(Run.instance.availableBossDropList, Mathf.Max(0f, RoR2PvPPlugin.CfgWeightYellow.Value));
			}
			List<PickupIndex> list2 = new List<PickupIndex>();
			if (Run.instance.availableVoidTier1DropList != null)
			{
				list2.AddRange(Run.instance.availableVoidTier1DropList);
			}
			if (Run.instance.availableVoidTier2DropList != null)
			{
				list2.AddRange(Run.instance.availableVoidTier2DropList);
			}
			if (Run.instance.availableVoidTier3DropList != null)
			{
				list2.AddRange(Run.instance.availableVoidTier3DropList);
			}
			if (Run.instance.availableVoidBossDropList != null)
			{
				list2.AddRange(Run.instance.availableVoidBossDropList);
			}
			if (list2.Count > 0)
			{
				val.AddChoice(list2, Mathf.Max(0f, RoR2PvPPlugin.CfgWeightVoidPurple.Value));
			}
			if (val.Count == 0)
			{
				return list;
			}
			int num = 0;
			while (list.Count < baseCount && num < 60)
			{
				num++;
				List<PickupIndex> list3 = val.Evaluate(Random.value);
				if (list3 != null && list3.Count != 0)
				{
					PickupIndex item = list3[Random.Range(0, list3.Count)];
					if (((PickupIndex)(ref item)).isValid && !list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			float num2 = Mathf.Clamp(RoR2PvPPlugin.CfgEquipmentSlotChancePercent.Value, 0f, 100f);
			if (Random.Range(0f, 100f) < num2)
			{
				List<PickupIndex> availableEquipmentDropList = Run.instance.availableEquipmentDropList;
				if (availableEquipmentDropList != null && availableEquipmentDropList.Count > 0)
				{
					PickupIndex item2 = availableEquipmentDropList[Random.Range(0, availableEquipmentDropList.Count)];
					if (((PickupIndex)(ref item2)).isValid)
					{
						list.Add(item2);
						hasBonusEquipment = true;
					}
				}
			}
			return list;
		}

		private void DeclareWinner(PlayerPvPStats winner)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			IsMatchFinished = true;
			string text = ((winner.Team != PvPTeam.None) ? (" [" + RoR2PvPPlugin.GetTeamNameRu(winner.Team) + "]") : "");
			WinnerName = winner.PlayerName + text;
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = "<color=#FFD700>========================================</color>\n" + $"<color=#00FF88><b>ПОБЕДИТЕЛЬ МАТЧА: {WinnerName}!</b></color> ({winner.Kills} убийств)\n" + "<color=#FFD700>Нажмите [F8] для полного перезапуска карты и раунда!</color>\n<color=#FFD700>========================================</color>"
			});
		}

		public void RestartRoundClean()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || (Object)(object)Run.instance == (Object)null)
			{
				return;
			}
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				if ((Object)(object)((instance != null) ? instance.master : null) == (Object)null)
				{
					continue;
				}
				instance.master.money = 0u;
				Inventory inventory = instance.master.inventory;
				if (!((Object)(object)inventory != (Object)null))
				{
					continue;
				}
				for (ItemIndex val = (ItemIndex)0; (int)val < ItemCatalog.itemCount; val = (ItemIndex)(val + 1))
				{
					int itemCount = inventory.GetItemCount(val);
					if (itemCount > 0)
					{
						inventory.RemoveItem(val, itemCount);
					}
				}
				inventory.SetEquipmentIndex((EquipmentIndex)(-1));
			}
			if ((Object)(object)ActiveSoloBotMaster != (Object)null)
			{
				if ((Object)(object)ActiveSoloBotMaster.GetBodyObject() != (Object)null)
				{
					Object.Destroy((Object)(object)ActiveSoloBotMaster.GetBodyObject());
				}
				Object.Destroy((Object)(object)((Component)ActiveSoloBotMaster).gameObject);
				ActiveSoloBotMaster = null;
			}
			AlliedMonsterAIController[] array = Object.FindObjectsOfType<AlliedMonsterAIController>();
			foreach (AlliedMonsterAIController alliedMonsterAIController in array)
			{
				if ((Object)(object)alliedMonsterAIController != (Object)null && (Object)(object)((Component)alliedMonsterAIController).gameObject != (Object)null)
				{
					CharacterMaster component = ((Component)alliedMonsterAIController).GetComponent<CharacterMaster>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.GetBodyObject() != (Object)null)
					{
						Object.Destroy((Object)(object)component.GetBodyObject());
					}
					Object.Destroy((Object)(object)((Component)alliedMonsterAIController).gameObject);
				}
			}
			SceneDef val2 = PickConfiguredArenaScene() ?? SceneCatalog.GetSceneDefForCurrentScene();
			if ((Object)(object)val2 != (Object)null)
			{
				Run.instance.AdvanceStage(val2);
			}
			else
			{
				StartNewPvPMatch();
			}
		}
	}
	public static class PvPNetworkHandler
	{
		public static void RegisterMessages()
		{
			NetworkingAPI.RegisterMessageType<SyncDraftOfferMessage>();
			NetworkingAPI.RegisterMessageType<ClientPickDraftItemMessage>();
			NetworkingAPI.RegisterMessageType<SyncMatchStateMessage>();
			NetworkingAPI.RegisterMessageType<ClientRequestRestartMessage>();
			NetworkingAPI.RegisterMessageType<ClientSelectTeamInLobbyMessage>();
			NetworkingAPI.RegisterMessageType<BroadcastLobbyTeamsMessage>();
			NetworkingAPI.RegisterMessageType<BroadcastKillFeedMessage>();
		}

		public static void ServerGrantPickupToMaster(CharacterMaster master, int pickupValue)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_003f: 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)
			if (!NetworkServer.active || (Object)(object)master == (Object)null || (Object)(object)master.inventory == (Object)null)
			{
				return;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(new PickupIndex(pickupValue));
			if (pickupDef != null)
			{
				if ((int)pickupDef.itemIndex != -1)
				{
					master.inventory.GiveItem(pickupDef.itemIndex, 1);
				}
				else if ((int)pickupDef.equipmentIndex != -1)
				{
					master.inventory.SetEquipmentIndex(pickupDef.equipmentIndex);
				}
			}
		}
	}
	public class ClientSelectTeamInLobbyMessage : INetMessage, ISerializableObject
	{
		public NetworkInstanceId NetworkUserNetId;

		public int TeamValue;

		public ClientSelectTeamInLobbyMessage()
		{
		}

		public ClientSelectTeamInLobbyMessage(NetworkInstanceId netUserId, PvPTeam team)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			NetworkUserNetId = netUserId;
			TeamValue = (int)team;
		}

		public void Serialize(NetworkWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(NetworkUserNetId);
			writer.Write(TeamValue);
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			NetworkUserNetId = reader.ReadNetworkId();
			TeamValue = reader.ReadInt32();
		}

		public void OnReceived()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && !((Object)(object)Run.instance != (Object)null))
			{
				PvPGameController.Instance?.ServerSetPlayerLobbyTeam(NetworkUserNetId, (PvPTeam)TeamValue);
			}
		}
	}
	public class BroadcastLobbyTeamsMessage : INetMessage, ISerializableObject
	{
		public int Count;

		public NetworkInstanceId[] UserNetIds;

		public int[] TeamValues;

		public void Serialize(NetworkWriter writer)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(Count);
			for (int i = 0; i < Count; i++)
			{
				writer.Write(UserNetIds[i]);
				writer.Write(TeamValues[i]);
			}
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_003a: 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)
			Count = reader.ReadInt32();
			UserNetIds = (NetworkInstanceId[])(object)new NetworkInstanceId[Count];
			TeamValues = new int[Count];
			for (int i = 0; i < Count; i++)
			{
				UserNetIds[i] = reader.ReadNetworkId();
				TeamValues[i] = reader.ReadInt32();
			}
		}

		public void OnReceived()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)PvPGameController.Instance == (Object)null))
			{
				for (int i = 0; i < Count; i++)
				{
					PvPGameController.Instance.ClientApplyLobbyTeam(UserNetIds[i], (PvPTeam)TeamValues[i]);
				}
			}
		}
	}
	public class BroadcastKillFeedMessage : INetMessage, ISerializableObject
	{
		public string KillerName;

		public int KillerTeam;

		public int KillerBodyIndex;

		public string VictimName;

		public int VictimTeam;

		public int VictimBodyIndex;

		public int KillerTotalKills;

		public int TargetKills;

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(KillerName ?? "Игрок");
			writer.Write(KillerTeam);
			writer.Write(KillerBodyIndex);
			writer.Write(VictimName ?? "Игрок");
			writer.Write(VictimTeam);
			writer.Write(VictimBodyIndex);
			writer.Write(KillerTotalKills);
			writer.Write(TargetKills);
		}

		public void Deserialize(NetworkReader reader)
		{
			KillerName = reader.ReadString();
			KillerTeam = reader.ReadInt32();
			KillerBodyIndex = reader.ReadInt32();
			VictimName = reader.ReadString();
			VictimTeam = reader.ReadInt32();
			VictimBodyIndex = reader.ReadInt32();
			KillerTotalKills = reader.ReadInt32();
			TargetKills = reader.ReadInt32();
		}

		public void OnReceived()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			PvPUIManager.Instance?.PushKillFeedEntry(new KillFeedEntry
			{
				KillerName = KillerName,
				KillerTeam = (PvPTeam)KillerTeam,
				KillerBodyIdx = (BodyIndex)KillerBodyIndex,
				VictimName = VictimName,
				VictimTeam = (PvPTeam)VictimTeam,
				VictimBodyIdx = (BodyIndex)VictimBodyIndex,
				KillerKills = KillerTotalKills,
				TargetKills = TargetKills,
				TimeRemaining = 4f,
				TotalDuration = 4f
			});
		}
	}
	public class SyncDraftOfferMessage : INetMessage, ISerializableObject
	{
		public NetworkInstanceId TargetMasterNetId;

		public int PicksAllowed;

		public bool IsKillerReward;

		public bool HasBonusEquipmentSlot;

		public int[] PickupIndices;

		public SyncDraftOfferMessage()
		{
		}

		public SyncDraftOfferMessage(NetworkInstanceId targetMasterNetId, int picksAllowed, bool isKillerReward, bool hasBonusEquipment, List<PickupIndex> choices)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			TargetMasterNetId = targetMasterNetId;
			PicksAllowed = picksAllowed;
			IsKillerReward = isKillerReward;
			HasBonusEquipmentSlot = hasBonusEquipment;
			PickupIndices = new int[choices.Count];
			for (int i = 0; i < choices.Count; i++)
			{
				PickupIndices[i] = choices[i].value;
			}
		}

		public void Serialize(NetworkWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(TargetMasterNetId);
			writer.Write(PicksAllowed);
			writer.Write(IsKillerReward);
			writer.Write(HasBonusEquipmentSlot);
			writer.Write(PickupIndices.Length);
			for (int i = 0; i < PickupIndices.Length; i++)
			{
				writer.Write(PickupIndices[i]);
			}
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			TargetMasterNetId = reader.ReadNetworkId();
			PicksAllowed = reader.ReadInt32();
			IsKillerReward = reader.ReadBoolean();
			HasBonusEquipmentSlot = reader.ReadBoolean();
			int num = reader.ReadInt32();
			PickupIndices = new int[num];
			for (int i = 0; i < num; i++)
			{
				PickupIndices[i] = reader.ReadInt32();
			}
		}

		public void OnReceived()
		{
			//IL_0010: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			CharacterMaster localPlayerMaster = PvPUIManager.GetLocalPlayerMaster();
			if (!((Object)(object)localPlayerMaster == (Object)null) && !(((NetworkBehaviour)localPlayerMaster).netId != TargetMasterNetId))
			{
				List<PickupIndex> list = new List<PickupIndex>(PickupIndices.Length);
				for (int i = 0; i < PickupIndices.Length; i++)
				{
					list.Add(new PickupIndex(PickupIndices[i]));
				}
				PvPUIManager.Instance?.EnqueueLocalDraft(new ItemDraftSession
				{
					Choices = list,
					RemainingPicks = PicksAllowed,
					IsKillerReward = IsKillerReward,
					HasBonusEquipmentSlot = HasBonusEquipmentSlot
				});
			}
		}
	}
	public class ClientPickDraftItemMessage : INetMessage, ISerializableObject
	{
		public NetworkInstanceId MasterNetId;

		public int PickupValue;

		public ClientPickDraftItemMessage()
		{
		}

		public ClientPickDraftItemMessage(NetworkInstanceId masterNetId, int pickupValue)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			MasterNetId = masterNetId;
			PickupValue = pickupValue;
		}

		public void Serialize(NetworkWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(MasterNetId);
			writer.Write(PickupValue);
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			MasterNetId = reader.ReadNetworkId();
			PickupValue = reader.ReadInt32();
		}

		public void OnReceived()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				GameObject val = NetworkServer.FindLocalObject(MasterNetId);
				if (!((Object)(object)val == (Object)null))
				{
					PvPNetworkHandler.ServerGrantPickupToMaster(val.GetComponent<CharacterMaster>(), PickupValue);
				}
			}
		}
	}
	public class SyncMatchStateMessage : INetMessage, ISerializableObject
	{
		public int TargetKills;

		public float WarmupTimer;

		public float ChestSpawnTimer;

		public bool IsMatchFinished;

		public string WinnerName;

		public int PlayerCount;

		public NetworkInstanceId[] NetIds;

		public string[] Names;

		public int[] Teams;

		public int[] Kills;

		public int[] Deaths;

		public int[] Streaks;

		public void Serialize(NetworkWriter writer)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(TargetKills);
			writer.Write(WarmupTimer);
			writer.Write(ChestSpawnTimer);
			writer.Write(IsMatchFinished);
			writer.Write(WinnerName ?? "");
			writer.Write(PlayerCount);
			for (int i = 0; i < PlayerCount; i++)
			{
				writer.Write(NetIds[i]);
				writer.Write(Names[i] ?? "Player");
				writer.Write(Teams[i]);
				writer.Write(Kills[i]);
				writer.Write(Deaths[i]);
				writer.Write(Streaks[i]);
			}
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			TargetKills = reader.ReadInt32();
			WarmupTimer = reader.ReadSingle();
			ChestSpawnTimer = reader.ReadSingle();
			IsMatchFinished = reader.ReadBoolean();
			WinnerName = reader.ReadString();
			PlayerCount = reader.ReadInt32();
			NetIds = (NetworkInstanceId[])(object)new NetworkInstanceId[PlayerCount];
			Names = new string[PlayerCount];
			Teams = new int[PlayerCount];
			Kills = new int[PlayerCount];
			Deaths = new int[PlayerCount];
			Streaks = new int[PlayerCount];
			for (int i = 0; i < PlayerCount; i++)
			{
				NetIds[i] = reader.ReadNetworkId();
				Names[i] = reader.ReadString();
				Teams[i] = reader.ReadInt32();
				Kills[i] = reader.ReadInt32();
				Deaths[i] = reader.ReadInt32();
				Streaks[i] = reader.ReadInt32();
			}
		}

		public void OnReceived()
		{
			if (!NetworkServer.active)
			{
				RoR2PvPPlugin.CfgTargetKills.Value = TargetKills;
				if ((Object)(object)PvPGameController.Instance != (Object)null)
				{
					PvPGameController.Instance.ApplySyncedStateFromHost(this);
				}
			}
		}
	}
	public class ClientRequestRestartMessage : INetMessage, ISerializableObject
	{
		public void Serialize(NetworkWriter writer)
		{
		}

		public void Deserialize(NetworkReader reader)
		{
		}

		public void OnReceived()
		{
			if (NetworkServer.active && (Object)(object)PvPGameController.Instance != (Object)null)
			{
				PvPGameController.Instance.RestartRoundClean();
			}
		}
	}
	public class ItemDraftSession
	{
		public List<PickupIndex> Choices = new List<PickupIndex>();

		public int RemainingPicks;

		public bool IsKillerReward;

		public bool HasBonusEquipmentSlot;
	}
	public class KillFeedEntry
	{
		public string KillerName;

		public PvPTeam KillerTeam;

		public BodyIndex KillerBodyIdx;

		public string VictimName;

		public PvPTeam VictimTeam;

		public BodyIndex VictimBodyIdx;

		public int KillerKills;

		public int TargetKills;

		public float TimeRemaining;

		public float TotalDuration;
	}
	public class PvPUIManager : MonoBehaviour
	{
		private bool _showConfigWindow;

		private Vector2 _configScroll;

		private Rect _configRect = new Rect(25f, 130f, 510f, 640f);

		private Rect _draftRect;

		private readonly Queue<ItemDraftSession> _localDraftQueue = new Queue<ItemDraftSession>();

		private readonly List<KillFeedEntry> _killFeedEntries = new List<KillFeedEntry>();

		private Texture2D _darkPanelTex;

		private Texture2D _cardBgTex;

		private Texture2D _whiteTex;

		public static PvPUIManager Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			CreateProceduralTextures();
		}

		private void CreateProceduralTextures()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			_darkPanelTex = MakeSolidTex(new Color(0.07f, 0.08f, 0.12f, 0.9f));
			_cardBgTex = MakeSolidTex(new Color(0.13f, 0.15f, 0.2f, 0.95f));
			_whiteTex = MakeSolidTex(Color.white);
		}

		private static Texture2D MakeSolidTex(Color col)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid I