Decompiled source of ServerSideMap PoV v1.0.2

plugins/ServerSideMap_PoV.dll

Decompiled 3 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Splatform;
using TMPro;
using UnityEngine;

[assembly: AssemblyTitle("ServerSideMap")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServerSideMap")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("38A5EB8E-7BF4-43B7-9806-9C0DD82AB865")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ServerSideMap;

public static class CommandsPinUpsync
{
	[HarmonyPatch(typeof(Chat), "InputText")]
	private class ChatPatchInputText
	{
		private static bool Prefix(Chat __instance, TMP_InputField ___m_input)
		{
			string text = ___m_input.text;
			if (text.ToLower().Equals("/convertpins ignorelocaldupes"))
			{
				UtilityPin.UploadAllPins(removeDupes: true);
				return false;
			}
			if (text.ToLower().Equals("/convertpins"))
			{
				UtilityPin.UploadAllPins();
				return false;
			}
			if (text.ToLower().Equals("/deletealllocalpins"))
			{
				UtilityPin.DeleteLocalPins();
				return false;
			}
			if (text.ToLower().Equals("/deleteallsharedpins confirm"))
			{
				UtilityPin.DeleteAllSharedPins();
				return false;
			}
			if (text.ToLower().Equals("/deleteallsharedpins"))
			{
				Utility.Message("This deletes EVERY shared pin for everyone. Type /deleteallsharedpins confirm");
				return false;
			}
			if (text.ToLower().Equals("/downloadpins"))
			{
				UtilityPin.DownloadPins();
				return false;
			}
			return true;
		}
	}
}
public static class ExplorationDatabase
{
	[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
	{
		typeof(Vector3),
		typeof(float)
	})]
	private class MinimapPatchExploreInterval
	{
		private static void Postfix(Minimap __instance)
		{
			if (_dirty)
			{
				object value = Traverse.Create((object)__instance).Field("m_fogTexture").GetValue();
				Texture2D val = (Texture2D)((value is Texture2D) ? value : null);
				val.Apply();
				_dirty = false;
			}
		}
	}

	private static bool _dirty;

	public static bool[] Explored;

	public const int MapSize = 2048;

	public const int MapSizeSquared = 4194304;

	private static List<PinData> ServerPins = new List<PinData>();

	public static List<PinData> ClientPins = new List<PinData>();

	public static ZPackage Default()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(4);
		val.Write(2048);
		for (int i = 0; i < 4194304; i++)
		{
			val.Write(false);
		}
		val.Write(0);
		val.SetPos(0);
		return val;
	}

	public static ZPackage PackPins(List<PinData> pins)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0034: 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_004a: Expected I4, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(pins.Count);
		foreach (PinData pin in pins)
		{
			val.Write(pin.Name);
			val.Write(pin.Pos);
			val.Write((int)pin.Type);
			val.Write(pin.Checked);
			val.Write(pin.Icon ?? "");
		}
		val.SetPos(0);
		Utility.Log("Packing pins: " + pins.Count);
		return val;
	}

	public static List<PinData> UnpackPins(ZPackage z)
	{
		//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)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		List<PinData> list = new List<PinData>();
		int num = z.ReadInt();
		for (int i = 0; i < num; i++)
		{
			PinData pinData = new PinData();
			pinData.Name = z.ReadString();
			pinData.Pos = z.ReadVector3();
			pinData.Type = (PinType)z.ReadInt();
			pinData.Checked = z.ReadBool();
			pinData.Icon = z.ReadString();
			PinData item = pinData;
			list.Add(item);
		}
		return list;
	}

	public static ZPackage PackPin(PinData pin, bool skipSetPos = false)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0014: 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_002a: Expected I4, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(pin.Name);
		val.Write(pin.Pos);
		val.Write((int)pin.Type);
		val.Write(pin.Checked);
		val.Write(pin.Icon ?? "");
		if (!skipSetPos)
		{
			val.SetPos(0);
		}
		return val;
	}

	public static PinData UnpackPin(ZPackage z)
	{
		//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)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		PinData pinData = new PinData();
		pinData.Name = z.ReadString();
		pinData.Pos = z.ReadVector3();
		pinData.Type = (PinType)z.ReadInt();
		pinData.Checked = z.ReadBool();
		pinData.Icon = z.ReadString();
		return pinData;
	}

	public static List<PinData> GetPins()
	{
		return ServerPins;
	}

	public static void AddPin(PinData pin)
	{
		ServerPins.Add(pin);
	}

	public static void RemovePinEqual(PinData needle)
	{
		foreach (PinData item in ServerPins.ToList())
		{
			if (UtilityPin.ArePinsEqual(item, needle))
			{
				ServerPins.Remove(item);
			}
		}
	}

	public static void SetPinState(PinData needle, bool state)
	{
		foreach (PinData item in ServerPins.ToList())
		{
			if (UtilityPin.ArePinsEqual(item, needle))
			{
				item.Checked = state;
			}
		}
	}

	public static void SetMapData(ZPackage mapData)
	{
		//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_0077: Unknown result type (might be due to invalid IL or missing references)
		ServerPins.Clear();
		int num = mapData.ReadInt();
		int num2 = mapData.ReadInt();
		bool[] array = new bool[num2 * num2];
		for (int i = 0; i < num2 * num2; i++)
		{
			array[i] = mapData.ReadBool();
		}
		int num3 = mapData.ReadInt();
		for (int j = 0; j < num3; j++)
		{
			PinData pinData = new PinData();
			pinData.Name = mapData.ReadString();
			pinData.Pos = mapData.ReadVector3();
			pinData.Type = (PinType)mapData.ReadInt();
			pinData.Checked = mapData.ReadBool();
			PinData pinData2 = pinData;
			if (num >= 4)
			{
				pinData2.Icon = mapData.ReadString();
			}
			ServerPins.Add(pinData2);
		}
		Explored = array;
	}

	public static ZPackage GetMapData()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected I4, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(4);
		val.Write(2048);
		bool[] explored = Explored;
		foreach (bool flag in explored)
		{
			val.Write(flag);
		}
		val.Write(ServerPins.Count);
		Utility.Log("Map saved. Pin Count: " + ServerPins.Count);
		foreach (PinData serverPin in ServerPins)
		{
			val.Write(serverPin.Name);
			val.Write(serverPin.Pos);
			val.Write((int)serverPin.Type);
			val.Write(serverPin.Checked);
			val.Write(serverPin.Icon ?? "");
		}
		return val;
	}

	public static void SetExplored(int x, int y)
	{
		Explored[y * 2048 + x] = true;
	}

	public static bool GetExplored(int x, int y)
	{
		return Explored[y * 2048 + x];
	}

	public static bool GetExplored(int idx)
	{
		return Explored[idx];
	}

	public static bool[] GetExplorationArray()
	{
		return Explored;
	}

	public static void MergeExplorationArray(bool[] arr, int startIndex, int size)
	{
		for (int i = 0; i < size; i++)
		{
			Explored[startIndex + i] = arr[i] || Explored[startIndex + i];
		}
	}

	public static ZPackage PackBoolArray(bool[] arr, int chunkId, int startIndex, int size)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(chunkId);
		byte b = 0;
		int num = 0;
		for (int i = startIndex; i < startIndex + size; i++)
		{
			if (arr[i])
			{
				byte b2 = (byte)(1 << num);
				b |= b2;
			}
			num++;
			if (num >= 8)
			{
				val.Write(b);
				b = 0;
				num = 0;
			}
		}
		if (num > 0)
		{
			val.Write(b);
		}
		return val;
	}

	public static bool[] UnpackBoolArray(ZPackage z, int length)
	{
		bool[] array = new bool[length];
		for (int i = 0; i < length; i += 8)
		{
			byte b = z.ReadByte();
			array[i] = (b & 1) != 0;
			array[i + 1] = (b & 2) != 0;
			array[i + 2] = (b & 4) != 0;
			array[i + 3] = (b & 8) != 0;
			array[i + 4] = (b & 0x10) != 0;
			array[i + 5] = (b & 0x20) != 0;
			array[i + 6] = (b & 0x40) != 0;
			array[i + 7] = (b & 0x80) != 0;
		}
		return array;
	}

	public static void OnReceiveMapData(ZRpc client, ZPackage mapData)
	{
		mapData.SetPos(0);
		int x = mapData.ReadInt();
		int y = mapData.ReadInt();
		object value = Traverse.Create(typeof(Minimap)).Field("s_instance").GetValue();
		Minimap instance = (Minimap)((value is Minimap) ? value : null);
		_dirty = _Minimap.Explore(instance, x, y) || _dirty;
	}
}
public class PinData
{
	public string Name;

	public PinType Type;

	public Vector3 Pos;

	public bool Checked;

	public string Icon = "";
}
public static class ExplorationMapSync
{
	[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
	{
		typeof(int),
		typeof(int)
	})]
	private class MinimapPatchExplore
	{
		private static void Postfix(int x, int y, bool __result)
		{
			if (__result && !_blockExplore && Store.IsSharingMap())
			{
				if (_ZNet.IsServer(_ZNet._instance))
				{
					OnClientExplore(null, x, y);
					return;
				}
				object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
				ZNet instance = (ZNet)((value is ZNet) ? value : null);
				ZRpc serverRPC = _ZNet.GetServerRPC(instance);
				serverRPC.Invoke("SSMPoV_OnClientExplore", new object[2] { x, y });
			}
		}
	}

	[HarmonyPatch(typeof(Minimap), "SetMapData", new Type[] { typeof(byte[]) })]
	private class MinimapPatchSetMapData
	{
		private static void Prefix()
		{
			_blockExplore = true;
		}

		private static void Postfix(Minimap __instance)
		{
			_blockExplore = false;
		}
	}

	private static bool _blockExplore = false;

	public static void OnClientExplore(ZRpc client, int x, int y)
	{
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		if (!Store.IsSharingMap())
		{
			return;
		}
		ExplorationDatabase.SetExplored(x, y);
		object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
		ZNet val = (ZNet)((value is ZNet) ? value : null);
		List<ZNetPeer> list = Traverse.Create((object)val).Field("m_peers").GetValue() as List<ZNetPeer>;
		foreach (ZNetPeer item in list)
		{
			if (item.IsReady() && item.m_rpc != client)
			{
				ZPackage val2 = new ZPackage();
				val2.Write(x);
				val2.Write(y);
				item.m_rpc.Invoke("SSMPoV_OnReceiveMapData", new object[1] { val2 });
			}
		}
		ZPackage val3 = new ZPackage();
		val3.Write(x);
		val3.Write(y);
		ExplorationDatabase.OnReceiveMapData(null, val3);
	}
}
public static class Hotkeys
{
	[HarmonyPatch(typeof(Player), "Update")]
	private class PlayerInputPatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (Store.HasKeyConvertAll() && Input.GetKeyDown(Store.GetKeyConvertAll()))
			{
				Utility.Log("Hotkey: GetKeyConvertAll");
				UtilityPin.UploadAllPins();
			}
			if (Store.HasKeyConvertIgnoreDupes() && Input.GetKeyDown(Store.GetKeyConvertIgnoreDupes()))
			{
				Utility.Log("Hotkey: GetKeyConvertIgnoreDupes");
				UtilityPin.UploadAllPins(removeDupes: true);
			}
		}
	}
}
public class InitialMapSync
{
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	private class ZnetPatchRPC_PeerInfo
	{
		private static void Postfix(ZRpc rpc, ZNet __instance)
		{
			if (Store.IsSharingMap() && __instance.IsServer())
			{
				SendChunkToClient(rpc, 0);
			}
		}
	}

	[HarmonyPatch(typeof(Minimap), "SetMapData", new Type[] { typeof(byte[]) })]
	private class MinimapPatchSetMapData
	{
		private static void Postfix(Minimap __instance)
		{
			if (Store.IsSharingMap() && _ZNet.IsServer(_ZNet._instance))
			{
				SendChunkToClient(null, 0);
			}
		}
	}

	private static int CHUNKS = 64;

	public static void OnReceiveMapDataInitial(ZRpc client, ZPackage mapData)
	{
		if (!Store.IsSharingMap())
		{
			return;
		}
		mapData.SetPos(0);
		int num = mapData.ReadInt();
		bool[] array = ExplorationDatabase.UnpackBoolArray(mapData, 4194304 / CHUNKS);
		int num2 = num * (4194304 / CHUNKS);
		for (int i = 0; i < array.Length; i++)
		{
			if (array[i])
			{
				_Minimap.Explore(_Minimap._instance, (num2 + i) % 2048, (num2 + i) / 2048);
			}
		}
		object value = Traverse.Create((object)_Minimap._instance).Field("m_fogTexture").GetValue();
		Texture2D val = (Texture2D)((value is Texture2D) ? value : null);
		val.Apply();
		((MonoBehaviour)_ZNet._instance).StartCoroutine(SendChunkToServer(client, num));
	}

	public static void OnClientInitialData(ZRpc client, ZPackage mapData)
	{
		if (Store.IsSharingMap())
		{
			mapData.SetPos(0);
			int num = mapData.ReadInt();
			int startIndex = num * (4194304 / CHUNKS);
			int num2 = 4194304 / CHUNKS;
			ExplorationDatabase.MergeExplorationArray(ExplorationDatabase.UnpackBoolArray(mapData, num2), startIndex, num2);
			SendChunkToClient(client, num + 1);
		}
	}

	private static void SendChunkToClient(ZRpc client, int chunk)
	{
		if (chunk < CHUNKS)
		{
			int size = 4194304 / CHUNKS;
			int startIndex = chunk * (4194304 / CHUNKS);
			ZPackage val = ExplorationDatabase.PackBoolArray(ExplorationDatabase.GetExplorationArray(), chunk, startIndex, size);
			if (client == null)
			{
				OnReceiveMapDataInitial(null, val);
				return;
			}
			client.Invoke("SSMPoV_OnReceiveMapDataInitial", new object[1] { val });
		}
	}

	private static IEnumerator SendChunkToServer(ZRpc client, int chunk)
	{
		if (chunk >= CHUNKS)
		{
			yield break;
		}
		int size = 4194304 / CHUNKS;
		int startIndex = chunk * (4194304 / CHUNKS);
		BitArray explored = Traverse.Create((object)_Minimap._instance).Field("m_explored").GetValue() as BitArray;
		bool[] legacy_bool_array = new bool[explored.Length];
		explored.CopyTo(legacy_bool_array, 0);
		ZPackage z = ExplorationDatabase.PackBoolArray(legacy_bool_array, chunk, startIndex, size);
		if (client == null)
		{
			OnClientInitialData(null, z);
			yield break;
		}
		yield return (object)new WaitUntil((Func<bool>)(() => _ZNet.GetServerRPC(_ZNet._instance) != null));
		ZRpc server = _ZNet.GetServerRPC(_ZNet._instance);
		server.Invoke("SSMPoV_OnClientInitialData", new object[1] { z });
	}
}
public class InitialPinSync
{
	[HarmonyPatch(typeof(Minimap), "ClearPins")]
	private class MinimapPatchClearPins
	{
		private static void Postfix(Minimap __instance)
		{
			ClientAppendPins();
		}
	}

	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	private class ZNetPatchShutdown
	{
		private static void Postfix(ZNet __instance)
		{
			ExplorationDatabase.ClientPins.Clear();
		}
	}

	[HarmonyPatch(typeof(Minimap), "SetMapData", new Type[] { typeof(byte[]) })]
	private class MinimapPatchSetMapData
	{
		private static void Postfix(Minimap __instance)
		{
			if (_ZNet.IsServer(_ZNet._instance))
			{
				SendPinsToClient(null);
			}
		}
	}

	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	private class ZnetPatchRPC_PeerInfo
	{
		private static void Postfix(ZRpc rpc, ZNet __instance)
		{
			if (__instance.IsServer())
			{
				SendPinsToClient(rpc);
			}
		}
	}

	public static void OnReceiveInitialDataPin(ZRpc client, ZPackage pinData)
	{
		Store.ServerPinShare = true;
		if (Store.IsSharingPin())
		{
			List<PinData> list = ExplorationDatabase.UnpackPins(pinData);
			Utility.Log("Client received initial pin data by server. Pins: " + list.Count);
			ExplorationDatabase.ClientPins = list;
			ClientAppendPins();
		}
	}

	private static void ClientAppendPins()
	{
		if (!Store.IsSharingPin())
		{
			return;
		}
		Utility.Log("ClientAppendPins " + ExplorationDatabase.ClientPins.Count);
		foreach (PinData clientPin in ExplorationDatabase.ClientPins)
		{
			PinData mapPin = UtilityPin.GetMapPin(clientPin);
			if (mapPin != null)
			{
				_Minimap.RemovePin(_Minimap._instance, mapPin);
			}
			UtilityPin.AddSharedMapPin(clientPin);
		}
	}

	public static void OnClientInitialDataPin(ZRpc client, ZPackage pinData)
	{
		Utility.Log("Server received initial pin data by client");
	}

	private static void SendPinsToClient(ZRpc client)
	{
		if (Store.IsSharingPin())
		{
			ZPackage val = ExplorationDatabase.PackPins(ExplorationDatabase.GetPins());
			if (client == null)
			{
				OnReceiveInitialDataPin(null, val);
				return;
			}
			client.Invoke("SSMPoV_OnReceiveInitialDataPin", new object[1] { val });
		}
	}

	private static void SendPinsToServer(ZRpc client)
	{
		List<PinData> list = Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>;
		List<PinData> list2 = new List<PinData>();
		foreach (PinData item in list)
		{
			if (item.m_save)
			{
				list2.Add(UtilityPin.ConvertPin(item));
			}
		}
		ZPackage val = ExplorationDatabase.PackPins(list2);
		if (client == null)
		{
			OnClientInitialDataPin(null, val);
			return;
		}
		object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
		ZNet instance = (ZNet)((value is ZNet) ? value : null);
		ZRpc serverRPC = _ZNet.GetServerRPC(instance);
		serverRPC.Invoke("SSMPoV_OnClientInitialDataPin", new object[1] { val });
	}
}
public class PinSync
{
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	private class MinimapPatchOnMapLeftClick
	{
		private static void Postfix(Minimap __instance)
		{
			if (LatestClosestPin != null)
			{
				PinData clientPin = UtilityPin.GetClientPin(LatestClosestPin);
				if (clientPin != null)
				{
					clientPin.Checked = LatestClosestPin.m_checked;
					CheckPinOnServer(clientPin, clientPin.Checked);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Minimap), "RemovePinUnderPointer")]
	private class MinimapPatchOnMapRightClick
	{
		private static void Postfix(Minimap __instance)
		{
			if (LatestClosestPin != null)
			{
				PinData clientPin = UtilityPin.GetClientPin(LatestClosestPin);
				if (clientPin != null)
				{
					RemovePinFromServer(clientPin);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Minimap), "GetClosestPin", new Type[]
	{
		typeof(Vector3),
		typeof(float),
		typeof(bool)
	})]
	private class MinimapPatchGetClosestPin
	{
		private static void Postfix(Minimap __instance, ref PinData __result, Vector3 pos, float radius, bool mustBeVisible = true)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (!Store.IsSharingPin())
			{
				return;
			}
			LatestClosestPin = __result;
			PinData pinData = null;
			float num = 999999f;
			foreach (PinData clientPin in ExplorationDatabase.ClientPins)
			{
				float num2 = Utils.DistanceXZ(pos, clientPin.Pos);
				if ((double)num2 < (double)radius && ((double)num2 < (double)num || pinData == null))
				{
					pinData = clientPin;
					num = num2;
				}
			}
			if (pinData == null)
			{
				return;
			}
			PinData mapPin = UtilityPin.GetMapPin(pinData);
			if (__result == null)
			{
				__result = mapPin;
				LatestClosestPin = mapPin;
				return;
			}
			float num3 = Utils.DistanceXZ(pos, __result.m_pos);
			if (num3 > num)
			{
				__result = mapPin;
				LatestClosestPin = mapPin;
			}
		}
	}

	[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
	private class MinimapPatchRemovePin
	{
		private static void Postfix(Minimap __instance, PinData pin)
		{
		}
	}

	[HarmonyPatch(typeof(Minimap), "OnPinTextEntered")]
	private class MinimapPatchOnPinTextEntered
	{
		private static void Prefix(Minimap __instance, out PinData __state, PinData ___m_namePin)
		{
			__state = null;
			if (___m_namePin != null)
			{
				__state = ___m_namePin;
			}
		}

		private static void Postfix(Minimap __instance, PinData __state)
		{
			if (__state != null)
			{
				SendPinToServer(__state);
			}
		}
	}

	private static PinData CurrentPin = null;

	private static PinData LatestClosestPin = null;

	public static void OnClientAddPin(ZRpc client, ZPackage pinData)
	{
		if (!Store.IsSharingPin())
		{
			return;
		}
		pinData.SetPos(0);
		object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
		ZNet val = (ZNet)((value is ZNet) ? value : null);
		List<ZNetPeer> list = Traverse.Create((object)val).Field("m_peers").GetValue() as List<ZNetPeer>;
		PinData pin = ExplorationDatabase.UnpackPin(pinData);
		ExplorationDatabase.AddPin(pin);
		Utility.Log("Server received pin by client");
		foreach (ZNetPeer item in list)
		{
			if (item.IsReady() && item.m_rpc != client)
			{
				item.m_rpc.Invoke("SSMPoV_OnServerAddPin", new object[1] { ExplorationDatabase.PackPin(pin) });
			}
		}
		if (client != null)
		{
			OnServerAddPin(null, ExplorationDatabase.PackPin(pin));
		}
	}

	public static void OnServerAddPin(ZRpc client, ZPackage pinData)
	{
		if (Store.IsSharingPin())
		{
			pinData.SetPos(0);
			PinData pinData2 = ExplorationDatabase.UnpackPin(pinData);
			ExplorationDatabase.ClientPins.Add(pinData2);
			UtilityPin.AddSharedMapPin(pinData2);
			Utility.Log("Client received pin by server");
		}
	}

	public static void OnClientRemovePin(ZRpc client, ZPackage pinData)
	{
		if (!Store.IsSharingPin())
		{
			return;
		}
		pinData.SetPos(0);
		object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
		ZNet val = (ZNet)((value is ZNet) ? value : null);
		List<ZNetPeer> list = Traverse.Create((object)val).Field("m_peers").GetValue() as List<ZNetPeer>;
		PinData pinData2 = ExplorationDatabase.UnpackPin(pinData);
		ExplorationDatabase.RemovePinEqual(pinData2);
		Utility.Log("Server deleted pin by client");
		foreach (ZNetPeer item in list)
		{
			if (item.IsReady() && item.m_rpc != client)
			{
				item.m_rpc.Invoke("SSMPoV_OnServerRemovePin", new object[1] { ExplorationDatabase.PackPin(pinData2) });
			}
		}
		if (client != null)
		{
			OnServerRemovePin(null, ExplorationDatabase.PackPin(pinData2));
		}
	}

	public static void OnServerRemovePin(ZRpc _, ZPackage pinData)
	{
		if (!Store.IsSharingPin())
		{
			return;
		}
		pinData.SetPos(0);
		Utility.Log("Client deleted pin by server");
		PinData pinData2 = ExplorationDatabase.UnpackPin(pinData);
		foreach (PinData item in ExplorationDatabase.ClientPins.ToList())
		{
			if (UtilityPin.ArePinsEqual(item, pinData2))
			{
				ExplorationDatabase.ClientPins.Remove(item);
			}
		}
		PinData mapPin = UtilityPin.GetMapPin(pinData2);
		if (mapPin != null)
		{
			_Minimap.RemovePin(_Minimap._instance, mapPin);
		}
	}

	public static void OnClientCheckPin(ZRpc client, ZPackage data)
	{
		if (!Store.IsSharingPin())
		{
			return;
		}
		data.SetPos(0);
		Utility.Log("Server checked pin by client");
		PinData pinData = ExplorationDatabase.UnpackPin(data);
		bool flag = data.ReadBool();
		ExplorationDatabase.SetPinState(pinData, flag);
		object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
		ZNet val = (ZNet)((value is ZNet) ? value : null);
		List<ZNetPeer> list = Traverse.Create((object)val).Field("m_peers").GetValue() as List<ZNetPeer>;
		foreach (ZNetPeer item in list)
		{
			if (item.IsReady() && item.m_rpc != client)
			{
				ZPackage val2 = ExplorationDatabase.PackPin(pinData, skipSetPos: true);
				val2.Write(flag);
				item.m_rpc.Invoke("SSMPoV_OnServerCheckPin", new object[1] { val2 });
			}
		}
		if (client != null)
		{
			ZPackage val3 = ExplorationDatabase.PackPin(pinData, skipSetPos: true);
			val3.Write(flag);
			OnServerCheckPin(null, val3);
		}
	}

	public static void OnServerCheckPin(ZRpc client, ZPackage data)
	{
		if (!Store.IsSharingPin())
		{
			return;
		}
		data.SetPos(0);
		Utility.Log("Client checked pin by server");
		PinData pin = ExplorationDatabase.UnpackPin(data);
		bool flag = data.ReadBool();
		foreach (PinData item in ExplorationDatabase.ClientPins.ToList())
		{
			if (UtilityPin.ArePinsEqual(item, pin))
			{
				item.Checked = flag;
				PinData mapPin = UtilityPin.GetMapPin(item);
				if (mapPin != null)
				{
					mapPin.m_checked = flag;
				}
			}
		}
	}

	public static void SendPinToServer(PinData pin, bool deletePin = true)
	{
		if (Store.IsSharingPin() && UtilityPin.IsShareable(pin))
		{
			PinData pinData = UtilityPin.ConvertPin(pin);
			ZPackage val = ExplorationDatabase.PackPin(pinData);
			pin.m_save = !deletePin && pin.m_save;
			ExplorationDatabase.ClientPins.Add(pinData);
			if (!_ZNet.IsServer(_ZNet._instance))
			{
				_ZNet.GetServerRPC(_ZNet._instance).Invoke("SSMPoV_OnClientAddPin", new object[1] { val });
			}
			else
			{
				OnClientAddPin(null, val);
			}
		}
	}

	public static void RemovePinFromServer(PinData pin)
	{
		if (Store.IsSharingPin())
		{
			ZPackage val = ExplorationDatabase.PackPin(pin);
			ExplorationDatabase.ClientPins.Remove(pin);
			if (!_ZNet.IsServer(_ZNet._instance))
			{
				_ZNet.GetServerRPC(_ZNet._instance).Invoke("SSMPoV_OnClientRemovePin", new object[1] { val });
			}
			else
			{
				OnClientRemovePin(null, val);
			}
		}
	}

	public static void CheckPinOnServer(PinData pin, bool state)
	{
		if (Store.IsSharingPin())
		{
			ZPackage val = ExplorationDatabase.PackPin(pin, skipSetPos: true);
			val.Write(state);
			val.SetPos(0);
			if (!_ZNet.IsServer(_ZNet._instance))
			{
				_ZNet.GetServerRPC(_ZNet._instance).Invoke("SSMPoV_OnClientCheckPin", new object[1] { val });
			}
			else
			{
				OnClientCheckPin(null, val);
			}
		}
	}
}
public static class PovBridge
{
	[HarmonyPatch(typeof(Minimap), "AddPin", new Type[]
	{
		typeof(Vector3),
		typeof(PinType),
		typeof(string),
		typeof(bool),
		typeof(bool),
		typeof(long),
		typeof(PlatformUserID)
	})]
	private class MinimapPatchAddPin
	{
		private static void Postfix(PinData __result)
		{
			if (InQuickMark && __result != null && __result.m_save && Store.IsSharingPin() && !string.IsNullOrEmpty(LocalIcon(__result)))
			{
				PinSync.SendPinToServer(__result);
			}
		}
	}

	[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
	private class MinimapPatchRemovePinQuickMark
	{
		private static void Postfix(PinData pin)
		{
			if (InQuickMark && pin != null)
			{
				PinData clientPin = UtilityPin.GetClientPin(pin);
				if (clientPin != null)
				{
					PinSync.RemovePinFromServer(clientPin);
				}
			}
		}
	}

	public static Harmony HarmonyInstance;

	private static bool initialised;

	private static MethodInfo iconAt;

	private static MethodInfo dress;

	[ThreadStatic]
	private static bool bypass;

	public static bool InQuickMark;

	public static void Init()
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Expected O, but got Unknown
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Expected O, but got Unknown
		if (initialised)
		{
			return;
		}
		initialised = true;
		try
		{
			Type type = AccessTools.TypeByName("PassiveTree.QuickMark");
			if (type == null)
			{
				Utility.Log("Path of Valheiman not found - sharing pins without custom icons.");
				return;
			}
			iconAt = AccessTools.Method(type, "IconAt", new Type[1] { typeof(PinData) }, (Type[])null);
			if (iconAt != null)
			{
				Harmony harmonyInstance = HarmonyInstance;
				MethodInfo methodInfo = iconAt;
				HarmonyMethod val = new HarmonyMethod(typeof(PovBridge), "IconAtPostfix", (Type[])null);
				harmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Utility.Log("PassiveTree.QuickMark.IconAt not found - custom icons disabled.");
			}
			Type type2 = AccessTools.TypeByName("PassiveTree.UI.MapIcons");
			dress = ((!(type2 == null)) ? AccessTools.Method(type2, "Dress", new Type[2]
			{
				typeof(Minimap),
				typeof(PinData)
			}, (Type[])null) : null);
			if (dress == null)
			{
				Utility.Log("PassiveTree.UI.MapIcons.Dress not found - shared pins will not be redrawn.");
			}
			Type type3 = AccessTools.Inner(type, "Player_Update");
			MethodInfo methodInfo2 = ((!(type3 == null)) ? AccessTools.Method(type3, "Postfix", (Type[])null, (Type[])null) : null);
			if (methodInfo2 != null)
			{
				Harmony harmonyInstance2 = HarmonyInstance;
				MethodInfo methodInfo = methodInfo2;
				HarmonyMethod val = new HarmonyMethod(typeof(PovBridge), "QuickMarkPrefix", (Type[])null);
				HarmonyMethod val2 = new HarmonyMethod(typeof(PovBridge), "QuickMarkFinalizer", (Type[])null);
				harmonyInstance2.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, val2, (HarmonyMethod)null);
			}
			else
			{
				Utility.Log("Quick Mark handler not found - new Quick Marks will not auto-share.");
			}
			Utility.Log("Path of Valheiman icon bridge active.");
		}
		catch (Exception ex)
		{
			Utility.Log("Path of Valheiman icon bridge failed: " + ex);
		}
	}

	public static string LocalIcon(PinData pin)
	{
		if (iconAt == null || pin == null)
		{
			return "";
		}
		bypass = true;
		try
		{
			return (iconAt.Invoke(null, new object[1] { pin }) as string) ?? "";
		}
		catch
		{
			return "";
		}
		finally
		{
			bypass = false;
		}
	}

	public static void Dress(PinData pin)
	{
		if (dress == null || pin == null || (Object)(object)_Minimap._instance == (Object)null)
		{
			return;
		}
		try
		{
			dress.Invoke(null, new object[2]
			{
				_Minimap._instance,
				pin
			});
		}
		catch (Exception ex)
		{
			Utility.Log("Dress failed: " + ex.Message);
		}
	}

	private static void IconAtPostfix(PinData __0, ref string __result)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		if (!bypass && __result == null && __0 != null && (int)__0.m_type == 3)
		{
			PinData clientPin = UtilityPin.GetClientPin(__0);
			if (clientPin != null && !string.IsNullOrEmpty(clientPin.Icon))
			{
				__result = clientPin.Icon;
			}
		}
	}

	private static void QuickMarkPrefix()
	{
		InQuickMark = true;
	}

	private static Exception QuickMarkFinalizer(Exception __exception)
	{
		InQuickMark = false;
		return __exception;
	}
}
public class SaveWorld
{
	[HarmonyPatch(typeof(ZNet), "ServerLoadWorld")]
	private class ZnetPatchLoadMap
	{
		private static void Postfix(ZNet __instance)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			object value = Traverse.Create(typeof(ZNet)).Field("m_world").GetValue();
			World val = (World)((value is World) ? value : null);
			string text = Path.ChangeExtension(val.GetDBPath(), null);
			Utility.Log("World .explored save path: " + text);
			string text2 = text + ".mod.serversidemap_pov.explored";
			string text3 = text2 + ".beforehs";
			if (File.Exists(text2) && !File.Exists(text3))
			{
				File.Copy(text2, text3);
			}
			string text4 = text + ".mod.serversidemap.explored";
			string path = text2;
			if (!File.Exists(text2) && File.Exists(text4))
			{
				Utility.Log("Migrating pins and exploration from original ServerSideMap file");
				path = text4;
			}
			FileStream input;
			try
			{
				input = File.OpenRead(path);
			}
			catch
			{
				GenerateDefaultExploredFile(__instance);
				return;
			}
			BinaryReader binaryReader = new BinaryReader(input);
			byte[] array = binaryReader.ReadAllBytes();
			binaryReader.Dispose();
			if (array.Length == 0)
			{
				Utility.Log("Existing explored file is 0 bytes. Generating new one.");
				GenerateDefaultExploredFile(__instance);
			}
			else
			{
				ZPackage mapData = new ZPackage(array);
				ExplorationDatabase.SetMapData(mapData);
				Utility.Log("loaded from existing explore file");
			}
		}
	}

	[HarmonyPatch(typeof(ZNet), "SaveWorldThread")]
	private class ZnetPatchSaveWorldThread
	{
		private static void Postfix()
		{
			byte[] array = ExplorationDatabase.GetMapData().GetArray();
			if (array.Length == 0)
			{
				Utility.Log("Explored data is zero bytes. Refusing to save.");
				return;
			}
			object value = Traverse.Create(typeof(ZNet)).Field("m_world").GetValue();
			World val = (World)((value is World) ? value : null);
			string text = Path.ChangeExtension(val.GetDBPath(), null);
			string path = text + ".mod.serversidemap_pov.explored";
			Utility.Log("World .explored save path: " + text);
			FileStream fileStream = File.Create(path);
			BinaryWriter binaryWriter = new BinaryWriter(fileStream);
			binaryWriter.Write(array);
			binaryWriter.Flush();
			fileStream.Flush(flushToDisk: true);
			fileStream.Close();
			fileStream.Dispose();
		}
	}

	public static void GenerateDefaultExploredFile(ZNet __instance)
	{
		ExplorationDatabase.SetMapData(ExplorationDatabase.Default());
		Utility.Log("new explore file generated");
		__instance.Save(true, false, false);
	}
}
[BepInPlugin("OGTristonMcPherson.ServerSideMapPoV", "ServerSideMap_PoV", "1.0.2")]
public class ServerSideMap : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	private class ZnetPatchOnNewConnection
	{
		private static void Postfix(ZNetPeer peer, ZNet __instance)
		{
			if (__instance.IsServer())
			{
				Utility.Log("Registered Server Events");
				if (Store.IsSharingMap())
				{
					peer.m_rpc.Register<int, int>("SSMPoV_OnClientExplore", (Action<ZRpc, int, int>)ExplorationMapSync.OnClientExplore);
					peer.m_rpc.Register<ZPackage>("SSMPoV_OnClientInitialData", (Action<ZRpc, ZPackage>)InitialMapSync.OnClientInitialData);
				}
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnClientInitialDataPin", (Action<ZRpc, ZPackage>)InitialPinSync.OnClientInitialDataPin);
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnClientAddPin", (Action<ZRpc, ZPackage>)PinSync.OnClientAddPin);
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnClientRemovePin", (Action<ZRpc, ZPackage>)PinSync.OnClientRemovePin);
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnClientCheckPin", (Action<ZRpc, ZPackage>)PinSync.OnClientCheckPin);
			}
			else
			{
				Utility.Log("Registered Client Events");
				if (Store.IsSharingMap())
				{
					peer.m_rpc.Register<ZPackage>("SSMPoV_OnReceiveMapData", (Action<ZRpc, ZPackage>)ExplorationDatabase.OnReceiveMapData);
					peer.m_rpc.Register<ZPackage>("SSMPoV_OnReceiveMapDataInitial", (Action<ZRpc, ZPackage>)InitialMapSync.OnReceiveMapDataInitial);
				}
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnReceiveInitialDataPin", (Action<ZRpc, ZPackage>)InitialPinSync.OnReceiveInitialDataPin);
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnServerAddPin", (Action<ZRpc, ZPackage>)PinSync.OnServerAddPin);
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnServerRemovePin", (Action<ZRpc, ZPackage>)PinSync.OnServerRemovePin);
				peer.m_rpc.Register<ZPackage>("SSMPoV_OnServerCheckPin", (Action<ZRpc, ZPackage>)PinSync.OnServerCheckPin);
			}
		}
	}

	private void Awake()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		PovBridge.HarmonyInstance = new Harmony("OGTristonMcPherson.ServerSideMapPoV.pov");
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		Store.EnableMapShare = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMapShare", true, "Client: Whether or not to participate in sharing the map. Server: Whether or not to allow map sharing");
		Store.EnablePinShare = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMarkerShare", true, "Client: Whether or not to participate in sharing markers. Server: Whether or not to allow marker sharing");
		Store.DuplicatePinRadius = ((BaseUnityPlugin)this).Config.Bind<float>("PinShare", "DuplicatePinRadius", 15f, "A local pin will not be uploaded if a pin exists in the given radius on the server (when using /convertpins ignorelocaldupes)");
		Store.sKeyConvertAll = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "KeyConvertAll", "", "Hotkey to run /convertpins");
		Store.sKeyConvertIgnoreDupes = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "KeyConvertIgnoreDupes", "", "Hotkey to run /convertpins ignorelocaldupes");
		Store.InitHotkeys();
		Utility.Log("Store1: " + Store.HasKeyConvertAll());
		Utility.Log("Store2: " + Store.HasKeyConvertIgnoreDupes());
	}
}
public static class Store
{
	public static ConfigEntry<bool> EnableMapShare;

	public static ConfigEntry<bool> EnablePinShare;

	public static ConfigEntry<float> DuplicatePinRadius;

	public static ConfigEntry<string> sKeyConvertAll;

	private static bool hasKeyConvertAll;

	private static KeyCode KeyConvertAll;

	public static ConfigEntry<string> sKeyConvertIgnoreDupes;

	private static bool hasKeyConvertIgnoreDupes;

	private static KeyCode KeyConvertIgnoreDupes;

	public static bool ServerPinShare = false;

	public static bool IsSharingMap()
	{
		return EnableMapShare.Value;
	}

	public static bool IsSharingPin()
	{
		return (ServerPinShare || _ZNet.IsServer(_ZNet._instance)) && EnablePinShare.Value;
	}

	public static float GetDuplicatePinRadius()
	{
		return DuplicatePinRadius.Value;
	}

	public static void InitHotkeys()
	{
		hasKeyConvertAll = Enum.TryParse<KeyCode>(sKeyConvertAll.Value, out KeyConvertAll);
		hasKeyConvertIgnoreDupes = Enum.TryParse<KeyCode>(sKeyConvertIgnoreDupes.Value, out KeyConvertIgnoreDupes);
	}

	public static bool HasKeyConvertAll()
	{
		return hasKeyConvertAll;
	}

	public static KeyCode GetKeyConvertAll()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		return KeyConvertAll;
	}

	public static bool HasKeyConvertIgnoreDupes()
	{
		return hasKeyConvertIgnoreDupes;
	}

	public static KeyCode GetKeyConvertIgnoreDupes()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		return KeyConvertIgnoreDupes;
	}
}
public static class Utility
{
	private static ManualLogSource _logInstance = Logger.CreateLogSource("ServerSideMap");

	public static void Log(object data)
	{
		_logInstance.Log((LogLevel)16, data);
	}

	public static void Message(string text)
	{
		Log(text);
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false);
		}
	}

	public static byte[] ReadAllBytes(this BinaryReader reader)
	{
		using MemoryStream memoryStream = new MemoryStream();
		byte[] array = new byte[4096];
		int count;
		while ((count = reader.Read(array, 0, array.Length)) != 0)
		{
			memoryStream.Write(array, 0, count);
		}
		return memoryStream.ToArray();
	}
}
public class UtilityPin
{
	public static bool ArePinsEqual(PinData pin1, PinData pin2)
	{
		//IL_0017: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		return pin1.Name == pin2.m_name && pin1.Type == pin2.m_type && ((Vector3)(ref pin1.Pos)).Equals(pin2.m_pos);
	}

	public static bool ArePinsEqual(PinData pin1, PinData pin2)
	{
		//IL_0017: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		return pin1.Name == pin2.Name && pin1.Type == pin2.Type && ((Vector3)(ref pin1.Pos)).Equals(pin2.Pos);
	}

	public static bool ArePinsDupes(PinData pin1, PinData pin2, float radius)
	{
		//IL_0001: 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)
		return Utils.DistanceXZ(pin1.m_pos, pin2.Pos) < radius;
	}

	public static PinData AddSharedMapPin(PinData pin)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		PinData val = _Minimap.AddPin(_Minimap._instance, pin.Pos, pin.Type, pin.Name, save: false, pin.Checked, 0L, new PlatformUserID(""));
		PovBridge.Dress(val);
		return val;
	}

	public static PinData FindServerDupe(PinData pin)
	{
		foreach (PinData clientPin in ExplorationDatabase.ClientPins)
		{
			if (ArePinsDupes(pin, clientPin, Store.GetDuplicatePinRadius()))
			{
				return clientPin;
			}
		}
		return null;
	}

	private static bool HasSharedCopy(PinData pin, string icon)
	{
		//IL_0019: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		foreach (PinData clientPin in ExplorationDatabase.ClientPins)
		{
			if (clientPin.Type != pin.m_type || Utils.DistanceXZ(pin.m_pos, clientPin.Pos) > 2f || (!string.IsNullOrEmpty(icon) && !(clientPin.Icon == icon)))
			{
				continue;
			}
			return true;
		}
		return false;
	}

	public static bool LocalPinIsDupe(PinData pin)
	{
		foreach (PinData clientPin in ExplorationDatabase.ClientPins)
		{
			if (ArePinsDupes(pin, clientPin, Store.GetDuplicatePinRadius()))
			{
				return true;
			}
		}
		return false;
	}

	public static PinData GetMapPin(PinData needle)
	{
		List<PinData> list = Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>;
		foreach (PinData item in list)
		{
			if (ArePinsEqual(needle, item))
			{
				return item;
			}
		}
		return null;
	}

	public static PinData GetClientPin(PinData needle)
	{
		foreach (PinData clientPin in ExplorationDatabase.ClientPins)
		{
			if (ArePinsEqual(clientPin, needle))
			{
				return clientPin;
			}
		}
		return null;
	}

	public static bool IsShareable(PinData pin)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected I4, but got Unknown
		PinType type = pin.m_type;
		switch (type - 4)
		{
		case 0:
		case 1:
		case 3:
		case 4:
		case 6:
		case 7:
		case 8:
		case 9:
			return false;
		default:
			return true;
		}
	}

	public static PinData ConvertPin(PinData pin)
	{
		//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)
		//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)
		PinData pinData = new PinData();
		pinData.Name = pin.m_name;
		pinData.Pos = pin.m_pos;
		pinData.Type = pin.m_type;
		pinData.Checked = pin.m_checked;
		pinData.Icon = PovBridge.LocalIcon(pin);
		return pinData;
	}

	public static void UploadAllPins(bool removeDupes = false)
	{
		List<PinData> source = Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>;
		foreach (PinData item in source.ToList())
		{
			if (!item.m_save || !IsShareable(item))
			{
				continue;
			}
			if (removeDupes)
			{
				PinData pinData = FindServerDupe(item);
				if (pinData != null)
				{
					if (!string.IsNullOrEmpty(pinData.Icon) || string.IsNullOrEmpty(PovBridge.LocalIcon(item)))
					{
						continue;
					}
					PinData mapPin = GetMapPin(pinData);
					PinSync.RemovePinFromServer(pinData);
					if (mapPin != null)
					{
						_Minimap.RemovePin(_Minimap._instance, mapPin);
					}
				}
			}
			PinData pinData2 = ConvertPin(item);
			PinSync.SendPinToServer(item, deletePin: false);
			ExplorationDatabase.ClientPins.Add(pinData2);
			AddSharedMapPin(pinData2);
		}
	}

	public static void DeleteLocalPins()
	{
		List<PinData> source = Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>;
		int num = 0;
		foreach (PinData item in source.ToList())
		{
			if (item.m_save && IsShareable(item))
			{
				_Minimap.RemovePin(_Minimap._instance, item);
				num++;
			}
		}
		Utility.Message("Removed " + num + " local pins");
	}

	public static void DeleteAllSharedPins()
	{
		List<PinData> list = ExplorationDatabase.ClientPins.ToList();
		foreach (PinData item in list)
		{
			PinData mapPin = GetMapPin(item);
			PinSync.RemovePinFromServer(item);
			if (mapPin != null)
			{
				_Minimap.RemovePin(_Minimap._instance, mapPin);
			}
		}
		Utility.Message("Deleted " + list.Count + " shared pins for everyone");
	}

	public static void DownloadPins()
	{
		List<PinData> list = ExplorationDatabase.ClientPins.ToList();
		foreach (PinData item in list)
		{
			PinData mapPin = GetMapPin(item);
			mapPin.m_save = true;
		}
	}
}
[HarmonyPatch]
public class _Minimap
{
	[HarmonyPatch(typeof(Minimap), "Awake")]
	public static class Awake
	{
		private static void Postfix(Minimap __instance)
		{
			_instance = __instance;
			PovBridge.Init();
			ManualLogSource val = Logger.CreateLogSource("ServerSideMap");
			val.LogInfo((object)"Minimap awake");
		}
	}

	public static Minimap _instance;

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
	{
		typeof(int),
		typeof(int)
	})]
	public static bool Explore(Minimap instance, int x, int y)
	{
		throw new NotImplementedException();
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(Minimap), "AddPin", new Type[]
	{
		typeof(Vector3),
		typeof(PinType),
		typeof(string),
		typeof(bool),
		typeof(bool),
		typeof(long),
		typeof(PlatformUserID)
	})]
	public static PinData AddPin(Minimap instance, Vector3 pos, PinType type, string name, bool save, bool isChecked, long owner, PlatformUserID author)
	{
		throw new NotImplementedException();
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
	public static void RemovePin(Minimap instance, PinData pin)
	{
		throw new NotImplementedException();
	}
}
[HarmonyPatch]
public class _ZNet
{
	[HarmonyPatch(typeof(ZNet), "Awake")]
	public static class Awake
	{
		private static void Postfix(ZNet __instance)
		{
			_instance = __instance;
			ManualLogSource val = Logger.CreateLogSource("ServerSideMap");
			val.LogInfo((object)"ZNet awake");
			Store.ServerPinShare = false;
		}
	}

	public static ZNet _instance;

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(ZNet), "GetServerRPC")]
	public static ZRpc GetServerRPC(ZNet instance)
	{
		throw new NotImplementedException();
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(ZNet), "IsServer")]
	public static bool IsServer(ZNet instance)
	{
		throw new NotImplementedException();
	}
}