Decompiled source of GridLock v1.0.1

GridLock.dll

Decompiled 11 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AskaGridLock.Core;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Fusion;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using SSSGame;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GridLock")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1+6379a3b43be4ae7432101963c1d23ba7fe81d4b2")]
[assembly: AssemblyProduct("Grid Lock")]
[assembly: AssemblyTitle("GridLock")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 AskaShared
{
	internal static class ConfigMigration
	{
		private const string NewPrefix = "mugsy33.";

		private const string OldPrefix = "smithio.aska.";

		internal static void Run(ConfigFile config, ManualLogSource log)
		{
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			bool flag = false;
			string text = null;
			bool flag2 = default(bool);
			try
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(config.ConfigFilePath);
				if (!fileNameWithoutExtension.StartsWith("mugsy33.", StringComparison.Ordinal))
				{
					return;
				}
				string text2 = "smithio.aska." + fileNameWithoutExtension.Substring("mugsy33.".Length);
				text = Path.Combine(Paths.ConfigPath, fileNameWithoutExtension + ".cfg");
				string text3 = Path.Combine(Paths.ConfigPath, text2 + ".cfg");
				string text4 = Path.Combine(Paths.ConfigPath, text2 + ".cfg.migrated");
				if (File.Exists(text))
				{
					if (File.Exists(text4))
					{
						File.Delete(text4);
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Deleted migrated legacy configuration: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
						}
						log.LogInfo(val);
					}
					else if (File.Exists(text3))
					{
						File.Move(text3, text4, overwrite: true);
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Legacy configuration renamed to ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
						}
						log.LogInfo(val);
					}
				}
				else if (File.Exists(text3))
				{
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Legacy configuration detected: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
					}
					log.LogInfo(val);
					string text5 = text + ".tmp";
					File.Copy(text3, text5, overwrite: true);
					File.Move(text5, text, overwrite: true);
					flag = true;
					val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Migrated legacy configuration to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					}
					log.LogInfo(val);
					config.Reload();
					File.Move(text3, text4, overwrite: true);
					val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Legacy configuration renamed to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
					}
					log.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(62, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Configuration migration failed; using existing configuration. ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogWarning(val2);
				if (flag && text != null)
				{
					try
					{
						File.Delete(text);
						return;
					}
					catch
					{
						return;
					}
				}
			}
		}
	}
}
namespace AskaGridLock
{
	[HarmonyPatch(typeof(Character))]
	public static class CharacterSpawnPatch
	{
		internal static Character LocalCharacter { get; private set; }

		[HarmonyPostfix]
		[HarmonyPatch("Spawned")]
		public static void Spawned(Character __instance)
		{
			//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)
			if (__instance.IsPlayer() && ((NetworkBehaviour)__instance).GetLocalAuthorityMask() == 1)
			{
				LocalCharacter = __instance;
				if (!((Object)(object)((Component)__instance).GetComponentInChildren<GridLockTool>() != (Object)null))
				{
					GameObject val = new GameObject("GridLockTool");
					val.transform.SetParent(((Component)__instance).gameObject.transform, false);
					val.AddComponent<GridLockTool>();
					Plugin.Log.LogInfo((object)"GridLockTool attached to local player.");
				}
			}
		}
	}
	internal static class GridLockConfig
	{
		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<bool> _snapTerrain;

		private static ConfigEntry<double> _spacing;

		private static ConfigEntry<double> _rotationStep;

		private const double SquareSize = 2.0;

		internal static ConfigEntry<KeyCode> FreeMoveKey;

		internal static bool Enabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return false;
			}
		}

		internal static bool SnapTerrain
		{
			get
			{
				if (_snapTerrain != null)
				{
					return _snapTerrain.Value;
				}
				return false;
			}
		}

		internal static GridConfig Grid { get; private set; }

		internal static void Init(ConfigFile config)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			_enabled = config.Bind<bool>("Grid", "Enabled", true, "Master switch. When false the mod snaps nothing.");
			_snapTerrain = config.Bind<bool>("Grid", "SnapTerrain", true, "Snap the Terrain Level Field tool's start point to the grid so leveled areas align with placed structures.");
			_spacing = config.Bind<double>("Grid", "Spacing", 0.5, "Minimum snap increment, in terraforming squares. One square is 2 world units, so the world snap step is Spacing * 2 (default 0.5 = 1.0 units).");
			_rotationStep = config.Bind<double>("Grid", "RotationStep", 15.0, "Rotation snap increment in degrees.");
			FreeMoveKey = config.Bind<KeyCode>("Grid", "FreeMoveKey", (KeyCode)304, "Hold to move the ghost freely off the grid, preserving its current rotation. Release to re-snap to the nearest grid pose.");
			GridConfig grid = default(GridConfig);
			((GridConfig)(ref grid))..ctor(_spacing.Value, _rotationStep.Value, 2.0);
			Grid = grid;
			bool flag = default(bool);
			if (((GridConfig)(ref grid)).Spacing != _spacing.Value)
			{
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock] Spacing ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(_spacing.Value);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clamped to ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(((GridConfig)(ref grid)).Spacing);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				log.LogInfo(val);
			}
			if (((GridConfig)(ref grid)).RotationStep != _rotationStep.Value)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock] RotationStep ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(_rotationStep.Value);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clamped to ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(((GridConfig)(ref grid)).RotationStep);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				log2.LogInfo(val);
			}
		}
	}
	public class GridLockTool : MonoBehaviour
	{
		private void Update()
		{
			SnapPatches.TickFreeMode();
		}
	}
	[BepInPlugin("mugsy33.gridlock", "Grid Lock", "1.0.1")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "mugsy33.gridlock";

		public const string PluginName = "Grid Lock";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log;

		public override void Load()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ClassInjector.RegisterTypeInIl2Cpp<GridLockTool>();
			Harmony.CreateAndPatchAll(typeof(CharacterSpawnPatch), (string)null);
			GridLockConfig.Init(((BasePlugin)this).Config);
			SnapPatches.Arm(new Harmony("mugsy33.gridlock.snap"));
			TerrainSnapPatches.Arm(new Harmony("mugsy33.gridlock.terrain"));
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Grid Lock");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.1");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			log.LogInfo(val);
		}
	}
	internal static class SessionState
	{
		private static PlayerBuilder _builder;

		internal static PlayerBuilder ResolveBuilder()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			try
			{
				if ((Object)(object)_builder != (Object)null)
				{
					return _builder;
				}
				Character localCharacter = CharacterSpawnPatch.LocalCharacter;
				if ((Object)(object)localCharacter != (Object)null)
				{
					PlayerBuilder val = ((Component)localCharacter).GetComponentInChildren<PlayerBuilder>(true);
					if ((Object)(object)val == (Object)null)
					{
						val = ((Component)localCharacter).GetComponentInParent<PlayerBuilder>();
					}
					if ((Object)(object)val != (Object)null)
					{
						_builder = val;
						return _builder;
					}
				}
				_builder = Object.FindObjectOfType<PlayerBuilder>();
				return _builder;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(52, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GridLock] resolving the local PlayerBuilder threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
				return null;
			}
		}

		internal static bool IsLocalPlacementTool(PlacementTool tool)
		{
			try
			{
				if ((Object)(object)tool == (Object)null)
				{
					return false;
				}
				PlayerBuilder val = ResolveBuilder();
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				PlacementTool placementTool = val._placementTool;
				if ((Object)(object)placementTool == (Object)null)
				{
					return false;
				}
				return ((Il2CppObjectBase)placementTool).Pointer == ((Il2CppObjectBase)tool).Pointer;
			}
			catch
			{
				return false;
			}
		}

		internal static void OnBuildModeExited()
		{
			_builder = null;
		}
	}
	internal static class SnapPatches
	{
		private static bool _snapFailureLogged;

		private static bool _endFailureLogged;

		private static bool _tickFailureLogged;

		private static readonly FreeModeState Free = new FreeModeState();

		private static bool _haveWrite;

		private static Vector3 _lastPos;

		private static Quaternion _lastRot = Quaternion.identity;

		private static Vector3 _rawPos;

		private static float _rawYaw;

		private static float _rawPitch;

		private static float _rawRoll;

		private static GridPose _cachedShown;

		private static GridPose _cachedRaw;

		private static bool _wasDown;

		private static IntPtr _templatePtr = IntPtr.Zero;

		private const float PosEps = 0.001f;

		private const float RotEps = 0.05f;

		internal static void Arm(Harmony harmony)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			HarmonyMethod postfix = new HarmonyMethod(typeof(SnapPatches), "SnapPostfix", (Type[])null);
			Type[] parameters = new Type[1] { typeof(Ray) };
			ArmDeclared(harmony, typeof(AnchorPointPlacementTool), "_OnBuildRayChanged", parameters, required: true, null, postfix);
			ArmDeclared(harmony, typeof(SkewedAnchorPointPlacementTool), "_OnBuildRayChanged", parameters, required: false, null, postfix);
			ArmDeclared(harmony, typeof(AnchorPointPlacementTool), "_ValidatePlacement", Type.EmptyTypes, required: true, null, postfix);
			ArmDeclared(harmony, typeof(SkewedAnchorPointPlacementTool), "_ValidatePlacement", Type.EmptyTypes, required: false, null, postfix);
			HarmonyMethod postfix2 = new HarmonyMethod(typeof(SnapPatches), "EndBuildingPostfix", (Type[])null);
			ArmDeclared(harmony, typeof(PlayerBuilder), "_EndBuilding", Type.EmptyTypes, required: true, null, postfix2);
			ArmDeclared(harmony, typeof(PlayerBuilder_NewController), "_EndBuilding", Type.EmptyTypes, required: false, null, postfix2);
			ArmDeclared(harmony, typeof(PlayerBuilder_Invector), "_EndBuilding", Type.EmptyTypes, required: false, null, postfix2);
			ArmDeclared(harmony, typeof(PlayerBuilder_Naughty), "_EndBuilding", Type.EmptyTypes, required: false, null, postfix2);
		}

		private static void SnapPostfix(AnchorPointPlacementTool __instance)
		{
			Apply(__instance);
		}

		private static void Apply(AnchorPointPlacementTool __instance)
		{
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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)
			//IL_018a: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null || !GridLockConfig.Enabled || !SessionState.IsLocalPlacementTool((PlacementTool)(object)__instance))
				{
					return;
				}
				string name = ((MemberInfo)((Object)__instance).GetIl2CppType()).Name;
				if (name != null && name.StartsWith("Skewed", StringComparison.Ordinal))
				{
					return;
				}
				AnchorPointPlacement pointPlacement = __instance._pointPlacement;
				if (pointPlacement == null)
				{
					return;
				}
				GridConfig grid = GridLockConfig.Grid;
				Vector3 position = ((PointPlacement)pointPlacement).position;
				if (!_haveWrite || !(Mathf.Abs(position.x - _lastPos.x) < 0.001f) || !(Mathf.Abs(position.z - _lastPos.z) < 0.001f))
				{
					_rawPos = position;
				}
				Quaternion rotation = ((PointPlacement)pointPlacement).rotation;
				if (!_haveWrite || !(Quaternion.Angle(rotation, _lastRot) < 0.05f))
				{
					Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
					_rawYaw = eulerAngles.y;
					_rawPitch = eulerAngles.x;
					_rawRoll = eulerAngles.z;
				}
				GridPose val = default(GridPose);
				((GridPose)(ref val))..ctor((double)_rawPos.x, (double)_rawPos.z, (double)_rawYaw);
				GridPose cachedShown = default(GridPose);
				if (Free.IsFree)
				{
					cachedShown = Free.PoseWhileFree(val);
				}
				else
				{
					double num = SnapMath.SnapAxis(((GridPose)(ref val)).X, ((GridConfig)(ref grid)).Cell);
					double num2 = SnapMath.SnapAxis(((GridPose)(ref val)).Z, ((GridConfig)(ref grid)).Cell);
					double num3 = SnapMath.SnapYaw(((GridPose)(ref val)).Yaw, ((GridConfig)(ref grid)).RotationStep);
					((GridPose)(ref cachedShown))..ctor(num, num2, num3);
				}
				_cachedRaw = val;
				_cachedShown = cachedShown;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor((float)((GridPose)(ref cachedShown)).X, _rawPos.y, (float)((GridPose)(ref cachedShown)).Z);
				Quaternion val3 = Quaternion.Euler(_rawPitch, (float)((GridPose)(ref cachedShown)).Yaw, _rawRoll);
				((PointPlacement)pointPlacement).position = val2;
				((PointPlacement)pointPlacement).rotation = val3;
				_lastPos = val2;
				_lastRot = val3;
				_haveWrite = true;
				PlayerBuilder val4 = SessionState.ResolveBuilder();
				if (!((Object)(object)val4 != (Object)null))
				{
					return;
				}
				StructurePreviewData previewData = val4.previewData;
				if (previewData == null)
				{
					return;
				}
				NodeStructurePreviewData val5 = ((Il2CppObjectBase)previewData).TryCast<NodeStructurePreviewData>();
				if (val5 != null)
				{
					GameObject previewInstance = val5.previewInstance;
					if ((Object)(object)previewInstance != (Object)null)
					{
						previewInstance.transform.position = val2;
						previewInstance.transform.rotation = val3;
					}
				}
			}
			catch (Exception ex)
			{
				if (!_snapFailureLogged)
				{
					_snapFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val6 = new BepInExErrorLogInterpolatedStringHandler(56, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[GridLock] snap postfix threw (logged once, fail-open): ");
						((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<Exception>(ex);
					}
					log.LogError(val6);
				}
			}
		}

		private static void EndBuildingPostfix(PlayerBuilder __instance)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			try
			{
				SessionState.OnBuildModeExited();
				Free.Reset();
				_wasDown = false;
				_templatePtr = IntPtr.Zero;
				_haveWrite = false;
			}
			catch (Exception ex)
			{
				if (!_endFailureLogged)
				{
					_endFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(64, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock] _EndBuilding postfix threw (logged once, fail-open): ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}

		internal static void TickFreeMode()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (GridLockConfig.FreeMoveKey != null)
				{
					IntPtr intPtr = CurrentTemplatePtr();
					if (intPtr != _templatePtr)
					{
						_templatePtr = intPtr;
						Free.Reset();
						_wasDown = false;
						_haveWrite = false;
					}
					bool key = Input.GetKey(GridLockConfig.FreeMoveKey.Value);
					if (key && !_wasDown)
					{
						Free.EnterFree(_cachedShown, _cachedRaw);
					}
					else if (!key && _wasDown)
					{
						Free.ExitFree();
					}
					_wasDown = key;
				}
			}
			catch (Exception ex)
			{
				if (!_tickFailureLogged)
				{
					_tickFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(56, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock] TickFreeMode threw (logged once, fail-open): ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}

		private static IntPtr CurrentTemplatePtr()
		{
			try
			{
				PlayerBuilder val = SessionState.ResolveBuilder();
				if ((Object)(object)val == (Object)null)
				{
					return IntPtr.Zero;
				}
				StructurePreviewData previewData = val.previewData;
				if (previewData == null)
				{
					return IntPtr.Zero;
				}
				return ((Il2CppObjectBase)previewData).Pointer;
			}
			catch
			{
				return IntPtr.Zero;
			}
		}

		private static void ArmDeclared(Harmony harmony, Type type, string name, Type[] parameters, bool required, HarmonyMethod prefix = null, HarmonyMethod postfix = null)
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null);
				if (methodInfo == null)
				{
					if (required)
					{
						Plugin.Log.LogError((object)($"[GridLock][arm-fail] {type.Name}.{name} not found via DeclaredMethod - " + "the snap patch cannot bind it. If the method is declared on a base type this is the base-vs-override case: find and patch the dispatched declarer."));
						return;
					}
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(72, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is not overridden here - the base implementation covers it.");
					}
					log.LogInfo(val);
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock][armed] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
					}
					log2.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(43, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GridLock][arm-fail] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(type.Name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" threw while arming: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log3.LogError(val2);
			}
		}
	}
	internal static class TerrainSnapPatches
	{
		private static bool _snapFailureLogged;

		internal static void Arm(Harmony harmony)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			HarmonyMethod postfix = new HarmonyMethod(typeof(TerrainSnapPatches), "RayPostfix", (Type[])null);
			Type typeFromHandle = typeof(DynamicDimensionsPlacementTool);
			ArmDeclared(harmony, typeFromHandle, "_OnBuildRayChanged", new Type[1] { typeof(Ray) }, required: true, null, postfix);
			ArmDeclared(harmony, typeFromHandle, "_ValidatePlacement", new Type[1] { typeof(bool) }, required: false, null, postfix);
		}

		private static void RayPostfix(DynamicDimensionsPlacementTool __instance)
		{
			Apply(__instance);
		}

		private static void Apply(DynamicDimensionsPlacementTool __instance)
		{
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null || !GridLockConfig.Enabled || !GridLockConfig.SnapTerrain || !SessionState.IsLocalPlacementTool((PlacementTool)(object)__instance) || !IsStartPoint(__instance))
				{
					return;
				}
				DynamicDimensionsPlacement dynamicPlacement = __instance._dynamicPlacement;
				if (dynamicPlacement == null)
				{
					return;
				}
				Il2CppReferenceArray<PointPlacement> points = ((SegmentPlacement)dynamicPlacement).points;
				if (points == null || ((Il2CppArrayBase<PointPlacement>)(object)points).Length < 1)
				{
					return;
				}
				PointPlacement val = ((Il2CppArrayBase<PointPlacement>)(object)points)[0];
				if (val != null)
				{
					GridConfig grid = GridLockConfig.Grid;
					Vector3 position = val.position;
					double num = SnapMath.SnapAxis((double)position.x, ((GridConfig)(ref grid)).Cell);
					double num2 = SnapMath.SnapAxis((double)position.z, ((GridConfig)(ref grid)).Cell);
					Vector3 position2 = default(Vector3);
					((Vector3)(ref position2))..ctor((float)num, position.y, (float)num2);
					val.position = position2;
					GameObject marker = __instance._marker;
					if ((Object)(object)marker != (Object)null)
					{
						marker.transform.position = position2;
					}
				}
			}
			catch (Exception ex)
			{
				if (!_snapFailureLogged)
				{
					_snapFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(64, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GridLock] terrain snap postfix threw (logged once, fail-open): ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
					}
					log.LogError(val2);
				}
			}
		}

		private static bool IsStartPoint(DynamicDimensionsPlacementTool inst)
		{
			//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)
			try
			{
				return ((object)inst._currentStage/*cast due to .constrained prefix*/).ToString() == "StartPoint";
			}
			catch
			{
				return false;
			}
		}

		private static void ArmDeclared(Harmony harmony, Type type, string name, Type[] parameters, bool required, HarmonyMethod prefix = null, HarmonyMethod postfix = null)
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(type, name, parameters, (Type[])null);
				if (methodInfo == null)
				{
					if (required)
					{
						Plugin.Log.LogError((object)($"[GridLock][arm-fail] {type.Name}.{name} not found via DeclaredMethod - " + "the terrain snap patch cannot bind it."));
						return;
					}
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is not declared here - skipped.");
					}
					log.LogInfo(val);
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GridLock][armed] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
					}
					log2.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(43, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GridLock][arm-fail] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(type.Name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" threw while arming: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log3.LogError(val2);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "GridLock";

		public const string PLUGIN_NAME = "Grid Lock";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}

GridLock.Core.dll

Decompiled 11 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GridLock.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6379a3b43be4ae7432101963c1d23ba7fe81d4b2")]
[assembly: AssemblyProduct("GridLock.Core")]
[assembly: AssemblyTitle("GridLock.Core")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 AskaGridLock.Core
{
	public sealed class FreeModeState
	{
		private GridPose _offset;

		public bool IsFree { get; private set; }

		public void EnterFree(GridPose shownPose, GridPose rawPose)
		{
			_offset = shownPose - rawPose;
			IsFree = true;
		}

		public GridPose PoseWhileFree(GridPose rawPose)
		{
			return rawPose + _offset;
		}

		public void ExitFree()
		{
			_offset = default(GridPose);
			IsFree = false;
		}

		public void Reset()
		{
			_offset = default(GridPose);
			IsFree = false;
		}
	}
	public readonly struct GridConfig
	{
		public const double MinSpacing = 0.01;

		public const double MaxSpacing = 100.0;

		public const double MinRotationStep = 1.0;

		public const double MaxRotationStep = 180.0;

		public const double MinSquareSize = 0.01;

		public const double MaxSquareSize = 1000.0;

		public double Spacing { get; }

		public double RotationStep { get; }

		public double SquareSize { get; }

		public double Cell { get; }

		public bool IsUsable
		{
			get
			{
				if (IsFinite(Spacing) && Spacing > 0.0 && IsFinite(RotationStep) && RotationStep > 0.0 && IsFinite(SquareSize) && SquareSize > 0.0 && IsFinite(Cell))
				{
					return Cell > 0.0;
				}
				return false;
			}
		}

		public GridConfig(double spacing, double rotationStep, double squareSize)
		{
			Spacing = Clamp(spacing, 0.01, 100.0);
			RotationStep = Clamp(rotationStep, 1.0, 180.0);
			SquareSize = Clamp(squareSize, 0.01, 1000.0);
			Cell = Spacing * SquareSize;
		}

		public static bool IsFinite(double value)
		{
			if (!double.IsNaN(value))
			{
				return !double.IsInfinity(value);
			}
			return false;
		}

		private static double Clamp(double value, double min, double max)
		{
			if (double.IsNaN(value))
			{
				return min;
			}
			if (double.IsPositiveInfinity(value))
			{
				return max;
			}
			if (double.IsNegativeInfinity(value))
			{
				return min;
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}
	}
	public readonly struct GridPose
	{
		public double X { get; }

		public double Z { get; }

		public double Yaw { get; }

		public GridPose(double x, double z, double yaw)
		{
			X = x;
			Z = z;
			Yaw = yaw;
		}

		public static GridPose operator +(GridPose a, GridPose b)
		{
			return new GridPose(a.X + b.X, a.Z + b.Z, a.Yaw + b.Yaw);
		}

		public static GridPose operator -(GridPose a, GridPose b)
		{
			return new GridPose(a.X - b.X, a.Z - b.Z, a.Yaw - b.Yaw);
		}
	}
	public static class SnapMath
	{
		public static double SnapAxis(double world, double cell)
		{
			if (!GridConfig.IsFinite(cell) || cell <= 0.0)
			{
				return world;
			}
			double num = Math.Round(world / cell, MidpointRounding.AwayFromZero) * cell;
			if (!GridConfig.IsFinite(num))
			{
				return world;
			}
			return num;
		}

		public static GridPose SnapPosition(GridPose pose, double cell)
		{
			return new GridPose(SnapAxis(pose.X, cell), SnapAxis(pose.Z, cell), pose.Yaw);
		}

		public static double SnapYaw(double yaw, double step)
		{
			if (!GridConfig.IsFinite(step) || step <= 0.0)
			{
				return yaw;
			}
			double num = Math.Round(yaw / step, MidpointRounding.AwayFromZero) * step;
			if (!GridConfig.IsFinite(num))
			{
				return yaw;
			}
			return NormalizeDegrees(num);
		}

		private static double NormalizeDegrees(double degrees)
		{
			double num = degrees % 360.0;
			if (num < 0.0)
			{
				num += 360.0;
			}
			if (num >= 360.0)
			{
				num -= 360.0;
			}
			return num;
		}
	}
}