Decompiled source of MimesisPlayerEnhancement v26.8.2

MimesisPlayerEnhancement.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Bifrost.ConstEnum;
using Bifrost.Cooked;
using Cysharp.Threading.Tasks;
using DLAgent;
using DunGen;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using FishySteamworks.Server;
using HarmonyLib;
using MelonLoader;
using MelonLoader.InternalUtils;
using MelonLoader.Logging;
using MelonLoader.Pastel;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using MimesisPlayerEnhancement;
using MimesisPlayerEnhancement.Config;
using MimesisPlayerEnhancement.Config.HostConfigSync;
using MimesisPlayerEnhancement.Config.Models;
using MimesisPlayerEnhancement.Config.QuickSettings;
using MimesisPlayerEnhancement.Features.DungeonRandomizer;
using MimesisPlayerEnhancement.Features.DungeonRandomizer.Patches;
using MimesisPlayerEnhancement.Features.DungeonTime;
using MimesisPlayerEnhancement.Features.Economy;
using MimesisPlayerEnhancement.Features.ExtendedSaveSlots;
using MimesisPlayerEnhancement.Features.JoinAnytime;
using MimesisPlayerEnhancement.Features.LootMultiplicator;
using MimesisPlayerEnhancement.Features.LootMultiplicator.Patches;
using MimesisPlayerEnhancement.Features.MimicTuning;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicEmoteProps;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicHorn;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicInventoryCopy;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicPossession;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicSocial;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicTrust;
using MimesisPlayerEnhancement.Features.MimicTuning.MimicVoiceTuning;
using MimesisPlayerEnhancement.Features.MimicTuning.Patches;
using MimesisPlayerEnhancement.Features.ModVersionDisplay;
using MimesisPlayerEnhancement.Features.MorePlayers;
using MimesisPlayerEnhancement.Features.MoreVoices;
using MimesisPlayerEnhancement.Features.Persistence;
using MimesisPlayerEnhancement.Features.Persistence.Patches;
using MimesisPlayerEnhancement.Features.PlayerAnnouncements;
using MimesisPlayerEnhancement.Features.PlayerTuning;
using MimesisPlayerEnhancement.Features.Privacy;
using MimesisPlayerEnhancement.Features.SavegamePreparation;
using MimesisPlayerEnhancement.Features.SpawnScaling;
using MimesisPlayerEnhancement.Features.Statistics;
using MimesisPlayerEnhancement.Features.Statistics.Models;
using MimesisPlayerEnhancement.Features.UserInterface;
using MimesisPlayerEnhancement.Features.UserInterface.CustomLoadingScreen;
using MimesisPlayerEnhancement.Features.UserInterface.DiscoBallSound;
using MimesisPlayerEnhancement.Features.UserInterface.FpsUi;
using MimesisPlayerEnhancement.Features.UserInterface.InGameMenuPlayerList;
using MimesisPlayerEnhancement.Features.UserInterface.InventoryNumberKeys;
using MimesisPlayerEnhancement.Features.UserInterface.InventorySlotOptimization;
using MimesisPlayerEnhancement.Features.UserInterface.LoadingWaitMovementLock;
using MimesisPlayerEnhancement.Features.UserInterface.LoadingWaitPlayerList;
using MimesisPlayerEnhancement.Features.UserInterface.RoundStartSound;
using MimesisPlayerEnhancement.Features.UserInterface.SpectatorPlayerList;
using MimesisPlayerEnhancement.Features.UserInterface.SpectatorVoiceBalance;
using MimesisPlayerEnhancement.Features.UserInterface.SurvivalResultPlayerList;
using MimesisPlayerEnhancement.Features.UserInterface.VoiceNoiseGate;
using MimesisPlayerEnhancement.Features.UserInterface.WorldOverlays;
using MimesisPlayerEnhancement.Features.Weather;
using MimesisPlayerEnhancement.Features.WebDashboard;
using MimesisPlayerEnhancement.Features.WebDashboard.Debug;
using MimesisPlayerEnhancement.Features.WebDashboard.Models;
using MimesisPlayerEnhancement.Ui;
using MimesisPlayerEnhancement.Ui.MenuMirror;
using MimesisPlayerEnhancement.Util;
using MimesisPlayerEnhancement.Util.Patches;
using MimesisPlayerEnhancement.Util.Players;
using Mimic;
using Mimic.Actors;
using Mimic.Animation;
using Mimic.Audio;
using Mimic.InputSystem;
using Mimic.Voice;
using Mimic.Voice.SpeechSystem;
using ModUtility;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using ReluProtocol;
using ReluProtocol.C2S;
using ReluProtocol.Enum;
using ReluReplay;
using ReluReplay.Data;
using ReluReplay.Recorder;
using ReluReplay.Serializer;
using ReluReplay.Shared;
using ReluServerBase.Threading;
using Steamworks;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "MimesisPlayerEnhancement", "26.8.2", "kalle", null)]
[assembly: MelonGame("ReLUGames", "MIMESIS")]
[assembly: HarmonyDontPatchAll]
[assembly: InternalsVisibleTo("MimesisPlayerEnhancement.Tests")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
[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();
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

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

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

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

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	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 new Enumerator(_item);
	}

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

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

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

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

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

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	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;
		}
	}
}
namespace MimesisPlayerEnhancement
{
	internal static class GlobalConfigStore
	{
		private const string Feature = "GlobalConfig";

		private static SparseTomlConfig.Document? _pendingDoc;

		private static bool _pendingDocLoaded;

		private static bool _dirty;

		internal static bool IsDirty => _dirty;

		internal static bool HasPendingDocument
		{
			get
			{
				if (_pendingDocLoaded)
				{
					return _pendingDoc != null;
				}
				return false;
			}
		}

		internal static SparseTomlConfig.Document Load()
		{
			if (string.IsNullOrEmpty(ModConfig.FilePath))
			{
				return new SparseTomlConfig.Document();
			}
			return SparseTomlConfig.Load(AtomicFileIO.ReadText(ModConfig.FilePath, "GlobalConfig"));
		}

		internal static bool TryWriteValue(string sectionId, string key, string normalized, out string? error, bool waitForCompletion = false)
		{
			error = null;
			if (!ModConfig.IsInitialized)
			{
				error = "Configuration is not initialized.";
				return false;
			}
			if (string.IsNullOrEmpty(ModConfig.FilePath))
			{
				error = "Global config path unavailable.";
				return false;
			}
			if (!ModConfigRegistry.TryGetEntry(sectionId, key, out MelonPreferences_Entry entry) || entry == null)
			{
				error = "Unknown setting.";
				return false;
			}
			string rawB = ModConfigRegistry.FormatEntryDefaultValue(entry);
			EnsurePendingDoc();
			SparseTomlConfig.Document pendingDoc = _pendingDoc;
			if (ModConfigRegistry.RawValuesEqual(sectionId, key, normalized, rawB))
			{
				RemoveKey(pendingDoc, sectionId, key);
			}
			else
			{
				EnsureSection(pendingDoc, sectionId);
				pendingDoc.Sections[sectionId][key] = normalized;
			}
			_dirty = true;
			return true;
		}

		internal static void RebuildPendingFromMemory()
		{
			if (!ModConfig.IsInitialized || SaveSlotConfigStore.IsApplyingOverrides || HostConfigMirror.BlocksGlobalConfigPersistence || _dirty)
			{
				return;
			}
			SparseTomlConfig.Document document = new SparseTomlConfig.Document();
			foreach (string item in ModConfigRegistry.GetSectionOrder())
			{
				foreach (string item2 in ModConfigRegistry.GetEntryOrder(item))
				{
					if (ModConfigRegistry.TryGetEntry(item, item2, out MelonPreferences_Entry entry) && entry != null)
					{
						string text = ModConfigRegistry.FormatEntryValue(entry);
						string rawB = ModConfigRegistry.FormatEntryDefaultValue(entry);
						if (!ModConfigRegistry.RawValuesEqual(item, item2, text, rawB))
						{
							EnsureSection(document, item);
							document.Sections[item][item2] = text;
						}
					}
				}
			}
			_pendingDoc = document;
			_pendingDocLoaded = true;
			_dirty = true;
		}

		internal static void FlushIfDirty()
		{
			if (_dirty)
			{
				ModLog.Debug("GlobalConfig", "Flushing pending global config before reload.");
				FlushToDisk();
			}
		}

		internal static void RestorePendingToDisk()
		{
			if (HasPendingDocument)
			{
				ModLog.Debug("GlobalConfig", "Restoring pending global config after MelonLoader save.");
				FlushToDisk(waitForCompletion: true, force: true);
			}
		}

		internal static void FlushToDisk(bool waitForCompletion = true, bool force = false)
		{
			if (!ModConfig.IsInitialized || string.IsNullOrEmpty(ModConfig.FilePath) || (!force && !_dirty))
			{
				return;
			}
			if (!_pendingDocLoaded || _pendingDoc == null)
			{
				if (!force)
				{
					_dirty = false;
				}
				return;
			}
			try
			{
				string directoryName = Path.GetDirectoryName(ModConfig.FilePath);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				if (SparseTomlConfig.IsEmpty(_pendingDoc) && File.Exists(ModConfig.FilePath))
				{
					AtomicFileIO.Delete(ModConfig.FilePath, "GlobalConfig");
				}
				else if (!SparseTomlConfig.IsEmpty(_pendingDoc))
				{
					AtomicFileIO.WriteText(ModConfig.FilePath, SparseTomlConfig.Serialize(_pendingDoc), "GlobalConfig");
				}
				_dirty = false;
			}
			catch (Exception ex)
			{
				ModLog.Error("GlobalConfig", "FlushToDisk: " + ex.Message);
			}
		}

		private static void EnsurePendingDoc()
		{
			if (!_pendingDocLoaded)
			{
				_pendingDoc = Load();
				_pendingDocLoaded = true;
			}
		}

		private static void EnsureSection(SparseTomlConfig.Document doc, string sectionId)
		{
			if (!doc.Sections.ContainsKey(sectionId))
			{
				doc.SectionOrder.Add(sectionId);
				doc.Sections[sectionId] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			}
		}

		private static void RemoveKey(SparseTomlConfig.Document doc, string sectionId, string key)
		{
			if (doc.Sections.TryGetValue(sectionId, out Dictionary<string, string> value))
			{
				value.Remove(key);
				if (value.Count == 0)
				{
					doc.Sections.Remove(sectionId);
					doc.SectionOrder.Remove(sectionId);
				}
			}
		}
	}
	public static class ModConfig
	{
		private const string MainCategoryId = "MimesisPlayerEnhancement";

		private static readonly List<MelonPreferences_Entry<float>> FloatEntries = new List<MelonPreferences_Entry<float>>();

		public static int Version => ModConfigRegistry.Version;

		public static bool IsInitialized { get; private set; }

		public static string FilePath { get; private set; } = "";

		public static MelonPreferences_Category MainCategory { get; private set; } = null;

		public static MelonPreferences_Entry<bool> EnableMorePlayers { get; internal set; } = null;

		public static MelonPreferences_Entry<int> MaxPlayers { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableScalingRoundGoals { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> OverrideMaxStageCount { get; internal set; } = null;

		public static MelonPreferences_Entry<float> RoundGoalBasePerZone { get; internal set; } = null;

		public static MelonPreferences_Entry<float> RoundGoalMoneyMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<int> RoundGoalRandomSpreadPercent { get; internal set; } = null;

		public static MelonPreferences_Entry<float> RoundGoalCurveExponent { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableMoreVoices { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> UnifyIndoorOutdoorVoices { get; internal set; } = null;

		public static MelonPreferences_Entry<int> MaxIndoorVoiceEvents { get; internal set; } = null;

		public static MelonPreferences_Entry<int> MaxDeathMatchVoiceEvents { get; internal set; } = null;

		public static MelonPreferences_Entry<int> MaxOutdoorVoiceEvents { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RecordVoiceInMaintenance { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RecordVoiceInTram { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RecordVoiceDuringMimicPossession { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableVoicePerformanceCache { get; internal set; } = null;

		public static MelonPreferences_Entry<int> VoiceClipCacheMaxEntries { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnablePersistence { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableStatistics { get; internal set; } = null;

		public static MelonPreferences_Entry<int> SessionReconnectGraceMinutes { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> ShowStatisticsToasts { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> ShowPlayerAnnouncements { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableJoinAnytime { get; internal set; } = null;

		public static MelonPreferences_Entry<int> JoinConnectionGraceSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableSpawnScaling { get; internal set; } = null;

		public static MelonPreferences_Entry<int> SpawnScalingBaselinePlayerCount { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicSpawnMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicSpawnPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> BossSpawnMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> BossSpawnPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntSpawnMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntSpawnPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> SpecialSpawnMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> SpecialSpawnPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrapSpawnMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrapSpawnPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<string> TrapRespawnMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrapRespawnDelaySeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrapRespawnDelayMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrapRespawnDelayMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrapRespawnMinPlayerDistanceMeters { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicWaveMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicWaveInitialDelaySeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicWaveInitialDelayMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicWaveInitialDelayMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicWaveIntervalSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicWaveIntervalMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicWaveIntervalMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<string> GruntWaveMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntWaveInitialDelaySeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntWaveInitialDelayMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntWaveInitialDelayMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntWaveIntervalSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntWaveIntervalMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> GruntWaveIntervalMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> BonusEncounterDelayMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> BonusEncounterDelayMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> BonusEncounterMinPlayerDistanceMeters { get; internal set; } = null;

		public static MelonPreferences_Entry<float> OtherSpawnMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> OtherSpawnPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableLootMultiplicator { get; internal set; } = null;

		public static MelonPreferences_Entry<int> LootMultiplicatorBaselinePlayerCount { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MapLootMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MapLootPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> DropLootMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> DropLootPerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<string> LootItemFilterMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> LootAllowlist { get; internal set; } = null;

		public static MelonPreferences_Entry<string> LootBlocklist { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> AutoScaleMapLootBudgetForFilter { get; internal set; } = null;

		public static MelonPreferences_Entry<int> ConvertFakeActorDyingDropChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableEconomy { get; internal set; } = null;

		public static MelonPreferences_Entry<int> EconomyBaselinePlayerCount { get; internal set; } = null;

		public static MelonPreferences_Entry<int> StartupMoney { get; internal set; } = null;

		public static MelonPreferences_Entry<int> StartingZone { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableUpgradeTramHorn { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableUpgradeScrapScanner { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableUpgradeTramBooster { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableUpgradeTramLight { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ScrapSellValueMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ScrapSellValuePerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ShopBuyPriceMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ShopBuyPricePerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<int> ShopDiscountMinPercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> ShopDiscountMaxPercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> ShopDiscountChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ReinforcePriceMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ReinforcePricePerPlayerMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RetainUnspentCurrencyBetweenCycles { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableDungeonTime { get; internal set; } = null;

		public static MelonPreferences_Entry<int> DungeonTimeBaselinePlayerCount { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ExtraShiftSecondsPerPlayerAboveBaseline { get; internal set; } = null;

		public static MelonPreferences_Entry<string> StartTimePreset { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TimeMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableRealtimeTramClock { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableMimicPossessionTuning { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RandomizeMimicPossessionDuration { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicPossessionMinTimeSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicPossessionMaxTimeSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicPossessionCooltimeMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableMimicTuning { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicVoiceTuningMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PeriodicVoiceIntervalMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<int> PlayerVoiceResponseChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PlayerVoiceResponseCooldownSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PlayerVoiceResponseDelayMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PlayerVoiceResponseDelayMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PlayerVoiceResponseMaxDistance { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicInventoryCopyMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicInventoryCopyPickRule { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ClipReuseCooldownSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> DeathMatchClipReuseCooldownSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> SpeakAudienceRangeMeters { get; internal set; } = null;

		public static MelonPreferences_Entry<string> PostReplyIntervalMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PostReplyIntervalFixedSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PostReplyIntervalMinSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PostReplyIntervalMaxSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<int> MinRequiredSpeechClips { get; internal set; } = null;

		public static MelonPreferences_Entry<string> HearOwnVoiceFromMimic { get; internal set; } = null;

		public static MelonPreferences_Entry<string> VoiceInitIntervalMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoiceInitIntervalMin { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoiceInitIntervalMax { get; internal set; } = null;

		public static MelonPreferences_Entry<string> VoicePeriodicIntervalMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoicePeriodicIntervalMin { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoicePeriodicIntervalMax { get; internal set; } = null;

		public static MelonPreferences_Entry<string> VoiceDeathMatchIntervalMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoiceDeathMatchIntervalMin { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoiceDeathMatchIntervalMax { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicTrustMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustOutdoorMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustLookingDelta { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustNotLookingDelta { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustApproachDelta { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustMaintainDelta { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustWalkAwayDelta { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustSprintAwayDelta { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustHitDamageMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustFriendlyThreshold { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustDistrustThreshold { get; internal set; } = null;

		public static MelonPreferences_Entry<string> TrustScoreValueMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustInitialFixed { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustInitialRandomMin { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustInitialRandomMax { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustBehaviorFixed { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustBehaviorRandomMin { get; internal set; } = null;

		public static MelonPreferences_Entry<float> TrustBehaviorRandomMax { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ChaseActivationDistanceMeters { get; internal set; } = null;

		public static MelonPreferences_Entry<float> ChaseForceRunDistanceMeters { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicSocialMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MimicRunawayChance { get; internal set; } = null;

		public static MelonPreferences_Entry<int> JumpCopyChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> SlotFollowChangeChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<float> PossessionRangeMeters { get; internal set; } = null;

		public static MelonPreferences_Entry<string> PossessionBtGateMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> MimicEmotePropsMode { get; internal set; } = null;

		public static MelonPreferences_Entry<int> EmoteRespondChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> EmoteSuggestChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> ReactToSprinklerChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> UseTrapSwitchChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> UseChargerChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> UseTransmitterChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<int> UseShutterSwitchChancePercent { get; internal set; } = null;

		public static MelonPreferences_Entry<string> HornImitationMode { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> AllowHornImitation { get; internal set; } = null;

		public static MelonPreferences_Entry<float> HornMaxRecordSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> HornRecordingGapSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<int> HornMaxStoredRecords { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnablePlayerTuning { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MoveSpeedMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> NoClipSpeedMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MaxStaminaMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> StaminaDrainMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> StaminaRegenMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> StaminaRegenDelayMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<float> MaxCarryWeightMultiplier { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> DisablePlayerCollision { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableDungeonRandomizer { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RandomizeDungeonPick { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DungeonPickPoolMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DungeonAllowlist { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DungeonBlocklist { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> IgnoreDungeonExcludeList { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> RandomizeMapVariant { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DungeonSeedFlavor { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableWeather { get; internal set; } = null;

		public static MelonPreferences_Entry<string> WeatherMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> FixedWeatherPreset { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> DisableRandomWeather { get; internal set; } = null;

		public static MelonPreferences_Entry<string> WeatherCyclePresets { get; internal set; } = null;

		public static MelonPreferences_Entry<float> WeatherCycleMinDelaySeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<float> WeatherCycleMaxDelaySeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<string> WebDashboardListenAddress { get; internal set; } = null;

		public static MelonPreferences_Entry<int> WebDashboardListenPort { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableDebugLogging { get; private set; } = null;

		public static MelonPreferences_Entry<string> LastSeenModVersion { get; private set; } = null;

		public static MelonPreferences_Entry<float> ModToastDurationSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableExtendedSaveSlots { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableExtendedSpectatorPlayerList { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableLoadingWaitPlayerList { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableExtendedInGameMenuPlayerList { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableDamageHealthGlow { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableFloatingDamageNumbers { get; internal set; } = null;

		public static MelonPreferences_Entry<float> FloatingDamageDurationSeconds { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableFpsUi { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableFpsUiInventoryNetWorth { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableInventorySlotOptimization { get; internal set; } = null;

		public static MelonPreferences_Entry<string> InventoryPickupSelectMode { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableInventorySelectNextOnRemove { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableInventoryNumberKeySelection { get; internal set; } = null;

		public static MelonPreferences_Entry<string> RoundStartSoundMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> RoundStartSoundVariant { get; internal set; } = null;

		public static MelonPreferences_Entry<string> RoundStartSoundRandomPool { get; internal set; } = null;

		public static MelonPreferences_Entry<float> RoundStartSoundVolume { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DiscoBallSoundMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DiscoBallSoundVariant { get; internal set; } = null;

		public static MelonPreferences_Entry<string> DiscoBallSoundRandomPool { get; internal set; } = null;

		public static MelonPreferences_Entry<float> DiscoBallSoundVolume { get; internal set; } = null;

		public static MelonPreferences_Entry<string> CustomLoadingScreenMode { get; internal set; } = null;

		public static MelonPreferences_Entry<string> CustomLoadingScreenVariant { get; internal set; } = null;

		public static MelonPreferences_Entry<string> CustomLoadingScreenRandomPool { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> CustomLoadingScreenMotion { get; internal set; } = null;

		public static MelonPreferences_Entry<string> SpectatorVoiceBalanceMode { get; internal set; } = null;

		public static MelonPreferences_Entry<float> SpectatorVoiceAttenuation { get; internal set; } = null;

		public static MelonPreferences_Entry<float> SpectatorVoiceDuckLevel { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnableVoiceNoiseGate { get; internal set; } = null;

		public static MelonPreferences_Entry<float> VoiceNoiseGateStrength { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> EnablePrivacy { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> BlockReluTelemetry { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> BlockReplayUpload { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> BlockReplayRecording { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> BlockCrashReports { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> StripCrashReportMetadata { get; internal set; } = null;

		public static MelonPreferences_Entry<bool> BlockKraftonGppSdk { get; internal set; } = null;

		public static event Action<ModConfigChangeInfo>? Changed
		{
			add
			{
				ModConfigChangeTracker.Changed += value;
			}
			remove
			{
				ModConfigChangeTracker.Changed -= value;
			}
		}

		internal static void TrackFloatEntry(MelonPreferences_Entry<float> entry)
		{
			FloatEntries.Add(entry);
		}

		public static void Initialize(Instance logger)
		{
			ModConfigRegistry.ClearRegistrationOrder();
			FilePath = Path.Combine(MelonEnvironment.UserDataDirectory, "MimesisPlayerEnhancement.cfg");
			SparseTomlConfig.RepairTomletCompatibility(FilePath);
			MainCategory = CreateCategory("MimesisPlayerEnhancement");
			PrivacyConfig.CreateCategory();
			UiConfig.CreateCategory();
			SavegamePreparationConfig.CreateCategory();
			JoinAnytimeConfig.CreateCategory();
			MorePlayersConfig.CreateCategory();
			MoreVoicesConfig.CreateCategory();
			PersistenceConfig.CreateCategory();
			PlayerAnnouncementsConfig.CreateCategory();
			StatisticsConfig.CreateCategory();
			DungeonTimeConfig.CreateCategory();
			EconomyConfig.CreateCategory();
			LootMultiplicatorConfig.CreateCategory();
			SpawnScalingConfig.CreateCategory();
			DungeonRandomizerConfig.CreateCategory();
			MimicTuningConfig.CreateCategory();
			PlayerTuningConfig.CreateCategory();
			WeatherConfig.CreateCategory();
			WebDashboardConfig.CreateCategory();
			EnableDebugLogging = CreateTrackedEntry(MainCategory, "EnableDebugLogging", defaultValue: false);
			LastSeenModVersion = CreateHiddenTrackedEntry(MainCategory, "LastSeenModVersion", string.Empty);
			PrivacyConfig.CreateEntries();
			UiConfig.CreateEntries();
			SavegamePreparationConfig.CreateEntries();
			JoinAnytimeConfig.CreateEntries();
			MorePlayersConfig.CreateEntries();
			MoreVoicesConfig.CreateEntries();
			PersistenceConfig.CreateEntries();
			PlayerAnnouncementsConfig.CreateEntries();
			StatisticsConfig.CreateEntries();
			DungeonTimeConfig.CreateEntries();
			EconomyConfig.CreateEntries();
			LootMultiplicatorConfig.CreateEntries();
			SpawnScalingConfig.CreateEntries();
			DungeonRandomizerConfig.CreateEntries();
			MimicTuningConfig.CreateEntries();
			PlayerTuningConfig.CreateEntries();
			WeatherConfig.CreateEntries();
			WebDashboardConfig.CreateEntries();
			MorePlayersConfig.SanitizeInitialValues(logger);
			JoinAnytimeConfig.SanitizeInitialValues(logger);
			EconomyConfig.SanitizeInitialValues(logger);
			DungeonRandomizerConfig.SanitizeInitialValues(logger);
			DungeonTimeConfig.SanitizeInitialValues(logger);
			WeatherConfig.SanitizeInitialValues(logger);
			MorePlayersConfig.WireValidation(logger);
			MoreVoicesConfig.WireValidation(logger);
			PersistenceConfig.WireValidation();
			StatisticsConfig.WireValidation(logger);
			PlayerAnnouncementsConfig.WireValidation();
			JoinAnytimeConfig.WireValidation(logger);
			SpawnScalingConfig.WireValidation(logger);
			LootMultiplicatorConfig.WireValidation(logger);
			EconomyConfig.WireValidation(logger);
			SavegamePreparationConfig.WireValidation(logger);
			DungeonTimeConfig.WireValidation(logger);
			MimicTuningConfig.WireValidation();
			PlayerTuningConfig.WireValidation(logger);
			DungeonRandomizerConfig.WireValidation(logger);
			WeatherConfig.WireValidation(logger);
			WebDashboardConfig.WireValidation(logger);
			UiConfig.WireValidation(logger);
			PrivacyConfig.WireValidation();
			((MelonEventBase<LemonAction<bool, bool>>)(object)EnableDebugLogging.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate
			{
				NotifyChanged((MelonPreferences_Entry)(object)EnableDebugLogging);
			}, 0, false);
			RegisterFloatEntries();
			ModConfigFloatHelper.SanitizeAll(FloatEntries);
			NormalizeSavedFloats();
			ModConfigRegistry.Rebuild();
			ModConfigRegistry.PurgeObsoleteFromFile(FilePath);
			MainCategory.LoadFromFile(false);
			SanitizeFloatEntries();
			IsInitialized = true;
			ModConfigLocalization.Apply();
		}

		public static void SaveToFile()
		{
			ModConfigRegistry.SaveToFile();
		}

		internal static void FlushGlobalToDisk()
		{
			GlobalConfigStore.FlushToDisk();
		}

		internal static void ReloadGlobalFromFile()
		{
			if (IsInitialized)
			{
				GlobalConfigStore.FlushIfDirty();
				MainCategory.LoadFromFile(false);
				SanitizeFloatEntries();
			}
		}

		public static bool TrySetEntryValue(string sectionId, string key, string value, out string? error)
		{
			return ModConfigRegistry.TrySetEntryValue(sectionId, key, value, out error);
		}

		internal static void NotifyFileReloaded()
		{
			ModConfigChangeTracker.NotifyFullReload();
		}

		public static void NormalizeSavedFloats()
		{
			ModConfigFloatHelper.NormalizeSavedFloats(FilePath, FloatEntries);
		}

		internal static void SanitizeFloatEntries()
		{
			ModConfigFloatHelper.SanitizeAll(FloatEntries);
		}

		private static void RegisterFloatEntries()
		{
			MorePlayersConfig.RegisterFloatEntries();
			SpawnScalingConfig.RegisterFloatEntries();
			LootMultiplicatorConfig.RegisterFloatEntries();
			EconomyConfig.RegisterFloatEntries();
			DungeonTimeConfig.RegisterFloatEntries();
			MimicTuningConfig.RegisterFloatEntries();
			PlayerTuningConfig.RegisterFloatEntries();
			WeatherConfig.RegisterFloatEntries();
			UiConfig.RegisterFloatEntries();
		}

		internal static void OnSpawnMultiplierChanged(Instance logger, float value, MelonPreferences_Entry<float> entry)
		{
			if (value < 0f)
			{
				logger.Warning(((MelonPreferences_Entry)entry).Identifier + " must be >= 0; resetting to 0.");
				entry.Value = 0f;
			}
			else
			{
				ModConfigFloatHelper.SanitizeEntry(entry);
				NotifyChanged((MelonPreferences_Entry)(object)entry);
			}
		}

		internal static void OnBaselinePlayerCountChanged(Instance logger, int value, MelonPreferences_Entry<int> entry)
		{
			if (value < 1)
			{
				logger.Warning(((MelonPreferences_Entry)entry).Identifier + " must be at least 1; resetting to 1.");
				entry.Value = 1;
			}
			else
			{
				NotifyChanged((MelonPreferences_Entry)(object)entry);
			}
		}

		internal static MelonPreferences_Category CreateCategory(string id)
		{
			string text = ModL10n.GetConfigSectionTitle(id) ?? id;
			MelonPreferences_Category obj = MelonPreferences.CreateCategory(id, text);
			obj.SetFilePath(FilePath);
			ModConfigRegistry.TrackCategory(obj);
			return obj;
		}

		internal static MelonPreferences_Entry<T> CreateTrackedEntry<T>(MelonPreferences_Category category, string identifier, T defaultValue)
		{
			string identifier2 = category.Identifier;
			string text = ModL10n.GetConfigEntryTitle(identifier2, identifier) ?? identifier;
			string text2 = ModL10n.GetConfigEntryDescription(identifier2, identifier) ?? string.Empty;
			MelonPreferences_Entry<T> obj = category.CreateEntry<T>(identifier, defaultValue, text, text2, false, false, (ValueValidator)null, (string)null);
			ModConfigRegistry.TrackEntry((MelonPreferences_Entry)(object)obj);
			return obj;
		}

		internal static MelonPreferences_Entry<T> CreateHiddenTrackedEntry<T>(MelonPreferences_Category category, string identifier, T defaultValue)
		{
			MelonPreferences_Entry<T> obj = CreateTrackedEntry(category, identifier, defaultValue);
			((MelonPreferences_Entry)obj).IsHidden = true;
			return obj;
		}

		internal static void NotifyChanged(MelonPreferences_Entry entry)
		{
			ModConfigChangeTracker.NotifyEntryChanged(entry);
		}
	}
	public sealed class ModConfigKeyChange
	{
		public string SectionId { get; set; } = "";

		public string Key { get; set; } = "";
	}
	public sealed class ModConfigChangeInfo
	{
		public static ModConfigChangeInfo FullReload { get; } = new ModConfigChangeInfo
		{
			IsFullReload = true
		};

		public bool IsFullReload { get; set; }

		public IReadOnlyList<ModConfigKeyChange> ChangedKeys { get; set; } = Array.Empty<ModConfigKeyChange>();

		public IEnumerable<string> ChangedSections => ChangedKeys.Select((ModConfigKeyChange change) => change.SectionId).Distinct<string>(StringComparer.OrdinalIgnoreCase);

		public bool AffectsSection(string sectionId)
		{
			if (IsFullReload)
			{
				return true;
			}
			return ChangedKeys.Any((ModConfigKeyChange change) => string.Equals(change.SectionId, sectionId, StringComparison.OrdinalIgnoreCase));
		}
	}
	internal static class ModConfigChangeTracker
	{
		private sealed class ChangeKeyComparer : IEqualityComparer<(string SectionId, string Key)>
		{
			internal static ChangeKeyComparer Instance { get; } = new ChangeKeyComparer();

			public bool Equals((string SectionId, string Key) x, (string SectionId, string Key) y)
			{
				if (string.Equals(x.SectionId, y.SectionId, StringComparison.OrdinalIgnoreCase))
				{
					return string.Equals(x.Key, y.Key, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}

			public int GetHashCode((string SectionId, string Key) obj)
			{
				return HashCode.Combine(StringComparer.OrdinalIgnoreCase.GetHashCode(obj.SectionId), StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Key));
			}
		}

		private static int _batchDepth;

		private static readonly HashSet<(string SectionId, string Key)> PendingChanges = new HashSet<(string, string)>(ChangeKeyComparer.Instance);

		internal static event Action<ModConfigChangeInfo>? Changed;

		internal static void BeginBatch()
		{
			_batchDepth++;
		}

		internal static void EndBatch()
		{
			if (_batchDepth > 0)
			{
				_batchDepth--;
				if (_batchDepth <= 0 && PendingChanges.Count != 0)
				{
					FlushPending();
				}
			}
		}

		internal static void CancelBatch()
		{
			PendingChanges.Clear();
			_batchDepth = 0;
		}

		internal static void NotifyChange(string sectionId, string key)
		{
			if (!string.IsNullOrWhiteSpace(sectionId) && !string.IsNullOrWhiteSpace(key))
			{
				if (_batchDepth > 0)
				{
					PendingChanges.Add((sectionId, key));
				}
				else
				{
					Dispatch(BuildInfo(new <>z__ReadOnlySingleElementList<(string, string)>((sectionId, key))));
				}
			}
		}

		internal static void NotifyEntryChanged(MelonPreferences_Entry entry)
		{
			NotifyChange(entry.Category.Identifier, entry.Identifier);
		}

		internal static void NotifyFullReload()
		{
			PendingChanges.Clear();
			_batchDepth = 0;
			Dispatch(ModConfigChangeInfo.FullReload);
		}

		private static void FlushPending()
		{
			if (PendingChanges.Count != 0)
			{
				List<(string SectionId, string Key)> pendingChanges = PendingChanges.ToList();
				PendingChanges.Clear();
				Dispatch(BuildInfo(pendingChanges));
			}
		}

		private static ModConfigChangeInfo BuildInfo(IReadOnlyList<(string SectionId, string Key)> pendingChanges)
		{
			ModConfigKeyChange[] changedKeys = pendingChanges.Select<(string, string), ModConfigKeyChange>(delegate((string SectionId, string Key) pair)
			{
				ModConfigKeyChange modConfigKeyChange = new ModConfigKeyChange();
				(modConfigKeyChange.SectionId, modConfigKeyChange.Key) = pair;
				return modConfigKeyChange;
			}).ToArray();
			return new ModConfigChangeInfo
			{
				ChangedKeys = changedKeys
			};
		}

		private static void Dispatch(ModConfigChangeInfo info)
		{
			ModConfigRegistry.NotifyRuntimeChange();
			ModConfigChangeTracker.Changed?.Invoke(info);
		}
	}
	internal readonly struct ModConfigEntryBound
	{
		internal string? MinValue { get; }

		internal string? MaxValue { get; }

		internal ModConfigEntryBound(string? minValue, string? maxValue)
		{
			MinValue = minValue;
			MaxValue = maxValue;
		}
	}
	internal static class ModConfigEntryBounds
	{
		private sealed class SectionKeyComparer : IEqualityComparer<(string SectionId, string Key)>
		{
			internal static readonly SectionKeyComparer Instance = new SectionKeyComparer();

			public bool Equals((string SectionId, string Key) x, (string SectionId, string Key) y)
			{
				if (string.Equals(x.SectionId, y.SectionId, StringComparison.OrdinalIgnoreCase))
				{
					return string.Equals(x.Key, y.Key, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}

			public int GetHashCode((string SectionId, string Key) obj)
			{
				return HashCode.Combine(StringComparer.OrdinalIgnoreCase.GetHashCode(obj.SectionId), StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Key));
			}
		}

		private static readonly Dictionary<(string SectionId, string Key), ModConfigEntryBound> Bounds;

		static ModConfigEntryBounds()
		{
			Bounds = new Dictionary<(string, string), ModConfigEntryBound>(SectionKeyComparer.Instance);
			Float("MimesisPlayerEnhancement_Ui", "ModToastDurationSeconds", 1f);
			FloatRange("MimesisPlayerEnhancement_Ui", "FloatingDamageDurationSeconds", 1f, 3f);
			FloatRange("MimesisPlayerEnhancement_Ui", "RoundStartSoundVolume", 0f, 1f);
			FloatRange("MimesisPlayerEnhancement_Ui", "DiscoBallSoundVolume", 0f, 1f);
			FloatRange("MimesisPlayerEnhancement_Ui", "SpectatorVoiceAttenuation", 0f, 1f);
			FloatRange("MimesisPlayerEnhancement_Ui", "SpectatorVoiceDuckLevel", 0f, 1f);
			FloatRange("MimesisPlayerEnhancement_Ui", "VoiceNoiseGateStrength", 0f, 1f);
			Int("MimesisPlayerEnhancement_MorePlayers", "MaxPlayers", 1);
			MinZeroFloat("MimesisPlayerEnhancement_MorePlayers", "RoundGoalBasePerZone", "RoundGoalMoneyMultiplier");
			FloatRange("MimesisPlayerEnhancement_MorePlayers", "RoundGoalCurveExponent", 0.1f, 2f);
			IntRange("MimesisPlayerEnhancement_MorePlayers", "RoundGoalRandomSpreadPercent", 0, 100);
			Int("MimesisPlayerEnhancement_MoreVoices", "MaxIndoorVoiceEvents", 1);
			Int("MimesisPlayerEnhancement_MoreVoices", "MaxDeathMatchVoiceEvents", 1);
			Int("MimesisPlayerEnhancement_MoreVoices", "MaxOutdoorVoiceEvents", 1);
			Int("MimesisPlayerEnhancement_MoreVoices", "VoiceClipCacheMaxEntries", 1);
			Int("MimesisPlayerEnhancement_Statistics", "SessionReconnectGraceMinutes", 1);
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "MoveSpeedMultiplier");
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "NoClipSpeedMultiplier");
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "MaxStaminaMultiplier");
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "StaminaDrainMultiplier");
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "StaminaRegenMultiplier");
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "StaminaRegenDelayMultiplier");
			FloatRange("MimesisPlayerEnhancement_PlayerTuning", "MaxCarryWeightMultiplier");
			MinZeroFloat("MimesisPlayerEnhancement_Economy", "ScrapSellValueMultiplier", "ScrapSellValuePerPlayerMultiplier", "ShopBuyPriceMultiplier", "ShopBuyPricePerPlayerMultiplier", "ReinforcePriceMultiplier", "ReinforcePricePerPlayerMultiplier");
			Int("MimesisPlayerEnhancement_Economy", "EconomyBaselinePlayerCount", 1);
			Int("MimesisPlayerEnhancement_SavegamePreparation", "StartupMoney", 0);
			IntRange("MimesisPlayerEnhancement_SavegamePreparation", "StartingZone", 1, 99);
			IntRange("MimesisPlayerEnhancement_Economy", "ShopDiscountMinPercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_Economy", "ShopDiscountMaxPercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_Economy", "ShopDiscountChancePercent", 0, 100);
			MinZeroFloat("MimesisPlayerEnhancement_LootMultiplicator", "MapLootMultiplier", "MapLootPerPlayerMultiplier", "DropLootMultiplier", "DropLootPerPlayerMultiplier");
			Int("MimesisPlayerEnhancement_LootMultiplicator", "LootMultiplicatorBaselinePlayerCount", 1);
			IntRange("MimesisPlayerEnhancement_LootMultiplicator", "ConvertFakeActorDyingDropChancePercent", 0, 100);
			MinZeroFloat("MimesisPlayerEnhancement_SpawnScaling", "MimicSpawnMultiplier", "MimicSpawnPerPlayerMultiplier", "MimicWaveInitialDelaySeconds", "MimicWaveInitialDelayMinSeconds", "MimicWaveInitialDelayMaxSeconds", "MimicWaveIntervalSeconds", "MimicWaveIntervalMinSeconds", "MimicWaveIntervalMaxSeconds", "BossSpawnMultiplier", "BossSpawnPerPlayerMultiplier", "GruntSpawnMultiplier", "GruntSpawnPerPlayerMultiplier", "GruntWaveInitialDelaySeconds", "GruntWaveInitialDelayMinSeconds", "GruntWaveInitialDelayMaxSeconds", "GruntWaveIntervalSeconds", "GruntWaveIntervalMinSeconds", "GruntWaveIntervalMaxSeconds", "SpecialSpawnMultiplier", "SpecialSpawnPerPlayerMultiplier", "TrapSpawnMultiplier", "TrapSpawnPerPlayerMultiplier", "TrapRespawnDelaySeconds", "TrapRespawnDelayMinSeconds", "TrapRespawnDelayMaxSeconds", "TrapRespawnMinPlayerDistanceMeters", "OtherSpawnMultiplier", "OtherSpawnPerPlayerMultiplier", "BonusEncounterDelayMinSeconds", "BonusEncounterDelayMaxSeconds", "BonusEncounterMinPlayerDistanceMeters");
			Int("MimesisPlayerEnhancement_SpawnScaling", "SpawnScalingBaselinePlayerCount", 1);
			Int("MimesisPlayerEnhancement_JoinAnytime", "JoinConnectionGraceSeconds", 1);
			Int("MimesisPlayerEnhancement_DungeonTime", "DungeonTimeBaselinePlayerCount", 1);
			Float("MimesisPlayerEnhancement_DungeonTime", "ExtraShiftSecondsPerPlayerAboveBaseline", 0f);
			FloatRange("MimesisPlayerEnhancement_DungeonTime", "TimeMultiplier", -5f, 5f);
			Float("MimesisPlayerEnhancement_Weather", "WeatherCycleMinDelaySeconds", 0f);
			Float("MimesisPlayerEnhancement_Weather", "WeatherCycleMaxDelaySeconds", 0f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "MimicPossessionMinTimeSeconds", 0.1f, 120f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "MimicPossessionMaxTimeSeconds", 0.1f, 120f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "MimicPossessionCooltimeMultiplier", 0.1f, 10f);
			MinZeroFloat("MimesisPlayerEnhancement_MimicTuning", "PeriodicVoiceIntervalMultiplier", "PlayerVoiceResponseCooldownSeconds", "PlayerVoiceResponseDelayMinSeconds", "PlayerVoiceResponseDelayMaxSeconds", "ClipReuseCooldownSeconds", "DeathMatchClipReuseCooldownSeconds", "SpeakAudienceRangeMeters", "PostReplyIntervalFixedSeconds", "PostReplyIntervalMinSeconds", "PostReplyIntervalMaxSeconds", "VoiceInitIntervalMin", "VoiceInitIntervalMax", "VoicePeriodicIntervalMin", "VoicePeriodicIntervalMax", "VoiceDeathMatchIntervalMin", "VoiceDeathMatchIntervalMax");
			Float("MimesisPlayerEnhancement_MimicTuning", "PlayerVoiceResponseMaxDistance", 1f);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "PlayerVoiceResponseChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "MinRequiredSpeechClips", 0, 50);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustOutdoorMultiplier", 0f, 10f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustLookingDelta", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustNotLookingDelta", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustApproachDelta", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustMaintainDelta", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustWalkAwayDelta", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustSprintAwayDelta", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustHitDamageMultiplier", -100f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustFriendlyThreshold", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustDistrustThreshold", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustInitialFixed", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustInitialRandomMin", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustInitialRandomMax", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustBehaviorFixed", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustBehaviorRandomMin", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "TrustBehaviorRandomMax", 0f, 100f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "ChaseActivationDistanceMeters", 0.1f, 200f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "ChaseForceRunDistanceMeters", 0.1f, 200f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "MimicRunawayChance", 0f, 1f);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "JumpCopyChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "SlotFollowChangeChancePercent", 0, 100);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "PossessionRangeMeters", 1f, 200f);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "EmoteRespondChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "EmoteSuggestChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "ReactToSprinklerChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "UseTrapSwitchChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "UseChargerChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "UseTransmitterChancePercent", 0, 100);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "UseShutterSwitchChancePercent", 0, 100);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "HornMaxRecordSeconds", 0.1f, 60f);
			FloatRange("MimesisPlayerEnhancement_MimicTuning", "HornRecordingGapSeconds", 0.1f, 30f);
			IntRange("MimesisPlayerEnhancement_MimicTuning", "HornMaxStoredRecords", 1, 100);
			IntRange("MimesisPlayerEnhancement_WebDashboard", "WebDashboardListenPort", 1, 65535);
		}

		internal static bool TryGet(string sectionId, string key, out ModConfigEntryBound bound)
		{
			return Bounds.TryGetValue((sectionId, key), out bound);
		}

		private static void Float(string sectionId, string key, float min, float? max = null)
		{
			Bounds[(sectionId, key)] = new ModConfigEntryBound(ModConfigFloatHelper.Format(min), max.HasValue ? ModConfigFloatHelper.Format(max.Value) : null);
		}

		private static void FloatRange(string sectionId, string key, float min, float max)
		{
			Float(sectionId, key, min, max);
		}

		private static void FloatRange(string sectionId, string key)
		{
			FloatRange(sectionId, key, 0.1f, 5f);
		}

		private static void Int(string sectionId, string key, int min, int? max = null)
		{
			Bounds[(sectionId, key)] = new ModConfigEntryBound(min.ToString(CultureInfo.InvariantCulture), max?.ToString(CultureInfo.InvariantCulture));
		}

		private static void IntRange(string sectionId, string key, int min, int max)
		{
			Int(sectionId, key, min, max);
		}

		private static void MinZeroFloat(string sectionId, params string[] keys)
		{
			for (int i = 0; i < keys.Length; i++)
			{
				Float(sectionId, keys[i], 0f);
			}
		}
	}
	internal readonly struct ModConfigEntryDependency
	{
		internal string DependsOnKey { get; }

		internal string? DependsOnValue { get; }

		internal ModConfigEntryDependency(string dependsOnKey, string? dependsOnValue = null)
		{
			DependsOnKey = dependsOnKey;
			DependsOnValue = dependsOnValue;
		}
	}
	internal static class ModConfigEntryDependencies
	{
		internal static void ApplyToEntry(WebDashboardConfigSectionDto section, WebDashboardConfigEntryDto entry)
		{
			if (TryGetDependency(section.Id, entry.Key, out var dependency))
			{
				entry.DependsOnKey = dependency.DependsOnKey;
				entry.DependsOnValue = dependency.DependsOnValue;
			}
		}

		private static bool TryGetDependency(string sectionId, string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			if (string.IsNullOrWhiteSpace(sectionId) || string.IsNullOrWhiteSpace(key))
			{
				return false;
			}
			return sectionId switch
			{
				"MimesisPlayerEnhancement_MimicTuning" => TryGetMimicTuningDependency(key, out dependency), 
				"MimesisPlayerEnhancement_SpawnScaling" => TryGetSpawnScalingDependency(key, out dependency), 
				"MimesisPlayerEnhancement_LootMultiplicator" => TryGetLootDependency(key, out dependency), 
				"MimesisPlayerEnhancement_Economy" => TryGetEconomyDependency(key, out dependency), 
				"MimesisPlayerEnhancement_DungeonRandomizer" => TryGetDungeonRandomizerDependency(key, out dependency), 
				"MimesisPlayerEnhancement_Weather" => TryGetWeatherDependency(key, out dependency), 
				"MimesisPlayerEnhancement_DungeonTime" => TryGetDungeonTimeDependency(key, out dependency), 
				"MimesisPlayerEnhancement_Ui" => TryGetUiDependency(key, out dependency), 
				_ => false, 
			};
		}

		private static bool TryGetUiDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			if (string.Equals(key, "RoundStartSoundVariant", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("RoundStartSoundMode", "Specific");
				return true;
			}
			if (string.Equals(key, "RoundStartSoundRandomPool", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("RoundStartSoundMode", "Random");
				return true;
			}
			if (string.Equals(key, "DiscoBallSoundVariant", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("DiscoBallSoundMode", "Specific");
				return true;
			}
			if (string.Equals(key, "DiscoBallSoundRandomPool", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("DiscoBallSoundMode", "Random");
				return true;
			}
			if (string.Equals(key, "CustomLoadingScreenVariant", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("CustomLoadingScreenMode", "Specific");
				return true;
			}
			if (string.Equals(key, "CustomLoadingScreenRandomPool", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("CustomLoadingScreenMode", "Random");
				return true;
			}
			if (string.Equals(key, "SpectatorVoiceAttenuation", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("SpectatorVoiceBalanceMode", "StaticAttenuation");
				return true;
			}
			if (string.Equals(key, "SpectatorVoiceDuckLevel", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("SpectatorVoiceBalanceMode", "SpeechDucking");
				return true;
			}
			if (string.Equals(key, "VoiceNoiseGateStrength", StringComparison.Ordinal))
			{
				dependency = new ModConfigEntryDependency("EnableVoiceNoiseGate");
				return true;
			}
			return false;
		}

		private static bool TryGetMimicTuningDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			switch (key)
			{
			case "PlayerVoiceResponseChancePercent":
			case "PlayerVoiceResponseDelayMaxSeconds":
			case "PlayerVoiceResponseDelayMinSeconds":
			case "PlayerVoiceResponseCooldownSeconds":
			case "DeathMatchClipReuseCooldownSeconds":
			case "ClipReuseCooldownSeconds":
			case "SpeakAudienceRangeMeters":
			case "HearOwnVoiceFromMimic":
			case "PostReplyIntervalMode":
			case "VoiceInitIntervalMode":
			case "MinRequiredSpeechClips":
			case "VoicePeriodicIntervalMode":
			case "VoiceDeathMatchIntervalMode":
			case "PeriodicVoiceIntervalMultiplier":
			case "PlayerVoiceResponseMaxDistance":
				dependency = new ModConfigEntryDependency("MimicVoiceTuningMode", "Custom");
				return true;
			case "PostReplyIntervalFixedSeconds":
				dependency = new ModConfigEntryDependency("PostReplyIntervalMode", "Fixed");
				return true;
			case "PostReplyIntervalMinSeconds":
			case "PostReplyIntervalMaxSeconds":
				dependency = new ModConfigEntryDependency("PostReplyIntervalMode", "Random");
				return true;
			case "VoiceInitIntervalMin":
			case "VoiceInitIntervalMax":
				dependency = new ModConfigEntryDependency("VoiceInitIntervalMode", "Random");
				return true;
			case "VoicePeriodicIntervalMin":
			case "VoicePeriodicIntervalMax":
				dependency = new ModConfigEntryDependency("VoicePeriodicIntervalMode", "Random");
				return true;
			case "VoiceDeathMatchIntervalMax":
			case "VoiceDeathMatchIntervalMin":
				dependency = new ModConfigEntryDependency("VoiceDeathMatchIntervalMode", "Random");
				return true;
			case "TrustHitDamageMultiplier":
			case "TrustOutdoorMultiplier":
			case "TrustFriendlyThreshold":
			case "TrustDistrustThreshold":
			case "ChaseForceRunDistanceMeters":
			case "ChaseActivationDistanceMeters":
			case "TrustSprintAwayDelta":
			case "TrustNotLookingDelta":
			case "TrustLookingDelta":
			case "TrustMaintainDelta":
			case "TrustWalkAwayDelta":
			case "TrustApproachDelta":
			case "TrustScoreValueMode":
				dependency = new ModConfigEntryDependency("MimicTrustMode", "Custom");
				return true;
			case "TrustInitialFixed":
				dependency = new ModConfigEntryDependency("TrustScoreValueMode", "Fixed");
				return true;
			case "TrustInitialRandomMin":
			case "TrustInitialRandomMax":
				dependency = new ModConfigEntryDependency("TrustScoreValueMode", "Random");
				return true;
			case "TrustBehaviorFixed":
				dependency = new ModConfigEntryDependency("TrustScoreValueMode", "Fixed");
				return true;
			case "TrustBehaviorRandomMin":
			case "TrustBehaviorRandomMax":
				dependency = new ModConfigEntryDependency("TrustScoreValueMode", "Random");
				return true;
			case "MimicInventoryCopyPickRule":
				dependency = new ModConfigEntryDependency("MimicInventoryCopyMode", "Custom");
				return true;
			case "RandomizeMimicPossessionDuration":
				dependency = new ModConfigEntryDependency("EnableMimicPossessionTuning");
				return true;
			case "MimicPossessionMinTimeSeconds":
			case "MimicPossessionMaxTimeSeconds":
				dependency = new ModConfigEntryDependency("RandomizeMimicPossessionDuration");
				return true;
			case "PossessionRangeMeters":
			case "PossessionBtGateMode":
			case "MimicPossessionCooltimeMultiplier":
				dependency = new ModConfigEntryDependency("EnableMimicPossessionTuning");
				return true;
			case "EmoteRespondChancePercent":
			case "EmoteSuggestChancePercent":
			case "UseTransmitterChancePercent":
			case "ReactToSprinklerChancePercent":
			case "UseShutterSwitchChancePercent":
			case "UseTrapSwitchChancePercent":
			case "UseChargerChancePercent":
				dependency = new ModConfigEntryDependency("MimicEmotePropsMode", "Custom");
				return true;
			case "HornMaxRecordSeconds":
			case "HornMaxStoredRecords":
			case "AllowHornImitation":
			case "HornRecordingGapSeconds":
				dependency = new ModConfigEntryDependency("HornImitationMode", "Custom");
				return true;
			default:
				return false;
			}
		}

		private static bool TryGetSpawnScalingDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			switch (key)
			{
			case "MimicWaveInitialDelaySeconds":
			case "MimicWaveIntervalSeconds":
				dependency = new ModConfigEntryDependency("MimicWaveMode", "Fixed");
				return true;
			case "MimicWaveInitialDelayMinSeconds":
			case "MimicWaveInitialDelayMaxSeconds":
			case "MimicWaveIntervalMinSeconds":
			case "MimicWaveIntervalMaxSeconds":
				dependency = new ModConfigEntryDependency("MimicWaveMode", "Random");
				return true;
			case "GruntWaveInitialDelaySeconds":
			case "GruntWaveIntervalSeconds":
				dependency = new ModConfigEntryDependency("GruntWaveMode", "Fixed");
				return true;
			case "GruntWaveInitialDelayMinSeconds":
			case "GruntWaveInitialDelayMaxSeconds":
			case "GruntWaveIntervalMinSeconds":
			case "GruntWaveIntervalMaxSeconds":
				dependency = new ModConfigEntryDependency("GruntWaveMode", "Random");
				return true;
			case "TrapRespawnDelaySeconds":
				dependency = new ModConfigEntryDependency("TrapRespawnMode", "Fixed");
				return true;
			case "TrapRespawnDelayMaxSeconds":
			case "TrapRespawnDelayMinSeconds":
				dependency = new ModConfigEntryDependency("TrapRespawnMode", "Random");
				return true;
			case "TrapRespawnMinPlayerDistanceMeters":
				dependency = new ModConfigEntryDependency("TrapRespawnMode", "!=Vanilla");
				return true;
			default:
				return false;
			}
		}

		private static bool TryGetLootDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			if (!(key == "LootAllowlist"))
			{
				if (key == "LootBlocklist")
				{
					dependency = new ModConfigEntryDependency("LootItemFilterMode", "BlocklistOnly");
					return true;
				}
				return false;
			}
			dependency = new ModConfigEntryDependency("LootItemFilterMode", "AllowlistOnly");
			return true;
		}

		private static bool TryGetEconomyDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			if (key == "ShopDiscountMinPercent" || key == "ShopDiscountMaxPercent")
			{
				dependency = new ModConfigEntryDependency("ShopDiscountChancePercent", ">0");
				return true;
			}
			return false;
		}

		private static bool TryGetDungeonRandomizerDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			switch (key)
			{
			case "DungeonPickPoolMode":
			case "DungeonAllowlist":
			case "DungeonBlocklist":
			case "IgnoreDungeonExcludeList":
				dependency = new ModConfigEntryDependency("RandomizeDungeonPick");
				return true;
			case "DungeonSeedFlavor":
				dependency = new ModConfigEntryDependency("EnableDungeonRandomizer");
				return true;
			default:
				return false;
			}
		}

		private static bool TryGetWeatherDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			switch (key)
			{
			case "FixedWeatherPreset":
				dependency = new ModConfigEntryDependency("WeatherMode", "Fixed");
				return true;
			case "DisableRandomWeather":
				dependency = new ModConfigEntryDependency("WeatherMode", "Vanilla");
				return true;
			case "WeatherCyclePresets":
			case "WeatherCycleMinDelaySeconds":
			case "WeatherCycleMaxDelaySeconds":
				dependency = new ModConfigEntryDependency("WeatherMode", "Cycle");
				return true;
			default:
				return false;
			}
		}

		private static bool TryGetDungeonTimeDependency(string key, out ModConfigEntryDependency dependency)
		{
			dependency = default(ModConfigEntryDependency);
			if (key == "EnableRealtimeTramClock" || key == "TimeMultiplier")
			{
				dependency = new ModConfigEntryDependency("EnableDungeonTime");
				return true;
			}
			return false;
		}
	}
	internal static class ModConfigEntryLocalEffect
	{
		private sealed class EntryKeyComparer : IEqualityComparer<(string SectionId, string Key)>
		{
			internal static readonly EntryKeyComparer Instance = new EntryKeyComparer();

			public bool Equals((string SectionId, string Key) x, (string SectionId, string Key) y)
			{
				if (string.Equals(x.SectionId, y.SectionId, StringComparison.OrdinalIgnoreCase))
				{
					return string.Equals(x.Key, y.Key, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}

			public int GetHashCode((string SectionId, string Key) obj)
			{
				return HashCode.Combine(StringComparer.OrdinalIgnoreCase.GetHashCode(obj.SectionId), StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Key));
			}
		}

		private const string MainSectionId = "MimesisPlayerEnhancement";

		private const string PlayerTuningSectionId = "MimesisPlayerEnhancement_PlayerTuning";

		private static readonly HashSet<(string SectionId, string Key)> LocalEntries = new HashSet<(string, string)>(EntryKeyComparer.Instance)
		{
			("MimesisPlayerEnhancement", "EnableDebugLogging"),
			("MimesisPlayerEnhancement", "LastSeenModVersion"),
			("MimesisPlayerEnhancement_Ui", "ModToastDurationSeconds"),
			("MimesisPlayerEnhancement_Ui", "EnableExtendedSaveSlots"),
			("MimesisPlayerEnhancement_Ui", "EnableExtendedSpectatorPlayerList"),
			("MimesisPlayerEnhancement_Ui", "EnableLoadingWaitPlayerList"),
			("MimesisPlayerEnhancement_Ui", "EnableExtendedInGameMenuPlayerList"),
			("MimesisPlayerEnhancement_Ui", "EnableDamageHealthGlow"),
			("MimesisPlayerEnhancement_Ui", "EnableFloatingDamageNumbers"),
			("MimesisPlayerEnhancement_Ui", "FloatingDamageDurationSeconds"),
			("MimesisPlayerEnhancement_Ui", "EnableFpsUi"),
			("MimesisPlayerEnhancement_Ui", "EnableFpsUiInventoryNetWorth"),
			("MimesisPlayerEnhancement_Ui", "EnableInventorySlotOptimization"),
			("MimesisPlayerEnhancement_Ui", "InventoryPickupSelectMode"),
			("MimesisPlayerEnhancement_Ui", "EnableInventorySelectNextOnRemove"),
			("MimesisPlayerEnhancement_Ui", "EnableInventoryNumberKeySelection"),
			("MimesisPlayerEnhancement_Ui", "RoundStartSoundMode"),
			("MimesisPlayerEnhancement_Ui", "RoundStartSoundVariant"),
			("MimesisPlayerEnhancement_Ui", "RoundStartSoundRandomPool"),
			("MimesisPlayerEnhancement_Ui", "RoundStartSoundVolume"),
			("MimesisPlayerEnhancement_Ui", "DiscoBallSoundMode"),
			("MimesisPlayerEnhancement_Ui", "DiscoBallSoundVariant"),
			("MimesisPlayerEnhancement_Ui", "DiscoBallSoundRandomPool"),
			("MimesisPlayerEnhancement_Ui", "DiscoBallSoundVolume"),
			("MimesisPlayerEnhancement_Ui", "CustomLoadingScreenMode"),
			("MimesisPlayerEnhancement_Ui", "CustomLoadingScreenVariant"),
			("MimesisPlayerEnhancement_Ui", "CustomLoadingScreenRandomPool"),
			("MimesisPlayerEnhancement_Ui", "CustomLoadingScreenMotion"),
			("MimesisPlayerEnhancement_Ui", "SpectatorVoiceBalanceMode"),
			("MimesisPlayerEnhancement_Ui", "SpectatorVoiceAttenuation"),
			("MimesisPlayerEnhancement_Ui", "SpectatorVoiceDuckLevel"),
			("MimesisPlayerEnhancement_Ui", "EnableVoiceNoiseGate"),
			("MimesisPlayerEnhancement_Ui", "VoiceNoiseGateStrength"),
			("MimesisPlayerEnhancement_Privacy", "EnablePrivacy"),
			("MimesisPlayerEnhancement_Privacy", "BlockReluTelemetry"),
			("MimesisPlayerEnhancement_Privacy", "BlockReplayUpload"),
			("MimesisPlayerEnhancement_Privacy", "BlockReplayRecording"),
			("MimesisPlayerEnhancement_Privacy", "BlockCrashReports"),
			("MimesisPlayerEnhancement_Privacy", "StripCrashReportMetadata"),
			("MimesisPlayerEnhancement_Privacy", "BlockKraftonGppSdk"),
			("MimesisPlayerEnhancement_PlayerTuning", "DisablePlayerCollision")
		};

		internal static bool HasLocalEffect(string sectionId, string key)
		{
			return LocalEntries.Contains((sectionId, key));
		}
	}
	internal static class ModConfigEntryUiHints
	{
		private sealed class EntryKeyComparer : IEqualityComparer<(string SectionId, string Key)>
		{
			internal static readonly EntryKeyComparer Instance = new EntryKeyComparer();

			public bool Equals((string SectionId, string Key) x, (string SectionId, string Key) y)
			{
				if (string.Equals(x.SectionId, y.SectionId, StringComparison.OrdinalIgnoreCase))
				{
					return string.Equals(x.Key, y.Key, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}

			public int GetHashCode((string SectionId, string Key) obj)
			{
				return HashCode.Combine(StringComparer.OrdinalIgnoreCase.GetHashCode(obj.SectionId), StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Key));
			}
		}

		private const string LootSectionId = "MimesisPlayerEnhancement_LootMultiplicator";

		private const string DungeonSectionId = "MimesisPlayerEnhancement_DungeonRandomizer";

		private const string WeatherSectionId = "MimesisPlayerEnhancement_Weather";

		private const string DungeonTimeSectionId = "MimesisPlayerEnhancement_DungeonTime";

		private const string SpawnScalingSectionId = "MimesisPlayerEnhancement_SpawnScaling";

		private const string EconomySectionId = "MimesisPlayerEnhancement_Economy";

		private const string MimicTuningSectionId = "MimesisPlayerEnhancement_MimicTuning";

		private const string SavegamePreparationSectionId = "MimesisPlayerEnhancement_SavegamePreparation";

		private const string MoreVoicesSectionId = "MimesisPlayerEnhancement_MoreVoices";

		private const string UiSectionId = "MimesisPlayerEnhancement_Ui";

		private static readonly Dictionary<(string SectionId, string Key), string[]> SelectValuesByEntry = new Dictionary<(string, string), string[]>(EntryKeyComparer.Instance)
		{
			[("MimesisPlayerEnhancement_LootMultiplicator", "LootItemFilterMode")] = new string[3] { "All", "AllowlistOnly", "BlocklistOnly" },
			[("MimesisPlayerEnhancement_DungeonRandomizer", "DungeonPickPoolMode")] = new string[2] { "WidenVanilla", "AllActiveUniform" },
			[("MimesisPlayerEnhancement_DungeonRandomizer", "DungeonSeedFlavor")] = DungeonSeedFlavorUtil.AllNames,
			[("MimesisPlayerEnhancement_Weather", "WeatherMode")] = new string[3] { "Vanilla", "Fixed", "Cycle" },
			[("MimesisPlayerEnhancement_Weather", "FixedWeatherPreset")] = new string[4] { "Sunny", "Rain", "HeavyRain", "Squall" },
			[("MimesisPlayerEnhancement_DungeonTime", "StartTimePreset")] = new string[6] { "Vanilla", "Morning", "Noon", "Dusk", "Night", "Midnight" },
			[("MimesisPlayerEnhancement_SpawnScaling", "MimicWaveMode")] = new string[3] { "Vanilla", "Fixed", "Random" },
			[("MimesisPlayerEnhancement_SpawnScaling", "GruntWaveMode")] = new string[3] { "Vanilla", "Fixed", "Random" },
			[("MimesisPlayerEnhancement_SpawnScaling", "TrapRespawnMode")] = new string[3] { "Vanilla", "Fixed", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "MimicVoiceTuningMode")] = new string[2] { "Vanilla", "Custom" },
			[("MimesisPlayerEnhancement_MimicTuning", "PostReplyIntervalMode")] = new string[3] { "Vanilla", "Fixed", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "HearOwnVoiceFromMimic")] = new string[3] { "Vanilla", "AlwaysHear", "OnlyWhenSingleplayer" },
			[("MimesisPlayerEnhancement_MimicTuning", "VoiceInitIntervalMode")] = new string[2] { "Vanilla", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "VoicePeriodicIntervalMode")] = new string[2] { "Vanilla", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "VoiceDeathMatchIntervalMode")] = new string[2] { "Vanilla", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "MimicTrustMode")] = new string[2] { "Vanilla", "Custom" },
			[("MimesisPlayerEnhancement_MimicTuning", "TrustScoreValueMode")] = new string[3] { "Vanilla", "Fixed", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "MimicSocialMode")] = new string[2] { "Vanilla", "Custom" },
			[("MimesisPlayerEnhancement_MimicTuning", "MimicInventoryCopyMode")] = new string[2] { "Vanilla", "Custom" },
			[("MimesisPlayerEnhancement_MimicTuning", "MimicInventoryCopyPickRule")] = new string[3] { "MinDistance", "MaxDistance", "Random" },
			[("MimesisPlayerEnhancement_MimicTuning", "PossessionBtGateMode")] = new string[2] { "Vanilla", "Always" },
			[("MimesisPlayerEnhancement_MimicTuning", "MimicEmotePropsMode")] = new string[2] { "Vanilla", "Custom" },
			[("MimesisPlayerEnhancement_MimicTuning", "HornImitationMode")] = new string[2] { "Vanilla", "Custom" },
			[("MimesisPlayerEnhancement_Ui", "RoundStartSoundMode")] = new string[3] { "Vanilla", "Random", "Specific" },
			[("MimesisPlayerEnhancement_Ui", "DiscoBallSoundMode")] = new string[3] { "Vanilla", "Random", "Specific" },
			[("MimesisPlayerEnhancement_Ui", "CustomLoadingScreenMode")] = new string[3] { "Vanilla", "Random", "Specific" },
			[("MimesisPlayerEnhancement_Ui", "InventoryPickupSelectMode")] = new string[3] { "Vanilla", "WeaponsOnly", "Always" },
			[("MimesisPlayerEnhancement_Ui", "SpectatorVoiceBalanceMode")] = new string[3] { "Vanilla", "SpeechDucking", "StaticAttenuation" }
		};

		internal static string ResolveInputKind(string sectionId, string key)
		{
			if (sectionId == "MimesisPlayerEnhancement_LootMultiplicator" && (string.Equals(key, "LootAllowlist", StringComparison.Ordinal) || string.Equals(key, "LootBlocklist", StringComparison.Ordinal)))
			{
				return "ItemIdList";
			}
			if (sectionId == "MimesisPlayerEnhancement_DungeonRandomizer" && (string.Equals(key, "DungeonAllowlist", StringComparison.Ordinal) || string.Equals(key, "DungeonBlocklist", StringComparison.Ordinal)))
			{
				return "DungeonIdList";
			}
			if (sectionId == "MimesisPlayerEnhancement_Weather" && string.Equals(key, "WeatherCyclePresets", StringComparison.Ordinal))
			{
				return "WeatherPresetList";
			}
			if (sectionId == "MimesisPlayerEnhancement_Ui" && (string.Equals(key, "RoundStartSoundRandomPool", StringComparison.Ordinal) || string.Equals(key, "DiscoBallSoundRandomPool", StringComparison.Ordinal) || string.Equals(key, "CustomLoadingScreenRandomPool", StringComparison.Ordinal)))
			{
				return "VariantIdList";
			}
			if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "RoundStartSoundVariant", StringComparison.Ordinal))
			{
				return "Select";
			}
			if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "DiscoBallSoundVariant", StringComparison.Ordinal))
			{
				return "Select";
			}
			if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "CustomLoadingScreenVariant", StringComparison.Ordinal))
			{
				return "Select";
			}
			if (SelectValuesByEntry.ContainsKey((sectionId, key)))
			{
				return "Select";
			}
			return "Default";
		}

		internal static void ApplyToEntry(WebDashboardConfigEntryDto entry, string sectionId, string key)
		{
			entry.InputKind = ResolveInputKind(sectionId, key);
			if (string.Equals(entry.InputKind, "VariantIdList", StringComparison.Ordinal))
			{
				if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "RoundStartSoundRandomPool", StringComparison.Ordinal))
				{
					entry.SelectOptions = BuildRoundStartSoundVariantOptions();
				}
				else if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "DiscoBallSoundRandomPool", StringComparison.Ordinal))
				{
					entry.SelectOptions = BuildDiscoBallSoundVariantOptions();
				}
				else if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "CustomLoadingScreenRandomPool", StringComparison.Ordinal))
				{
					entry.SelectOptions = BuildCustomLoadingScreenVariantOptions();
				}
			}
			else
			{
				if (!string.Equals(entry.InputKind, "Select", StringComparison.Ordinal))
				{
					return;
				}
				string[] value;
				if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "RoundStartSoundVariant", StringComparison.Ordinal))
				{
					entry.SelectOptions = BuildRoundStartSoundVariantOptions();
				}
				else if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "DiscoBallSoundVariant", StringComparison.Ordinal))
				{
					entry.SelectOptions = BuildDiscoBallSoundVariantOptions();
				}
				else if (sectionId == "MimesisPlayerEnhancement_Ui" && string.Equals(key, "CustomLoadingScreenVariant", StringComparison.Ordinal))
				{
					entry.SelectOptions = BuildCustomLoadingScreenVariantOptions();
				}
				else if (SelectValuesByEntry.TryGetValue((sectionId, key), out value))
				{
					List<WebDashboardConfigSelectOptionDto> list = new List<WebDashboardConfigSelectOptionDto>();
					string[] array = value;
					foreach (string text in array)
					{
						string configSelectOptionLabel = WebDashboardL10n.GetConfigSelectOptionLabel(sectionId, key, text);
						list.Add(new WebDashboardConfigSelectOptionDto
						{
							Value = text,
							Label = (string.IsNullOrWhiteSpace(configSelectOptionLabel) ? text : configSelectOptionLabel)
						});
					}
					entry.SelectOptions = list;
				}
			}
		}

		internal static void AssignEntryGroups(WebDashboardConfigSectionDto section)
		{
			string id = section.Id;
			string b = section.FeatureToggle?.Key;
			List<WebDashboardConfigEntryDto> entries = section.Entries;
			Dictionary<string, string> explicitGroups = GetExplicitGroups(id);
			foreach (WebDashboardConfigEntryDto item in entries)
			{
				if (explicitGroups.TryGetValue(item.Key, out var value))
				{
					item.EntryGroup = id + "::" + value;
				}
			}
			for (int i = 0; i < entries.Count; i++)
			{
				WebDashboardConfigEntryDto webDashboardConfigEntryDto = entries[i];
				if (!webDashboardConfigEntryDto.Key.StartsWith("Enable", StringComparison.Ordinal) || string.Equals(webDashboardConfigEntryDto.Key, b, StringComparison.Ordinal) || !string.IsNullOrEmpty(webDashboardConfigEntryDto.EntryGroup))
				{
					continue;
				}
				string entryGroup = (webDashboardConfigEntryDto.EntryGroup = id + "::" + webDashboardConfigEntryDto.Key);
				for (int j = i + 1; j < entries.Count; j++)
				{
					WebDashboardConfigEntryDto webDashboardConfigEntryDto2 = entries[j];
					if (webDashboardConfigEntryDto2.Key.StartsWith("Enable", StringComparison.Ordinal) || !string.IsNullOrEmpty(webDashboardConfigEntryDto2.EntryGroup))
					{
						break;
					}
					webDashboardConfigEntryDto2.EntryGroup = entryGroup;
				}
			}
		}

		private static Dictionary<string, string> GetExplicitGroups(string sectionId)
		{
			return sectionId switch
			{
				"MimesisPlayerEnhancement_LootMultiplicator" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["LootMultiplicatorBaselinePlayerCount"] = "playerScaling",
					["MapLootMultiplier"] = "mapLoot",
					["MapLootPerPlayerMultiplier"] = "mapLoot",
					["DropLootMultiplier"] = "dropLoot",
					["DropLootPerPlayerMultiplier"] = "dropLoot",
					["LootItemFilterMode"] = "lootFilter",
					["LootAllowlist"] = "lootFilter",
					["LootBlocklist"] = "lootFilter",
					["AutoScaleMapLootBudgetForFilter"] = "lootFilter"
				}, 
				"MimesisPlayerEnhancement_Economy" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["EconomyBaselinePlayerCount"] = "playerScaling",
					["ScrapSellValueMultiplier"] = "scrapSellValue",
					["ScrapSellValuePerPlayerMultiplier"] = "scrapSellValue",
					["ShopBuyPriceMultiplier"] = "shopBuyPrice",
					["ShopBuyPricePerPlayerMultiplier"] = "shopBuyPrice",
					["ReinforcePriceMultiplier"] = "reinforcePrice",
					["ReinforcePricePerPlayerMultiplier"] = "reinforcePrice"
				}, 
				"MimesisPlayerEnhancement_DungeonRandomizer" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["RandomizeDungeonPick"] = "dungeonPick",
					["DungeonPickPoolMode"] = "dungeonPick",
					["DungeonAllowlist"] = "dungeonPick",
					["DungeonBlocklist"] = "dungeonPick",
					["IgnoreDungeonExcludeList"] = "dungeonPick",
					["DungeonSeedFlavor"] = "dungeonSeed"
				}, 
				"MimesisPlayerEnhancement_SpawnScaling" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["SpawnScalingBaselinePlayerCount"] = "playerScaling",
					["MimicSpawnMultiplier"] = "mimicSpawn",
					["MimicSpawnPerPlayerMultiplier"] = "mimicSpawn",
					["MimicWaveMode"] = "mimicWaveTiming",
					["MimicWaveInitialDelaySeconds"] = "mimicWaveTiming",
					["MimicWaveInitialDelayMinSeconds"] = "mimicWaveTiming",
					["MimicWaveInitialDelayMaxSeconds"] = "mimicWaveTiming",
					["MimicWaveIntervalSeconds"] = "mimicWaveTiming",
					["MimicWaveIntervalMinSeconds"] = "mimicWaveTiming",
					["MimicWaveIntervalMaxSeconds"] = "mimicWaveTiming",
					["BossSpawnMultiplier"] = "bossSpawn",
					["BossSpawnPerPlayerMultiplier"] = "bossSpawn",
					["GruntSpawnMultiplier"] = "gruntSpawn",
					["GruntSpawnPerPlayerMultiplier"] = "gruntSpawn",
					["GruntWaveMode"] = "gruntWaveTiming",
					["GruntWaveInitialDelaySeconds"] = "gruntWaveTiming",
					["GruntWaveInitialDelayMinSeconds"] = "gruntWaveTiming",
					["GruntWaveInitialDelayMaxSeconds"] = "gruntWaveTiming",
					["GruntWaveIntervalSeconds"] = "gruntWaveTiming",
					["GruntWaveIntervalMinSeconds"] = "gruntWaveTiming",
					["GruntWaveIntervalMaxSeconds"] = "gruntWaveTiming",
					["SpecialSpawnMultiplier"] = "specialSpawn",
					["SpecialSpawnPerPlayerMultiplier"] = "specialSpawn",
					["TrapSpawnMultiplier"] = "trapSpawn",
					["TrapSpawnPerPlayerMultiplier"] = "trapSpawn",
					["OtherSpawnMultiplier"] = "otherSpawn",
					["OtherSpawnPerPlayerMultiplier"] = "otherSpawn",
					["TrapRespawnMode"] = "trapRespawn",
					["TrapRespawnDelaySeconds"] = "trapRespawn",
					["TrapRespawnDelayMinSeconds"] = "trapRespawn",
					["TrapRespawnDelayMaxSeconds"] = "trapRespawn",
					["TrapRespawnMinPlayerDistanceMeters"] = "trapRespawn",
					["BonusEncounterDelayMinSeconds"] = "bonusEncounterTiming",
					["BonusEncounterDelayMaxSeconds"] = "bonusEncounterTiming",
					["BonusEncounterMinPlayerDistanceMeters"] = "bonusEncounterTiming"
				}, 
				"MimesisPlayerEnhancement_MimicTuning" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["MimicVoiceTuningMode"] = "mimicVoice",
					["PeriodicVoiceIntervalMultiplier"] = "mimicVoice",
					["PlayerVoiceResponseChancePercent"] = "mimicVoice",
					["PlayerVoiceResponseCooldownSeconds"] = "mimicVoice",
					["PlayerVoiceResponseDelayMinSeconds"] = "mimicVoice",
					["PlayerVoiceResponseDelayMaxSeconds"] = "mimicVoice",
					["PlayerVoiceResponseMaxDistance"] = "mimicVoice",
					["ClipReuseCooldownSeconds"] = "mimicVoice",
					["DeathMatchClipReuseCooldownSeconds"] = "mimicVoice",
					["SpeakAudienceRangeMeters"] = "mimicVoice",
					["PostReplyIntervalMode"] = "mimicVoice",
					["PostReplyIntervalFixedSeconds"] = "mimicVoice",
					["PostReplyIntervalMinSeconds"] = "mimicVoice",
					["PostReplyIntervalMaxSeconds"] = "mimicVoice",
					["MinRequiredSpeechClips"] = "mimicVoice",
					["HearOwnVoiceFromMimic"] = "mimicVoice",
					["VoiceInitIntervalMode"] = "mimicVoice",
					["VoiceInitIntervalMin"] = "mimicVoice",
					["VoiceInitIntervalMax"] = "mimicVoice",
					["VoicePeriodicIntervalMode"] = "mimicVoice",
					["VoicePeriodicIntervalMin"] = "mimicVoice",
					["VoicePeriodicIntervalMax"] = "mimicVoice",
					["VoiceDeathMatchIntervalMode"] = "mimicVoice",
					["VoiceDeathMatchIntervalMin"] = "mimicVoice",
					["VoiceDeathMatchIntervalMax"] = "mimicVoice",
					["MimicTrustMode"] = "mimicTrust",
					["TrustOutdoorMultiplier"] = "mimicTrust",
					["TrustLookingDelta"] = "mimicTrust",
					["TrustNotLookingDelta"] = "mimicTrust",
					["TrustApproachDelta"] = "mimicTrust",
					["TrustMaintainDelta"] = "mimicTrust",
					["TrustWalkAwayDelta"] = "mimicTrust",
					["TrustSprintAwayDelta"] = "mimicTrust",
					["TrustHitDamageMultiplier"] = "mimicTrust",
					["TrustFriendlyThreshold"] = "mimicTrust",
					["TrustDistrustThreshold"] = "mimicTrust",
					["TrustScoreValueMode"] = "mimicTrust",
					["TrustInitialFixed"] = "mimicTrust",
					["TrustInitialRandomMin"] = "mimicTrust",
					["TrustInitialRandomMax"] = "mimicTrust",
					["TrustBehaviorFixed"] = "mimicTrust",
					["TrustBehaviorRandomMin"] = "mimicTrust",
					["TrustBehaviorRandomMax"] = "mimicTrust",
					["ChaseActivationDistanceMeters"] = "mimicTrust",
					["ChaseForceRunDistanceMeters"] = "mimicTrust",
					["MimicSocialMode"] = "mimicSocial",
					["MimicRunawayChance"] = "mimicSocial",
					["JumpCopyChancePercent"] = "mimicSocial",
					["SlotFollowChangeChancePercent"] = "mimicSocial",
					["EnableMimicPossessionTuning"] = "mimicPossession",
					["RandomizeMimicPossessionDuration"] = "mimicPossession",
					["MimicPossessionMinTimeSeconds"] = "mimicPossession",
					["MimicPossessionMaxTimeSeconds"] = "mimicPossession",
					["MimicPossessionCooltimeMultiplier"] = "mimicPossession",
					["PossessionRangeMeters"] = "mimicPossession",
					["PossessionBtGateMode"] = "mimicPossession",
					["MimicEmotePropsMode"] = "mimicEmoteProps",
					["EmoteRespondChancePercent"] = "mimicEmoteProps",
					["EmoteSuggestChancePercent"] = "mimicEmoteProps",
					["ReactToSprinklerChancePercent"] = "mimicEmoteProps",
					["UseTrapSwitchChancePercent"] = "mimicEmoteProps",
					["UseChargerChancePercent"] = "mimicEmoteProps",
					["UseTransmitterChancePercent"] = "mimicEmoteProps",
					["UseShutterSwitchChancePercent"] = "mimicEmoteProps",
					["HornImitationMode"] = "mimicHorn",
					["AllowHornImitation"] = "mimicHorn",
					["HornMaxRecordSeconds"] = "mimicHorn",
					["HornRecordingGapSeconds"] = "mimicHorn",
					["HornMaxStoredRecords"] = "mimicHorn"
				}, 
				"MimesisPlayerEnhancement_DungeonTime" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["StartTimePreset"] = "startTime",
					["TimeMultiplier"] = "startTime",
					["EnableRealtimeTramClock"] = "startTime"
				}, 
				"MimesisPlayerEnhancement_Weather" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["WeatherMode"] = "weatherMode",
					["FixedWeatherPreset"] = "weatherMode",
					["DisableRandomWeather"] = "weatherMode",
					["WeatherCyclePresets"] = "weatherCycle",
					["WeatherCycleMinDelaySeconds"] = "weatherCycle",
					["WeatherCycleMaxDelaySeconds"] = "weatherCycle"
				}, 
				"MimesisPlayerEnhancement_Ui" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["ModToastDurationSeconds"] = "modToasts",
					["EnableExtendedSaveSlots"] = "extendedSaveSlots",
					["EnableExtendedSpectatorPlayerList"] = "extendedSpectatorList",
					["EnableLoadingWaitPlayerList"] = "customLoadingScreen",
					["EnableExtendedInGameMenuPlayerList"] = "extendedInGameMenuPlayerList",
					["EnableDamageHealthGlow"] = "damageHealthGlow",
					["EnableFloatingDamageNumbers"] = "floatingDamage",
					["FloatingDamageDurationSeconds"] = "floatingDamage",
					["EnableFpsUi"] = "fpsUi",
					["EnableFpsUiInventoryNetWorth"] = "fpsUi",
					["EnableInventorySlotOptimization"] = "inventorySlotOptimization",
					["InventoryPickupSelectMode"] = "inventorySlotOptimization",
					["EnableInventorySelectNextOnRemove"] = "inventorySlotOptimization",
					["EnableInventoryNumberKeySelection"] = "inventoryNumberKeys",
					["RoundStartSoundMode"] = "roundStartSound",
					["RoundStartSoundRandomPool"] = "roundStartSound",
					["RoundStartSoundVariant"] = "roundStartSound",
					["RoundStartSoundVolume"] = "roundStartSound",
					["DiscoBallSoundMode"] = "discoBallSound",
					["DiscoBallSoundRandomPool"] = "discoBallSound",
					["DiscoBallSoundVariant"] = "discoBallSound",
					["DiscoBallSoundVolume"] = "discoBallSound",
					["CustomLoadingScreenMode"] = "customLoadingScreen",
					["CustomLoadingScreenRandomPool"] = "customLoadingScreen",
					["CustomLoadingScreenVariant"] = "customLoadingScreen",
					["CustomLoadingScreenMotion"] = "customLoadingScreen",
					["SpectatorVoiceBalanceMode"] = "spectatorVoiceBalance",
					["SpectatorVoiceAttenuation"] = "spectatorVoiceBalance",
					["SpectatorVoiceDuckLevel"] = "spectatorVoiceBalance",
					["EnableVoiceNoiseGate"] = "voiceNoiseGate",
					["VoiceNoiseGateStrength"] = "voiceNoiseGate"
				}, 
				"MimesisPlayerEnhancement_Privacy" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["BlockReluTelemetry"] = "telemetry",
					["BlockReplayUpload"] = "replay",
					["BlockReplayRecording"] = "replay",
					["BlockCrashReports"] = "crashReports",
					["StripCrashReportMetadata"] = "crashReports",
					["BlockKraftonGppSdk"] = "thirdParty"
				}, 
				"MimesisPlayerEnhancement_SavegamePreparation" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["StartupMoney"] = "startupMoney",
					["StartingZone"] = "startingZone",
					["EnableUpgradeTramHorn"] = "upgrades",
					["EnableUpgradeScrapScanner"] = "upgrades",
					["EnableUpgradeTramBooster"] = "upgrades",
					["EnableUpgradeTramLight"] = "upgrades"
				}, 
				"MimesisPlayerEnhancement_MoreVoices" => new Dictionary<string, string>(StringComparer.Ordinal)
				{
					["UnifyIndoorOutdoorVoices"] = "voiceLimits",
					["MaxIndoorVoiceEvents"] = "voiceLimits",
					["MaxDeathMatchVoiceEvents"] = "voiceLimits",
					["MaxOutdoorVoiceEvents"] = "voiceLimits",
					["RecordVoiceInMaintenance"] = "voiceRecording",
					["RecordVoiceInTram"] = "voiceRecording",
					["RecordVoiceDuringMimicPossession"] = "voiceRecording"
				}, 
				_ => new Dictionary<string, string>(StringComparer.Ordinal), 
			};
		}

		private static List<WebDashboardConfigSelectOptionDto> BuildRoundStartSoundVariantOptions()
		{
			List<WebDashboardConfigSelectOptionDto> list = new List<WebDashboardConfigSelectOptionDto>();
			foreach (string item in RoundStartSoundResolver.ListVariantOptionValues())
			{
				string configSelectOptionLabel = WebDashboardL10n.GetConfigSelectOptionLabel("MimesisPlayerEnhancement_Ui", "RoundStartSoundVariant", item);
				list.Add(new WebDashboardConfigSelectOptionDto
				{
					Value = item,
					Label = (string.IsNullOrWhiteSpace(configSelectOptionLabel) ? RoundStartSoundResolver.FormatVariantDisplayName(item) : configSelectOptionLabel)
				});
			}
			return list;
		}

		private static List<WebDashboardConfigSelectOptionDto> BuildDiscoBallSoundVariantOptions()
		{
			List<WebDashboardConfigSelectOptionDto> list = new List<WebDashboardConfigSelectOptionDto>();
			foreach (string item in DiscoBallSoundResolver.ListVariantOptionValues())
			{
				string configSelectOptionLabel = WebDashboardL10n.GetConfigSelectOptionLabel("MimesisPlayerEnhancement_Ui", "DiscoBallSoundVariant", item);
				list.Add(new WebDashboardConfigSelectOptionDto
				{
					Value = item,
					Label = (string.IsNullOrWhiteSpace(configSelectOptionLabel) ? DiscoBallSoundResolver.FormatVariantDisplayName(item) : configSelectOptionLabel)
				});
			}
			return list;
		}

		private static List<WebDashboardConfigSelectOptionDto> BuildCustomLoadingScreenVariantOptions()
		{
			List<WebDashboardConfigSelectOptionDto> list = new List<WebDashboardConfigSelectOptionDto>();
			foreach (string item in CustomLoadingScreenResolver.ListVariantOpti