Decompiled source of RoombaMines v1.1.6

RoombaMines.dll

Decompiled 3 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoombaMines.NetcodePatcher;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("RoombaMines")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Mines move around like Roombas")]
[assembly: AssemblyFileVersion("1.1.5.0")]
[assembly: AssemblyInformationalVersion("1.1.5+51d9983fa3e3e49e0967ed8f065cc3cca7989b7a")]
[assembly: AssemblyProduct("RoombaMines")]
[assembly: AssemblyTitle("RoombaMines")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RoombaMines
{
	[BepInPlugin("RoombaMines", "RoombaMines", "1.1.5")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public class NetworkObjectManager
		{
			public static GameObject roombaPrefab;

			public static int mineIndex;

			[HarmonyPatch(typeof(GameNetworkManager), "Start")]
			[HarmonyPostfix]
			public static void Init()
			{
				NetworkManager.Singleton.NetworkConfig.ForceSamePrefabs = false;
			}

			[HarmonyPatch(typeof(RoundManager), "SpawnMapObjects")]
			[HarmonyPrefix]
			public static void MinePrefabPatch(RoundManager __instance)
			{
				if ((Object)(object)roombaPrefab == (Object)null)
				{
					for (mineIndex = 0; mineIndex < __instance.currentLevel.spawnableMapObjects.Length; mineIndex++)
					{
						if (Object.op_Implicit((Object)(object)__instance.currentLevel.spawnableMapObjects[mineIndex].prefabToSpawn.GetComponentInChildren<Landmine>()))
						{
							roombaPrefab = __instance.currentLevel.spawnableMapObjects[mineIndex].prefabToSpawn;
							break;
						}
					}
					roombaPrefab.AddComponent<NetworkTransform>();
					roombaPrefab.AddComponent<Roomba>();
					NetworkManager.Singleton.RemoveNetworkPrefab(__instance.currentLevel.spawnableMapObjects[mineIndex].prefabToSpawn);
					NetworkManager.Singleton.AddNetworkPrefab(roombaPrefab);
				}
				__instance.currentLevel.spawnableMapObjects[mineIndex].prefabToSpawn = roombaPrefab;
			}
		}

		public class Roomba : NetworkBehaviour
		{
			public enum MovementState
			{
				Idle,
				Forward,
				RotateRight,
				RotateLeft
			}

			public MovementState state;

			public Landmine mine;

			public string scanName;

			private int _tick_timer = 0;

			private int _tick_length = roombaUpdateTickLength.Value;

			private float _fixed_tick_time = 0f;

			private float _move_rate = roombaMoveSpeed.Value;

			private float _rotate_rate = roombaTurnSpeed.Value;

			private readonly float _scale = 0.55f;

			private readonly float _scale_vert = 0.2f;

			private int _mask = StartOfRound.Instance.allPlayersCollideWithMask;

			private void Awake()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				RaycastHit val = default(RaycastHit);
				if (((Component)this).transform.position.y > -50f || Random.Range(0f, 1f) > mineBecomesRoombaChance.Value)
				{
					((Behaviour)this).enabled = false;
				}
				else if (Physics.Raycast(((Component)this).transform.position, ((Component)this).transform.forward, ref val, _scale * 1.42f, _mask & -2097153) || Physics.Raycast(((Component)this).transform.position, -((Component)this).transform.forward, ref val, _scale * 1.42f, _mask & -2097153) || Physics.Raycast(((Component)this).transform.position, ((Component)this).transform.right, ref val, _scale * 1.42f, _mask & -2097153) || Physics.Raycast(((Component)this).transform.position, -((Component)this).transform.right, ref val, _scale * 1.42f, _mask & -2097153))
				{
					Vector3 position = ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * _scale * 2f;
					((Component)this).transform.position = position;
				}
			}

			private void Start()
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				state = MovementState.RotateRight;
				Vector3 position = ((Component)this).transform.position;
				Debug.Log((object)("Roomba at position: " + ((object)(Vector3)(ref position)).ToString()));
				_fixed_tick_time = Time.fixedDeltaTime * (float)_tick_length;
			}

			public override void OnNetworkSpawn()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				((NetworkBehaviour)this).OnNetworkSpawn();
				mine = ((Component)this).gameObject.GetComponentInChildren<Landmine>();
				((Component)mine).transform.localScale = new Vector3(1f, 1f, 1.1f);
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					SetNameServerRPC(roombaNames[Random.Range(0, roombaNames.Count)]);
				}
			}

			[ServerRpc(RequireOwnership = false)]
			public void SetNameServerRPC(string newName)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Invalid comparison between Unknown and I4
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager == null || !networkManager.IsListening)
				{
					return;
				}
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1048009792u, val, (RpcDelivery)0);
					bool flag = newName != null;
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
					if (flag)
					{
						((FastBufferWriter)(ref val2)).WriteValueSafe(newName, false);
					}
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1048009792u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer))
				{
					Debug.Log((object)("Host: Set Roomba name: " + newName));
					SetNameClientRPC(newName);
				}
			}

			[ClientRpc]
			public void SetNameClientRPC(string newName)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Invalid comparison between Unknown and I4
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager == null || !networkManager.IsListening)
				{
					return;
				}
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(945291587u, val, (RpcDelivery)0);
					bool flag = newName != null;
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
					if (flag)
					{
						((FastBufferWriter)(ref val2)).WriteValueSafe(newName, false);
					}
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 945291587u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Debug.Log((object)("Client: Set Roomba name: " + newName));
					scanName = newName;
					((Component)((Component)mine).transform.parent).GetComponentInChildren<ScanNodeProperties>().headerText = scanName;
				}
			}

			private void Update()
			{
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				if (!((Behaviour)mine).enabled)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				else if ((NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) && !mine.hasExploded)
				{
					if (state == MovementState.Forward)
					{
						Transform transform = ((Component)this).transform;
						transform.position += ((Component)this).transform.forward * Time.deltaTime * _move_rate;
					}
					else if (state == MovementState.RotateRight)
					{
						((Component)this).transform.Rotate(((Component)this).transform.up, Time.deltaTime * _rotate_rate);
					}
					else if (state == MovementState.RotateLeft)
					{
						((Component)this).transform.Rotate(-((Component)this).transform.up, Time.deltaTime * _rotate_rate);
					}
				}
			}

			private void FixedUpdate()
			{
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d9: 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_00a6: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				if ((!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer) || mine.hasExploded)
				{
					return;
				}
				_tick_timer++;
				if (_tick_timer < _tick_length)
				{
					return;
				}
				_tick_timer = 0;
				RaycastHit val = default(RaycastHit);
				if (!Physics.Raycast(((Component)this).transform.position, -((Component)this).transform.up, 0.1f, _mask, (QueryTriggerInteraction)1) && Physics.Raycast(((Component)this).transform.position, -((Component)this).transform.up, ref val, 5f, _mask, (QueryTriggerInteraction)1))
				{
					((Component)this).transform.position = ((RaycastHit)(ref val)).point;
					Debug.Log((object)("Moving mine to Y coord " + ((Component)this).transform.position.y));
				}
				bool flag = !Physics.CheckBox(((Component)this).transform.position + ((Component)this).transform.forward * (_scale + _fixed_tick_time * _move_rate / 2f) + ((Component)this).transform.up * 0.01f, new Vector3(_scale, 0.005f, _fixed_tick_time * _move_rate / 2f), ((Component)this).transform.rotation, _mask, (QueryTriggerInteraction)1);
				bool flag2 = Physics.Raycast(((Component)this).transform.position + ((Component)this).transform.forward * (_scale + _fixed_tick_time * _move_rate), -((Component)this).transform.up, 0.1f, _mask, (QueryTriggerInteraction)1);
				if (flag && flag2)
				{
					state = MovementState.Forward;
				}
				else if (state == MovementState.Forward)
				{
					if (!roombaAllowRotateLeft.Value || Random.Range(0, 2) == 0)
					{
						state = MovementState.RotateRight;
					}
					else
					{
						state = MovementState.RotateLeft;
					}
				}
			}

			protected override void __initializeVariables()
			{
				((NetworkBehaviour)this).__initializeVariables();
			}

			[RuntimeInitializeOnLoadMethod]
			internal static void InitializeRPCS_Roomba()
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Expected O, but got Unknown
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				NetworkManager.__rpc_func_table.Add(1048009792u, new RpcReceiveHandler(__rpc_handler_1048009792));
				NetworkManager.__rpc_func_table.Add(945291587u, new RpcReceiveHandler(__rpc_handler_945291587));
			}

			private static void __rpc_handler_1048009792(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
			{
				//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)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = target.NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					bool flag = default(bool);
					((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
					string nameServerRPC = null;
					if (flag)
					{
						((FastBufferReader)(ref reader)).ReadValueSafe(ref nameServerRPC, false);
					}
					target.__rpc_exec_stage = (__RpcExecStage)1;
					((Roomba)(object)target).SetNameServerRPC(nameServerRPC);
					target.__rpc_exec_stage = (__RpcExecStage)0;
				}
			}

			private static void __rpc_handler_945291587(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
			{
				//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)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = target.NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					bool flag = default(bool);
					((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
					string nameClientRPC = null;
					if (flag)
					{
						((FastBufferReader)(ref reader)).ReadValueSafe(ref nameClientRPC, false);
					}
					target.__rpc_exec_stage = (__RpcExecStage)2;
					((Roomba)(object)target).SetNameClientRPC(nameClientRPC);
					target.__rpc_exec_stage = (__RpcExecStage)0;
				}
			}

			protected internal override string __getTypeName()
			{
				return "Roomba";
			}
		}

		public static AssetBundle ModAssets;

		public static ConfigEntry<float> roombaMoveSpeed;

		public static ConfigEntry<float> roombaTurnSpeed;

		public static ConfigEntry<int> roombaUpdateTickLength;

		public static ConfigEntry<bool> roombaAllowRotateLeft;

		public static ConfigEntry<float> mineBecomesRoombaChance;

		public static List<string> roombaNames;

		public static string roombaNameFilePath = Application.persistentDataPath + "/roomba_names.txt";

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RoombaMines is loaded!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Embedded resources found:");
			string[] manifestResourceNames = ((object)this).GetType().Assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)(text ?? ""));
			}
			roombaMoveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "RoombaMoveSpeed", 0.5f, "Speed of the Roomba when moving forward (measured in m/s)\nNote: Roomba behavior can only be affected by the host. These settings do nothing for the clients.");
			roombaTurnSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "RoombaTurnSpeed", 50f, "How quickly the Roomba will rotate when it's hit a wall (measured in degrees/s)");
			roombaUpdateTickLength = ((BaseUnityPlugin)this).Config.Bind<int>("Behavior", "RoombaUpdateTickLength", 30, "Roombas check for obstructions at the beginning of every tick, this determines how long those ticks last (measured in 1/60ths of a second)");
			roombaAllowRotateLeft = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "RoombaAllowRotateLeft", false, "If true, Roombas will turn left 50% of the time, otherwise they will always turn right");
			mineBecomesRoombaChance = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "MineBecomesRoombaChance", 1f, "The probability a mine will behave like a Roomba after it's spawned. A value of 1.0 will result in every mine becoming a Roomba, a value of 0.0 will effectively disable the mod, 0.5 will result in half normal mines, etc.");
			if (!File.Exists(roombaNameFilePath))
			{
				StreamWriter streamWriter = new StreamWriter(roombaNameFilePath);
				streamWriter.Write("John\nGeorge\nPaul\nRingo\nHenry\nWilliam\nJoshua\nSam\nFred\nVinny\nRoss\nJoey");
				streamWriter.Close();
			}
			roombaNames = new List<string>(File.ReadAllText(roombaNameFilePath).Split("\n"));
			NetcodePatcher();
			Harmony.CreateAndPatchAll(typeof(NetworkObjectManager), (string)null);
		}

		private static void NetcodePatcher()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "RoombaMines";

		public const string PLUGIN_NAME = "RoombaMines";

		public const string PLUGIN_VERSION = "1.1.5";
	}
}
namespace RoombaMines.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("RoombaMines.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace RoombaMines.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}