Decompiled source of DiscordBot v1.3.0

DiscordBot.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiscordBot.Jobs;
using DiscordBot.Notices;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using uGIF;

[assembly: AssemblyConfiguration("")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("DiscordBot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("RustyMods")]
[assembly: AssemblyProduct("DiscordBot")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: ComVisible(false)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[<75ba1982-4c34-4130-941b-b108d9e37ff0>Embedded]
	[CompilerGenerated]
	internal sealed class <75ba1982-4c34-4130-941b-b108d9e37ff0>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<75ba1982-4c34-4130-941b-b108d9e37ff0>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <dc4658e1-2651-4595-adbe-0ac702760418>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <dc4658e1-2651-4595-adbe-0ac702760418>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <dc4658e1-2651-4595-adbe-0ac702760418>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	[<75ba1982-4c34-4130-941b-b108d9e37ff0>Embedded]
	internal sealed class <9ec34b11-198f-4c60-880a-abf52c50783b>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <9ec34b11-198f-4c60-880a-abf52c50783b>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace uGIF
{
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public class GIFEncoder
	{
		public bool useGlobalColorTable = false;

		public Color32? transparent = null;

		public int repeat = -1;

		public int dispose = -1;

		public int quality = 10;

		private int delay = 0;

		private int width;

		private int height;

		private int transIndex;

		private bool started = false;

		private MemoryStream ms;

		private Color32[] pixels;

		private byte[] indexedPixels;

		private byte[] prevIndexedPixels;

		private int colorDepth;

		private byte[] colorTab;

		private bool[] usedEntry = new bool[256];

		private int palSize = 7;

		private bool firstFrame = true;

		private NeuQuant nq;

		public float FPS
		{
			set
			{
				delay = Mathf.RoundToInt(100f / value);
			}
		}

		public void AddFrame(Image im)
		{
			if (im == null)
			{
				throw new ArgumentNullException("im");
			}
			if (!started)
			{
				throw new InvalidOperationException("Start() must be called before AddFrame()");
			}
			if (firstFrame)
			{
				width = im.width;
				height = im.height;
			}
			pixels = im.pixels;
			RemapPixels();
			pixels = null;
			if (firstFrame)
			{
				WriteLSD();
				WritePalette();
				if (repeat >= 0)
				{
					WriteNetscapeExt();
				}
			}
			WriteGraphicCtrlExt();
			WriteImageDesc();
			if (!firstFrame && !useGlobalColorTable)
			{
				WritePalette();
			}
			WritePixels();
			firstFrame = false;
		}

		public void Finish()
		{
			if (!started)
			{
				throw new InvalidOperationException("Start() must be called before Finish()");
			}
			started = false;
			ms.WriteByte(59);
			ms.Flush();
			transIndex = 0;
			pixels = null;
			indexedPixels = null;
			prevIndexedPixels = null;
			colorTab = null;
			firstFrame = true;
			nq = null;
		}

		public void Start(MemoryStream os)
		{
			if (os == null)
			{
				throw new ArgumentNullException("os");
			}
			ms = os;
			started = true;
			WriteString("GIF89a");
		}

		private void RemapPixels()
		{
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			int num = pixels.Length;
			indexedPixels = new byte[num];
			if (firstFrame || !useGlobalColorTable)
			{
				nq = new NeuQuant(pixels, num, quality);
				colorTab = nq.Process();
			}
			for (int i = 0; i < num; i++)
			{
				int num2 = nq.Map(pixels[i].r & 0xFF, pixels[i].g & 0xFF, pixels[i].b & 0xFF);
				usedEntry[num2] = true;
				indexedPixels[i] = (byte)num2;
				if (dispose == 1 && prevIndexedPixels != null)
				{
					if (indexedPixels[i] == prevIndexedPixels[i])
					{
						indexedPixels[i] = (byte)transIndex;
					}
					else
					{
						prevIndexedPixels[i] = (byte)num2;
					}
				}
			}
			colorDepth = 8;
			palSize = 7;
			if (transparent.HasValue)
			{
				Color32 value = transparent.Value;
				transIndex = nq.Map(value.b, value.g, value.r);
			}
			if (dispose == 1 && prevIndexedPixels == null)
			{
				prevIndexedPixels = indexedPixels.Clone() as byte[];
			}
		}

		private int FindClosest(Color32 c)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (colorTab == null)
			{
				return -1;
			}
			int r = c.r;
			int g = c.g;
			int b = c.b;
			int result = 0;
			int num = 16777216;
			int num2 = colorTab.Length;
			for (int i = 0; i < num2; i++)
			{
				int num3 = r - (colorTab[i++] & 0xFF);
				int num4 = g - (colorTab[i++] & 0xFF);
				int num5 = b - (colorTab[i] & 0xFF);
				int num6 = num3 * num3 + num4 * num4 + num5 * num5;
				int num7 = i / 3;
				if (usedEntry[num7] && num6 < num)
				{
					num = num6;
					result = num7;
				}
			}
			return result;
		}

		private void WriteGraphicCtrlExt()
		{
			ms.WriteByte(33);
			ms.WriteByte(249);
			ms.WriteByte(4);
			int num;
			int num2;
			if (!transparent.HasValue)
			{
				num = 0;
				num2 = 0;
			}
			else
			{
				num = 1;
				num2 = 2;
			}
			if (dispose >= 0)
			{
				num2 = dispose & 7;
			}
			num2 <<= 2;
			ms.WriteByte(Convert.ToByte(0 | num2 | 0 | num));
			WriteShort(delay);
			ms.WriteByte(Convert.ToByte(transIndex));
			ms.WriteByte(0);
		}

		private void WriteImageDesc()
		{
			ms.WriteByte(44);
			WriteShort(0);
			WriteShort(0);
			WriteShort(width);
			WriteShort(height);
			ms.WriteByte(0);
		}

		private void WriteLSD()
		{
			WriteShort(width);
			WriteShort(height);
			ms.WriteByte(Convert.ToByte(0xF0 | palSize));
			ms.WriteByte(0);
			ms.WriteByte(0);
		}

		private void WriteNetscapeExt()
		{
			ms.WriteByte(33);
			ms.WriteByte(byte.MaxValue);
			ms.WriteByte(11);
			WriteString("NETSCAPE2.0");
			ms.WriteByte(3);
			ms.WriteByte(1);
			WriteShort(repeat);
			ms.WriteByte(0);
		}

		private void WritePalette()
		{
			ms.Write(colorTab, 0, colorTab.Length);
			int num = 768 - colorTab.Length;
			for (int i = 0; i < num; i++)
			{
				ms.WriteByte(0);
			}
		}

		private void WritePixels()
		{
			LZWEncoder lZWEncoder = new LZWEncoder(width, height, indexedPixels, colorDepth);
			lZWEncoder.Encode(ms);
		}

		private void WriteShort(int value)
		{
			ms.WriteByte(Convert.ToByte(value & 0xFF));
			ms.WriteByte(Convert.ToByte((value >> 8) & 0xFF));
		}

		private void WriteString(string s)
		{
			char[] array = s.ToCharArray();
			for (int i = 0; i < array.Length; i++)
			{
				ms.WriteByte((byte)array[i]);
			}
		}
	}
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	public class Image
	{
		public int width;

		public int height;

		public Color32[] pixels;

		public Image(Texture2D f)
		{
			pixels = f.GetPixels32();
			width = ((Texture)f).width;
			height = ((Texture)f).height;
		}

		public Image(Color32[] pixels, int width, int height)
		{
			this.pixels = pixels;
			this.width = width;
			this.height = height;
		}

		public Image(int width, int height)
		{
			this.width = width;
			this.height = height;
			pixels = (Color32[])(object)new Color32[width * height];
		}

		public void DrawImage(Image image, int i, int i2)
		{
			throw new NotImplementedException();
		}

		public Color32 GetPixel(int tw, int th)
		{
			//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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			int num = th * width + tw;
			return pixels[num];
		}

		public void Flip()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			for (int i = 0; i < height / 2; i++)
			{
				for (int j = 0; j < width; j++)
				{
					int num = i * width + j;
					int num2 = (height - i - 1) * width + j;
					Color32 val = pixels[num];
					pixels[num] = pixels[num2];
					pixels[num2] = val;
				}
			}
		}

		public void Resize(int scale)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (scale <= 1)
			{
				return;
			}
			int num = width / scale;
			int num2 = height / scale;
			Color32[] array = (Color32[])(object)new Color32[num * num2];
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num; j++)
				{
					array[i * num + j] = pixels[i * scale * width + j * scale];
				}
			}
			pixels = array;
			height = num2;
			width = num;
		}

		public void ResizeBilinear(int newWidth, int newHeight)
		{
			//IL_00bd: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			if (newWidth == width && newHeight == height)
			{
				return;
			}
			Color32[] array = pixels;
			Color32[] array2 = (Color32[])(object)new Color32[newWidth * newHeight];
			float num = 1f / ((float)newWidth / (float)(width - 1));
			float num2 = 1f / ((float)newHeight / (float)(height - 1));
			int num3 = width;
			for (int i = 0; i < newHeight; i++)
			{
				int num4 = Mathf.FloorToInt((float)i * num2);
				int num5 = num4 * num3;
				int num6 = (num4 + 1) * num3;
				int num7 = i * newWidth;
				for (int j = 0; j < newWidth; j++)
				{
					int num8 = (int)Mathf.Floor((float)j * num);
					float p = (float)j * num - (float)num8;
					array2[num7 + j] = ColorLerpUnclamped(Color32.op_Implicit(ColorLerpUnclamped(Color32.op_Implicit(array[num5 + num8]), Color32.op_Implicit(array[num5 + num8 + 1]), p)), Color32.op_Implicit(ColorLerpUnclamped(Color32.op_Implicit(array[num6 + num8]), Color32.op_Implicit(array[num6 + num8 + 1]), p)), (float)i * num2 - (float)num4);
				}
			}
			pixels = array2;
			height = newHeight;
			width = newWidth;
		}

		private Color32 ColorLerpUnclamped(Color A, Color B, float P)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			return Color32.op_Implicit(new Color(A.r + (B.r - A.r) * P, A.g + (B.g - A.g) * P, A.b + (B.b - A.b) * P, A.a + (B.a - A.a) * P));
		}
	}
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	public class LZWEncoder
	{
		private static readonly int EOF = -1;

		private byte[] pixAry;

		private int initCodeSize;

		private int curPixel;

		private static readonly int BITS = 12;

		private static readonly int HSIZE = 5003;

		private int n_bits;

		private int maxbits = BITS;

		private int maxcode;

		private int maxmaxcode = 1 << BITS;

		private int[] htab = new int[HSIZE];

		private int[] codetab = new int[HSIZE];

		private int hsize = HSIZE;

		private int free_ent = 0;

		private bool clear_flg = false;

		private int g_init_bits;

		private int ClearCode;

		private int EOFCode;

		private int cur_accum = 0;

		private int cur_bits = 0;

		private int[] masks = new int[17]
		{
			0, 1, 3, 7, 15, 31, 63, 127, 255, 511,
			1023, 2047, 4095, 8191, 16383, 32767, 65535
		};

		private int a_count;

		private byte[] accum = new byte[256];

		public LZWEncoder(int width, int height, byte[] pixels, int color_depth)
		{
			pixAry = pixels;
			initCodeSize = Math.Max(2, color_depth);
		}

		private void Add(byte c, Stream outs)
		{
			accum[a_count++] = c;
			if (a_count >= 254)
			{
				Flush(outs);
			}
		}

		private void ClearTable(Stream outs)
		{
			ResetCodeTable(hsize);
			free_ent = ClearCode + 2;
			clear_flg = true;
			Output(ClearCode, outs);
		}

		private void ResetCodeTable(int hsize)
		{
			for (int i = 0; i < hsize; i++)
			{
				htab[i] = -1;
			}
		}

		private void Compress(int init_bits, Stream outs)
		{
			g_init_bits = init_bits;
			clear_flg = false;
			n_bits = g_init_bits;
			maxcode = MaxCode(n_bits);
			ClearCode = 1 << init_bits - 1;
			EOFCode = ClearCode + 1;
			free_ent = ClearCode + 2;
			a_count = 0;
			int num = NextPixel();
			int num2 = 0;
			for (int num3 = hsize; num3 < 65536; num3 *= 2)
			{
				num2++;
			}
			num2 = 8 - num2;
			int num4 = hsize;
			ResetCodeTable(num4);
			Output(ClearCode, outs);
			int num5;
			while ((num5 = NextPixel()) != EOF)
			{
				int num3 = (num5 << maxbits) + num;
				int num6 = (num5 << num2) ^ num;
				if (htab[num6] == num3)
				{
					num = codetab[num6];
					continue;
				}
				if (htab[num6] >= 0)
				{
					int num7 = num4 - num6;
					if (num6 == 0)
					{
						num7 = 1;
					}
					while (true)
					{
						if ((num6 -= num7) < 0)
						{
							num6 += num4;
						}
						if (htab[num6] == num3)
						{
							break;
						}
						if (htab[num6] >= 0)
						{
							continue;
						}
						goto IL_0160;
					}
					num = codetab[num6];
					continue;
				}
				goto IL_0160;
				IL_0160:
				Output(num, outs);
				num = num5;
				if (free_ent < maxmaxcode)
				{
					codetab[num6] = free_ent++;
					htab[num6] = num3;
				}
				else
				{
					ClearTable(outs);
				}
			}
			Output(num, outs);
			Output(EOFCode, outs);
		}

		public void Encode(Stream os)
		{
			os.WriteByte(Convert.ToByte(initCodeSize));
			curPixel = 0;
			Compress(initCodeSize + 1, os);
			os.WriteByte(0);
		}

		private void Flush(Stream outs)
		{
			if (a_count > 0)
			{
				outs.WriteByte(Convert.ToByte(a_count));
				outs.Write(accum, 0, a_count);
				a_count = 0;
			}
		}

		private int MaxCode(int n_bits)
		{
			return (1 << n_bits) - 1;
		}

		private int NextPixel()
		{
			if (curPixel == pixAry.Length)
			{
				return EOF;
			}
			curPixel++;
			return pixAry[curPixel - 1] & 0xFF;
		}

		private void Output(int code, Stream outs)
		{
			cur_accum &= masks[cur_bits];
			if (cur_bits > 0)
			{
				cur_accum |= code << cur_bits;
			}
			else
			{
				cur_accum = code;
			}
			cur_bits += n_bits;
			while (cur_bits >= 8)
			{
				Add((byte)((uint)cur_accum & 0xFFu), outs);
				cur_accum >>= 8;
				cur_bits -= 8;
			}
			if (free_ent > maxcode || clear_flg)
			{
				if (clear_flg)
				{
					maxcode = MaxCode(n_bits = g_init_bits);
					clear_flg = false;
				}
				else
				{
					n_bits++;
					if (n_bits == maxbits)
					{
						maxcode = maxmaxcode;
					}
					else
					{
						maxcode = MaxCode(n_bits);
					}
				}
			}
			if (code == EOFCode)
			{
				while (cur_bits > 0)
				{
					Add((byte)((uint)cur_accum & 0xFFu), outs);
					cur_accum >>= 8;
					cur_bits -= 8;
				}
				Flush(outs);
			}
		}
	}
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public class NeuQuant
	{
		private static readonly int netsize = 256;

		private static readonly int prime1 = 499;

		private static readonly int prime2 = 491;

		private static readonly int prime3 = 487;

		private static readonly int prime4 = 503;

		private static readonly int minpicturebytes = 3 * prime4;

		private static readonly int maxnetpos = netsize - 1;

		private static readonly int netbiasshift = 4;

		private static readonly int ncycles = 100;

		private static readonly int intbiasshift = 16;

		private static readonly int intbias = 1 << intbiasshift;

		private static readonly int gammashift = 10;

		private static readonly int gamma = 1 << gammashift;

		private static readonly int betashift = 10;

		private static readonly int beta = intbias >> betashift;

		private static readonly int betagamma = intbias << gammashift - betashift;

		private static readonly int initrad = netsize >> 3;

		private static readonly int radiusbiasshift = 6;

		private static readonly int radiusbias = 1 << radiusbiasshift;

		private static readonly int initradius = initrad * radiusbias;

		private static readonly int radiusdec = 30;

		private static readonly int alphabiasshift = 10;

		private static readonly int initalpha = 1 << alphabiasshift;

		private int alphadec;

		private static readonly int radbiasshift = 8;

		private static readonly int radbias = 1 << radbiasshift;

		private static readonly int alpharadbshift = alphabiasshift + radbiasshift;

		private static readonly int alpharadbias = 1 << alpharadbshift;

		private Color32[] thepicture;

		private int lengthcount;

		private int samplefac;

		private int[][] network;

		private int[] netindex = new int[256];

		private int[] bias = new int[netsize];

		private int[] freq = new int[netsize];

		private int[] radpower = new int[initrad];

		public NeuQuant(Color32[] thepic, int len, int sample)
		{
			thepicture = thepic;
			lengthcount = len;
			samplefac = sample;
			network = new int[netsize][];
			for (int i = 0; i < netsize; i++)
			{
				network[i] = new int[4];
				int[] array = network[i];
				array[0] = (array[1] = (array[2] = (i << netbiasshift + 8) / netsize));
				freq[i] = intbias / netsize;
				bias[i] = 0;
			}
		}

		private byte[] ColorMap()
		{
			byte[] array = new byte[3 * netsize];
			int[] array2 = new int[netsize];
			for (int i = 0; i < netsize; i++)
			{
				array2[network[i][3]] = i;
			}
			int num = 0;
			for (int j = 0; j < netsize; j++)
			{
				int num2 = array2[j];
				array[num++] = (byte)network[num2][0];
				array[num++] = (byte)network[num2][1];
				array[num++] = (byte)network[num2][2];
			}
			return array;
		}

		private void Inxbuild()
		{
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < netsize; i++)
			{
				int[] array = network[i];
				int num3 = i;
				int num4 = array[1];
				int[] array2;
				for (int j = i + 1; j < netsize; j++)
				{
					array2 = network[j];
					if (array2[1] < num4)
					{
						num3 = j;
						num4 = array2[1];
					}
				}
				array2 = network[num3];
				if (i != num3)
				{
					int j = array2[0];
					array2[0] = array[0];
					array[0] = j;
					j = array2[1];
					array2[1] = array[1];
					array[1] = j;
					j = array2[2];
					array2[2] = array[2];
					array[2] = j;
					j = array2[3];
					array2[3] = array[3];
					array[3] = j;
				}
				if (num4 != num)
				{
					netindex[num] = num2 + i >> 1;
					for (int j = num + 1; j < num4; j++)
					{
						netindex[j] = i;
					}
					num = num4;
					num2 = i;
				}
			}
			netindex[num] = num2 + maxnetpos >> 1;
			for (int j = num + 1; j < 256; j++)
			{
				netindex[j] = maxnetpos;
			}
		}

		private void Learn()
		{
			if (lengthcount < minpicturebytes)
			{
				samplefac = 1;
			}
			alphadec = 30 + (samplefac - 1) / 3;
			Color32[] array = thepicture;
			int num = 0;
			int num2 = lengthcount;
			int num3 = lengthcount / (3 * samplefac);
			int num4 = num3 / ncycles;
			int num5 = initalpha;
			int num6 = initradius;
			int num7 = num6 >> radiusbiasshift;
			if (num7 <= 1)
			{
				num7 = 0;
			}
			int i;
			for (i = 0; i < num7; i++)
			{
				radpower[i] = num5 * ((num7 * num7 - i * i) * radbias / (num7 * num7));
			}
			int num8 = ((lengthcount < minpicturebytes) ? 3 : ((lengthcount % prime1 != 0) ? (3 * prime1) : ((lengthcount % prime2 != 0) ? (3 * prime2) : ((lengthcount % prime3 == 0) ? (3 * prime4) : (3 * prime3)))));
			i = 0;
			while (i < num3)
			{
				int b = (array[num].r & 0xFF) << netbiasshift;
				int g = (array[num].g & 0xFF) << netbiasshift;
				int r = (array[num].b & 0xFF) << netbiasshift;
				int i2 = Contest(b, g, r);
				Altersingle(num5, i2, b, g, r);
				if (num7 != 0)
				{
					Alterneigh(num7, i2, b, g, r);
				}
				num += num8;
				if (num >= num2)
				{
					num -= lengthcount;
				}
				i++;
				if (num4 == 0)
				{
					num4 = 1;
				}
				if (i % num4 == 0)
				{
					num5 -= num5 / alphadec;
					num6 -= num6 / radiusdec;
					num7 = num6 >> radiusbiasshift;
					if (num7 <= 1)
					{
						num7 = 0;
					}
					for (i2 = 0; i2 < num7; i2++)
					{
						radpower[i2] = num5 * ((num7 * num7 - i2 * i2) * radbias / (num7 * num7));
					}
				}
			}
		}

		public int Map(int b, int g, int r)
		{
			int num = 1000;
			int result = -1;
			int num2 = netindex[g];
			int num3 = num2 - 1;
			while (num2 < netsize || num3 >= 0)
			{
				int[] array;
				int num5;
				int num4;
				if (num2 < netsize)
				{
					array = network[num2];
					num4 = array[1] - g;
					if (num4 >= num)
					{
						num2 = netsize;
					}
					else
					{
						num2++;
						if (num4 < 0)
						{
							num4 = -num4;
						}
						num5 = array[0] - b;
						if (num5 < 0)
						{
							num5 = -num5;
						}
						num4 += num5;
						if (num4 < num)
						{
							num5 = array[2] - r;
							if (num5 < 0)
							{
								num5 = -num5;
							}
							num4 += num5;
							if (num4 < num)
							{
								num = num4;
								result = array[3];
							}
						}
					}
				}
				if (num3 < 0)
				{
					continue;
				}
				array = network[num3];
				num4 = g - array[1];
				if (num4 >= num)
				{
					num3 = -1;
					continue;
				}
				num3--;
				if (num4 < 0)
				{
					num4 = -num4;
				}
				num5 = array[0] - b;
				if (num5 < 0)
				{
					num5 = -num5;
				}
				num4 += num5;
				if (num4 < num)
				{
					num5 = array[2] - r;
					if (num5 < 0)
					{
						num5 = -num5;
					}
					num4 += num5;
					if (num4 < num)
					{
						num = num4;
						result = array[3];
					}
				}
			}
			return result;
		}

		public byte[] Process()
		{
			Learn();
			Unbiasnet();
			Inxbuild();
			return ColorMap();
		}

		private void Unbiasnet()
		{
			for (int i = 0; i < netsize; i++)
			{
				network[i][0] >>= netbiasshift;
				network[i][1] >>= netbiasshift;
				network[i][2] >>= netbiasshift;
				network[i][3] = i;
			}
		}

		private void Alterneigh(int rad, int i, int b, int g, int r)
		{
			int num = i - rad;
			if (num < -1)
			{
				num = -1;
			}
			int num2 = i + rad;
			if (num2 > netsize)
			{
				num2 = netsize;
			}
			int num3 = i + 1;
			int num4 = i - 1;
			int num5 = 1;
			while (num3 < num2 || num4 > num)
			{
				int num6 = radpower[num5++];
				if (num3 < num2)
				{
					int[] array = network[num3++];
					array[0] -= num6 * (array[0] - b) / alpharadbias;
					array[1] -= num6 * (array[1] - g) / alpharadbias;
					array[2] -= num6 * (array[2] - r) / alpharadbias;
				}
				if (num4 > num)
				{
					int[] array = network[num4--];
					array[0] -= num6 * (array[0] - b) / alpharadbias;
					array[1] -= num6 * (array[1] - g) / alpharadbias;
					array[2] -= num6 * (array[2] - r) / alpharadbias;
				}
			}
		}

		private void Altersingle(int alpha, int i, int b, int g, int r)
		{
			int[] array = network[i];
			array[0] -= alpha * (array[0] - b) / initalpha;
			array[1] -= alpha * (array[1] - g) / initalpha;
			array[2] -= alpha * (array[2] - r) / initalpha;
		}

		private int Contest(int b, int g, int r)
		{
			int num = int.MaxValue;
			int num2 = num;
			int num3 = -1;
			int result = num3;
			for (int i = 0; i < netsize; i++)
			{
				int[] array = network[i];
				int num4 = array[0] - b;
				if (num4 < 0)
				{
					num4 = -num4;
				}
				int num5 = array[1] - g;
				if (num5 < 0)
				{
					num5 = -num5;
				}
				num4 += num5;
				num5 = array[2] - r;
				if (num5 < 0)
				{
					num5 = -num5;
				}
				num4 += num5;
				if (num4 < num)
				{
					num = num4;
					num3 = i;
				}
				int num6 = num4 - (bias[i] >> intbiasshift - netbiasshift);
				if (num6 < num2)
				{
					num2 = num6;
					result = i;
				}
				int num7 = freq[i] >> betashift;
				freq[i] -= num7;
				bias[i] += num7 << gammashift;
			}
			freq[num3] += beta;
			bias[num3] -= betagamma;
			return result;
		}
	}
}
namespace LocalizationManager
{
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[PublicAPI]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out var value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out var value2))
			{
				text = value2.Aggregate(text, [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null)
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1];
				if (dictionary.ContainsKey(text))
				{
					Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
				}
				else
				{
					dictionary[text] = item;
				}
			}
			if (!dictionary.TryGetValue("English", out var value))
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected a file like " + plugin.Info.Metadata.Name + ".English.json or .yml.");
			}
			Dictionary<string, string> dictionary2 = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(value));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: English localization file was empty.");
			}
			string text2 = null;
			if (language != "English" && dictionary.TryGetValue(language, out var value2))
			{
				text2 = File.ReadAllText(value2);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in JsonConvert.DeserializeObject<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		[return: <dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
		private static byte[] LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(2)]
		public static byte[] ReadEmbeddedFileBytes([<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)] string resourceFileName, Assembly containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace DiscordBot
{
	[PublicAPI]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	public static class API
	{
		public static List<Action> m_queue = new List<Action>();

		public static void RegisterCommand(string command, string description, [<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 2, 1, 1 })] Action<string[]> action, [<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 2, 1 })] Action<ZPackage> reaction, bool adminOnly, bool isSecret, string emoji)
		{
			if (DiscordCommands.loaded)
			{
				if (!DiscordCommands.m_commands.ContainsKey(command))
				{
					new DiscordCommands.DiscordCommand(command, description, action, reaction, adminOnly, isSecret, emoji);
				}
				return;
			}
			m_queue.Add(delegate
			{
				if (!DiscordCommands.m_commands.ContainsKey(command))
				{
					new DiscordCommands.DiscordCommand(command, description, action, reaction, adminOnly, isSecret, emoji);
				}
			});
		}

		public static void SendWebhookMessage(string channel, string message)
		{
			switch (channel.ToLower())
			{
			case "notifications":
				Discord.instance?.SendMessage(Webhook.Notifications, "", message);
				break;
			case "chat":
				Discord.instance?.SendMessage(Webhook.Chat, "", message);
				break;
			case "commands":
				Discord.instance?.SendMessage(Webhook.Commands, "", message);
				break;
			}
		}

		public static void SendWebhookTable(string channel, string title, Dictionary<string, string> tableData)
		{
			switch (channel.ToLower())
			{
			case "notifications":
				Discord.instance?.SendTableEmbed(Webhook.Notifications, title, tableData);
				break;
			case "chat":
				Discord.instance?.SendTableEmbed(Webhook.Chat, title, tableData);
				break;
			case "commands":
				Discord.instance?.SendTableEmbed(Webhook.Commands, title, tableData);
				break;
			}
		}

		public static void SendNotification(string message)
		{
			Discord.instance?.SendMessage(Webhook.Notifications, message);
		}

		public static void SendChat(string message)
		{
			Discord.instance?.SendMessage(Webhook.Chat, message);
		}

		public static void SendCommandMessage(string message)
		{
			Discord.instance?.SendMessage(Webhook.Commands, message);
		}
	}
	[PublicAPI]
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public static class DiscordBot_API
	{
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		[PublicAPI]
		public enum Channel
		{
			Notifications,
			Chat,
			Commands
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		internal class Method
		{
			private const string Namespace = "DiscordBot";

			private const string ClassName = "API";

			private const string Assembly = "DiscordBot";

			private const string API_LOCATION = "DiscordBot.API, DiscordBot";

			private static readonly Dictionary<string, Type> CachedTypes = new Dictionary<string, Type>();

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
			private readonly MethodInfo info;

			[return: <dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 1, 2 })]
			public object[] Invoke([<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 1, 2 })] params object[] args)
			{
				object obj = info?.Invoke(null, args);
				object[] array = new object[args.Length + 1];
				array[0] = obj;
				Array.Copy(args, 0, array, 1, args.Length);
				return array;
			}

			public Method(string typeNameWithAssembly, string methodName, BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public)
			{
				if (!TryGetType(typeNameWithAssembly, out var type))
				{
					return;
				}
				if (type == null)
				{
					Debug.LogWarning((object)("Type resolution returned null for: '" + typeNameWithAssembly + "'"));
					return;
				}
				info = type.GetMethod(methodName, bindingFlags);
				if (info == null)
				{
					Debug.LogWarning((object)("Failed to find public static method '" + methodName + "' in type '" + type.FullName + "'. Verify the method name is correct, the method exists, and it is marked as public static. "));
				}
			}

			public Method(string methodName, BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public)
				: this("DiscordBot.API, DiscordBot", methodName, bindingFlags)
			{
			}

			private static bool TryGetType(string typeNameWithAssembly, [<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)] out Type type)
			{
				if (CachedTypes.TryGetValue(typeNameWithAssembly, out type))
				{
					return true;
				}
				Type type2 = Type.GetType(typeNameWithAssembly);
				if ((object)type2 == null)
				{
					Debug.LogWarning((object)("Failed to resolve type: '" + typeNameWithAssembly + "'. Verify the namespace, class name, and assembly name are correct. Ensure the assembly is loaded and accessible."));
					return false;
				}
				type = type2;
				CachedTypes[typeNameWithAssembly] = type2;
				return true;
			}

			public Method(string typeNameWithAssembly, string methodName, params Type[] types)
			{
				if (!TryGetType(typeNameWithAssembly, out var type))
				{
					return;
				}
				if (type == null)
				{
					Debug.LogWarning((object)("Type resolution returned null for: '" + typeNameWithAssembly + "'"));
					return;
				}
				info = type.GetMethod(methodName, types);
				if (info == null)
				{
					Debug.LogWarning((object)("Failed to find public static method '" + methodName + "' in type '" + type.FullName + "'. Verify the method name is correct, the method exists, and it is marked as public static. "));
				}
			}

			public Method(string methodName, params Type[] types)
				: this("DiscordBot.API, DiscordBot", methodName, types)
			{
			}

			[PublicAPI]
			public ParameterInfo[] GetParameters()
			{
				return info?.GetParameters() ?? Array.Empty<ParameterInfo>();
			}

			[PublicAPI]
			public static void ClearCache()
			{
				CachedTypes.Clear();
			}
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
		private static readonly Method _RegisterCommand;

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
		private static readonly Method _SendWebhookMessage;

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
		private static readonly Method _SendWebhookTable;

		private static readonly Dictionary<string, string> Emojis;

		public static bool IsLoaded()
		{
			return Type.GetType("DiscordBot.API, DiscordBot") != null;
		}

		static DiscordBot_API()
		{
			Emojis = new Dictionary<string, string>
			{
				{ "smile", "\ud83d\ude0a" },
				{ "grin", "\ud83d\ude01" },
				{ "laugh", "\ud83d\ude02" },
				{ "wink", "\ud83d\ude09" },
				{ "wave", "\ud83d\udc4b" },
				{ "clap", "\ud83d\udc4f" },
				{ "thumbsup", "\ud83d\udc4d" },
				{ "thumbsdown", "\ud83d\udc4e" },
				{ "ok", "\ud83d\udc4c" },
				{ "pray", "\ud83d\ude4f" },
				{ "muscle", "\ud83d\udcaa" },
				{ "facepalm", "\ud83e\udd26" },
				{ "dog", "\ud83d\udc36" },
				{ "cat", "\ud83d\udc31" },
				{ "mouse", "\ud83d\udc2d" },
				{ "fox", "\ud83e\udd8a" },
				{ "bear", "\ud83d\udc3b" },
				{ "panda", "\ud83d\udc3c" },
				{ "koala", "\ud83d\udc28" },
				{ "lion", "\ud83e\udd81" },
				{ "tiger", "\ud83d\udc2f" },
				{ "monkey", "\ud83d\udc35" },
				{ "unicorn", "\ud83e\udd84" },
				{ "dragon", "\ud83d\udc09" },
				{ "tree", "\ud83c\udf33" },
				{ "palm", "\ud83c\udf34" },
				{ "flower", "\ud83c\udf38" },
				{ "rose", "\ud83c\udf39" },
				{ "sun", "☀\ufe0f" },
				{ "moon", "\ud83c\udf19" },
				{ "star", "⭐" },
				{ "rain", "\ud83c\udf27\ufe0f" },
				{ "snow", "❄\ufe0f" },
				{ "fire", "\ud83d\udd25" },
				{ "lightning", "⚡" },
				{ "pizza", "\ud83c\udf55" },
				{ "burger", "\ud83c\udf54" },
				{ "fries", "\ud83c\udf5f" },
				{ "taco", "\ud83c\udf2e" },
				{ "cake", "\ud83c\udf70" },
				{ "donut", "\ud83c\udf69" },
				{ "coffee", "☕" },
				{ "tea", "\ud83c\udf75" },
				{ "beer", "\ud83c\udf7a" },
				{ "wine", "\ud83c\udf77" },
				{ "rocket", "\ud83d\ude80" },
				{ "car", "\ud83d\ude97" },
				{ "bike", "\ud83d\udeb2" },
				{ "airplane", "✈\ufe0f" },
				{ "train", "\ud83d\ude86" },
				{ "bus", "\ud83d\ude8c" },
				{ "ship", "\ud83d\udea2" },
				{ "book", "\ud83d\udcd6" },
				{ "pencil", "✏\ufe0f" },
				{ "pen", "\ud83d\udd8a\ufe0f" },
				{ "paint", "\ud83c\udfa8" },
				{ "camera", "\ud83d\udcf7" },
				{ "phone", "\ud83d\udcf1" },
				{ "computer", "\ud83d\udcbb" },
				{ "gift", "\ud83c\udf81" },
				{ "balloon", "\ud83c\udf88" },
				{ "key", "\ud83d\udd11" },
				{ "lock", "\ud83d\udd12" },
				{ "soccer", "⚽" },
				{ "basketball", "\ud83c\udfc0" },
				{ "football", "\ud83c\udfc8" },
				{ "tennis", "\ud83c\udfbe" },
				{ "golf", "⛳" },
				{ "run", "\ud83c\udfc3" },
				{ "swim", "\ud83c\udfca" },
				{ "ski", "⛷\ufe0f" },
				{ "game", "\ud83c\udfae" },
				{ "music", "\ud83c\udfb5" },
				{ "guitar", "\ud83c\udfb8" },
				{ "drum", "\ud83e\udd41" },
				{ "check", "✅" },
				{ "x", "❌" },
				{ "warning", "⚠\ufe0f" },
				{ "question", "❓" },
				{ "exclamation", "❗" },
				{ "infinity", "♾\ufe0f" },
				{ "heart", "❤\ufe0f" },
				{ "brokenheart", "\ud83d\udc94" },
				{ "sparkle", "✨" },
				{ "starstruck", "\ud83e\udd29" },
				{ "plus", "✚" },
				{ "minus", "━" },
				{ "tornado", "\ud83c\udf2a\ufe0f" },
				{ "storm", "⛈\ufe0f" },
				{ "save", "\ud83d\udcbe" },
				{ "stop", "\ud83d\udd34" }
			};
			if (IsLoaded())
			{
				_RegisterCommand = new Method("RegisterCommand");
				_SendWebhookMessage = new Method("SendWebhookMessage");
				_SendWebhookTable = new Method("SendWebhookTable");
			}
		}

		public static void SendWebhookMessage(Channel channel, string message)
		{
			_SendWebhookMessage?.Invoke(channel.ToString(), message);
		}

		public static void SendWebhookTable(Channel channel, string title, Dictionary<string, string> tableData)
		{
			_SendWebhookTable?.Invoke(channel.ToString(), title, tableData);
		}

		public static void RegisterCommand(string command, string description, Action<string[]> action, [<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 2, 1 })] Action<ZPackage> reaction = null, bool adminOnly = false, bool isSecret = false, string emoji = "")
		{
			_RegisterCommand?.Invoke(command, description, action, reaction, adminOnly, isSecret, emoji);
		}
	}
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public static class Extensions
	{
		public static string ToURL(this Webhook type)
		{
			if (1 == 0)
			{
			}
			string result = type switch
			{
				Webhook.Chat => DiscordBotPlugin.ChatWebhookURL, 
				Webhook.Notifications => DiscordBotPlugin.NoticeWebhookURL, 
				Webhook.Commands => DiscordBotPlugin.CommandWebhookURL, 
				Webhook.DeathFeed => DiscordBotPlugin.DeathFeedWebhookURL, 
				_ => DiscordBotPlugin.ChatWebhookURL, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static string ToID(this Channel type)
		{
			if (1 == 0)
			{
			}
			string result = type switch
			{
				Channel.Chat => DiscordBotPlugin.ChatChannelID, 
				Channel.Commands => DiscordBotPlugin.CommandChannelID, 
				_ => DiscordBotPlugin.ChatChannelID, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static T GetOrAddComponent<[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)] T>(this GameObject obj) where T : Component
		{
			T val = default(T);
			return obj.TryGetComponent<T>(ref val) ? val : obj.AddComponent<T>();
		}
	}
	public enum Toggle
	{
		On = 1,
		Off = 0
	}
	public enum Webhook
	{
		Notifications,
		Chat,
		Commands,
		DeathFeed
	}
	public enum Channel
	{
		Chat,
		Commands
	}
	public enum ChatDisplay
	{
		Player,
		Bot
	}
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[BepInPlugin("RustyMods.DiscordBot", "DiscordBot", "1.3.0")]
	public class DiscordBotPlugin : BaseUnityPlugin
	{
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		[HarmonyPatch(typeof(ZNet), "Awake")]
		private static class ZNet_Awake_Patch
		{
			[UsedImplicitly]
			[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
			private static void Postfix(ZNet __instance)
			{
				((Component)m_instance).gameObject.GetOrAddComponent<Discord>();
				((Component)m_instance).gameObject.GetOrAddComponent<Screenshot>();
				((Component)m_instance).gameObject.GetOrAddComponent<Recorder>();
				((Component)m_instance).gameObject.GetOrAddComponent<ChatAI>();
				if (__instance.IsServer())
				{
					((Component)m_instance).gameObject.GetOrAddComponent<DiscordGatewayClient>();
					((Component)m_instance).gameObject.GetOrAddComponent<JobManager>();
					UpdateServerAIKeys();
					UpdateServerAIOption();
					UpdateServerWebhooks();
				}
			}
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class StringListConfig
		{
			public readonly List<string> list;

			public StringListConfig(List<string> items)
			{
				list = items;
			}

			public StringListConfig(string items)
			{
				list = items.Split(new char[1] { ',' }).ToList();
			}

			public static void Draw(ConfigEntryBase cfg)
			{
				//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)
				//IL_0103: Expected O, but got Unknown
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_014d: Expected O, but got Unknown
				bool valueOrDefault = cfg.Description.Tags.Select([<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault();
				bool flag = false;
				List<string> list = new List<string>();
				GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
				foreach (string item2 in new StringListConfig((string)cfg.BoxedValue).list)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					string item = item2;
					string text = GUILayout.TextField(item2, Array.Empty<GUILayoutOption>());
					if (text != item2 && !valueOrDefault)
					{
						flag = true;
						item = text;
					}
					if (GUILayout.Button("x", new GUIStyle(GUI.skin.button)
					{
						fixedWidth = 21f
					}, Array.Empty<GUILayoutOption>()) && !valueOrDefault)
					{
						flag = true;
					}
					else
					{
						list.Add(item);
					}
					if (GUILayout.Button("+", new GUIStyle(GUI.skin.button)
					{
						fixedWidth = 21f
					}, Array.Empty<GUILayoutOption>()) && !valueOrDefault)
					{
						list.Add("");
						flag = true;
					}
					GUILayout.EndHorizontal();
				}
				GUILayout.EndVertical();
				if (flag)
				{
					cfg.BoxedValue = new StringListConfig(list).ToString();
				}
			}

			public override string ToString()
			{
				return string.Join(",", list);
			}
		}

		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class Resolution
		{
			public readonly int width;

			public readonly int height;

			public Resolution(int width, int height)
			{
				this.width = width;
				this.height = height;
				resolutions[ToString()] = this;
			}

			[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
			public sealed override string ToString()
			{
				return $"{width}x{height}";
			}
		}

		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order = null;

			[UsedImplicitly]
			public bool? Browsable = null;

			[UsedImplicitly]
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
			public string Category = null;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(new byte[] { 2, 1 })]
			[UsedImplicitly]
			public Action<ConfigEntryBase> CustomDrawer = null;
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class ServerWebhooks
		{
			public readonly string notifications = "";

			public readonly string commands = "";

			public readonly string chat = "";

			public readonly string death = "";

			public readonly string start = "";

			public readonly string save = "";

			public readonly string shutdown = "";

			public readonly string login = "";

			public readonly string logout = "";

			public readonly string events = "";

			public readonly string newDay = "";

			public readonly string useCommands = "";

			public readonly string boss = "";

			public ServerWebhooks()
			{
			}

			public ServerWebhooks(string notifications, string commands, string chat, string death, string start, string save, string shutdown, string login, string logout, string events, string newDay, string useCommands, string boss)
			{
				this.notifications = notifications;
				this.commands = commands;
				this.chat = chat;
				this.death = death;
				this.start = start;
				this.save = save;
				this.shutdown = shutdown;
				this.login = login;
				this.logout = logout;
				this.events = events;
				this.newDay = newDay;
				this.useCommands = useCommands;
				this.boss = boss;
			}

			public ServerWebhooks(string configs)
			{
				string[] array = configs.Split(new char[1] { ';' });
				if (array.Length >= 13)
				{
					notifications = array[0];
					commands = array[1];
					chat = array[2];
					death = array[3];
					start = array[4];
					save = array[5];
					shutdown = array[6];
					login = array[7];
					logout = array[8];
					events = array[9];
					newDay = array[10];
					useCommands = array[11];
					boss = array[12];
				}
			}

			public override string ToString()
			{
				return notifications + ";" + commands + ";" + chat + ";" + death + ";" + start + ";" + save + ";" + shutdown + ";" + login + ";" + logout + ";" + events + ";" + newDay + ";" + useCommands + ";" + boss;
			}
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class ServerKeys
		{
			public readonly string ChatGPT = "";

			public readonly string Gemini = "";

			public readonly string DeepSeek = "";

			public readonly string OpenRouter = "";

			public ServerKeys()
			{
			}

			public ServerKeys(string ChatGPT, string Gemini, string DeepSeek, string OpenRouter)
			{
				this.ChatGPT = ChatGPT;
				this.Gemini = Gemini;
				this.DeepSeek = DeepSeek;
				this.OpenRouter = OpenRouter;
			}

			public ServerKeys(string keys)
			{
				string[] array = keys.Split(new char[1] { ';' });
				if (array.Length >= 4)
				{
					ChatGPT = array[0];
					Gemini = array[1];
					DeepSeek = array[2];
					OpenRouter = array[3];
				}
			}

			public override string ToString()
			{
				return ChatGPT + ";" + Gemini + ";" + DeepSeek + ";" + OpenRouter;
			}
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class ServerAIOption
		{
			public readonly AIService service = AIService.Gemini;

			public readonly OpenRouterModel openRouterModel = OpenRouterModel.Claude3_5Sonnet;

			public readonly GeminiModel geminiModel = GeminiModel.Flash2_0;

			public ServerAIOption()
			{
			}

			public ServerAIOption(string config)
			{
				string[] array = config.Split(new char[1] { ';' });
				if (array.Length >= 3)
				{
					Enum.TryParse<AIService>(array[0], ignoreCase: true, out service);
					Enum.TryParse<OpenRouterModel>(array[1], ignoreCase: true, out openRouterModel);
					Enum.TryParse<GeminiModel>(array[2], ignoreCase: true, out geminiModel);
				}
			}

			public ServerAIOption(AIService service, OpenRouterModel openRouterModel, GeminiModel geminiModel)
			{
				this.service = service;
				this.openRouterModel = openRouterModel;
				this.geminiModel = geminiModel;
			}

			public override string ToString()
			{
				return $"{service};{openRouterModel};{geminiModel}";
			}
		}

		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class Record
		{
			private readonly List<string> logs = new List<string>();

			public void Log(LogLevel level, string log)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				logs.Add($"[{DateTime.Now:HH:mm:ss}][{level}]: {log}");
				if ((int)level == 2)
				{
					if (LogErrors)
					{
						DiscordBotLogger.Log(level, (object)log);
					}
				}
				else if (ShowDetailedLogs)
				{
					DiscordBotLogger.Log(level, (object)log);
				}
			}

			public void Write()
			{
				directory.WriteAllLines("RustyMods.DiscordBot.log", logs);
			}
		}

		internal const string ModName = "DiscordBot";

		internal const string ModVersion = "1.3.0";

		internal const string Author = "RustyMods";

		private const string ModGUID = "RustyMods.DiscordBot";

		private const string ConfigFileName = "RustyMods.DiscordBot.cfg";

		private static readonly string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("RustyMods.DiscordBot");

		public static readonly ManualLogSource DiscordBotLogger;

		private static readonly ConfigSync ConfigSync;

		public static readonly Dir directory;

		public static DiscordBotPlugin m_instance;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		private static ConfigEntry<string> m_startWorldHook;

		private static ConfigEntry<string> m_saveWebhook;

		private static ConfigEntry<string> m_shutdownWebhook;

		private static ConfigEntry<string> m_loginWebhook;

		private static ConfigEntry<string> m_logoutWebhook;

		private static ConfigEntry<string> m_eventWebhook;

		private static ConfigEntry<string> m_newDayWebhook;

		private static ConfigEntry<string> m_useCommandWebhook;

		private static ConfigEntry<string> m_bossWebhook;

		private static ConfigEntry<string> m_notificationWebhookURL;

		private static ConfigEntry<Toggle> m_serverStartNotice;

		private static ConfigEntry<Toggle> m_serverStopNotice;

		private static ConfigEntry<Toggle> m_serverSaveNotice;

		private static ConfigEntry<Toggle> m_deathNotice;

		private static ConfigEntry<Toggle> m_loginNotice;

		private static ConfigEntry<Toggle> m_logoutNotice;

		private static ConfigEntry<Toggle> m_eventNotice;

		private static ConfigEntry<Toggle> m_newDayNotice;

		private static ConfigEntry<Toggle> m_coordinateDetails;

		private static ConfigEntry<Toggle> m_commandNotice;

		private static ConfigEntry<Toggle> m_showServerDetails;

		private static ConfigEntry<Toggle> m_showBossDeath;

		private static ConfigEntry<string> m_chatWebhookURL;

		private static ConfigEntry<string> m_chatChannelID;

		private static ConfigEntry<Toggle> m_chatEnabled;

		private static ConfigEntry<ChatDisplay> m_chatType;

		private static ConfigEntry<string> m_commandWebhookURL;

		private static ConfigEntry<string> m_commandChannelID;

		private static ConfigEntry<string> m_deathFeedURL;

		private static ConfigEntry<string> m_discordAdmins;

		private static ConfigEntry<Toggle> m_logErrors;

		private static ConfigEntry<string> m_botToken;

		private static ConfigEntry<Toggle> m_showDetailedLogs;

		private static ConfigEntry<Toggle> m_screenshotDeath;

		private static ConfigEntry<float> m_screenshotDelay;

		private static ConfigEntry<string> m_screenshotResolution;

		private static ConfigEntry<Toggle> m_screenshotGif;

		private static ConfigEntry<int> m_gifFPS;

		private static ConfigEntry<float> m_gifDuration;

		private static ConfigEntry<string> m_gifResolution;

		private static ConfigEntry<KeyCode> m_selfieKey;

		private static ConfigEntry<AIService> m_aiService;

		private static ConfigEntry<string> m_chatGPTAPIKEY;

		private static ConfigEntry<string> m_geminiAPIKEY;

		private static ConfigEntry<GeminiModel> m_geminiModel;

		private static ConfigEntry<string> m_deepSeekAPIKEY;

		private static ConfigEntry<string> m_openRouterAPIKEY;

		private static ConfigEntry<OpenRouterModel> m_openRouterModel;

		private static ConfigEntry<Toggle> m_useServerKeys;

		private static readonly CustomSyncedValue<string> m_serverKeys;

		private static readonly CustomSyncedValue<string> m_serverOptions;

		private static ConfigEntry<Toggle> m_allowDiscordPrompt;

		private static ConfigEntry<Toggle> m_improveDeathQuips;

		private static ConfigEntry<Toggle> m_improveDayQuips;

		private static ConfigEntry<Toggle> m_enableJobs;

		private static readonly Dictionary<string, Resolution> resolutions;

		private static readonly CustomSyncedValue<string> ServerSyncedWebhooks;

		private static ServerKeys SyncedAIKeys;

		private static ServerAIOption SyncedAIOption;

		private static ServerWebhooks SyncedWebhooks;

		public static readonly Record records;

		public static bool ShowServerStart => m_serverStartNotice.Value == Toggle.On;

		public static bool ShowBossDeath => m_showBossDeath.Value == Toggle.On;

		public static bool ShowServerDetails => m_showServerDetails.Value == Toggle.On;

		public static bool ShowChat => m_chatEnabled.Value == Toggle.On;

		private static bool LogErrors => m_logErrors.Value == Toggle.On;

		public static bool ShowServerStop => m_serverStopNotice.Value == Toggle.On;

		public static bool ShowServerSave => m_serverSaveNotice.Value == Toggle.On;

		public static bool ShowOnDeath => m_deathNotice.Value == Toggle.On;

		public static bool ShowOnLogin => m_loginNotice.Value == Toggle.On;

		public static bool ShowOnLogout => m_logoutNotice.Value == Toggle.On;

		public static bool ShowEvent => m_eventNotice.Value == Toggle.On;

		public static bool ShowNewDay => m_newDayNotice.Value == Toggle.On;

		public static bool ShowCoordinates => m_coordinateDetails.Value == Toggle.On;

		private static bool ShowDetailedLogs => m_showDetailedLogs.Value == Toggle.On;

		public static bool ShowCommandUse => m_commandNotice.Value == Toggle.On;

		public static ChatDisplay ChatType => m_chatType.Value;

		public static string DiscordAdmins => m_discordAdmins.Value;

		public static string BOT_TOKEN => m_botToken.Value;

		public static string ChatChannelID => m_chatChannelID.Value;

		public static string CommandChannelID => m_commandChannelID.Value;

		public static string ChatWebhookURL => SyncedWebhooks.chat;

		public static string CommandWebhookURL => SyncedWebhooks.commands;

		public static string NoticeWebhookURL => SyncedWebhooks.notifications;

		public static string DeathFeedWebhookURL => SyncedWebhooks.death;

		public static bool ScreenshotDeath => m_screenshotDeath.Value == Toggle.On;

		public static bool ScreenshotGif => m_screenshotGif.Value == Toggle.On;

		public static float ScreenshotDelay => m_screenshotDelay.Value;

		public static int GIF_FPS => m_gifFPS.Value;

		public static float GIF_DURATION => m_gifDuration.Value;

		public static Resolution ScreenshotResolution => resolutions[m_screenshotResolution.Value];

		public static Resolution GifResolution => resolutions[m_gifResolution.Value];

		public static KeyCode SelfieKey => m_selfieKey.Value;

		public static AIService AIService => m_aiService.Value;

		private static string ChatGPT_KEY => m_chatGPTAPIKEY.Value;

		private static string Gemini_KEY => m_geminiAPIKEY.Value;

		private static string DeepSeek_KEY => m_deepSeekAPIKEY.Value;

		private static string OpenRouter_KEY => m_openRouterAPIKEY.Value;

		private static bool UseServerKeys => m_useServerKeys.Value == Toggle.On;

		private static OpenRouterModel OpenRouterModel => m_openRouterModel.Value;

		private static GeminiModel GeminiModel => m_geminiModel.Value;

		public static bool AllowDiscordPrompt => m_allowDiscordPrompt.Value == Toggle.On;

		public static bool ImproveDeathQuips => m_improveDeathQuips.Value == Toggle.On;

		public static bool ImproveDayQuips => m_improveDayQuips.Value == Toggle.On;

		public static List<string> OnWorldStartHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.start) ? new List<string>() : new StringListConfig(SyncedWebhooks.start).list;

		public static List<string> OnWorldSaveHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.save) ? new List<string>() : new StringListConfig(SyncedWebhooks.save).list;

		public static List<string> OnWorldShutdownHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.shutdown) ? new List<string>() : new StringListConfig(SyncedWebhooks.shutdown).list;

		public static List<string> OnLoginHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.login) ? new List<string>() : new StringListConfig(SyncedWebhooks.login).list;

		public static List<string> OnLogoutHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.logout) ? new List<string>() : new StringListConfig(SyncedWebhooks.logout).list;

		public static List<string> OnEventHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.events) ? new List<string>() : new StringListConfig(SyncedWebhooks.events).list;

		public static List<string> OnNewDayHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.newDay) ? new List<string>() : new StringListConfig(SyncedWebhooks.newDay).list;

		public static List<string> OnUseCommandHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.useCommands) ? new List<string>() : new StringListConfig(SyncedWebhooks.useCommands).list;

		public static List<string> OnBossDeathHooks => Utility.IsNullOrWhiteSpace(SyncedWebhooks.boss) ? new List<string>() : new StringListConfig(SyncedWebhooks.boss).list;

		public static bool JobsEnabled => m_enableJobs.Value == Toggle.On;

		public static void SetDiscordAdmins(string value)
		{
			m_discordAdmins.Value = value;
		}

		public static void LogWarning(string message)
		{
			records.Log((LogLevel)4, message);
		}

		public static void LogDebug(string message)
		{
			records.Log((LogLevel)32, message);
		}

		public static void LogError(string message)
		{
			records.Log((LogLevel)2, message);
		}

		public static AIService GetAIServiceOption()
		{
			AIService aIService = AIService;
			if (1 == 0)
			{
			}
			AIService result = aIService switch
			{
				AIService.ChatGPT => (!string.IsNullOrEmpty(ChatGPT_KEY) || !UseServerKeys) ? AIService.ChatGPT : SyncedAIOption.service, 
				AIService.Gemini => (string.IsNullOrEmpty(Gemini_KEY) && UseServerKeys) ? SyncedAIOption.service : AIService.Gemini, 
				AIService.DeepSeek => (string.IsNullOrEmpty(DeepSeek_KEY) && UseServerKeys) ? SyncedAIOption.service : AIService.DeepSeek, 
				AIService.OpenRouter => (string.IsNullOrEmpty(OpenRouter_KEY) && UseServerKeys) ? SyncedAIOption.service : AIService.OpenRouter, 
				_ => AIService, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static OpenRouterModel GetOpenRouterOption()
		{
			return (string.IsNullOrEmpty(OpenRouter_KEY) && UseServerKeys) ? SyncedAIOption.openRouterModel : OpenRouterModel;
		}

		public static GeminiModel GetGeminiOption()
		{
			return (string.IsNullOrEmpty(Gemini_KEY) && UseServerKeys) ? SyncedAIOption.geminiModel : GeminiModel;
		}

		public static string GetChatGPTKey()
		{
			return (string.IsNullOrEmpty(ChatGPT_KEY) && UseServerKeys) ? SyncedAIKeys.ChatGPT : ChatGPT_KEY;
		}

		public static string GetGeminiKey()
		{
			return (string.IsNullOrEmpty(Gemini_KEY) && UseServerKeys) ? SyncedAIKeys.Gemini : Gemini_KEY;
		}

		public static string GetDeepSeekKey()
		{
			return (string.IsNullOrEmpty(DeepSeek_KEY) && UseServerKeys) ? SyncedAIKeys.DeepSeek : DeepSeek_KEY;
		}

		public static string GetOpenRouterKey()
		{
			return (string.IsNullOrEmpty(OpenRouter_KEY) && UseServerKeys) ? SyncedAIKeys.OpenRouter : OpenRouter_KEY;
		}

		public void Awake()
		{
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Expected O, but got Unknown
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Expected O, but got Unknown
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Expected O, but got Unknown
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Expected O, but got Unknown
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Expected O, but got Unknown
			//IL_05f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Expected O, but got Unknown
			//IL_065b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0666: Expected O, but got Unknown
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b1: Expected O, but got Unknown
			//IL_06f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fc: Expected O, but got Unknown
			//IL_073c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Expected O, but got Unknown
			//IL_0787: Unknown result type (might be due to invalid IL or missing references)
			//IL_0792: Expected O, but got Unknown
			//IL_07d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07dd: Expected O, but got Unknown
			//IL_081d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0828: Expected O, but got Unknown
			//IL_0868: Unknown result type (might be due to invalid IL or missing references)
			//IL_0873: Expected O, but got Unknown
			//IL_08b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08be: Expected O, but got Unknown
			Keys.Write();
			Localizer.Load();
			m_instance = this;
			_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
			m_logErrors = config("1 - General", "Log Errors", Toggle.Off, "If on, caught errors will log to console");
			m_showDetailedLogs = config("1 - General", "Detailed Logs", Toggle.Off, "Show detailed logs");
			m_notificationWebhookURL = config("2 - Notifications", "Webhook URL", "", "Set webhook to receive notifications, like server start, stop, save etc... [Server Only]", synchronizedSetting: false);
			m_notificationWebhookURL.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_serverStartNotice = config("2 - Notifications", "Startup", Toggle.On, "If on, bot will send message when server is starting");
			m_showServerDetails = config("2 - Notifications", "Server Details", Toggle.Off, "If on, bot will send server details when starting");
			m_serverStopNotice = config("2 - Notifications", "Shutdown", Toggle.On, "If on, bot will send message when server is shutting down");
			m_serverSaveNotice = config("2 - Notifications", "Saving", Toggle.On, "If on, bot will send message when server is saving");
			m_loginNotice = config("2 - Notifications", "Login", Toggle.On, "If on, bot will send message when player logs in");
			m_logoutNotice = config("2 - Notifications", "Logout", Toggle.On, "If on, bot will send message when player logs out");
			m_eventNotice = config("2 - Notifications", "Random Events", Toggle.On, "If on, bot will send message when random event starts");
			m_newDayNotice = config("2 - Notifications", "New Day", Toggle.Off, "If on, bot will send message when a new day begins");
			m_coordinateDetails = config("2 - Notifications", "Show Coordinates", Toggle.On, "If on, coordinates will be added to login/logout notifications");
			m_showBossDeath = config("2 - Notifications", "Show Boss Death", Toggle.Off, "If on, bot will send boss death notifications");
			m_commandNotice = config("2 - Notifications", "Show Command Use", Toggle.Off, "If on, bot will send message when a player uses a cheat terminal command");
			m_chatWebhookURL = config("3 - Chat", "Webhook URL", "", "Set discord webhook to display chat messages [Server Only]", synchronizedSetting: false);
			m_chatWebhookURL.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_chatChannelID = config("3 - Chat", "Channel ID", "", "Set channel ID to monitor for messages");
			m_chatEnabled = config("3 - Chat", "Enabled", Toggle.On, "If on, bot will send message when player shouts and monitor discord for messages");
			m_chatType = config("3 - Chat", "Display As", ChatDisplay.Player, "Set how chat messages appear, if Player, message sent by player, else sent by bot with a prefix that player is saying");
			m_commandWebhookURL = config("4 - Commands", "Webhook URL", "", "Set discord webhook to display feedback messages from commands [Server Only]", synchronizedSetting: false);
			m_commandWebhookURL.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_commandChannelID = config("4 - Commands", "Channel ID", "", "Set channel ID to monitor for input commands");
			m_discordAdmins = config("4 - Commands", "Discord Admin", "", new ConfigDescription("List of discord admins, who can run commands", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}));
			m_enableJobs = config("4 - Commands", "Jobs", Toggle.On, "If on, jobs are enabled");
			m_botToken = config("5 - Setup", "BOT TOKEN", "", "Add bot token here, server only", synchronizedSetting: false);
			m_deathNotice = config("6 - Death Feed", "Enabled", Toggle.On, "If on, bot will send message when player dies");
			m_deathFeedURL = config("6 - Death Feed", "Webhook URL", "", "Set webhook to receive death feed messages [Server Only]", synchronizedSetting: false);
			m_deathFeedURL.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_screenshotDeath = config("6 - Death Feed", "Screenshot", Toggle.On, "If on, bot will post screenshot of death", synchronizedSetting: false);
			m_screenshotDelay = config("6 - Death Feed", "Screenshot Delay", 0.3f, new ConfigDescription("Set delay", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()), synchronizedSetting: false);
			Resolution resolution = new Resolution(800, 600);
			Resolution resolution2 = new Resolution(960, 540);
			Resolution resolution3 = new Resolution(1280, 720);
			Resolution resolution4 = new Resolution(1920, 1080);
			m_screenshotResolution = config("6 - Death Feed", "Screenshot Resolution", resolution2.ToString(), new ConfigDescription("Set resolution", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[4]
			{
				resolution.ToString(),
				resolution2.ToString(),
				resolution3.ToString(),
				resolution4.ToString()
			}), Array.Empty<object>()), synchronizedSetting: false);
			m_screenshotGif = config("6 - Death Feed", "Screenshot GIF", Toggle.On, "If on, bot will post gif of death", synchronizedSetting: false);
			m_gifFPS = config("6 - Death Feed", "GIF FPS", 30, new ConfigDescription("Set frames per second", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()), synchronizedSetting: false);
			m_gifDuration = config("6 - Death Feed", "GIF Record Duration", 3f, new ConfigDescription("Set recording duration for gif, in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()), synchronizedSetting: false);
			Resolution resolution5 = new Resolution(256, 144);
			Resolution resolution6 = new Resolution(320, 180);
			Resolution resolution7 = new Resolution(480, 270);
			Resolution resolution8 = new Resolution(640, 360);
			m_gifResolution = config("6 - Death Feed", "GIF Resolution", resolution7.ToString(), new ConfigDescription("Set resolution", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[4]
			{
				resolution5.ToString(),
				resolution6.ToString(),
				resolution7.ToString(),
				resolution8.ToString()
			}), Array.Empty<object>()), synchronizedSetting: false);
			m_selfieKey = config<KeyCode>("1 - General", "Selfie", (KeyCode)0, "Hotkey to take selfie and send to discord", synchronizedSetting: false);
			m_startWorldHook = config("7 - Webhooks", "On World Start", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_saveWebhook = config("7 - Webhooks", "On World Save", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_shutdownWebhook = config("7 - Webhooks", "On World Shutdown", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_loginWebhook = config("7 - Webhooks", "On Login", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_logoutWebhook = config("7 - Webhooks", "On Logout", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_eventWebhook = config("7 - Webhooks", "On Event", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_newDayWebhook = config("7 - Webhooks", "On New Day", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_useCommandWebhook = config("7 - Webhooks", "On Use Command", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_bossWebhook = config("7 - Webhooks", "On Boss Death", "", new ConfigDescription("If empty, will use default notification webhook [Server Only]", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = StringListConfig.Draw
				}
			}), synchronizedSetting: false);
			m_startWorldHook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_saveWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_shutdownWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_loginWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_logoutWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_eventWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_newDayWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_useCommandWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_bossWebhook.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerWebhooks();
			};
			m_aiService = config("8 - AI", "Provider", AIService.Gemini, "Set which Artificial Intelligence API to use", synchronizedSetting: false);
			m_chatGPTAPIKEY = config("8 - AI", "ChatGPT", "", "Set ChatGPT key", synchronizedSetting: false);
			m_geminiAPIKEY = config("8 - AI", "Gemini", "", "Set Gemini key", synchronizedSetting: false);
			m_deepSeekAPIKEY = config("8 - AI", "DeepSeek", "", "Set DeepSeek key", synchronizedSetting: false);
			m_openRouterAPIKEY = config("8 - AI", "OpenRouter", "", "Set OpenRouter key", synchronizedSetting: false);
			m_openRouterModel = config("8 - AI", "OpenRouter Model", OpenRouterModel.Claude3_5Sonnet, "Set OpenRouter Model", synchronizedSetting: false);
			m_useServerKeys = config("8 - AI", "Use Server Keys", Toggle.On, "If on and client does not have API Keys, will try to use server's API Keys");
			m_geminiModel = config("8 - AI", "Gemini Model", GeminiModel.Flash2_0, "Set Gemini Model", synchronizedSetting: false);
			m_allowDiscordPrompt = config("8 - AI", "Discord Prompt", Toggle.Off, "If on, users can prompt server's AI using command !prompt");
			m_chatGPTAPIKEY.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIKeys();
			};
			m_geminiAPIKEY.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIKeys();
			};
			m_deepSeekAPIKEY.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIKeys();
			};
			m_openRouterAPIKEY.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIKeys();
			};
			m_aiService.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIOption();
			};
			m_openRouterModel.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIOption();
			};
			m_geminiModel.SettingChanged += [<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdateServerAIOption();
			};
			m_serverKeys.ValueChanged += delegate
			{
				if (!string.IsNullOrWhiteSpace(m_serverKeys.Value))
				{
					ZNet instance3 = ZNet.instance;
					if (instance3 == null || !instance3.IsServer())
					{
						SyncedAIKeys = new ServerKeys(m_serverKeys.Value);
						LogDebug("Received server AI keys");
					}
				}
			};
			m_serverOptions.ValueChanged += delegate
			{
				if (!string.IsNullOrWhiteSpace(m_serverOptions.Value))
				{
					ZNet instance2 = ZNet.instance;
					if (instance2 == null || !instance2.IsServer())
					{
						SyncedAIOption = new ServerAIOption(m_serverOptions.Value);
						LogDebug("Received server AI options");
					}
				}
			};
			ServerSyncedWebhooks.ValueChanged += delegate
			{
				if (!string.IsNullOrWhiteSpace(ServerSyncedWebhooks.Value))
				{
					ZNet instance = ZNet.instance;
					if (instance == null || !instance.IsServer())
					{
						SyncedWebhooks = new ServerWebhooks(ServerSyncedWebhooks.Value);
						LogDebug("Received server webhooks");
					}
				}
			};
			m_improveDeathQuips = config("8 - AI", "Death Quips", Toggle.On, "If on and AI is setup, will prompt to improve quip");
			m_improveDayQuips = config("8 - AI", "Day Quips", Toggle.On, "If on, and AI is setup, will prompt to improve quip");
			DiscordCommands.Setup();
			DeathQuips.Setup();
			DayQuips.Setup();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private static void UpdateServerWebhooks()
		{
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				SyncedWebhooks = new ServerWebhooks(m_notificationWebhookURL.Value, m_commandWebhookURL.Value, m_chatWebhookURL.Value, m_deathFeedURL.Value, m_startWorldHook.Value, m_saveWebhook.Value, m_shutdownWebhook.Value, m_loginWebhook.Value, m_logoutWebhook.Value, m_eventWebhook.Value, m_newDayWebhook.Value, m_useCommandWebhook.Value, m_bossWebhook.Value);
				ServerSyncedWebhooks.Value = SyncedWebhooks.ToString();
				records.Log((LogLevel)16, "Updating server webhooks");
			}
		}

		private static void UpdateServerAIKeys()
		{
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				ServerKeys serverKeys = new ServerKeys(ChatGPT_KEY, Gemini_KEY, DeepSeek_KEY, OpenRouter_KEY);
				m_serverKeys.Value = serverKeys.ToString();
				records.Log((LogLevel)16, "Updating server AI API keys");
			}
		}

		private static void UpdateServerAIOption()
		{
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				ServerAIOption serverAIOption = new ServerAIOption(AIService, OpenRouterModel, GeminiModel);
				m_serverOptions.Value = serverAIOption.ToString();
				records.Log((LogLevel)16, "Updating server AI options");
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
			records.Write();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "RustyMods.DiscordBot.cfg");
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				DiscordBotLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				DiscordBotLogger.LogError((object)"There was an issue loading your RustyMods.DiscordBot.cfg");
				DiscordBotLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private ConfigEntry<T> config<[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		public ConfigEntry<T> config<[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		static DiscordBotPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + "RustyMods.DiscordBot.cfg";
			ConnectionError = "";
			DiscordBotLogger = Logger.CreateLogSource("DiscordBot");
			ConfigSync = new ConfigSync("RustyMods.DiscordBot")
			{
				DisplayName = "DiscordBot",
				CurrentVersion = "1.3.0",
				MinimumRequiredVersion = "1.3.0"
			};
			directory = new Dir(Paths.ConfigPath, "DiscordBot");
			m_instance = null;
			_serverConfigLocked = null;
			m_startWorldHook = null;
			m_saveWebhook = null;
			m_shutdownWebhook = null;
			m_loginWebhook = null;
			m_logoutWebhook = null;
			m_eventWebhook = null;
			m_newDayWebhook = null;
			m_useCommandWebhook = null;
			m_bossWebhook = null;
			m_notificationWebhookURL = null;
			m_serverStartNotice = null;
			m_serverStopNotice = null;
			m_serverSaveNotice = null;
			m_deathNotice = null;
			m_loginNotice = null;
			m_logoutNotice = null;
			m_eventNotice = null;
			m_newDayNotice = null;
			m_coordinateDetails = null;
			m_commandNotice = null;
			m_showServerDetails = null;
			m_showBossDeath = null;
			m_chatWebhookURL = null;
			m_chatChannelID = null;
			m_chatEnabled = null;
			m_chatType = null;
			m_commandWebhookURL = null;
			m_commandChannelID = null;
			m_deathFeedURL = null;
			m_discordAdmins = null;
			m_logErrors = null;
			m_botToken = null;
			m_showDetailedLogs = null;
			m_screenshotDeath = null;
			m_screenshotDelay = null;
			m_screenshotResolution = null;
			m_screenshotGif = null;
			m_gifFPS = null;
			m_gifDuration = null;
			m_gifResolution = null;
			m_selfieKey = null;
			m_aiService = null;
			m_chatGPTAPIKEY = null;
			m_geminiAPIKEY = null;
			m_geminiModel = null;
			m_deepSeekAPIKEY = null;
			m_openRouterAPIKEY = null;
			m_openRouterModel = null;
			m_useServerKeys = null;
			m_serverKeys = new CustomSyncedValue<string>(ConfigSync, "RustyMods.DiscordBot.ServerKeys", "");
			m_serverOptions = new CustomSyncedValue<string>(ConfigSync, "RustyMods.DiscordBot.ServerOptions", "");
			m_allowDiscordPrompt = null;
			m_improveDeathQuips = null;
			m_improveDayQuips = null;
			m_enableJobs = null;
			resolutions = new Dictionary<string, Resolution>();
			ServerSyncedWebhooks = new CustomSyncedValue<string>(ConfigSync, "RustyMods.DiscordBot.SyncedWebhooks", "");
			SyncedAIKeys = new ServerKeys();
			SyncedAIOption = new ServerAIOption();
			SyncedWebhooks = new ServerWebhooks();
			records = new Record();
		}
	}
	public enum AIService
	{
		None,
		ChatGPT,
		Gemini,
		DeepSeek,
		OpenRouter
	}
	[PublicAPI]
	public enum GPTModel
	{
		[InternalName("gpt-3.5-turbo")]
		Turbo,
		[InternalName("gpt-4o")]
		GPT4o,
		[InternalName("gpt-4o-mini")]
		GPT4oMini,
		[InternalName("gpt-4.1")]
		GPT4_1
	}
	[PublicAPI]
	public enum GeminiModel
	{
		[InternalName("gemini-2.0-flash")]
		Flash2_0,
		[InternalName("gemini-2.5-flash")]
		Flash2_5,
		[InternalName("gemini-2.0-pro")]
		Pro2_0,
		[InternalName("gemini-2.5-pro")]
		Pro2_5
	}
	[PublicAPI]
	public enum DeepSeekModel
	{
		[InternalName("deepseek-chat")]
		Chat,
		[InternalName("deepseek-reasoner")]
		Reasoner
	}
	[PublicAPI]
	public enum OpenRouterModel
	{
		[InternalName("anthropic/claude-3.5-sonnet")]
		Claude3_5Sonnet,
		[InternalName("google/gemini-2.0-flash-exp:free")]
		GeminiFlashFree,
		[InternalName("meta-llama/llama-4-maverick:free")]
		Llama4_Maverick,
		[InternalName("microsoft/wizardlm-2-8x22b")]
		WizardLM8x22B,
		[InternalName("openai/gpt-4o-mini")]
		GPT4oMini,
		[InternalName("deepseek/deepseek-chat")]
		DeepSeekChat,
		[InternalName("nousresearch/hermes-3-llama-3.1-405b:free")]
		Hermes3_Llama31_405b
	}
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
	[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
	public class ChatAI : MonoBehaviour
	{
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		[HarmonyPatch(typeof(Terminal), "UpdateChat")]
		private static class Terminal_UpdateChat_Patch
		{
			[UsedImplicitly]
			[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
			private static void Postfix(Terminal __instance)
			{
				if (!((Object)(object)__instance != (Object)(object)Chat.instance) && Object.op_Implicit((Object)(object)instance))
				{
					instance.tempChat = ((TMP_Text)__instance.m_output).text;
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		private static class ZNet_OnNewConnection_Patch
		{
			[UsedImplicitly]
			[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(1)]
			private static void Postfix(ZNetPeer peer)
			{
				peer.m_rpc.Register<string, string>("RPC_ChatAIMessage", (Action<ZRpc, string, string>)RPC_ChatAIMessage);
			}
		}

		[Serializable]
		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class GPTRequest
		{
			public string model = "gpt-4o-mini";

			public List<GPTMessage> messages = new List<GPTMessage>();
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GPTResponse
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public GPTChoice[] choices;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GPTChoice
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public GPTMessage message;
		}

		[Serializable]
		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class GPTMessage
		{
			public string role;

			public string content;

			public GPTMessage()
			{
			}

			public GPTMessage(string role, string content)
			{
				this.role = role;
				this.content = content;
			}
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GeminiRequest
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public List<GeminiContent> contents = new List<GeminiContent>();
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GeminiContent
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public List<GeminiPart> parts;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GeminiPart
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public string text;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GeminiResponse
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public GeminiCandidate[] candidates;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(2)]
			public GeminiUsageMetadata UsageMetadata;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GeminiUsageMetadata
		{
			public int promptTokenCount;

			public int candidatesTokenCount;

			public int totalTokenCount;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class GeminiCandidate
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public GeminiContent content;
		}

		[Serializable]
		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class DeepSeekRequest
		{
			public string model = "deepseek-chat";

			public List<DeepSeekMessage> messages = new List<DeepSeekMessage>();

			public bool stream = false;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class DeepSeekResponse
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public DeepSeekChoice[] choices;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class DeepSeekChoice
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public DeepSeekMessage message;
		}

		[Serializable]
		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class DeepSeekMessage
		{
			public string role;

			public string content;

			public DeepSeekMessage()
			{
			}

			public DeepSeekMessage(string role, string content)
			{
				this.role = role;
				this.content = content;
			}
		}

		[Serializable]
		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class OpenRouterRequest
		{
			public string model = "anthropic/claude-3.5-sonnet";

			public List<OpenRouterMessage> messages = new List<OpenRouterMessage>();

			public bool stream = false;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class OpenRouterResponse
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public OpenRouterChoice[] choices;
		}

		[Serializable]
		[<9ec34b11-198f-4c60-880a-abf52c50783b>NullableContext(0)]
		public class OpenRouterChoice
		{
			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(1)]
			public OpenRouterMessage message;
		}

		[Serializable]
		[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
		public class OpenRouterMessage
		{
			public string role;

			public string content;

			public OpenRouterMessage()
			{
			}

			public OpenRouterMessage(string role, string content)
			{
				this.role = role;
				this.content = content;
			}
		}

		[CompilerGenerated]
		private sealed class <PromptDeepSeek>d__43 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			private object <>2__current;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			public string apiKey;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			public string prompt;

			public bool deathQuip;

			public bool dayQuip;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			public ChatAI <>4__this;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			private DeepSeekRequest <deepSeekRequest>5__1;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			private string <json>5__2;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			private byte[] <body>5__3;

			[<dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
			private UnityWebRequest <request>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				[return: <dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				[return: <dc4658e1-2651-4595-adbe-0ac702760418>Nullable(0)]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PromptDeepSeek>d__43(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<deepSeekRequest>5__1 = null;
				<json>5__2 = null;
				<body>5__3 = null;
				<request>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Expected O, but got Unknown
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Expected O, but got Unknown
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Expected O, but got Unknown
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_015d: Invalid comparison between Unknown and I4
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<>4__this.isThinking = true;
						<deepSeekRequest>5__1 = new DeepSeekRequest();
						<deepSeekRequest>5__1.model = Utils.GetAttributeOfType<InternalName>((Enum)DeepSeekModel.Chat).internalName;
						<deepSeekRequest>5__1.messages.Add(new DeepSeekMessage("user", prompt));
						<json>5__2 = JsonConvert.SerializeObject((object)<deepSeekRequest>5__1);
						<body>5__3 = Encoding.UTF8.GetBytes(<json>5__2);
						<request>5__4 = new UnityWebRequest("https://api.deepseek.com/chat/completions", "POST");
						<>1__state = -3;
						<request>5__4.uploadHandler = (UploadHandler)new UploadHandlerRaw(<body>5__3);
						<request>5__4.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
						<request>5__4.SetRequestHeader("Content-Type", "application/json");
						<request>5__4.SetRequestHeader("Authorization", "Bearer " + apiKey);
						<>2__current = <request>5__4.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						<>4__this.isThinking = false;
						if ((int)<request>5__4.result != 1)
						{
							<>4__this.OnError?.Invoke("Failed to prompt DeepSeek: " + <request>5__4.error);
							<>4__this.OnError?.Invoke("Response: " + <request>5__4.downloadHandler.text);
							result = false;
						}
						else
						{
							<>4__this.Par