Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Groups v1.2.10
Groups.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
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