Decompiled source of Groups v1.2.10

Groups.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using APIManager;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Preloader;
using BepInEx.Preloader.Patching;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using ServerSync;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Groups")]
[assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/Groups")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Groups")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6CDE724A-63F3-4457-91A5-C9CAF71649CE")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Groups
{
	[PublicAPI]
	public class API
	{
		public static event Action? joinedGroup;

		public static event Action? leftGroup;

		public static event Action<PlayerReference>? memberJoined;

		public static event Action<PlayerReference>? memberLeft;

		public static event Action<PlayerReference>? leaderChanged;

		public static event Action<PlayerReference, GameObject>? invitationReceived;

		public static event Action<PlayerReference, GameObject>? uiUpdate;

		internal static void InvokeGroupJoined()
		{
			API.joinedGroup?.Invoke();
		}

		internal static void InvokeGroupLeft()
		{
			API.leftGroup?.Invoke();
		}

		internal static void InvokeMemberJoined(PlayerReference player)
		{
			API.memberJoined?.Invoke(player);
		}

		internal static void InvokeMemberLeft(PlayerReference player)
		{
			API.memberLeft?.Invoke(player);
		}

		internal static void InvokeLeaderChanged(PlayerReference player)
		{
			API.leaderChanged?.Invoke(player);
		}

		internal static void InvokeInvitationReceived(PlayerReference player, GameObject invitationDialog)
		{
			API.invitationReceived?.Invoke(player, invitationDialog);
		}

		internal static void InvokeUIUpdate(PlayerReference player, GameObject playerRoot)
		{
			API.uiUpdate?.Invoke(player, playerRoot);
		}

		public static bool IsLoaded()
		{
			return true;
		}

		public static int GetMaxGroupSize()
		{
			return Groups.maximumGroupSize.Value;
		}

		public static List<PlayerReference> GroupPlayers()
		{
			if (Groups.ownGroup == null)
			{
				return new List<PlayerReference>();
			}
			return Groups.ownGroup.playerStates.Keys.ToList();
		}

		public static PlayerReference? GetLeader()
		{
			return Groups.ownGroup?.leader;
		}

		public static bool CreateNewGroup()
		{
			LeaveGroup();
			Groups.ownGroup = new Group(PlayerReference.fromPlayer(Player.m_localPlayer), Group.PlayerState.fromLocal());
			InvokeGroupJoined();
			return true;
		}

		public static bool WriteToGroup(string message)
		{
			if (Groups.ownGroup != null)
			{
				foreach (PlayerReference key in Groups.ownGroup.playerStates.Keys)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(key.peerId, "Groups AddMessage", new object[1] { message });
				}
				return true;
			}
			return false;
		}

		public static bool LeaveGroup()
		{
			Groups.ownGroup?.Leave();
			Groups.ownGroup = null;
			return true;
		}

		public static bool JoinGroup(PlayerReference targetPlayer)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			if (Groups.ownGroup != null)
			{
				LeaveGroup();
			}
			ZPackage val = new ZPackage();
			Group.PlayerState.fromLocal().write(val);
			ZRoutedRpc.instance.InvokeRoutedRPC(targetPlayer.peerId, "Groups AcceptInvitation", new object[1] { val });
			return true;
		}

		public static bool PromoteToLeader(PlayerReference groupMember)
		{
			if (Groups.ownGroup != null)
			{
				Groups.ownGroup.PromoteMember(groupMember, sendToLeader: true);
				return true;
			}
			return false;
		}

		public static bool ForcePlayerIntoOwnGroup(PlayerReference targetPlayer)
		{
			if (Groups.ownGroup == null)
			{
				CreateNewGroup();
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(targetPlayer.peerId, "Groups ForcedInvitation", Array.Empty<object>());
			return true;
		}

		public static PlayerReference? FindGroupMemberByPlayerId(long playerId)
		{
			if (playerId == Game.instance.m_playerProfile.GetPlayerID())
			{
				return PlayerReference.fromPlayerId(ZDOMan.GetSessionID());
			}
			Group ownGroup = Groups.ownGroup;
			if (ownGroup != null)
			{
				foreach (KeyValuePair<PlayerReference, Group.PlayerState> playerState in ownGroup.playerStates)
				{
					if (playerState.Value.playerId == playerId)
					{
						return playerState.Key;
					}
				}
			}
			return null;
		}
	}
	[PublicAPI]
	public struct PlayerReference
	{
		public long peerId;

		public string name;

		public static PlayerReference fromPlayerId(long id)
		{
			return ZNet.instance.m_players.Where((PlayerInfo p) => ((ZDOID)(ref p.m_characterID)).UserID == id).Select(fromPlayerInfo).FirstOrDefault();
		}

		public static PlayerReference fromPlayerInfo(PlayerInfo playerInfo)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			PlayerReference result = default(PlayerReference);
			result.peerId = ((ZDOID)(ref playerInfo.m_characterID)).UserID;
			result.name = playerInfo.m_name ?? "";
			return result;
		}

		public static PlayerReference fromPlayer(Player player)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Player player2 = player;
			if (!((Object)(object)player2 == (Object)(object)Player.m_localPlayer))
			{
				return fromPlayerInfo(((IEnumerable<PlayerInfo>)ZNet.instance.m_players).FirstOrDefault((Func<PlayerInfo, bool>)((PlayerInfo info) => info.m_characterID == ((Character)player2).GetZDOID())));
			}
			PlayerReference result = default(PlayerReference);
			result.peerId = ZDOMan.GetSessionID();
			result.name = Game.instance.GetPlayerProfile().GetName();
			return result;
		}

		public static bool operator !=(PlayerReference a, PlayerReference b)
		{
			return !(a == b);
		}

		public static bool operator ==(PlayerReference a, PlayerReference b)
		{
			if (a.peerId == b.peerId)
			{
				return a.name == b.name;
			}
			return false;
		}

		public bool Equals(PlayerReference other)
		{
			return this == other;
		}

		public override bool Equals(object? obj)
		{
			if (obj is PlayerReference other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (peerId.GetHashCode() * 397) ^ (name?.GetHashCode() ?? 0);
		}

		public override string ToString()
		{
			return $"{peerId}:{name}";
		}

		public static PlayerReference fromString(string str)
		{
			string[] array = str.Split(new char[1] { ':' });
			PlayerReference result = default(PlayerReference);
			result.peerId = long.Parse(array[0]);
			result.name = array[1];
			return result;
		}
	}
	public class DragNDrop : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler
	{
		public RectTransform target;

		public bool shouldReturn;

		private bool isMouseDown;

		private Vector3 startMousePosition;

		private Vector3 startPosition;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			target = (RectTransform)((Component)this).transform;
		}

		private void Update()
		{
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (isMouseDown)
			{
				Vector3 val = Input.mousePosition - startMousePosition;
				Vector3 position = startPosition + val;
				SetPosition(position);
			}
		}

		public void SetPosition(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 sizeDelta = target.sizeDelta;
			position.x = Mathf.Clamp(position.x, sizeDelta.x / 2f, (float)Screen.width - sizeDelta.x / 2f);
			position.y = Mathf.Clamp(position.y, sizeDelta.y / 2f, (float)Screen.height - sizeDelta.y / 2f);
			((Transform)target).position = position;
			Groups.groupInterfaceAnchor.Value = Vector2.op_Implicit(((Transform)target).localPosition);
		}

		public void OnPointerDown(PointerEventData dt)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			isMouseDown = true;
			startPosition = ((Transform)target).position;
			((Transform)target).position = startPosition;
			startMousePosition = Input.mousePosition;
		}

		public void OnPointerUp(PointerEventData dt)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			isMouseDown = false;
			if (shouldReturn)
			{
				((Transform)target).position = startPosition;
				Groups.groupInterfaceAnchor.Value = Vector2.op_Implicit(((Transform)target).localPosition);
			}
		}
	}
	public class Group
	{
		public class PlayerState
		{
			public float health;

			public float maxHealth;

			public long playerId;

			public static PlayerState read(ZPackage group)
			{
				return new PlayerState
				{
					health = group.ReadSingle(),
					maxHealth = group.ReadSingle(),
					playerId = group.ReadLong()
				};
			}

			public void write(ZPackage group)
			{
				group.Write(health);
				group.Write(maxHealth);
				group.Write(playerId);
			}

			public static PlayerState fromLocal()
			{
				return new PlayerState
				{
					health = ((Character)Player.m_localPlayer).GetHealth(),
					maxHealth = ((Character)Player.m_localPlayer).GetMaxHealth(),
					playerId = Game.instance.m_playerProfile.GetPlayerID()
				};
			}
		}

		private PlayerReference _leader;

		public readonly Dictionary<PlayerReference, PlayerState> playerStates;

		public PlayerReference leader
		{
			get
			{
				return _leader;
			}
			set
			{
				if (value != _leader)
				{
					_leader = value;
					API.InvokeLeaderChanged(value);
				}
			}
		}

		public Group(PlayerReference leader, PlayerState playerState)
		{
			this.leader = leader;
			playerStates = new Dictionary<PlayerReference, PlayerState> { { leader, playerState } };
		}

		private bool CheckGroupFull()
		{
			return playerStates.Count >= Groups.maximumGroupSize.Value;
		}

		public bool AddMember(PlayerReference player, PlayerState playerState)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			if (playerStates.ContainsKey(player))
			{
				return false;
			}
			if (CheckGroupFull())
			{
				return false;
			}
			PlayerReference[] array = playerStates.Keys.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				PlayerReference playerReference = array[i];
				if (playerReference != player)
				{
					ZPackage val = new ZPackage();
					playerState.write(val);
					ZRoutedRpc.instance.InvokeRoutedRPC(playerReference.peerId, "Groups AddMember", new object[2]
					{
						player.ToString(),
						val
					});
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(playerReference.peerId, "Groups AddMessage", new object[1] { Localization.instance.Localize("$groups_player_joined", new string[1] { player.name }) });
			}
			return true;
		}

		public bool RemoveMember(PlayerReference player, bool self = false)
		{
			if (playerStates.ContainsKey(player))
			{
				PlayerReference[] array = playerStates.Keys.ToArray();
				for (int i = 0; i < array.Length; i++)
				{
					PlayerReference playerReference = array[i];
					ZRoutedRpc.instance.InvokeRoutedRPC(playerReference.peerId, "Groups UpdateGroup", new object[2]
					{
						player.ToString(),
						"Member Removed"
					});
					if (playerReference != player)
					{
						string text = Localization.instance.Localize(self ? "$groups_player_left" : "$groups_player_removed", new string[1] { player.name });
						ZRoutedRpc.instance.InvokeRoutedRPC(playerReference.peerId, "Groups AddMessage", new object[1] { text });
					}
				}
				if (!self)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(player.peerId, "Groups AddMessage", new object[1] { Localization.instance.Localize("$groups_self_removed") });
				}
				return true;
			}
			return false;
		}

		public bool PromoteMember(PlayerReference player, bool sendToLeader = false)
		{
			if (player == leader)
			{
				return false;
			}
			if (playerStates.ContainsKey(player))
			{
				foreach (PlayerReference key in playerStates.Keys)
				{
					if (key != leader || sendToLeader)
					{
						ZRoutedRpc.instance.InvokeRoutedRPC(key.peerId, "Groups UpdateGroup", new object[2]
						{
							player.ToString(),
							"Member Promoted"
						});
					}
					ZRoutedRpc.instance.InvokeRoutedRPC(key.peerId, "Groups AddMessage", new object[1] { Localization.instance.Localize("$groups_player_promoted", new string[1] { player.name }) });
				}
				leader = player;
				return true;
			}
			return false;
		}

		public void Leave()
		{
			API.InvokeGroupLeft();
			ChatCommands.ToggleGroupsChat(active: false);
			PlayerReference ownReference = PlayerReference.fromPlayer(Player.m_localPlayer);
			if (leader == ownReference && playerStates.Count > 1)
			{
				PromoteMember(playerStates.Keys.First((PlayerReference p) => p != ownReference));
			}
			RemoveMember(PlayerReference.fromPlayer(Player.m_localPlayer), self: true);
		}
	}
	[BepInPlugin("org.bepinex.plugins.groups", "Groups", "1.2.10")]
	[BepInIncompatibility("org.bepinex.plugins.valheim_plus")]
	public class Groups : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		public enum GroupLeaderDisplayOption
		{
			Disabled,
			Icon,
			Color
		}

		public enum BlockInvitation
		{
			Never,
			Always,
			[Description("While PvP enabled")]
			PvP,
			[Description("While Enemy Player Nearby")]
			Enemy
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;
		}

		[HarmonyPatch(typeof(Aoe), "OnHit")]
		private static class TagFriendlyFireAoe
		{
			[CompilerGenerated]
			private sealed class <Transpiler>d__3 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private CodeInstruction <>2__current;

				private int <>l__initialThreadId;

				private IEnumerable<CodeInstruction> instructions;

				public IEnumerable<CodeInstruction> <>3__instructions;

				private bool <preDamage>5__2;

				private IEnumerator<CodeInstruction> <>7__wrap2;

				private CodeInstruction <instruction>5__4;

				CodeInstruction IEnumerator<CodeInstruction>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <Transpiler>d__3(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					int num = <>1__state;
					if (num == -3 || (uint)(num - 1) <= 2u)
					{
						try
						{
						}
						finally
						{
							<>m__Finally1();
						}
					}
					<>7__wrap2 = null;
					<instruction>5__4 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00cf: Expected O, but got Unknown
					//IL_0089: Unknown result type (might be due to invalid IL or missing references)
					//IL_0093: Expected O, but got Unknown
					try
					{
						switch (<>1__state)
						{
						default:
							return false;
						case 0:
							<>1__state = -1;
							<preDamage>5__2 = false;
							<>7__wrap2 = instructions.GetEnumerator();
							<>1__state = -3;
							goto IL_0123;
						case 1:
							<>1__state = -3;
							<>2__current = new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(TagFriendlyFireAoe), "CheckAndTag", (Type[])null, (Type[])null));
							<>1__state = 2;
							return true;
						case 2:
							<>1__state = -3;
							goto IL_00fd;
						case 3:
							{
								<>1__state = -3;
								<instruction>5__4 = null;
								goto IL_0123;
							}
							IL_0123:
							if (<>7__wrap2.MoveNext())
							{
								<instruction>5__4 = <>7__wrap2.Current;
								if (<preDamage>5__2 && CodeInstructionExtensions.Calls(<instruction>5__4, Damage))
								{
									<preDamage>5__2 = false;
									<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
									<>1__state = 1;
									return true;
								}
								if (CodeInstructionExtensions.Calls(<instruction>5__4, ModifyHit))
								{
									<preDamage>5__2 = true;
								}
								goto IL_00fd;
							}
							<>m__Finally1();
							<>7__wrap2 = null;
							return false;
							IL_00fd:
							<>2__current = <instruction>5__4;
							<>1__state = 3;
							return true;
						}
					}
					catch
					{
						//try-fault
						((IDisposable)this).Dispose();
						throw;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				private void <>m__Finally1()
				{
					<>1__state = -1;
					if (<>7__wrap2 != null)
					{
						<>7__wrap2.Dispose();
					}
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
				{
					<Transpiler>d__3 <Transpiler>d__;
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						<Transpiler>d__ = this;
					}
					else
					{
						<Transpiler>d__ = new <Transpiler>d__3(0);
					}
					<Transpiler>d__.instructions = <>3__instructions;
					return <Transpiler>d__;
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
				}
			}

			private static readonly MethodInfo ModifyHit = AccessTools.DeclaredMethod(typeof(DamageTypes), "Modify", new Type[1] { typeof(float) }, (Type[])null);

			private static readonly MethodInfo Damage = AccessTools.DeclaredMethod(typeof(IDestructible), "Damage", (Type[])null, (Type[])null);

			private static HitData CheckAndTag(HitData hit, Aoe aoe)
			{
				if (aoe.m_hitFriendly && Object.op_Implicit((Object)(object)Projectile.FindHitObject(hit.m_hitCollider).GetComponent<Player>()))
				{
					hit.m_weakSpot = -23749;
				}
				return hit;
			}

			[IteratorStateMachine(typeof(<Transpiler>d__3))]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <Transpiler>d__3(-2)
				{
					<>3__instructions = instructions
				};
			}
		}

		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class FriendlyFirePatch
		{
			private static bool Prefix(Character __instance, HitData hit)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					Character attacker = hit.GetAttacker();
					Player val = (Player)(object)((attacker is Player) ? attacker : null);
					if (val != null && hit.m_weakSpot != -23749 && friendlyFire.Value == Toggle.Off && ownGroup != null && ownGroup.playerStates.ContainsKey(PlayerReference.fromPlayer(val)))
					{
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		private static class PreventFriendlyFireMarkerOverwrite
		{
			[CompilerGenerated]
			private sealed class <Transpiler>d__2 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private CodeInstruction <>2__current;

				private int <>l__initialThreadId;

				private IEnumerable<CodeInstruction> instructions;

				public IEnumerable<CodeInstruction> <>3__instructions;

				private IEnumerator<CodeInstruction> <>7__wrap1;

				CodeInstruction IEnumerator<CodeInstruction>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <Transpiler>d__2(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					int num = <>1__state;
					if (num == -3 || (uint)(num - 1) <= 1u)
					{
						try
						{
						}
						finally
						{
							<>m__Finally1();
						}
					}
					<>7__wrap1 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_0077: Unknown result type (might be due to invalid IL or missing references)
					//IL_0081: Expected O, but got Unknown
					try
					{
						switch (<>1__state)
						{
						default:
							return false;
						case 0:
							<>1__state = -1;
							<>7__wrap1 = instructions.GetEnumerator();
							<>1__state = -3;
							break;
						case 1:
							<>1__state = -3;
							break;
						case 2:
							<>1__state = -3;
							break;
						}
						if (<>7__wrap1.MoveNext())
						{
							CodeInstruction current = <>7__wrap1.Current;
							if (CodeInstructionExtensions.StoresField(current, weakSpotField))
							{
								<>2__current = new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(PreventFriendlyFireMarkerOverwrite), "WriteWeakSpot", (Type[])null, (Type[])null));
								<>1__state = 1;
								return true;
							}
							<>2__current = current;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>7__wrap1 = null;
						return false;
					}
					catch
					{
						//try-fault
						((IDisposable)this).Dispose();
						throw;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				private void <>m__Finally1()
				{
					<>1__state = -1;
					if (<>7__wrap1 != null)
					{
						<>7__wrap1.Dispose();
					}
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
				{
					<Transpiler>d__2 <Transpiler>d__;
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						<Transpiler>d__ = this;
					}
					else
					{
						<Transpiler>d__ = new <Transpiler>d__2(0);
					}
					<Transpiler>d__.instructions = <>3__instructions;
					return <Transpiler>d__;
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
				}
			}

			private static readonly FieldInfo weakSpotField = AccessTools.DeclaredField(typeof(HitData), "m_weakSpot");

			private static void WriteWeakSpot(HitData hit, short index)
			{
				if (hit.m_weakSpot >= -1)
				{
					hit.m_weakSpot = index;
				}
			}

			[IteratorStateMachine(typeof(<Transpiler>d__2))]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <Transpiler>d__2(-2)
				{
					<>3__instructions = instructions
				};
			}
		}

		[HarmonyPatch(typeof(Game), "Shutdown")]
		public class LeaveGroupOnLogout
		{
			private static void Postfix()
			{
				ownGroup = null;
			}
		}

		private const string ModName = "Groups";

		private const string ModVersion = "1.2.10";

		private const string ModGUID = "org.bepinex.plugins.groups";

		public static Group? ownGroup;

		private static ConfigEntry<Toggle> serverConfigLocked = null;

		public static ConfigEntry<int> maximumGroupSize = null;

		public static ConfigEntry<Toggle> friendlyFire = null;

		public static ConfigEntry<Color> friendlyNameColor = null;

		public static ConfigEntry<string> ignoreList = null;

		public static ConfigEntry<Color> groupChatColor = null;

		public static ConfigEntry<Vector2> groupInterfaceAnchor = null;

		public static ConfigEntry<KeyboardShortcut> groupPingHotkey = null;

		public static ConfigEntry<Toggle> horizontalGroupInterface = null;

		public static ConfigEntry<GroupLeaderDisplayOption> groupLeaderDisplay = null;

		public static ConfigEntry<Color> groupLeaderColor = null;

		public static ConfigEntry<float> spaceBetweenGroupMembers = null;

		public static ConfigEntry<BlockInvitation> blockInvitations = null;

		private static int configOrder = 0;

		private static readonly ConfigSync configSync = new ConfigSync("Groups")
		{
			CurrentVersion = "1.2.10",
			MinimumRequiredVersion = "1.2.10"
		};

		private const short IsFriendlyAoe = -23749;

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, new ConfigDescription(description.Description, description.AcceptableValues, (description.Tags.Length != 0) ? description.Tags : new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = configOrder--
				}
			}));
			configSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting;
			return val;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		public void Awake()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_01bc: 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_01d7: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Expected O, but got Unknown
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Expected O, but got Unknown
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Expected O, but got Unknown
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Expected O, but got Unknown
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Expected O, but got Unknown
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			Patcher.Patch();
			Localizer.Load();
			Type configManagerType = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager");
			object configManager = ((configManagerType == null) ? null : Chainloader.ManagerObject.GetComponent(configManagerType));
			serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, new ConfigDescription("If on, only server admins can change the configuration.", (AcceptableValueBase)null, Array.Empty<object>()));
			configSync.AddLockingConfigEntry<Toggle>(serverConfigLocked);
			maximumGroupSize = config("1 - General", "Maximum size for groups", 5, new ConfigDescription("Maximum size for groups.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), Array.Empty<object>()));
			friendlyFire = config("1 - General", "Friendly fire in groups", Toggle.Off, new ConfigDescription("If members of the same group can damage each other in PvP.", (AcceptableValueBase)null, Array.Empty<object>()));
			groupChatColor = config<Color>("2 - Display", "Color of the group chat", new Color(0f, 1f, 0f), new ConfigDescription("The color for messages in your group.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			friendlyNameColor = config<Color>("2 - Display", "Name color for group members", new Color(0f, 1f, 0f), new ConfigDescription("The color for names of members of the own group, if you see them in the world.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			friendlyNameColor.SettingChanged += delegate
			{
				Map.UpdateMapPinColor();
			};
			groupInterfaceAnchor = config<Vector2>("2 - Display", "Position of the group interface", new Vector2(-875f, 310f), new ConfigDescription("Sets the anchor position of the group interface.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			groupInterfaceAnchor.SettingChanged += Interface.AnchorGroupInterface;
			horizontalGroupInterface = config("2 - Display", "Horizontal group interface", Toggle.Off, new ConfigDescription("Aligns the group interface horizontally, instead of vertically.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			horizontalGroupInterface.SettingChanged += Interface.UpdateGroupInterfaceSpacing;
			groupLeaderDisplay = config("2 - Display", "Group leader display", GroupLeaderDisplayOption.Icon, new ConfigDescription("How the leader of the group is displayed.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			ConfigurationManagerAttributes colorDisplay = new ConfigurationManagerAttributes
			{
				Order = (configOrder -= 1),
				Browsable = (groupLeaderDisplay.Value == GroupLeaderDisplayOption.Color)
			};
			groupLeaderDisplay.SettingChanged += delegate
			{
				colorDisplay.Browsable = groupLeaderDisplay.Value == GroupLeaderDisplayOption.Color;
				reloadConfigDisplay();
			};
			groupLeaderColor = config<Color>("2 - Display", "Group leader color", new Color(0.6f, 0.6f, 0.2f), new ConfigDescription("Color of the group leader, if using the group leader color display option.", (AcceptableValueBase)null, new object[1] { colorDisplay }), synchronizedSetting: false);
			spaceBetweenGroupMembers = config("2 - Display", "Space between group members", 75f, new ConfigDescription("The space between group members in the group display.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			spaceBetweenGroupMembers.SettingChanged += Interface.UpdateGroupInterfaceSpacing;
			groupPingHotkey = config<KeyboardShortcut>("3 - Other", "Group ping modifier key", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), new ConfigDescription("Modifier key that has to be pressed while pinging the map, to make the map ping visible to group members only.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			ignoreList = config("3 - Other", "Names of people who cannot invite you", "", new ConfigDescription("Ignore group invitations from people on this list. Comma separated.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			blockInvitations = config("3 - Other", "Block all invitations", BlockInvitation.Never, new ConfigDescription("Can be used to block all invitations. Optionally, only block invitations while PvP is enabled.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			new Harmony("org.bepinex.plugins.groups").PatchAll(executingAssembly);
			Interface.Init();
			Map.Init();
			((MonoBehaviour)this).InvokeRepeating("updatePositon", 0f, 2f);
			void reloadConfigDisplay()
			{
				configManagerType?.GetMethod("BuildSettingList").Invoke(configManager, Array.Empty<object>());
			}
		}

		private void updatePositon()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer == null || ownGroup == null || ZNet.instance.m_publicReferencePosition)
			{
				return;
			}
			foreach (PlayerReference item in ownGroup.playerStates.Keys.Where((PlayerReference r) => r.peerId != ZDOMan.GetSessionID()))
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(item.peerId, "Groups UpdatePosition", new object[1] { ((Component)localPlayer).transform.position });
			}
		}
	}
	public static class Helper
	{
		private static byte[] ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Assembly.GetExecutingAssembly().GetManifestResourceStream("Groups." + name)?.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static Texture2D loadTexture(string name)
		{
			//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)
			//IL_001d: Expected O, but got Unknown
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name));
			return val;
		}

		public static Sprite loadSprite(string name, int width, int height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
		}
	}
	public static class ChatCommands
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		public class AddChatCommands
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__0_0;

				public static Func<PlayerInfo, string> <>9__0_9;

				public static ConsoleOptionsFetcher <>9__0_1;

				public static ConsoleEvent <>9__0_2;

				public static Func<PlayerReference, string> <>9__0_11;

				public static Func<string, bool> <>9__0_12;

				public static ConsoleOptionsFetcher <>9__0_3;

				public static ConsoleEvent <>9__0_4;

				public static Func<PlayerReference, string> <>9__0_14;

				public static Func<string, bool> <>9__0_15;

				public static ConsoleOptionsFetcher <>9__0_5;

				public static ConsoleEvent <>9__0_6;

				public static ConsoleEvent <>9__0_7;

				internal void <Postfix>b__0_0(ConsoleEventArgs args)
				{
					//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
					<>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0();
					if (args.FullLine.Length <= "invite".Length || (Object)(object)Chat.instance == (Object)null)
					{
						return;
					}
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer == null || ((Character)localPlayer).m_nview.GetZDO().GetBool("dead", false))
					{
						args.Context.AddString(Localization.instance.Localize("$groups_dead"));
						return;
					}
					CS$<>8__locals0.playerName = args.FullLine.Substring(7);
					if (string.Compare(CS$<>8__locals0.playerName, ((Character)Player.m_localPlayer).GetHoverName(), StringComparison.OrdinalIgnoreCase) == 0)
					{
						args.Context.AddString(Localization.instance.Localize("$groups_cannot_invite_self"));
						return;
					}
					PlayerInfo val = ((IEnumerable<PlayerInfo>)ZNet.instance.m_players).FirstOrDefault((Func<PlayerInfo, bool>)((PlayerInfo p) => string.Compare(CS$<>8__locals0.playerName, p.m_name, StringComparison.OrdinalIgnoreCase) == 0));
					long userID = ((ZDOID)(ref val.m_characterID)).UserID;
					if (userID == 0L)
					{
						args.Context.AddString(Localization.instance.Localize("$groups_player_not_online", new string[1] { CS$<>8__locals0.playerName }));
						return;
					}
					if (Groups.ownGroup == null)
					{
						Groups.ownGroup = new Group(PlayerReference.fromPlayer(Player.m_localPlayer), Group.PlayerState.fromLocal());
						API.InvokeGroupJoined();
					}
					if (Groups.ownGroup.leader == PlayerReference.fromPlayer(Player.m_localPlayer))
					{
						ZRoutedRpc.instance.InvokeRoutedRPC(userID, "Groups InvitePlayer", new object[1] { ((Character)Player.m_localPlayer).GetHoverName() });
						args.Context.AddString(Localization.instance.Localize("$groups_invitation_sent", new string[1] { CS$<>8__locals0.playerName }));
					}
					else
					{
						args.Context.AddString(Localization.instance.Localize("$groups_leader_can_invite"));
					}
				}

				internal List<string> <Postfix>b__0_1()
				{
					return ZNet.instance.m_players.Select((PlayerInfo p) => p.m_name).ToList();
				}

				internal string <Postfix>b__0_9(PlayerInfo p)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					return p.m_name;
				}

				internal void <Postfix>b__0_2(ConsoleEventArgs args)
				{
					<>c__DisplayClass0_1 CS$<>8__locals0 = new <>c__DisplayClass0_1();
					if (args.FullLine.Length <= "remove".Length || (Object)(object)Chat.instance == (Object)null)
					{
						return;
					}
					if (Groups.ownGroup == null)
					{
						args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
						return;
					}
					if (Groups.ownGroup.leader != PlayerReference.fromPlayer(Player.m_localPlayer))
					{
						args.Context.AddString(Localization.instance.Localize("$groups_leader_can_remove"));
						return;
					}
					CS$<>8__locals0.playerName = args.FullLine.Substring(7);
					if (string.Compare(CS$<>8__locals0.playerName, ((Character)Player.m_localPlayer).GetHoverName(), StringComparison.OrdinalIgnoreCase) == 0)
					{
						args.Context.AddString(Localization.instance.Localize("$groups_removed_self"));
					}
					else if (!Groups.ownGroup.RemoveMember(Groups.ownGroup.playerStates.Keys.FirstOrDefault((PlayerReference p) => string.Compare(p.name, CS$<>8__locals0.playerName, StringComparison.OrdinalIgnoreCase) == 0)))
					{
						args.Context.AddString(Localization.instance.Localize("$groups_target_not_in_group", new string[1] { CS$<>8__locals0.playerName }));
					}
				}

				internal List<string> <Postfix>b__0_3()
				{
					return (from p in Groups.ownGroup?.playerStates.Keys
						select p.name into n
						where n != ((Character)Player.m_localPlayer).GetHoverName()
						select n).ToList() ?? new List<string>();
				}

				internal string <Postfix>b__0_11(PlayerReference p)
				{
					return p.name;
				}

				internal bool <Postfix>b__0_12(string n)
				{
					return n != ((Character)Player.m_localPlayer).GetHoverName();
				}

				internal void <Postfix>b__0_4(ConsoleEventArgs args)
				{
					<>c__DisplayClass0_2 CS$<>8__locals0 = new <>c__DisplayClass0_2();
					if (args.FullLine.Length <= "promote".Length || (Object)(object)Chat.instance == (Object)null)
					{
						return;
					}
					if (Groups.ownGroup == null)
					{
						args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
						return;
					}
					if (Groups.ownGroup.leader != PlayerReference.fromPlayer(Player.m_localPlayer))
					{
						args.Context.AddString(Localization.instance.Localize("$groups_leader_can_promote"));
						return;
					}
					CS$<>8__locals0.playerName = args.FullLine.Substring(8);
					if (!Groups.ownGroup.PromoteMember(Groups.ownGroup.playerStates.Keys.FirstOrDefault((PlayerReference p) => string.Compare(p.name, CS$<>8__locals0.playerName, StringComparison.OrdinalIgnoreCase) == 0)))
					{
						args.Context.AddString(Localization.instance.Localize("$groups_target_not_in_group", new string[1] { CS$<>8__locals0.playerName }));
					}
				}

				internal List<string> <Postfix>b__0_5()
				{
					return (from p in Groups.ownGroup?.playerStates.Keys
						select p.name into n
						where n != ((Character)Player.m_localPlayer).GetHoverName()
						select n).ToList() ?? new List<string>();
				}

				internal string <Postfix>b__0_14(PlayerReference p)
				{
					return p.name;
				}

				internal bool <Postfix>b__0_15(string n)
				{
					return n != ((Character)Player.m_localPlayer).GetHoverName();
				}

				internal void <Postfix>b__0_6(ConsoleEventArgs args)
				{
					if (args.FullLine.Length >= "leave".Length && !((Object)(object)Chat.instance == (Object)null))
					{
						if (Groups.ownGroup == null)
						{
							args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
						}
						else
						{
							Groups.ownGroup.Leave();
						}
					}
				}

				internal void <Postfix>b__0_7(ConsoleEventArgs args)
				{
					if ((Object)(object)Chat.instance == (Object)null)
					{
						return;
					}
					if (Groups.ownGroup == null)
					{
						args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
						return;
					}
					if (args.FullLine.Length > 2)
					{
						string text = args.FullLine.Substring(2);
						{
							foreach (PlayerReference key in Groups.ownGroup.playerStates.Keys)
							{
								ZRoutedRpc.instance.InvokeRoutedRPC(key.peerId, "Groups ChatMessage", new object[2]
								{
									UserInfo.GetLocalUser(),
									text
								});
							}
							return;
						}
					}
					ToggleGroupsChat(!groupChatActive);
				}
			}

			[CompilerGenerated]
			private sealed class <>c__DisplayClass0_0
			{
				public string playerName;

				internal bool <Postfix>b__8(PlayerInfo p)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					return string.Compare(playerName, p.m_name, StringComparison.OrdinalIgnoreCase) == 0;
				}
			}

			[CompilerGenerated]
			private sealed class <>c__DisplayClass0_1
			{
				public string playerName;

				internal bool <Postfix>b__10(PlayerReference p)
				{
					return string.Compare(p.name, playerName, StringComparison.OrdinalIgnoreCase) == 0;
				}
			}

			[CompilerGenerated]
			private sealed class <>c__DisplayClass0_2
			{
				public string playerName;

				internal bool <Postfix>b__13(PlayerReference p)
				{
					return string.Compare(p.name, playerName, StringComparison.OrdinalIgnoreCase) == 0;
				}
			}

			private static void Postfix()
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Expected O, but got Unknown
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Expected O, but got Unknown
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Expected O, but got Unknown
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: 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_010a: Expected O, but got Unknown
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Expected O, but got Unknown
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Expected O, but got Unknown
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Expected O, but got Unknown
				//IL_01a5: 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_019c: Expected O, but got Unknown
				groupChatPlaceholder = Localization.instance.Localize("$groups_chat_placeholder");
				ChatCommands.terminalCommands.Clear();
				List<ConsoleCommand> terminalCommands = ChatCommands.terminalCommands;
				object obj = <>c.<>9__0_0;
				if (obj == null)
				{
					ConsoleEvent val = delegate(ConsoleEventArgs args)
					{
						//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
						//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
						if (args.FullLine.Length > "invite".Length && !((Object)(object)Chat.instance == (Object)null))
						{
							Player localPlayer = Player.m_localPlayer;
							if (localPlayer == null || ((Character)localPlayer).m_nview.GetZDO().GetBool("dead", false))
							{
								args.Context.AddString(Localization.instance.Localize("$groups_dead"));
							}
							else
							{
								string playerName3 = args.FullLine.Substring(7);
								if (string.Compare(playerName3, ((Character)Player.m_localPlayer).GetHoverName(), StringComparison.OrdinalIgnoreCase) == 0)
								{
									args.Context.AddString(Localization.instance.Localize("$groups_cannot_invite_self"));
								}
								else
								{
									PlayerInfo val9 = ((IEnumerable<PlayerInfo>)ZNet.instance.m_players).FirstOrDefault((Func<PlayerInfo, bool>)((PlayerInfo p) => string.Compare(playerName3, p.m_name, StringComparison.OrdinalIgnoreCase) == 0));
									long userID = ((ZDOID)(ref val9.m_characterID)).UserID;
									if (userID == 0L)
									{
										args.Context.AddString(Localization.instance.Localize("$groups_player_not_online", new string[1] { playerName3 }));
									}
									else
									{
										if (Groups.ownGroup == null)
										{
											Groups.ownGroup = new Group(PlayerReference.fromPlayer(Player.m_localPlayer), Group.PlayerState.fromLocal());
											API.InvokeGroupJoined();
										}
										if (Groups.ownGroup.leader == PlayerReference.fromPlayer(Player.m_localPlayer))
										{
											ZRoutedRpc.instance.InvokeRoutedRPC(userID, "Groups InvitePlayer", new object[1] { ((Character)Player.m_localPlayer).GetHoverName() });
											args.Context.AddString(Localization.instance.Localize("$groups_invitation_sent", new string[1] { playerName3 }));
										}
										else
										{
											args.Context.AddString(Localization.instance.Localize("$groups_leader_can_invite"));
										}
									}
								}
							}
						}
					};
					<>c.<>9__0_0 = val;
					obj = (object)val;
				}
				object obj2 = <>c.<>9__0_1;
				if (obj2 == null)
				{
					ConsoleOptionsFetcher val2 = () => ZNet.instance.m_players.Select((PlayerInfo p) => p.m_name).ToList();
					<>c.<>9__0_1 = val2;
					obj2 = (object)val2;
				}
				terminalCommands.Add(new ConsoleCommand("invite", "invite someone to your group", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false));
				List<ConsoleCommand> terminalCommands2 = ChatCommands.terminalCommands;
				object obj3 = <>c.<>9__0_2;
				if (obj3 == null)
				{
					ConsoleEvent val3 = delegate(ConsoleEventArgs args)
					{
						if (args.FullLine.Length > "remove".Length && !((Object)(object)Chat.instance == (Object)null))
						{
							if (Groups.ownGroup == null)
							{
								args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
							}
							else if (Groups.ownGroup.leader != PlayerReference.fromPlayer(Player.m_localPlayer))
							{
								args.Context.AddString(Localization.instance.Localize("$groups_leader_can_remove"));
							}
							else
							{
								string playerName2 = args.FullLine.Substring(7);
								if (string.Compare(playerName2, ((Character)Player.m_localPlayer).GetHoverName(), StringComparison.OrdinalIgnoreCase) == 0)
								{
									args.Context.AddString(Localization.instance.Localize("$groups_removed_self"));
								}
								else if (!Groups.ownGroup.RemoveMember(Groups.ownGroup.playerStates.Keys.FirstOrDefault((PlayerReference p) => string.Compare(p.name, playerName2, StringComparison.OrdinalIgnoreCase) == 0)))
								{
									args.Context.AddString(Localization.instance.Localize("$groups_target_not_in_group", new string[1] { playerName2 }));
								}
							}
						}
					};
					<>c.<>9__0_2 = val3;
					obj3 = (object)val3;
				}
				object obj4 = <>c.<>9__0_3;
				if (obj4 == null)
				{
					ConsoleOptionsFetcher val4 = () => (from p in Groups.ownGroup?.playerStates.Keys
						select p.name into n
						where n != ((Character)Player.m_localPlayer).GetHoverName()
						select n).ToList() ?? new List<string>();
					<>c.<>9__0_3 = val4;
					obj4 = (object)val4;
				}
				terminalCommands2.Add(new ConsoleCommand("remove", "removes someone from your group", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)obj4, false, false, false));
				List<ConsoleCommand> terminalCommands3 = ChatCommands.terminalCommands;
				object obj5 = <>c.<>9__0_4;
				if (obj5 == null)
				{
					ConsoleEvent val5 = delegate(ConsoleEventArgs args)
					{
						if (args.FullLine.Length > "promote".Length && !((Object)(object)Chat.instance == (Object)null))
						{
							if (Groups.ownGroup == null)
							{
								args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
							}
							else if (Groups.ownGroup.leader != PlayerReference.fromPlayer(Player.m_localPlayer))
							{
								args.Context.AddString(Localization.instance.Localize("$groups_leader_can_promote"));
							}
							else
							{
								string playerName = args.FullLine.Substring(8);
								if (!Groups.ownGroup.PromoteMember(Groups.ownGroup.playerStates.Keys.FirstOrDefault((PlayerReference p) => string.Compare(p.name, playerName, StringComparison.OrdinalIgnoreCase) == 0)))
								{
									args.Context.AddString(Localization.instance.Localize("$groups_target_not_in_group", new string[1] { playerName }));
								}
							}
						}
					};
					<>c.<>9__0_4 = val5;
					obj5 = (object)val5;
				}
				object obj6 = <>c.<>9__0_5;
				if (obj6 == null)
				{
					ConsoleOptionsFetcher val6 = () => (from p in Groups.ownGroup?.playerStates.Keys
						select p.name into n
						where n != ((Character)Player.m_localPlayer).GetHoverName()
						select n).ToList() ?? new List<string>();
					<>c.<>9__0_5 = val6;
					obj6 = (object)val6;
				}
				terminalCommands3.Add(new ConsoleCommand("promote", "promotes someone to group leader", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)obj6, false, false, false));
				object obj7 = <>c.<>9__0_6;
				if (obj7 == null)
				{
					ConsoleEvent val7 = delegate(ConsoleEventArgs args)
					{
						if (args.FullLine.Length >= "leave".Length && !((Object)(object)Chat.instance == (Object)null))
						{
							if (Groups.ownGroup == null)
							{
								args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
							}
							else
							{
								Groups.ownGroup.Leave();
							}
						}
					};
					<>c.<>9__0_6 = val7;
					obj7 = (object)val7;
				}
				new ConsoleCommand("leave", "leaves your current group", (ConsoleEvent)obj7, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj8 = <>c.<>9__0_7;
				if (obj8 == null)
				{
					ConsoleEvent val8 = delegate(ConsoleEventArgs args)
					{
						if (!((Object)(object)Chat.instance == (Object)null))
						{
							if (Groups.ownGroup == null)
							{
								args.Context.AddString(Localization.instance.Localize("$groups_not_in_group"));
							}
							else
							{
								if (args.FullLine.Length > 2)
								{
									string text = args.FullLine.Substring(2);
									{
										foreach (PlayerReference key in Groups.ownGroup.playerStates.Keys)
										{
											ZRoutedRpc.instance.InvokeRoutedRPC(key.peerId, "Groups ChatMessage", new object[2]
											{
												UserInfo.GetLocalUser(),
												text
											});
										}
										return;
									}
								}
								ToggleGroupsChat(!groupChatActive);
							}
						}
					};
					<>c.<>9__0_7 = val8;
					obj8 = (object)val8;
				}
				new ConsoleCommand("p", "toggles the group chat on", (ConsoleEvent)obj8, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			}
		}

		[HarmonyPatch(typeof(Chat), "Awake")]
		public class AddGroupChat
		{
			private static void Postfix(Chat __instance)
			{
				int index = Math.Max(0, ((Terminal)__instance).m_chatBuffer.Count - 5);
				((Terminal)__instance).m_chatBuffer.Insert(index, Localization.instance.Localize("$groups_group_chat_message_hint"));
				((Terminal)__instance).m_chatBuffer.Insert(index, Localization.instance.Localize("$groups_group_chat_toggle_hint"));
				((Terminal)__instance).UpdateChat();
			}
		}

		[HarmonyPatch(typeof(Chat), "InputText")]
		public class SendMessageToGroup
		{
			private static void Prefix(Chat __instance)
			{
				if (((TMP_InputField)((Terminal)__instance).m_input).text.Length != 0 && groupChatActive && ((TMP_InputField)((Terminal)__instance).m_input).text[0] != '/')
				{
					((TMP_InputField)((Terminal)__instance).m_input).text = "/p " + ((TMP_InputField)((Terminal)__instance).m_input).text;
				}
			}
		}

		private static string groupChatPlaceholder = null;

		private static readonly List<ConsoleCommand> terminalCommands = new List<ConsoleCommand>();

		private static bool groupChatActive
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Chat.instance))
				{
					return ((TMP_Text)((Component)((Component)((Terminal)Chat.instance).m_input).transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>()).text == groupChatPlaceholder;
				}
				return false;
			}
		}

		public static void ToggleGroupsChat(bool active)
		{
			if (Object.op_Implicit((Object)(object)Chat.instance))
			{
				TextMeshProUGUI component = ((Component)((Component)((Terminal)Chat.instance).m_input).transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>();
				if (active)
				{
					((TMP_Text)component).text = groupChatPlaceholder;
					Localization.instance.textMeshStrings[(TMP_Text)(object)component] = groupChatPlaceholder;
				}
				else if (((TMP_Text)component).text == groupChatPlaceholder)
				{
					((TMP_Text)component).text = Localization.instance.Localize("$chat_entertext");
					Localization.instance.textMeshStrings[(TMP_Text)(object)component] = "$chat_entertext";
				}
			}
		}

		public static void UpdateAutoCompletion()
		{
			foreach (ConsoleCommand terminalCommand in terminalCommands)
			{
				terminalCommand.m_tabOptions = null;
			}
		}
	}
	public static class Interface
	{
		[HarmonyPatch(typeof(Hud), "Awake")]
		public class AddGroupDisplay
		{
			private static void Postfix(Hud __instance)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Expected O, but got Unknown
				//IL_0046: 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_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: 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_00de: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: 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_01f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_020b: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = new GameObject("Groups", new Type[1] { typeof(RectTransform) });
				val.AddComponent<DragNDrop>();
				val.transform.SetParent(__instance.m_rootObject.transform);
				val.transform.localPosition = Vector2.op_Implicit(Groups.groupInterfaceAnchor.Value);
				groupMemberFirst = Object.Instantiate<GameObject>(EnemyHud.instance.m_baseHudPlayer, val.transform);
				groupMemberFirst.transform.localPosition = Vector3.zero;
				Transform obj = groupMemberFirst.transform.Find("Health");
				obj.localScale = new Vector3(1f, 3.5f, 1f);
				((Component)((Component)obj).transform.Find("darken")).GetComponent<RectTransform>().sizeDelta = new Vector2(8f, 3f);
				GameObject val2 = new GameObject("Leader Icon");
				val2.transform.SetParent(groupMemberFirst.transform);
				val2.AddComponent<Image>().sprite = groupLeaderIcon;
				RectTransform component = val2.GetComponent<RectTransform>();
				component.sizeDelta = new Vector2(32f, 32f);
				((Transform)component).localPosition = Vector2.op_Implicit(new Vector2(0f, 46f));
				val2.SetActive(false);
				GameObject val3 = new GameObject("Life Display Text", new Type[1] { typeof(RectTransform) });
				val3.transform.SetParent(groupMemberFirst.transform, false);
				((RectTransform)val3.transform).sizeDelta = new Vector2(300f, 50f);
				val3.transform.localPosition = new Vector3(0f, 5f);
				Text obj2 = val3.AddComponent<Text>();
				obj2.font = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font x) => ((Object)x).name == "AveriaSerifLibre-Bold"));
				obj2.fontSize = 14;
				obj2.alignment = (TextAnchor)4;
				Outline obj3 = val3.AddComponent<Outline>();
				((Shadow)obj3).effectColor = Color.black;
				((Shadow)obj3).effectDistance = new Vector2(1f, -1f);
			}
		}

		[HarmonyPatch(typeof(Hud), "Update")]
		public class UpdateGroupDisplay
		{
			private static void Postfix()
			{
				//IL_0096: 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_018c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0303: Unknown result type (might be due to invalid IL or missing references)
				Transform parent = groupMemberFirst.transform.parent;
				bool flag = ((Component)parent).gameObject.activeSelf;
				((Component)parent).gameObject.SetActive(Groups.ownGroup != null);
				if (Groups.ownGroup == null)
				{
					return;
				}
				Vector2 sizeDelta = default(Vector2);
				while (parent.childCount < Groups.ownGroup.playerStates.Count)
				{
					GameObject obj = Object.Instantiate<GameObject>(groupMemberFirst, parent, false);
					obj.transform.localPosition = ((Groups.horizontalGroupInterface.Value == Groups.Toggle.On) ? new Vector3((float)(parent.childCount - 1) * Groups.spaceBetweenGroupMembers.Value, 0f) : new Vector3(0f, (float)(-(parent.childCount - 1)) * Groups.spaceBetweenGroupMembers.Value));
					GuiBar component = ((Component)groupMemberFirst.transform.Find("Health/health_slow")).GetComponent<GuiBar>();
					((Vector2)(ref sizeDelta))..ctor(Mathf.Max(component.m_bar.sizeDelta.x, component.m_width), component.m_bar.sizeDelta.y);
					((Component)obj.transform.Find("Health/health_slow")).GetComponent<GuiBar>().m_firstSet = true;
					((Component)obj.transform.Find("Health/health_slow")).GetComponent<GuiBar>().m_bar.sizeDelta = sizeDelta;
					((Component)obj.transform.Find("Health/health_fast")).GetComponent<GuiBar>().m_firstSet = true;
					((Component)obj.transform.Find("Health/health_fast")).GetComponent<GuiBar>().m_bar.sizeDelta = sizeDelta;
					flag = false;
				}
				if (!flag)
				{
					((Component)parent).GetComponent<DragNDrop>().SetPosition(((Component)parent).transform.position);
				}
				for (int i = 0; i < parent.childCount; i++)
				{
					Transform child = parent.GetChild(i);
					List<KeyValuePair<PlayerReference, Group.PlayerState>> list = Groups.ownGroup.playerStates.ToList();
					bool flag2 = i < Groups.ownGroup.playerStates.Count;
					((Component)child).gameObject.SetActive(flag2);
					if (flag2)
					{
						PlayerReference key = list[i].Key;
						Group.PlayerState value = list[i].Value;
						((Component)child.Find("Health/health_slow")).GetComponent<GuiBar>().SetValue(value.health / value.maxHealth);
						((Component)child.Find("Health/health_fast")).GetComponent<GuiBar>().SetValue(value.health / value.maxHealth);
						((Component)child.Find("Life Display Text")).GetComponent<Text>().text = ((value.health <= 0f) ? "DEAD" : (Mathf.Ceil(value.health) + " / " + Mathf.Ceil(value.maxHealth)));
						TextMeshProUGUI component2 = ((Component)child.Find("Name")).GetComponent<TextMeshProUGUI>();
						((TMP_Text)component2).text = key.name;
						((Graphic)component2).color = ((key == Groups.ownGroup.leader && Groups.groupLeaderDisplay.Value == Groups.GroupLeaderDisplayOption.Color) ? Groups.groupLeaderColor.Value : Groups.friendlyNameColor.Value);
						((Component)child.Find("Leader Icon")).gameObject.SetActive(key == Groups.ownGroup.leader && Groups.groupLeaderDisplay.Value == Groups.GroupLeaderDisplayOption.Icon);
						API.InvokeUIUpdate(key, ((Component)child).gameObject);
					}
				}
			}
		}

		[HarmonyPatch]
		public class BroadcastHealth
		{
			[CompilerGenerated]
			private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private MethodBase <>2__current;

				private int <>l__initialThreadId;

				MethodBase IEnumerator<MethodBase>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <TargetMethods>d__0(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Character), "SetHealth", (Type[])null, (Type[])null);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<>2__current = AccessTools.Method(typeof(Character), "SetMaxHealth", (Type[])null, (Type[])null);
						<>1__state = 2;
						return true;
					case 2:
						<>1__state = -1;
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
				{
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						return this;
					}
					return new <TargetMethods>d__0(0);
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<MethodBase>)this).GetEnumerator();
				}
			}

			[IteratorStateMachine(typeof(<TargetMethods>d__0))]
			private static IEnumerable<MethodBase> TargetMethods()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <TargetMethods>d__0(-2);
			}

			private static void Postfix(Character __instance)
			{
				if (Groups.ownGroup == null || !((Object)(object)__instance == (Object)(object)Player.m_localPlayer))
				{
					return;
				}
				foreach (PlayerReference key in Groups.ownGroup.playerStates.Keys)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(key.peerId, "Groups UpdateHealth", new object[2]
					{
						__instance.GetHealth(),
						__instance.GetMaxHealth()
					});
				}
			}
		}

		private static Sprite groupLeaderIcon;

		private static GameObject? groupMemberFirst;

		public static void Init()
		{
			groupLeaderIcon = Helper.loadSprite("groupLeaderIcon.png", 32, 32);
		}

		public static void AnchorGroupInterface(object sender, EventArgs e)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (groupMemberFirst != null)
			{
				Transform parent = groupMemberFirst.transform.parent;
				Vector2 val = Vector2.op_Implicit(parent.localPosition) - Groups.groupInterfaceAnchor.Value;
				if ((double)((Vector2)(ref val)).magnitude > 0.001)
				{
					parent.localPosition = Vector2.op_Implicit(Groups.groupInterfaceAnchor.Value);
					((Component)parent).GetComponent<DragNDrop>().SetPosition(parent.position);
				}
			}
		}

		public static void UpdateGroupInterfaceSpacing(object sender, EventArgs e)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (groupMemberFirst != null)
			{
				Transform parent = groupMemberFirst.transform.parent;
				for (int i = 0; i < parent.childCount; i++)
				{
					parent.GetChild(i).localPosition = ((Groups.horizontalGroupInterface.Value == Groups.Toggle.On) ? new Vector3((float)i * Groups.spaceBetweenGroupMembers.Value, 0f) : new Vector3(0f, (float)(-i) * Groups.spaceBetweenGroupMembers.Value));
				}
			}
		}

		public static void onUpdateHealth(long senderId, float health, float maxHealth)
		{
			if (Groups.ownGroup != null && Groups.ownGroup.playerStates.TryGetValue(PlayerReference.fromPlayerId(senderId), out Group.PlayerState value))
			{
				value.health = health;
				value.maxHealth = maxHealth;
			}
		}
	}
	public static class Map
	{
		[HarmonyPatch(typeof(EnemyHud), "ShowHud")]
		public class ColorNames
		{
			private static void Postfix(Character c, Dictionary<Character, HudData> ___m_huds)
			{
				//IL_0049: 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)
				Player val = (Player)(object)((c is Player) ? c : null);
				if (val != null)
				{
					((Graphic)((Component)___m_huds[c].m_gui.transform.Find("Name")).GetComponent<TextMeshProUGUI>()).color = ((Groups.ownGroup != null && Groups.ownGroup.playerStates.ContainsKey(PlayerReference.fromPlayer(val))) ? Groups.friendlyNameColor.Value : defaultColor);
				}
			}
		}

		[HarmonyPatch(typeof(Chat), "SendPing")]
		private static class RestrictPingsToGroupOnModifierHeld
		{
			[UsedImplicitly]
			private static bool RestrictBroadcast(ZRoutedRpc instance, long targetPeerId, string methodName, params object[] parameters)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				if (Groups.ownGroup != null && targetPeerId == ZRoutedRpc.Everybody)
				{
					KeyboardShortcut value = Groups.groupPingHotkey.Value;
					if (((KeyboardShortcut)(ref value)).IsPressed())
					{
						foreach (PlayerReference key in Groups.ownGroup.playerStates.Keys)
						{
							instance.InvokeRoutedRPC(key.peerId, "Groups MapPing", parameters);
						}
						return true;
					}
				}
				return false;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructionsEnumerable, ILGenerator ilg)
			{
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Expected O, but got Unknown
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Expected O, but got Unknown
				MethodInfo routedRPC = AccessTools.DeclaredMethod(typeof(ZRoutedRpc), "InvokeRoutedRPC", new Type[3]
				{
					typeof(long),
					typeof(string),
					typeof(object[])
				}, (Type[])null);
				MethodInfo routedRPCInstance = AccessTools.DeclaredPropertyGetter(typeof(ZRoutedRpc), "instance");
				List<CodeInstruction> list = instructionsEnumerable.ToList();
				int num = list.FindIndex((CodeInstruction i) => CodeInstructionExtensions.Calls(i, routedRPC));
				int num2 = list.FindLastIndex(num, (CodeInstruction i) => CodeInstructionExtensions.Calls(i, routedRPCInstance));
				Label label = ilg.DefineLabel();
				list[num + 1].labels.Add(label);
				list.InsertRange(num2, list.Skip(num2).Take(num - num2).Concat((IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(RestrictPingsToGroupOnModifierHeld), "RestrictBroadcast", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Brtrue, (object)label)
				})
					.ToArray());
				return list;
			}
		}

		[HarmonyPatch(typeof(Chat), "RPC_ChatMessage")]
		private class ClearGroupPing
		{
			public static void Prefix(Chat __instance, long sender)
			{
				WorldTextInstance val = __instance.FindExistingWorldText(sender);
				if (val == null || !groupPingTexts.Remove(val) || !Object.op_Implicit((Object)(object)Minimap.instance))
				{
					return;
				}
				for (int i = 0; i < Minimap.instance.m_tempShouts.Count; i++)
				{
					PinData val2 = Minimap.instance.m_pingPins[i];
					if (Minimap.instance.m_tempShouts[i] == val)
					{
						val2.m_icon = Minimap.instance.GetSprite((PinType)12);
						if (Object.op_Implicit((Object)(object)val2.m_iconElement))
						{
							val2.m_iconElement.sprite = val2.m_icon;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdatePlayerPins")]
		private class ChangeGroupMemberPin
		{
			private static void Postfix(Minimap __instance)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < __instance.m_tempPlayerInfo.Count; i++)
				{
					PinData val = __instance.m_playerPins[i];
					PlayerInfo val2 = __instance.m_tempPlayerInfo[i];
					if (val.m_name == val2.m_name)
					{
						bool flag = false;
						Group? ownGroup = Groups.ownGroup;
						if (ownGroup != null && ownGroup.playerStates.ContainsKey(PlayerReference.fromPlayerInfo(val2)))
						{
							val.m_icon = groupMapPlayerIcon;
							flag = true;
						}
						else if ((Object)(object)val.m_icon == (Object)(object)groupMapPlayerIcon)
						{
							val.m_icon = __instance.GetSprite((PinType)10);
							flag = true;
						}
						if (flag && Object.op_Implicit((Object)(object)val.m_iconElement))
						{
							val.m_iconElement.sprite = val.m_icon;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdatePingPins")]
		private class ChangeGroupMemberPing
		{
			private static void Postfix(Minimap __instance)
			{
				for (int i = 0; i < __instance.m_tempShouts.Count; i++)
				{
					PinData val = __instance.m_pingPins[i];
					WorldTextInstance key = __instance.m_tempShouts[i];
					if (groupPingTexts.TryGetValue(key, out object _))
					{
						val.m_icon = groupMapPingIcon;
						if (Object.op_Implicit((Object)(object)val.m_iconElement))
						{
							val.m_iconElement.sprite = val.m_icon;
						}
					}
				}
			}
		}

		private static Sprite groupMapPlayerIcon = null;

		private static Sprite groupMapPingIcon = null;

		private static readonly ConditionalWeakTable<WorldTextInstance, object> groupPingTexts = new ConditionalWeakTable<WorldTextInstance, object>();

		private static readonly Color defaultColor = new Color(1f, 61f / 85f, 49f / 136f);

		public static void Init()
		{
			groupMapPlayerIcon = Helper.loadSprite("groupPlayerIcon.png", 64, 64);
			groupMapPingIcon = Helper.loadSprite("groupMapPingIcon.png", 64, 64);
			UpdateMapPinColor();
		}

		public static void onMapPing(long senderId, Vector3 position, int type, UserInfo name, string text)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Chat.instance.RPC_ChatMessage(senderId, position, type, name, text);
			WorldTextInstance val = Chat.instance.FindExistingWorldText(senderId);
			((Graphic)val.m_textMeshField).color = Groups.friendlyNameColor.Value;
			groupPingTexts.Add(val, Array.Empty<object>());
		}

		public static void UpdateMapPinColor()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			Color[] pixels = Helper.loadTexture("groupPlayerIcon.png").GetPixels();
			for (int i = 0; i < pixels.Length; i++)
			{
				if ((double)pixels[i].r > 0.5 && (double)pixels[i].b < 0.5 && (double)pixels[i].g < 0.5)
				{
					pixels[i] = Groups.friendlyNameColor.Value;
				}
			}
			groupMapPlayerIcon.texture.SetPixels(pixels);
			groupMapPlayerIcon.texture.Apply();
			pixels = Helper.loadTexture("groupMapPingIcon.png").GetPixels();
			for (int j = 0; j < pixels.Length; j++)
			{
				if ((double)pixels[j].r > 0.5 && (double)pixels[j].b < 0.5 && (double)pixels[j].g < 0.5)
				{
					pixels[j].b = Groups.friendlyNameColor.Value.b;
					pixels[j].g = Groups.friendlyNameColor.Value.g;
					pixels[j].r = Groups.friendlyNameColor.Value.r;
				}
			}
			groupMapPingIcon.texture.SetPixels(pixels);
			groupMapPingIcon.texture.Apply();
		}
	}
	public static class RPC
	{
		[HarmonyPatch(typeof(Game), "Start")]
		private class AddRPCs
		{
			private static void Postfix()
			{
				ZRoutedRpc.instance.Register<string>("Groups AddMessage", (Action<long, string>)delegate(long _, string message)
				{
					((Terminal)Chat.instance).AddString(message);
					Chat.instance.m_hideTimer = 0f;
				});
				ZRoutedRpc.instance.Register<UserInfo, string>("Groups ChatMessage", (Action<long, UserInfo, string>)onChatMessageReceived);
				ZRoutedRpc.instance.Register<string>("Groups InvitePlayer", (Action<long, string>)onInvitationReceived);
				ZRoutedRpc.instance.Register("Groups ForcedInvitation", (Action<long>)onForcedInvitationReceived);
				ZRoutedRpc.instance.Register<ZPackage>("Groups AcceptInvitation", (Action<long, ZPackage>)onInvitationAccepted);
				ZRoutedRpc.instance.Register<ZPackage>("Groups AcceptInvitationResponse", (Action<long, ZPackage>)onInvitationAcceptedResponse);
				ZRoutedRpc.instance.Register<string, string>("Groups UpdateGroup", (Action<long, string, string>)onUpdateGroup);
				ZRoutedRpc.instance.Register<string, ZPackage>("Groups AddMember", (Action<long, string, ZPackage>)onNewGroupMember);
				ZRoutedRpc.instance.Register<float, float>("Groups UpdateHealth", (Action<long, float, float>)Interface.onUpdateHealth);
				ZRoutedRpc.instance.Register<Vector3>("Groups UpdatePosition", (Action<long, Vector3>)onUpdatePosition);
				ZRoutedRpc.instance.Register<Vector3, int, UserInfo, string>("Groups MapPing", (Method<Vector3, int, UserInfo, string>)Map.onMapPing);
			}
		}

		[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
		private class SetCharacterId
		{
			private static void Postfix(Player __instance)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				ZNet.instance.m_characterID = ((Character)__instance).GetZDOID();
			}
		}

		[HarmonyPatch]
		private class RemoveFromGroupOnLogoutAndPreservePosition
		{
			private static IEnumerable<MethodInfo> TargetMethods()
			{
				return new MethodInfo[2]
				{
					AccessTools.DeclaredMethod(typeof(ZNet), "RPC_PlayerList", (Type[])null, (Type[])null),
					AccessTools.DeclaredMethod(typeof(ZNet), "UpdatePlayerList", (Type[])null, (Type[])null)
				};
			}

			private static void Prefix(ZNet __instance, out Dictionary<long, Vector3> __state)
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: 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_0050: 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_0059: Unknown result type (might be due to invalid IL or missing references)
				__state = new Dictionary<long, Vector3>();
				if (Groups.ownGroup == null)
				{
					return;
				}
				foreach (PlayerInfo item in __instance.m_players.Where((PlayerInfo p) => Groups.ownGroup.playerStates.ContainsKey(PlayerReference.fromPlayerId(((ZDOID)(ref p.m_characterID)).UserID))))
				{
					Dictionary<long, Vector3> obj = __state;
					ZDOID characterID = item.m_characterID;
					obj[((ZDOID)(ref characterID)).UserID] = item.m_position;
				}
			}

			private static void Postfix(ZNet __instance, Dictionary<long, Vector3> __state)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: 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_002e: 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)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: 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_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: 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_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: 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_0167: Unknown result type (might be due to invalid IL or missing references)
				ZNet __instance2 = __instance;
				foreach (PlayerInfo player2 in __instance2.m_players)
				{
					if (player2.m_characterID != ZDOID.None)
					{
						characterIdCache[player2.m_userInfo.m_id] = PlayerReference.fromPlayerInfo(player2);
					}
				}
				PlatformUserID[] array = characterIdCache.Keys.Where((PlatformUserID host) => __instance2.m_players.All((PlayerInfo p) => p.m_userInfo.m_id != host)).ToArray();
				foreach (PlatformUserID key in array)
				{
					characterIdCache.Remove(key);
				}
				ChatCommands.UpdateAutoCompletion();
				if (Groups.ownGroup == null)
				{
					return;
				}
				List<PlayerInfo> list = new List<PlayerInfo>();
				foreach (PlayerInfo player3 in __instance2.m_players)
				{
					PlayerInfo val = player3;
					characterIdCache.TryGetValue(val.m_userInfo.m_id, out var value);
					if (Groups.ownGroup.playerStates.ContainsKey(value) && value.peerId != ZDOMan.GetSessionID())
					{
						ZDOID characterID = player3.m_characterID;
						if (__state.TryGetValue(((ZDOID)(ref characterID)).UserID, out var value2) && !player3.m_publicPosition)
						{
							val.m_position = value2;
						}
						val.m_publicPosition = true;
					}
					list.Add(val);
				}
				__instance2.m_players = list;
				if (Groups.ownGroup.leader.peerId != ZDOMan.GetSessionID())
				{
					if (characterIdCache.ContainsValue(Groups.ownGroup.leader) || Groups.ownGroup.playerStates.Keys.OrderBy((PlayerReference p) => p.peerId).First(((IEnumerable<PlayerReference>)characterIdCache.Values).Contains<PlayerReference>).peerId != ZDOMan.GetSessionID())
					{
						return;
					}
					Groups.ownGroup.PromoteMember(PlayerReference.fromPlayerId(ZDOMan.GetSessionID()));
				}
				PlayerReference[] array2 = Groups.ownGroup.playerStates.Keys.Except(characterIdCache.Values).ToArray();
				foreach (PlayerReference player in array2)
				{
					Groups.ownGroup.RemoveMember(player, self: true);
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static PopupButtonCallback <0>__Pop;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<Player, bool> <>9__8_1;

			public static PopupButtonCallback <>9__8_2;

			public static Func<PlayerReference, bool> <>9__10_1;

			internal bool <onInvitationReceived>b__8_1(Player p)
			{
				//IL_004d: 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)p != (Object)(object)Player.m_localPlayer && ((Character)p).IsPVPEnabled())
				{
					if (Groups.friendlyFire.Value != Groups.Toggle.On)
					{
						Group? ownGroup = Groups.ownGroup;
						if (ownGroup != null && ownGroup.playerStates.ContainsKey(PlayerReference.fromPlayer(p)))
						{
							goto IL_006a;
						}
					}
					return Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)p).transform.position) < 30f;
				}
				goto IL_006a;
				IL_006a:
				return false;
			}

			internal void <onInvitationReceived>b__8_2()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Expected O, but got Unknown
				Groups.ownGroup?.Leave();
				UnifiedPopup.Pop();
				ZPackage val = new ZPackage();
				Group.PlayerState.fromLocal().write(val);
				ZRoutedRpc.instance.InvokeRoutedRPC(pendingInvitationSenderId, "Groups AcceptInvitation", new object[1] { val });
			}

			internal bool <onInvitationAccepted>b__10_1(PlayerReference p)
			{
				return p != Groups.ownGroup.leader;
			}
		}

		private static long pendingInvitationSenderId;

		private static readonly Dictionary<PlatformUserID, PlayerReference> characterIdCache = new Dictionary<PlatformUserID, PlayerReference>();

		private static void onUpdateGroup(long senderId, string playerReference, string action)
		{
			if (Groups.ownGroup == null)
			{
				return;
			}
			if (!(action == "Member Removed"))
			{
				if (action == "Member Promoted")
				{
					Groups.ownGroup.leader = PlayerReference.fromString(playerReference);
					ChatCommands.UpdateAutoCompletion();
				}
				return;
			}
			PlayerReference playerReference2 = PlayerReference.fromString(playerReference);
			if (playerReference2 == PlayerReference.fromPlayer(Player.m_localPlayer))
			{
				API.InvokeGroupLeft();
				ChatCommands.ToggleGroupsChat(active: false);
				Groups.ownGroup = null;
			}
			else
			{
				Groups.ownGroup.playerStates.Remove(playerReference2);
				API.InvokeMemberLeft(playerReference2);
			}
			ChatCommands.UpdateAutoCompletion();
		}

		private static void onNewGroupMember(long senderId, string playerReference, ZPackage playerState)
		{
			if (Groups.ownGroup != null)
			{
				PlayerReference playerReference2 = PlayerReference.fromString(playerReference);
				Groups.ownGroup.playerStates.Add(playerReference2, Group.PlayerState.read(playerState));
				API.InvokeMemberJoined(playerReference2);
				ChatCommands.UpdateAutoCompletion();
			}
		}

		private static void onChatMessageReceived(long senderId, UserInfo name, string message)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			((Terminal)Chat.instance).AddString("<color=orange>" + name.Name + "</color>: <color=#" + ColorUtility.ToHtmlStringRGBA(Groups.groupChatColor.Value) + ">" + message + "</color>");
			Chat.instance.m_hideTimer = 0f;
			ZDOID characterID = ((IEnumerable<PlayerInfo>)ZNet.instance.m_players).FirstOrDefault((Func<PlayerInfo, bool>)((PlayerInfo p) => ((ZDOID)(ref p.m_characterID)).UserID == senderId)).m_characterID;
			if (!(characterID != ZDOID.None))
			{
				return;
			}
			GameObject val = ZNetScene.instance.FindInstance(characterID);
			if (val != null)
			{
				Player component = val.GetComponent<Player>();
				if (component != null && (!Object.op_Implicit((Object)(object)Minimap.instance) || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || (int)Minimap.instance.m_mode != 0 || !(Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Character)component).GetHeadPoint()) > Minimap.instance.m_nomapPingDistance)))
				{
					Chat.instance.AddInworldText(val, senderId, ((Character)component).GetHeadPoint(), (Type)1, name, "<color=#" + ColorUtility.ToHtmlStringRGBA(Groups.groupChatColor.Value) + ">" + message + "</color>");
				}
			}
		}

		private static void onInvitationReceived(long senderId, string name)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			string name2 = name;
			if (Groups.ignoreList.Value.Split(new char[1] { ',' }).Any((string s) => string.Compare(s.Trim(), name2, StringComparison.OrdinalIgnoreCase) == 0) || Groups.blockInvitations.Value == Groups.BlockInvitation.Always)
			{
				return;
			}
			if (Groups.blockInvitations.Value == Groups.BlockInvitation.PvP)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null && ((Character)localPlayer).IsPVPEnabled())
				{
					return;
				}
			}
			if (Groups.blockInvitations.Value == Groups.BlockInvitation.Enemy)
			{
				Player localPlayer2 = Player.m_localPlayer;
				if (localPlayer2 != null && ((Character)localPlayer2).IsPVPEnabled() && Player.s_players.Any(delegate(Player p)
				{
					//IL_004d: 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)p != (Object)(object)Player.m_localPlayer && ((Character)p).IsPVPEnabled())
					{
						if (Groups.friendlyFire.Value != Groups.Toggle.On)
						{
							Group? ownGroup = Groups.ownGroup;
							if (ownGroup != null && ownGroup.playerStates.ContainsKey(PlayerReference.fromPlayer(p)))
							{
								goto IL_006a;
							}
						}
						return Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)p).transform.position) < 30f;
					}
					goto IL_006a;
					IL_006a:
					return false;
				}))
				{
					return;
				}
			}
			pendingInvitationSenderId = senderId;
			string text = Localization.instance.Localize("$groups_invitation_received_description", new string[1] { name2 });
			object obj = <>c.<>9__8_2;
			if (obj == null)
			{
				PopupButtonCallback val = delegate
				{
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_001b: Expected O, but got Unknown
					Groups.ownGroup?.Leave();
					UnifiedPopup.Pop();
					ZPackage val3 = new ZPackage();
					Group.PlayerState.fromLocal().write(val3);
					ZRoutedRpc.instance.InvokeRoutedRPC(pendingInvitationSenderId, "Groups AcceptInvitation", new object[1] { val3 });
				};
				<>c.<>9__8_2 = val;
				obj = (object)val;
			}
			object obj2 = <>O.<0>__Pop;
			if (obj2 == null)
			{
				PopupButtonCallback val2 = UnifiedPopup.Pop;
				<>O.<0>__Pop = val2;
				obj2 = (object)val2;
			}
			UnifiedPopup.Push((PopupBase)new YesNoPopup("$groups_invitation_received_title", text, (PopupButtonCallback)obj, (PopupButtonCallback)obj2, true));
			API.InvokeInvitationReceived(PlayerReference.fromPlayerId(senderId), UnifiedPopup.instance.popupUIParent);
		}

		private static void onForcedInvitationReceived(long senderId)
		{
			API.JoinGroup(PlayerReference.fromPlayerId(senderId));
		}

		private static void onInvitationAccepted(long senderId, ZPackage playerState)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			ZPackage group = new ZPackage();
			if (Groups.ownGroup != null && Groups.ownGroup.AddMember(PlayerReference.fromPlayerId(senderId), Group.PlayerState.read(playerState)))
			{
				AddPlayer(Groups.ownGroup.leader);
				group.Write(Groups.ownGroup.playerStates.Count - 1);
				foreach (PlayerReference item in Groups.ownGroup.playerStates.Keys.Where((PlayerReference p) => p != Groups.ownGroup.leader))
				{
					AddPlayer(item);
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(senderId, "Groups AcceptInvitationResponse", new object[1] { group });
			}
			else
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(senderId, "Groups AcceptInvitationResponse", new object[1] { group });
			}
			void AddPlayer(PlayerReference player)
			{
				group.Write(player.ToString());
				Groups.ownGroup.playerStates[player].write(group);
			}
		}

		private static void onInvitationAcceptedResponse(long senderId, ZPackage group)
		{
			if (group.Size() == 0)
			{
				((Terminal)Chat.instance).AddString(Localization.instance.Localize("$groups_joining_failed"));
				return;
			}
			Group group2 = new Group(PlayerReference.fromString(group.ReadString()), Group.PlayerState.read(group));
			int num = group.ReadInt();
			for (int i = 0; i < num; i++)
			{
				group2.playerStates.Add(PlayerReference.fromString(group.ReadString()), Group.PlayerState.read(group));
			}
			Groups.ownGroup = group2;
			API.InvokeGroupJoined();
			ChatCommands.UpdateAutoCompletion();
		}

		private static void onUpdatePosition(long senderId, Vector3 position)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerInfo> list = new List<PlayerInfo>();
			foreach (PlayerInfo player in ZNet.instance.m_players)
			{
				PlayerInfo current = player;
				if (((ZDOID)(ref current.m_characterID)).UserID == senderId)
				{
					current.m_position = position;
				}
				list.Add(current);
			}
			ZNet.instance.m_players = list;
		}
	}
}
namespace ServerSync
{
	[PublicAPI]
	internal abstract class OwnConfigEntryBase
	{
		public object? LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	internal class SyncedConfigEntry<T> : OwnConfigEntryBase
	{
		public r