Decompiled source of PortalGhostFix v1.0.0

plugins/PortalGhostFix/PortalObserverFix.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("sfantul.portalobserverfix", "Portal Ghost Fix", "1.0.0")]
public sealed class PortalObserverFix : BaseUnityPlugin
{
	private readonly Dictionary<ZDOID, Vector3> positions = new Dictionary<ZDOID, Vector3>();

	private float next;

	private ZDOMan manager;

	private static readonly MethodInfo rosterMethod = typeof(ZNet).GetMethod("GetPlayerList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

	private void Awake()
	{
		if (rosterMethod == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Unsupported game: player roster unavailable. Fix disabled.");
			((Behaviour)this).enabled = false;
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Portal Ghost Fix 1.0.0 ready. Large player moves queue existing network records for observers; no movement, combat or save changes.");
		}
	}

	internal static bool IsJump(Vector3 before, Vector3 after)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = after - before;
		return ((Vector3)(ref val)).sqrMagnitude >= 4096f;
	}

	private void Update()
	{
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		if (Time.realtimeSinceStartup < next)
		{
			return;
		}
		next = Time.realtimeSinceStartup + 0.25f;
		if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null)
		{
			positions.Clear();
			manager = null;
			return;
		}
		if (manager != ZDOMan.instance)
		{
			positions.Clear();
			manager = ZDOMan.instance;
		}
		try
		{
			if (!(rosterMethod.Invoke(ZNet.instance, null) is IEnumerable enumerable))
			{
				return;
			}
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			foreach (object item in enumerable)
			{
				FieldInfo field = item.GetType().GetField("m_characterID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					throw new MissingFieldException("PlayerInfo.m_characterID");
				}
				ZDOID val = (ZDOID)field.GetValue(item);
				if (val == ZDOID.None)
				{
					continue;
				}
				hashSet.Add(val);
				ZDO zDO = manager.GetZDO(val);
				if (zDO == null)
				{
					positions.Remove(val);
					continue;
				}
				Vector3 position = zDO.GetPosition();
				if (positions.TryGetValue(val, out var value) && IsJump(value, position))
				{
					manager.ForceSendZDO(val);
					((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat(DateTime.UtcNow.ToString("o"), " Queued observer update character=", val, " distance=", Vector3.Distance(value, position).ToString("F1"), "m"));
				}
				positions[val] = position;
			}
			List<ZDOID> list = new List<ZDOID>();
			foreach (ZDOID key in positions.Keys)
			{
				if (!hashSet.Contains(key))
				{
					list.Add(key);
				}
			}
			foreach (ZDOID item2 in list)
			{
				positions.Remove(item2);
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Observer fix disabled after error: " + ex));
			((Behaviour)this).enabled = false;
		}
	}
}