Decompiled source of REPO Werewolf v1.5.0

BepInEx/plugins/Minorunara_Werewolf/Minorunara_Werewolf.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Photon.Voice.Unity;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.InputSystem;
using UnityEngine.TextCore;
using UnityEngine.UI;
using Werewolf.Core;
using Werewolf.Core.Replay;
using Werewolf.Debugging;
using Werewolf.Game;
using Werewolf.Game.Patches;
using Werewolf.Net;
using Werewolf.Scenarios.Core;
using Werewolf.Scenarios.Game;
using Werewolf.Scenarios.UI;
using Werewolf.Scenarios.Vanilla;
using Werewolf.UI;
using Werewolf.Vanilla;

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

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	internal static class IsExternalInit
	{
	}
}
namespace Werewolf
{
	internal sealed class ConfigBindings
	{
		private const string SecGeneral = "01. General";

		private const string SecMeeting = "02. Meeting";

		private const string SecRoleAssignment = "03. Role Assignment";

		private const string SecShaman = "04. Shaman";

		private const string SecWerewolf = "05. Werewolf";

		private const string SecBlackCat = "06. Black Cat";

		private const string SecBomber = "07. Bomber";

		internal const string SecStage = "08. Stage";

		private const string SecPlayerUpgrades = "09. Player Upgrades";

		internal const string SecLoadoutItems = "10. Loadout Items";

		private const string SecClientKeybinds = "Client Keybinds";

		private const string SecClientUi = "Client UI";

		private const string SecStreamer = "Streamer";

		private const string SecTutorial = "Tutorial";

		private const string SecScenario = "Tutorial Scenarios";

		private const string SecVoice = "Voice";

		private const string SecDebug = "Debug";

		internal ConfigEntry<int> WerewolfCount;

		internal ConfigEntry<int> BlackCatChancePercent;

		internal ConfigEntry<int> PeacefulVillageChancePercent;

		internal ConfigEntry<int> BomberChancePercent;

		internal ConfigEntry<int> RoundSeconds;

		internal ConfigEntry<int> BlackCatRevealDelaySec;

		internal ConfigEntry<bool> BlackCatCurseEnabled;

		internal ConfigEntry<bool> DebugMode;

		internal ConfigEntry<bool> DebugLogging;

		internal ConfigEntry<int> ShamanChancePercent;

		internal ConfigEntry<int> ShamanGazeFullSec;

		internal ConfigEntry<int> ShamanGhostCooldownSec;

		internal ConfigEntry<int> ShamanStormWeakMeters;

		internal ConfigEntry<int> ShamanStormMediumMeters;

		internal ConfigEntry<int> ShamanStormStrongMeters;

		internal ConfigEntry<int> BomberProximityMeters;

		internal ConfigEntry<int> BomberGaugeFullSec;

		internal ConfigEntry<int> BomberInitialCooldownSec;

		internal ConfigEntry<int> BomberCooldownSec;

		internal ConfigEntry<int> BomberBlastRadiusMeters;

		internal ConfigEntry<int> BomberBlastPlayerDamage;

		internal ConfigEntry<int> BomberBlastEnemyDamage;

		internal ConfigEntry<int> BomberAmmoRefillPct;

		internal ConfigEntry<KeyCode> BomberPlantKey;

		internal ConfigEntry<KeyCode> BomberDetonateKey;

		internal ConfigEntry<string> Language;

		internal ConfigEntry<int> MeetingRightsPerPlayer;

		internal ConfigEntry<int> ConveneSuppressStartSec;

		internal ConfigEntry<int> ConveneSuppressAfterSec;

		internal ConfigEntry<int> MeetingCountdownSec;

		internal ConfigEntry<int> MeetingDurationSec;

		internal ConfigEntry<bool> VoteTimeCutEnabled;

		internal ConfigEntry<int> ResultDisplaySec;

		internal ConfigEntry<bool> MeetingScatterEnabled;

		internal ConfigEntry<int> ScatterGuardSec;

		internal ConfigEntry<int> MeetingEnemyRespawnScalePct;

		internal ConfigEntry<float> ButtonOffsetX;

		internal ConfigEntry<float> ButtonOffsetY;

		internal ConfigEntry<float> ButtonOffsetZ;

		internal ConfigEntry<float> ButtonYaw;

		internal ConfigEntry<float> ButtonPitch;

		internal ConfigEntry<int> StaminaUnlockPct;

		internal ConfigEntry<int> JumpUnlockPct;

		internal ConfigEntry<int> EnemyIgnoreUnlockPct;

		internal ConfigEntry<int> HealUnlockPct;

		internal ConfigEntry<int> HealIntervalSec;

		internal ConfigEntry<int> BeaconChargePct;

		internal ConfigEntry<int> InformantThresholdPct;

		internal ConfigEntry<int> ExtraJumpCount;

		internal ConfigEntry<int> BeaconCooldownSec;

		internal ConfigEntry<int> BeaconSuppressStartSec;

		internal ConfigEntry<int> BeaconSuppressAfterMeetingSec;

		internal ConfigEntry<int> CatGaugeSyncIntervalSec;

		internal ConfigEntry<bool> OrbGaugeEnabled;

		internal ConfigEntry<KeyCode> WolfModeKey;

		internal ConfigEntry<KeyCode> BeaconKey;

		internal ConfigEntry<bool> WerewolfModeEnabled;

		internal ConfigEntry<bool> MinimapHideEnabled;

		internal ConfigEntry<bool> OutfitChangeAllowed;

		internal ConfigEntry<int> ValuableMapMode;

		internal ConfigEntry<int> GameOverAutoReturnSec;

		internal ConfigEntry<int> ToastDurationSec;

		internal ConfigEntry<KeyCode> LobbySettingsPanelKey;

		internal ConfigEntry<KeyCode> ManualKey;

		internal ConfigEntry<KeyCode> CorpseReportKey;

		internal ConfigEntry<KeyCode> ResultReturnKey;

		internal ConfigEntry<KeyCode> VoidMatchKey;

		internal ConfigEntry<KeyCode> MeetingMapKey;

		internal ConfigEntry<KeyCode> MeetingChatLogKey;

		internal ConfigEntry<KeyCode> ReplayViewerKey;

		internal ConfigEntry<float> MeetingMapOrthoSize;

		internal ConfigEntry<int> MeetingMapResolution;

		internal ConfigEntry<bool> MeetingMapGrid;

		internal ConfigEntry<bool> MeetingChatLog;

		internal ConfigEntry<int> NecroVoiceMode;

		internal ConfigEntry<float> NecroVoiceVolume;

		internal ConfigEntry<float> NecroVoiceLowPassCutoffHz;

		internal ConfigEntry<float> NecroVoiceEchoDelayMs;

		internal ConfigEntry<float> NecroVoiceEchoDecay;

		internal ConfigEntry<float> NecroVoiceReverbRoom;

		internal ConfigEntry<float> NecroVoiceReverbRoomHF;

		internal ConfigEntry<float> NecroVoiceReverbDecayTime;

		internal ConfigEntry<float> NecroVoiceReverbDecayHFRatio;

		internal ConfigEntry<float> NecroVoiceReverbReflections;

		internal ConfigEntry<float> NecroVoiceReverbReflectionsDelay;

		internal ConfigEntry<float> NecroVoiceReverbLevel;

		internal ConfigEntry<float> NecroVoiceReverbDelay;

		internal ConfigEntry<float> NecroVoiceReverbDiffusion;

		internal ConfigEntry<float> NecroVoiceReverbDensity;

		internal ConfigEntry<float> NecroVoiceReverbHFReference;

		private Dictionary<TutorialId, ConfigEntry<bool>> _tutorialSeen;

		internal ConfigEntry<bool> ResetTutorials;

		internal ConfigEntry<float> TutorialFontScale;

		private Dictionary<ScenarioId, ConfigEntry<bool>> _scenarioCleared;

		internal ConfigEntry<bool> StreamerSafeMode;

		internal ConfigEntry<float> CursorMirrorScale;

		internal ConfigEntry<int> HudOffsetX;

		internal ConfigEntry<int> HudOffsetY;

		internal ConfigEntry<int> StartLevelNumber;

		internal ConfigEntry<string> StartMapName;

		internal ConfigEntry<int> StartEnergyPct;

		internal ConfigEntry<int> OrbDropMax;

		internal ConfigEntry<int> StartHaulGoalPct;

		internal ConfigEntry<int> EnemySetsDanger1;

		internal ConfigEntry<int> EnemySetsDanger2;

		internal ConfigEntry<int> EnemySetsDanger3;

		private Dictionary<string, ConfigEntry<int>> _startUpgrades;

		private readonly ValuableMapMode _valuableMapModeDefault;

		private readonly NecroVoiceMode _necroVoiceModeDefault;

		internal Func<string> ItemsSpecProvider { get; set; }

		internal ConfigBindings(ConfigFile config)
		{
			GameConfig gameConfig = new GameConfig();
			_valuableMapModeDefault = gameConfig.ValuableMapMode;
			_necroVoiceModeDefault = gameConfig.NecroVoiceMode;
			BindGeneral(config, gameConfig);
			BindMeeting(config, gameConfig);
			BindRoleAssignment(config, gameConfig);
			BindShaman(config, gameConfig);
			BindWerewolf(config, gameConfig);
			BindBlackCat(config, gameConfig);
			BindBomber(config, gameConfig);
			BindStage(config, gameConfig);
			BindPlayerUpgrades(config, gameConfig);
			BindClientKeybinds(config, gameConfig);
			BindClientUi(config, gameConfig);
			BindStreamer(config, gameConfig);
			BindTutorial(config, gameConfig);
			BindVoice(config, gameConfig);
			BindDebug(config, gameConfig);
		}

		private void BindGeneral(ConfigFile config, GameConfig defaults)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			WerewolfModeEnabled = config.Bind<bool>("01. General", "WerewolfModeEnabled", true, "Werewolf mode ON/OFF. While true, rounds are played as werewolf sessions. Host authoritative: only the host's value applies to the room / 人狼モードのON/OFF。true の間はラウンドが人狼セッションとして進行する。ホスト権威(部屋に効くのはホストの値のみ。参加者側の値は自分がホストのときにだけ効く)");
			Language = config.Bind<string>("01. General", "Language (restart required)", "English", new ConfigDescription("Display language (restart required). 日本語 = built-in Japanese, English = built-in English, custom = load Lang/custom.txt next to the DLL. A matching Lang file (Lang/en.txt for English, Lang/custom.txt for custom), if present, overrides the built-in text per key (missing keys fall back to the built-in table) / 表示言語(反映には再起動が必要)。日本語=埋め込み日本語, English=埋め込み英語, custom=DLL同階層の Lang/custom.txt。対応する Lang ファイル(English は Lang/en.txt)があればキー単位で埋め込み文言を上書きする(欠落キーは埋め込みへフォールバック)", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "日本語", "English", "custom" }), Array.Empty<object>()));
			RoundSeconds = config.Bind<int>("01. General", "RoundSeconds", defaults.RoundSeconds, new ConfigDescription("Round time limit (seconds) / ラウンド制限時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(180, 3600), Array.Empty<object>()));
			MinimapHideEnabled = config.Bind<bool>("01. General", "MinimapHideEnabled", defaults.MinimapHideEnabled, "Hide valuables and corpses from the minimap / 貴重品・死体のミニマップ非表示設定");
			OutfitChangeAllowed = config.Bind<bool>("01. General", "OutfitChangeAllowed", defaults.OutfitChangeAllowed, "Allow appearance (cosmetic) changes during a match (impersonation play) / 試合中の見た目(コスメ)変更を許可する(着替えなりすましを遊びとして認める)");
			ValuableMapMode = config.Bind<int>("01. General", "ValuableMapMode", (int)defaults.ValuableMapMode, new ConfigDescription("Valuable map mode (0 = realtime, 1 = meeting sync (recommended; positions freeze at discovery and snapshot at meeting start / extraction complete), 2 = hidden) / 貴重品マップ表示モード(0=リアルタイム, 1=会議同期(推奨・発見時の位置で静止表示し会議開始/抽出完了時にスナップショット更新), 2=非表示)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
			OrbGaugeEnabled = config.Bind<bool>("01. General", "OrbGaugeEnabled", defaults.OrbGaugeEnabled, "Whether value lost as enemy-dropped orbs counts toward the perk gauge / 敵ドロップ品(オーブ)の減額を特典ゲージへ算入するか");
			NecroVoiceMode = config.Bind<int>("01. General", "NecroVoiceMode", (int)_necroVoiceModeDefault, new ConfigDescription("Netherworld voice eavesdrop mode (0 = OFF, 1 = non-werewolf dead, 2 = all dead). Host setting, synced to all clients / 冥界の声の傍聴モード(0=OFF, 1=人狼以外の死者, 2=全死者)。ホスト設定で全クライアントに同期される", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
			GameOverAutoReturnSec = config.Bind<int>("01. General", "GameOverAutoReturnSec", defaults.GameOverAutoReturnSec, new ConfigDescription("Fallback: seconds until the result screen auto-returns to the lobby when the host does not press the return key (0 = never) / ホストが帰還キーを押さない場合に結果画面から自動でロビーへ戻るまでの保険秒数(0=自動で戻らない)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
		}

		private void BindMeeting(ConfigFile config, GameConfig defaults)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			MeetingRightsPerPlayer = config.Bind<int>("02. Meeting", "MeetingRightsPerPlayer", defaults.MeetingRightsPerPlayer, new ConfigDescription("Emergency meeting calls per player. Consumed only when a call is accepted / 1人あたりの会議開催権の回数。召集が受理された時点でのみ消費する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
			MeetingCountdownSec = config.Bind<int>("02. Meeting", "MeetingCountdownSec", defaults.MeetingCountdownSec, new ConfigDescription("Lead time from the meeting announcement until everyone warps (seconds) / 会議開始通知から全員ワープまでの予告時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), Array.Empty<object>()));
			MeetingDurationSec = config.Bind<int>("02. Meeting", "MeetingDurationSec", defaults.MeetingDurationSec, new ConfigDescription("Meeting time limit (seconds). End time = warp time + this value / 会議の制限時間(秒)。終了時刻 = ワープ時刻 + この秒数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 600), Array.Empty<object>()));
			VoteTimeCutEnabled = config.Bind<bool>("02. Meeting", "VoteTimeCutEnabled", defaults.VoteTimeCutEnabled, "Whether each accepted vote shortens the remaining meeting time by a share based on the number of living players / 投票が受理されるたびに会議残り時間を生存人数に応じた割合で短縮するか");
			ResultDisplaySec = config.Bind<int>("02. Meeting", "ResultDisplaySec", defaults.ResultDisplaySec, new ConfigDescription("How long the vote results stay on screen before play resumes (seconds) / 開票結果の表示保持時間(秒)。この経過後に通常プレイへ復帰する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
			MeetingScatterEnabled = config.Bind<bool>("02. Meeting", "MeetingScatterEnabled", defaults.MeetingScatterEnabled, "Reshuffle surviving players into random groups of 3+ and warp each group to its own destination (truck / completed extraction points) when a meeting ends. Groups are announced to everyone, destinations stay hidden. No scatter below 6 survivors or before the first completed extraction (prevents fixed patrol groups) / 会議終了時に生存者を3人以上の組へ無作為に組み替え、組ごとにトラック+納品済み抽出地点の別行き先へ分散ワープさせるか(固定グループ巡回の防止。組分けは全員へ発表・行き先は非公開。生存6人未満・最初の納品完了前は分散なし)");
			ScatterGuardSec = config.Bind<int>("02. Meeting", "ScatterGuardSec", defaults.ScatterGuardSec, new ConfigDescription("Guard window after a scatter warp (seconds). If anyone dies within this window right after groups scattered, the host auto-convenes an immediate meeting (no warning countdown, no meeting right consumed) shown as a \"handover incident\" — punishes spawn-kills right after warp-in. 0 = off. Not triggered during the last run / 散開ワープ後の監視時間(秒)。分散直後のこの時間内に死亡が発生するとホストが即時会議(予告なし=即時ワープ・開催権消費なし・「引き継ぎのトラブル」表示)を自動召集する=着地直後の即キルの逃げ得防止。0=無効。ラストラン中は発火しない", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
			MeetingEnemyRespawnScalePct = config.Bind<int>("02. Meeting", "MeetingEnemyRespawnScalePct", defaults.MeetingEnemyRespawnScalePct, new ConfigDescription("How fast enemy respawn timers (and the stay-too-long respawn-interval ramp) keep running while a meeting suppresses enemies (%). Default 75 = three quarters of real time, 100 = real time as vanilla, 0 = fully paused (enemies come back exactly as they were before the meeting). Lower this for text-chat lobbies where meetings run long / 会議の敵抑制中に敵のリスポーンタイマーと滞在時間によるリスポーン間隔短縮が進む速さ(%)。既定75=実時間の3/4で進む、100=バニラどおり実時間で進む、0=一切進まない(会議前後で敵の復活状況が同一)。テキストチャット主体で会議が長引くロビーはさらに下げる", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			ConveneSuppressStartSec = config.Bind<int>("02. Meeting", "ConveneSuppressStartSec", defaults.ConveneSuppressStartSec, new ConfigDescription("Time right after the game starts during which meetings cannot be called (seconds) / ゲーム開始直後に会議召集を抑止する時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
			ConveneSuppressAfterSec = config.Bind<int>("02. Meeting", "ConveneSuppressAfterSec", defaults.ConveneSuppressAfterSec, new ConfigDescription("Time right after a meeting ends during which the next meeting cannot be called (seconds) / 会議終了直後に次の会議召集を抑止する時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
		}

		private void BindRoleAssignment(ConfigFile config, GameConfig defaults)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			ShamanChancePercent = config.Bind<int>("03. Role Assignment", "ShamanChancePercent", defaults.ShamanChancePercent, new ConfigDescription("Shaman appearance chance P_shaman (0..100%). Villager-side variant: one villager is converted, werewolf count N is unaffected / 祈祷師の出現確率 P_shaman(0..100%)。村人側変種=当選時に村人1名が変換され、人狼の人数 N には影響しない", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			WerewolfCount = config.Bind<int>("03. Role Assignment", "WerewolfCount", defaults.WerewolfCount, new ConfigDescription("Number of werewolves N (Werewolf slots; a winning Bomber roll converts one slot, always leaving at least one pure Werewolf). The Black Cat mutates from the villager side and is not counted here / 人狼の人数 N(人狼枠。爆弾魔当選時はこの枠の1人が爆弾魔へ変異する。純人狼は最低1人残る)。黒猫は村人陣営から変異するためこの人数には含まれない", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			BlackCatChancePercent = config.Bind<int>("03. Role Assignment", "BlackCatChancePercent", defaults.BlackCatChancePercent, new ConfigDescription("Black Cat appearance chance P_cat (0..100%). The Black Cat mutates from one villager and joins the werewolf team; rolls happen only while at least one villager would remain / 黒猫の出現確率 P_cat(0..100%)。黒猫は村人陣営から変異して人狼陣営に加わる(変異後も村人が最低1人残る構成でのみ抽選)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			BomberChancePercent = config.Bind<int>("03. Role Assignment", "BomberChancePercent", defaults.BomberChancePercent, new ConfigDescription("Bomber appearance chance P_bomber (0..100%). The Bomber mutates from one werewolf slot (needs werewolves >= 2) / 爆弾魔の出現確率 P_bomber(0..100%)。爆弾魔は人狼枠から変異する(人狼の人数2以上で抽選)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			PeacefulVillageChancePercent = config.Bind<int>("03. Role Assignment", "PeacefulVillageChancePercent", defaults.PeacefulVillageChancePercent, new ConfigDescription("Peaceful village chance P_peace (0..100%). A winning roll puts nobody in the werewolf slots: everyone is a villager (no Black Cat or Bomber; a Shaman may still appear). Nobody can tell during the match / 平和村の確率 P_peace(0..100%)。当選した試合は人狼枠に誰も入らず全員が村人陣営になる(黒猫・爆弾魔も出ない。祈祷師は出得る)。試合中は誰にも分からない", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		}

		private void BindShaman(ConfigFile config, GameConfig defaults)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			ShamanGazeFullSec = config.Bind<int>("04. Shaman", "ShamanGazeFullSec", defaults.ShamanGazeFullSec, new ConfigDescription("Seconds of keeping the nearest unannounced corpse in view to trigger the spirit vision (decays at double speed while out of view) / 霊表示に必要な注視秒数(最寄りの未周知死体が視界内で蓄積・視界外は倍速減衰)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			ShamanGhostCooldownSec = config.Bind<int>("04. Shaman", "ShamanGhostCooldownSec", defaults.ShamanGhostCooldownSec, new ConfigDescription("Cooldown after the spirit vision ends before it can charge again (seconds) / 霊表示終了から再蓄積可能になるまでのクールダウン(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 120), Array.Empty<object>()));
			ShamanStormWeakMeters = config.Bind<int>("04. Shaman", "ShamanStormWeakMeters", defaults.ShamanStormWeakMeters, new ConfigDescription("Radius of the weak haunting ring around an unannounced corpse (m) / 霊障(弱)の発動半径(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			ShamanStormMediumMeters = config.Bind<int>("04. Shaman", "ShamanStormMediumMeters", defaults.ShamanStormMediumMeters, new ConfigDescription("Radius of the medium haunting ring (m) / 霊障(中)の発動半径(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			ShamanStormStrongMeters = config.Bind<int>("04. Shaman", "ShamanStormStrongMeters", defaults.ShamanStormStrongMeters, new ConfigDescription("Radius of the strong haunting ring (m) / 霊障(強)の発動半径(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
		}

		private void BindWerewolf(ConfigFile config, GameConfig defaults)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Expected O, but got Unknown
			StaminaUnlockPct = config.Bind<int>("05. Werewolf", "StaminaUnlockPct", defaults.StaminaUnlockPct, new ConfigDescription("Unlock threshold for infinite stamina (% of the map's total valuable value destroyed) / 無限スタミナの解禁閾値(マップ総貴重品額に対する減額%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			JumpUnlockPct = config.Bind<int>("05. Werewolf", "JumpUnlockPct", defaults.JumpUnlockPct, new ConfigDescription("Unlock threshold for extra jumps (%) / 追加ジャンプの解禁閾値(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			ExtraJumpCount = config.Bind<int>("05. Werewolf", "ExtraJumpCount", defaults.ExtraJumpCount, new ConfigDescription("Extra mid-air jumps (-1 = effectively unlimited) / 滞空中の追加ジャンプ回数(-1=実質無限)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 20), Array.Empty<object>()));
			EnemyIgnoreUnlockPct = config.Bind<int>("05. Werewolf", "EnemyIgnoreUnlockPct", defaults.EnemyIgnoreUnlockPct, new ConfigDescription("Unlock threshold for enemy ignore (%) / 敵認識無効の解禁閾値(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			HealUnlockPct = config.Bind<int>("05. Werewolf", "HealUnlockPct", defaults.HealUnlockPct, new ConfigDescription("Unlock threshold for regeneration (%) / 自然治癒の解禁閾値(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			HealIntervalSec = config.Bind<int>("05. Werewolf", "HealIntervalSec", defaults.HealIntervalSec, new ConfigDescription("Regeneration interval while Wolf Mode is on (seconds per 1 HP) / 狼化中の自然治癒の回復間隔(1HPあたりの秒数)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
			BeaconChargePct = config.Bind<int>("05. Werewolf", "BeaconChargePct", defaults.BeaconChargePct, new ConfigDescription("Threshold per beacon charge (%; each multiple reached grants every werewolf one use) / ビーコン1チャージあたりの閾値(%。この倍数の到達ごとに各人狼へ1回分付与)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			BeaconCooldownSec = config.Bind<int>("05. Werewolf", "BeaconCooldownSec", defaults.BeaconCooldownSec, new ConfigDescription("Beacon cooldown (seconds) / ビーコンのクールダウン時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600), Array.Empty<object>()));
			BeaconSuppressStartSec = config.Bind<int>("05. Werewolf", "BeaconSuppressStartSec", defaults.BeaconSuppressStartSec, new ConfigDescription("Time right after the game starts during which the beacon cannot be used (seconds) / ゲーム開始直後のビーコン使用抑止時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 180), Array.Empty<object>()));
			BeaconSuppressAfterMeetingSec = config.Bind<int>("05. Werewolf", "BeaconSuppressAfterMeetingSec", defaults.BeaconSuppressAfterMeetingSec, new ConfigDescription("Time right after a meeting ends during which the beacon cannot be used (seconds) / 会議終了直後のビーコン使用抑止時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 180), Array.Empty<object>()));
		}

		private void BindBlackCat(ConfigFile config, GameConfig defaults)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			BlackCatRevealDelaySec = config.Bind<int>("06. Black Cat", "BlackCatRevealDelaySec", defaults.BlackCatRevealDelaySec, new ConfigDescription("Delay from game start until the Black Cat is privately notified of its role (seconds) / ゲーム開始から黒猫本人へ自覚通知するまでの遅延(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			BlackCatCurseEnabled = config.Bind<bool>("06. Black Cat", "BlackCatCurseEnabled", defaults.BlackCatCurseEnabled, "Enable the Black Cat's drag-down ability when executed / 黒猫が処刑されたときの道連れ能力を有効にする");
			InformantThresholdPct = config.Bind<int>("06. Black Cat", "InformantThresholdPct", defaults.InformantThresholdPct, new ConfigDescription("Informant threshold: reveals the werewolf list to the Black Cat (%; a high value not reached early is recommended) / 内通(黒猫への人狼一覧開示)の閾値(%。序盤に到達しない高めを推奨)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			CatGaugeSyncIntervalSec = config.Bind<int>("06. Black Cat", "CatGaugeSyncIntervalSec", defaults.CatGaugeSyncIntervalSec, new ConfigDescription("Gauge sync interval to the Black Cat (seconds; 0 = realtime. Werewolves always get realtime. Meeting start/end always refreshes regardless of the interval) / 黒猫へのゲージ配信間隔(秒。0=リアルタイム配信。人狼へは常にリアルタイム。会議開始・終了時は間隔に関係なく更新される)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600), Array.Empty<object>()));
		}

		private void BindBomber(ConfigFile config, GameConfig defaults)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			BomberProximityMeters = config.Bind<int>("07. Bomber", "BomberProximityMeters", defaults.BomberProximityMeters, new ConfigDescription("Distance within which the Bomber counts a plant target as close contact (m) / 爆弾魔がプラント対象を至近と見なす距離(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			BomberGaugeFullSec = config.Bind<int>("07. Bomber", "BomberGaugeFullSec", defaults.BomberGaugeFullSec, new ConfigDescription("Total seconds of close contact needed to fill the proximity gauge / 近接ゲージが満タンになるまでの累計滞在秒", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
			BomberInitialCooldownSec = config.Bind<int>("07. Bomber", "BomberInitialCooldownSec", defaults.BomberInitialCooldownSec, new ConfigDescription("Initial cooldown after the match starts; proximity gauges are paused during it (seconds) / 試合開始直後の専用クールダウン。この間は近接ゲージも停止(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 180), Array.Empty<object>()));
			BomberCooldownSec = config.Bind<int>("07. Bomber", "BomberCooldownSec", defaults.BomberCooldownSec, new ConfigDescription("Cooldown after meetings, planting, re-planting, and detonation (seconds) / 会議後・プラント・付替・爆破後クールダウン(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
			BomberAmmoRefillPct = config.Bind<int>("07. Bomber", "BomberAmmoRefillPct", defaults.BomberAmmoRefillPct, new ConfigDescription("Perk-gauge share required to refill one bomb (%) / 弾1発の補充に要する特典ゲージ割合%", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			BomberBlastRadiusMeters = config.Bind<int>("07. Bomber", "BomberBlastRadiusMeters", Mathf.RoundToInt(defaults.BomberBlastRadiusMeters), new ConfigDescription("Blast radius / warning-sound audible radius (m, integer) / 爆風半径・警告音可聴半径(m・整数)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			BomberBlastPlayerDamage = config.Bind<int>("07. Bomber", "BomberBlastPlayerDamage", defaults.BomberBlastPlayerDamage, new ConfigDescription("Damage to nearby players / 周囲プレイヤーへのダメージ", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 999), Array.Empty<object>()));
			BomberBlastEnemyDamage = config.Bind<int>("07. Bomber", "BomberBlastEnemyDamage", defaults.BomberBlastEnemyDamage, new ConfigDescription("Damage to enemies / 敵ダメージ", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 999), Array.Empty<object>()));
		}

		private void BindStage(ConfigFile config, GameConfig defaults)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			StartLevelNumber = config.Bind<int>("08. Stage", "StartLevelNumber", defaults.StartLevelNumber, new ConfigDescription("Level of the werewolf session (the N in the on-screen \"Level N\") / 人狼セッションのレベル(画面表示「Level N」の N)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			StartMapName = config.Bind<string>("08. Stage", "StartMapName", "", "Map type name for the werewolf session. Empty = random (vanilla default selection). Unknown names also mean random / 人狼セッションの開始マップ種別名。空 = ランダム(バニラ既定の選択)。実在しない名前もランダム扱い");
			StartEnergyPct = config.Bind<int>("08. Stage", "StartEnergyPct", defaults.StartEnergyPct, new ConfigDescription("Truck charger level at session start (%; 0 = empty, 100 = full) / トラック充電器の開始時充電量(%。0 = 空, 100 = 満充電)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			OrbDropMax = config.Bind<int>("08. Stage", "OrbDropMax", defaults.OrbDropMax, new ConfigDescription("Number of valuable orbs dropped when an enemy dies (vanilla = 3) / 敵撃破時にドロップする貴重品オーブの数(バニラ = 3)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>()));
			StartHaulGoalPct = config.Bind<int>("08. Stage", "StartHaulGoalPct", defaults.StartHaulGoalPct, new ConfigDescription("Extraction quota as a percentage of the map's total valuable value (0 = vanilla). The Werewolves win by checkmate once (100 - this) percent of the map is destroyed / 抽出ノルマをマップ総貴重品額の割合で指定する(0 = バニラのまま)。マップの(100-指定値)%を壊すと人狼の詰み勝ちになる", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			EnemySetsDanger1 = BindEnemySets(config, "EnemySetsDanger1", defaults.EnemySetsDanger1, "tier 1 (weak)", "ティア1(弱)");
			EnemySetsDanger2 = BindEnemySets(config, "EnemySetsDanger2", defaults.EnemySetsDanger2, "tier 2 (medium)", "ティア2(中)");
			EnemySetsDanger3 = BindEnemySets(config, "EnemySetsDanger3", defaults.EnemySetsDanger3, "tier 3 (strong)", "ティア3(強)");
		}

		private static ConfigEntry<int> BindEnemySets(ConfigFile config, string key, int defaultValue, string tierEn, string tierJa)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			return config.Bind<int>("08. Stage", key, defaultValue, new ConfigDescription("Number of enemy sets rolled for " + tierEn + " regardless of level (-1 = vanilla curve, 0 = none). A set is one roll, not one body: some sets spawn several enemies at once / " + tierJa + "の敵セット数。レベルに関係なく決める(-1 = バニラのカーブのまま、0 = 引かない)。1セット=1抽選で体数ではなく、1セットで複数体湧くものがある", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 20), Array.Empty<object>()));
		}

		private void BindPlayerUpgrades(ConfigFile config, GameConfig defaults)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			Dictionary<string, int> dictionary = new Dictionary<string, int>
			{
				["Health"] = 1,
				["Strength"] = 2
			};
			_startUpgrades = new Dictionary<string, ConfigEntry<int>>(WorldgenUpgrades.Names.Count);
			foreach (string name in WorldgenUpgrades.Names)
			{
				int value;
				int num = (dictionary.TryGetValue(name, out value) ? value : 0);
				_startUpgrades[name] = config.Bind<int>("09. Player Upgrades", "StartUpgrade" + name, num, new ConfigDescription("Starting upgrade level shared by all players (" + name + "). 0 = no upgrade / 全プレイヤー共通の開始時強化段階(" + name + ")。0 = 強化なし", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>()));
			}
		}

		private void BindClientKeybinds(ConfigFile config, GameConfig defaults)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Expected O, but got Unknown
			WolfModeKey = config.Bind<KeyCode>("Client Keybinds", "WolfModeKey", (KeyCode)102, new ConfigDescription("Key binding for the Wolf Mode toggle (bulk ON/OFF of unlocked perks) / 狼化トグル(解禁済み特典の一括ON/OFF)のキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			BeaconKey = config.Bind<KeyCode>("Client Keybinds", "BeaconKey", (KeyCode)103, new ConfigDescription("Key binding for using the beacon / ビーコン使用のキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			BomberPlantKey = config.Bind<KeyCode>("Client Keybinds", "BomberPlantKey", (KeyCode)102, new ConfigDescription("Key binding for the Bomber's plant (turn a player into a bomb) / 爆弾魔のプラント(爆弾化)キーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			BomberDetonateKey = config.Bind<KeyCode>("Client Keybinds", "BomberDetonateKey", (KeyCode)103, new ConfigDescription("Key binding for the Bomber's detonation / 爆弾魔の起爆キーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			CorpseReportKey = config.Bind<KeyCode>("Client Keybinds", "CorpseReportKey", (KeyCode)114, new ConfigDescription("Key binding to report an emergency meeting near an undiscovered body (dead player's head) / 未発見の死体(死者頭部)の近くで押すと緊急会議を通報するキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			MeetingMapKey = config.Bind<KeyCode>("Client Keybinds", "MeetingMapKey", (KeyCode)109, new ConfigDescription("Key binding to toggle the full-map overlay during meetings / 会議中の全体マップオーバーレイのトグルキー", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			MeetingChatLogKey = config.Bind<KeyCode>("Client Keybinds", "MeetingChatLogKey", (KeyCode)108, new ConfigDescription("Key binding to toggle the chat log panel during meetings / 会議チャットログのトグルキー", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			ReplayViewerKey = config.Bind<KeyCode>("Client Keybinds", "ReplayViewerKey", (KeyCode)114, new ConfigDescription("Key binding to toggle the replay viewer on the match result screen / 試合結果画面でリプレイビューアを開閉するキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			LobbySettingsPanelKey = config.Bind<KeyCode>("Client Keybinds", "LobbySettingsPanelKey", (KeyCode)288, new ConfigDescription("Key binding to toggle the lobby settings panel / ロビー設定確認パネルの表示/非表示トグルのキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			ManualKey = config.Bind<KeyCode>("Client Keybinds", "ManualKey", (KeyCode)282, new ConfigDescription("Key binding to toggle the in-game manual / ゲーム内説明書の表示/非表示トグルのキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			ResultReturnKey = config.Bind<KeyCode>("Client Keybinds", "ResultReturnKey", (KeyCode)286, new ConfigDescription("Host only: key binding to return to the lobby from the match result screen / ホスト専用: 試合結果画面からロビーへ戻るキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			VoidMatchKey = config.Bind<KeyCode>("Client Keybinds", "VoidMatchKey", (KeyCode)286, new ConfigDescription("Host only: hold this key to declare the match a no contest / ホスト専用: 長押しで試合を無効試合にするキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
		}

		private void BindClientUi(ConfigFile config, GameConfig defaults)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Expected O, but got Unknown
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Expected O, but got Unknown
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Expected O, but got Unknown
			ButtonOffsetX = config.Bind<float>("Client UI", "ButtonOffsetX", defaults.ButtonOffsetX, new ConfigDescription("Meeting button offset X relative to the truck (fine-tuned on Stage 1) / 会議召集ボタンのトラック基準相対オフセットX", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), new object[1] { "HideFromREPOConfig" }));
			ButtonOffsetY = config.Bind<float>("Client UI", "ButtonOffsetY", defaults.ButtonOffsetY, new ConfigDescription("Meeting button offset Y relative to the truck (fine-tuned on Stage 1) / 会議召集ボタンのトラック基準相対オフセットY", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), new object[1] { "HideFromREPOConfig" }));
			ButtonOffsetZ = config.Bind<float>("Client UI", "ButtonOffsetZ", defaults.ButtonOffsetZ, new ConfigDescription("Meeting button offset Z relative to the truck (fine-tuned on Stage 1) / 会議召集ボタンのトラック基準相対オフセットZ", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), new object[1] { "HideFromREPOConfig" }));
			ButtonYaw = config.Bind<float>("Client UI", "ButtonYaw", defaults.ButtonYaw, new ConfigDescription("Meeting button yaw fine-tune (degrees; tuned on Stage 1) / 会議召集ボタンの向き(Yaw, 度)の微調整", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { "HideFromREPOConfig" }));
			ButtonPitch = config.Bind<float>("Client UI", "ButtonPitch", defaults.ButtonPitch, new ConfigDescription("Meeting button pitch (degrees). 0 = flat facing up, 90 = wall mount (vertical, facing forward) / 会議召集ボタンのピッチ(度)。0=水平面上向き、90=壁面マウント(垂直面前向き)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { "HideFromREPOConfig" }));
			ToastDurationSec = config.Bind<int>("Client UI", "ToastDurationSec", defaults.ToastDurationSec, new ConfigDescription("Toast notification duration (seconds) / トースト通知の表示秒数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), new object[1] { "HideFromREPOConfig" }));
			MeetingMapOrthoSize = config.Bind<float>("Client UI", "MeetingMapOrthoSize", 60f, new ConfigDescription("Camera orthographicSize while the full-map overlay is open (larger = wider view). MiniMap MOD defaults to 2.25 / max 10; a larger default is used here to show the whole level. Needs vary per level, so tune in-game (recommended range 5-50) / 全体マップオーバーレイ表示時のカメラ orthographicSize(大きいほど広範囲)。レベル毎に必要な広さが異なるため実機で調整可(推奨レンジ 5〜50)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.5f, 200f), new object[1] { "HideFromREPOConfig" }));
			MeetingMapResolution = config.Bind<int>("Client UI", "MeetingMapResolution", 1, new ConfigDescription("Full-map overlay render resolution preset. 0=1280x768 / 1=1600x960 / 2=1920x1152 (all 5:3, same aspect as the 1200x720 panel). The vanilla handheld-map RT is low-res and blurry when magnified, so a dedicated RT replaces it while the overlay is open / 全体マップオーバーレイのレンダリング解像度プリセット(0=1280x768 / 1=1600x960 / 2=1920x1152)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), new object[1] { "HideFromREPOConfig" }));
			MeetingMapGrid = config.Bind<bool>("Client UI", "MeetingMapGrid", true, new ConfigDescription("Show an Excel-style coordinate grid on the meeting full-map overlay (columns A,B,C... left to right / rows 1,2,3... top to bottom; one cell = one room module), so locations can be called out like \"the room at C5\" / 会議全体マップにエクセル風の座標グリッド(列=左からA,B,C…・行=上から1,2,3…・1マス=1部屋モジュール)を重ねて表示する(「C5の部屋」のような位置伝達用)", (AcceptableValueBase)null, Array.Empty<object>()));
			MeetingChatLog = config.Bind<bool>("Client UI", "MeetingChatLog", true, new ConfigDescription("Show the chat log panel on the right side of the screen during meetings (speaker avatar and message bubbles, plus a recap of deaths, destroyed valuables, delivery progress and beacon uses). Messages from the dead are shown only to the dead / 会議中に画面右端へ会議チャットログを表示する(発言者アバターと吹き出し+死亡者・破壊された貴重品・納品状況・ビーコン使用の要約)。死者の発言は死者にだけ表示される", (AcceptableValueBase)null, Array.Empty<object>()));
			CursorMirrorScale = config.Bind<float>("Client UI", "CursorMirrorScale", 1f, new ConfigDescription("Scale of the mirror cursor drawn over meeting panels (1.0 = vanilla cursor's measured size) / 会議パネル等の上に重ねるミラーカーソルのサイズ倍率(1.0=バニラカーソルの実測換算そのまま)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
			HudOffsetX = config.Bind<int>("Client UI", "HudOffsetX (+right)", 0, new ConfigDescription("Horizontal offset of the top-left role badge in 1920x1080-reference px (+ = right). Adjust if it overlaps the vanilla health/stamina display on your resolution / 左上役職バッジの横オフセット(1920x1080基準px・+で右)。バニラの体力/スタミナ表示と重なる環境で調整する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>()));
			HudOffsetY = config.Bind<int>("Client UI", "HudOffsetY (+down)", 0, new ConfigDescription("Vertical offset of the top-left role badge in 1920x1080-reference px (+ = down). Adjust if it overlaps the vanilla health/stamina display on your resolution / 左上役職バッジの縦オフセット(1920x1080基準px・+で下)。バニラの体力/スタミナ表示と重なる環境で調整する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>()));
		}

		private void BindStreamer(ConfigFile config, GameConfig defaults)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			StreamerSafeMode = config.Bind<bool>("Streamer", "StreamerSafeMode", false, new ConfigDescription("Streamer-safe mode: replaces some parody visuals and distinctive sound effects (the Bomber's two ability icons, the meeting-convene chime, and the two execution sounds) with generic assets or silence, to avoid automated content detection on streaming platforms and viewer misunderstandings. Local setting (affects only your own screen and audio); applies after a game restart / 配信者向けセーフモード: 配信プラットフォームの自動判定や視聴者の誤解を避けるため、一部のパロディ表現や特徴的な効果音(爆弾魔の能力アイコン2種・会議招集チャイム・処刑演出の合の手2種)を汎用素材・無音に置き換える。ローカル設定(自分の画面と音にだけ効く)・反映はゲーム再起動", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
		}

		private void BindTutorial(ConfigFile config, GameConfig defaults)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			ResetTutorials = config.Bind<bool>("Tutorial", "ResetTutorials", false, "Set to true to reset all tutorial seen-flags (flips back to false automatically on the next poll; acts as a reset button to show the tutorials again) / true にするとチュートリアルの既読状態を全てリセットする(次のポーリングで自動的にfalseへ戻る。チュートリアルをもう一度表示させたい時のリセットボタン代わり)");
			TutorialFontScale = config.Bind<float>("Tutorial", "FontScale", 0.7f, new ConfigDescription("Tutorial text font scale (ratio against the vanilla tutorial notification's maximum size) / チュートリアル文言のフォントサイズ倍率(バニラのチュートリアル通知の上限サイズに対する比率)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 1.5f), Array.Empty<object>()));
			_tutorialSeen = new Dictionary<TutorialId, ConfigEntry<bool>>();
			foreach (TutorialId value in Enum.GetValues(typeof(TutorialId)))
			{
				_tutorialSeen[value] = config.Bind<bool>("Tutorial", "Seen" + value, false, new ConfigDescription($"Whether tutorial \"{value}\" has been shown (internal bookkeeping) / チュートリアル「{value}」を表示済みか(内部管理用)", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			}
			_scenarioCleared = new Dictionary<ScenarioId, ConfigEntry<bool>>();
			foreach (ScenarioId value2 in Enum.GetValues(typeof(ScenarioId)))
			{
				_scenarioCleared[value2] = config.Bind<bool>("Tutorial Scenarios", "Cleared" + value2, false, new ConfigDescription($"Whether tutorial scenario \"{value2}\" has been completed (internal bookkeeping) / チュートリアルシナリオ「{value2}」を完了済みか(内部管理用)", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			}
		}

		private void BindVoice(ConfigFile config, GameConfig defaults)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Expected O, but got Unknown
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Expected O, but got Unknown
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Expected O, but got Unknown
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Expected O, but got Unknown
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Expected O, but got Unknown
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Expected O, but got Unknown
			NecroVoiceVolume = config.Bind<float>("Voice", "NecroVoiceVolume", defaults.NecroVoiceVolume, new ConfigDescription("Eavesdrop voice volume (0..1; vanilla normal voice is roughly 0.5) / 傍聴音声の再生音量(0..1。バニラ通常声≒0.5相当)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceLowPassCutoffHz = config.Bind<float>("Voice", "NecroVoiceLowPassCutoffHz", defaults.NecroVoiceLowPassCutoffHz, new ConfigDescription("Eavesdrop voice muffling (LowPass cutoff frequency, Hz) / 傍聴音声のくすみ(LowPass カットオフ周波数 Hz)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 20000f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceEchoDelayMs = config.Bind<float>("Voice", "NecroVoiceEchoDelayMs", defaults.NecroVoiceEchoDelayMs, new ConfigDescription("Eavesdrop voice echo interval (ms) / 傍聴音声の反響1回の間隔(ms)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 2000f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceEchoDecay = config.Bind<float>("Voice", "NecroVoiceEchoDecay", defaults.NecroVoiceEchoDecay, new ConfigDescription("Eavesdrop voice echo decay (0..1) / 傍聴音声の反響の減衰率(0..1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbRoom = config.Bind<float>("Voice", "NecroVoiceReverbRoom", defaults.NecroVoiceReverbRoom, new ConfigDescription("Eavesdrop voice reverb room level (1/100 dB) / 傍聴音声の Reverb ルーム全体レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 0f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbRoomHF = config.Bind<float>("Voice", "NecroVoiceReverbRoomHF", defaults.NecroVoiceReverbRoomHF, new ConfigDescription("Eavesdrop voice reverb room HF level (1/100 dB) / 傍聴音声の Reverb ルーム高域レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 0f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbDecayTime = config.Bind<float>("Voice", "NecroVoiceReverbDecayTime", defaults.NecroVoiceReverbDecayTime, new ConfigDescription("Eavesdrop voice reverb decay time (seconds) / 傍聴音声の Reverb 残響減衰時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbDecayHFRatio = config.Bind<float>("Voice", "NecroVoiceReverbDecayHFRatio", defaults.NecroVoiceReverbDecayHFRatio, new ConfigDescription("Eavesdrop voice reverb HF decay ratio / 傍聴音声の Reverb 高域減衰比", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbReflections = config.Bind<float>("Voice", "NecroVoiceReverbReflections", defaults.NecroVoiceReverbReflections, new ConfigDescription("Eavesdrop voice reverb early reflection level (1/100 dB) / 傍聴音声の Reverb 初期反射レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 1000f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbReflectionsDelay = config.Bind<float>("Voice", "NecroVoiceReverbReflectionsDelay", defaults.NecroVoiceReverbReflectionsDelay, new ConfigDescription("Eavesdrop voice reverb early reflection delay (seconds) / 傍聴音声の Reverb 初期反射遅延(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.3f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbLevel = config.Bind<float>("Voice", "NecroVoiceReverbLevel", defaults.NecroVoiceReverbLevel, new ConfigDescription("Eavesdrop voice reverb late reflection level (1/100 dB) / 傍聴音声の Reverb 後期反射レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 2000f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbDelay = config.Bind<float>("Voice", "NecroVoiceReverbDelay", defaults.NecroVoiceReverbDelay, new ConfigDescription("Eavesdrop voice reverb late reflection delay (seconds) / 傍聴音声の Reverb 後期反射遅延(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbDiffusion = config.Bind<float>("Voice", "NecroVoiceReverbDiffusion", defaults.NecroVoiceReverbDiffusion, new ConfigDescription("Eavesdrop voice reverb diffusion (0..100) / 傍聴音声の Reverb 拡散度(0..100)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbDensity = config.Bind<float>("Voice", "NecroVoiceReverbDensity", defaults.NecroVoiceReverbDensity, new ConfigDescription("Eavesdrop voice reverb density (0..100) / 傍聴音声の Reverb 密度(0..100)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { "HideFromREPOConfig" }));
			NecroVoiceReverbHFReference = config.Bind<float>("Voice", "NecroVoiceReverbHFReference", defaults.NecroVoiceReverbHFReference, new ConfigDescription("Eavesdrop voice reverb HF reference frequency (Hz) / 傍聴音声の Reverb 高域基準周波数(Hz)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 20000f), new object[1] { "HideFromREPOConfig" }));
		}

		private void BindDebug(ConfigFile config, GameConfig defaults)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			DebugMode = config.Bind<bool>("Debug", "DebugMode", defaults.DebugMode, new ConfigDescription("Debug gameplay mode. true allows cheat commands (/ww ...), enables detailed logs, and shows a persistent TEST PLAY banner to every participant when the host enables it / ゲームプレイのデバッグモード。true でチートコマンド(/ww ...)と詳細ログを有効にする。ホストが有効にすると全参加者にテストプレイ常設バナーが表示される", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			DebugLogging = config.Bind<bool>("Debug", "DebugLogging", false, new ConfigDescription("Verbose diagnostics for this client, independently of gameplay DebugMode. Public trace lines are written at Debug level; secret role/vote lines are held until the match ends or you disconnect. This does not affect gameplay or reveal secrets during a normal match; disable it only to reduce log volume / この端末だけ、ゲームプレイの DebugMode とは独立して詳細な診断ログを出力する。公開情報のトレースは Debug レベル、役職・投票などの秘密情報は試合終了または切断後に一括出力する。通常試合中のゲーム進行や秘密情報の見え方には影響せず、false にするとログ量だけを減らせる", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
		}

		internal GameConfig Snapshot()
		{
			int value = ValuableMapMode.Value;
			ValuableMapMode valuableMapMode = ((value >= 0 && value <= 2) ? ((ValuableMapMode)value) : _valuableMapModeDefault);
			int value2 = NecroVoiceMode.Value;
			NecroVoiceMode necroVoiceMode = ((value2 >= 0 && value2 <= 2) ? ((NecroVoiceMode)value2) : _necroVoiceModeDefault);
			Dictionary<string, int> dictionary = new Dictionary<string, int>(_startUpgrades.Count);
			foreach (KeyValuePair<string, ConfigEntry<int>> startUpgrade in _startUpgrades)
			{
				dictionary[startUpgrade.Key] = startUpgrade.Value.Value;
			}
			return new GameConfig
			{
				WerewolfCount = WerewolfCount.Value,
				BlackCatChancePercent = BlackCatChancePercent.Value,
				BomberChancePercent = BomberChancePercent.Value,
				PeacefulVillageChancePercent = PeacefulVillageChancePercent.Value,
				RoundSeconds = RoundSeconds.Value,
				BlackCatRevealDelaySec = BlackCatRevealDelaySec.Value,
				BlackCatCurseEnabled = BlackCatCurseEnabled.Value,
				DebugMode = DebugMode.Value,
				MeetingRightsPerPlayer = MeetingRightsPerPlayer.Value,
				ConveneSuppressStartSec = ConveneSuppressStartSec.Value,
				ConveneSuppressAfterSec = ConveneSuppressAfterSec.Value,
				MeetingCountdownSec = MeetingCountdownSec.Value,
				MeetingDurationSec = MeetingDurationSec.Value,
				VoteTimeCutEnabled = VoteTimeCutEnabled.Value,
				ResultDisplaySec = ResultDisplaySec.Value,
				MeetingScatterEnabled = MeetingScatterEnabled.Value,
				ScatterGuardSec = ScatterGuardSec.Value,
				MeetingEnemyRespawnScalePct = MeetingEnemyRespawnScalePct.Value,
				ButtonOffsetX = ButtonOffsetX.Value,
				ButtonOffsetY = ButtonOffsetY.Value,
				ButtonOffsetZ = ButtonOffsetZ.Value,
				ButtonYaw = ButtonYaw.Value,
				ButtonPitch = ButtonPitch.Value,
				StaminaUnlockPct = StaminaUnlockPct.Value,
				JumpUnlockPct = JumpUnlockPct.Value,
				EnemyIgnoreUnlockPct = EnemyIgnoreUnlockPct.Value,
				HealUnlockPct = HealUnlockPct.Value,
				HealIntervalSec = HealIntervalSec.Value,
				BeaconChargePct = BeaconChargePct.Value,
				InformantThresholdPct = InformantThresholdPct.Value,
				ExtraJumpCount = ExtraJumpCount.Value,
				BeaconCooldownSec = BeaconCooldownSec.Value,
				BeaconSuppressStartSec = BeaconSuppressStartSec.Value,
				BeaconSuppressAfterMeetingSec = BeaconSuppressAfterMeetingSec.Value,
				CatGaugeSyncIntervalSec = CatGaugeSyncIntervalSec.Value,
				OrbGaugeEnabled = OrbGaugeEnabled.Value,
				WerewolfModeEnabled = WerewolfModeEnabled.Value,
				MinimapHideEnabled = MinimapHideEnabled.Value,
				OutfitChangeAllowed = OutfitChangeAllowed.Value,
				ValuableMapMode = valuableMapMode,
				GameOverAutoReturnSec = GameOverAutoReturnSec.Value,
				ToastDurationSec = ToastDurationSec.Value,
				StartLevelNumber = StartLevelNumber.Value,
				StartMapName = (StartMapName.Value ?? ""),
				StartItemsSpec = (ItemsSpecProvider?.Invoke() ?? ""),
				StartEnergyPct = StartEnergyPct.Value,
				StartUpgradesSpec = WorldgenSpec.Encode(dictionary),
				OrbDropMax = OrbDropMax.Value,
				StartHaulGoalPct = StartHaulGoalPct.Value,
				EnemySetsDanger1 = EnemySetsDanger1.Value,
				EnemySetsDanger2 = EnemySetsDanger2.Value,
				EnemySetsDanger3 = EnemySetsDanger3.Value,
				NecroVoiceMode = necroVoiceMode,
				NecroVoiceVolume = NecroVoiceVolume.Value,
				NecroVoiceLowPassCutoffHz = NecroVoiceLowPassCutoffHz.Value,
				NecroVoiceEchoDelayMs = NecroVoiceEchoDelayMs.Value,
				NecroVoiceEchoDecay = NecroVoiceEchoDecay.Value,
				NecroVoiceReverbRoom = NecroVoiceReverbRoom.Value,
				NecroVoiceReverbRoomHF = NecroVoiceReverbRoomHF.Value,
				NecroVoiceReverbDecayTime = NecroVoiceReverbDecayTime.Value,
				NecroVoiceReverbDecayHFRatio = NecroVoiceReverbDecayHFRatio.Value,
				NecroVoiceReverbReflections = NecroVoiceReverbReflections.Value,
				NecroVoiceReverbReflectionsDelay = NecroVoiceReverbReflectionsDelay.Value,
				NecroVoiceReverbLevel = NecroVoiceReverbLevel.Value,
				NecroVoiceReverbDelay = NecroVoiceReverbDelay.Value,
				NecroVoiceReverbDiffusion = NecroVoiceReverbDiffusion.Value,
				NecroVoiceReverbDensity = NecroVoiceReverbDensity.Value,
				NecroVoiceReverbHFReference = NecroVoiceReverbHFReference.Value,
				ShamanChancePercent = ShamanChancePercent.Value,
				ShamanGazeFullSec = ShamanGazeFullSec.Value,
				ShamanGhostCooldownSec = ShamanGhostCooldownSec.Value,
				ShamanStormWeakMeters = ShamanStormWeakMeters.Value,
				ShamanStormMediumMeters = ShamanStormMediumMeters.Value,
				ShamanStormStrongMeters = ShamanStormStrongMeters.Value,
				BomberProximityMeters = BomberProximityMeters.Value,
				BomberGaugeFullSec = BomberGaugeFullSec.Value,
				BomberInitialCooldownSec = BomberInitialCooldownSec.Value,
				BomberCooldownSec = BomberCooldownSec.Value,
				BomberBlastRadiusMeters = BomberBlastRadiusMeters.Value,
				BomberBlastPlayerDamage = BomberBlastPlayerDamage.Value,
				BomberBlastEnemyDamage = BomberBlastEnemyDamage.Value,
				BomberAmmoRefillPct = BomberAmmoRefillPct.Value
			};
		}

		internal bool IsTutorialSeen(TutorialId id)
		{
			if (_tutorialSeen.TryGetValue(id, out var value))
			{
				return value.Value;
			}
			return true;
		}

		internal void MarkTutorialSeen(TutorialId id)
		{
			if (_tutorialSeen.TryGetValue(id, out var value))
			{
				value.Value = true;
			}
		}

		internal void TickTutorialReset()
		{
			if (!ResetTutorials.Value)
			{
				return;
			}
			foreach (ConfigEntry<bool> value in _tutorialSeen.Values)
			{
				value.Value = false;
			}
			ResetTutorials.Value = false;
		}

		internal bool IsScenarioCleared(ScenarioId id)
		{
			if (_scenarioCleared.TryGetValue(id, out var value))
			{
				return value.Value;
			}
			return false;
		}

		internal void MarkScenarioCleared(ScenarioId id)
		{
			if (_scenarioCleared.TryGetValue(id, out var value))
			{
				value.Value = true;
			}
		}
	}
	internal static class GameRefs
	{
		public static FieldRef<PlayerAvatar, bool> PlayerAvatar_deadSet;

		public static FieldRef<PlayerAvatar, bool> PlayerAvatar_isDisabled;

		public static FieldRef<PlayerAvatar, bool> PlayerAvatar_isTumbling;

		public static FieldRef<PlayerAvatar, bool> PlayerAvatar_levelAnimationCompleted;

		public static FieldRef<PlayerAvatar, PlayerDeathHead> PlayerAvatar_playerDeathHead;

		public static FieldRef<PlayerAvatar, PlayerVoiceChat> PlayerAvatar_voiceChat;

		public static FieldRef<PlayerAvatar, bool> PlayerAvatar_voiceChatFetched;

		public static FieldRef<PlayerAvatar, PlayerTumble> PlayerAvatar_tumble;

		public static FieldRef<PlayerHealth, int> PlayerHealth_health;

		public static FieldRef<PlayerTumble, PhysGrabObject> PlayerTumble_physGrabObject;

		public static FieldRef<PlayerDeathHead, PhysGrabObject> PlayerDeathHead_physGrabObject;

		public static FieldRef<PlayerVoiceChat, bool> PlayerVoiceChat_isTalking;

		public static FieldRef<PlayerVoiceChat, AudioSource> PlayerVoiceChat_audioSource;

		public static FieldRef<PlayerVoiceChat, Recorder> PlayerVoiceChat_recorder;

		public static FieldRef<RunManager, Level> RunManager_debugLevel;

		public static FieldRef<RunManager, bool> RunManager_restarting;

		public static FieldRef<RunManager, List<PlayerVoiceChat>> RunManager_voiceChats;

		public static FieldRef<RunManager, float> RunManager_cosmeticWorldObjectCooldown;

		public static FieldRef<RunManager, bool> RunManager_moonLevelChanged;

		public static FieldRef<RoundDirector, int> RoundDirector_extractionPoints;

		public static FieldRef<RoundDirector, int> RoundDirector_extractionPointsCompleted;

		public static FieldRef<RoundDirector, bool> RoundDirector_allExtractionPointsCompleted;

		public static FieldRef<RoundDirector, int> RoundDirector_haulGoal;

		public static FieldRef<RoundDirector, int> RoundDirector_haulGoalMax;

		public static FieldRef<RoundDirector, int> RoundDirector_extractionPointSurplus;

		public static FieldRef<ExtractionPoint, State> ExtractionPoint_currentState;

		public static FieldRef<StatsManager, string> StatsManager_saveFileCurrent;

		public static FieldRef<StatsManager, SortedDictionary<string, Dictionary<string, int>>> StatsManager_dictionaryOfDictionaries;

		public static FieldRef<PunManager, PhotonView> PunManager_photonView;

		public static FieldRef<MetaManager, List<int>> MetaManager_cosmeticTokens;

		public static FieldRef<InputManager, Dictionary<InputKey, InputAction>> InputManager_inputActions;

		public static FieldRef<DataDirector, bool> DataDirector_toggleMute;

		public static FieldRef<ChatManager, string> ChatManager_chatMessage;

		public static FieldRef<MenuPlayerListed, PlayerAvatar> MenuPlayerListed_playerAvatar;

		public static FieldRef<MenuPlayerListed, int> MenuPlayerListed_listSpot;

		public static FieldRef<MenuPlayerHead, bool> MenuPlayerHead_isTalking;

		public static FieldRef<MenuPlayerHead, RectTransform> MenuPlayerHead_headTransform;

		public static FieldRef<PlayerCrown, PlayerAvatar> PlayerCrown_playerAvatar;

		public static FieldRef<PlayerCrown, bool> PlayerCrown_active;

		public static FieldRef<WorldSpaceUIPlayerName, PlayerAvatar> WorldSpaceUIPlayerName_playerAvatar;

		public static FieldRef<MapToolController, bool> MapToolController_Active;

		public static FieldRef<TruckScreenText, PlayerChatBoxState> TruckScreenText_playerChatBoxState;

		public static FieldRef<PlayerController, bool> PlayerController_JumpFirst;

		public static FieldRef<PlayerController, int> PlayerController_JumpExtraCurrent;

		public static FieldRef<ItemMelee, HurtCollider> ItemMelee_hurtCollider;

		public static FieldRef<PhysGrabber, PhysGrabObject> PhysGrabber_grabbedPhysGrabObject;

		public static FieldRef<PhysGrabObject, bool> PhysGrabObject_isMelee;

		public static FieldRef<ValuableObject, float> ValuableObject_dollarValueCurrent;

		public static FieldRef<ValuableObject, float> ValuableObject_dollarValueOriginal;

		public static FieldRef<ValuableObject, int> ValuableObject_dollarValueOverride;

		public static FieldRef<ValuableObject, bool> ValuableObject_discovered;

		public static FieldRef<PhysGrabObjectImpactDetector, ValuableObject> PhysGrabObjectImpactDetector_valuableObject;

		public static FieldRef<PhysGrabObjectImpactDetector, PhysGrabObject> PhysGrabObjectImpactDetector_physGrabObject;

		public static FieldRef<EnemyParent, Enemy> EnemyParent_Enemy;

		public static FieldRef<EnemyParent, bool> EnemyParent_Spawned;

		public static FieldRef<EnemyParent, bool> EnemyParent_firstSpawnPointUsed;

		public static FieldRef<Enemy, EnemyRigidbody> Enemy_Rigidbody;

		public static FieldRef<Enemy, bool> Enemy_HasRigidbody;

		public static FieldRef<MapCustom, MapCustomEntity> MapCustom_mapCustomEntity;

		public static FieldRef<EnemyDirector, List<string>> EnemyDirector_debugNoVision;

		public static FieldRef<EnemyDirector, float> EnemyDirector_despawnedDecreaseTimer;

		public static FieldRef<EnemyDirector, float> EnemyDirector_spawnIdlePauseTimer;

		public static FieldRef<EnemyShadow, PlayerAvatar> EnemyShadow_playerTarget;

		public static MethodInfo EnemyShadow_UpdatePlayerTarget;

		public static FieldInfo ParticleScriptExplosion_explosionPrefab;

		public static FieldInfo ParticlePrefabExplosion_HurtColliderSecondSetup;

		public static FieldRef<RoundDirector, int> RoundDirector_currentHaul;

		public static FieldRef<LevelGenerator, float> LevelGenerator_DebugLevelSize;

		private static List<string> s_failures;

		public static bool ResolveAll()
		{
			s_failures = new List<string>();
			PlayerAvatar_deadSet = Field<PlayerAvatar, bool>("deadSet");
			PlayerAvatar_isDisabled = Field<PlayerAvatar, bool>("isDisabled");
			PlayerAvatar_isTumbling = Field<PlayerAvatar, bool>("isTumbling");
			PlayerAvatar_levelAnimationCompleted = Field<PlayerAvatar, bool>("levelAnimationCompleted");
			PlayerAvatar_playerDeathHead = Field<PlayerAvatar, PlayerDeathHead>("playerDeathHead");
			PlayerAvatar_voiceChat = Field<PlayerAvatar, PlayerVoiceChat>("voiceChat");
			PlayerAvatar_voiceChatFetched = Field<PlayerAvatar, bool>("voiceChatFetched");
			PlayerAvatar_tumble = Field<PlayerAvatar, PlayerTumble>("tumble");
			PlayerHealth_health = Field<PlayerHealth, int>("health");
			PlayerTumble_physGrabObject = Field<PlayerTumble, PhysGrabObject>("physGrabObject");
			PlayerDeathHead_physGrabObject = Field<PlayerDeathHead, PhysGrabObject>("physGrabObject");
			PlayerVoiceChat_isTalking = Field<PlayerVoiceChat, bool>("isTalking");
			PlayerVoiceChat_audioSource = Field<PlayerVoiceChat, AudioSource>("audioSource");
			PlayerVoiceChat_recorder = Field<PlayerVoiceChat, Recorder>("recorder");
			RunManager_debugLevel = Field<RunManager, Level>("debugLevel");
			RunManager_restarting = Field<RunManager, bool>("restarting");
			RunManager_voiceChats = Field<RunManager, List<PlayerVoiceChat>>("voiceChats");
			RunManager_cosmeticWorldObjectCooldown = Field<RunManager, float>("cosmeticWorldObjectCooldown");
			RunManager_moonLevelChanged = Field<RunManager, bool>("moonLevelChanged");
			RoundDirector_extractionPoints = Field<RoundDirector, int>("extractionPoints");
			ExtractionPoint_currentState = Field<ExtractionPoint, State>("currentState");
			RoundDirector_extractionPointsCompleted = Field<RoundDirector, int>("extractionPointsCompleted");
			RoundDirector_allExtractionPointsCompleted = Field<RoundDirector, bool>("allExtractionPointsCompleted");
			RoundDirector_haulGoal = Field<RoundDirector, int>("haulGoal");
			RoundDirector_haulGoalMax = Field<RoundDirector, int>("haulGoalMax");
			RoundDirector_extractionPointSurplus = Field<RoundDirector, int>("extractionPointSurplus");
			StatsManager_saveFileCurrent = Field<StatsManager, string>("saveFileCurrent");
			StatsManager_dictionaryOfDictionaries = Field<StatsManager, SortedDictionary<string, Dictionary<string, int>>>("dictionaryOfDictionaries");
			PunManager_photonView = Field<PunManager, PhotonView>("photonView");
			MetaManager_cosmeticTokens = Field<MetaManager, List<int>>("cosmeticTokens");
			InputManager_inputActions = Field<InputManager, Dictionary<InputKey, InputAction>>("inputActions");
			DataDirector_toggleMute = Field<DataDirector, bool>("toggleMute");
			ChatManager_chatMessage = Field<ChatManager, string>("chatMessage");
			MenuPlayerListed_playerAvatar = Field<MenuPlayerListed, PlayerAvatar>("playerAvatar");
			MenuPlayerListed_listSpot = Field<MenuPlayerListed, int>("listSpot");
			MenuPlayerHead_isTalking = Field<MenuPlayerHead, bool>("isTalking");
			MenuPlayerHead_headTransform = Field<MenuPlayerHead, RectTransform>("headTransform");
			PlayerCrown_playerAvatar = Field<PlayerCrown, PlayerAvatar>("playerAvatar");
			PlayerCrown_active = Field<PlayerCrown, bool>("active");
			WorldSpaceUIPlayerName_playerAvatar = Field<WorldSpaceUIPlayerName, PlayerAvatar>("playerAvatar");
			MapToolController_Active = Field<MapToolController, bool>("Active");
			TruckScreenText_playerChatBoxState = Field<TruckScreenText, PlayerChatBoxState>("playerChatBoxState");
			PlayerController_JumpFirst = Field<PlayerController, bool>("JumpFirst");
			PlayerController_JumpExtraCurrent = Field<PlayerController, int>("JumpExtraCurrent");
			ItemMelee_hurtCollider = Field<ItemMelee, HurtCollider>("hurtCollider");
			PhysGrabber_grabbedPhysGrabObject = Field<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject");
			PhysGrabObject_isMelee = Field<PhysGrabObject, bool>("isMelee");
			ValuableObject_dollarValueCurrent = Field<ValuableObject, float>("dollarValueCurrent");
			ValuableObject_dollarValueOriginal = Field<ValuableObject, float>("dollarValueOriginal");
			ValuableObject_dollarValueOverride = Field<ValuableObject, int>("dollarValueOverride");
			ValuableObject_discovered = Field<ValuableObject, bool>("discovered");
			PhysGrabObjectImpactDetector_valuableObject = Field<PhysGrabObjectImpactDetector, ValuableObject>("valuableObject");
			PhysGrabObjectImpactDetector_physGrabObject = Field<PhysGrabObjectImpactDetector, PhysGrabObject>("physGrabObject");
			EnemyParent_Enemy = Field<EnemyParent, Enemy>("Enemy");
			EnemyParent_Spawned = Field<EnemyParent, bool>("Spawned");
			EnemyParent_firstSpawnPointUsed = Field<EnemyParent, bool>("firstSpawnPointUsed");
			Enemy_Rigidbody = Field<Enemy, EnemyRigidbody>("Rigidbody");
			Enemy_HasRigidbody = Field<Enemy, bool>("HasRigidbody");
			MapCustom_mapCustomEntity = Field<MapCustom, MapCustomEntity>("mapCustomEntity");
			EnemyDirector_debugNoVision = Field<EnemyDirector, List<string>>("debugNoVision");
			EnemyDirector_despawnedDecreaseTimer = Field<EnemyDirector, float>("despawnedDecreaseTimer");
			EnemyDirector_spawnIdlePauseTimer = Field<EnemyDirector, float>("spawnIdlePauseTimer");
			EnemyShadow_playerTarget = Field<EnemyShadow, PlayerAvatar>("playerTarget");
			EnemyShadow_UpdatePlayerTarget = RawMethod(typeof(EnemyShadow), "UpdatePlayerTarget");
			ParticleScriptExplosion_explosionPrefab = RawField(typeof(ParticleScriptExplosion), "explosionPrefab");
			ParticlePrefabExplosion_HurtColliderSecondSetup = RawField(typeof(ParticlePrefabExplosion), "HurtColliderSecondSetup");
			if (s_failures.Count == 0)
			{
				return true;
			}
			WLog.Line("game_refs_disabled", false, ("failedFields", s_failures.Count));
			return false;
		}

		public static int ResolveScenarioRefs()
		{
			if (s_failures == null)
			{
				s_failures = new List<string>();
			}
			int count = s_failures.Count;
			RoundDirector_currentHaul = Field<RoundDirector, int>("currentHaul");
			LevelGenerator_DebugLevelSize = Field<LevelGenerator, float>("DebugLevelSize");
			return s_failures.Count - count;
		}

		private static FieldRef<TObj, TField> Field<TObj, TField>(string fieldName) where TObj : class
		{
			try
			{
				return AccessTools.FieldRefAccess<TObj, TField>(fieldName);
			}
			catch (Exception ex)
			{
				Fail(typeof(TObj).Name, fieldName, ex.Message);
				return null;
			}
		}

		private static MethodInfo RawMethod(Type type, string methodName)
		{
			MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Fail(type.Name, methodName, "method not found");
				return null;
			}
			return methodInfo;
		}

		private static FieldInfo RawField(Type type, string fieldName)
		{
			FieldInfo fieldInfo = AccessTools.Field(type, fieldName);
			if (fieldInfo == null)
			{
				Fail(type.Name, fieldName, "field not found");
				return null;
			}
			return fieldInfo;
		}

		private static void Fail(string typeName, string fieldName, string error)
		{
			s_failures.Add(typeName + "." + fieldName);
			WLog.Line("game_ref_failed", false, ("type", typeName), ("field", fieldName), ("err", error));
		}
	}
	[BepInPlugin("minorunara.werewolf", "Werewolf", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "minorunara.werewolf";

		public const string PluginName = "Werewolf";

		public const string PluginVersion = "1.5.0";

		internal const string MenuLibGuid = "nickklmao.menulib";

		internal static ManualLogSource Logger;

		internal static GameConfig GameConfig;

		internal static ConfigBindings Bindings;

		internal static ConfigEntry<KeyCode> WolfModeKey;

		internal static ConfigEntry<KeyCode> BeaconKey;

		internal static ConfigEntry<KeyCode> LobbySettingsPanelKey;

		internal static ConfigEntry<KeyCode> MeetingMapKey;

		internal static ConfigEntry<KeyCode> MeetingChatLogKey;

		internal static ConfigEntry<KeyCode> ReplayViewerKey;

		internal static ConfigEntry<KeyCode> CorpseReportKey;

		internal static ConfigEntry<KeyCode> ResultReturnKey;

		internal static ConfigEntry<KeyCode> ManualKey;

		internal static ConfigEntry<KeyCode> VoidMatchKey;

		internal static void RefreshGameConfig()
		{
			if (Bindings != null)
			{
				GameConfig = Bindings.Snapshot();
				if (ScenarioRun.Active)
				{
					GameConfig = ScenarioGameConfig.Build(GameConfig, ScenarioRun.Definition);
				}
			}
		}

		private void Awake()
		{
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			if (!CosmeticLottery.ValidateWeights())
			{
				Logger.LogWarning((object)"CosmeticLottery.ValidateWeights failed: weight constants (Common/Uncommon/Rare/UltraRare) do not sum to TotalWeight. Cosmetic coin drop rates will be inconsistent.");
			}
			StructuredLog.Install();
			Bindings = new ConfigBindings(((BaseUnityPlugin)this).Config);
			GameConfig = Bindings.Snapshot();
			WolfModeKey = Bindings.WolfModeKey;
			BeaconKey = Bindings.BeaconKey;
			LobbySettingsPanelKey = Bindings.LobbySettingsPanelKey;
			MeetingMapKey = Bindings.MeetingMapKey;
			MeetingChatLogKey = Bindings.MeetingChatLogKey;
			ReplayViewerKey = Bindings.ReplayViewerKey;
			CorpseReportKey = Bindings.CorpseReportKey;
			ManualKey = Bindings.ManualKey;
			ResultReturnKey = Bindings.ResultReturnKey;
			VoidMatchKey = Bindings.VoidMatchKey;
			WorldgenItemBindings.Install(((BaseUnityPlugin)this).Config, Bindings);
			WorldgenMapBinding.Install(((BaseUnityPlugin)this).Config, Bindings);
			LoadLanguageOverride();
			AssetCatalog.SetStreamerSafeMode(Bindings.StreamerSafeMode.Value);
			if (Bindings.StreamerSafeMode.Value)
			{
				WLog.Line("streamer_safe_mode", false, ("enabled", true));
			}
			if (!GameRefs.ResolveAll())
			{
				Logger.LogError((object)"Werewolf 1.5.0: 本体フィールド参照の解決に失敗したためMODを無効化しました(本体アップデートでフィールドが変わった可能性。修復手順: docs/steering/tech.md「本体アップデート対応プレイブック」)");
				return;
			}
			int num = GameRefs.ResolveScenarioRefs();
			if (num > 0)
			{
				ScenarioRun.DisableForFailedRefs(num);
				Logger.LogWarning((object)("Werewolf 1.5.0: チュートリアル用の本体フィールド参照" + $"{num}件が解決できないため、チュートリアルの入口だけを閉じました" + "(本編は通常どおり動作します)"));
			}
			EnemyMapIcons.TextureResolver = AssetCatalog.GetTexture;
			MeetingButton.PrefabResolver = AssetCatalog.GetPrefab;
			if (!ApplyPatchesIsolated(new Harmony("minorunara.werewolf")))
			{
				Logger.LogError((object)"Werewolf 1.5.0: Harmonyパッチ適用に失敗したためMODを無効化しました(本体アップデートでパッチ対象が変わった可能性。修復手順: docs/steering/tech.md「本体アップデート対応プレイブック」)");
				return;
			}
			((Component)this).gameObject.AddComponent<WerewolfDirector>();
			ScenarioMenuEntry.TryInstall();
		}

		private void OnDestroy()
		{
			StructuredLog.FlushDeferredSecrets("plugin_destroy");
		}

		private static bool ApplyPatchesIsolated(Harmony harmony)
		{
			List<(string, Exception)> list = new List<(string, Exception)>();
			int num = 0;
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception item)
				{
					list.Add((type.FullName, item));
					if (PatchTierPolicy.IsScenarioTier(type.FullName))
					{
						num++;
					}
				}
			}
			foreach (var item4 in list)
			{
				string item2 = item4.Item1;
				Exception item3 = item4.Item2;
				Exception ex = item3.InnerException ?? item3;
				WLog.Line("harmony_patch_failed", false, ("patchClass", item2), ("err", ex.Message));
				Logger.LogError((object)$"Harmony patch failed: {item2}\n{item3}");
			}
			switch (PatchTierPolicy.Decide(list.Count - num, num))
			{
			case PatchApplyOutcome.ModDisabled:
				harmony.UnpatchSelf();
				WLog.Line("harmony_disabled", false, ("failedClasses", list.Count));
				return false;
			case PatchApplyOutcome.ScenariosDisabled:
				ScenarioRun.DisableForFailedPatches(num);
				break;
			}
			return true;
		}

		private void LoadLanguageOverride()
		{
			try
			{
				string text = Bindings?.Language?.Value;
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				int num;
				switch (text)
				{
				case "ja":
					return;
				default:
					num = ((text == "en") ? 1 : 0);
					break;
				case "English":
					num = 1;
					break;
				}
				bool flag = (byte)num != 0;
				if (flag)
				{
					Texts.Current = Language.English;
				}
				string text2 = (flag ? "en" : text);
				string location = typeof(Plugin).Assembly.Location;
				string text3 = (string.IsNullOrEmpty(location) ? null : Path.GetDirectoryName(location));
				if (string.IsNullOrEmpty(text3))
				{
					if (!flag)
					{
						WLog.Line("lang_load_failed", false, ("code", text2), ("reason", "no_dll_dir"));
					}
					return;
				}
				string text4 = Path.Combine(text3, "Lang", text2 + ".txt");
				if (!File.Exists(text4))
				{
					if (!flag)
					{
						WLog.Line("lang_load_failed", false, ("code", text2), ("reason", "file_missing"), ("path", text4));
					}
				}
				else
				{
					Texts.SetOverride(LangFile.Parse(File.ReadAllText(text4, Encoding.UTF8)));
				}
			}
			catch (Exception ex)
			{
				WLog.Line("lang_load_failed", false, ("reason", "exception"), ("detail", ex.GetType().Name));
			}
		}
	}
	internal static class WorldgenItemBindings
	{
		private static ConfigFile _config;

		private static ConfigBindings _bindings;

		private static Dictionary<string, ConfigEntry<int>> _entries;

		private static bool _initialized;

		private static bool _failed;

		private static bool _skipLogged;

		private static readonly Dictionary<string, int> DefaultAmounts = new Dictionary<string, int>
		{
			["Item Cart Cannon"] = 1,
			["Item Cart Medium"] = 2,
			["Item Cart Small"] = 1,
			["Item Drone Indestructible"] = 1,
			["Item Drone Zero Gravity"] = 1,
			["Item Grenade Explosive"] = 2,
			["Item Grenade Shockwave"] = 2,
			["Item Grenade Stun"] = 2,
			["Item Gun Laser"] = 1,
			["Item Gun Shockwave"] = 1,
			["Item Gun Shotgun"] = 1,
			["Item Gun Stun"] = 1,
			["Item Gun Tranq"] = 1,
			["Item Health Pack Large"] = 1,
			["Item Health Pack Medium"] = 2,
			["Item Health Pack Small"] = 3,
			["Item Leaf Blower"] = 1,
			["Item Melee Baseball Bat"] = 1,
			["Item Melee Frying Pan"] = 1,
			["Item Melee Inflatable Hammer"] = 0,
			["Item Melee Stun Baton"] = 1,
			["Item Melee Sword"] = 1,
			["Item Mine Explosive"] = 2,
			["Item Mine Shockwave"] = 2,
			["Item Mine Stun"] = 2,
			["Item Orb Zero Gravity"] = 1,
			["Item Phase Bridge"] = 1,
			["Item Staff Torque"] = 1,
			["Item Staff Void"] = 1,
			["Item Staff Zero Gravity"] = 1,
			["Item Upgrade Map Player Count"] = 1,
			["Item Vehicle Semiscooter"] = 1,
			["Item Vehicle Semiscooter Small"] = 1,
			["Item WalkieTalkieBox"] = 1
		};

		internal static void Install(ConfigFile config, ConfigBindings bindings)
		{
			_config = config;
			_bindings = bindings;
		}

		internal static void TryInitialize()
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			if (_initialized || _failed || _config == null)
			{
				return;
			}
			try
			{
				IReadOnlyDictionary<string, int> itemMaxAmounts = GameItemDatabase.Instance.ItemMaxAmounts;
				if (itemMaxAmounts == null || itemMaxAmounts.Count == 0)
				{
					return;
				}
				Dictionary<string, ConfigEntry<int>> dictionary = new Dictionary<string, ConfigEntry<int>>(itemMaxAmounts.Count);
				foreach (KeyValuePair<string, int> item in itemMaxAmounts)
				{
					try
					{
						int value;
						int num = (DefaultAmounts.TryGetValue(item.Key, out value) ? Math.Min(value, item.Value) : 0);
						dictionary[item.Key] = _config.Bind<int>("10. Loadout Items", item.Key, num, new ConfigDescription($"Amount brought to the truck at werewolf session start (0 = none, max = {item.Value}) / " + $"人狼セッション開始時にトラックへ持ち込む個数(0 = 持ち込まない, 上限 = {item.Value})", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, item.Value), Array.Empty<object>()));
					}
					catch (Exception ex)
					{
						WLog.Line("worldgen_itembind_skip", false, ("item", item.Key), ("err", ex.Message));
					}
				}
				_entries = dictionary;
				_initialized = true;
				if (_bindings != null)
				{
					_bindings.ItemsSpecProvider = ComposeSpec;
				}
			}
			catch (Exception ex2)
			{
				_failed = true;
				WLog.Line("worldgen_itembind_error", false, ("err", ex2.Message));
			}
		}

		internal static string ComposeSpec()
		{
			Dictionary<string, ConfigEntry<int>> entries = _entries;
			if (entries == null)
			{
				return "";
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>(entries.Count);
			foreach (KeyValuePair<string, ConfigEntry<int>> item in entries)
			{
				dictionary[item.Key] = item.Value.Value;
			}
			List<string> list = new List<string>();
			string result = WorldgenSpec.Encode(dictionary, list);
			if (list.Count > 0 && !_skipLogged)
			{
				_skipLogged = true;
				WLog.Line("worldgen_itemspec_skip", false, ("names", string.Join(" / ", list)));
			}
			return result;
		}
	}
	internal static class WorldgenMapBinding
	{
		private static ConfigFile _config;

		private static ConfigBindings _bindings;

		private static bool _initialized;

		private static bool _failed;

		internal static void Install(ConfigFile config, ConfigBindings bindings)
		{
			_config = config;
			_bindings = bindings;
		}

		internal static void TryInitialize()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			if (_initialized || _failed || _config == null || _bindings == null)
			{
				return;
			}
			try
			{
				IReadOnlyList<string> playableLevelNames = GameItemDatabase.Instance.PlayableLevelNames;
				if (playableLevelNames == null || playableLevelNames.Count == 0)
				{
					return;
				}
				List<string> list = new List<string>(playableLevelNames.Count + 1) { "" };
				foreach (string item in playableLevelNames)
				{
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
				ConfigEntry<string> startMapName = _bindings.StartMapName;
				string text = startMapName.Value ?? "";
				_config.Remove(((ConfigEntryBase)startMapName).Definition);
				ConfigEntry<string> val = _config.Bind<string>("08. Stage", "StartMapName", "", new ConfigDescription("Map type name for the werewolf session. Empty = random (vanilla default selection) / 人狼セッションの開始マップ種別名。空 = ランダム(バニラ既定の選択)", (AcceptableValueBase)(object)new AcceptableValueList<string>(list.ToArray()), Array.Empty<object>()));
				val.Value = text;
				_bindings.StartMapName = val;
				_initialized = true;
				if (!string.Equals(val.Value, text, StringComparison.Ordinal))
				{
					WLog.Line("worldgen_mapbind_fallback", false, ("from", text));
				}
			}
			catch (Exception ex)
			{
				_failed = true;
				WLog.Line("worldgen_mapbind_error", false, ("err", ex.Message));
			}
		}
	}
	internal static class WerewolfBuildInfo
	{
		public const string Version = "1.5.0";
	}
}
namespace Werewolf.Vanilla
{
	public sealed class BeaconEffect
	{
		private sealed class ActiveSequence
		{
			public BeaconPulseSequence Sequence;

			public Vector3 Position;

			public int Fired;
		}

		private const float InvestigateRadius = 100f;

		private readonly List<ActiveSequence> _active = new List<ActiveSequence>();

		private readonly BeaconSummonGate _summonGate = new BeaconSummonGate();

		public void Trigger(PlayerHandle requester, long nowUnixMs, int summonCooldownSec)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar avatar = requester.Avatar;
			if ((Object)(object)avatar == (Object)null)
			{
				WLog.Line("beacon_effect_skipped", true, ("reason", "no_avatar"));
				return;
			}
			Vector3 position = ((Component)avatar).transform.position;
			_active.Add(new ActiveSequence
			{
				Sequence = new BeaconPulseSequence(nowUnixMs),
				Position = position,
				Fired = 0
			});
			WLog.Line("beacon_effect", true, ("x", (int)position.x), ("y", (int)position.y), ("z", (int)position.z));
			TrySummon(nowUnixMs, summonCooldownSec);
			Tick(nowUnixMs);
		}

		private void TrySummon(long nowUnixMs, int cooldownSec)
		{
			EnemyDirector instance = EnemyDirector.instance;
			if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null)
			{
				return;
			}
			List<EnemyParent> list = new List<EnemyParent>();
			foreach (EnemyParent item in instance.enemiesSpawned)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				try
				{
					if (!GameRefs.EnemyParent_Spawned.Invoke(item))
					{
						list.Add(item);
					}
				}
				catch (Exception ex)