Decompiled source of Diomedes v0.9.0

BepInEx/patchers/Diomedes.Client.Preloader.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("me.loaforc.diomedes")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("MMHOOK_0Harmony")]
[assembly: AssemblyCompany("Diomedes.Client.Preloader")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+03a1858111402c9890133d64cf3f83ce16b9ffdb")]
[assembly: AssemblyProduct("Diomedes.Client.Preloader")]
[assembly: AssemblyTitle("Diomedes.Client.Preloader")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Diomedes.Client.Preloader
{
	public static class CecilHelper
	{
		public static bool AddField(this TypeDefinition self, FieldAttributes fieldAttributes, string name, TypeReference type, Action<bool, string>? logCallback = null)
		{
			//IL_0056: 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)
			//IL_0062: Expected O, but got Unknown
			logCallback?.Invoke(arg1: false, "Adding field '" + name + "' to " + ((MemberReference)self).FullName);
			if (Extensions.FindField(self, name) != null)
			{
				logCallback?.Invoke(arg1: true, "Field '" + name + "' already exists in " + ((MemberReference)self).FullName);
				return false;
			}
			self.Fields.Add(new FieldDefinition(name, fieldAttributes, type));
			return true;
		}

		public static bool AddMethod(this TypeDefinition self, string methodName, MethodAttributes attributes = (MethodAttributes)1, TypeReference? returnType = null, ParameterDefinition[]? parameters = null, Action<bool, string>? logCallback = null)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0103: 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_0115: Invalid comparison between Unknown and I4
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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)
			if (returnType == null)
			{
				returnType = ((MemberReference)self).Module.TypeSystem.Void;
			}
			if (parameters == null)
			{
				parameters = Array.Empty<ParameterDefinition>();
			}
			logCallback?.Invoke(arg1: false, "Adding method " + ((MemberReference)returnType).FullName + " " + methodName + "(" + string.Join(",", parameters.Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).FullName)) + ") to " + ((MemberReference)self).FullName);
			if (Extensions.FindMethod(self, methodName, true) != null)
			{
				logCallback?.Invoke(arg1: true, "Method '" + methodName + "' already exists in " + ((MemberReference)self).FullName);
				return false;
			}
			MethodDefinition val = new MethodDefinition(methodName, (MethodAttributes)(attributes | 0x80), returnType);
			self.Methods.Add(val);
			Extensions.AddRange<ParameterDefinition>(((MethodReference)val).Parameters, (IEnumerable<ParameterDefinition>)parameters);
			ILProcessor iLProcessor = val.Body.GetILProcessor();
			Instruction val2 = iLProcessor.Create(OpCodes.Ret);
			if ((int)returnType.MetadataType != 1)
			{
				ConstructorInfo constructor = typeof(NotImplementedException).GetConstructor(new Type[1] { typeof(string) });
				MethodReference val3 = ((MemberReference)self).Module.ImportReference((MethodBase)constructor);
				iLProcessor.Emit(OpCodes.Ldstr, "This is a Stub");
				iLProcessor.Emit(OpCodes.Newobj, val3);
				iLProcessor.Emit(OpCodes.Throw);
			}
			iLProcessor.Append(val2);
			return true;
		}
	}
	internal class DiomedesPreloader
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Func<Hook, MethodBase, MethodBase, object, bool> <0>__GuardHook;

			public static Func<ILHook, MethodBase, Manipulator, bool> <1>__GuardILHook;

			public static Func<Detour, MethodBase, MethodBase, bool> <2>__GuardDetour;

			public static hook_UpdateWrapper <3>__GuardUpdateWrapper;
		}

		internal static readonly Harmony harmony = new Harmony("Diomedes.Client.Preloader");

		private static readonly string MainDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		internal static ManualLogSource Log { get; } = Logger.CreateLogSource("DiomedesPreloader");

		public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>();

		public static void Patch(AssemblyDefinition assembly)
		{
		}

		public static void Initialize()
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			Hook.OnDetour = (Func<Hook, MethodBase, MethodBase, object, bool>)Delegate.Combine(Hook.OnDetour, new Func<Hook, MethodBase, MethodBase, object, bool>(GuardHook));
			ILHook.OnDetour = (Func<ILHook, MethodBase, Manipulator, bool>)Delegate.Combine(ILHook.OnDetour, new Func<ILHook, MethodBase, Manipulator, bool>(GuardILHook));
			Detour.OnDetour = (Func<Detour, MethodBase, MethodBase, bool>)Delegate.Combine(Detour.OnDetour, new Func<Detour, MethodBase, MethodBase, bool>(GuardDetour));
			object obj = <>O.<3>__GuardUpdateWrapper;
			if (obj == null)
			{
				hook_UpdateWrapper val = GuardUpdateWrapper;
				<>O.<3>__GuardUpdateWrapper = val;
				obj = (object)val;
			}
			PatchFunctions.UpdateWrapper += (hook_UpdateWrapper)obj;
		}

		private static bool GuardDetour(Detour detour, MethodBase source, MethodBase target)
		{
			if (!IsProtectedMethod(source))
			{
				return true;
			}
			return false;
		}

		private static bool GuardILHook(ILHook hook, MethodBase source, Manipulator manipulator)
		{
			if (!IsProtectedMethod(source))
			{
				return true;
			}
			return false;
		}

		private static bool GuardHook(Hook hook, MethodBase source, MethodBase target, object arg4)
		{
			if (!IsProtectedMethod(source))
			{
				return true;
			}
			return false;
		}

		private static MethodInfo GuardUpdateWrapper(orig_UpdateWrapper orig, MethodBase original, PatchInfo patchInfo)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!IsProtectedMethod(original))
			{
				return orig.Invoke(original, patchInfo);
			}
			return orig.Invoke(original, new PatchInfo());
		}

		private static bool IsProtectedMethod(MethodBase? method)
		{
			string text = (method?.DeclaringType?.Assembly)?.GetName().Name.ToLowerInvariant();
			if (text == null)
			{
				return false;
			}
			if (!text.Contains("diomedes"))
			{
				return text.Contains("athena");
			}
			return true;
		}

		public static void Finish()
		{
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static bool IsPresent()
		{
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Diomedes.Client.Preloader";

		public const string PLUGIN_NAME = "Diomedes.Client.Preloader";

		public const string PLUGIN_VERSION = "0.9.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BepInEx/core/Diomedes/Diomedes.Shared.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Athena;
using Diomedes.Shared.Data;
using Diomedes.Shared.Data.Settings;
using Diomedes.Shared.Data.User;
using Diomedes.Shared.GameMode;
using Diomedes.Shared.GameMode.GameSettings;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Serilog;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Diomedes.Shared")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+03a1858111402c9890133d64cf3f83ce16b9ffdb")]
[assembly: AssemblyProduct("Diomedes.Shared")]
[assembly: AssemblyTitle("Diomedes.Shared")]
[assembly: AssemblyVersion("0.9.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Diomedes.Shared
{
	public static class DiomedesHelpers
	{
		public enum DurationFormat
		{
			AlwaysIncludeHours,
			IncludeHours,
			NeverIncludeHours
		}

		public const int LATEST_LC_VERSION = 81;

		public static readonly JsonSerializerSettings JSONSettings = new JsonSerializerSettings
		{
			ContractResolver = (IContractResolver)new DefaultContractResolver
			{
				NamingStrategy = (NamingStrategy)new SnakeCaseNamingStrategy()
			}
		};

		public static List<GameSettingsType> GetSettingsForGameMode<T>() where T : IGameMode
		{
			List<GameSettingsType> list = new List<GameSettingsType>();
			PropertyInfo[] properties = typeof(T).GetProperties();
			for (int i = 0; i < properties.Length; i++)
			{
				GameSettingsRefAttribute customAttribute = properties[i].GetCustomAttribute<GameSettingsRefAttribute>();
				if (customAttribute != null)
				{
					list.Add(customAttribute.SettingsType);
				}
			}
			return list;
		}

		public static bool TryUpdateGameSettings<T>(T gameInstance, GameSettingsType settingsType, BinaryReader reader, [NotNullWhen(true)] out IGameSettings? settings) where T : IGameMode
		{
			PropertyInfo[] properties = gameInstance.GetType().GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				GameSettingsRefAttribute customAttribute = propertyInfo.GetCustomAttribute<GameSettingsRefAttribute>();
				if (customAttribute != null && customAttribute.SettingsType == settingsType)
				{
					settings = (IGameSettings)propertyInfo.PropertyType.GetMethod("AthenaReadFrom").Invoke(null, new object[1] { reader });
					propertyInfo.SetValue(gameInstance, settings);
					return true;
				}
			}
			settings = null;
			return false;
		}

		public static ushort GetMaxPacketID()
		{
			ushort num = 0;
			FieldInfo[] fields = typeof(PacketID).GetFields();
			for (int i = 0; i < fields.Length; i++)
			{
				ushort num2 = (ushort)fields[i].GetValue(null);
				if (num2 > num)
				{
					num = num2;
				}
			}
			return num;
		}

		public static string ToOrdinal(int number)
		{
			if (number < 0)
			{
				return number.ToString();
			}
			int num = number % 100;
			if (num == 11 || num == 12 || num == 13)
			{
				return number + "th";
			}
			return (number % 10) switch
			{
				1 => number + "st", 
				2 => number + "nd", 
				3 => number + "rd", 
				_ => number + "th", 
			};
		}

		public static string ToPercentage(float value)
		{
			return Math.Round(value * 100f) + "%";
		}

		public static string ToFormattedDifference(int target, int actual)
		{
			if (target == actual)
			{
				return "0";
			}
			if (target < actual)
			{
				return $"+{actual - target}";
			}
			return $"-{target - actual}";
		}

		public static string ToDuration(TimeSpan timer, DurationFormat format = DurationFormat.AlwaysIncludeHours)
		{
			if (format == DurationFormat.AlwaysIncludeHours || (format == DurationFormat.IncludeHours && timer.TotalHours > 0.0))
			{
				return $"{(int)timer.TotalHours:D2}:{timer.Minutes:D2}:{timer.Seconds:D2}";
			}
			return $"{timer.Minutes:D2}:{timer.Seconds:D2}";
		}

		public static string GroupSizeName(int number)
		{
			return number switch
			{
				1 => "Solo", 
				2 => "Duo", 
				3 => "Trio", 
				4 => "Squad", 
				_ => "Crowd", 
			};
		}

		public static string ToNaturalList(IList<string> items)
		{
			if (items == null || items.Count == 0)
			{
				return string.Empty;
			}
			if (items.Count == 1)
			{
				return items[0];
			}
			return string.Join(", ", items.Take(items.Count - 1)) + " and " + items.Last();
		}

		public static float GetProgress(DateTime start, DateTime end, DateTime now)
		{
			double totalSeconds = (end - start).TotalSeconds;
			return Math.Clamp((float)((now - start).TotalSeconds / totalSeconds), 0f, 1f);
		}
	}
	public static class DiomedesConstants
	{
		public const string VERSION = "0.9.0";
	}
}
namespace Diomedes.Shared.Util
{
	public static class SessionTokenHelpers
	{
		public static string GenerateSessionToken()
		{
			byte[] array = new byte[32];
			using (RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create())
			{
				randomNumberGenerator.GetBytes(array);
			}
			return Convert.ToBase64String(array);
		}

		public static string HashSessionToken(string token)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(token);
			using SHA256 sHA = SHA256.Create();
			return BytesToHex(sHA.ComputeHash(bytes));
		}

		private static string BytesToHex(byte[] bytes)
		{
			StringBuilder stringBuilder = new StringBuilder(bytes.Length * 2);
			foreach (byte b in bytes)
			{
				stringBuilder.Append(b.ToString("x2"));
			}
			return stringBuilder.ToString();
		}
	}
}
namespace Diomedes.Shared.Util.Extensions
{
	public static class EnumFlagExtensions
	{
		public static TEnum SetFlag<TEnum>(this TEnum flags, TEnum flag, bool enabled) where TEnum : struct, Enum
		{
			ulong num = Convert.ToUInt64(flags);
			ulong num2 = Convert.ToUInt64(flag);
			ulong value = (enabled ? (num | num2) : (num & ~num2));
			return (TEnum)Enum.ToObject(typeof(TEnum), value);
		}

		public static bool HasFlagFast<TEnum>(this TEnum flags, TEnum flag) where TEnum : struct, Enum
		{
			ulong num = Convert.ToUInt64(flags);
			ulong num2 = Convert.ToUInt64(flag);
			return (num & num2) == num2;
		}
	}
	public static class RandomExtensions
	{
		public static T NextItem<T>(this Random random, List<T> list)
		{
			return list[random.Next(0, list.Count)];
		}

		public static T NextWeighted<T>(this Random random, List<T> list) where T : IWeighted
		{
			int num = list.Sum((T it) => it.Weight);
			int num2 = random.Next(0, num + 1);
			T result = default(T);
			foreach (T item in list)
			{
				result = item;
				num2 -= item.Weight;
				if (num2 <= 0)
				{
					break;
				}
			}
			return result;
		}
	}
}
namespace Diomedes.Shared.Logging
{
	public class ConsoleLogger : IDiomedesLogger
	{
		public void LogDebug(object message)
		{
			ConsoleColor foregroundColor = Console.ForegroundColor;
			Console.ForegroundColor = ConsoleColor.DarkGray;
			Console.WriteLine($"[DEBUG] {message}");
			Console.ForegroundColor = foregroundColor;
		}

		public void LogInfo(object message)
		{
			Console.WriteLine($"[INFO] {message}");
		}

		public void LogWarn(object message)
		{
			ConsoleColor foregroundColor = Console.ForegroundColor;
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.WriteLine($"[WARN] {message}");
			Console.ForegroundColor = foregroundColor;
		}

		public void LogError(object message)
		{
			ConsoleColor foregroundColor = Console.ForegroundColor;
			Console.ForegroundColor = ConsoleColor.Red;
			Console.WriteLine($"[ERROR] {message}");
			Console.ForegroundColor = foregroundColor;
		}
	}
	public class FileLogger : IDiomedesLogger, IDisposable, IAsyncDisposable
	{
		private readonly FileStream? _stream;

		private readonly TextWriter? _writer;

		private readonly Timer? _timer;

		public FileLogger(string filePath)
		{
			try
			{
				_stream = new FileStream(filePath, FileMode.Create);
				_writer = TextWriter.Synchronized(new StreamWriter(_stream, Encoding.UTF8));
				_timer = new Timer(delegate
				{
					_writer.Flush();
				}, null, 2000, 2000);
			}
			catch (Exception)
			{
			}
		}

		public void LogDebug(object message)
		{
			_writer?.WriteLine($"[DEBUG] {message}");
		}

		public void LogInfo(object message)
		{
			_writer?.WriteLine($"[INFO] {message}");
		}

		public void LogWarn(object message)
		{
			_writer?.WriteLine($"[WARN] {message}");
		}

		public void LogError(object message)
		{
			_writer?.WriteLine($"[ERROR] {message}");
		}

		public void Dispose()
		{
			_stream?.Dispose();
			_writer?.Dispose();
			_timer?.Dispose();
		}

		public async ValueTask DisposeAsync()
		{
			if (_stream != null)
			{
				await _stream.DisposeAsync();
			}
			if (_writer != null)
			{
				await _writer.DisposeAsync();
			}
			if (_timer != null)
			{
				await _timer.DisposeAsync();
			}
		}
	}
	public interface IDiomedesLogger
	{
		void LogDebug(object message);

		void LogInfo(object message);

		void LogWarn(object message);

		void LogError(object message);
	}
	public class MultiLogger(params IDiomedesLogger[] loggers) : IDiomedesLogger
	{
		public void LogDebug(object message)
		{
			IDiomedesLogger[] array = loggers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].LogDebug(message);
			}
		}

		public void LogInfo(object message)
		{
			IDiomedesLogger[] array = loggers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].LogInfo(message);
			}
		}

		public void LogWarn(object message)
		{
			IDiomedesLogger[] array = loggers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].LogWarn(message);
			}
		}

		public void LogError(object message)
		{
			IDiomedesLogger[] array = loggers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].LogError(message);
			}
		}
	}
	public class PrefixWrappedLogger(string prefix, IDiomedesLogger passthrough) : IDiomedesLogger
	{
		public void LogDebug(object message)
		{
			passthrough.LogDebug($"[{prefix}] {message}");
		}

		public void LogInfo(object message)
		{
			passthrough.LogInfo($"[{prefix}] {message}");
		}

		public void LogWarn(object message)
		{
			passthrough.LogWarn($"[{prefix}] {message}");
		}

		public void LogError(object message)
		{
			passthrough.LogError($"[{prefix}] {message}");
		}
	}
	public class RemoveDebugLogsLogger(IDiomedesLogger passthrough) : IDiomedesLogger
	{
		public void LogDebug(object message)
		{
		}

		public void LogInfo(object message)
		{
			passthrough.LogInfo(message);
		}

		public void LogWarn(object message)
		{
			passthrough.LogWarn(message);
		}

		public void LogError(object message)
		{
			passthrough.LogError(message);
		}
	}
	public class WrapSerilogLogger(ILogger logger) : IDiomedesLogger
	{
		public void LogDebug(object message)
		{
			logger.Debug(message.ToString());
		}

		public void LogInfo(object message)
		{
			logger.Information(message.ToString());
		}

		public void LogWarn(object message)
		{
			logger.Warning(message.ToString());
		}

		public void LogError(object message)
		{
			logger.Error(message.ToString());
		}
	}
}
namespace Diomedes.Shared.GameMode
{
	[PacketSerializable]
	public class DayInfo
	{
		public bool IsCompanyDay { get; set; }

		public int Seed { get; set; }

		public string MoonKey { get; set; } = string.Empty;

		public string WeatherKey { get; set; } = string.Empty;

		public static bool operator ==(DayInfo day1, DayInfo day2)
		{
			return day1.Seed != day2.Seed;
		}

		public static bool operator !=(DayInfo day1, DayInfo day2)
		{
			return !(day1 == day2);
		}

		public override bool Equals(object? obj)
		{
			if (this == obj)
			{
				return true;
			}
			if (obj == null)
			{
				return false;
			}
			throw new NotImplementedException();
		}

		public override int GetHashCode()
		{
			throw new NotImplementedException();
		}

		public static DayInfo AthenaReadFrom(BinaryReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			bool isCompanyDay = reader.ReadBoolean();
			int seed = reader.ReadInt32();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"MoonKey has a length of {num} exceeding the max 255");
			}
			string moonKey = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			int num2 = reader.ReadInt32();
			if (num2 >= 256)
			{
				throw new AthenaSerializationException($"WeatherKey has a length of {num2} exceeding the max 255");
			}
			string weatherKey = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			return new DayInfo
			{
				IsCompanyDay = isCompanyDay,
				Seed = seed,
				MoonKey = moonKey,
				WeatherKey = weatherKey
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(IsCompanyDay);
			writer.Write(Seed);
			byte[] bytes = Encoding.Unicode.GetBytes(MoonKey);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			byte[] bytes2 = Encoding.Unicode.GetBytes(WeatherKey);
			writer.Write(bytes2.Length);
			writer.Write(bytes2);
		}
	}
	public interface IGameMode
	{
		string Name { get; }
	}
}
namespace Diomedes.Shared.GameMode.Race
{
	public enum RaceCheckpointType : byte
	{
		Day,
		Quota,
		Race
	}
	[PacketSerializable]
	public class QuotaInfo
	{
		public DayInfo[] Days { get; init; } = Array.Empty<DayInfo>();

		public void DebugLog(ILogger logger)
		{
			for (int i = 0; i < Days.Length; i++)
			{
				DayInfo dayInfo = Days[i];
				logger.Information("\tDay {Day}: {Moon} ({Weather}); Seed = {Seed}", new object[4] { i, dayInfo.MoonKey, dayInfo.WeatherKey, dayInfo.Seed });
			}
		}

		public static QuotaInfo AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Days has a length of {num} exceeding the max 255");
			}
			DayInfo[] array = new DayInfo[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = DayInfo.AthenaReadFrom(reader);
			}
			return new QuotaInfo
			{
				Days = array
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Days.Length);
			DayInfo[] days = Days;
			for (int i = 0; i < days.Length; i++)
			{
				days[i].AthenaWriteTo(writer);
			}
		}
	}
	[PacketSerializable]
	public class RaceGameData
	{
		public QuotaInfo[] Quotas { get; init; } = Array.Empty<QuotaInfo>();

		public void DebugLog(ILogger logger)
		{
			for (int i = 0; i < Quotas.Length; i++)
			{
				QuotaInfo obj = Quotas[i];
				logger.Information<int>("Quota {Quota}:", i);
				obj.DebugLog(logger);
			}
		}

		public bool TryGetDay(int quota, int day, [NotNullWhen(true)] out DayInfo? dayInfo)
		{
			dayInfo = null;
			if (quota >= Quotas.Length)
			{
				return false;
			}
			if (day >= Quotas[quota].Days.Length)
			{
				return false;
			}
			dayInfo = Quotas[quota].Days[day];
			return true;
		}

		public static RaceGameData AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Quotas has a length of {num} exceeding the max 255");
			}
			QuotaInfo[] array = new QuotaInfo[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = QuotaInfo.AthenaReadFrom(reader);
			}
			return new RaceGameData
			{
				Quotas = array
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Quotas.Length);
			QuotaInfo[] quotas = Quotas;
			for (int i = 0; i < quotas.Length; i++)
			{
				quotas[i].AthenaWriteTo(writer);
			}
		}
	}
	[PacketSerializable]
	public class RaceGameResults
	{
		public byte[] CrewPlacements { get; set; } = Array.Empty<byte>();

		public static RaceGameResults AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"CrewPlacements has a length of {num} exceeding the max 255");
			}
			byte[] array = new byte[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = reader.ReadByte();
			}
			return new RaceGameResults
			{
				CrewPlacements = array
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(CrewPlacements.Length);
			byte[] crewPlacements = CrewPlacements;
			foreach (byte value in crewPlacements)
			{
				writer.Write(value);
			}
		}
	}
	public enum CompletionBroadcastMode : byte
	{
		Everytime,
		CrewNewHighest,
		MatchNewHighest
	}
	[PacketSerializable]
	public class RaceGameSettings : IGameSettings
	{
		public int TargetQuota { get; set; } = 3;

		public QuotaFormula Formula { get; set; } = new QuotaFormula();

		public bool AllowDuplicateMoonsInQuota { get; set; }

		public bool AllowDuplicateWeathersInQuota { get; set; }

		public bool IncludeDine { get; set; }

		public bool GenerateLocally { get; set; }

		public int MaxCompletions { get; set; } = 1;

		public CompletionBroadcastMode CompletionBroadcast { get; set; } = CompletionBroadcastMode.CrewNewHighest;

		public GameSettingsType SettingsType => GameSettingsType.Race;

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine($"Race to be the first {MaxCompletions} crew(s) to complete the target quota!");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine($"TargetQuota = {TargetQuota}");
			stringBuilder.AppendLine(Formula.Describe() ?? "");
			stringBuilder.AppendLine("Scrap is not kept between quotas");
			stringBuilder.AppendLine("Losing a quota restarts the current one.");
			switch (CompletionBroadcast)
			{
			case CompletionBroadcastMode.Everytime:
				stringBuilder.AppendLine("Everytime a crew completes a day/quota a message is broadcasted.");
				break;
			case CompletionBroadcastMode.CrewNewHighest:
				stringBuilder.AppendLine("When a crew reaches a new highest day/quota a message is broadcasted");
				break;
			case CompletionBroadcastMode.MatchNewHighest:
				stringBuilder.AppendLine("When a crew reaches a new highest day/quota across the entire match, a message is broadcasted.");
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return stringBuilder.ToString();
		}

		public static RaceGameSettings AthenaReadFrom(BinaryReader reader)
		{
			int targetQuota = reader.ReadInt32();
			QuotaFormula formula = QuotaFormula.AthenaReadFrom(reader);
			bool allowDuplicateMoonsInQuota = reader.ReadBoolean();
			bool allowDuplicateWeathersInQuota = reader.ReadBoolean();
			bool includeDine = reader.ReadBoolean();
			bool generateLocally = reader.ReadBoolean();
			int maxCompletions = reader.ReadInt32();
			CompletionBroadcastMode completionBroadcast = (CompletionBroadcastMode)reader.ReadByte();
			return new RaceGameSettings
			{
				TargetQuota = targetQuota,
				Formula = formula,
				AllowDuplicateMoonsInQuota = allowDuplicateMoonsInQuota,
				AllowDuplicateWeathersInQuota = allowDuplicateWeathersInQuota,
				IncludeDine = includeDine,
				GenerateLocally = generateLocally,
				MaxCompletions = maxCompletions,
				CompletionBroadcast = completionBroadcast
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(TargetQuota);
			Formula.AthenaWriteTo(writer);
			writer.Write(AllowDuplicateMoonsInQuota);
			writer.Write(AllowDuplicateWeathersInQuota);
			writer.Write(IncludeDine);
			writer.Write(GenerateLocally);
			writer.Write(MaxCompletions);
			writer.Write((byte)CompletionBroadcast);
		}
	}
}
namespace Diomedes.Shared.GameMode.Knockout
{
	[PacketSerializable]
	public class KnockoutGameResults
	{
		public byte WinningCrew { get; set; }

		public static KnockoutGameResults AthenaReadFrom(BinaryReader reader)
		{
			byte winningCrew = reader.ReadByte();
			return new KnockoutGameResults
			{
				WinningCrew = winningCrew
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(WinningCrew);
		}
	}
	[PacketSerializable]
	public class KnockoutGameSettings : IGameSettings
	{
		public int Lives { get; set; } = 3;

		public float DepreciationFactor { get; set; } = 0.4f;

		public float SafePercentage { get; set; } = 0.5f;

		public int SafeQuotas { get; set; }

		public bool IncludeDine { get; set; }

		public bool GenerateLocally { get; set; }

		public KnockoutOddStratergy OddStratergy { get; set; }

		public GameSettingsType SettingsType => GameSettingsType.Knockout;

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("Fight to collect the most scrap in a quota, or lose a life and face elimination...");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine($"{Lives} lives");
			stringBuilder.AppendLine("Bottom " + DiomedesHelpers.ToPercentage(1f - SafePercentage) + " lose a life.");
			if (SafeQuotas == 0)
			{
				stringBuilder.AppendLine("No safe quota.");
			}
			else if (SafeQuotas == 1)
			{
				stringBuilder.AppendLine("First quota no lives are lost.");
			}
			else
			{
				stringBuilder.AppendLine($"First {SafeQuotas} quotas have no lives lost.");
			}
			stringBuilder.AppendLine("Scrap is not kept between quotas");
			return stringBuilder.ToString();
		}

		public static KnockoutGameSettings AthenaReadFrom(BinaryReader reader)
		{
			int lives = reader.ReadInt32();
			float depreciationFactor = reader.ReadSingle();
			float safePercentage = reader.ReadSingle();
			int safeQuotas = reader.ReadInt32();
			bool includeDine = reader.ReadBoolean();
			bool generateLocally = reader.ReadBoolean();
			KnockoutOddStratergy oddStratergy = (KnockoutOddStratergy)reader.ReadByte();
			return new KnockoutGameSettings
			{
				Lives = lives,
				DepreciationFactor = depreciationFactor,
				SafePercentage = safePercentage,
				SafeQuotas = safeQuotas,
				IncludeDine = includeDine,
				GenerateLocally = generateLocally,
				OddStratergy = oddStratergy
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Lives);
			writer.Write(DepreciationFactor);
			writer.Write(SafePercentage);
			writer.Write(SafeQuotas);
			writer.Write(IncludeDine);
			writer.Write(GenerateLocally);
			writer.Write((byte)OddStratergy);
		}
	}
	[PacketSerializable]
	public class Placement
	{
		public byte CrewID;

		public int ScrapSold;

		public static Placement AthenaReadFrom(BinaryReader reader)
		{
			return new Placement();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	[PacketSerializable]
	public class KnockoutLeaderboard
	{
		public Placement[] Placements;

		[Obsolete]
		public int SafePlacement;

		public int RemainingCrews;

		public static KnockoutLeaderboard AthenaReadFrom(BinaryReader reader)
		{
			return new KnockoutLeaderboard();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public enum KnockoutOddStratergy : byte
	{
		RoundUp,
		RoundDown
	}
}
namespace Diomedes.Shared.GameMode.GameSettings
{
	[PacketSerializable]
	public class ChatGameSettings : IGameSettings
	{
		public bool GlobalChat { get; set; } = true;

		public bool DeadAliveTalk { get; set; }

		public GameSettingsType SettingsType => GameSettingsType.Chat;

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (GlobalChat)
			{
				stringBuilder.Append("Players can talk to eachother from any distance");
			}
			if (DeadAliveTalk)
			{
				stringBuilder.Append("The dead can talk with the living");
			}
			return stringBuilder.ToString();
		}

		public static ChatGameSettings AthenaReadFrom(BinaryReader reader)
		{
			bool globalChat = reader.ReadBoolean();
			bool deadAliveTalk = reader.ReadBoolean();
			return new ChatGameSettings
			{
				GlobalChat = globalChat,
				DeadAliveTalk = deadAliveTalk
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(GlobalChat);
			writer.Write(DeadAliveTalk);
		}
	}
	[Flags]
	public enum CompanyFlags : byte
	{
		None = 0,
		CanAttack = 1,
		AlwaysMaxBuyRate = 2
	}
	[PacketSerializable]
	public class CompanyGameSettings : IGameSettings
	{
		public CompanyFlags Flags { get; set; } = CompanyFlags.AlwaysMaxBuyRate;

		public GameSettingsType SettingsType => GameSettingsType.Company;

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (!Flags.HasFlag(CompanyFlags.CanAttack))
			{
				stringBuilder.AppendLine("The company can not attack.");
			}
			if (Flags.HasFlag(CompanyFlags.AlwaysMaxBuyRate))
			{
				stringBuilder.AppendLine("The company always buys at 100%.");
			}
			return stringBuilder.ToString();
		}

		public static CompanyGameSettings AthenaReadFrom(BinaryReader reader)
		{
			CompanyFlags flags = (CompanyFlags)reader.ReadByte();
			return new CompanyGameSettings
			{
				Flags = flags
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write((byte)Flags);
		}
	}
	public enum GameModeType : byte
	{
		Knockout,
		Race,
		Bingo
	}
	[AttributeUsage(AttributeTargets.Property)]
	public sealed class GameSettingsRefAttribute(GameSettingsType settingsType) : Attribute()
	{
		public GameSettingsType SettingsType => settingsType;
	}
	public enum GameSettingsType : byte
	{
		Knockout,
		Race,
		ScrapClear,
		Company,
		Bingo,
		Main,
		Chat
	}
	public interface IGameSettings
	{
		GameSettingsType SettingsType { get; }

		string Description();

		void AthenaWriteTo(BinaryWriter writer);
	}
	[PacketSerializable]
	public class MainGameSettings : IGameSettings
	{
		public GameSettingsType SettingsType => GameSettingsType.Main;

		public bool AllowVanillaLogging { get; set; }

		public int StartingCredits { get; set; } = 60;

		public bool AllowOvertime { get; set; }

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Starting Credits: ");
			stringBuilder.Append(StartingCredits);
			if (AllowVanillaLogging)
			{
				stringBuilder.Append("\nVanilla Logging is enabled (Should only be enabled for debug purposes).");
			}
			if (AllowOvertime)
			{
				stringBuilder.Append("\nOvertime is enabled.");
			}
			return stringBuilder.ToString();
		}

		public static MainGameSettings AthenaReadFrom(BinaryReader reader)
		{
			bool allowVanillaLogging = reader.ReadBoolean();
			int startingCredits = reader.ReadInt32();
			bool allowOvertime = reader.ReadBoolean();
			return new MainGameSettings
			{
				AllowVanillaLogging = allowVanillaLogging,
				StartingCredits = startingCredits,
				AllowOvertime = allowOvertime
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(AllowVanillaLogging);
			writer.Write(StartingCredits);
			writer.Write(AllowOvertime);
		}
	}
	[PacketSerializable]
	public class ScrapClearSettings : IGameSettings
	{
		public GameSettingsType SettingsType => GameSettingsType.ScrapClear;

		public bool ExcludeCertainWeapons { get; set; } = true;

		public bool AutoSell { get; set; } = true;

		public bool AllowSellingDeadPlayers { get; set; }

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Scrap is not kept between quotas.");
			if (ExcludeCertainWeapons)
			{
				stringBuilder.Append(" (Shotguns and knives are excluded)");
			}
			if (AutoSell)
			{
				stringBuilder.Append("\nItems are automatically sold.");
			}
			if (AllowSellingDeadPlayers)
			{
				stringBuilder.Append("\nDead players can be sold for extra cash.");
			}
			return stringBuilder.ToString();
		}

		public static ScrapClearSettings AthenaReadFrom(BinaryReader reader)
		{
			bool excludeCertainWeapons = reader.ReadBoolean();
			bool autoSell = reader.ReadBoolean();
			bool allowSellingDeadPlayers = reader.ReadBoolean();
			return new ScrapClearSettings
			{
				ExcludeCertainWeapons = excludeCertainWeapons,
				AutoSell = autoSell,
				AllowSellingDeadPlayers = allowSellingDeadPlayers
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(ExcludeCertainWeapons);
			writer.Write(AutoSell);
			writer.Write(AllowSellingDeadPlayers);
		}
	}
}
namespace Diomedes.Shared.GameMode.Bingo
{
	[PacketSerializable]
	public class BingoBoard
	{
		public string[] Namespaces { get; init; } = Array.Empty<string>();

		public BingoSquare[,] Squares { get; init; }

		public static BingoBoard AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Namespaces has a length of {num} exceeding the max 255");
			}
			string[] array = new string[num];
			for (int i = 0; i < num; i++)
			{
				int num2 = reader.ReadInt32();
				if (num2 >= 256)
				{
					throw new AthenaSerializationException($"element[NamespacesRank0] in array Namespaces has a length of {num2} exceeding the max 255");
				}
				array[i] = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			}
			int num3 = reader.ReadInt32();
			if (num3 >= 256)
			{
				throw new AthenaSerializationException($"Squares has a length of {num3} exceeding the max 255");
			}
			int num4 = reader.ReadInt32();
			if (num4 >= 256)
			{
				throw new AthenaSerializationException($"Squares has a length of {num4} exceeding the max 255");
			}
			BingoSquare[,] array2 = new BingoSquare[num3, num4];
			for (int j = 0; j < num3; j++)
			{
				for (int k = 0; k < num4; k++)
				{
					array2[j, k] = BingoSquare.AthenaReadFrom(reader);
				}
			}
			return new BingoBoard
			{
				Namespaces = array,
				Squares = array2
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Namespaces.Length);
			string[] namespaces = Namespaces;
			foreach (string s in namespaces)
			{
				byte[] bytes = Encoding.Unicode.GetBytes(s);
				writer.Write(bytes.Length);
				writer.Write(bytes);
			}
			writer.Write(Squares.GetLength(0));
			writer.Write(Squares.GetLength(1));
			BingoSquare[,] squares = Squares;
			int i = squares.GetUpperBound(0);
			int upperBound = squares.GetUpperBound(1);
			for (int j = squares.GetLowerBound(0); j <= i; j++)
			{
				for (int k = squares.GetLowerBound(1); k <= upperBound; k++)
				{
					squares[j, k].AthenaWriteTo(writer);
				}
			}
		}
	}
	[PacketSerializable]
	public class BingoGameSettings : IGameSettings
	{
		public GameSettingsType SettingsType => GameSettingsType.Bingo;

		public string Description()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("Complete challenges along the bingo board to win!");
			stringBuilder.AppendLine("5x5 board");
			stringBuilder.AppendLine("Lockout Bingo: Once a challenge is completed, no other crew can claim it!");
			return stringBuilder.ToString();
		}

		public static BingoGameSettings AthenaReadFrom(BinaryReader reader)
		{
			return new BingoGameSettings();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	[PacketSerializable]
	public class BingoSquare
	{
		public byte NamespaceID { get; init; }

		public string Key { get; init; } = string.Empty;

		public override string ToString()
		{
			return Key;
		}

		public static BingoSquare AthenaReadFrom(BinaryReader reader)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			byte namespaceID = reader.ReadByte();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Key has a length of {num} exceeding the max 255");
			}
			string key = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			return new BingoSquare
			{
				NamespaceID = namespaceID,
				Key = key
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(NamespaceID);
			byte[] bytes = Encoding.Unicode.GetBytes(Key);
			writer.Write(bytes.Length);
			writer.Write(bytes);
		}
	}
	public enum BingoWinCondition : byte
	{
		Line,
		Lockout
	}
	public enum ChallengeDifficulty : byte
	{
		ONE,
		TWO,
		THREE,
		FOUR,
		FIVE
	}
}
namespace Diomedes.Shared.Packets
{
	[PacketSerializable]
	public class ActiveClientRestriction
	{
		public required string LiftedAt { get; init; }

		public bool IsPermanent()
		{
			return string.IsNullOrEmpty(LiftedAt);
		}

		public ActiveClientRestriction()
		{
		}

		public ActiveClientRestriction(DateTime? dateTime)
		{
			LiftedAt = dateTime?.ToString() ?? string.Empty;
		}

		public DateTime AsDateTime()
		{
			return DateTime.Parse(LiftedAt);
		}

		public static ActiveClientRestriction AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"LiftedAt has a length of {num} exceeding the max 255");
			}
			string liftedAt = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			return new ActiveClientRestriction
			{
				LiftedAt = liftedAt
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(LiftedAt);
			writer.Write(bytes.Length);
			writer.Write(bytes);
		}
	}
	[PacketSerializable]
	public class ClientRestrictions
	{
		public ActiveClientRestriction? Access { get; set; }

		public ActiveClientRestriction? Text { get; set; }

		public ActiveClientRestriction? Voice { get; set; }

		public ActiveClientRestriction? Competitive { get; set; }

		public static ClientRestrictions Clean => new ClientRestrictions();

		public void DebugLog(ILogger logger)
		{
			logger.Information<bool>("Access Restricted? {Value}", Access != null);
			logger.Information<bool>("Text Chat Restricted? {Value}", Text != null);
			logger.Information<bool>("Voice Chat Restricted? {Value}", Voice != null);
			logger.Information<bool>("Competitive Restricted? {Value}", Competitive != null);
		}

		public bool IsClean()
		{
			if (Access == null && Text == null && Voice == null)
			{
				return Competitive == null;
			}
			return false;
		}

		public static ClientRestrictions AthenaReadFrom(BinaryReader reader)
		{
			bool num = reader.ReadBoolean();
			ActiveClientRestriction access = null;
			if (num)
			{
				access = ActiveClientRestriction.AthenaReadFrom(reader);
			}
			bool num2 = reader.ReadBoolean();
			ActiveClientRestriction text = null;
			if (num2)
			{
				text = ActiveClientRestriction.AthenaReadFrom(reader);
			}
			bool num3 = reader.ReadBoolean();
			ActiveClientRestriction voice = null;
			if (num3)
			{
				voice = ActiveClientRestriction.AthenaReadFrom(reader);
			}
			bool num4 = reader.ReadBoolean();
			ActiveClientRestriction competitive = null;
			if (num4)
			{
				competitive = ActiveClientRestriction.AthenaReadFrom(reader);
			}
			return new ClientRestrictions
			{
				Access = access,
				Text = text,
				Voice = voice,
				Competitive = competitive
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Access != null);
			if (Access != null)
			{
				Access.AthenaWriteTo(writer);
			}
			writer.Write(Text != null);
			if (Text != null)
			{
				Text.AthenaWriteTo(writer);
			}
			writer.Write(Voice != null);
			if (Voice != null)
			{
				Voice.AthenaWriteTo(writer);
			}
			writer.Write(Competitive != null);
			if (Competitive != null)
			{
				Competitive.AthenaWriteTo(writer);
			}
		}
	}
}
namespace Diomedes.Shared.Data
{
	[PacketSerializable]
	public class DayResults
	{
		public byte Quota { get; init; }

		public byte Day { get; init; }

		public override string ToString()
		{
			return $"Q{Quota}D{Day}";
		}

		public static bool operator >(DayResults r1, DayResults r2)
		{
			if (r1.Quota > r2.Quota)
			{
				return true;
			}
			if (r1.Day > r2.Day)
			{
				return true;
			}
			return false;
		}

		public static bool operator <(DayResults r1, DayResults r2)
		{
			if (r1.Quota < r2.Quota)
			{
				return true;
			}
			if (r1.Day < r2.Day)
			{
				return true;
			}
			return false;
		}

		public static DayResults AthenaReadFrom(BinaryReader reader)
		{
			byte quota = reader.ReadByte();
			byte day = reader.ReadByte();
			return new DayResults
			{
				Quota = quota,
				Day = day
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Quota);
			writer.Write(Day);
		}
	}
	[PacketSerializable]
	public class DColor
	{
		public byte Red { get; init; }

		public byte Green { get; init; }

		public byte Blue { get; init; }

		public static DColor FromHexCode(string hexCode)
		{
			string text = hexCode.Replace("#", string.Empty);
			string s = text.Substring(0, 2);
			string s2 = text.Substring(2, 2);
			string s3 = text.Substring(4, 2);
			return new DColor
			{
				Red = byte.Parse(s, NumberStyles.HexNumber),
				Green = byte.Parse(s2, NumberStyles.HexNumber),
				Blue = byte.Parse(s3, NumberStyles.HexNumber)
			};
		}

		public string ToHexCode()
		{
			return $"#{Red:X2}{Green:X2}{Blue:X2}";
		}

		public static DColor AthenaReadFrom(BinaryReader reader)
		{
			byte red = reader.ReadByte();
			byte green = reader.ReadByte();
			byte blue = reader.ReadByte();
			return new DColor
			{
				Red = red,
				Green = green,
				Blue = blue
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Red);
			writer.Write(Green);
			writer.Write(Blue);
		}
	}
	public interface IWeighted
	{
		int Weight { get; }
	}
	public class PossibleChoice<T>(T value, int weight) : IWeighted
	{
		public int Weight => <weight>P;

		public T Value => <value>P;
	}
	[PacketSerializable]
	public class QuotaResults
	{
		public int ScrapSold { get; init; }

		public bool Passed { get; init; }

		public static QuotaResults AthenaReadFrom(BinaryReader reader)
		{
			int scrapSold = reader.ReadInt32();
			bool passed = reader.ReadBoolean();
			return new QuotaResults
			{
				ScrapSold = scrapSold,
				Passed = passed
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(ScrapSold);
			writer.Write(Passed);
		}
	}
	[PacketSerializable]
	public class SerializableDateTime
	{
		public int Year { get; init; }

		public byte Month { get; init; }

		public byte Day { get; init; }

		public byte Hour { get; init; }

		public byte Minute { get; init; }

		public byte Second { get; init; }

		public static SerializableDateTime FromDateTime(DateTime dateTime)
		{
			return new SerializableDateTime
			{
				Year = dateTime.Year,
				Month = (byte)dateTime.Month,
				Day = (byte)dateTime.Day,
				Hour = (byte)dateTime.Hour,
				Minute = (byte)dateTime.Minute,
				Second = (byte)dateTime.Second
			};
		}

		public static SerializableDateTime Parse(string input)
		{
			return FromDateTime(DateTime.Parse(input));
		}

		public DateTime ToDateTime()
		{
			return new DateTime(Year, Month, Day, Hour, Minute, Second);
		}

		public static SerializableDateTime AthenaReadFrom(BinaryReader reader)
		{
			int year = reader.ReadInt32();
			byte month = reader.ReadByte();
			byte day = reader.ReadByte();
			byte hour = reader.ReadByte();
			byte minute = reader.ReadByte();
			byte second = reader.ReadByte();
			return new SerializableDateTime
			{
				Year = year,
				Month = month,
				Day = day,
				Hour = hour,
				Minute = minute,
				Second = second
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Year);
			writer.Write(Month);
			writer.Write(Day);
			writer.Write(Hour);
			writer.Write(Minute);
			writer.Write(Second);
		}
	}
	[PacketSerializable]
	public class ServerInfo
	{
		public string Version { get; init; } = "0.9.0";

		public string DiscordClientID { get; init; } = string.Empty;

		public static ServerInfo AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: 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)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Version has a length of {num} exceeding the max 255");
			}
			string version = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			int num2 = reader.ReadInt32();
			if (num2 >= 256)
			{
				throw new AthenaSerializationException($"DiscordClientID has a length of {num2} exceeding the max 255");
			}
			string discordClientID = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			return new ServerInfo
			{
				Version = version,
				DiscordClientID = discordClientID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(Version);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			byte[] bytes2 = Encoding.Unicode.GetBytes(DiscordClientID);
			writer.Write(bytes2.Length);
			writer.Write(bytes2);
		}
	}
}
namespace Diomedes.Shared.Data.User
{
	[PacketSerializable]
	public class CrewInfo
	{
		public byte ID { get; init; }

		public string Name { get; set; } = "A crew";

		public UserInfo[] Users { get; set; } = Array.Empty<UserInfo>();

		public Guid CaptainUUID { get; set; }

		public DColor Color { get; set; } = DColor.FromHexCode("#ffffff");

		public override string ToString()
		{
			return $"{Name} (captain: {CaptainUUID})";
		}

		public static CrewInfo AthenaReadFrom(BinaryReader reader)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			byte iD = reader.ReadByte();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Name has a length of {num} exceeding the max 255");
			}
			string name = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			int num2 = reader.ReadInt32();
			if (num2 >= 256)
			{
				throw new AthenaSerializationException($"Users has a length of {num2} exceeding the max 255");
			}
			UserInfo[] array = new UserInfo[num2];
			for (int i = 0; i < num2; i++)
			{
				array[i] = UserInfo.AthenaReadFrom(reader);
			}
			Guid captainUUID = new Guid(reader.ReadBytes(16));
			DColor color = DColor.AthenaReadFrom(reader);
			return new CrewInfo
			{
				ID = iD,
				Name = name,
				Users = array,
				CaptainUUID = captainUUID,
				Color = color
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(ID);
			byte[] bytes = Encoding.Unicode.GetBytes(Name);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			writer.Write(Users.Length);
			UserInfo[] users = Users;
			for (int i = 0; i < users.Length; i++)
			{
				users[i].AthenaWriteTo(writer);
			}
			writer.Write(CaptainUUID.ToByteArray());
			Color.AthenaWriteTo(writer);
		}
	}
	public enum LoginFailReason : byte
	{
		DisallowGuests,
		NotWhitelisted,
		DiscordAuthFail,
		SessionTokenInvalid,
		MismatchSteamID,
		AccessBanned,
		InternalServerFail,
		ServerFull
	}
	[PacketSerializable]
	public class UserInfo
	{
		public Guid UUID { get; init; }

		public string Username { get; init; } = string.Empty;

		public ulong SteamId { get; init; }

		public string DiscordID { get; init; }

		public override int GetHashCode()
		{
			return UUID.GetHashCode();
		}

		public override string ToString()
		{
			return $"{Username} ({UUID}) ({SteamId})";
		}

		public static UserInfo AthenaReadFrom(BinaryReader reader)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Guid uUID = new Guid(reader.ReadBytes(16));
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Username has a length of {num} exceeding the max 255");
			}
			string username = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			ulong steamId = reader.ReadUInt64();
			int num2 = reader.ReadInt32();
			if (num2 >= 256)
			{
				throw new AthenaSerializationException($"DiscordID has a length of {num2} exceeding the max 255");
			}
			string discordID = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			return new UserInfo
			{
				UUID = uUID,
				Username = username,
				SteamId = steamId,
				DiscordID = discordID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(UUID.ToByteArray());
			byte[] bytes = Encoding.Unicode.GetBytes(Username);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			writer.Write(SteamId);
			byte[] bytes2 = Encoding.Unicode.GetBytes(DiscordID);
			writer.Write(bytes2.Length);
			writer.Write(bytes2);
		}
	}
}
namespace Diomedes.Shared.Data.Settings
{
	[PacketSerializable]
	public class QuotaFormula
	{
		public int Starting { get; set; } = 400;

		public int LinearIncrease { get; set; } = 100;

		public int CalculateForQuota(int quota)
		{
			return Starting + LinearIncrease * quota;
		}

		public string Describe()
		{
			return $"Quota starts at {Starting} and increases by +{LinearIncrease}";
		}

		public static QuotaFormula AthenaReadFrom(BinaryReader reader)
		{
			int starting = reader.ReadInt32();
			int linearIncrease = reader.ReadInt32();
			return new QuotaFormula
			{
				Starting = starting,
				LinearIncrease = linearIncrease
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Starting);
			writer.Write(LinearIncrease);
		}
	}
}
namespace Diomedes.Shared.Data.Match
{
	public enum LobbyJoinFailReason : byte
	{
		MatchFull,
		MatchDoesNotExist,
		AlreadyInAMatch,
		InProgress,
		TimedOut,
		InternalServerFail
	}
	[PacketSerializable]
	public class MatchInfo
	{
		public int JoinCode { get; init; }

		public GameModeType GameMode { get; init; }

		public CrewInfo[] Crews { get; init; }

		public Guid HostUUID { get; init; }

		public string Name { get; init; } = string.Empty;

		public bool IsDaily { get; init; }

		public bool IsComp { get; init; }

		public static MatchInfo AthenaReadFrom(BinaryReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			int joinCode = reader.ReadInt32();
			GameModeType gameMode = (GameModeType)reader.ReadByte();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Crews has a length of {num} exceeding the max 255");
			}
			CrewInfo[] array = new CrewInfo[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = CrewInfo.AthenaReadFrom(reader);
			}
			Guid hostUUID = new Guid(reader.ReadBytes(16));
			int num2 = reader.ReadInt32();
			if (num2 >= 256)
			{
				throw new AthenaSerializationException($"Name has a length of {num2} exceeding the max 255");
			}
			string name = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			bool isDaily = reader.ReadBoolean();
			bool isComp = reader.ReadBoolean();
			return new MatchInfo
			{
				JoinCode = joinCode,
				GameMode = gameMode,
				Crews = array,
				HostUUID = hostUUID,
				Name = name,
				IsDaily = isDaily,
				IsComp = isComp
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(JoinCode);
			writer.Write((byte)GameMode);
			writer.Write(Crews.Length);
			CrewInfo[] crews = Crews;
			for (int i = 0; i < crews.Length; i++)
			{
				crews[i].AthenaWriteTo(writer);
			}
			writer.Write(HostUUID.ToByteArray());
			byte[] bytes = Encoding.Unicode.GetBytes(Name);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			writer.Write(IsDaily);
			writer.Write(IsComp);
		}
	}
	public enum MatchState : byte
	{
		InLobby,
		PreGame,
		InGame,
		PostGame
	}
}
namespace Diomedes.Shared.Data.Chat
{
	public class ChatChannel : IEnumerable<ChatMessage>, IEnumerable
	{
		public ChatTarget Target;

		public string ChannelName = "Default Name";

		private List<ChatMessage> _messages = new List<ChatMessage>();

		public static ChatFilter? Filter { get; set; }

		public event Action<ChatMessage> OnNewMessage = delegate
		{
		};

		public void Add(ChatMessage message)
		{
			if (Filter != null)
			{
				message.Message = Filter.Filter(message.Message);
			}
			_messages.Add(message);
			this.OnNewMessage(message);
		}

		public IEnumerator<ChatMessage> GetEnumerator()
		{
			return _messages.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public class ChatFilter
	{
		private record struct CompiledFilter(Regex Regex, string Replacement);

		private List<CompiledFilter> _regex = words.Select((string it) => new CompiledFilter(new Regex("\\b" + it.ToLowerInvariant() + "\\b"), new string('*', it.Length))).ToList();

		public ChatFilter(IEnumerable<string> words)
		{
		}

		public string Filter(string input)
		{
			foreach (CompiledFilter item in _regex)
			{
				input = item.Regex.Replace(input, item.Replacement);
			}
			return input;
		}
	}
	[PacketSerializable]
	public class ChatMessage
	{
		public ChatTarget Target { get; init; }

		public string Sender { get; init; } = string.Empty;

		public string Message { get; set; } = string.Empty;

		public bool IsServerMessage()
		{
			return string.IsNullOrEmpty(Sender);
		}

		public static ChatMessage AthenaReadFrom(BinaryReader reader)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ChatTarget target = (ChatTarget)reader.ReadByte();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Sender has a length of {num} exceeding the max 255");
			}
			string sender = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			int num2 = reader.ReadInt32();
			if (num2 >= 256)
			{
				throw new AthenaSerializationException($"Message has a length of {num2} exceeding the max 255");
			}
			string message = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			return new ChatMessage
			{
				Target = target,
				Sender = sender,
				Message = message
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write((byte)Target);
			byte[] bytes = Encoding.Unicode.GetBytes(Sender);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			byte[] bytes2 = Encoding.Unicode.GetBytes(Message);
			writer.Write(bytes2.Length);
			writer.Write(bytes2);
		}
	}
	[PacketSerializable]
	public class ChatRequest
	{
		public ChatTarget Target { get; init; }

		public string Message { get; init; } = string.Empty;

		public static ChatRequest AthenaReadFrom(BinaryReader reader)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			ChatTarget target = (ChatTarget)reader.ReadByte();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Message has a length of {num} exceeding the max 255");
			}
			string message = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			return new ChatRequest
			{
				Target = target,
				Message = message
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write((byte)Target);
			byte[] bytes = Encoding.Unicode.GetBytes(Message);
			writer.Write(bytes.Length);
			writer.Write(bytes);
		}
	}
	public enum ChatTarget : byte
	{
		Match,
		Crew
	}
}

BepInEx/core/Diomedes/Diomedes.Shared.Packets.dll

Decompiled 16 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Athena;
using Diomedes.Shared.Data;
using Diomedes.Shared.Data.Chat;
using Diomedes.Shared.Data.Match;
using Diomedes.Shared.Data.User;
using Diomedes.Shared.GameMode.Bingo;
using Diomedes.Shared.GameMode.GameSettings;
using Diomedes.Shared.GameMode.Knockout;
using Diomedes.Shared.GameMode.Race;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Diomedes.Shared.Packets")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+03a1858111402c9890133d64cf3f83ce16b9ffdb")]
[assembly: AssemblyProduct("Diomedes.Shared.Packets")]
[assembly: AssemblyTitle("Diomedes.Shared.Packets")]
[assembly: AssemblyVersion("0.9.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Diomedes.Shared
{
	public class BingoBoardPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)37913);

		public required BingoBoard Board { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static BingoBoardPacket AthenaReadFrom(BinaryReader reader)
		{
			BingoBoard board = BingoBoard.AthenaReadFrom(reader);
			return new BingoBoardPacket
			{
				Board = board
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Board.AthenaWriteTo(writer);
		}
	}
	public class BingoChallengeCompletePacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)62286);

		public required byte ChallengeID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static BingoChallengeCompletePacket AthenaReadFrom(BinaryReader reader)
		{
			byte challengeID = reader.ReadByte();
			return new BingoChallengeCompletePacket
			{
				ChallengeID = challengeID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(ChallengeID);
		}
	}
	public class BingoChallengeCompletedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)12441);

		public required byte ChallengeID { get; init; }

		public required byte CrewID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static BingoChallengeCompletedPacket AthenaReadFrom(BinaryReader reader)
		{
			byte challengeID = reader.ReadByte();
			byte crewID = reader.ReadByte();
			return new BingoChallengeCompletedPacket
			{
				ChallengeID = challengeID,
				CrewID = crewID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(ChallengeID);
			writer.Write(CrewID);
		}
	}
	public class CaptainReadyPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)49677);

		public required ulong LobbyID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static CaptainReadyPacket AthenaReadFrom(BinaryReader reader)
		{
			ulong lobbyID = reader.ReadUInt64();
			return new CaptainReadyPacket
			{
				LobbyID = lobbyID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(LobbyID);
		}
	}
	public class ChatMessagePacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)45062);

		public ChatMessage Message { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ChatMessagePacket AthenaReadFrom(BinaryReader reader)
		{
			ChatMessage message = ChatMessage.AthenaReadFrom(reader);
			return new ChatMessagePacket
			{
				Message = message
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Message.AthenaWriteTo(writer);
		}
	}
	public class ChatRequestPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)46686);

		public ChatRequest Request { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ChatRequestPacket AthenaReadFrom(BinaryReader reader)
		{
			ChatRequest request = ChatRequest.AthenaReadFrom(reader);
			return new ChatRequestPacket
			{
				Request = request
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Request.AthenaWriteTo(writer);
		}
	}
	public class CrewReadyPacket : AthenaPacket
	{
		public static readonly CrewReadyPacket Instance = new CrewReadyPacket();

		public static readonly PacketID ID = new PacketID((ushort)62038);

		private CrewReadyPacket()
		{
		}

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static CrewReadyPacket AthenaReadFrom(BinaryReader reader)
		{
			return new CrewReadyPacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class DayCompletedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)60654);

		public required DayResults Results { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static DayCompletedPacket AthenaReadFrom(BinaryReader reader)
		{
			DayResults results = DayResults.AthenaReadFrom(reader);
			return new DayCompletedPacket
			{
				Results = results
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Results.AthenaWriteTo(writer);
		}
	}
	public class DisbandCrewPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)18105);

		public byte CrewID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static DisbandCrewPacket AthenaReadFrom(BinaryReader reader)
		{
			byte crewID = reader.ReadByte();
			return new DisbandCrewPacket
			{
				CrewID = crewID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(CrewID);
		}
	}
	public class ForceMatchLeavePacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)38718);

		public required string Message { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ForceMatchLeavePacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Message has a length of {num} exceeding the max 255");
			}
			string message = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			return new ForceMatchLeavePacket
			{
				Message = message
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(Message);
			writer.Write(bytes.Length);
			writer.Write(bytes);
		}
	}
	public class GameOverPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)51365);

		public RaceGameResults? RaceResults { get; init; }

		public KnockoutGameResults? KnockoutResults { get; init; }

		public byte BingoWinningCrew { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static GameOverPacket AthenaReadFrom(BinaryReader reader)
		{
			bool num = reader.ReadBoolean();
			RaceGameResults raceResults = null;
			if (num)
			{
				raceResults = RaceGameResults.AthenaReadFrom(reader);
			}
			bool num2 = reader.ReadBoolean();
			KnockoutGameResults knockoutResults = null;
			if (num2)
			{
				knockoutResults = KnockoutGameResults.AthenaReadFrom(reader);
			}
			byte bingoWinningCrew = reader.ReadByte();
			return new GameOverPacket
			{
				RaceResults = raceResults,
				KnockoutResults = knockoutResults,
				BingoWinningCrew = bingoWinningCrew
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(RaceResults != null);
			if (RaceResults != null)
			{
				RaceResults.AthenaWriteTo(writer);
			}
			writer.Write(KnockoutResults != null);
			if (KnockoutResults != null)
			{
				KnockoutResults.AthenaWriteTo(writer);
			}
			writer.Write(BingoWinningCrew);
		}
	}
	public class GenerateDataRequestPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)21100);

		public required int Seed { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static GenerateDataRequestPacket AthenaReadFrom(BinaryReader reader)
		{
			int seed = reader.ReadInt32();
			return new GenerateDataRequestPacket
			{
				Seed = seed
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Seed);
		}
	}
	public class JoinGameLobbyPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)4590);

		public ulong LobbyID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static JoinGameLobbyPacket AthenaReadFrom(BinaryReader reader)
		{
			ulong lobbyID = reader.ReadUInt64();
			return new JoinGameLobbyPacket
			{
				LobbyID = lobbyID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(LobbyID);
		}
	}
	public class JoinTimeoutPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)19189);

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static JoinTimeoutPacket AthenaReadFrom(BinaryReader reader)
		{
			return new JoinTimeoutPacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class KickPlayerPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)19617);

		public required Guid UUID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static KickPlayerPacket AthenaReadFrom(BinaryReader reader)
		{
			Guid uUID = new Guid(reader.ReadBytes(16));
			return new KickPlayerPacket
			{
				UUID = uUID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(UUID.ToByteArray());
		}
	}
	public class KnockoutCrewLivesChangedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)40083);

		public required byte CrewID { get; init; }

		public required int NewLives { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static KnockoutCrewLivesChangedPacket AthenaReadFrom(BinaryReader reader)
		{
			byte crewID = reader.ReadByte();
			int newLives = reader.ReadInt32();
			return new KnockoutCrewLivesChangedPacket
			{
				CrewID = crewID,
				NewLives = newLives
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(CrewID);
			writer.Write(NewLives);
		}
	}
	public class KnockoutLeaderboardPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)52036);

		public required KnockoutLeaderboard Leaderboard { get; init; }

		public required int SafePlacement { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static KnockoutLeaderboardPacket AthenaReadFrom(BinaryReader reader)
		{
			KnockoutLeaderboard leaderboard = KnockoutLeaderboard.AthenaReadFrom(reader);
			int safePlacement = reader.ReadInt32();
			return new KnockoutLeaderboardPacket
			{
				Leaderboard = leaderboard,
				SafePlacement = safePlacement
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Leaderboard.AthenaWriteTo(writer);
			writer.Write(SafePlacement);
		}
	}
	public class KnockoutNewCrewsCompletedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)26018);

		public required int Completed { get; init; }

		public required int Alive { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static KnockoutNewCrewsCompletedPacket AthenaReadFrom(BinaryReader reader)
		{
			int completed = reader.ReadInt32();
			int alive = reader.ReadInt32();
			return new KnockoutNewCrewsCompletedPacket
			{
				Completed = completed,
				Alive = alive
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Completed);
			writer.Write(Alive);
		}
	}
	public class KnockoutNewQuotaPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)45127);

		public QuotaInfo Quota { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static KnockoutNewQuotaPacket AthenaReadFrom(BinaryReader reader)
		{
			QuotaInfo quota = QuotaInfo.AthenaReadFrom(reader);
			return new KnockoutNewQuotaPacket
			{
				Quota = quota
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Quota.AthenaWriteTo(writer);
		}
	}
	public class ManualEjectPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)11224);

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ManualEjectPacket AthenaReadFrom(BinaryReader reader)
		{
			return new ManualEjectPacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class NewCrewCaptainPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)57975);

		public byte CrewID { get; init; }

		public Guid UUID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static NewCrewCaptainPacket AthenaReadFrom(BinaryReader reader)
		{
			byte crewID = reader.ReadByte();
			Guid uUID = new Guid(reader.ReadBytes(16));
			return new NewCrewCaptainPacket
			{
				CrewID = crewID,
				UUID = uUID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(CrewID);
			writer.Write(UUID.ToByteArray());
		}
	}
	public class NewGameSettingsPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)34211);

		public required GameSettingsType Type { get; init; }

		public byte[] Data { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static NewGameSettingsPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0006: 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)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			GameSettingsType type = (GameSettingsType)reader.ReadByte();
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"Data has a length of {num} exceeding the max 255");
			}
			byte[] array = new byte[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = reader.ReadByte();
			}
			return new NewGameSettingsPacket
			{
				Type = type,
				Data = array
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			writer.Write((byte)(int)Type);
			writer.Write(Data.Length);
			byte[] data = Data;
			foreach (byte value in data)
			{
				writer.Write(value);
			}
		}
	}
	public class NewMatchHostPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)31614);

		public Guid UUID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static NewMatchHostPacket AthenaReadFrom(BinaryReader reader)
		{
			Guid uUID = new Guid(reader.ReadBytes(16));
			return new NewMatchHostPacket
			{
				UUID = uUID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(UUID.ToByteArray());
		}
	}
	public class NextDayInfoPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)6935);

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static NextDayInfoPacket AthenaReadFrom(BinaryReader reader)
		{
			return new NextDayInfoPacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class PlayerJoinedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)15260);

		public UserInfo UserInfo { get; init; }

		public byte CrewID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static PlayerJoinedPacket AthenaReadFrom(BinaryReader reader)
		{
			UserInfo userInfo = UserInfo.AthenaReadFrom(reader);
			byte crewID = reader.ReadByte();
			return new PlayerJoinedPacket
			{
				UserInfo = userInfo,
				CrewID = crewID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			UserInfo.AthenaWriteTo(writer);
			writer.Write(CrewID);
		}
	}
	public class PlayerMovedCrewPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)63521);

		public Guid UUID { get; init; }

		public byte CrewID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static PlayerMovedCrewPacket AthenaReadFrom(BinaryReader reader)
		{
			Guid uUID = new Guid(reader.ReadBytes(16));
			byte crewID = reader.ReadByte();
			return new PlayerMovedCrewPacket
			{
				UUID = uUID,
				CrewID = crewID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(UUID.ToByteArray());
			writer.Write(CrewID);
		}
	}
	public class QuotaCompletedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)56114);

		public required QuotaResults Results { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static QuotaCompletedPacket AthenaReadFrom(BinaryReader reader)
		{
			QuotaResults results = QuotaResults.AthenaReadFrom(reader);
			return new QuotaCompletedPacket
			{
				Results = results
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Results.AthenaWriteTo(writer);
		}
	}
	public class RaceCheckpointCompletedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)904);

		public required RaceCheckpointType Type { get; init; }

		public required byte CrewID { get; init; }

		public int Quota { get; set; }

		public int Day { get; set; }

		public int Placement { get; set; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static RaceCheckpointCompletedPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0006: 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)
			RaceCheckpointType type = (RaceCheckpointType)reader.ReadByte();
			byte crewID = reader.ReadByte();
			int quota = reader.ReadInt32();
			int day = reader.ReadInt32();
			int placement = reader.ReadInt32();
			return new RaceCheckpointCompletedPacket
			{
				Type = type,
				CrewID = crewID,
				Quota = quota,
				Day = day,
				Placement = placement
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			writer.Write((byte)(int)Type);
			writer.Write(CrewID);
			writer.Write(Quota);
			writer.Write(Day);
			writer.Write(Placement);
		}
	}
	public class RaceGameDataPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)64736);

		public required RaceGameData GameData { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static RaceGameDataPacket AthenaReadFrom(BinaryReader reader)
		{
			RaceGameData gameData = RaceGameData.AthenaReadFrom(reader);
			return new RaceGameDataPacket
			{
				GameData = gameData
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			GameData.AthenaWriteTo(writer);
		}
	}
	public class RenameMatchPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)31567);

		public string NewName { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static RenameMatchPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"NewName has a length of {num} exceeding the max 255");
			}
			string newName = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			return new RenameMatchPacket
			{
				NewName = newName
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(NewName);
			writer.Write(bytes.Length);
			writer.Write(bytes);
		}
	}
	public class SetupCountdownPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)27336);

		public required int Seconds { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static SetupCountdownPacket AthenaReadFrom(BinaryReader reader)
		{
			int seconds = reader.ReadInt32();
			return new SetupCountdownPacket
			{
				Seconds = seconds
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(Seconds);
		}
	}
	public class StartDayPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)47637);

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static StartDayPacket AthenaReadFrom(BinaryReader reader)
		{
			return new StartDayPacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class StartGamePacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)2604);

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static StartGamePacket AthenaReadFrom(BinaryReader reader)
		{
			return new StartGamePacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class UpdateSeedPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)50772);

		public required int NewSeed { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static UpdateSeedPacket AthenaReadFrom(BinaryReader reader)
		{
			int newSeed = reader.ReadInt32();
			return new UpdateSeedPacket
			{
				NewSeed = newSeed
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(NewSeed);
		}
	}
}
namespace Diomedes.Shared.Packets
{
	public class ACVPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)18932);

		public required byte VID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ACVPacket AthenaReadFrom(BinaryReader reader)
		{
			byte vID = reader.ReadByte();
			return new ACVPacket
			{
				VID = vID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(VID);
		}
	}
	public class ApplyRestrictionsPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)44346);

		public required ClientRestrictions Restrictions { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ApplyRestrictionsPacket AthenaReadFrom(BinaryReader reader)
		{
			ClientRestrictions restrictions = ClientRestrictions.AthenaReadFrom(reader);
			return new ApplyRestrictionsPacket
			{
				Restrictions = restrictions
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			Restrictions.AthenaWriteTo(writer);
		}
	}
	public class CompetitiveModListPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)23812);

		public required string[] ModGUIDS { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static CompetitiveModListPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: 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)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"ModGUIDS has a length of {num} exceeding the max 255");
			}
			string[] array = new string[num];
			for (int i = 0; i < num; i++)
			{
				int num2 = reader.ReadInt32();
				if (num2 >= 256)
				{
					throw new AthenaSerializationException($"element[ModGUIDSRank0] in array ModGUIDS has a length of {num2} exceeding the max 255");
				}
				array[i] = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num2)));
			}
			return new CompetitiveModListPacket
			{
				ModGUIDS = array
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(ModGUIDS.Length);
			string[] modGUIDS = ModGUIDS;
			foreach (string s in modGUIDS)
			{
				byte[] bytes = Encoding.Unicode.GetBytes(s);
				writer.Write(bytes.Length);
				writer.Write(bytes);
			}
		}
	}
	public class CreatePrivateLobbyPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)45761);

		public required GameModeType GameMode { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static CreatePrivateLobbyPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0006: 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)
			GameModeType gameMode = (GameModeType)reader.ReadByte();
			return new CreatePrivateLobbyPacket
			{
				GameMode = gameMode
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			writer.Write((byte)(int)GameMode);
		}
	}
	public class JoinDailyRacePacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)26198);

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static JoinDailyRacePacket AthenaReadFrom(BinaryReader reader)
		{
			return new JoinDailyRacePacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public interface ILoginPacket
	{
		ulong SteamID { get; }

		int GameVersion { get; }
	}
	public class LoginDiscordPacket : AthenaPacket, ILoginPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)39250);

		public required string AuthCode { get; init; }

		public ulong SteamID { get; init; }

		public int GameVersion { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static LoginDiscordPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"AuthCode has a length of {num} exceeding the max 255");
			}
			string authCode = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			ulong steamID = reader.ReadUInt64();
			int gameVersion = reader.ReadInt32();
			return new LoginDiscordPacket
			{
				AuthCode = authCode,
				SteamID = steamID,
				GameVersion = gameVersion
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(AuthCode);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			writer.Write(SteamID);
			writer.Write(GameVersion);
		}
	}
	public class LoginGuestPacket : AthenaPacket, ILoginPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)48033);

		public required string PreferredUsername { get; init; }

		public ulong SteamID { get; init; }

		public int GameVersion { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static LoginGuestPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"PreferredUsername has a length of {num} exceeding the max 255");
			}
			string preferredUsername = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			ulong steamID = reader.ReadUInt64();
			int gameVersion = reader.ReadInt32();
			return new LoginGuestPacket
			{
				PreferredUsername = preferredUsername,
				SteamID = steamID,
				GameVersion = gameVersion
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(PreferredUsername);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			writer.Write(SteamID);
			writer.Write(GameVersion);
		}
	}
	public class LoginSessionPacket : AthenaPacket, ILoginPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)41558);

		public required string SessionToken { get; init; }

		public ulong SteamID { get; init; }

		public int GameVersion { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static LoginSessionPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"SessionToken has a length of {num} exceeding the max 255");
			}
			string sessionToken = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			ulong steamID = reader.ReadUInt64();
			int gameVersion = reader.ReadInt32();
			return new LoginSessionPacket
			{
				SessionToken = sessionToken,
				SteamID = steamID,
				GameVersion = gameVersion
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			byte[] bytes = Encoding.Unicode.GetBytes(SessionToken);
			writer.Write(bytes.Length);
			writer.Write(bytes);
			writer.Write(SteamID);
			writer.Write(GameVersion);
		}
	}
	public class LoginSuccessPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)10418);

		public required UserInfo UserInfo { get; init; }

		public required string SessionToken { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static LoginSuccessPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			UserInfo userInfo = UserInfo.AthenaReadFrom(reader);
			int num = reader.ReadInt32();
			if (num >= 256)
			{
				throw new AthenaSerializationException($"SessionToken has a length of {num} exceeding the max 255");
			}
			string sessionToken = new string(Encoding.Unicode.GetChars(reader.ReadBytes(num)));
			return new LoginSuccessPacket
			{
				UserInfo = userInfo,
				SessionToken = sessionToken
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			UserInfo.AthenaWriteTo(writer);
			byte[] bytes = Encoding.Unicode.GetBytes(SessionToken);
			writer.Write(bytes.Length);
			writer.Write(bytes);
		}
	}
	public class LoginFailPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)6336);

		public LoginFailReason Reason { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static LoginFailPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0006: 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)
			LoginFailReason reason = (LoginFailReason)reader.ReadByte();
			return new LoginFailPacket
			{
				Reason = reason
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			writer.Write((byte)(int)Reason);
		}
	}
	public class MatchJoinSuccessPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)57345);

		public required MatchInfo MatchInfo { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static MatchJoinSuccessPacket AthenaReadFrom(BinaryReader reader)
		{
			MatchInfo matchInfo = MatchInfo.AthenaReadFrom(reader);
			return new MatchJoinSuccessPacket
			{
				MatchInfo = matchInfo
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			MatchInfo.AthenaWriteTo(writer);
		}
	}
	public class MatchJoinFailPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)5339);

		public required LobbyJoinFailReason Reason { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static MatchJoinFailPacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0006: 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)
			LobbyJoinFailReason reason = (LobbyJoinFailReason)reader.ReadByte();
			return new MatchJoinFailPacket
			{
				Reason = reason
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			writer.Write((byte)(int)Reason);
		}
	}
	public class MatchLeavePacket : AthenaPacket
	{
		public static readonly MatchLeavePacket Instance = new MatchLeavePacket();

		public static readonly PacketID ID = new PacketID((ushort)10212);

		private MatchLeavePacket()
		{
		}

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static MatchLeavePacket AthenaReadFrom(BinaryReader reader)
		{
			return new MatchLeavePacket();
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
		}
	}
	public class NewCrewPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)46465);

		public CrewInfo CrewInfo { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static NewCrewPacket AthenaReadFrom(BinaryReader reader)
		{
			CrewInfo crewInfo = CrewInfo.AthenaReadFrom(reader);
			return new NewCrewPacket
			{
				CrewInfo = crewInfo
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			CrewInfo.AthenaWriteTo(writer);
		}
	}
	public class PlayerLeftPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)12450);

		public Guid UUID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static PlayerLeftPacket AthenaReadFrom(BinaryReader reader)
		{
			Guid uUID = new Guid(reader.ReadBytes(16));
			return new PlayerLeftPacket
			{
				UUID = uUID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(UUID.ToByteArray());
		}
	}
	public class RequestMatchJoinPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)4004);

		public required int MatchID { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static RequestMatchJoinPacket AthenaReadFrom(BinaryReader reader)
		{
			int matchID = reader.ReadInt32();
			return new RequestMatchJoinPacket
			{
				MatchID = matchID
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			writer.Write(MatchID);
		}
	}
	public class ServerInfoPacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)2525);

		public ServerInfo ServerInfo { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static ServerInfoPacket AthenaReadFrom(BinaryReader reader)
		{
			ServerInfo serverInfo = ServerInfo.AthenaReadFrom(reader);
			return new ServerInfoPacket
			{
				ServerInfo = serverInfo
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			ServerInfo.AthenaWriteTo(writer);
		}
	}
	public class UpdateMatchStatePacket : AthenaPacket
	{
		public static readonly PacketID ID = new PacketID((ushort)32162);

		public MatchState NewState { get; init; }

		public override void Send(INetworkConnection conn)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = conn.RentBuffer();
			using MemoryStream memoryStream = new MemoryStream(array);
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
			BinaryWriterExtensions.Write(binaryWriter, ID);
			AthenaWriteTo(binaryWriter);
			conn.SendBuffer(array, (int)memoryStream.Position);
		}

		public static UpdateMatchStatePacket AthenaReadFrom(BinaryReader reader)
		{
			//IL_0006: 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)
			MatchState newState = (MatchState)reader.ReadByte();
			return new UpdateMatchStatePacket
			{
				NewState = newState
			};
		}

		public void AthenaWriteTo(BinaryWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			writer.Write((byte)(int)NewState);
		}
	}
}

BepInEx/core/Diomedes/Athena.WebSockets.dll

Decompiled 16 hours ago
using System;
using System.Buffers;
using System.Diagnostics;
using System.IO;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Athena.WebSockets")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("WebSocket transport for Athena and easy client connection code")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0-pre1+bd2380b7e853477e3b2a895242384dc115ea08bf")]
[assembly: AssemblyProduct("Athena.WebSockets")]
[assembly: AssemblyTitle("Athena.WebSockets")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Athena.WebSockets
{
	public static class AthenaWebSocketClient
	{
		[Obsolete("AthenaNetworkConnection should be instiated manually for more control over logging")]
		public static async Task<AthenaNetworkConnection> ConnectAsync(Uri uri, CancellationToken token = default(CancellationToken))
		{
			AthenaNetworkConnection val = new AthenaNetworkConnection((INetworkTransport)(object)(await ConnectTransportAsync(uri, token)));
			val.RunAsync().ConfigureAwait(continueOnCapturedContext: false);
			return val;
		}

		public static async Task<AthenaWebSocketTransport> ConnectTransportAsync(Uri uri, CancellationToken token = default(CancellationToken))
		{
			ClientWebSocket client = new ClientWebSocket();
			await client.ConnectAsync(uri, token);
			return new AthenaWebSocketTransport(client);
		}
	}
	public sealed class AthenaWebSocketTransport(WebSocket socket) : INetworkTransport, IAsyncDisposable
	{
		private const int MaxPacketSize = 4096;

		private readonly WebSocket _socket = socket;

		private readonly ArrayPool<byte> _pool = ArrayPool<byte>.Shared;

		int INetworkTransport.MaxPacketSize => 4096;

		public event Action OnDisconnect = delegate
		{
		};

		public ValueTask DisposeAsync()
		{
			socket.Dispose();
			return default(ValueTask);
		}

		public async Task<ReadOnlyMemory<byte>> RecvAsync(CancellationToken token = default(CancellationToken))
		{
			byte[] buffer = _pool.Rent(4096);
			try
			{
				using MemoryStream message = new MemoryStream();
				WebSocketReceiveResult webSocketReceiveResult;
				do
				{
					webSocketReceiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), token).ConfigureAwait(continueOnCapturedContext: false);
					if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close)
					{
						this.OnDisconnect();
						throw new EndOfStreamException();
					}
					if (webSocketReceiveResult.MessageType != WebSocketMessageType.Binary)
					{
						throw new InvalidOperationException("Non-Binary websocket messages are not supported, are we connected to a non-athena host?");
					}
					message.Write(buffer, 0, webSocketReceiveResult.Count);
				}
				while (!webSocketReceiveResult.EndOfMessage);
				return message.ToArray();
			}
			catch (Exception innerException)
			{
				this.OnDisconnect();
				throw new Exception("An exception occured in the websocket transport when receiving", innerException);
			}
			finally
			{
				_pool.Return(buffer);
			}
		}

		public async Task SendAsync(ReadOnlyMemory<byte> data, CancellationToken token = default(CancellationToken))
		{
			await socket.SendAsync(data, WebSocketMessageType.Binary, endOfMessage: true, token);
		}
	}
}

BepInEx/core/Diomedes/Athena.dll

Decompiled 16 hours ago
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Athena")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Easy, efficient, typesafe C# networking")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0-pre1+bd2380b7e853477e3b2a895242384dc115ea08bf")]
[assembly: AssemblyProduct("Athena")]
[assembly: AssemblyTitle("Athena")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	public sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	public sealed class IsExternalInit : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	public sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public CompilerFeatureRequiredAttribute(string FeatureName)
		{
		}
	}
}
namespace Athena
{
	public sealed class AthenaNetworkConnection : INetworkConnection, IAsyncDisposable
	{
		private readonly INetworkTransport _transport;

		private readonly ArrayPool<byte> _pool = ArrayPool<byte>.Shared;

		private readonly ConcurrentQueue<QueuedPacket> _sendQueue = new ConcurrentQueue<QueuedPacket>();

		private readonly SemaphoreSlim _sendSignal = new SemaphoreSlim(0, 1);

		private readonly CancellationTokenSource _cts = new CancellationTokenSource();

		private readonly Dictionary<PacketID, PacketHandlerDelegate> _handlers = new Dictionary<PacketID, PacketHandlerDelegate>();

		public IUnknownPacketLogger UnknownPacketLogger { get; init; } = NoOpUnknownPacketLogger.Instance;

		private event Action<INetworkConnection> _onDisconnect = delegate
		{
		};

		public event Action OnDisconnect = delegate
		{
		};

		public event Action<Exception> OnException = delegate
		{
		};

		public AthenaNetworkConnection(INetworkTransport transport)
		{
			_transport = transport;
			_transport.OnDisconnect += delegate
			{
				this._onDisconnect(this);
				this.OnDisconnect();
			};
		}

		public Task RunAsync()
		{
			Task task = SendLoopAsync(_cts.Token);
			Task task2 = ReceiveLoopAsync(_cts.Token);
			return Task.WhenAny(new Task[2] { task, task2 });
		}

		private async Task SendLoopAsync(CancellationToken token)
		{
			while (!token.IsCancellationRequested)
			{
				await _sendSignal.WaitAsync(token);
				QueuedPacket queued;
				while (_sendQueue.TryDequeue(out queued))
				{
					try
					{
						await _transport.SendAsync(queued.Buffer.AsMemory(0, queued.Size), token);
					}
					finally
					{
						_pool.Return(queued.Buffer);
					}
				}
			}
		}

		private async Task ReceiveLoopAsync(CancellationToken token)
		{
			while (!token.IsCancellationRequested)
			{
				using MemoryStream stream = new MemoryStream((await _transport.RecvAsync(token)).ToArray());
				using BinaryReader reader = new BinaryReader(stream);
				PacketID packetID = reader.ReadPacketID();
				if (_handlers.TryGetValue(packetID, out PacketHandlerDelegate value))
				{
					try
					{
						await value(reader, this);
					}
					catch (Exception obj)
					{
						this.OnException(obj);
					}
				}
				else
				{
					UnknownPacketLogger.Log(packetID);
				}
			}
		}

		public byte[] RentBuffer()
		{
			return _pool.Rent(_transport.MaxPacketSize);
		}

		public void SendBuffer(byte[] buffer, int size)
		{
			_sendQueue.Enqueue(new QueuedPacket(buffer, size));
			if (_sendSignal.CurrentCount == 0)
			{
				_sendSignal.Release();
			}
		}

		public void Register(PacketRegister register)
		{
			foreach (var (key, value) in register.handlers)
			{
				_handlers.Add(key, value);
			}
			foreach (Action<INetworkConnection> disconnectCallback in register.disconnectCallbacks)
			{
				_onDisconnect += disconnectCallback;
			}
		}

		public void Unregister(PacketRegister register)
		{
			foreach (PacketID key in register.handlers.Keys)
			{
				_handlers.Remove(key);
			}
			foreach (Action<INetworkConnection> disconnectCallback in register.disconnectCallbacks)
			{
				_onDisconnect -= disconnectCallback;
			}
		}

		public ValueTask DisposeAsync()
		{
			_cts.Cancel();
			_sendSignal.Dispose();
			return _transport.DisposeAsync();
		}
	}
	public interface INetworkConnection : IAsyncDisposable
	{
		event Action OnDisconnect;

		event Action<Exception> OnException;

		byte[] RentBuffer();

		void SendBuffer(byte[] buffer, int size);

		void Register(PacketRegister register);

		void Unregister(PacketRegister register);
	}
	public interface IUnknownPacketLogger
	{
		void Log(PacketID ID);
	}
	public class NoOpUnknownPacketLogger : IUnknownPacketLogger
	{
		public static NoOpUnknownPacketLogger Instance { get; } = new NoOpUnknownPacketLogger();

		public void Log(PacketID ID)
		{
		}

		private NoOpUnknownPacketLogger()
		{
		}
	}
	public delegate Task PacketHandlerDelegate(BinaryReader reader, INetworkConnection conn);
	public sealed class PacketRegister
	{
		internal List<Action<INetworkConnection>> disconnectCallbacks = new List<Action<INetworkConnection>>();

		internal Dictionary<PacketID, PacketHandlerDelegate> handlers = new Dictionary<PacketID, PacketHandlerDelegate>();

		public PacketRegister RegisterPacket(PacketID packetID, PacketHandlerDelegate callback)
		{
			handlers[packetID] = callback;
			return this;
		}

		public PacketRegister OnDisconnect(Action<INetworkConnection> callback)
		{
			disconnectCallbacks.Add(callback);
			return this;
		}
	}
	public record struct QueuedPacket(byte[] Buffer, int Size);
	internal static class BinaryReaderExtensions
	{
		internal static PacketID ReadPacketID(this BinaryReader reader)
		{
			return new PacketID(reader.ReadUInt16());
		}
	}
	public static class BinaryWriterExtensions
	{
		public static void Write(this BinaryWriter writer, PacketID packet)
		{
			writer.Write(packet.ID);
		}
	}
	public abstract class AthenaPacket
	{
		public abstract void Send(INetworkConnection conn);

		public void Broadcast(IEnumerable<INetworkConnection> connections)
		{
			foreach (INetworkConnection connection in connections)
			{
				Send(connection);
			}
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public sealed class AthenaPacketHandlerAttribute : Attribute
	{
	}
	public interface IPacketHandler
	{
	}
	public record struct PacketID(ushort ID);
	public class AthenaSerializationException : Exception
	{
		public AthenaSerializationException(string message)
			: base(message)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
	public sealed class PacketSerializableAttribute : Attribute
	{
	}
	public interface INetworkTransport : IAsyncDisposable
	{
		int MaxPacketSize { get; }

		event Action OnDisconnect;

		Task SendAsync(ReadOnlyMemory<byte> data, CancellationToken token = default(CancellationToken));

		Task<ReadOnlyMemory<byte>> RecvAsync(CancellationToken token = default(CancellationToken));
	}
}

BepInEx/core/Diomedes/Diomedes.API.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Diomedes.API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Diomedes API domain objects, use Diomedes.API.Client for the official client")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+6c90293b56f5942afde130c84e9a147852dc0d08")]
[assembly: AssemblyProduct("Diomedes.API")]
[assembly: AssemblyTitle("Diomedes.API")]
[assembly: AssemblyVersion("2.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Diomedes.API
{
	public sealed record Incident(DateTime Created, DateTime LastUpdated, bool Active, Dictionary<string, Content> Contents)
	{
		public sealed record Content(string Title, string ShortDesc, string? Description);
	}
	public sealed record DailyRaceChallenge(string Name, DateTime Date, DateTime Expires, int TotalClears, List<QuotaInfo> Quotas);
	public sealed record DailyRaceClear(DateTime Date, int MatchID, int Rank, TimeSpan ClearTime, Crew Crew);
	public sealed record DailyRaceLeaderboard(DateTime Date, int CrewSize, List<DailyRaceClear> Entries);
	public static class DiomedesAPI
	{
		public static readonly JsonSerializerOptions JSONSettings = new JsonSerializerOptions
		{
			PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
			Converters = 
			{
				(JsonConverter)new CrewIDConverter(),
				(JsonConverter)new DiomedesKeyConverter(),
				(JsonConverter)new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
			}
		};
	}
	public sealed record DiomedesKey(string Namespace, string Key)
	{
		public override string ToString()
		{
			return Namespace + ":" + Key;
		}

		public bool IsVanilla()
		{
			return Namespace == "lethal_company";
		}

		public bool IsDiomedes()
		{
			return Namespace == "diomedes";
		}

		public static DiomedesKey Parse(string input)
		{
			string[] array = input.Split(":");
			if (array.Length == 1)
			{
				return new DiomedesKey("lethal_company", array[0]);
			}
			return new DiomedesKey(array[0], array[1]);
		}
	}
	public sealed class DiomedesKeyConverter : JsonConverter<DiomedesKey>
	{
		public override DiomedesKey? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			string text = reader.GetString();
			if (text == null)
			{
				return null;
			}
			return DiomedesKey.Parse(text);
		}

		public override void Write(Utf8JsonWriter writer, DiomedesKey value, JsonSerializerOptions options)
		{
			writer.WriteStringValue(value.ToString());
		}
	}
	public sealed record BingoGameData(BingoBoard Board, CrewID? WinningCrew) : IGameModeData;
	public sealed record BingoBoard(BingoSquare[,] Squares);
	public sealed record BingoSquare(DiomedesKey ChallengeKey);
	public sealed record BingoChallengeCompleted(DateTime Timestamp, CrewID CrewID, DiomedesKey ChallengeKey) : IGameEvent;
	public record struct CrewID(byte Value);
	public record Crew(CrewID CrewID, string Name, SimpleUser Captain, List<SimpleUser> Players);
	public class CrewIDConverter : JsonConverter<CrewID>
	{
		public override CrewID Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			return new CrewID(reader.GetByte());
		}

		public override void Write(Utf8JsonWriter writer, CrewID value, JsonSerializerOptions options)
		{
			writer.WriteNumberValue(value.Value);
		}
	}
	public sealed record KnockoutGameData(List<QuotaInfo> Quotas, CrewID? WinningCrew) : IGameModeData;
	public sealed record KnockoutLeaderboardEntry(CrewID CrweID, int SoldAmount, bool LostLife);
	public sealed record KOStartDay(DateTime Timestamp, int Quota, int Day) : IGameEvent;
	public sealed record KOLeaderboard(DateTime Timestamp, int SafePlacement, List<KnockoutLeaderboardEntry> Entries) : IGameEvent;
	public sealed record KOQuotaGenerated(DateTime Timestamp, QuotaInfo Quota) : IGameEvent;
	public enum MatchType
	{
		Private,
		DailyRace,
		KnockoutCup,
		Ranked
	}
	public sealed record Match(int ID, MatchType MatchType, List<Crew> Crews, IGameModeData GameData, List<IGameEvent> Events);
	[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
	[JsonDerivedType(typeof(RaceGameData), "race")]
	[JsonDerivedType(typeof(KnockoutGameData), "knockout")]
	[JsonDerivedType(typeof(BingoGameData), "bingo")]
	public interface IGameModeData
	{
	}
	[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
	[JsonDerivedType(typeof(KOStartDay), "knockout:start_day")]
	[JsonDerivedType(typeof(KOLeaderboard), "knockout:leaderboard")]
	[JsonDerivedType(typeof(KOQuotaGenerated), "knockout:quota_generated")]
	[JsonDerivedType(typeof(RaceQuotaCompleted), "race:quota_completed")]
	[JsonDerivedType(typeof(DayCompleted), "day_completed")]
	[JsonDerivedType(typeof(RaceCompleted), "race:completed")]
	[JsonDerivedType(typeof(RaceQuotaReset), "race:quota_reset")]
	[JsonDerivedType(typeof(BingoChallengeCompleted), "bingo:challenge_completed")]
	public interface IGameEvent
	{
		DateTime Timestamp { get; }
	}
	public sealed record DayInfo(DiomedesKey MoonKey, DiomedesKey? WeatherKey, int Seed);
	public sealed record QuotaInfo(List<DayInfo> Days);
	public sealed record DayResults(int Quota, int Day, int ScrapBottomLine, int CollectedScrap, List<PlayerResults> Players, Flags Extra)
	{
		[Flags]
		public enum Flags
		{
			None = 1,
			Apparatus = 2
		}
	}
	public sealed record PlayerResults(Guid UserID, bool Lived);
	public sealed record RaceQuotaCompleted(DateTime Timestamp, CrewID CrewID, int Quota) : IGameEvent;
	public sealed record DayCompleted(DateTime Timestamp, CrewID CrewID, DayResults Results) : IGameEvent;
	public sealed record RaceCompleted(DateTime Timestamp, CrewID CrewID) : IGameEvent;
	public sealed record RaceQuotaReset(DateTime Timestamp, CrewID CrewID, int Quota, bool WasManualEject) : IGameEvent;
	public sealed record RaceGameData(List<QuotaInfo> Quotas) : IGameModeData;
	public sealed record ServerInfo(string DiomedesVersion, int TotalOnlinePlayers, int ActiveMatches);
	public record AdvancedUser(Guid UUID, string Username, string DiscordID, Times Dates)
	{
		public record Times(DateTime CreationDate, DateTime LastLoginDate);
	}
	public record SimpleUser(Guid UUID, string Username, string DiscordID);
	public sealed record UserDailyRaceStats(Guid UUID, List<DailyRaceClear> Clears)
	{
		private (int CurrentStreak, int BestStreak) GetStreaks()
		{
			int num = 0;
			int num2 = 0;
			List<DateTime> list = (from it in Clears.Select((DailyRaceClear it) => it.Date).Distinct()
				orderby it
				select it).ToList();
			for (int num3 = 0; num3 < list.Count; num3++)
			{
				num2 = ((num3 == 0 || list[num3] == list[num3 - 1].AddDays(1.0)) ? (num2 + 1) : 0);
				num = Math.Max(num2, num);
			}
			return (CurrentStreak: num, BestStreak: num2);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	internal static class IsExternalInit
	{
	}
}

BepInEx/core/Diomedes/Diomedes.API.Client.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Diomedes.API.Client")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Official C# Diomedes API")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+6c90293b56f5942afde130c84e9a147852dc0d08")]
[assembly: AssemblyProduct("Diomedes.API.Client")]
[assembly: AssemblyTitle("Diomedes.API.Client")]
[assembly: AssemblyVersion("2.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Diomedes.API.Client
{
	public sealed record APIErrorResponse(string Message, Dictionary<string, List<string>> Errors);
	public sealed class DiomedesAPIClient : IDiomedesAPIClient
	{
		private HttpClient? _client;

		public Uri BaseURL { get; init; } = new Uri("https://api.diomedeslc.com");

		private async Task<T?> GetAsync<T>(string requestUri, CancellationToken? token = null)
		{
			if (_client == null)
			{
				_client = new HttpClient
				{
					BaseAddress = BaseURL
				};
			}
			HttpResponseMessage response = await _client.GetAsync(requestUri, token ?? CancellationToken.None);
			string json = await response.Content.ReadAsStringAsync();
			if (response.StatusCode == HttpStatusCode.NotFound)
			{
				return default(T);
			}
			if (!response.IsSuccessStatusCode)
			{
				APIErrorResponse? aPIErrorResponse = JsonSerializer.Deserialize<APIErrorResponse>(json, DiomedesAPI.JSONSettings);
				StringBuilder stringBuilder = new StringBuilder(aPIErrorResponse.Message);
				foreach (string item in aPIErrorResponse.Errors.Values.SelectMany((List<string> it) => it))
				{
					stringBuilder.AppendLine(" - " + item);
				}
				throw new DiomedesAPIException(stringBuilder.ToString());
			}
			return JsonSerializer.Deserialize<T>(json, DiomedesAPI.JSONSettings);
		}

		private async Task<T> GetNotNullAsync<T>(string requestUri, CancellationToken? token = null)
		{
			return (await GetAsync<T>(requestUri, token)) ?? throw new DiomedesAPIException("Did not recieve a response from the API");
		}

		public Task<ServerInfo> GetServerInfoAsync(CancellationToken? token = null)
		{
			return GetNotNullAsync<ServerInfo>("/v2/server_info", token);
		}

		public async Task<AdvancedUser?> GetUserAsync(IUserLookup lookup, CancellationToken? token = null)
		{
			return await GetAsync<AdvancedUser>("/v2/user/" + lookup.AsString(), token);
		}

		public Task<Match?> GetMatchAsync(int MatchID, CancellationToken? token = null)
		{
			return GetAsync<Match>($"/v2/match/{MatchID}", token);
		}

		public Task<DailyRaceChallenge?> GetDailyRaceChallengeAsync(DateTime? date = null, CancellationToken? token = null)
		{
			DateTime valueOrDefault = date.GetValueOrDefault();
			if (!date.HasValue)
			{
				valueOrDefault = DateTime.UtcNow;
				date = valueOrDefault;
			}
			return GetAsync<DailyRaceChallenge>($"/v2/daily_race/{date.Value.Date:yyyy-MM-dd}", token);
		}

		public Task<DailyRaceLeaderboard?> GetDailyRaceLeaderboardAsync(int crewSize, DateTime? date = null, CancellationToken? token = null)
		{
			DateTime valueOrDefault = date.GetValueOrDefault();
			if (!date.HasValue)
			{
				valueOrDefault = DateTime.UtcNow;
				date = valueOrDefault;
			}
			return GetAsync<DailyRaceLeaderboard>($"/v2/daily_race/{date.Value.Date:yyyy-MM-dd}/leaderboard?crewSize={crewSize}", token);
		}

		public async Task<IEnumerable<Incident>> GetIncidentsAsync(CancellationToken? token = null)
		{
			return await GetNotNullAsync<List<Incident>>("/v2/incidents", token);
		}

		public Task<UserDailyRaceStats?> GetUserDailyStatsAsync(IUserLookup lookup, CancellationToken? token = null)
		{
			return GetAsync<UserDailyRaceStats>("/v2/user/" + lookup.AsString() + "/daily", token);
		}
	}
	public class DiomedesAPIException : Exception
	{
		internal DiomedesAPIException(string message)
			: base(message)
		{
		}
	}
	public interface IDiomedesAPIClient
	{
		Task<ServerInfo> GetServerInfoAsync(CancellationToken? token = null);

		Task<AdvancedUser?> GetUserAsync(IUserLookup lookup, CancellationToken? token = null);

		Task<Match?> GetMatchAsync(int MatchID, CancellationToken? token = null);

		Task<DailyRaceChallenge?> GetDailyRaceChallengeAsync(DateTime? date = null, CancellationToken? token = null);

		Task<DailyRaceLeaderboard?> GetDailyRaceLeaderboardAsync(int crewSize, DateTime? date = null, CancellationToken? token = null);

		Task<UserDailyRaceStats?> GetUserDailyStatsAsync(IUserLookup lookup, CancellationToken? token = null);

		Task<IEnumerable<Incident>> GetIncidentsAsync(CancellationToken? token = null);
	}
	public interface IUserLookup
	{
		string AsString();
	}
	public record struct UUIDLookup(Guid UUID) : IUserLookup
	{
		public string AsString()
		{
			return UUID.ToString();
		}
	}
	public record struct DiscordIDLookup(string DiscordID) : IUserLookup
	{
		public string AsString()
		{
			return "discord:" + DiscordID;
		}
	}
	public record struct UsernameLookup(string Username) : IUserLookup
	{
		public string AsString()
		{
			return Username;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	internal static class IsExternalInit
	{
	}
}

BepInEx/plugins/Diomedes/me.loaforc.diomedes.dll

Decompiled 16 hours ago
using System;
using System.Buffers;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Athena;
using Athena.Unity;
using Athena.WebSockets;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using Dawn.Internal;
using Dawn.Utils;
using Diomedes.API;
using Diomedes.API.Client;
using Diomedes.Client.API;
using Diomedes.Client.GameMode;
using Diomedes.Client.GameMode.Bingo;
using Diomedes.Client.GameMode.Bingo.Challenges;
using Diomedes.Client.GameMode.Knockout;
using Diomedes.Client.GameMode.Race;
using Diomedes.Client.Match;
using Diomedes.Client.Networking;
using Diomedes.Client.Networking.Discord;
using Diomedes.Client.Patch;
using Diomedes.Client.Preloader;
using Diomedes.Client.Providers;
using Diomedes.Client.Saves;
using Diomedes.Client.UI;
using Diomedes.Client.UI.Bingo;
using Diomedes.Client.UI.Settings;
using Diomedes.Client.Util;
using Diomedes.Client.Util.Extensions;
using Diomedes.Shared;
using Diomedes.Shared.Data;
using Diomedes.Shared.Data.Chat;
using Diomedes.Shared.Data.Match;
using Diomedes.Shared.Data.User;
using Diomedes.Shared.GameMode;
using Diomedes.Shared.GameMode.Bingo;
using Diomedes.Shared.GameMode.GameSettings;
using Diomedes.Shared.GameMode.Knockout;
using Diomedes.Shared.GameMode.Race;
using Diomedes.Shared.Internal.References;
using Diomedes.Shared.Logging;
using Diomedes.Shared.Packets;
using Diomedes.Shared.Util.Extensions;
using GameNetcodeStuff;
using HarmonyLib;
using IL;
using IL.GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using On.GameNetcodeStuff;
using On.UnityEngine;
using Serilog;
using Serilog.Configuration;
using Serilog.Context;
using Serilog.Core;
using Serilog.Core.Enrichers;
using Serilog.Events;
using Serilog.Exceptions;
using Serilog.Formatting;
using Serilog.Formatting.Json;
using Serilog.Sinks.BepInEx.Themes;
using Serilog.Sinks.File;
using Steamworks;
using Steamworks.Data;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using me.loaforc.diomedes.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Athena")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("giosuel.Imperium")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: AssemblyCompany("me.loaforc.diomedes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+03a1858111402c9890133d64cf3f83ce16b9ffdb")]
[assembly: AssemblyProduct("Diomedes.Client")]
[assembly: AssemblyTitle("me.loaforc.diomedes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[Flags]
public enum GrabbableObjectFilter : byte
{
	None = 0,
	NonExcluded = 1,
	Excluded = 2,
	Special = 4
}
internal static class GrabbableObjectExtensions
{
	public static List<GrabbableObject> Grab(this IEnumerable<GrabbableObject> grabbableObjects, GrabbableObjectFilter grabbableObjectType, out int totalScrapValue, NamespacedKey? ExcludeTag = null, ILogger? logger = null)
	{
		List<GrabbableObject> list = new List<GrabbableObject>();
		totalScrapValue = 0;
		foreach (GrabbableObject grabbableObject in grabbableObjects)
		{
			if (logger != null)
			{
				logger.Debug<string>("Scrap to sell: {scrap}", grabbableObject.itemProperties.itemName);
			}
			if (!grabbableObject.itemProperties.isScrap)
			{
				if (grabbableObject.itemProperties.itemId == 14 && grabbableObjectType.HasFlag(GrabbableObjectFilter.Special))
				{
					totalScrapValue += grabbableObject.scrapValue;
					list.Add(grabbableObject);
					if (logger != null)
					{
						logger.Debug<string>("Found special scrap {scrap}", grabbableObject.itemProperties.itemName);
					}
				}
				continue;
			}
			DawnItemInfo dawnInfo = ItemExtensions.GetDawnInfo(grabbableObject.itemProperties);
			if (ExcludeTag != null)
			{
				if (((DawnBaseInfo<DawnItemInfo>)(object)dawnInfo).HasTag(ExcludeTag))
				{
					if (grabbableObjectType.HasFlag(GrabbableObjectFilter.Excluded))
					{
						totalScrapValue += grabbableObject.scrapValue;
						list.Add(grabbableObject);
						if (logger != null)
						{
							logger.Debug<string>("Found excluded scrap {scrap}", grabbableObject.itemProperties.itemName);
						}
					}
				}
				else if (grabbableObjectType.HasFlag(GrabbableObjectFilter.NonExcluded))
				{
					totalScrapValue += grabbableObject.scrapValue;
					list.Add(grabbableObject);
					if (logger != null)
					{
						logger.Debug<string>("Found non-excluded scrap {scrap}", grabbableObject.itemProperties.itemName);
					}
				}
			}
			else if (grabbableObjectType.HasFlag(GrabbableObjectFilter.NonExcluded))
			{
				totalScrapValue += grabbableObject.scrapValue;
				list.Add(grabbableObject);
				if (logger != null)
				{
					logger.Debug<string>("Found non-excluded scrap {scrap}", grabbableObject.itemProperties.itemName);
				}
			}
		}
		return list;
	}

	public static void SafelyDespawn(this GrabbableObject grabbable)
	{
		if ((grabbable.isHeld || grabbable.isPocketed) && ((NetworkBehaviour)grabbable).IsOwner)
		{
			PlayerControllerB playerHeldBy = grabbable.playerHeldBy;
			playerHeldBy.carryWeight = Mathf.Clamp(playerHeldBy.carryWeight - (grabbable.itemProperties.weight - 1f), 1f, 10f);
			playerHeldBy.DestroyItemInSlotAndSync(Array.IndexOf(playerHeldBy.ItemSlots, grabbable));
		}
		else if (((NetworkBehaviour)grabbable).IsServer)
		{
			((NetworkBehaviour)grabbable).NetworkObject.Despawn(true);
		}
		if (RoundManager.Instance.spawnedSyncedObjects.Contains(((Component)grabbable).gameObject))
		{
			RoundManager.Instance.spawnedSyncedObjects.Remove(((Component)grabbable).gameObject);
		}
	}

	public static void SafelyDespawn(this IEnumerable<GrabbableObject> grabbableObjects)
	{
		foreach (GrabbableObject grabbableObject in grabbableObjects)
		{
			grabbableObject.SafelyDespawn();
		}
	}

	public static int GetScrapValues(this IEnumerable<GrabbableObject> grabbableObjects)
	{
		return grabbableObjects.Sum((GrabbableObject grabbable) => grabbable.scrapValue);
	}
}
namespace Athena.Unity
{
	public class UnityNetworkConnection : INetworkConnection, IAsyncDisposable
	{
		private readonly INetworkTransport _transport;

		private readonly ArrayPool<byte> _pool = ArrayPool<byte>.Shared;

		private readonly ConcurrentQueue<QueuedPacket> _sendQueue = new ConcurrentQueue<QueuedPacket>();

		private readonly SemaphoreSlim _sendSignal = new SemaphoreSlim(0, 1);

		private readonly CancellationTokenSource _cts = new CancellationTokenSource();

		private readonly Dictionary<PacketID, PacketHandlerDelegate> _handlers = new Dictionary<PacketID, PacketHandlerDelegate>();

		private ConcurrentQueue<byte[]> _queuedPackets = new ConcurrentQueue<byte[]>();

		private FileStream _file = new FileStream(Path.Combine(Paths.GameRootPath, "test.bin"), FileMode.Create);

		public IUnknownPacketLogger UnknownPacketLogger { get; init; } = (IUnknownPacketLogger)(object)NoOpUnknownPacketLogger.Instance;

		private event Action<INetworkConnection> _onDisconnect = delegate
		{
		};

		public event Action OnDisconnect = delegate
		{
		};

		public event Action<Exception> OnException = delegate
		{
		};

		public UnityNetworkConnection(INetworkTransport transport)
		{
			_transport = transport;
			_transport.OnDisconnect += delegate
			{
				this._onDisconnect((INetworkConnection)(object)this);
				this.OnDisconnect();
			};
		}

		public Task RunAsync()
		{
			Task task = SendLoopAsync(_cts.Token);
			Task task2 = ReceiveLoopAsync(_cts.Token);
			return Task.WhenAll(task, task2);
		}

		private async Task SendLoopAsync(CancellationToken token)
		{
			while (!token.IsCancellationRequested)
			{
				await _sendSignal.WaitAsync(token);
				QueuedPacket queued;
				while (_sendQueue.TryDequeue(out queued))
				{
					try
					{
						await _transport.SendAsync((ReadOnlyMemory<byte>)((QueuedPacket)(ref queued)).Buffer.AsMemory(0, ((QueuedPacket)(ref queued)).Size), token);
					}
					finally
					{
						_pool.Return(((QueuedPacket)(ref queued)).Buffer);
					}
				}
			}
		}

		private async Task ReceiveLoopAsync(CancellationToken token)
		{
			while (!token.IsCancellationRequested)
			{
				ReadOnlyMemory<byte> data = await _transport.RecvAsync(token);
				await _file.WriteAsync(data);
				await _file.FlushAsync();
				_queuedPackets.Enqueue(data.ToArray());
			}
		}

		public byte[] RentBuffer()
		{
			return _pool.Rent(_transport.MaxPacketSize);
		}

		public void SendBuffer(byte[] buffer, int size)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_sendQueue.Enqueue(new QueuedPacket(buffer, size));
			if (_sendSignal.CurrentCount == 0)
			{
				_sendSignal.Release();
			}
		}

		public void Register(PacketRegister register)
		{
			//IL_0021: 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)
			foreach (var (key, value) in register.handlers)
			{
				_handlers.Add(key, value);
			}
			foreach (Action<INetworkConnection> disconnectCallback in register.disconnectCallbacks)
			{
				_onDisconnect += disconnectCallback;
			}
		}

		public void Unregister(PacketRegister register)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			foreach (PacketID key in register.handlers.Keys)
			{
				_handlers.Remove(key);
			}
			foreach (Action<INetworkConnection> disconnectCallback in register.disconnectCallbacks)
			{
				_onDisconnect -= disconnectCallback;
			}
		}

		public ValueTask DisposeAsync()
		{
			_cts.Cancel();
			_sendSignal.Dispose();
			return ((IAsyncDisposable)_transport).DisposeAsync();
		}

		public void RunThroughQueue()
		{
			//IL_0021: 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)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			byte[] result;
			while (_queuedPackets.TryDequeue(out result))
			{
				using MemoryStream input = new MemoryStream(result);
				using BinaryReader binaryReader = new BinaryReader(input);
				PacketID val = BinaryReaderExtensions.ReadPacketID(binaryReader);
				if (_handlers.TryGetValue(val, out PacketHandlerDelegate value))
				{
					try
					{
						Task task = value.Invoke(binaryReader, (INetworkConnection)(object)this);
						if (task.IsCompleted)
						{
							continue;
						}
						Task.Run(async delegate
						{
							try
							{
								await task;
							}
							catch (Exception obj2)
							{
								this.OnException(obj2);
							}
						});
					}
					catch (Exception obj)
					{
						this.OnException(obj);
					}
				}
				else
				{
					UnknownPacketLogger.Log(val);
				}
			}
		}
	}
}
namespace Diomedes.Shared.Internal.References
{
	public static class MenuManagerRefs
	{
		private static MenuManager? _instance;

		public static MenuManager Instance
		{
			get
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = Object.FindFirstObjectByType<MenuManager>();
				}
				return _instance;
			}
		}
	}
}
namespace Diomedes.Client
{
	public static class DiomedesContent
	{
		public static Registry<ChallengeInfo> Challenges { get; } = new Registry<ChallengeInfo>();

		public static Registry<ChallengeGroup> ChallengeGroups { get; } = new Registry<ChallengeGroup>();
	}
	[BepInPlugin("me.loaforc.diomedes", "Diomedes.Client", "0.9.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DiomedesPlugin : BaseUnityPlugin
	{
		private static Logger _seriLogger;

		internal static readonly List<ILHook> ILHooks = new List<ILHook>();

		internal static readonly List<Hook> Hooks = new List<Hook>();

		internal static string RootInstancePath = string.Empty;

		internal static readonly string ModInstallFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		internal static readonly SynchronizationContext DefaultSyncContext = SynchronizationContext.Current;

		internal static ILogger Logger => (ILogger)(object)_seriLogger;

		internal static DiomedesNetworkManager NetworkManager { get; private set; } = null;

		internal static DiomedesSaveManager SaveManager { get; private set; } = null;

		internal static PersistentDataContainer DiomedesDataContainer { get; private set; } = null;

		internal static ClientMatch? CurrentMatch => NetworkManager.CurrentMatch;

		internal static DiomedesAssets Assets { get; private set; } = null;

		internal static DiomedesBingoAssets BingoAssets { get; private set; } = null;

		internal static string ConductorAddress { get; private set; }

		[MemberNotNullWhen(true, "CurrentMatch")]
		public static bool IsInMatch()
		{
			return CurrentMatch != null;
		}

		[MemberNotNullWhen(false, "CurrentMatch")]
		public static bool IsNotInMatch()
		{
			return !IsInMatch();
		}

		private void Awake()
		{
			RootInstancePath = Path.Combine(Paths.BepInExRootPath, "Diomedes");
			SetupLogging();
			Application.quitting += _seriLogger.Dispose;
			SetupPatches();
			SetupAssets();
			SetupNetworkManager();
			SetupSaveManager();
			SetupBalanceAdjustments();
			SetupAPI();
			BingoHandler.Setup();
			Logger.Information("me.loaforc.diomedes v0.9.0 has loaded!");
		}

		private void SetupAPI()
		{
			DiomedesClientAPI.Init();
		}

		private void SetupLogging()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			bool value = ((BaseUnityPlugin)this).Config.Bind<bool>("Internal Debugging", "DumpJsonLogs", false, "Dumps some logs as json files for easier parsing, should not be enabled by default.").Value;
			LoggerSinkConfiguration writeTo = BepInExLoggerConfigurationExtensions.BepInExLogger(LoggerEnrichmentConfigurationExtensions.WithExceptionDetails(new LoggerConfiguration().Enrich).WriteTo, "me.loaforc.diomedes", "[{Timestamp:HH:mm:ss}] [{SourceName}/{Level:u3}] {Message:lj}{NewLine}{Exception}", (IFormatProvider)null, (BepInExConsoleTheme)null).WriteTo;
			string text = RootInstancePath + "/full.log";
			int? num = 7;
			LoggerConfiguration val = FileLoggerConfigurationExtensions.File(FileLoggerConfigurationExtensions.File(writeTo, text, (LogEventLevel)0, "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}", (IFormatProvider)null, (long?)1073741824L, (LoggingLevelSwitch)null, false, false, (TimeSpan?)null, (RollingInterval)3, false, num, (Encoding)null, (FileLifecycleHooks)null, (TimeSpan?)null).WriteTo, (ITextFormatter)new JsonFormatter((string)null, false, (IFormatProvider)null), RootInstancePath + "/exceptions.log.json", (LogEventLevel)4, (long?)1073741824L, (LoggingLevelSwitch)null, false, false, (TimeSpan?)null, (RollingInterval)0, false, (int?)31, (Encoding)null, (FileLifecycleHooks)null, (TimeSpan?)null);
			if (value)
			{
				FileLoggerConfigurationExtensions.File(val.WriteTo, (ITextFormatter)new JsonFormatter((string)null, false, (IFormatProvider)null), RootInstancePath + "/full.log.json", (LogEventLevel)0, (long?)1073741824L, (LoggingLevelSwitch)null, false, false, (TimeSpan?)null, (RollingInterval)0, false, (int?)31, (Encoding)null, (FileLifecycleHooks)null, (TimeSpan?)null);
			}
			_seriLogger = val.CreateLogger();
			Logger.Information<string>("Diomedes version: {version}", "0.9.0");
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private void SetupBalanceAdjustments()
		{
			Logger.Information("Registering listeners to do balance adjustments");
			((Registry<DawnMoonInfo>)(object)LethalContent.Moons).OnFreeze += delegate
			{
				foreach (DawnMoonInfo value in ((Registry<DawnMoonInfo>)(object)LethalContent.Moons).Values)
				{
					((DawnBaseInfo<DawnMoonInfo>)(object)value).Internal_AddTag(DawnLibTags.LunarConfig);
					value.DawnPurchaseInfo.PurchasePredicate = (ITerminalPurchasePredicate)(object)new DiomedesMoonPurchasePredicate(value, value.DawnPurchaseInfo.PurchasePredicate);
					value.DawnPurchaseInfo.Cost = new DiomedesFreeMoonProvider(value.DawnPurchaseInfo.Cost);
					Logger.Debug<NamespacedKey>("Replaced moon PurchasePredicate for {MoonKey}", ((DawnBaseInfo<DawnMoonInfo>)(object)value).Key);
				}
			};
			DawnLib.ApplyAllTagsInFolder(Path.Combine(ModInstallFolder, "data", "tags"));
		}

		private void SetupPatches()
		{
			Logger.Information("Doing patches.");
			InitalizeGamePatch.Init();
			RoundManagerPatch.Init();
			TerminalPatch.Init();
			MenuManagerPatch.Init();
			TimeOfDayPatch.Init();
			StartOfRoundPatch.Init();
			StartMatchLeverPatch.Init();
			HUDManagerPatch.Init();
			DepositItemsDeskPatch.Init();
			GameNetworkManagerPatch.Init();
			UnityDebugPatch.Init();
			QuickMenuManagerPatch.Init();
			UsernamePatch.Init();
			PreInitScenePatch.Init();
		}

		private void SetupAssets()
		{
			Assets = new DiomedesAssets("diomedes");
			BingoAssets = new DiomedesBingoAssets("diomedesbingo");
		}

		private void SetupNetworkManager()
		{
			IAuthStorage authStorage = new AuthStorage("release");
			NetworkManager = new DiomedesNetworkManager
			{
				AuthStorage = authStorage
			};
			ConductorAddress = "wss://conductor.diomedeslc.com/client";
			if (true)
			{
				NetworkManager.UseDiscordAuth(new DiscordAuthenticator());
			}
			NetworkManager.OnJoinMatch += delegate(ClientMatch match)
			{
				match.OnStateChanged += delegate(MatchState state)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0002: Invalid comparison between Unknown and I4
					//IL_0063: Unknown result type (might be due to invalid IL or missing references)
					//IL_006d: Expected O, but got Unknown
					if ((int)state == 1)
					{
						if (Object.op_Implicit((Object)(object)StartOfRound.Instance))
						{
							GameNetworkManager.Instance.Disconnect();
						}
						if (match.IsCaptain)
						{
							SaveMetadata save = match.Save;
							Logger.Information<string>("Hosting lobby! SaveFileName = {SaveName}", save.Name);
							SaveManager.SetAsCurrentSave(save);
							GameNetworkManager.Instance.lobbyHostSettings = new HostSettings("DiomedesLobby", false, "");
							GameNetworkManager.Instance.StartHost();
						}
					}
				};
			};
		}

		private void SetupSaveManager()
		{
			int value = ((BaseUnityPlugin)this).Config.Bind<int>("Save Handling", "Max Saves", 5, "Diomedes creates saves per match, this values indicates how many keep be held at once before old saves are cleared.").Value;
			ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Save Handling", "Delete All Next Startup", false, "On the next startup Diomedes will delete all match save files, then set this value back to false");
			Logger.Information("Setting up SaveManager.");
			Logger.Information<int>("{MaxSaves} Max number of Saves", value);
			DiomedesDataContainer = BepInPluginExtensions.GetPersistentDataContainer((BaseUnityPlugin)(object)this);
			SaveManager = new DiomedesSaveManager((IDataContainer)(object)DiomedesDataContainer, value);
			if (val.Value)
			{
				val.Value = false;
				SaveManager.DeleteAllSaves();
			}
			else
			{
				SaveManager.DoPrune();
			}
			NetworkManager.OnLeaveMatch += delegate
			{
				SaveManager.DoPrune();
			};
		}

		internal static ILogger SetupLogging<T>()
		{
			if (Logger == null)
			{
				if (Application.isEditor)
				{
					return null;
				}
				throw new InvalidOperationException("Logger has not been initialized.");
			}
			return Logger.ForContext<T>();
		}

		internal static ILogger SetupLogging(ILogEventEnricher enricher)
		{
			if (Logger == null)
			{
				if (Application.isEditor)
				{
					return null;
				}
				throw new InvalidOperationException("Logger has not been initialized.");
			}
			return Logger.ForContext(enricher);
		}

		internal static ILogger SetupLogging(IEnumerable<ILogEventEnricher> enrichers)
		{
			if (Logger == null)
			{
				if (Application.isEditor)
				{
					return null;
				}
				throw new InvalidOperationException("Logger has not been initialized.");
			}
			return Logger.ForContext(enrichers);
		}
	}
	public class DiomedesAssets : AssetBundleLoader<DiomedesAssets>
	{
		[LoadFromBundle("DiomedesMenu.prefab")]
		public GameObject MenuManagerPrefab { get; private set; }

		[LoadFromBundle("InGameDiomedesMatchInfoUI.prefab")]
		public GameObject InGameDiomedesMatchInfoUI { get; private set; }

		public DiomedesAssets(string filePath)
			: base(filePath)
		{
		}
	}
	public static class DiomedesKeys
	{
		public const string NAMESPACE = "diomedes";

		public static NamespacedKey SaveDatabase = NamespacedKey.From("diomedes", "save_database");

		public static NamespacedKey<ChallengeGroup> VisitMoonGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "visit_moons");

		public static NamespacedKey<ChallengeGroup> LandEclipsedGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "land_eclipsed");

		public static NamespacedKey<ChallengeGroup> PlayerDeathsGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "player_deaths");

		public static NamespacedKey<ChallengeGroup> SpecificEnemyKillsGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "specific_enemy_kills");

		public static NamespacedKey<ChallengeGroup> SpecificScrapCollectedGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "specific_scrap_collected");

		public static NamespacedKey<ChallengeGroup> TotalDayScrapGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "scrap_collected_in_a_day");

		public static NamespacedKey<ChallengeGroup> TimesFulfilledQuotaGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "times_fulfilled_quota");

		public static NamespacedKey<ChallengeGroup> ApparatusGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "apparatus");

		public static NamespacedKey<ChallengeGroup> ShipTeleporterGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "ship_teleporter");

		public static NamespacedKey<ChallengeGroup> CombatGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "combat");

		public static NamespacedKey<ChallengeGroup> MoonTechGroup = NamespacedKey<ChallengeGroup>.From("diomedes", "moon_tech");

		public static NamespacedKey<IClientKnockoutGenerator> DefaultKOClientGenerator = NamespacedKey<IClientKnockoutGenerator>.From("diomedes", "default");

		public static NamespacedKey<IClientRaceGenerator> DefaultRaceClientGenerator = NamespacedKey<IClientRaceGenerator>.From("diomedes", "default");
	}
	internal static class DiomedesTags
	{
		public const string NAMESPACE = "diomedes";

		public static readonly NamespacedKey ScrapRemoveExcludeable = NamespacedKey.From("diomedes", "scrap_remove_excludeable");

		public static readonly NamespacedKey Earlygame = NamespacedKey.From("diomedes", "earlygame");

		public static readonly NamespacedKey Midgame = NamespacedKey.From("diomedes", "midgame");

		public static readonly NamespacedKey Lategame = NamespacedKey.From("diomedes", "lategame");

		public static readonly NamespacedKey MoonGenExclude = NamespacedKey.From("diomedes", "moon_gen_exclude");
	}
	internal abstract class MatchLeverResult
	{
		public class SuccessResult : MatchLeverResult
		{
			internal static readonly SuccessResult Instance = new SuccessResult();

			private SuccessResult()
			{
			}
		}

		public class FailResult(string reason) : MatchLeverResult()
		{
			public string Reason { get; } = reason;
		}

		public static MatchLeverResult Success()
		{
			return SuccessResult.Instance;
		}

		public static MatchLeverResult Fail(string message)
		{
			return new FailResult(message);
		}
	}
	internal enum MatchLeverState
	{
		Landed,
		InOrbit
	}
	internal interface IMatchLeverPredicate
	{
		MatchLeverResult Evaluate(MatchLeverState state);
	}
	internal class KnockoutLeverPredicate : IMatchLeverPredicate
	{
		public MatchLeverResult Evaluate(MatchLeverState state)
		{
			if (DiomedesPlugin.CurrentMatch == null || !(DiomedesPlugin.CurrentMatch.GameMode is ClientKnockoutGame clientKnockoutGame))
			{
				return MatchLeverResult.Success();
			}
			if (state == MatchLeverState.Landed)
			{
				return MatchLeverResult.Success();
			}
			if (!DiomedesPlugin.CurrentMatch.IsHost)
			{
				return MatchLeverResult.Fail("Must be host of Knockout lobby");
			}
			if (clientKnockoutGame.CompletedCrews != clientKnockoutGame.AliveCrews)
			{
				return MatchLeverResult.Fail("Not all crews have completed yet");
			}
			return MatchLeverResult.Success();
		}
	}
	internal class StartingSoonLeverPredicate : IMatchLeverPredicate
	{
		public MatchLeverResult Evaluate(MatchLeverState state)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if (DiomedesPlugin.CurrentMatch == null)
			{
				return MatchLeverResult.Success();
			}
			if ((int)DiomedesPlugin.CurrentMatch.CurrentState == 2)
			{
				return MatchLeverResult.Success();
			}
			return MatchLeverResult.Fail("Match is starting soon.");
		}
	}
	internal interface IAuthStorage
	{
		bool TryGetSessionToken(out string token);

		void SaveSessionToken(string token);

		void ClearSessionToken();
	}
	public abstract class QuotaRequirement
	{
		public class VanillaQuota : QuotaRequirement
		{
		}

		public class NoQuota : QuotaRequirement
		{
		}

		public class SetQuota(int requirement) : QuotaRequirement()
		{
			public int Requirement => requirement;
		}

		public static QuotaRequirement KeepVanilla()
		{
			return new VanillaQuota();
		}

		public static QuotaRequirement Remove()
		{
			return new NoQuota();
		}

		public static QuotaRequirement Set(int requirement)
		{
			return new SetQuota(requirement);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "me.loaforc.diomedes";

		public const string PLUGIN_NAME = "Diomedes.Client";

		public const string PLUGIN_VERSION = "0.9.0";
	}
	[GeneratedCode("DawnLib", "0.9.21")]
	public static class ChallengeKeys
	{
		public static NamespacedKey<ChallengeInfo>? GetByReflection(string name)
		{
			return (NamespacedKey<ChallengeInfo>)(typeof(ChallengeKeys).GetField(name)?.GetValue(null));
		}
	}
}
namespace Diomedes.Client.Util
{
	public abstract class AssetBundleLoader<T> where T : AssetBundleLoader<T>
	{
		protected ILogger Logger = DiomedesPlugin.SetupLogging<AssetBundleLoader<T>>();

		public AssetBundleLoader(string filePath)
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filePath));
			Logger.Debug<string, string>("AssetBundle `{FilePath}` contains these objects: \n{AllAssetNames}", filePath, string.Join("\n", val.GetAllAssetNames()));
			Type typeFromHandle = typeof(T);
			PropertyInfo[] properties = typeFromHandle.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				LoadFromBundleAttribute loadFromBundleAttribute = (LoadFromBundleAttribute)propertyInfo.GetCustomAttribute(typeof(LoadFromBundleAttribute));
				if (loadFromBundleAttribute != null)
				{
					Logger.Debug("Got LoadFromBundle attribute on `" + propertyInfo.Name + "`. Loading asset: `" + loadFromBundleAttribute.BundleFile + "` into the property.");
					propertyInfo.SetValue(this, LoadAsset<Object>(val, loadFromBundleAttribute.BundleFile.ToLower(CultureInfo.GetCultureInfo("en-GB"))));
				}
			}
			FinishLoadingAssets(val);
		}

		protected virtual void FinishLoadingAssets(AssetBundle bundle)
		{
		}

		protected AssetType LoadAsset<AssetType>(AssetBundle bundle, string path) where AssetType : Object
		{
			AssetType val = bundle.LoadAsset<AssetType>(path);
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException(path + " is not valid in the assetbundle!");
			}
			return val;
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class LoadFromBundleAttribute(string bundleFile) : Attribute()
	{
		public string BundleFile { get; private set; } = bundleFile;
	}
}
namespace Diomedes.Client.Util.Extensions
{
	internal static class ActiveClientRestrictionExtensions
	{
		internal static string FormatLength(this ActiveClientRestriction restriction)
		{
			if (restriction.IsPermanent())
			{
				return "permanently";
			}
			return $"until {restriction.AsDateTime()}";
		}
	}
	public static class APIQuotaInfoExtensions
	{
		internal static QuotaInfo ToSharedDTO(this QuotaInfo info)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			QuotaInfo val = new QuotaInfo();
			val.set_Days((DayInfo[])(object)new DayInfo[info.Days.Count + 1]);
			QuotaInfo val2 = val;
			foreach (var (num, val3) in IEnumerableExtensions.WithIndex<DayInfo>((IEnumerable<DayInfo>)info.Days))
			{
				val2.Days[num] = new DayInfo
				{
					MoonKey = ((object)val3.MoonKey).ToString(),
					WeatherKey = (((object)val3.WeatherKey)?.ToString() ?? string.Empty),
					Seed = val3.Seed
				};
			}
			val2.Days[info.Days.Count] = new DayInfo
			{
				IsCompanyDay = true,
				MoonKey = "gordion",
				Seed = Random.Range(0, 100000000)
			};
			return val2;
		}
	}
	public static class DayInfoExtensions
	{
		public static void SetAsCurrent(this DayInfo day)
		{
			DiomedesPlugin.Logger.Debug<string, string, bool>("Setting current DayInfo to: {MoonKey} ({WeatherKey}) IsCompanyDay? {IsCompanyDay}", day.MoonKey, day.WeatherKey, day.IsCompanyDay);
			StartOfRound.Instance.overrideRandomSeed = true;
			StartOfRound.Instance.overrideSeedNumber = day.Seed;
			DawnMoonInfo val;
			if (day.IsCompanyDay)
			{
				val = ((Registry<DawnMoonInfo>)(object)LethalContent.Moons)[MoonKeys.Gordion];
			}
			else
			{
				if (string.IsNullOrEmpty(day.MoonKey))
				{
					throw new ArgumentException("Day must have a moonKey or be a company day.");
				}
				val = ((Registry<DawnMoonInfo>)(object)LethalContent.Moons)[NamespacedKey.ForceParse(day.MoonKey).AsTyped<DawnMoonInfo>()];
			}
			val.RouteTo();
			if (!string.IsNullOrEmpty(day.WeatherKey))
			{
				DawnWeatherEffectInfo val2 = ((Registry<DawnWeatherEffectInfo>)(object)LethalContent.Weathers)[NamespacedKey.ForceParse(day.WeatherKey).AsTyped<DawnWeatherEffectInfo>()];
				DiomedesPlugin.Logger.Debug<string, string>("WeatherKey is not null or empty. DawnWeatherEffectInfo. name: {Name} effectObject.name: {EffectObject}", val2.WeatherEffect.name, ((Object)val2.WeatherEffect.effectObject).name);
				val.ChangeWeatherTo(val2);
			}
			else
			{
				DiomedesPlugin.Logger.Debug("WeatherKey is null or empty, setting to none");
				val.ChangeWeatherTo((LevelWeatherType)(-1));
			}
		}
	}
	internal static class DColorExtensions
	{
		public static Color ToUnityColor(this DColor color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			return new Color
			{
				r = (float)(int)color.Red / 255f,
				g = (float)(int)color.Green / 255f,
				b = (float)(int)color.Blue / 255f,
				a = 1f
			};
		}
	}
	public static class NamespacedKeyExtensions
	{
		public static DiomedesKey ToDiomedesKey(this NamespacedKey key)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			return new DiomedesKey(key.Namespace, key.Key);
		}

		public static DiomedesKey ToDiomedesKey<T>(this NamespacedKey<T> key) where T : INamespaced<T>
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			return new DiomedesKey(((NamespacedKey)key).Namespace, ((NamespacedKey)key).Key);
		}
	}
	internal static class RegistryExtensions
	{
		internal static async ValueTask WaitForFreezeAsync<T>(this Registry<T> self) where T : INamespaced<T>
		{
			TaskCompletionSource<object> tcs;
			if (!self.IsFrozen)
			{
				tcs = new TaskCompletionSource<object>();
				self.OnFreeze += OnFreeze;
				await tcs.Task;
			}
			void OnFreeze()
			{
				tcs.SetResult(null);
				self.OnFreeze -= OnFreeze;
			}
		}
	}
}
namespace Diomedes.Client.UI
{
	public class DiomedesMenuManager : Singleton<DiomedesMenuManager>
	{
		internal UI_MatchLobbyScreen lobbyScreen;

		internal UI_JoinPrivateMatch joinSettings;

		internal UI_HostPrivateMatch hostSettings;

		internal UI_MenuPortal menuPortal;

		[SerializeField]
		private UI_MatchLobbyScreen _lobbyScreenPrefab;

		[SerializeField]
		private UI_JoinPrivateMatch _joinSettingsPrefab;

		[SerializeField]
		private UI_HostPrivateMatch _hostSettingsPrefab;

		[SerializeField]
		private UI_MenuPortal _menuPortalPrefab;

		[SerializeField]
		private UI_DropDown _dropDownPrefab;

		private UI_DropDown _currentDropdown;

		public static readonly ILogger Logger = DiomedesPlugin.SetupLogging<DiomedesMenuManager>();

		private void Start()
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			MenuManagerRefs.Instance.DisableUIPanel(MenuManagerRefs.Instance.menuButtons);
			MenuManagerRefs.Instance.DisableUIPanel(((Component)MenuManagerRefs.Instance.versionNumberText).gameObject);
			lobbyScreen = Object.Instantiate<UI_MatchLobbyScreen>(_lobbyScreenPrefab, ((Component)this).transform.parent);
			((Component)lobbyScreen).gameObject.SetActive(false);
			joinSettings = Object.Instantiate<UI_JoinPrivateMatch>(_joinSettingsPrefab, ((Component)this).transform.parent);
			((Component)joinSettings).gameObject.SetActive(false);
			hostSettings = Object.Instantiate<UI_HostPrivateMatch>(_hostSettingsPrefab, ((Component)this).transform.parent);
			((Component)hostSettings).gameObject.SetActive(false);
			menuPortal = Object.Instantiate<UI_MenuPortal>(_menuPortalPrefab, MenuManagerRefs.Instance.menuButtons.transform);
			((Component)menuPortal).gameObject.SetActive(false);
			if (DiomedesPlugin.CurrentMatch != null)
			{
				Logger.Debug("Client is still in a match, likely just came back from InGame.");
				Logger.Debug<bool, bool>("LobbyScreen: {LobbyScreenExists}, MenuManager: {MenuManagerExists}", (Object)(object)lobbyScreen != (Object)null, (Object)(object)MenuManagerRefs.Instance != (Object)null);
				EnterMatch(DiomedesPlugin.CurrentMatch);
			}
			Logger.Debug("DiomedesMenuManager.Start");
			MenuManagerRefs.Instance.menuNotification.transform.SetAsLastSibling();
			((UnityEvent)MenuManagerRefs.Instance.menuNotification.GetComponentInChildren<Button>().onClick).AddListener(new UnityAction(DisableMainButtonsIfDiomedesMenuEnabled));
		}

		private void DisableMainButtonsIfDiomedesMenuEnabled()
		{
			if (((Component)this).gameObject.activeSelf)
			{
				MenuManagerRefs.Instance.DisableUIPanel(MenuManagerRefs.Instance.menuButtons);
			}
		}

		private void OnJoinMatch(ClientMatch match)
		{
			Logger.Debug("Joined match");
			EnterMatch(match);
		}

		private void OnEnable()
		{
			DiomedesPlugin.NetworkManager.OnLeaveMatch += OnLeaveMatch;
			DiomedesPlugin.NetworkManager.OnMatchJoinFail += OnMatchJoinFail;
			DiomedesPlugin.NetworkManager.OnJoinMatch += OnJoinMatch;
		}

		private void OnDisable()
		{
			DiomedesPlugin.NetworkManager.OnLeaveMatch -= OnLeaveMatch;
			DiomedesPlugin.NetworkManager.OnMatchJoinFail -= OnMatchJoinFail;
			DiomedesPlugin.NetworkManager.OnJoinMatch -= OnJoinMatch;
			Logger.Debug("Cleaning up menu manager");
		}

		public void OnMatchJoinFail(LobbyJoinFailReason failReason)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected I4, but got Unknown
			string text = (int)failReason switch
			{
				0 => "Match is full", 
				1 => "Match does not exist", 
				2 => "??", 
				3 => "Match is in progress", 
				4 => "Server did not respond in time", 
				5 => "An internal server exception occured!", 
				_ => throw new NotImplementedException(), 
			};
			MenuManagerRefs.Instance.DisableUIPanel(((Component)joinSettings).gameObject);
			MenuManagerRefs.Instance.DisplayMenuNotification(text, "Okay", true);
			Logger.Debug<string>("Display match join fail: {HumanReadable}", text);
		}

		private void OnLeaveMatch()
		{
			Logger.Debug<bool, bool>("OnLeaveMatch\nLobbyScreen: {LobbyScreenExists}, MenuManager: {MenuManagerExists}", (Object)(object)lobbyScreen != (Object)null, (Object)(object)MenuManagerRefs.Instance != (Object)null);
			if (!((Object)(object)lobbyScreen == (Object)null) && !((Object)(object)MenuManagerRefs.Instance == (Object)null))
			{
				MenuManagerRefs.Instance.DisableUIPanel(((Component)lobbyScreen).gameObject);
				MenuManagerRefs.Instance.EnableUIPanel(((Component)this).gameObject);
			}
		}

		public void OpenDailyRace()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			Logger.Debug("Joining daily race!");
			if (DiomedesPlugin.NetworkManager.Restrictions.Competitive != null)
			{
				MenuManagerRefs.Instance.DisplayMenuNotification("You have been banned from competitive modes " + DiomedesPlugin.NetworkManager.Restrictions.Competitive.FormatLength(), "[ Uh oh ]", true);
			}
			else if (DiomedesPlugin.NetworkManager.HasNonCompetitiveModInstalled)
			{
				MenuManagerRefs.Instance.DisplayMenuNotification("You have a mod installed that isn't allowed in competitive play.", "[ Okay ]", true);
			}
			else
			{
				DiomedesPlugin.NetworkManager.SendPacket((AthenaPacket)new JoinDailyRacePacket());
			}
		}

		public void OpenJoinSettings()
		{
			MenuManagerRefs.Instance.PlayConfirmSFX();
			MenuManagerRefs.Instance.EnableUIPanel(((Component)joinSettings).gameObject);
		}

		public void OpenHostSettings()
		{
			MenuManagerRefs.Instance.PlayConfirmSFX();
			MenuManagerRefs.Instance.EnableUIPanel(((Component)hostSettings).gameObject);
		}

		public void BackToRegularMenu()
		{
			MenuManagerRefs.Instance.PlayCancelSFX();
			MenuManagerRefs.Instance.DisableUIPanel(((Component)this).gameObject);
			MenuManagerRefs.Instance.EnableUIPanel(MenuManagerRefs.Instance.menuButtons);
			MenuManagerRefs.Instance.EnableUIPanel(((Component)MenuManagerRefs.Instance.versionNumberText).gameObject);
			MenuManagerRefs.Instance.EnableUIPanel(((Component)menuPortal).gameObject);
		}

		internal void EnterMatch(ClientMatch match)
		{
			MenuManagerRefs.Instance.DisableUIPanel(((Component)this).gameObject);
			MenuManagerRefs.Instance.DisableUIPanel(((Component)joinSettings).gameObject);
			MenuManagerRefs.Instance.DisableUIPanel(((Component)hostSettings).gameObject);
			MenuManagerRefs.Instance.EnableUIPanel(((Component)lobbyScreen).gameObject);
			lobbyScreen.Setup(match, this);
			match.OnStateChanged += delegate(MatchState state)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Invalid comparison between Unknown and I4
				Logger.Debug<MatchState>("Match state changed to {State}", state);
				if ((int)state == 1)
				{
					Logger.Debug("Going in game, hiding lobby screen.");
					MenuManagerRefs.Instance.DisableUIPanel(((Component)lobbyScreen).gameObject);
					if (!match.IsCaptain)
					{
						Logger.Debug("Not the crew captain, setting the loading screen now.");
						MenuManagerRefs.Instance.SetLoadingScreen(true, (RoomEnter)5, "");
					}
				}
			};
		}

		public UI_DropDown CreateDropdown()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_currentDropdown))
			{
				Object.Destroy((Object)(object)((Component)_currentDropdown).gameObject);
			}
			_currentDropdown = Object.Instantiate<UI_DropDown>(_dropDownPrefab, ((Component)this).transform.parent);
			RectTransform val = (RectTransform)((Component)((Component)this).GetComponentInParent<Canvas>()).transform;
			Vector2 val2 = default(Vector2);
			RectTransformUtility.ScreenPointToLocalPointInRectangle(val, ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue(), GameObject.Find("UICamera").GetComponent<Camera>(), ref val2);
			((Component)_currentDropdown).transform.position = ((Transform)val).TransformPoint(Vector2.op_Implicit(val2));
			Logger.Debug<Vector3>("Created a dropdown at {CreatedPosition}", ((Component)_currentDropdown).transform.position);
			return _currentDropdown;
		}
	}
	public class UI_ChatBox : MonoBehaviour
	{
		[SerializeField]
		[Header("Header")]
		private Button _headerButtonPrefab;

		[SerializeField]
		private Transform _headerParent;

		[SerializeField]
		private string _headerButtonFormat = "[ {0} ]";

		[Header("Chat Message History")]
		[SerializeField]
		private Transform _historyParent;

		[SerializeField]
		private TextMeshProUGUI _messagePrefab;

		[SerializeField]
		private string _chatMessageFormat = "{0}: {1}";

		[SerializeField]
		[Header("Text Input")]
		private TMP_InputField _inputField;

		private ChatChannel? _currentChannel;

		private static readonly ILogger _logger = DiomedesPlugin.SetupLogging<UI_ChatBox>();

		private Dictionary<ChatChannel, Button> _channelButtons = new Dictionary<ChatChannel, Button>();

		public Func<string, string> MsgSenderToHexColor = (string <p0>) => "#ff0000";

		private IEnumerable<ChatChannel> AllTrackedChannels => _channelButtons.Keys;

		public event Action<string> OnCommand = delegate
		{
		};

		public event Action<ChatRequest> OnSendChat = delegate
		{
		};

		private void Awake()
		{
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)delegate
			{
				SendMessage();
			});
			_inputField.characterLimit = 65535;
			_inputField.richText = false;
		}

		private void Update()
		{
			if (((ButtonControl)Keyboard.current.slashKey).wasPressedThisFrame)
			{
				((Selectable)_inputField).Select();
			}
			if (((ButtonControl)Keyboard.current.tabKey).wasPressedThisFrame)
			{
				int index = 0;
				List<ChatChannel> list = AllTrackedChannels.ToList();
				if (_currentChannel != null)
				{
					int num = list.IndexOf(_currentChannel);
					index = (num + 1) % list.Count;
				}
				if (list.Count != 0)
				{
					ChangeChannel(list[index]);
				}
			}
		}

		public void StartTracking(ChatChannel channel)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			Button val = Object.Instantiate<Button>(_headerButtonPrefab, _headerParent);
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				ChangeChannel(channel);
			});
			((TMP_Text)((Component)val).GetComponentInChildren<TextMeshProUGUI>()).text = string.Format(_headerButtonFormat, channel.ChannelName);
			_channelButtons[channel] = val;
			if (_currentChannel == null)
			{
				val.Press();
				ChangeChannel(channel);
			}
		}

		public void StopTrackingAll()
		{
			_currentChannel = null;
			TransformExtensions.KillAllChildren(_headerParent);
			_channelButtons.Clear();
			Clear();
		}

		private void ChangeChannel(ChatChannel channel)
		{
			if (_currentChannel != null)
			{
				_currentChannel.OnNewMessage -= OnNewMessage;
			}
			_logger.Debug<string, string>("Changing channels: {PreviousChannel} -> {NewChannel}", _currentChannel?.ChannelName ?? "None", channel.ChannelName);
			_currentChannel = channel;
			_currentChannel.OnNewMessage += OnNewMessage;
			Clear();
			foreach (ChatMessage item in _currentChannel)
			{
				OnNewMessage(item);
			}
			foreach (var (val3, val4) in _channelButtons)
			{
				((Selectable)val4).interactable = val3 != channel;
			}
		}

		private string FormatMessageIntoText(ChatMessage msg)
		{
			string text = (msg.IsServerMessage() ? "#fff457" : MsgSenderToHexColor(msg.Sender));
			string text2 = (msg.IsServerMessage() ? "Server" : msg.Sender);
			return string.Format(_chatMessageFormat, "<color=" + text + ">" + text2 + "</color>", "<noparse>" + msg.Message + "</noparse>");
		}

		private void OnNewMessage(ChatMessage msg)
		{
			string text = FormatMessageIntoText(msg);
			TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(_messagePrefab, _historyParent);
			((TMP_Text)val).text = text;
			Image componentInChildren = ((Component)val).GetComponentInChildren<Image>();
			((Behaviour)componentInChildren).enabled = false;
		}

		public void Clear()
		{
			TransformExtensions.KillAllChildren(_historyParent);
		}

		public void SendMessage()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			string text = _inputField.text;
			_inputField.text = string.Empty;
			EventSystem.current.SetSelectedGameObject((GameObject)null);
			if (!string.IsNullOrEmpty(text))
			{
				if (_currentChannel == null)
				{
					_logger.Warning("Tried to send a message but the chat box doesn't have a channel!");
				}
				else if (text.StartsWith("/"))
				{
					_logger.Debug<string>("Running command: '{text}'", text);
					string text2 = text.Replace("/", string.Empty);
					_logger.Debug<string>("trimmed: '{command}'", text2);
					this.OnCommand(text2);
				}
				else
				{
					ChatRequest val = new ChatRequest();
					val.set_Target(_currentChannel.Target);
					val.set_Message(text);
					ChatRequest obj = val;
					this.OnSendChat(obj);
				}
			}
		}
	}
	public class UI_DailyRaceStats
	{
	}
	public class UI_DropDown : MonoBehaviour, IPointerExitHandler, IEventSystemHandler
	{
		[SerializeField]
		private Button _buttonPrefab;

		[SerializeField]
		private string _buttonTextFormat = "[ {0} ]";

		private void Update()
		{
			if (Mouse.current.leftButton.wasPressedThisFrame && !EventSystem.current.IsPointerOverGameObject())
			{
				DiomedesMenuManager.Logger.Debug("Mouse click outside dropdown, destroying!");
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		public UI_DropDown AddButton(string text, Action callback)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Button val = Object.Instantiate<Button>(_buttonPrefab, ((Component)this).transform);
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				DiomedesMenuManager.Logger.Debug<string>("clicked: '{text}' on the dropdown!", text);
				callback();
				Object.Destroy((Object)(object)((Component)this).gameObject);
			});
			((TMP_Text)((Component)val).GetComponentInChildren<TextMeshProUGUI>()).text = string.Format(_buttonTextFormat, text);
			return this;
		}

		public void Finish()
		{
			if (((Component)this).transform.childCount == 1)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	public class UI_HostPrivateMatch : MonoBehaviour
	{
		[SerializeField]
		private Button _knockoutGame;

		[SerializeField]
		private Button _raceGame;

		[SerializeField]
		private Button _bingoGame;

		[SerializeField]
		private GameObject _content;

		[SerializeField]
		private GameObject _loading;

		private GameModeType _currentGameMode;

		private static readonly int SelectedHash = Animator.StringToHash("Selected");

		private void OnEnable()
		{
			SetKnockout();
			_content.SetActive(true);
			_loading.SetActive(false);
		}

		public void SetAnimation(Animator animator)
		{
			animator.SetBool(SelectedHash, true);
		}

		public void Confirm()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			_content.SetActive(false);
			_loading.SetActive(true);
			DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
			CreatePrivateLobbyPacket val = new CreatePrivateLobbyPacket();
			val.set_GameMode(_currentGameMode);
			networkManager.SendPacket((AthenaPacket)val);
		}

		public void SetKnockout()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_currentGameMode = (GameModeType)0;
			((Selectable)_knockoutGame).interactable = false;
			((Selectable)_raceGame).interactable = true;
			((Selectable)_bingoGame).interactable = true;
		}

		public void SetRace()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_currentGameMode = (GameModeType)1;
			((Selectable)_knockoutGame).interactable = true;
			((Selectable)_raceGame).interactable = false;
			((Selectable)_bingoGame).interactable = true;
		}

		public void SetBingo()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_currentGameMode = (GameModeType)2;
			((Selectable)_knockoutGame).interactable = true;
			((Selectable)_raceGame).interactable = true;
			((Selectable)_bingoGame).interactable = false;
		}

		public void Back()
		{
			MenuManagerRefs.Instance.PlayCancelSFX();
			MenuManagerRefs.Instance.DisableUIPanel(((Component)this).gameObject);
		}
	}
	public class UI_JoinPrivateMatch : MonoBehaviour
	{
		[SerializeField]
		private TMP_InputField _matchCodeInput;

		[SerializeField]
		private GameObject _content;

		[SerializeField]
		private GameObject _loading;

		private Coroutine? _timeout;

		private void OnEnable()
		{
			_content.SetActive(true);
			_loading.SetActive(false);
			DiomedesPlugin.NetworkManager.OnJoinMatch += OnJoinMatch;
			DiomedesPlugin.NetworkManager.OnMatchJoinFail += OnMatchJoinFail;
		}

		private void OnDisable()
		{
			DiomedesPlugin.NetworkManager.OnJoinMatch -= OnJoinMatch;
			DiomedesPlugin.NetworkManager.OnMatchJoinFail -= OnMatchJoinFail;
		}

		private void OnMatchJoinFail(LobbyJoinFailReason reason)
		{
			if (_timeout != null)
			{
				((MonoBehaviour)this).StopCoroutine(_timeout);
				_timeout = null;
			}
		}

		private void OnJoinMatch(ClientMatch match)
		{
			if (_timeout != null)
			{
				((MonoBehaviour)this).StopCoroutine(_timeout);
				_timeout = null;
			}
		}

		public void Confirm()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			_content.SetActive(false);
			_loading.SetActive(true);
			if (!int.TryParse(_matchCodeInput.text, out var result))
			{
				MenuManagerRefs.Instance.DisplayMenuNotification("Not a valid match code!", "Okay", true);
				MenuManagerRefs.Instance.DisableUIPanel(((Component)this).gameObject);
				return;
			}
			DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
			RequestMatchJoinPacket val = new RequestMatchJoinPacket();
			val.set_MatchID(result);
			networkManager.SendPacket((AthenaPacket)val);
			_timeout = ((MonoBehaviour)this).StartCoroutine(JoinTimeout(3));
		}

		public void Back()
		{
			MenuManagerRefs.Instance.PlayCancelSFX();
			MenuManagerRefs.Instance.DisableUIPanel(((Component)this).gameObject);
		}

		private IEnumerator JoinTimeout(int seconds)
		{
			yield return (object)new WaitForSeconds((float)seconds);
			Singleton<DiomedesMenuManager>.Instance?.OnMatchJoinFail((LobbyJoinFailReason)4);
			DiomedesPlugin.NetworkManager.SendPacket((AthenaPacket)new JoinTimeoutPacket());
		}
	}
	public class UI_MatchInfo : MonoBehaviour
	{
		[SerializeField]
		private TextMeshProUGUI _matchNameText;

		[SerializeField]
		private TextMeshProUGUI _matchInfoText;

		private ClientMatch _match;

		private ILogger _logger;

		internal void Setup(ILogger logger, ClientMatch match)
		{
			_logger = logger;
			_match = match;
			((TMP_Text)_matchNameText).text = match.Name;
			UpdateMatchInfoText();
			match.OnPlayerJoined += UpdateOnPlayerEvent;
			match.OnPlayerLeft += UpdateOnPlayerEvent;
			match.OnMatchRenamed += UpdateMatchInfoText;
			match.GameMode.OnNewSettings += UpdateMatchInfoText;
		}

		private void OnDestroy()
		{
			_match.OnPlayerJoined -= UpdateOnPlayerEvent;
			_match.OnPlayerLeft -= UpdateOnPlayerEvent;
			_match.OnMatchRenamed -= UpdateMatchInfoText;
			_match.GameMode.OnNewSettings -= UpdateMatchInfoText;
		}

		private void UpdateOnPlayerEvent(UserInfo _)
		{
			UpdateMatchInfoText();
		}

		private void UpdateMatchInfoText()
		{
			_logger.Debug("Updating match info text");
			if (Object.op_Implicit((Object)(object)_matchInfoText))
			{
				List<string> list = new List<string>(2)
				{
					_match.GameMode.Name,
					$"{_match.AllPlayers().Count()} Players"
				};
				if (_match.IsDaily)
				{
					list.Add("Daily");
				}
				((TMP_Text)_matchInfoText).text = string.Join(" | ", list);
			}
			((TMP_Text)_matchNameText).text = _match.Name;
		}
	}
	public class UI_MatchLobbyHeader : MonoBehaviour
	{
		[SerializeField]
		private GameObject _startGameButton;

		[SerializeField]
		private GameObject _settingsButton;

		[SerializeField]
		private GameObject _settingsUI;

		private ClientMatch _match;

		private ILogger _logger;

		private DiomedesMenuManager _menuManager;

		internal void Setup(ILogger logger, ClientMatch match, DiomedesMenuManager menuManager)
		{
			_match = match;
			_logger = logger;
			_menuManager = menuManager;
			CheckIsHost();
			_match.OnNewHost += CheckIsHost;
		}

		private void OnDestroy()
		{
			_match.OnNewHost -= CheckIsHost;
		}

		private void CheckIsHost()
		{
			_startGameButton.SetActive(_match.IsHost);
			_settingsButton.SetActive(_match.IsHost && !_match.IsDaily);
		}

		public void CopyCode()
		{
			GUIUtility.systemCopyBuffer = _match.ID.ToString();
		}

		public void StartGame()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!_match.IsHost)
			{
				_logger.Warning("How did client click start game button but is not the host?");
			}
			else
			{
				DiomedesPlugin.NetworkManager.SendPacket((AthenaPacket)new StartGamePacket());
			}
		}

		public void LeaveMatch()
		{
			DiomedesPlugin.NetworkManager.LeaveMatch();
			MenuManagerRefs.Instance.DisableUIPanel(((Component)_menuManager.lobbyScreen).gameObject);
			MenuManagerRefs.Instance.DisableUIPanel(_settingsUI);
			MenuManagerRefs.Instance.EnableUIPanel(((Component)_menuManager).gameObject);
		}
	}
	public class UI_MatchLobbyScreen : MonoBehaviour
	{
		[SerializeField]
		private UI_MatchLobbyHeader _header;

		[SerializeField]
		private UI_MatchPlayerList _playerList;

		[SerializeField]
		private UI_MatchInfo _matchInfo;

		[SerializeField]
		private UI_ChatBox _chatBox;

		[SerializeField]
		private UI_MatchSettings _matchSettings;

		private static readonly ILogger _logger = DiomedesPlugin.SetupLogging<UI_MatchLobbyScreen>();

		internal void Setup(ClientMatch match, DiomedesMenuManager menuManager)
		{
			_header.Setup(_logger, match, menuManager);
			_playerList.Setup(match);
			_matchInfo.Setup(_logger, match);
			_matchSettings.Setup(match);
			_chatBox.OnSendChat += OnSendChat;
			_chatBox.MsgSenderToHexColor = delegate(string sender)
			{
				UserInfo val = match.AllPlayers().First((UserInfo it) => it.Username == sender);
				CrewInfo crewFor = match.GetCrewFor(val.UUID);
				return crewFor.Color.ToHexCode();
			};
			_chatBox.StopTrackingAll();
			_chatBox.StartTracking(match.MatchChat);
			_chatBox.StartTracking(match.CrewChat);
		}

		private void OnSendChat(ChatRequest req)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
			ChatRequestPacket val = new ChatRequestPacket();
			val.set_Request(req);
			networkManager.SendPacket((AthenaPacket)val);
		}

		private void OnDisable()
		{
			_chatBox.OnSendChat -= OnSendChat;
		}
	}
	public class UI_MatchPlayerList : MonoBehaviour
	{
		[SerializeField]
		private UI_PlayerNameplate _nameplatePrefab;

		[SerializeField]
		private Transform _parent;

		private Dictionary<UserInfo, UI_PlayerNameplate> _nameplates = new Dictionary<UserInfo, UI_PlayerNameplate>();

		private ClientMatch _match;

		internal void Setup(ClientMatch match)
		{
			_match = match;
			_nameplates = new Dictionary<UserInfo, UI_PlayerNameplate>();
			TransformExtensions.KillAllChildren(_parent);
			foreach (UserInfo item in match.AllPlayers())
			{
				AddPlayer(item);
			}
			match.OnPlayerJoined += AddPlayer;
			match.OnPlayerLeft += RemovePlayer;
		}

		private void OnDestroy()
		{
			_match.OnPlayerJoined -= AddPlayer;
			_match.OnPlayerLeft -= RemovePlayer;
		}

		private void AddPlayer(UserInfo userInfo)
		{
			UI_PlayerNameplate uI_PlayerNameplate = Object.Instantiate<UI_PlayerNameplate>(_nameplatePrefab, _parent);
			_nameplates[userInfo] = uI_PlayerNameplate;
			uI_PlayerNameplate.Setup(_match, userInfo);
			uI_PlayerNameplate.OnPlayerIconClick += delegate
			{
				UI_DropDown uI_DropDown = Singleton<DiomedesMenuManager>.Instance.CreateDropdown();
				if (_match.IsHost)
				{
					if (userInfo.UUID != DiomedesPlugin.NetworkManager.LocalUser.UUID)
					{
						uI_DropDown.AddButton("Kick Player", delegate
						{
							//IL_0005: Unknown result type (might be due to invalid IL or missing references)
							//IL_000a: Unknown result type (might be due to invalid IL or missing references)
							//IL_0020: Expected O, but got Unknown
							DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
							KickPlayerPacket val = new KickPlayerPacket();
							val.set_UUID(userInfo.UUID);
							networkManager.SendPacket((AthenaPacket)val);
						}).AddButton("Promote Host", delegate
						{
							//IL_0005: Unknown result type (might be due to invalid IL or missing references)
							//IL_000a: Unknown result type (might be due to invalid IL or missing references)
							//IL_0020: Expected O, but got Unknown
							DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
							NewMatchHostPacket val = new NewMatchHostPacket();
							val.set_UUID(userInfo.UUID);
							networkManager.SendPacket((AthenaPacket)val);
						});
					}
					foreach (CrewInfo info in _match.Crews.Values)
					{
						uI_DropDown.AddButton("Move: " + info.Name, delegate
						{
							//IL_002f: Unknown result type (might be due to invalid IL or missing references)
							//IL_0034: Unknown result type (might be due to invalid IL or missing references)
							//IL_004a: Unknown result type (might be due to invalid IL or missing references)
							//IL_0060: Expected O, but got Unknown
							DiomedesMenuManager.Logger.Debug<string, string>("Moving: {UserName} to crew of {CrewInfoName}", userInfo.Username, info.Name);
							DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
							PlayerMovedCrewPacket val = new PlayerMovedCrewPacket();
							val.set_UUID(userInfo.UUID);
							val.set_CrewID(info.ID);
							networkManager.SendPacket((AthenaPacket)val);
						});
					}
				}
				if (userInfo.UUID != DiomedesPlugin.NetworkManager.LocalUser.UUID)
				{
					CrewInfo localUserCrew = _match.LocalUserCrew;
					CrewInfo crewFor = _match.GetCrewFor(userInfo.UUID);
					if (_match.IsCaptain && localUserCrew == crewFor)
					{
						uI_DropDown.AddButton("Promote Captain", delegate
						{
							//IL_0034: 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_004f: Expected O, but got Unknown
							DiomedesMenuManager.Logger.Debug<string, string>("Promoting: {UserName} to captain of {UserCrewName}", userInfo.Username, _match.LocalUserCrew.Name);
							DiomedesNetworkManager networkManager = DiomedesPlugin.NetworkManager;
							NewCrewCaptainPacket val = new NewCrewCaptainPacket();
							val.set_UUID(userInfo.UUID);
							networkManager.SendPacket((AthenaPacket)val);
						});
					}
				}
				uI_DropDown.Finish();
			};
		}

		private void RemovePlayer(UserInfo userInfo)
		{
			UI_PlayerNameplate uI_PlayerNameplate = _nameplates[userInfo];
			Object.Destroy((Object)(object)((Component)uI_PlayerNameplate).gameObject);
			_nameplates.Remove(userInfo);
		}
	}
	public class UI_MenuPortal : MonoBehaviour
	{
		public void BackToDiomedes()
		{
			MenuManagerRefs.Instance.PlayConfirmSFX();
			MenuManagerRefs.Instance.EnableUIPanel(((Component)Singleton<DiomedesMenuManager>.Instance).gameObject);
			MenuManagerRefs.Instance.DisableUIPanel(MenuManagerRefs.Instance.menuButtons);
			MenuManagerRefs.Instance.DisableUIPanel(((Component)MenuManagerRefs.Instance.versionNumberText).gameObject);
			MenuManagerRefs.Instance.DisableUIPanel(((Component)this).gameObject);
		}
	}
	public class UI_PlayerNameplate : MonoBehaviour
	{
		[SerializeField]
		private RawImage _rawImage;

		[SerializeField]
		private TextMeshProUGUI _usernameText;

		private UserInfo _info;

		private ClientMatch _match;

		public event Action OnPlayerIconClick = delegate
		{
		};

		internal void Setup(ClientMatch match, UserInfo userInfo)
		{
			_match = match;
			_info = userInfo;
			UpdateUsername();
			match.OnNewHost += UpdateUsername;
			match.OnPlayerMovedCrew += UpdateUsername;
			match.OnNewCaptain += UpdateUsername;
		}

		private void OnDestroy()
		{
			if (_match != null)
			{
				_match.OnNewHost -= UpdateUsername;
				_match.OnPlayerMovedCrew -= UpdateUsername;
				_match.OnNewCaptain -= UpdateUsername;
			}
		}

		private void UpdateUsername()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			CrewInfo crewFor = _match.GetCrewFor(_info.UUID);
			DiomedesMenuManager.Logger.Debug<Color>("color: {CrewColor}", crewFor.Color.ToUnityColor());
			((TMP_Text)_usernameText).text = _info.Username;
			((Graphic)_rawImage).color = crewFor.Color.ToUnityColor();
			if (_match.HostUUID == _info.UUID)
			{
				TextMeshProUGUI usernameText = _usernameText;
				((TMP_Text)usernameText).text = ((TMP_Text)usernameText).text + " [HOST]";
			}
			if (crewFor.CaptainUUID == _info.UUID)
			{
				TextMeshProUGUI usernameText2 = _usernameText;
				((TMP_Text)usernameText2).text = ((TMP_Text)usernameText2).text + " [CAPTAIN]";
			}
		}

		public void PlayerIconClick()
		{
			this.OnPlayerIconClick();
		}
	}
	public class UI_Timer : MonoBehaviour
	{
		[SerializeField]
		private TextMeshProUGUI _text;

		[SerializeField]
		private string _textFormat = "Ends in: {0}";

		[SerializeField]
		private Slider _slider;

		private DateTime _startTime;

		private DateTime _endTime;

		public void SetTimes(DateTime startTime, DateTime endTime)
		{
			_startTime = startTime;
			_endTime = endTime;
		}

		private void Update()
		{
			_ = _endTime;
			_ = _startTime;
			if (Object.op_Implicit((Object)(object)_text))
			{
				((TMP_Text)_text).text = string.Format(_textFormat, DiomedesHelpers.ToDuration(DateTime.UtcNow - _endTime, (DurationFormat)0));
			}
			if (Object.op_Implicit((Object)(object)_slider))
			{
				_slider.value = DiomedesHelpers.GetProgress(_startTime, _endTime, DateTime.UtcNow);
			}
		}
	}
	public class UI_VersionNumber : MonoBehaviour
	{
		[SerializeField]
		private TMP_Text _versionText;

		private void Awake()
		{
			_versionText.text = "v0.9.0";
		}
	}
}
namespace Diomedes.Client.UI.Settings
{
	public enum SettingType
	{
		Text,
		StringInput,
		IntInput,
		BoolToggle,
		Dropdown,
		FloatInput
	}
	public abstract class AcceptableSettingType(string settingName)
	{
		protected static readonly ILogger _logger = DiomedesPlugin.SetupLogging<AcceptableSettingType>();

		private TextMeshProUGUI _nameText;

		public string SettingName { get; } = settingName;

		public abstract SettingType SettingType { get; }

		public abstract void RefreshUI();

		public virtual void SetupUI(GameObject gameObject)
		{
			_nameText = ((Component)gameObject.transform.Find("SettingName")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)_nameText).text = SettingName;
		}

		public abstract void Reset();
	}
	public abstract class AcceptableSettingType<T> : AcceptableSettingType
	{
		private T _previousValue;

		private T _value;

		private readonly T _defaultValue;

		protected AcceptableSettingType(string settingName, T value)
		{
			_previousValue = value;
			_value = value;
			_defaultValue = value;
			base..ctor(settingName);
		}

		public virtual void EditValue(T newValue)
		{
			_previousValue = _value;
			_value = newValue;
			RefreshUI();
			AcceptableSettingType._logger.Debug<string, T, T>("Edited {settingName} to {newValue} from {previousValue}", base.SettingName, newValue, _previousValue);
		}

		public T GetValue()
		{
			return _value;
		}

		public override void Reset()
		{
			EditValue(_defaultValue);
			RefreshUI();
		}

		public abstract void SubscribeToInputField(Action<T> callback);
	}
	public class DropdownMatchSetting : AcceptableSettingType<int>
	{
		private TMP_Dropdown _dropdownField;

		public override SettingType SettingType => SettingType.Dropdown;

		public DropdownMatchSetting(string settingName, IEnumerable<string> values)
		{
			<values>P = values;
			base..ctor(settingName, 0);
		}

		public static DropdownMatchSetting Create(string settingName, IEnumerable<string> values)
		{
			return new DropdownMatchSetting(settingName, values);
		}

		public override void RefreshUI()
		{
			if (_dropdownField.value != GetValue())
			{
				_dropdownField.value = GetValue();
			}
		}

		public override void SetupUI(GameObject gameObject)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			base.SetupUI(gameObject);
			_dropdownField = ((Component)gameObject.transform.Find("Dropdown")).GetComponent<TMP_Dropdown>();
			_dropdownField.options.Clear();
			foreach (string item in <values>P)
			{
				_dropdownField.options.Add(new OptionData(item));
			}
			RefreshUI();
		}

		public override void SubscribeToInputField(Action<int> callback)
		{
			((UnityEvent<int>)(object)_dropdownField.onValueChanged).AddListener((UnityAction<int>)wrappedAction);
			((UnityEvent<int>)(object)_dropdownField.onValueChanged).AddListener((UnityAction<int>)EditValueAction);
			void EditValueAction(int s)
			{
				EditValue(s);
			}
			void wrappedAction(int s)
			{
				callback(s);
			}
		}
	}
	public class FloatInputMatchSetting : AcceptableSettingType<float>
	{
		private TMP_InputField _inputField;

		public override SettingType SettingType => SettingType.FloatInput;

		public FloatInputMatchSetting(string settingName, float value, BoundedRange range)
		{
			<range>P = range;
			base..ctor(settingName, value);
		}

		public static FloatInputMatchSetting Create(string settingName, float value, BoundedRange range)
		{
			return new FloatInputMatchSetting(settingName, value, range);
		}

		public override void RefreshUI()
		{
			if (!(_inputField.text == GetValue().ToString()))
			{
				_inputField.text = GetValue().ToString();
				_inputField.SendOnSubmit();
			}
		}

		public override void EditValue(float newValue)
		{
			if (!<range>P.IsInRange(newValue))
			{
				if (newValue < <range>P.Min)
				{
					newValue = <range>P.Min;
				}
				else if (newValue > <range>P.Max)
				{
					newValue = <range>P.Max;
				}
			}
			base.EditValue(newValue);
		}

		public override void SetupUI(GameObject gameObject)
		{
			base.SetupUI(gameObject);
			_inputField = ((Component)gameObject.transform.Find("InputField")).GetComponent<TMP_InputField>();
			RefreshUI();
		}

		public override void SubscribeToInputField(Action<float> callback)
		{
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)wrappedAction);
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)editValueAction);
			void editValueAction(string s)
			{
				EditValue(float.Parse(s.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture));
			}
			void wrappedAction(string s)
			{
				callback(float.Parse(s.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture));
			}
		}
	}
	public class IntInputMatchSetting : AcceptableSettingType<int>
	{
		private TMP_InputField _inputField;

		public override SettingType SettingType => SettingType.IntInput;

		public IntInputMatchSetting(string settingName, int value, BoundedRange range)
		{
			<range>P = range;
			base..ctor(settingName, value);
		}

		public static IntInputMatchSetting Create(string settingName, int value, BoundedRange range)
		{
			return new IntInputMatchSetting(settingName, value, range);
		}

		public override void RefreshUI()
		{
			if (!(_inputField.text == GetValue().ToString()))
			{
				_inputField.text = GetValue().ToString();
				_inputField.SendOnSubmit();
			}
		}

		public override void EditValue(int newValue)
		{
			if (!<range>P.IsInRange((float)newValue))
			{
				if ((float)newValue < <range>P.Min)
				{
					newValue = (int)<range>P.Min;
				}
				else if ((float)newValue > <range>P.Max)
				{
					newValue = (int)<range>P.Max;
				}
			}
			base.EditValue(newValue);
		}

		public override void SetupUI(GameObject gameObject)
		{
			base.SetupUI(gameObject);
			_inputField = ((Component)gameObject.transform.Find("InputField")).GetComponent<TMP_InputField>();
			RefreshUI();
		}

		public override void SubscribeToInputField(Action<int> callback)
		{
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)wrappedAction);
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)editValueAction);
			void editValueAction(string s)
			{
				EditValue(int.Parse(s.Trim()));
			}
			void wrappedAction(string s)
			{
				callback(int.Parse(s.Trim()));
			}
		}
	}
	public class StringInputMatchSetting : AcceptableSettingType<string>
	{
		private TMP_InputField _inputField;

		public override SettingType SettingType => SettingType.StringInput;

		public StringInputMatchSetting(string settingName, string value)
			: base(settingName, value)
		{
		}

		public static StringInputMatchSetting Create(string settingName, string value)
		{
			return new StringInputMatchSetting(settingName, value);
		}

		public override void RefreshUI()
		{
			if (!(_inputField.text == GetValue()))
			{
				_inputField.text = GetValue();
				_inputField.SendOnSubmit();
			}
		}

		public override void SetupUI(GameObject gameObject)
		{
			base.SetupUI(gameObject);
			_inputField = ((Component)gameObject.transform.Find("InputField")).GetComponent<TMP_InputField>();
			RefreshUI();
		}

		public override void SubscribeToInputField(Action<string> callback)
		{
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)wrappedAction);
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener((UnityAction<string>)EditValueAction);
			void EditValueAction(string s)
			{
				EditValue(s);
			}
			void wrappedAction(string s)
			{
				callback(s);
			}
		}
	}
	public class TextMatchSetting : AcceptableSettingType<string>
	{
		private TextMeshProUGUI _textField;

		public override SettingType SettingType => SettingType.Text;

		public TextMatchSetting(string settingName, string value)
			: base(settingName, value)
		{
		}

		public static TextMatchSetting Create(string settingName, string value)
		{
			return new TextMatchSetting(settingName, value);
		}

		public override void RefreshUI()
		{
			if (!(((TMP_Text)_textField).text == GetValue()))
			{
				((TMP_Text)_textField).text = GetValue();
			}
		}

		public override void SetupUI(GameObject gameObject)
		{
			base.SetupUI(gameObject);
			_textField = ((Component)gameObject.transform.Find("SettingOption")).GetComponent<TextMeshProUGUI>();
			RefreshUI();
		}

		public override void SubscribeToInputField(Action<string> callback)
		{
		}
	}
	public class ToggleMatchSetting : AcceptableSettingType<bool>
	{
		private ToggleSwitch _toggleSwitch;

		public override SettingType SettingType => SettingType.BoolToggle;

		public ToggleMatchSetting(string settingName, bool value)
			: base(settingName, value)
		{
		}

		public static ToggleMatchSetting Create(string settingName, bool value)
		{
			return new ToggleMatchSetting(settingName, value);
		}

		public override void RefreshUI()
		{
			_toggleSwitch.SetStateAndStartAnimation(GetValue());
		}

		public override void SetupUI(GameObject gameObject)
		{
			base.SetupUI(gameObject);
			_toggleSwitch = ((Component)gameObject.transform.Find("ToggleSlider")).GetComponent<ToggleSwitch>();
			RefreshUI();
		}

		public override void SubscribeToInputField(Action<bool> callback)
		{
			((UnityEvent<bool>)_toggleSwitch.OnToggled).AddListener((UnityAction<bool>)wrappedAction);
			((UnityEvent<bool>)_toggleSwitch.OnToggled).AddListener((UnityAction<bool>)EditValueAction);
			void EditValueAction(bool s)
			{
				EditValue(s);
			}
			void wrappedAction(bool s)
			{
				callback(s);
			}
		}
	}
	public class ToggleEvent : UnityEvent<bool>
	{
	}
	[RequireComponent(typeof(Slider))]
	public class ToggleSwitch : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		[Header("Slider Value")]
		[SerializeField]
		[Range(0f, 1f)]
		protected float _sliderValue;

		protected Slider _slider;

		[Header("Animation")]
		[SerializeField]
		[Range(0f, 1f)]
		private float _animationDuration = 0.33f;

		[SerializeField]
		private AnimationCurve _slideEase = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);

		private Coroutine? _animateSliderCoroutine;

		private ToggleSwitchGroupManager _toggleSwitchGroupManager;

		protected Action _transitionEffect = delegate
		{
		};

		public bool CurrentValue { get; private set; }

		[field: Header("Event")]
		public ToggleEvent OnToggled { get; private set; } = new ToggleEvent();

		protected virtual void OnValidate()
		{
			SetupToggleComponents();
			_slider.value = _sliderValue;
		}

		private void SetupToggleComponents()
		{
			if (!((Object)(object)_slider != (Object)null))
			{
				SetupSliderComponent();
			}
		}

		[MemberNotNull("_slider")]
		private void SetupSliderComponent()
		{
			//IL_001e: 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_0026: 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)
			_slider = ((Component)this).GetComponent<Slider>();
			((Selectable)_slider).interactable = false;
			ColorBlock colors = ((Selectable)_slider).colors;
			((ColorBlock)(ref colors)).disabledColor = Color.white;
			((Selectable)_slider).colors = colors;
			((Selectable)_slider).transition = (Transition)0;
		}

		public void SetupForManager(ToggleSwitchGroupManager toggleSwitchGroupManager)
		{
			_toggleSwitchGroupManager = toggleSwitchGroupManager;
		}

		protected virtual void Awake()
		{
			SetupToggleComponents();
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			Toggle();
		}

		private void Toggle()
		{
			if ((Object)(object)_toggleSwitchGroupManager != (Object)null)
			{
				_toggleSwitchGroupManager.ToggleGroup(this);
			}
			else
			{
				SetStateAndStartAnimation(!CurrentValue);
			}
		}

		public void ToggleByGroupManager(bool valueToSetTo)
		{
			SetStateAndStartAnimation(valueToSetTo);
		}

		public void SetStateAndStartAnimation(bool valueToSetTo)
		{
			if (CurrentValue == valueToSetTo)
			{
				return;
			}
			CurrentValue = valueToSetTo;
			((UnityEvent<bool>)OnToggled).Invoke(CurrentValue);
			if (_animateSliderCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_animateSliderCoroutine);
				_animateSliderCoroutine = null;
			}
			if (!((Component)this).gameObject.activeInHierarchy)
			{
				if ((Object)(object)_slider == (Object)null)
				{
					SetupSliderComponent();
				}
				_slider.value = (CurrentValue ? 1f : 0f);
				_transitionEffect();
			}
			else
			{
				_animateSliderCoroutine = ((MonoBehaviour)this).StartCoroutine(AnimateSlider());
			}
		}

		private IEnumerator AnimateSlider()
		{
			float startValue = _slider.value;
			float endValue = (CurrentValue ? 1f : 0f);
			float time = 0f;
			if (_animationDuration > 0f)
			{
				while (time < _animationDuration)
				{
					time += Time.deltaTime;
					float num = _slideEase.Evaluate(time / _animationDuration);
					_slider.value = Mathf.Lerp(startValue, endValue, num);
					_transitionEffect();
					yield return null;
				}
			}
			_slider.value = endValue;
		}
	}
	public class ToggleSwitchColorChange : ToggleSwitch
	{
		[Header("Elements to Recolor")]
		[SerializeField]
		private Image _backgroundImage;

		[SerializeField]
		private Image _handleImage;

		[Space]
		[SerializeField]
		private bool _recolorBackground;

		[SerializeField]
		private bool _recolorHandle;

		[Header("Colors")]
		[SerializeField]
		private Color _backgroundColorOff = Color.white;

		[SerializeField]
		private Color _backgroundColorOn = Color.white;

		[Space]
		[SerializeField]
		private Color _handleColorOff = Color.white;

		[SerializeField]
		private Color _handleColorOn = Color.white;

		private bool _isBackgroundImageNotNull;

		private bool _isHandleImageNotNull;

		protected override void OnValidate()
		{
			base.OnValidate();
			CheckForNull();
			ChangeColors();
		}

		private void OnEnable()
		{
			_transitionEffect = (Action)Delegate.Combine(_transitionEffect, new Action(ChangeColors));
		}

		private void OnDisable()
		{
			_transitionEffect = (Action)Delegate.Remove(_transitionEffect, new Action(ChangeColors));
		}

		protected override void Awake()
		{
			base.Awake();
			CheckForNull();
			ChangeColors();
		}

		private void CheckForNull()
		{
			_isBackgroundImageNotNull = (Object)(object)_backgroundImage != (Object)null;
			_isHandleImageNotNull = (Object)(object)_handleImage != (Object)null;
		}

		private void ChangeColors()
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (_recolorBackground && _isBackgroundImageNotNull)
			{
				((Graphic)_backgroundImage).color = Color.Lerp(_backgroundColorOff, _backgroundColorOn, _slider.value);
			}
			if (_recolorHandle && _isHandleImageNotNull)
			{
				((Graphic)_handleImage).color = Color.Lerp(_handleColorOff, _handleColorOn, _slider.value);
			}
		}
	}
	public class ToggleSwitchGroupManager : MonoBehaviour
	{
		[Header("Start Value")]
		[SerializeField]
		private ToggleSwitch _initialToggleSwitch;

		[Header("Toggle Options")]
		[SerializeField]
		private bool _allCanBeToggledOff;

		private List<ToggleSwitch> _toggleSwitches = new List<ToggleSwitch>();

		private void Awake()
		{
			ToggleSwitch[] componentsInChildren = ((Component)this).GetComponentsInChildren<ToggleSwitch>();
			ToggleSwitch[] array = componentsInChildren;
			foreach (ToggleSwitch toggleSwitch in array)
			{
				RegisterToggleButtonToGroup(toggleSwitch);
			}
		}

		private void RegisterToggleButtonToGroup(ToggleSwitch toggleSwitch)
		{
			if (!_toggleSwitches.Contains(_initialToggleSwitch))
			{
				_toggleSwitches.Add(toggleSwitch);
				toggleSwitch.SetupForManager(this);
			}
		}

		private void Start()
		{
			bool flag = true;
			foreach (ToggleSwitch toggleSwitch in _toggleSwitches)
			{
				if (toggleSwitch.CurrentValue)
				{
					flag = false;
					break;
				}
			}
			if (flag && !_allCanBeToggledOff)
			{
				if ((Object)(object)_initialToggleSwitch != (Object)null)
				{
					_initialToggleSwitch.ToggleByGroupManager(valueToSetTo: true);
				}
				else
				{
					_toggleSwitches[0].ToggleByGroupManager(valueToSetTo: true);
				}
			}
		}

		public void ToggleGroup(ToggleSwitch toggleSwitch)
		{
			if (_toggleSwitches.Count <= 1)
			{
				return;
			}
			if (_allCanBeToggledOff && toggleSwitch.CurrentValue)
			{
				foreach (ToggleSwitch toggleSwitch2 in _toggleSwitches)
				{
					if (!((Object)(object)toggleSwitch2 == (Object)null))
					{
						toggleSwitch2.ToggleByGroupManager(valueToSetTo: false);
					}
				}
				return;
			}
			foreach (ToggleSwitch toggleSwitch3 in _toggleSwitches)
			{
				if (!((Object)(object)toggleSwitch3 == (Object)null))
				{
					if ((Object)(object)toggleSwitch3 == (Object)(object)toggleSwitch)
					{
						toggleSwitch3.ToggleByGroupManager(valueToSetTo: true);
					}
					else
					{
						toggleSwitch3.ToggleByGroupManager(valueToSetTo: false);
					}
				}
			}
		}
	}
	public class UI_MatchSettings : MonoBehaviour
	{
		[SerializeField]
		private Transform _content;

		[SerializeField]
		private GameObject _categoryPrefab;

		[SerializeField]
		private List<GameObject> _settingPrefabs;

		private Dictionary<string, int> _categoryToChildIndex = new Dictionary<string, int>();

		private Dictionary<string, List<AcceptableSettingType>> _categoryToSettings = new Dictionary<string, List<AcceptableSettingType>>();

		internal void Setup(ClientMatch match)
		{
			TransformExtensions.KillAllChildren(_content);
			_categoryToSettings.Clear();
			_categoryToChildIndex.Clear();
			if (!match.IsDaily)
			{
				match.GameMode.InitSettings(this);
			}
		}

		public void ResetAllSettings()
		{
			foreach (KeyValuePair<string, List<AcceptableSettingType>> categoryToSetting in _categoryToSettings)
			{
				foreach (AcceptableSettingType item in categoryToSetting.Value)
				{
					item.Reset();
				}
			}
		}

		public void CreateNewSetting<T>(string categoryName, AcceptableSettingType<T> settingValue, Action<T> callBack)
		{
			if (!_categoryToSettings.TryGetValue(categoryName, out List<AcceptableSettingType> value))
			{
				value = new List<AcceptableSettingType>();
				_categoryToSettings[categoryName] = value;
			}
			if (!_categoryToChildIndex.TryGetValue(categoryName, out var value2))
			{
				value2 = _content.childCount;
				_categoryToChildIndex[categoryName] = value2;
				((TMP_Text)Object.Instantiate<GameObject>(_categoryPrefab, _content).GetComponentInChildren<TextMeshProUGUI>()).text = categoryName;
			}
			int num = _content.childCount;
			foreach (KeyValuePair<string, int> item in _categoryToChildIndex)
			{
				if (!(item.Key == categoryName) && item.Value > value2 && item.Value < num)
				{
					num = item.Value;
				}
			}
			GameObject val = _settingPrefabs[(int)settingValue.SettingType];
			GameObject val2 = Object.Instantiate<GameObject>(val, _content);
			val2.transform.SetSiblingIndex(num);
			List<string> list = new List<string>(_categoryToChildIndex.Keys);
			foreach (string item2 in list)
			{
				if (_categoryToChildIndex[item2] >= num)
				{
					_categoryToChildIndex[item2]++;
				}
			}
			settingValue.SetupUI(val2);
			value.Add(settingValue);
			if (callBack != null)
			{
				settingValue.SubscribeToInputField(callBack);
			}
		}

		public bool TryGetSetting<T>(string categoryName, string settingName, [NotNullWhen(true)] out AcceptableSettingType<T>? acceptableSetting)
		{
			acceptableSetting = null;
			if (!_categoryToSettings.TryGetValue(categoryName, out List<AcceptableSettingType> value))
			{
				return false;
			}
			foreach (AcceptableSettingType item in value)
			{
				if (item.SettingName == settingName && item is AcceptableSettingType<T> acceptableSettingType)
				{
					acceptableSetting = acceptableSettingType;
					return true;
				}
			}
			return false;
		}
	}
}
namespace Diomedes.Client.UI.Bingo
{
	public class UI_BingoBoard : MonoBehaviour
	{
		[SerializeField]
		private UI_BingoSquare _squarePrefab;

		[SerializeField]
		private GameObject _rowPrefab;

		[SerializeField]
		private Transform _contentParent;

		internal void Setup(ClientBingoGame game)
		{
			TransformExtensions.KillAllChildren(_contentParent);
			DiomedesPlugin.Logger.Debug("Setting up bingo board, the following is null:");
			if (game == null)
			{
				DiomedesPlugin.Logger.Debug("Game is null");
			}
			else if (game.RealBoard != null)
			{
				OnReady();
			}
			else
			{
				game.OnBingoBoardReady += OnReady;
			}
			void OnReady()
			{
				game.OnBingoBoardReady -= OnReady;
				for (int i = 0; i < game.RealBoard.GetLength(0); i++)
				{
					GameObject val = Object.Instantiate<GameObject>(_rowPrefab, _contentParent);
					for (int j = 0; j < game.RealBoard.GetLength(1); j++)
					{
						UI_BingoSquare uI_BingoSquare = Object.Instantiate<UI_BingoSquare>(_squarePrefab, val.transform);
						uI_BingoSquare.Setup(game, game.RealBoard[i, j]);
					}
				}
			}
		}
	}
	public class UI_BingoSquare : MonoBehaviour
	{
		[SerializeField]
		private Image _carosuelImage;

		[SerializeField]
		private TMP_Text _text;

		[SerializeField]
		private Image _background;

		[SerializeField]
		private Color _localCrewCompletedTextColor;

		[SerializeField]
		private float _timeBetweenCarosuelImages = 1.5f;

		private BingoChallenge _challenge;

		private ClientBingoGame _game;

		private BingoUIState _state;

		private float _timeSinceLastImageOnCarousel;

		private int _currentIndex;

		internal void Setup(ClientBingoGame game, BingoChallenge challenge)
		{
			_game = game;
			_challenge = challenge;
			game.OnChallengeCompletedByCrew += OnChallengeCompletedByCrew;
			BingoUIState bingoUIState = challenge.CreateUI();
			_text.text = bingoUIState.Name;
			_state = bingoUIState;
			if (bingoUIState.CarosuelSprites.Count == 0)
			{
				((Behaviour)_carosuelImage).enabled = false;
				return;
			}
			_carosuelImage.sprite = bingoUIState.CarosuelSprites[0];
			_timeSinceLastImageOnCarousel = _timeBetweenCarosuelImages;
		}

		private void OnChallengeCompletedByCrew(CrewInfo crew, BingoChallenge challenge)
		{
			//IL_0028: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (_challenge == challenge)
			{
				Image val = Object.Instantiate<Image>(_background, ((Component)_background).transform);
				Color color = crew.Color.ToUnityColor();
				color.a = 0.3f;
				((Graphic)val).color = color;
				if (crew == _game.Match.LocalUserCrew)
				{
					((Graphic)_text).color = _localCrewCompletedTextColor;
				}
			}
		}

		private void OnDestroy()
		{
			_game.OnChallengeCompletedByCrew -= OnChallengeCompletedByCrew;
		}

		private void Update()
		{
			if (_state.CarosuelSprites.Count > 1)
			{
				_timeSinceLastImageOnCarousel -= Time.deltaTime;
				if (_timeSinceLastImageOnCarousel <= 0f)
				{
					_timeSinceLastImageOnCarousel = _timeBetweenCarosuelImages;
					_currentIndex = (_currentIndex + 1) % _state.CarosuelSprites.Count;
					_carosuelImage.sprite = _state.CarosuelSprites[_currentIndex];
				}
			}
		}
	}
}
namespace Diomedes.Client.Saves
{
	public class DiomedesSaveManager
	{
		private readonly int _maxSaves;

		private readonly IDataContainer _dataContainer;

		private ILogger _logger = DiomedesPlugin.SetupLogging<DiomedesSaveManager>();

		private Dictionary<int, SaveMetadata> _saves;

		public int SaveFileNum => -2;

		public DiomedesSaveManager(IDataContainer dataContainer, int maxSaves)
		{
			_dataContainer = dataContainer;
			_maxSaves = maxSaves;
			_saves = dataContainer.GetOrCreateDefault<Dictionary<int, SaveMetadata>>(DiomedesKeys.SaveDatabase);
		}

		public void DeleteAllSaves()
		{
			using (_dataContainer.CreateEditContext())
			{
				_logger.Warning("Deleting all diomedes saves!");
				foreach (SaveMetadata value in _saves.Values)
				{
					DeleteSave(value);
				}
			}
		}

		private void DeleteSave(SaveMetadata save)
		{
			ClearSave(save);
			_saves.Remove(save.ID);
			_dataContainer.Set<Dictionary<int, SaveMetadata>>(DiomedesKeys.SaveDatabase, _saves);
		}

		public void ClearSave(SaveMetadata save)
		{
			_logger.Information<string, string>("Deleting save: {SaveName} (created: {TimeCreated})", save.Name, save.Created.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture));
			ES3.DeleteFile(save.Name);
			PersistentDataContainer val = DawnNetworker.CreateContractContainer(save.Name);
			val.AutoSave = false;
			val.DeleteFile();
			((DataContainer)val).Clear();
			PersistentDataContainer val2 = DawnNetworker.CreateSaveContainer(save.Name);
			val2.AutoSave = false;
			val2.DeleteFile();
			((DataContainer)val2).Clear();
		}

		public void DoPrune()
		{
			using (_dataContainer.CreateEditContext())
			{
				_logger.Information("Checking for oldest saves to remove..");
				List<SaveMetadata> list = _saves.Values.OrderBy((SaveMetadata it) => it.Created).ToList();
				if (list.Count <= _maxSaves)
				{
					return;
				}
				_logger.Information<int, int, int>("{SortedSaveAmount} is more than the max allowed saves of {MaxSavesAmount}, deleting {NumberToDelete} saves!", list.Count, _maxSaves, list.Count - _maxSaves);
				foreach (SaveMetadata item in list.Take(list.Count - _maxSaves))
				{
					DeleteSave(item);
				}
			}
		}

		public void SetAsCurrentSave(SaveMetadata save)
		{
			GameNetworkManager.Instance.currentSaveFileName = save.Name;
			GameNetworkManager.Instance.saveFileNum = SaveFileNum;
		}

		public SaveMetadata GetOrCreateForMatch(int matchID)
		{
			if (_saves.TryGetValue(matchID, out SaveMetadata value))
			{
				return value;
			}
			value = new SaveMetadata($"DiomedesSave{matchID}", matchID, DateTime.UtcNow);
			_saves[matchID] = value;
			_dataContainer.Set<Dictionary<int, SaveMetadata>>(DiomedesKeys.SaveDatabase, _saves);
			return value;
		}
	}
	public record SaveMetadata(string Name, int ID, DateTime Created);
}
namespace Diomedes.Client.Providers
{
	public class DiomedesFreeMoonProvider(IProvider<int> original) : IProvider<int>
	{
		public int Provide()
		{
			ClientMatch? 

BepInEx/plugins/Diomedes/me.loaforc.phoebe.standardmod.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using IL;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("me.loaforc.phoebe.standardmod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+fb03b90e98b187d0176ed0294352f99dc9c97dd7")]
[assembly: AssemblyProduct("Phoebe.Standardization")]
[assembly: AssemblyTitle("me.loaforc.phoebe.standardmod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Phoebe.Standardization
{
	[BepInPlugin("me.loaforc.phoebe.standardmod", "Phoebe.Standardization", "0.1.0")]
	public class PhoebeStandardMod : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<Instruction, bool> <>9__6_3;

			public static Func<Instruction, bool> <>9__6_5;

			public static Func<Instruction, bool> <>9__6_6;

			public static Func<Instruction, bool> <>9__6_7;

			public static Func<Instruction, bool> <>9__6_8;

			public static hook_GetRandomWeightedIndex <>9__6_1;

			public static hook_GetRandomWeightedIndexList <>9__6_2;

			internal bool <Awake>b__6_3(Instruction i)
			{
				return ILPatternMatchingExt.MatchLdstr(i, "Number of scrap to spawn: {0}. minTotalScrapValue: {1}. Total value of items: {2}.");
			}

			internal bool <Awake>b__6_5(Instruction i)
			{
				return ILPatternMatchingExt.MatchLdloc(i, 18);
			}

			internal bool <Awake>b__6_6(Instruction i)
			{
				return ILPatternMatchingExt.MatchLdcR4(i, 0f);
			}

			internal bool <Awake>b__6_7(Instruction i)
			{
				return ILPatternMatchingExt.MatchStfld<GrabbableObject>(i, "fallTime");
			}

			internal bool <Awake>b__6_8(Instruction i)
			{
				return ILPatternMatchingExt.MatchLdloc(i, 4);
			}

			internal int <Awake>b__6_1(orig_GetRandomWeightedIndex orig, RoundManager self, int[] weights, Random randomSeed)
			{
				if (randomSeed == null)
				{
					randomSeed = self.AnomalyRandom;
				}
				return GetRandomIndexWeightedFixed(weights, randomSeed);
			}

			internal int <Awake>b__6_2(orig_GetRandomWeightedIndexList orig, RoundManager self, List<int> weights, Random randomSeed)
			{
				if (randomSeed == null)
				{
					randomSeed = self.AnomalyRandom;
				}
				return GetRandomIndexWeightedFixed(weights, randomSeed);
			}
		}

		private List<int> _overwrittenValues = new List<int>();

		internal static ManualLogSource Logger { get; private set; }

		public static int GetRandomIndexWeightedFixed(IList<int> weights, Random randomSeed)
		{
			if (weights.Count == 0)
			{
				throw new ArgumentException("Weights cannot be empty!", "weights");
			}
			int num = 0;
			foreach (int weight in weights)
			{
				if (weight >= 0)
				{
					num += weight;
				}
			}
			if (weights.Count == 1)
			{
				return 0;
			}
			if (num <= 0)
			{
				return randomSeed.Next(0, weights.Count);
			}
			double num2 = randomSeed.NextDouble();
			double num3 = 0.0;
			for (int i = 0; i < weights.Count; i++)
			{
				if (weights[i] > 0)
				{
					num3 += (double)weights[i] / (double)num;
					if (num3 >= num2)
					{
						return i;
					}
				}
			}
			Logger.LogError((object)$"Still went onto fallback, oh no! Seed = {StartOfRound.Instance.randomMapSeed}");
			return randomSeed.Next(0, weights.Count);
		}

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0054: 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_005f: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			RoundManager.SpawnScrapInLevel += (Manipulator)delegate(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_015d: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val3 = new ILCursor(il);
				val3.GotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdstr(i, "Number of scrap to spawn: {0}. minTotalScrapValue: {1}. Total value of items: {2}.")
				});
				val3.Emit(OpCodes.Ldloc_0);
				val3.Emit(OpCodes.Ldfld, AccessTools.Field(AccessTools.Inner(typeof(RoundManager), "<>c__DisplayClass154_0"), "ScrapToSpawn"));
				val3.Emit(OpCodes.Ldloc_2);
				val3.EmitDelegate<Action<List<Item>, int>>((Action<List<Item>, int>)delegate(List<Item> scrapToSpawn, int sidItemIndex)
				{
					_overwrittenValues.Clear();
					foreach (Item item in scrapToSpawn)
					{
						int num2 = (int)((float)RoundManager.Instance.AnomalyRandom.Next(item.minValue, item.maxValue) * RoundManager.Instance.scrapValueMultiplier);
						if (sidItemIndex != -1)
						{
							num2 = Mathf.Clamp(num2, 50, 170);
						}
						_overwrittenValues.Add(num2);
					}
				});
				val3.GotoNext((MoveType)2, new Func<Instruction, bool>[3]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 18),
					(Instruction i) => ILPatternMatchingExt.MatchLdcR4(i, 0f),
					(Instruction i) => ILPatternMatchingExt.MatchStfld<GrabbableObject>(i, "fallTime")
				});
				int index = val3.Index;
				val3.GotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 4)
				});
				int num = val3.Index - index;
				val3.Index = index;
				val3.RemoveRange(num);
				val3.Emit(OpCodes.Ldloc, 3);
				val3.Emit(OpCodes.Ldloc, 17);
				val3.Emit(OpCodes.Ldfld, AccessTools.Field(AccessTools.Inner(typeof(RoundManager), "<>c__DisplayClass154_1"), "i"));
				val3.EmitDelegate<Action<List<int>, int>>((Action<List<int>, int>)delegate(List<int> scrapValues, int i)
				{
					scrapValues.Add(_overwrittenValues[i]);
				});
			};
			object obj = <>c.<>9__6_1;
			if (obj == null)
			{
				hook_GetRandomWeightedIndex val = delegate(orig_GetRandomWeightedIndex orig, RoundManager self, int[] weights, Random randomSeed)
				{
					if (randomSeed == null)
					{
						randomSeed = self.AnomalyRandom;
					}
					return GetRandomIndexWeightedFixed(weights, randomSeed);
				};
				<>c.<>9__6_1 = val;
				obj = (object)val;
			}
			RoundManager.GetRandomWeightedIndex += (hook_GetRandomWeightedIndex)obj;
			object obj2 = <>c.<>9__6_2;
			if (obj2 == null)
			{
				hook_GetRandomWeightedIndexList val2 = delegate(orig_GetRandomWeightedIndexList orig, RoundManager self, List<int> weights, Random randomSeed)
				{
					if (randomSeed == null)
					{
						randomSeed = self.AnomalyRandom;
					}
					return GetRandomIndexWeightedFixed(weights, randomSeed);
				};
				<>c.<>9__6_2 = val2;
				obj2 = (object)val2;
			}
			RoundManager.GetRandomWeightedIndexList += (hook_GetRandomWeightedIndexList)obj2;
			Logger.LogInfo((object)"me.loaforc.phoebe.standardmod v0.1.0 has loaded!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "me.loaforc.phoebe.standardmod";

		public const string PLUGIN_NAME = "Phoebe.Standardization";

		public const string PLUGIN_VERSION = "0.1.0";
	}
}