Decompiled source of RainbowGuard v1.0.0

Mods/RainbowGuard.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using MelonLoader;
using MelonLoader.NativeUtils;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using RainbowGuard;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(global::RainbowGuard.RainbowGuard), "RainbowGuard", "1.0.0", "ninjaguardian", "https://thunderstore.io/c/rumble/p/ninjaguardian/RainbowGuard")]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(255, 0, 160, 230)]
[assembly: MelonAuthorColor(255, 0, 160, 230)]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: VerifyLoaderVersion("0.7.3", true)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ninjaguardian (github)")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2026 ninjaguardian (github), This work is dedicated to the public domain under CC0 1.0.")]
[assembly: AssemblyDescription("Changes the color of the guard effect")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RainbowGuard")]
[assembly: AssemblyTitle("RainbowGuard")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ninjaguardian/RainbowGuard")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
}
namespace RainbowGuard
{
	internal static class WindowHandle
	{
		[return: MarshalAs(UnmanagedType.Bool)]
		private delegate bool EnumThreadDelegate([In] IntPtr hWnd, [In] IntPtr lParam);

		private static readonly EnumThreadDelegate Callback = EnumThreadCallback;

		private static IntPtr _foundHwnd;

		private static bool EnumThreadCallback(IntPtr hWnd, IntPtr lParam)
		{
			if (_foundHwnd == IntPtr.Zero)
			{
				_foundHwnd = hWnd;
			}
			return true;
		}

		[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool EnumThreadWindows([In] uint dwThreadId, [In] EnumThreadDelegate lpfn, [In] IntPtr lParam);

		[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
		private static extern uint GetCurrentThreadId();

		internal static IntPtr GetWindowHandle()
		{
			_foundHwnd = IntPtr.Zero;
			EnumThreadWindows(GetCurrentThreadId(), Callback, IntPtr.Zero);
			return _foundHwnd;
		}
	}
	internal static class DXInterop
	{
		internal enum HResult
		{
			S_OK = 0,
			S_FALSE = 1,
			E_INVALIDARG = -2147024809,
			E_OUTOFMEMORY = -2147024882,
			E_FAIL = -2147467259
		}

		internal enum D3D11_MAP : uint
		{
			D3D11_MAP_READ = 1u,
			D3D11_MAP_WRITE,
			D3D11_MAP_READ_WRITE,
			D3D11_MAP_WRITE_DISCARD,
			D3D11_MAP_WRITE_NO_OVERWRITE
		}

		[Flags]
		internal enum D3D11_MAP_FLAG : uint
		{
			D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000u
		}

		private enum D3D_FEATURE_LEVEL : uint
		{
			D3D_FEATURE_LEVEL_1_0_GENERIC = 256u,
			D3D_FEATURE_LEVEL_1_0_CORE = 4096u,
			D3D_FEATURE_LEVEL_9_1 = 37120u,
			D3D_FEATURE_LEVEL_9_2 = 37376u,
			D3D_FEATURE_LEVEL_9_3 = 37632u,
			D3D_FEATURE_LEVEL_10_0 = 40960u,
			D3D_FEATURE_LEVEL_10_1 = 41216u,
			D3D_FEATURE_LEVEL_11_0 = 45056u,
			D3D_FEATURE_LEVEL_11_1 = 45312u,
			D3D_FEATURE_LEVEL_12_0 = 49152u,
			D3D_FEATURE_LEVEL_12_1 = 49408u,
			D3D_FEATURE_LEVEL_12_2 = 49664u
		}

		private enum D3D_DRIVER_TYPE : uint
		{
			D3D_DRIVER_TYPE_UNKNOWN,
			D3D_DRIVER_TYPE_HARDWARE,
			D3D_DRIVER_TYPE_REFERENCE,
			D3D_DRIVER_TYPE_NULL,
			D3D_DRIVER_TYPE_SOFTWARE,
			D3D_DRIVER_TYPE_WARP
		}

		private enum DXGI_FORMAT : uint
		{
			DXGI_FORMAT_UNKNOWN = 0u,
			DXGI_FORMAT_R32G32B32A32_TYPELESS = 1u,
			DXGI_FORMAT_R32G32B32A32_FLOAT = 2u,
			DXGI_FORMAT_R32G32B32A32_UINT = 3u,
			DXGI_FORMAT_R32G32B32A32_SINT = 4u,
			DXGI_FORMAT_R32G32B32_TYPELESS = 5u,
			DXGI_FORMAT_R32G32B32_FLOAT = 6u,
			DXGI_FORMAT_R32G32B32_UINT = 7u,
			DXGI_FORMAT_R32G32B32_SINT = 8u,
			DXGI_FORMAT_R16G16B16A16_TYPELESS = 9u,
			DXGI_FORMAT_R16G16B16A16_FLOAT = 10u,
			DXGI_FORMAT_R16G16B16A16_UNORM = 11u,
			DXGI_FORMAT_R16G16B16A16_UINT = 12u,
			DXGI_FORMAT_R16G16B16A16_SNORM = 13u,
			DXGI_FORMAT_R16G16B16A16_SINT = 14u,
			DXGI_FORMAT_R32G32_TYPELESS = 15u,
			DXGI_FORMAT_R32G32_FLOAT = 16u,
			DXGI_FORMAT_R32G32_UINT = 17u,
			DXGI_FORMAT_R32G32_SINT = 18u,
			DXGI_FORMAT_R32G8X24_TYPELESS = 19u,
			DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20u,
			DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21u,
			DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22u,
			DXGI_FORMAT_R10G10B10A2_TYPELESS = 23u,
			DXGI_FORMAT_R10G10B10A2_UNORM = 24u,
			DXGI_FORMAT_R10G10B10A2_UINT = 25u,
			DXGI_FORMAT_R11G11B10_FLOAT = 26u,
			DXGI_FORMAT_R8G8B8A8_TYPELESS = 27u,
			DXGI_FORMAT_R8G8B8A8_UNORM = 28u,
			DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29u,
			DXGI_FORMAT_R8G8B8A8_UINT = 30u,
			DXGI_FORMAT_R8G8B8A8_SNORM = 31u,
			DXGI_FORMAT_R8G8B8A8_SINT = 32u,
			DXGI_FORMAT_R16G16_TYPELESS = 33u,
			DXGI_FORMAT_R16G16_FLOAT = 34u,
			DXGI_FORMAT_R16G16_UNORM = 35u,
			DXGI_FORMAT_R16G16_UINT = 36u,
			DXGI_FORMAT_R16G16_SNORM = 37u,
			DXGI_FORMAT_R16G16_SINT = 38u,
			DXGI_FORMAT_R32_TYPELESS = 39u,
			DXGI_FORMAT_D32_FLOAT = 40u,
			DXGI_FORMAT_R32_FLOAT = 41u,
			DXGI_FORMAT_R32_UINT = 42u,
			DXGI_FORMAT_R32_SINT = 43u,
			DXGI_FORMAT_R24G8_TYPELESS = 44u,
			DXGI_FORMAT_D24_UNORM_S8_UINT = 45u,
			DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46u,
			DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47u,
			DXGI_FORMAT_R8G8_TYPELESS = 48u,
			DXGI_FORMAT_R8G8_UNORM = 49u,
			DXGI_FORMAT_R8G8_UINT = 50u,
			DXGI_FORMAT_R8G8_SNORM = 51u,
			DXGI_FORMAT_R8G8_SINT = 52u,
			DXGI_FORMAT_R16_TYPELESS = 53u,
			DXGI_FORMAT_R16_FLOAT = 54u,
			DXGI_FORMAT_D16_UNORM = 55u,
			DXGI_FORMAT_R16_UNORM = 56u,
			DXGI_FORMAT_R16_UINT = 57u,
			DXGI_FORMAT_R16_SNORM = 58u,
			DXGI_FORMAT_R16_SINT = 59u,
			DXGI_FORMAT_R8_TYPELESS = 60u,
			DXGI_FORMAT_R8_UNORM = 61u,
			DXGI_FORMAT_R8_UINT = 62u,
			DXGI_FORMAT_R8_SNORM = 63u,
			DXGI_FORMAT_R8_SINT = 64u,
			DXGI_FORMAT_A8_UNORM = 65u,
			DXGI_FORMAT_R1_UNORM = 66u,
			DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67u,
			DXGI_FORMAT_R8G8_B8G8_UNORM = 68u,
			DXGI_FORMAT_G8R8_G8B8_UNORM = 69u,
			DXGI_FORMAT_BC1_TYPELESS = 70u,
			DXGI_FORMAT_BC1_UNORM = 71u,
			DXGI_FORMAT_BC1_UNORM_SRGB = 72u,
			DXGI_FORMAT_BC2_TYPELESS = 73u,
			DXGI_FORMAT_BC2_UNORM = 74u,
			DXGI_FORMAT_BC2_UNORM_SRGB = 75u,
			DXGI_FORMAT_BC3_TYPELESS = 76u,
			DXGI_FORMAT_BC3_UNORM = 77u,
			DXGI_FORMAT_BC3_UNORM_SRGB = 78u,
			DXGI_FORMAT_BC4_TYPELESS = 79u,
			DXGI_FORMAT_BC4_UNORM = 80u,
			DXGI_FORMAT_BC4_SNORM = 81u,
			DXGI_FORMAT_BC5_TYPELESS = 82u,
			DXGI_FORMAT_BC5_UNORM = 83u,
			DXGI_FORMAT_BC5_SNORM = 84u,
			DXGI_FORMAT_B5G6R5_UNORM = 85u,
			DXGI_FORMAT_B5G5R5A1_UNORM = 86u,
			DXGI_FORMAT_B8G8R8A8_UNORM = 87u,
			DXGI_FORMAT_B8G8R8X8_UNORM = 88u,
			DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89u,
			DXGI_FORMAT_B8G8R8A8_TYPELESS = 90u,
			DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91u,
			DXGI_FORMAT_B8G8R8X8_TYPELESS = 92u,
			DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93u,
			DXGI_FORMAT_BC6H_TYPELESS = 94u,
			DXGI_FORMAT_BC6H_UF16 = 95u,
			DXGI_FORMAT_BC6H_SF16 = 96u,
			DXGI_FORMAT_BC7_TYPELESS = 97u,
			DXGI_FORMAT_BC7_UNORM = 98u,
			DXGI_FORMAT_BC7_UNORM_SRGB = 99u,
			DXGI_FORMAT_AYUV = 100u,
			DXGI_FORMAT_Y410 = 101u,
			DXGI_FORMAT_Y416 = 102u,
			DXGI_FORMAT_NV12 = 103u,
			DXGI_FORMAT_P010 = 104u,
			DXGI_FORMAT_P016 = 105u,
			DXGI_FORMAT_420_OPAQUE = 106u,
			DXGI_FORMAT_YUY2 = 107u,
			DXGI_FORMAT_Y210 = 108u,
			DXGI_FORMAT_Y216 = 109u,
			DXGI_FORMAT_NV11 = 110u,
			DXGI_FORMAT_AI44 = 111u,
			DXGI_FORMAT_IA44 = 112u,
			DXGI_FORMAT_P8 = 113u,
			DXGI_FORMAT_A8P8 = 114u,
			DXGI_FORMAT_B4G4R4A4_UNORM = 115u,
			DXGI_FORMAT_P208 = 130u,
			DXGI_FORMAT_V208 = 131u,
			DXGI_FORMAT_V408 = 132u,
			DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189u,
			DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190u,
			DXGI_FORMAT_A4B4G4R4_UNORM = 191u,
			DXGI_FORMAT_FORCE_UINT = uint.MaxValue
		}

		private enum DXGI_MODE_SCANLINE_ORDER : uint
		{
			DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
			DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE,
			DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST,
			DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST
		}

		private enum DXGI_MODE_SCALING : uint
		{
			DXGI_MODE_SCALING_UNSPECIFIED,
			DXGI_MODE_SCALING_CENTERED,
			DXGI_MODE_SCALING_STRETCHED
		}

		private enum DXGI_SWAP_EFFECT : uint
		{
			DXGI_SWAP_EFFECT_DISCARD = 0u,
			DXGI_SWAP_EFFECT_SEQUENTIAL = 1u,
			DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3u,
			DXGI_SWAP_EFFECT_FLIP_DISCARD = 4u
		}

		[Flags]
		private enum DXGI_USAGE : uint
		{
			DXGI_USAGE_SHADER_INPUT = 0x10u,
			DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x20u,
			DXGI_USAGE_BACK_BUFFER = 0x40u,
			DXGI_USAGE_SHARED = 0x80u,
			DXGI_USAGE_READ_ONLY = 0x100u,
			DXGI_USAGE_DISCARD_ON_PRESENT = 0x200u,
			DXGI_USAGE_UNORDERED_ACCESS = 0x400u
		}

		[Flags]
		private enum DXGI_SWAP_CHAIN_FLAG : uint
		{
			DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1u,
			DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2u,
			DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4u,
			DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8u,
			DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 0x10u,
			DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 0x20u,
			DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 0x40u,
			DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 0x80u,
			DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 0x100u,
			DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 0x200u,
			DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED = 0x400u,
			DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING = 0x800u,
			DXGI_SWAP_CHAIN_FLAG_RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 0x1000u
		}

		private struct DXGI_RATIONAL
		{
			public uint Numerator;

			public uint Denominator;
		}

		private struct DXGI_MODE_DESC
		{
			public uint Width;

			public uint Height;

			public DXGI_RATIONAL RefreshRate;

			public DXGI_FORMAT Format;

			public DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;

			public DXGI_MODE_SCALING Scaling;
		}

		private struct DXGI_SAMPLE_DESC
		{
			public uint Count;

			public uint Quality;
		}

		private struct DXGI_SWAP_CHAIN_DESC
		{
			public DXGI_MODE_DESC BufferDesc;

			public DXGI_SAMPLE_DESC SampleDesc;

			public DXGI_USAGE BufferUsage;

			public uint BufferCount;

			public IntPtr OutputWindow;

			[MarshalAs(UnmanagedType.Bool)]
			public bool Windowed;

			public DXGI_SWAP_EFFECT SwapEffect;

			public DXGI_SWAP_CHAIN_FLAG Flags;
		}

		internal struct D3D11_MAPPED_SUBRESOURCE
		{
			public unsafe void* pData;

			public uint RowPitch;

			public uint DepthPitch;
		}

		internal static class Rrid
		{
			public static Guid IDXGIFactory = new Guid("7b7166ec-21c7-44ae-b21a-c9ae321ae369");

			public static Guid WKPDID_D3DDebugObjectName = new Guid(1117490210u, 37256, 19212, 135, 66, 172, 176, 191, 133, 194, 0);

			public static Guid WKPDID_D3DDebugObjectNameW = new Guid(1288331224u, 37407, 17096, 133, 102, 112, 202, 242, 169, 183, 65);
		}

		internal sealed class D3D11Output : IDisposable
		{
			public IntPtr SwapChain;

			public IntPtr Device;

			public IntPtr Context;

			public void Dispose()
			{
				if (SwapChain != IntPtr.Zero)
				{
					Marshal.Release(SwapChain);
					SwapChain = IntPtr.Zero;
				}
				if (Device != IntPtr.Zero)
				{
					Marshal.Release(Device);
					Device = IntPtr.Zero;
				}
				if (Context != IntPtr.Zero)
				{
					Marshal.Release(Context);
					Context = IntPtr.Zero;
				}
			}
		}

		[UnmanagedFunctionPointer(CallingConvention.StdCall)]
		internal unsafe delegate HResult CreatePixelShader(IntPtr device, [In] void* shaderBytecode, [In] nuint bytecodeLength, [In] IntPtr classLinkage, [Out] IntPtr* pixelShader);

		[UnmanagedFunctionPointer(CallingConvention.StdCall)]
		internal unsafe delegate void PSSetShader(IntPtr context, [In] IntPtr pPixelShader, [In] IntPtr* ppClassInstances, uint numClassInstances);

		[UnmanagedFunctionPointer(CallingConvention.StdCall)]
		internal unsafe delegate void PSSetConstantBuffers(IntPtr context, [In] uint startSlot, [In] uint numBuffers, [In] IntPtr* ppConstantBuffers);

		[DllImport("dxgi.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
		private static extern HResult CreateDXGIFactory(ref Guid riid, out IntPtr factory);

		[DllImport("d3d11.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]
		private static extern HResult D3D11CreateDeviceAndSwapChain([In] IntPtr adapter, D3D_DRIVER_TYPE driverType, IntPtr software, uint flags, [In] D3D_FEATURE_LEVEL[] featureLevels, uint featureLevelCount, uint sdkVersion, [In] ref DXGI_SWAP_CHAIN_DESC swapChainDesc, out IntPtr swapChain, out IntPtr device, out uint featureLevel, out IntPtr context);

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe static IntPtr GetVTableEntry(IntPtr comObject, int index)
		{
			return (IntPtr)(*(void**)((nint)(*(IntPtr*)(void*)comObject) + (nint)index * (nint)sizeof(void*)));
		}

		internal unsafe static D3D11Output? Locate()
		{
			IntPtr factory = IntPtr.Zero;
			IntPtr zero = IntPtr.Zero;
			try
			{
				HResult hResult = CreateDXGIFactory(ref Rrid.IDXGIFactory, out factory);
				if (hResult != HResult.S_OK)
				{
					MelonLogger.Error($"CreateDXGIFactory failed: {hResult}");
					return null;
				}
				if (factory == IntPtr.Zero)
				{
					MelonLogger.Error("Failed to create DXGI factory");
					return null;
				}
				IntPtr vTableEntry = GetVTableEntry(factory, 7);
				if (vTableEntry == IntPtr.Zero)
				{
					MelonLogger.Error("Could not locate EnumAdapters");
					return null;
				}
				hResult = ((delegate* unmanaged[Stdcall]<IntPtr, uint, out IntPtr, HResult>)(void*)vTableEntry)(factory, 0u, out zero);
				if (hResult != HResult.S_OK)
				{
					MelonLogger.Error($"EnumAdapters failed: {hResult}");
					return null;
				}
				if (zero == IntPtr.Zero)
				{
					MelonLogger.Error("Failed to get adapter");
					return null;
				}
				IntPtr windowHandle = WindowHandle.GetWindowHandle();
				if (windowHandle == IntPtr.Zero)
				{
					MelonLogger.Error("Failed to get window handle");
					return null;
				}
				DXGI_SWAP_CHAIN_DESC swapChainDesc = new DXGI_SWAP_CHAIN_DESC
				{
					BufferDesc = 
					{
						Width = 100u,
						Height = 100u,
						Format = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM,
						RefreshRate = 
						{
							Numerator = 60u,
							Denominator = 1u
						}
					},
					SampleDesc = 
					{
						Count = 1u
					},
					BufferUsage = DXGI_USAGE.DXGI_USAGE_RENDER_TARGET_OUTPUT,
					BufferCount = 1u,
					OutputWindow = windowHandle,
					Windowed = true,
					SwapEffect = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_DISCARD,
					Flags = DXGI_SWAP_CHAIN_FLAG.DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
				};
				D3D_FEATURE_LEVEL[] array = new D3D_FEATURE_LEVEL[3]
				{
					D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0,
					D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_10_1,
					D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_10_0
				};
				hResult = D3D11CreateDeviceAndSwapChain(zero, D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_UNKNOWN, IntPtr.Zero, 0u, array, (uint)array.Length, 7u, ref swapChainDesc, out var swapChain, out var device, out var _, out var context);
				if (hResult != HResult.S_OK)
				{
					MelonLogger.Error($"D3D11CreateDeviceAndSwapChain failed {hResult}");
				}
				return new D3D11Output
				{
					Context = context,
					SwapChain = swapChain,
					Device = device
				};
			}
			finally
			{
				if (zero != IntPtr.Zero)
				{
					Marshal.Release(zero);
				}
				if (factory != IntPtr.Zero)
				{
					Marshal.Release(factory);
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveOptimization)]
		internal unsafe static string GetDebugName(IntPtr deviceChild)
		{
			if (deviceChild == IntPtr.Zero)
			{
				return "<null>";
			}
			delegate* unmanaged[Stdcall]<IntPtr, ref Guid, ref uint, void*, HResult> delegate* = (delegate* unmanaged[Stdcall]<IntPtr, ref Guid, ref uint, void*, HResult>)(void*)GetVTableEntry(deviceChild, 4);
			if (delegate* == (delegate* unmanaged[Stdcall]<IntPtr, ref Guid, ref uint, void*, HResult>)null)
			{
				return "<unnamed>";
			}
			uint num = 256u;
			byte* ptr = stackalloc byte[(int)num];
			if (delegate*(deviceChild, ref Rrid.WKPDID_D3DDebugObjectName, ref num, ptr) != HResult.S_OK || num == 0)
			{
				return "<unnamed>";
			}
			string text = Marshal.PtrToStringAnsi((IntPtr)ptr, (int)num);
			if (!string.IsNullOrEmpty(text))
			{
				return text.TrimEnd('\0');
			}
			return "<unnamed>";
		}
	}
	public static class RainbowGuardModInfo
	{
		public const string ModName = "RainbowGuard";

		public const string ModVersion = "1.0.0";

		public const string MLVersion = "0.7.3";
	}
	public class RainbowGuard : MelonMod
	{
		private bool _didLoad;

		public override void OnEarlyInitializeMelon()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType != 2)
			{
				MelonLogger.Error("This mod only works on Direct3D11");
				return;
			}
			DXInterop.D3D11Output d3D11Output = DXInterop.Locate();
			if (d3D11Output == null)
			{
				MelonLogger.Error("Could not generate D3D11 device");
				return;
			}
			using (d3D11Output)
			{
				CreatePixelShaderStore.Init(d3D11Output);
				HookCB.Init(d3D11Output);
				HookShader.Init(d3D11Output);
			}
			_didLoad = true;
		}

		public override void OnDeinitializeMelon()
		{
			if (_didLoad)
			{
				CreatePixelShaderStore.DeInit();
				HookCB.DeInit();
				HookShader.DeInit();
			}
		}
	}
	internal static class HookShader
	{
		private static NativeHook<DXInterop.PSSetShader>? _hookInstance;

		internal static readonly object Lock = new object();

		internal static readonly Dictionary<IntPtr, IntPtr> CurrentPsByContext = new Dictionary<IntPtr, IntPtr>();

		internal const string Match = "Hidden/VFX/Guardstone VFX/System/Output Particle Shader Graph Quad - Unlit";

		internal unsafe static void Init(DXInterop.D3D11Output output)
		{
			if (_hookInstance != null)
			{
				return;
			}
			if (output.Context == IntPtr.Zero)
			{
				MelonLogger.Error("Could not generate D3D11 context methods");
				return;
			}
			IntPtr vTableEntry = DXInterop.GetVTableEntry(output.Context, 9);
			if (vTableEntry == IntPtr.Zero)
			{
				MelonLogger.Error("Failed to get PSSetShader");
				return;
			}
			IntPtr intPtr = (IntPtr)(delegate*<IntPtr, IntPtr, IntPtr*, uint, void>)(&Hook);
			_hookInstance = new NativeHook<DXInterop.PSSetShader>(vTableEntry, intPtr);
			_hookInstance.Attach();
		}

		internal static void DeInit()
		{
			_hookInstance?.Detach();
			_hookInstance = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveOptimization)]
		[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })]
		private unsafe static void Hook(IntPtr context, IntPtr pPixelShader, IntPtr* ppClassInstances, uint numClassInstances)
		{
			_hookInstance.Trampoline(context, pPixelShader, ppClassInstances, numClassInstances);
			lock (Lock)
			{
				CurrentPsByContext[context] = pPixelShader;
			}
		}
	}
	internal static class HookCB
	{
		private static NativeHook<DXInterop.PSSetConstantBuffers>? _hookInstance;

		private const string BufferName = "ConstantBuffer-733-1632";

		private const string LivBufferName = "ConstantBuffer-733-2128";

		internal unsafe static void Init(DXInterop.D3D11Output output)
		{
			if (_hookInstance != null)
			{
				return;
			}
			if (output.Context == IntPtr.Zero)
			{
				MelonLogger.Error("Could not generate D3D11 context methods");
				return;
			}
			IntPtr vTableEntry = DXInterop.GetVTableEntry(output.Context, 16);
			if (vTableEntry == IntPtr.Zero)
			{
				MelonLogger.Error("Failed to get PSSetConstantBuffers");
				return;
			}
			IntPtr intPtr = (IntPtr)(delegate*<IntPtr, uint, uint, IntPtr*, void>)(&Hook);
			_hookInstance = new NativeHook<DXInterop.PSSetConstantBuffers>(vTableEntry, intPtr);
			_hookInstance.Attach();
		}

		internal static void DeInit()
		{
			_hookInstance?.Detach();
			_hookInstance = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveOptimization)]
		[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })]
		private unsafe static void Hook(IntPtr context, uint startSlot, uint numBuffers, IntPtr* ppConstantBuffers)
		{
			IntPtr value;
			lock (HookShader.Lock)
			{
				HookShader.CurrentPsByContext.TryGetValue(context, out value);
			}
			if (value == IntPtr.Zero || DXInterop.GetDebugName(value) != "Hidden/VFX/Guardstone VFX/System/Output Particle Shader Graph Quad - Unlit")
			{
				_hookInstance.Trampoline(context, startSlot, numBuffers, ppConstantBuffers);
				return;
			}
			IntPtr vTableEntry = DXInterop.GetVTableEntry(context, 14);
			if (vTableEntry == IntPtr.Zero)
			{
				MelonLogger.Error("Failed to get Map");
				_hookInstance.Trampoline(context, startSlot, numBuffers, ppConstantBuffers);
				return;
			}
			delegate* unmanaged[Stdcall]<IntPtr, IntPtr, uint, DXInterop.D3D11_MAP, DXInterop.D3D11_MAP_FLAG, out DXInterop.D3D11_MAPPED_SUBRESOURCE, DXInterop.HResult> delegate* = (delegate* unmanaged[Stdcall]<IntPtr, IntPtr, uint, DXInterop.D3D11_MAP, DXInterop.D3D11_MAP_FLAG, out DXInterop.D3D11_MAPPED_SUBRESOURCE, DXInterop.HResult>)(void*)vTableEntry;
			IntPtr vTableEntry2 = DXInterop.GetVTableEntry(context, 15);
			if (vTableEntry2 == IntPtr.Zero)
			{
				MelonLogger.Error("Failed to get Unmap");
				_hookInstance.Trampoline(context, startSlot, numBuffers, ppConstantBuffers);
				return;
			}
			delegate* unmanaged[Stdcall]<IntPtr, IntPtr, uint, void> delegate*2 = (delegate* unmanaged[Stdcall]<IntPtr, IntPtr, uint, void>)(void*)vTableEntry2;
			DXInterop.D3D11_MAPPED_SUBRESOURCE d3D11_MAPPED_SUBRESOURCE = default(DXInterop.D3D11_MAPPED_SUBRESOURCE);
			for (uint num = 0u; num < numBuffers; num++)
			{
				IntPtr intPtr = ppConstantBuffers[num];
				string debugName = DXInterop.GetDebugName(intPtr);
				if (!(debugName != "ConstantBuffer-733-1632") || !(debugName != "ConstantBuffer-733-2128"))
				{
					DXInterop.HResult hResult = delegate*(context, intPtr, 0u, DXInterop.D3D11_MAP.D3D11_MAP_WRITE_NO_OVERWRITE, (DXInterop.D3D11_MAP_FLAG)0u, out d3D11_MAPPED_SUBRESOURCE);
					if (hResult != DXInterop.HResult.S_OK)
					{
						MelonLogger.Error($"Could not map buffer {debugName} ({hResult})");
					}
					else
					{
						float* pData = (float*)d3D11_MAPPED_SUBRESOURCE.pData;
						double num2 = (double)Environment.TickCount * 0.0005;
						pData[12] = (float)(Math.Sin(num2 * 2.0) * 0.5 + 0.5);
						pData[13] = (float)(Math.Sin(num2 * 2.0 + 2.094) * 0.5 + 0.5);
						pData[14] = (float)(Math.Sin(num2 * 2.0 + 4.188) * 0.5 + 0.5);
						delegate*2(context, intPtr, 0u);
					}
				}
			}
			_hookInstance.Trampoline(context, startSlot, numBuffers, ppConstantBuffers);
		}
	}
	internal static class CreatePixelShaderStore
	{
		private static NativeHook<DXInterop.CreatePixelShader>? _hookInstance;

		private static readonly byte[] MainMatchShader = File.ReadAllBytes(Path.Combine(MelonEnvironment.UserDataDirectory, "RainbowGuard", "main.match.dxbc"));

		private static readonly byte[] MainNewShader = File.ReadAllBytes(Path.Combine(MelonEnvironment.UserDataDirectory, "RainbowGuard", "main.new.dxbc"));

		private static readonly byte[] LivMatchShader = File.ReadAllBytes(Path.Combine(MelonEnvironment.UserDataDirectory, "RainbowGuard", "liv.match.dxbc"));

		private static readonly byte[] LivNewShader = File.ReadAllBytes(Path.Combine(MelonEnvironment.UserDataDirectory, "RainbowGuard", "liv.new.dxbc"));

		internal unsafe static void Init(DXInterop.D3D11Output output)
		{
			if (_hookInstance != null)
			{
				return;
			}
			if (output.Device == IntPtr.Zero)
			{
				MelonLogger.Error("Could not generate D3D11 device methods");
				return;
			}
			IntPtr vTableEntry = DXInterop.GetVTableEntry(output.Device, 15);
			if (vTableEntry == IntPtr.Zero)
			{
				MelonLogger.Error("Failed to get CreatePixelShader");
				return;
			}
			IntPtr intPtr = (IntPtr)(delegate*<IntPtr, void*, nuint, IntPtr, IntPtr*, DXInterop.HResult>)(&Hook);
			_hookInstance = new NativeHook<DXInterop.CreatePixelShader>(vTableEntry, intPtr);
			_hookInstance.Attach();
		}

		internal static void DeInit()
		{
			_hookInstance?.Detach();
			_hookInstance = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveOptimization)]
		[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })]
		private unsafe static DXInterop.HResult Hook(IntPtr device, void* shaderBytecode, nuint bytecodeLength, IntPtr classLinkage, IntPtr* pixelShader)
		{
			if (shaderBytecode == null)
			{
				return _hookInstance.Trampoline(device, shaderBytecode, bytecodeLength, classLinkage, pixelShader);
			}
			if (bytecodeLength == (nuint)MainMatchShader.Length && new ReadOnlySpan<byte>(shaderBytecode, MainMatchShader.Length).SequenceEqual(MainMatchShader))
			{
				fixed (byte* mainNewShader = MainNewShader)
				{
					return _hookInstance.Trampoline(device, mainNewShader, (nuint)MainNewShader.Length, classLinkage, pixelShader);
				}
			}
			if (bytecodeLength == (nuint)LivMatchShader.Length && new ReadOnlySpan<byte>(shaderBytecode, LivMatchShader.Length).SequenceEqual(LivMatchShader))
			{
				fixed (byte* livNewShader = LivNewShader)
				{
					return _hookInstance.Trampoline(device, livNewShader, (nuint)LivNewShader.Length, classLinkage, pixelShader);
				}
			}
			return _hookInstance.Trampoline(device, shaderBytecode, bytecodeLength, classLinkage, pixelShader);
		}
	}
}