Decompiled source of RoadMapper v1.0.1

BepInEx/Plugins/RoadMapper/RoadMapper.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RoadMapper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RoadMapper")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.2.0")]
namespace RoadMapper;

[BepInPlugin("com.jotunn.RoadMapper", "RoadMapper", "0.0.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class RoadMapper : BaseUnityPlugin
{
	public struct MarkerPoint
	{
		public float x;

		public float z;

		public int BrushId;
	}

	[HarmonyPatch(typeof(Player), "PlacePiece")]
	public static class Player_PlacePiece_Patch
	{
		public static void Postfix(Piece piece, Vector3 pos)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0069: 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)
			//IL_0097: 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_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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_0183: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)piece).name == "RoadMapper_Eraser")
			{
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
				{
					Instance.EraseMarkersNear(pos.x, pos.z);
					Instance.RefreshSyncedPointsLocally();
				}
				else
				{
					ZPackage val = new ZPackage();
					val.Write(pos.x);
					val.Write(pos.z);
					EraseRPC.SendPackage(0L, val);
					Logger.LogInfo((object)$"Erase request sent: ({pos.x}, {pos.z})");
				}
				ZNetView component = ((Component)piece).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null)
				{
					component.Destroy();
				}
				return;
			}
			int num;
			switch (((Object)piece).name)
			{
			default:
				return;
			case "RoadMapper_PathMarker":
				num = 1;
				break;
			case "RoadMapper_RoadMarker":
				num = 2;
				break;
			case "RoadMapper_WallMarker":
				num = 3;
				break;
			case "RoadMapper_FenceMarker":
				num = 4;
				break;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				Instance.RecordMarkerPoint(pos.x, pos.z, num);
				Instance.RefreshSyncedPointsLocally();
				return;
			}
			ZPackage val2 = new ZPackage();
			val2.Write(pos.x);
			val2.Write(pos.z);
			val2.Write(num);
			PathMarkerRPC.SendPackage(0L, val2);
			Logger.LogInfo((object)$"Paint Coord sent: ({pos.x}, {pos.z}, {num})");
		}
	}

	[HarmonyPatch(typeof(Minimap), "SetMapMode")]
	public static class Minimap_SetMapMode_Patch
	{
		public static void Postfix(MapMode mode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if ((int)mode == 2)
			{
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
				{
					Instance.RefreshSyncedPointsLocally();
					return;
				}
				ZPackage val = new ZPackage();
				ResyncRPC.SendPackage(0L, val);
				Logger.LogInfo((object)"[RoadMapper] Map Opened - Requesting resync");
			}
		}
	}

	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class Znet_RPC_PeerInfo_Patch
	{
		public static void Postfix()
		{
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				Instance.ForceResyncAllClients();
				Logger.LogInfo((object)"[RoadMapper] New guy came in, everyone gets a new map.");
			}
		}
	}

	public class MapModResyncCommand : ConsoleCommand
	{
		public override string Name => "mapmod_resync";

		public override string Help => "Forces a fresh map-marker resync to all connected clients";

		public override bool IsCheat => false;

		public override bool IsNetwork => true;

		public override bool OnlyServer => true;

		public override void Run(string[] args)
		{
			Instance.ForceResyncAllClients();
		}
	}

	public const string PluginGUID = "com.jotunn.RoadMapper";

	public const string PluginName = "RoadMapper";

	public const string PluginVersion = "0.0.2";

	public const string PathMarkerPrefabName = "RoadMapper_PathMarker";

	public const string RoadMarkerPrefabName = "RoadMapper_RoadMarker";

	public const string WallMarkerPrefabName = "RoadMapper_WallMarker";

	public const string FenceMarkerPrefabName = "RoadMapper_FenceMarker";

	public const string EraserPrefabName = "RoadMapper_Eraser";

	public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

	public static RoadMapper Instance;

	public static CustomRPC PathMarkerRPC;

	public static CustomRPC ResyncRPC;

	public static CustomRPC EraseRPC;

	private Dictionary<long, float> _lastResyncTime = new Dictionary<long, float>();

	private List<MarkerPoint> _syncedPoints = new List<MarkerPoint>();

	private ConfigEntry<float> _dedupDistance;

	private ConfigEntry<float> _resyncCooldownSeconds;

	private ConfigEntry<float> _brush1Size;

	private ConfigEntry<string> _brush1Colour;

	private ConfigEntry<float> _brush2Size;

	private ConfigEntry<string> _brush2Colour;

	private ConfigEntry<float> _brush3Size;

	private ConfigEntry<string> _brush3Colour;

	private ConfigEntry<float> _brush4Size;

	private ConfigEntry<string> _brush4Colour;

	private ConfigEntry<float> _eraserSize;

	private Harmony _harmony;

	private static Sprite LoadIcon(string relativePath)
	{
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string text = Paths.PluginPath.TrimStart('\\', '/');
		string path = (directoryName.StartsWith(text) ? directoryName.Substring(text.Length).TrimStart('\\', '/') : "");
		string text2 = Path.Combine(path, relativePath);
		return AssetUtils.LoadSpriteFromFile(text2);
	}

	public void ForceResyncAllClients()
	{
		ResyncRPC.SendPackage(0L, BuildResyncPackage());
		RefreshSyncedPointsLocally();
		Logger.LogInfo((object)"[RoadMapper] Admin is jamming a resync down everyone's throats.");
	}

	private ZPackage BuildResyncPackage()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Expected O, but got Unknown
		List<MarkerPoint> list = LoadPointsFromFile(GetWorldDataFilePath());
		ZPackage val = new ZPackage();
		val.Write(list.Count);
		foreach (MarkerPoint item in list)
		{
			val.Write(item.x);
			val.Write(item.z);
			val.Write(item.BrushId);
		}
		return val;
	}

	private string GetWorldDataFilePath()
	{
		string text = Path.Combine(Paths.ConfigPath, "RoadMapper");
		Directory.CreateDirectory(text);
		return Path.Combine(text, ZNet.instance.GetWorldName() + ".txt");
	}

	private static float Distance(MarkerPoint a, MarkerPoint b)
	{
		float num = a.x - b.x;
		float num2 = a.z - b.z;
		return Mathf.Sqrt(num * num + num2 * num2);
	}

	private List<MarkerPoint> LoadPointsFromFile(string path)
	{
		List<MarkerPoint> list = new List<MarkerPoint>();
		if (!File.Exists(path))
		{
			return list;
		}
		string[] array = File.ReadAllLines(path);
		foreach (string text in array)
		{
			if (!string.IsNullOrWhiteSpace(text))
			{
				string[] array2 = text.Split(new char[1] { ',' });
				if (array2.Length != 3)
				{
					Logger.LogWarning((object)("[RoadMapper] Skipping cocked up line in " + path + ": \"" + text + "\""));
				}
				else
				{
					list.Add(new MarkerPoint
					{
						x = float.Parse(array2[0], CultureInfo.InvariantCulture),
						z = float.Parse(array2[1], CultureInfo.InvariantCulture),
						BrushId = int.Parse(array2[2], CultureInfo.InvariantCulture)
					});
				}
			}
		}
		return list;
	}

	private void OnWorldSaveFinished()
	{
		string worldDataFilePath = GetWorldDataFilePath();
		List<MarkerPoint> list = LoadPointsFromFile(worldDataFilePath);
		if (list.Count == 0)
		{
			return;
		}
		List<MarkerPoint> list2 = new List<MarkerPoint>();
		foreach (MarkerPoint item in list)
		{
			bool flag = false;
			foreach (MarkerPoint item2 in list2)
			{
				if (item2.BrushId == item.BrushId && Distance(item2, item) <= _dedupDistance.Value)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				list2.Add(item);
			}
		}
		string[] array = new string[list2.Count];
		for (int i = 0; i < list2.Count; i++)
		{
			array[i] = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", list2[i].x, list2[i].z, list2[i].BrushId);
		}
		File.WriteAllLines(worldDataFilePath, array);
		Logger.LogInfo((object)$"[RoadMapper] World save dedup: {list.Count} lines -> {list2.Count} after dedup.");
	}

	private void EraseMarkersNear(float x, float z)
	{
		string worldDataFilePath = GetWorldDataFilePath();
		List<MarkerPoint> list = LoadPointsFromFile(worldDataFilePath);
		MarkerPoint b = new MarkerPoint
		{
			x = x,
			z = z,
			BrushId = 0
		};
		List<MarkerPoint> list2 = new List<MarkerPoint>();
		int num = 0;
		foreach (MarkerPoint item in list)
		{
			if (Distance(item, b) <= _eraserSize.Value)
			{
				num++;
			}
			else
			{
				list2.Add(item);
			}
		}
		if (num == 0)
		{
			Logger.LogInfo((object)$"[RoadMapper] Eraser used at ({x:F1}, {z:F1})... but there is nothing there to erase.");
			return;
		}
		string[] array = new string[list2.Count];
		for (int i = 0; i < list2.Count; i++)
		{
			array[i] = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", list2[i].x, list2[i].z, list2[i].BrushId);
		}
		File.WriteAllLines(worldDataFilePath, array);
		Logger.LogInfo((object)$"[RoadMapper] Eraser removed {num} Marker(s) near ({x:F1}, {z:F1}).");
	}

	private void RefreshSyncedPointsLocally()
	{
		_syncedPoints = LoadPointsFromFile(GetWorldDataFilePath());
		if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated())
		{
			DrawMarkerOverlay();
			Logger.LogInfo((object)$"[RoadMapper] Host refreshed markers locally: {_syncedPoints.Count} points.");
		}
	}

	private void Awake()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_009e: 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)
		//IL_00ac: Expected O, but got Unknown
		//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_00ec: Expected O, but got Unknown
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Expected O, but got Unknown
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Expected O, but got Unknown
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Expected O, but got Unknown
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Expected O, but got Unknown
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Expected O, but got Unknown
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Expected O, but got Unknown
		//IL_02de: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Expected O, but got Unknown
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Expected O, but got Unknown
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Expected O, but got Unknown
		//IL_0357: Expected O, but got Unknown
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Expected O, but got Unknown
		//IL_0383: Expected O, but got Unknown
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Expected O, but got Unknown
		//IL_03af: Expected O, but got Unknown
		Logger.LogInfo((object)"RoadMapper has landed");
		CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new MapModResyncCommand());
		ZNet.WorldSaveFinished = (Action)Delegate.Combine(ZNet.WorldSaveFinished, new Action(OnWorldSaveFinished));
		Instance = this;
		ConfigFile config = ((BaseUnityPlugin)this).Config;
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_dedupDistance = ConfigFileExtensions.BindConfig<float>(config, "DeDuplicate", "Distance", 2f, "Minimum distance for two brushpoints to be apart before they are counted as duplicate", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config2 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_resyncCooldownSeconds = ConfigFileExtensions.BindConfig<float>(config2, "Resync", "CooldownSeconds", 10f, "Time in seconds to wait before resyncing a client map markers", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config3 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush1Size = ConfigFileExtensions.BindConfig<float>(config3, "Brush1", "Size", 1f, "Map dot size for the Path Marker (brush 1)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config4 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush1Colour = ConfigFileExtensions.BindConfig<string>(config4, "Brush1", "Colour", "#FFFFFF", "Map overlay colour for the Path Marker (brush 1), as a hex string", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config5 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush2Size = ConfigFileExtensions.BindConfig<float>(config5, "Brush2", "Size", 2f, "Map dot size for the Road Marker (brush 2)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config6 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush2Colour = ConfigFileExtensions.BindConfig<string>(config6, "Brush2", "Colour", "#F5C26B", "Map overlay colour for the Road Marker (brush 2), as a hex string", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config7 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush3Size = ConfigFileExtensions.BindConfig<float>(config7, "Brush3", "Size", 2f, "Map dot size for the Wall Marker (brush 3)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config8 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush3Colour = ConfigFileExtensions.BindConfig<string>(config8, "Brush3", "Colour", "#CBD6E2", "Map overlay colour for the Wall Marker (brush 3), as a hex string", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config9 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush4Size = ConfigFileExtensions.BindConfig<float>(config9, "Brush4", "Size", 1f, "Map dot size for the Fence Marker (brush 4)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config10 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_brush4Colour = ConfigFileExtensions.BindConfig<string>(config10, "Brush4", "Colour", "#8B4513", "Map overlay colour for the Fence Marker (brush 4), as a hex string", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		ConfigFile config11 = ((BaseUnityPlugin)this).Config;
		val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		_eraserSize = ConfigFileExtensions.BindConfig<float>(config11, "Eraser", "Size", 2f, "Radius for the eraser tool", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, val);
		PrefabManager.OnVanillaPrefabsAvailable += CreatePieces;
		_harmony = new Harmony("com.jotunn.RoadMapper");
		_harmony.PatchAll();
		ResyncRPC = NetworkManager.Instance.AddRPC("RoadMapper_ResyncRPC", new CoroutineHandler(ServerReceiveResyncRequest), new CoroutineHandler(ClientReceiveResyncData));
		PathMarkerRPC = NetworkManager.Instance.AddRPC("RoadMapper_PathMarkerRPC", new CoroutineHandler(ServerReceivePathMarker), new CoroutineHandler(ClientReceivePathMarker));
		EraseRPC = NetworkManager.Instance.AddRPC("RoadMapper_EraseRPC", new CoroutineHandler(ServerReceiveEraseRequest), new CoroutineHandler(ClientReceiveEraseAck));
		MinimapManager.OnVanillaMapDataLoaded += DrawMarkerOverlay;
	}

	private void DrawMarkerOverlay()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		MapOverlay mapOverlay = MinimapManager.Instance.GetMapOverlay("RoadMapperOverlay", false);
		Color[] pixels = ArrayExtensions.Populate<Color>((Color[])(object)new Color[((Texture)mapOverlay.OverlayTex).width * ((Texture)mapOverlay.OverlayTex).height], Color.clear);
		mapOverlay.OverlayTex.SetPixels(pixels);
		foreach (MarkerPoint syncedPoint in _syncedPoints)
		{
			DrawMarkerPoint(mapOverlay, syncedPoint);
		}
		mapOverlay.OverlayTex.Apply();
	}

	private void DrawMarkerPoint(MapOverlay overlay, MarkerPoint point)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		(float size, string colour) brushConfig = GetBrushConfig(point.BrushId);
		float item = brushConfig.size;
		string item2 = brushConfig.colour;
		int num = Mathf.Max(1, (int)item);
		Color magenta = default(Color);
		if (!ColorUtility.TryParseHtmlString(item2, ref magenta))
		{
			magenta = Color.magenta;
		}
		Color[] array = ArrayExtensions.Populate<Color>((Color[])(object)new Color[num * num], magenta);
		Vector2 val = MinimapManager.Instance.WorldToOverlayCoords(new Vector3(point.x, 0f, point.z), ((MapOverlayBase)overlay).TextureSize);
		overlay.OverlayTex.SetPixels((int)val.x, (int)val.y, num, num, array);
		Logger.LogInfo((object)$"[RoadMapper] Point ({point.x},{point.z}) -> overlay pixel ({val.x},{val.y}), overlay size {((MapOverlayBase)overlay).TextureSize}, squareSize {num}");
	}

	private (float size, string colour) GetBrushConfig(int brushId)
	{
		return brushId switch
		{
			1 => (size: _brush1Size.Value, colour: _brush1Colour.Value), 
			2 => (size: _brush2Size.Value, colour: _brush2Colour.Value), 
			3 => (size: _brush3Size.Value, colour: _brush3Colour.Value), 
			4 => (size: _brush4Size.Value, colour: _brush4Colour.Value), 
			_ => (size: 2f, colour: "#FFFFFF"), 
		};
	}

	private IEnumerator ServerReceiveEraseRequest(long sender, ZPackage package)
	{
		float x = package.ReadSingle();
		float z = package.ReadSingle();
		EraseMarkersNear(x, z);
		yield break;
	}

	private IEnumerator ClientReceiveEraseAck(long sender, ZPackage package)
	{
		yield break;
	}

	private IEnumerator ServerReceiveResyncRequest(long sender, ZPackage package)
	{
		float now = Time.time;
		if (_lastResyncTime.TryGetValue(sender, out var lastTime) && now - lastTime < _resyncCooldownSeconds.Value)
		{
			Logger.LogInfo((object)$"[RoadMapper] Ignoring resync request from {sender} because they are spamming it.");
			yield break;
		}
		_lastResyncTime[sender] = now;
		ResyncRPC.SendPackage(sender, BuildResyncPackage());
		Logger.LogInfo((object)$"[RoadMapper] Sent resync data to {sender}");
	}

	private IEnumerator ClientReceiveResyncData(long sender, ZPackage package)
	{
		int count = package.ReadInt();
		List<MarkerPoint> points = new List<MarkerPoint>(count);
		for (int i = 0; i < count; i++)
		{
			points.Add(new MarkerPoint
			{
				x = package.ReadSingle(),
				z = package.ReadSingle(),
				BrushId = package.ReadInt()
			});
		}
		_syncedPoints = points;
		Logger.LogInfo((object)$"[RoadMapper] Received resync data: {points.Count} points.");
		DrawMarkerOverlay();
		yield break;
	}

	private IEnumerator ClientReceivePathMarker(long sender, ZPackage package)
	{
		yield break;
	}

	private void CreatePieces()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Expected O, but got Unknown
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Expected O, but got Unknown
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Expected O, but got Unknown
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Expected O, but got Unknown
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Expected O, but got Unknown
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Expected O, but got Unknown
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Expected O, but got Unknown
		PrefabManager.OnVanillaPrefabsAvailable -= CreatePieces;
		PieceConfig val = new PieceConfig();
		val.Name = "Path Marker";
		val.Description = "Marks a path outline on the map. Does not affect terrain.";
		val.PieceTable = PieceTables.Hoe;
		val.Category = "Map Markers";
		val.Icon = LoadIcon("Icons/PathIcon.png");
		PieceManager.Instance.AddPiece(new CustomPiece("RoadMapper_PathMarker", "mud_road_v2", val));
		PieceConfig val2 = new PieceConfig();
		val2.Name = "Road Marker";
		val2.Description = "Like the path marker, but for major roads.";
		val2.PieceTable = PieceTables.Hoe;
		val2.Category = "Map Markers";
		val2.Icon = LoadIcon("Icons/RoadIcon.png");
		PieceManager.Instance.AddPiece(new CustomPiece("RoadMapper_RoadMarker", "mud_road_v2", val2));
		PieceConfig val3 = new PieceConfig();
		val3.Name = "Wall Marker";
		val3.Description = "Marks out walls on the map.";
		val3.PieceTable = PieceTables.Hoe;
		val3.Category = "Map Markers";
		val3.Icon = LoadIcon("Icons/WallIcon.png");
		PieceManager.Instance.AddPiece(new CustomPiece("RoadMapper_WallMarker", "mud_road_v2", val3));
		PieceConfig val4 = new PieceConfig();
		val4.Name = "Fence Marker";
		val4.Description = "Marks out fences on the map.";
		val4.PieceTable = PieceTables.Hoe;
		val4.Category = "Map Markers";
		val4.Icon = LoadIcon("Icons/FenceIcon.png");
		PieceManager.Instance.AddPiece(new CustomPiece("RoadMapper_FenceMarker", "mud_road_v2", val4));
		PieceConfig val5 = new PieceConfig();
		val5.Name = "Mark Eraser";
		val5.Description = "Erases all marks from the map.";
		val5.PieceTable = PieceTables.Hoe;
		val5.Category = "Map Markers";
		val5.Icon = LoadIcon("Icons/EraserIcon.png");
		PieceManager.Instance.AddPiece(new CustomPiece("RoadMapper_Eraser", "mud_road_v2", val5));
	}

	private void RecordMarkerPoint(float x, float z, int brushId)
	{
		Logger.LogInfo((object)$"[RoadMapper] Recording paint coord: ({x:F1}, {z:F1}, {brushId})");
		try
		{
			string worldDataFilePath = GetWorldDataFilePath();
			string contents = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}{3}", x, z, brushId, Environment.NewLine);
			File.AppendAllText(worldDataFilePath, contents);
			Logger.LogDebug((object)("[RoadMapper] Wrote point to " + worldDataFilePath));
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("[RoadMapper] A fuck up occurred. " + ex.GetType().Name + ": " + ex.Message + "\n" + ex.StackTrace));
		}
	}

	private IEnumerator ServerReceivePathMarker(long sender, ZPackage package)
	{
		float x = package.ReadSingle();
		float z = package.ReadSingle();
		int brushId = package.ReadInt();
		RecordMarkerPoint(x, z, brushId);
		yield break;
	}
}