Decompiled source of Odin Red Power Mod v0.4.2

BepInEx/plugins/OdinRedPowerMod.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Rendering;

[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("OdinRedPowerMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.2.0")]
[assembly: AssemblyInformationalVersion("0.4.2")]
[assembly: AssemblyProduct("OdinRedPowerMod")]
[assembly: AssemblyTitle("OdinRedPowerMod")]
[assembly: AssemblyVersion("0.4.2.0")]
namespace Oftech.Valheim.OdinRedPowerMod;

[BepInPlugin("oftech.valheim.odinredpowermod", "Odin Red Power Mod", "0.4.2")]
public sealed class Plugin : BaseUnityPlugin
{
	private sealed class PowerSettings
	{
		internal bool PowerEnabled;

		internal float DamageMultiplier;

		internal float CarryMultiplier;

		internal float HealthBonus;

		internal float StaminaBonus;

		internal float HealthRegenMultiplier;

		internal float DamageReduction;

		internal float StaminaCostReduction;

		internal float RunMultiplier;

		internal float JumpMultiplier;

		internal bool GroundCircleEnabled;

		internal float CircleRed;

		internal float CircleGreen;

		internal float CircleBlue;

		internal HashSet<long> DeniedPlayerIds = new HashSet<long>();
	}

	private sealed class OnlinePlayer
	{
		internal readonly long Id;

		internal readonly string Name;

		internal readonly bool IsHost;

		internal OnlinePlayer(long id, string name, bool isHost)
		{
			Id = id;
			Name = name;
			IsHost = isHost;
		}
	}

	private enum UiLanguage
	{
		English,
		Turkish,
		Spanish
	}

	public const string PluginGuid = "oftech.valheim.odinredpowermod";

	public const string PluginName = "Odin Red Power Mod";

	public const string PluginVersion = "0.4.2";

	internal const float DefaultDamageMultiplier = 1.25f;

	internal const float DefaultCarryMultiplier = 1.5f;

	internal const float DefaultHealthBonus = 100f;

	internal const float DefaultStaminaBonus = 200f;

	internal const float DefaultHealthRegenMultiplier = 1.5f;

	internal const float DefaultDamageReduction = 0.2f;

	internal const float DefaultStaminaCostReduction = 0.2f;

	internal const float DefaultRunMultiplier = 1.2f;

	internal const float DefaultJumpMultiplier = 1.5f;

	internal const float DefaultCircleRed = 0.86f;

	internal const float DefaultCircleGreen = 0.055f;

	internal const float DefaultCircleBlue = 0.045f;

	internal const string AuraStateKey = "oftech.odinredpowermod.active";

	internal const string DamageMultiplierKey = "oftech.odinredpowermod.damage";

	internal const string CarryMultiplierKey = "oftech.odinredpowermod.carry";

	internal const string HealthBonusKey = "oftech.odinredpowermod.health";

	internal const string StaminaBonusKey = "oftech.odinredpowermod.stamina";

	internal const string HealthRegenMultiplierKey = "oftech.odinredpowermod.healthregen";

	internal const string DamageReductionKey = "oftech.odinredpowermod.damagereduction";

	internal const string StaminaCostReductionKey = "oftech.odinredpowermod.staminacostreduction";

	internal const string RunMultiplierKey = "oftech.odinredpowermod.run";

	internal const string JumpMultiplierKey = "oftech.odinredpowermod.jump";

	internal const string CircleEnabledKey = "oftech.odinredpowermod.circle.enabled";

	internal const string CircleRedKey = "oftech.odinredpowermod.circle.red";

	internal const string CircleGreenKey = "oftech.odinredpowermod.circle.green";

	internal const string CircleBlueKey = "oftech.odinredpowermod.circle.blue";

	private const int SettingsProtocolVersion = 3;

	private const int MaximumSerializedDeniedPlayers = 512;

	private const string RequestSettingsRpc = "OFDTECH_OdinRedPower_RequestSettings_v3";

	private const string ReceiveSettingsRpc = "OFDTECH_OdinRedPower_ReceiveSettings_v3";

	private const float SettingsBroadcastInterval = 5f;

	internal static ConfigEntry<bool> PowerEnabled;

	internal static ConfigEntry<float> DamageMultiplier;

	internal static ConfigEntry<float> CarryMultiplier;

	internal static ConfigEntry<float> HealthBonus;

	internal static ConfigEntry<float> StaminaBonus;

	internal static ConfigEntry<float> HealthRegenMultiplier;

	internal static ConfigEntry<float> DamageReduction;

	internal static ConfigEntry<float> StaminaCostReduction;

	internal static ConfigEntry<float> RunMultiplier;

	internal static ConfigEntry<float> JumpMultiplier;

	internal static ConfigEntry<bool> GroundCircleEnabled;

	internal static ConfigEntry<float> CircleRed;

	internal static ConfigEntry<float> CircleGreen;

	internal static ConfigEntry<float> CircleBlue;

	private readonly HashSet<long> _deniedPlayerIds = new HashSet<long>();

	private readonly List<OnlinePlayer> _onlinePlayers = new List<OnlinePlayer>();

	private Harmony _harmony;

	private MethodInfo _updateFoodMethod;

	private ZNet _observedNetwork;

	private ZRoutedRpc _registeredRoutedRpc;

	private MethodInfo _getServerPeerIdMethod;

	private long _observedWorldId = long.MinValue;

	private long _observedLocalUserId = long.MinValue;

	private long _observedServerPeerId = long.MinValue;

	private long _permissionWorldId = long.MinValue;

	private ConfigEntry<string> _deniedPlayersConfig;

	private string _lastDeniedConfigValue;

	private PowerSettings _lastAuthoritySettings;

	private PowerSettings _remoteSettings;

	private PowerSettings _localRuntimeSettings;

	private PowerSettings _lastAppliedSettings;

	private Player _lastAppliedPlayer;

	private bool _lastAppliedPowerActive;

	private bool _localRuntimePowerActive;

	private bool _hasLocalRuntimeState;

	private bool _hasAppliedLocalState;

	private bool _warnedFoodRefreshFailure;

	private bool _warnedNoPlayerOwnership;

	private bool _warnedRoutedPeerIdFailure;

	private float _nextSettingsRequestTime;

	private float _nextSettingsBroadcastTime;

	private float _nextPlayerRefreshTime;

	private const int WindowId = 184326;

	private const float PreferredWindowWidth = 860f;

	private const float PreferredWindowHeight = 720f;

	private static readonly Dictionary<string, string[]> UiStrings = new Dictionary<string, string[]>
	{
		{
			"subtitle_host",
			new string[3] { "HOST SETTINGS", "SUNUCU SAHİBİ AYARLARI", "AJUSTES DEL ANFITRIÓN" }
		},
		{
			"subtitle_single",
			new string[3] { "SINGLE-PLAYER SETTINGS", "TEK OYUNCULU AYARLARI", "AJUSTES DE UN JUGADOR" }
		},
		{
			"enabled",
			new string[3] { "POWER ACTIVE", "GÜÇ AÇIK", "PODER ACTIVO" }
		},
		{
			"disabled",
			new string[3] { "POWER INACTIVE", "GÜÇ KAPALI", "PODER INACTIVO" }
		},
		{
			"close",
			new string[3] { "Close", "Kapat", "Cerrar" }
		},
		{
			"tab_power",
			new string[3] { "POWER", "GÜÇ", "PODER" }
		},
		{
			"tab_appearance",
			new string[3] { "APPEARANCE", "GÖRÜNÜM", "ASPECTO" }
		},
		{
			"tab_players",
			new string[3] { "PLAYERS", "OYUNCULAR", "JUGADORES" }
		},
		{
			"power_section",
			new string[3] { "POWER STATUS", "GÜÇ DURUMU", "ESTADO DEL PODER" }
		},
		{
			"sync_desc",
			new string[3] { "Settings are shared with allowed players in this world.", "Ayarlar bu dünyadaki izinli oyuncularla eşitlenir.", "Los ajustes se comparten con los jugadores autorizados de este mundo." }
		},
		{
			"solo_desc",
			new string[3] { "Enable or disable your powers in this world.", "Bu dünyadaki güçlerini etkinleştir veya kapat.", "Activa o desactiva tus poderes en este mundo." }
		},
		{
			"disable_power",
			new string[3] { "DISABLE POWER", "GÜCÜ KAPAT", "DESACTIVAR PODER" }
		},
		{
			"enable_power",
			new string[3] { "ENABLE POWER", "GÜCÜ ETKİNLEŞTİR", "ACTIVAR PODER" }
		},
		{
			"combat",
			new string[3] { "COMBAT & MOVEMENT", "SAVAŞ VE HAREKET", "COMBATE Y MOVIMIENTO" }
		},
		{
			"attack_damage",
			new string[3] { "Attack damage", "Saldırı hasarı", "Daño de ataque" }
		},
		{
			"carry",
			new string[3] { "Carry capacity", "Taşıma kapasitesi", "Capacidad de carga" }
		},
		{
			"run",
			new string[3] { "Run speed", "Koşu hızı", "Velocidad al correr" }
		},
		{
			"jump",
			new string[3] { "Jump height", "Zıplama yüksekliği", "Altura de salto" }
		},
		{
			"vitality",
			new string[3] { "VITALITY & DEFENSE", "CAN VE SAVUNMA", "VITALIDAD Y DEFENSA" }
		},
		{
			"health_bonus",
			new string[3] { "Maximum health bonus", "Ek azami can", "Salud máxima adicional" }
		},
		{
			"stamina_bonus",
			new string[3] { "Maximum stamina bonus", "Ek azami dayanıklılık", "Resistencia máxima adicional" }
		},
		{
			"health_regen",
			new string[3] { "Health regeneration", "Can yenilenmesi", "Regeneración de salud" }
		},
		{
			"damage_reduction",
			new string[3] { "Incoming damage reduction", "Alınan hasar azaltma", "Reducción de daño recibido" }
		},
		{
			"stamina_reduction",
			new string[3] { "Stamina cost reduction", "Dayanıklılık tüketimi azaltma", "Reducción del coste de resistencia" }
		},
		{
			"food_refill",
			new string[3] { "When enabled, food-based maximums recalculate and both bars refill.", "Güç açılınca yemek kaynaklı azami değerler yenilenir ve barlar dolar.", "Al activar el poder, se recalculan los máximos de comida y se rellenan ambas barras." }
		},
		{
			"appearance",
			new string[3] { "PLAYER APPEARANCE", "OYUNCU GÖRÜNÜMÜ", "ASPECTO DEL JUGADOR" }
		},
		{
			"ground_circle",
			new string[3] { "Ground circle", "Zemin dairesi", "Círculo en el suelo" }
		},
		{
			"circle_desc",
			new string[3] { "Shown under players while their power is active.", "Gücü etkin oyuncuların altında görünür.", "Aparece bajo los jugadores con el poder activo." }
		},
		{
			"on",
			new string[3] { "ON", "AÇIK", "ACTIVO" }
		},
		{
			"off",
			new string[3] { "OFF", "KAPALI", "INACTIVO" }
		},
		{
			"circle_color",
			new string[3] { "CIRCLE COLOR", "DAİRE RENGİ", "COLOR DEL CÍRCULO" }
		},
		{
			"rgb_desc",
			new string[3] { "Adjust RGB values; the preview updates immediately.", "RGB değerlerini değiştir; önizleme anında güncellenir.", "Ajusta los valores RGB; la vista previa cambia al instante." }
		},
		{
			"red",
			new string[3] { "Red", "Kırmızı", "Rojo" }
		},
		{
			"green",
			new string[3] { "Green", "Yeşil", "Verde" }
		},
		{
			"blue",
			new string[3] { "Blue", "Mavi", "Azul" }
		},
		{
			"permissions",
			new string[3] { "PLAYER PERMISSIONS", "OYUNCU İZİNLERİ", "PERMISOS DE JUGADORES" }
		},
		{
			"permission_desc",
			new string[3] { "Only the host can change access. New players are allowed by default.", "İzinleri yalnızca sunucu sahibi değiştirir. Yeni oyuncular varsayılan olarak izinlidir.", "Solo el anfitrión puede cambiar los permisos. Los jugadores nuevos tienen acceso por defecto." }
		},
		{
			"loading_players",
			new string[3] { "Waiting for connected players…", "Oyuncu listesi yükleniyor…", "Esperando a los jugadores conectados…" }
		},
		{
			"host_role",
			new string[3] { "WORLD HOST", "SUNUCU SAHİBİ", "ANFITRIÓN DEL MUNDO" }
		},
		{
			"connected_role",
			new string[3] { "CONNECTED PLAYER", "BAĞLI OYUNCU", "JUGADOR CONECTADO" }
		},
		{
			"allowed",
			new string[3] { "POWER ALLOWED", "GÜÇ İZNİ VAR", "PODER PERMITIDO" }
		},
		{
			"denied",
			new string[3] { "POWER BLOCKED", "GÜÇ ENGELLİ", "PODER BLOQUEADO" }
		},
		{
			"footer_host",
			new string[3] { "OPEN FROM THE PAUSE MENU · HOST ONLY", "DURAKLATMA MENÜSÜNDEN AÇ · YALNIZCA SUNUCU SAHİBİ", "ABRIR DESDE PAUSA · SOLO ANFITRIÓN" }
		},
		{
			"footer_toggle",
			new string[3] { "Open from the pause menu", "Duraklatma menüsünden aç", "Abrir desde el menú de pausa" }
		},
		{
			"pause_button",
			new string[3] { "OdinRedPower", "OdinRedPower", "OdinRedPower" }
		},
		{
			"reset",
			new string[3] { "RESET DEFAULTS", "VARSAYILANLAR", "RESTABLECER" }
		}
	};

	private static readonly CultureInfo[] UiCultures = new CultureInfo[3]
	{
		CultureInfo.GetCultureInfo("en-US"),
		CultureInfo.GetCultureInfo("tr-TR"),
		CultureInfo.GetCultureInfo("es-ES")
	};

	private bool _menuOpen;

	private bool _pausedByMod;

	private bool _languageChangeSubscribed;

	private bool _cursorWasVisible;

	private bool _cursorWasRequested;

	private CursorLockMode _cursorLockWas;

	private UiLanguage _uiLanguage;

	private string _detectedGameLanguage;

	private Rect _pauseMenuButtonRect;

	private float _nextPauseMenuLayoutCheck;

	private GameObject _pauseMenuUiButton;

	private Transform _pauseMenuUiButtonParent;

	private bool _pauseMenuUiButtonFailureLogged;

	private float _nextPauseMenuUiButtonAttempt;

	private int _activeTab;

	private Rect _windowRect;

	private Vector2 _contentScroll;

	private readonly List<Texture2D> _guiTextures = new List<Texture2D>();

	private Texture2D _shadeTexture;

	private GUIStyle _windowStyle;

	private GUIStyle _headerStyle;

	private GUIStyle _cardStyle;

	private GUIStyle _rowStyle;

	private GUIStyle _titleStyle;

	private GUIStyle _subtitleStyle;

	private GUIStyle _sectionStyle;

	private GUIStyle _labelStyle;

	private GUIStyle _mutedStyle;

	private GUIStyle _valueStyle;

	private GUIStyle _statusStyle;

	private GUIStyle _tabStyle;

	private GUIStyle _activeTabStyle;

	private GUIStyle _buttonStyle;

	private GUIStyle _primaryButtonStyle;

	private GUIStyle _denyButtonStyle;

	private GUIStyle _allowButtonStyle;

	private GUIStyle _closeButtonStyle;

	private GUIStyle _pauseMenuButtonStyle;

	private GUIStyle _sliderStyle;

	private GUIStyle _sliderThumbStyle;

	private GUIStyle _colorPreviewStyle;

	private GUIStyle _accentStyle;

	internal static Plugin Instance { get; private set; }

	private bool IsServerAuthority
	{
		get
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return ZNet.instance.IsServer();
			}
			return false;
		}
	}

	private bool IsMultiplayerSession
	{
		get
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return !ZNet.IsSinglePlayer;
			}
			return false;
		}
	}

	private bool CanOpenMenu
	{
		get
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				return IsServerAuthority;
			}
			return false;
		}
	}

	private void Awake()
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		Instance = this;
		((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
		BindConfiguration();
		_updateFoodMethod = AccessTools.Method(typeof(Player), "UpdateFood", new Type[2]
		{
			typeof(float),
			typeof(bool)
		}, (Type[])null);
		_getServerPeerIdMethod = AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null);
		_harmony = new Harmony("oftech.valheim.odinredpowermod");
		_harmony.PatchAll(Assembly.GetExecutingAssembly());
		PatchOptionalGameplayBonuses();
		InitializeWindow();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Odin Red Power Mod 0.4.2 yüklendi.");
	}

	private void PatchOptionalGameplayBonuses()
	{
		int num = PatchMethods(typeof(Player), "UpdateHealth", typeof(float), "HealthUpdatePrefix");
		int num2 = PatchMethods(typeof(Humanoid), "UseStamina", typeof(float), "StaminaUsePrefix");
		int num3 = PatchMethods(typeof(Character), "Damage", typeof(HitData), "IncomingDamagePrefix");
		if (num == 0)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Health regeneration hook was not found; the health regeneration slider will have no effect.");
		}
		if (num2 == 0)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Stamina usage hook was not found; the stamina cost slider will have no effect.");
		}
		if (num3 == 0)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Incoming damage hook was not found; the damage reduction slider will have no effect.");
		}
	}

	private int PatchMethods(Type targetType, string methodName, Type firstParameterType, string prefixName)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), prefixName, (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			return 0;
		}
		int num = 0;
		MethodInfo[] methods = targetType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo methodInfo2 in methods)
		{
			if (methodInfo2.Name != methodName)
			{
				continue;
			}
			ParameterInfo[] parameters = methodInfo2.GetParameters();
			if (parameters.Length != 0 && !(parameters[0].ParameterType != firstParameterType))
			{
				try
				{
					_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not patch " + targetType.Name + "." + methodName + ": " + ex.GetBaseException().Message));
				}
			}
		}
		return num;
	}

	private static void HealthUpdatePrefix(Player __instance, object[] __args)
	{
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && IsPowerActive(__instance) && __args != null && __args.Length != 0 && __args[0] is float)
		{
			float num = (float)__args[0];
			if (num > 0f)
			{
				float playerValue = GetPlayerValue(__instance, "oftech.odinredpowermod.healthregen", 1.5f);
				__args[0] = num * Mathf.Clamp(playerValue, 1f, 3f);
			}
		}
	}

	private static void StaminaUsePrefix(Humanoid __instance, object[] __args)
	{
		Player val = (Player)(object)((__instance is Player) ? __instance : null);
		if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && IsPowerActive(val) && __args != null && __args.Length != 0 && __args[0] is float)
		{
			float num = (float)__args[0];
			if (num > 0f)
			{
				float num2 = Mathf.Clamp01(GetPlayerValue(val, "oftech.odinredpowermod.staminacostreduction", 0.2f));
				__args[0] = num * (1f - num2);
			}
		}
	}

	private static void IncomingDamagePrefix(Character __instance, object[] __args)
	{
		Player val = (Player)(object)((__instance is Player) ? __instance : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !IsPowerActive(val) || __args == null || __args.Length == 0)
		{
			return;
		}
		object obj = __args[0];
		HitData val2 = (HitData)((obj is HitData) ? obj : null);
		if (val2 != null)
		{
			float num = Mathf.Clamp(GetPlayerValue(val, "oftech.odinredpowermod.damagereduction", 0.2f), 0f, 0.75f);
			if (num > 0f)
			{
				((DamageTypes)(ref val2.m_damage)).Modify(1f - num);
			}
		}
	}

	private void BindConfiguration()
	{
		PowerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Power", "Enabled", false, "Güç bonuslarını ve zemin dairesini etkinleştirir.");
		DamageMultiplier = BindFloat("Power", "DamageMultiplier", 1.25f, 1f, 3f, "Verilen saldırı hasarı çarpanı.");
		CarryMultiplier = BindFloat("Power", "CarryWeightMultiplier", 1.5f, 1f, 4f, "Azami taşıma ağırlığı çarpanı.");
		HealthBonus = BindFloat("Power", "HealthBonus", 100f, 0f, 300f, "Ek azami can.");
		StaminaBonus = BindFloat("Power", "StaminaBonus", 200f, 0f, 400f, "Ek azami dayanıklılık.");
		HealthRegenMultiplier = BindFloat("Power", "HealthRegenMultiplier", 1.5f, 1f, 3f, "Can yenilenme hızı çarpanı.");
		DamageReduction = BindFloat("Power", "DamageReduction", 0.2f, 0f, 0.75f, "Alınan hasardan azaltılacak oran.");
		StaminaCostReduction = BindFloat("Power", "StaminaCostReduction", 0.2f, 0f, 0.75f, "Harcanan dayanıklılıktan azaltılacak oran.");
		RunMultiplier = BindFloat("Power", "RunSpeedMultiplier", 1.2f, 1f, 1.5f, "Koşu hızı çarpanı.");
		JumpMultiplier = BindFloat("Power", "JumpHeightMultiplier", 1.5f, 1f, 2f, "Zıplama yüksekliği çarpanı.");
		GroundCircleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "GroundCircleEnabled", true, "Güç etkinken karakterin altında daire gösterir.");
		CircleRed = BindFloat("Visual", "CircleRed", 0.86f, 0f, 1f, "Zemin dairesinin kırmızı renk değeri.");
		CircleGreen = BindFloat("Visual", "CircleGreen", 0.055f, 0f, 1f, "Zemin dairesinin yeşil renk değeri.");
		CircleBlue = BindFloat("Visual", "CircleBlue", 0.045f, 0f, 1f, "Zemin dairesinin mavi renk değeri.");
	}

	private ConfigEntry<float> BindFloat(string section, string key, float defaultValue, float minimum, float maximum, string description)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		return ((BaseUnityPlugin)this).Config.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(minimum, maximum), Array.Empty<object>()));
	}

	private void Update()
	{
		ObserveNetworkChanges();
		EnsureDeniedPlayersConfiguration();
		EnsureRoutedRpcRegistration();
		SyncDeniedListFromConfig();
		EnsureLanguageChangeSubscription();
		RefreshOnlinePlayers(force: false);
		if (IsServerAuthority)
		{
			if (AuthoritySettingsChanged())
			{
				PowerSettings settings = (_lastAuthoritySettings = CaptureAuthoritySettings());
				if (IsMultiplayerSession)
				{
					BroadcastSettings(settings);
					_nextSettingsBroadcastTime = Time.unscaledTime + 5f;
				}
			}
			else if (IsMultiplayerSession && Time.unscaledTime >= _nextSettingsBroadcastTime)
			{
				BroadcastSettings(_lastAuthoritySettings = CaptureAuthoritySettings());
				_nextSettingsBroadcastTime = Time.unscaledTime + 5f;
			}
		}
		else if (IsMultiplayerSession)
		{
			RequestSettingsIfNeeded();
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			_lastAppliedPlayer = null;
			_localRuntimeSettings = null;
			_localRuntimePowerActive = false;
			_hasLocalRuntimeState = false;
			_hasAppliedLocalState = false;
		}
		else
		{
			PowerSettings effectiveSettings = GetEffectiveSettings();
			if (effectiveSettings == null)
			{
				KeepLocalPlayerDisabled(localPlayer);
			}
			else
			{
				ApplySettingsToLocalPlayer(localPlayer, effectiveSettings);
			}
		}
	}

	private void LateUpdate()
	{
		if (_menuOpen)
		{
			ForceCursorFree();
		}
	}

	private void ObserveNetworkChanges()
	{
		ZNet instance = ZNet.instance;
		long num = (((Object)(object)instance == (Object)null) ? 0 : instance.GetWorldUID());
		long num2 = (((Object)(object)instance == (Object)null) ? 0 : ZNet.GetUID());
		long num3 = 0L;
		if ((Object)(object)instance != (Object)null && !instance.IsServer())
		{
			num3 = GetRoutedServerPeerId();
		}
		bool num4 = (Object)(object)instance != (Object)(object)_observedNetwork;
		bool flag = num != 0L && num != _observedWorldId;
		bool flag2 = num2 != 0L && num2 != _observedLocalUserId;
		bool flag3 = num3 != _observedServerPeerId;
		if (num4 || flag || flag2 || flag3)
		{
			if (_menuOpen)
			{
				SetMenuOpen(open: false);
			}
			_observedNetwork = instance;
			if (num != 0L)
			{
				_observedWorldId = num;
			}
			if (num2 != 0L)
			{
				_observedLocalUserId = num2;
			}
			_observedServerPeerId = num3;
			_registeredRoutedRpc = null;
			_remoteSettings = null;
			_localRuntimeSettings = null;
			_localRuntimePowerActive = false;
			_hasLocalRuntimeState = false;
			_lastAuthoritySettings = null;
			_deniedPlayersConfig = null;
			_lastDeniedConfigValue = null;
			_permissionWorldId = long.MinValue;
			_deniedPlayerIds.Clear();
			_onlinePlayers.Clear();
			_lastAppliedPlayer = null;
			_lastAppliedSettings = null;
			_hasAppliedLocalState = false;
			_nextSettingsRequestTime = 0f;
			_nextSettingsBroadcastTime = 0f;
		}
	}

	private void EnsureDeniedPlayersConfiguration()
	{
		if (IsServerAuthority && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.IsSinglePlayer)
		{
			long worldUID = ZNet.instance.GetWorldUID();
			if (worldUID != 0L && (_deniedPlayersConfig == null || _permissionWorldId != worldUID))
			{
				_permissionWorldId = worldUID;
				string text = "DeniedPlayerIds_" + worldUID.ToString("X16", CultureInfo.InvariantCulture);
				_deniedPlayersConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Player Permissions", text, string.Empty, "Comma-separated Valheim player IDs denied the power in this world. Edit permissions from the pause menu.");
				_lastDeniedConfigValue = _deniedPlayersConfig.Value ?? string.Empty;
				ParseDeniedPlayerIds(_lastDeniedConfigValue, _deniedPlayerIds);
				_lastAuthoritySettings = null;
			}
		}
	}

	private void SyncDeniedListFromConfig()
	{
		if (_deniedPlayersConfig != null)
		{
			string text = _deniedPlayersConfig.Value ?? string.Empty;
			if (!string.Equals(text, _lastDeniedConfigValue, StringComparison.Ordinal))
			{
				_lastDeniedConfigValue = text;
				ParseDeniedPlayerIds(text, _deniedPlayerIds);
				_lastAuthoritySettings = null;
			}
		}
	}

	private static void ParseDeniedPlayerIds(string value, HashSet<long> target)
	{
		target.Clear();
		if (string.IsNullOrWhiteSpace(value))
		{
			return;
		}
		string[] array = value.Split(new char[6] { ',', ';', ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			if (target.Count >= 512)
			{
				break;
			}
			if (long.TryParse(array[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && result != 0L)
			{
				target.Add(result);
			}
		}
	}

	private void SaveDeniedPlayerIds()
	{
		if (_deniedPlayersConfig != null)
		{
			List<long> list = new List<long>(_deniedPlayerIds);
			list.Sort();
			string text = string.Join(",", list.ConvertAll((long id) => id.ToString(CultureInfo.InvariantCulture)).ToArray());
			_deniedPlayersConfig.Value = text;
			_lastDeniedConfigValue = text;
			((BaseUnityPlugin)this).Config.Save();
			_lastAuthoritySettings = null;
		}
	}

	private void EnsureRoutedRpcRegistration()
	{
		ZRoutedRpc instance = ZRoutedRpc.instance;
		if (instance != null && instance != _registeredRoutedRpc)
		{
			if (_registeredRoutedRpc != null && !IsServerAuthority)
			{
				_remoteSettings = null;
				_nextSettingsRequestTime = 0f;
			}
			_registeredRoutedRpc = instance;
			instance.Register("OFDTECH_OdinRedPower_RequestSettings_v3", (Action<long>)RPC_RequestSettings);
			instance.Register<ZPackage>("OFDTECH_OdinRedPower_ReceiveSettings_v3", (Action<long, ZPackage>)RPC_ReceiveSettings);
		}
	}

	private void RPC_RequestSettings(long sender)
	{
		if (IsServerAuthority && _registeredRoutedRpc != null && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.GetPeer(sender) != null)
		{
			SendSettingsToPeer(sender, CaptureAuthoritySettings());
		}
	}

	private void RPC_ReceiveSettings(long sender, ZPackage package)
	{
		if (IsServerAuthority || !IsMultiplayerSession || _registeredRoutedRpc == null || package == null)
		{
			return;
		}
		long routedServerPeerId = GetRoutedServerPeerId();
		if (sender != routedServerPeerId)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Sunucu dışı bir istemciden ayar paketi geldi; paket yok sayıldı.");
			return;
		}
		if (!TryReadSettings(package, out var settings))
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Sunucudan gelen ayar paketi geçersiz veya desteklenmeyen biçimde.");
			return;
		}
		bool num = !SettingsEqual(_remoteSettings, settings);
		_remoteSettings = settings;
		if (num)
		{
			_lastAppliedSettings = null;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Received authoritative Odin Red Power settings. Power: " + (settings.PowerEnabled ? "enabled" : "disabled") + ", denied players: " + settings.DeniedPlayerIds.Count.ToString(CultureInfo.InvariantCulture) + "."));
		}
	}

	private void RequestSettingsIfNeeded()
	{
		if (_remoteSettings != null || _registeredRoutedRpc == null || (Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		float unscaledTime = Time.unscaledTime;
		if (!(unscaledTime < _nextSettingsRequestTime))
		{
			long routedServerPeerId = GetRoutedServerPeerId();
			if (routedServerPeerId == 0L)
			{
				_nextSettingsRequestTime = unscaledTime + 2f;
				return;
			}
			_registeredRoutedRpc.InvokeRoutedRPC(routedServerPeerId, "OFDTECH_OdinRedPower_RequestSettings_v3", Array.Empty<object>());
			_nextSettingsRequestTime = unscaledTime + 3f;
		}
	}

	private long GetRoutedServerPeerId()
	{
		ZRoutedRpc val = ((_registeredRoutedRpc != null) ? _registeredRoutedRpc : ZRoutedRpc.instance);
		if (val != null)
		{
			try
			{
				if (_getServerPeerIdMethod == null)
				{
					_getServerPeerIdMethod = AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null);
				}
				if (_getServerPeerIdMethod != null && _getServerPeerIdMethod.Invoke(val, null) is long num && num != 0L)
				{
					return num;
				}
			}
			catch (Exception ex)
			{
				if (!_warnedRoutedPeerIdFailure)
				{
					_warnedRoutedPeerIdFailure = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read Valheim's routed server peer ID; falling back to the connection peer ID: " + ex.GetBaseException().Message));
				}
			}
		}
		ZNet instance = ZNet.instance;
		return (((Object)(object)instance == (Object)null) ? null : instance.GetServerPeer())?.m_uid ?? 0;
	}

	private void BroadcastSettings(PowerSettings settings)
	{
		if (!IsServerAuthority || _registeredRoutedRpc == null || (Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		List<ZNetPeer> peers = ZNet.instance.GetPeers();
		if (peers == null)
		{
			return;
		}
		for (int i = 0; i < peers.Count; i++)
		{
			ZNetPeer val = peers[i];
			if (val != null && val.IsReady())
			{
				SendSettingsToPeer(val.m_uid, settings);
			}
		}
	}

	private void SendSettingsToPeer(long peerId, PowerSettings settings)
	{
		if (_registeredRoutedRpc == null || settings == null)
		{
			return;
		}
		try
		{
			ZPackage val = WriteSettings(settings);
			_registeredRoutedRpc.InvokeRoutedRPC(peerId, "OFDTECH_OdinRedPower_ReceiveSettings_v3", new object[1] { val });
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Ayarlar oyuncuya gönderilemedi (" + peerId.ToString(CultureInfo.InvariantCulture) + "): " + ex.GetBaseException().Message));
		}
	}

	private static ZPackage WriteSettings(PowerSettings settings)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(3);
		val.Write(settings.PowerEnabled);
		val.Write(settings.DamageMultiplier);
		val.Write(settings.CarryMultiplier);
		val.Write(settings.HealthBonus);
		val.Write(settings.StaminaBonus);
		val.Write(settings.HealthRegenMultiplier);
		val.Write(settings.DamageReduction);
		val.Write(settings.StaminaCostReduction);
		val.Write(settings.RunMultiplier);
		val.Write(settings.JumpMultiplier);
		val.Write(settings.GroundCircleEnabled);
		val.Write(settings.CircleRed);
		val.Write(settings.CircleGreen);
		val.Write(settings.CircleBlue);
		List<long> list = new List<long>(settings.DeniedPlayerIds);
		list.Sort();
		if (list.Count > 512)
		{
			list.RemoveRange(512, list.Count - 512);
		}
		val.Write(list.Count);
		for (int i = 0; i < list.Count; i++)
		{
			val.Write(list[i]);
		}
		return val;
	}

	private static bool TryReadSettings(ZPackage package, out PowerSettings settings)
	{
		settings = null;
		try
		{
			package.SetPos(0);
			if (package.ReadInt() != 3)
			{
				return false;
			}
			PowerSettings powerSettings = new PowerSettings();
			powerSettings.PowerEnabled = package.ReadBool();
			float num = package.ReadSingle();
			float num2 = package.ReadSingle();
			float num3 = package.ReadSingle();
			float num4 = package.ReadSingle();
			float num5 = package.ReadSingle();
			float num6 = package.ReadSingle();
			float num7 = package.ReadSingle();
			float num8 = package.ReadSingle();
			float num9 = package.ReadSingle();
			powerSettings.GroundCircleEnabled = package.ReadBool();
			float num10 = package.ReadSingle();
			float num11 = package.ReadSingle();
			float num12 = package.ReadSingle();
			if (!IsFinite(num) || !IsFinite(num2) || !IsFinite(num3) || !IsFinite(num4) || !IsFinite(num5) || !IsFinite(num6) || !IsFinite(num7) || !IsFinite(num8) || !IsFinite(num9) || !IsFinite(num10) || !IsFinite(num11) || !IsFinite(num12))
			{
				return false;
			}
			powerSettings.DamageMultiplier = Mathf.Clamp(num, 1f, 3f);
			powerSettings.CarryMultiplier = Mathf.Clamp(num2, 1f, 4f);
			powerSettings.HealthBonus = Mathf.Clamp(num3, 0f, 300f);
			powerSettings.StaminaBonus = Mathf.Clamp(num4, 0f, 400f);
			powerSettings.HealthRegenMultiplier = Mathf.Clamp(num5, 1f, 3f);
			powerSettings.DamageReduction = Mathf.Clamp(num6, 0f, 0.75f);
			powerSettings.StaminaCostReduction = Mathf.Clamp(num7, 0f, 0.75f);
			powerSettings.RunMultiplier = Mathf.Clamp(num8, 1f, 1.5f);
			powerSettings.JumpMultiplier = Mathf.Clamp(num9, 1f, 2f);
			powerSettings.CircleRed = Mathf.Clamp01(num10);
			powerSettings.CircleGreen = Mathf.Clamp01(num11);
			powerSettings.CircleBlue = Mathf.Clamp01(num12);
			int num13 = package.ReadInt();
			if (num13 < 0 || num13 > 512)
			{
				return false;
			}
			powerSettings.DeniedPlayerIds = new HashSet<long>();
			for (int i = 0; i < num13; i++)
			{
				long num14 = package.ReadLong();
				if (num14 != 0L)
				{
					powerSettings.DeniedPlayerIds.Add(num14);
				}
			}
			settings = powerSettings;
			return true;
		}
		catch
		{
			return false;
		}
	}

	private static bool IsFinite(float value)
	{
		if (!float.IsNaN(value))
		{
			return !float.IsInfinity(value);
		}
		return false;
	}

	private PowerSettings CaptureAuthoritySettings()
	{
		return new PowerSettings
		{
			PowerEnabled = PowerEnabled.Value,
			DamageMultiplier = DamageMultiplier.Value,
			CarryMultiplier = CarryMultiplier.Value,
			HealthBonus = HealthBonus.Value,
			StaminaBonus = StaminaBonus.Value,
			HealthRegenMultiplier = HealthRegenMultiplier.Value,
			DamageReduction = DamageReduction.Value,
			StaminaCostReduction = StaminaCostReduction.Value,
			RunMultiplier = RunMultiplier.Value,
			JumpMultiplier = JumpMultiplier.Value,
			GroundCircleEnabled = GroundCircleEnabled.Value,
			CircleRed = CircleRed.Value,
			CircleGreen = CircleGreen.Value,
			CircleBlue = CircleBlue.Value,
			DeniedPlayerIds = new HashSet<long>(_deniedPlayerIds)
		};
	}

	private PowerSettings GetEffectiveSettings()
	{
		if (IsServerAuthority)
		{
			return _lastAuthoritySettings ?? CaptureAuthoritySettings();
		}
		if (!IsMultiplayerSession)
		{
			return _lastAuthoritySettings ?? CaptureAuthoritySettings();
		}
		return _remoteSettings;
	}

	private bool AuthoritySettingsChanged()
	{
		PowerSettings lastAuthoritySettings = _lastAuthoritySettings;
		if (lastAuthoritySettings != null && lastAuthoritySettings.PowerEnabled == PowerEnabled.Value && !(Mathf.Abs(lastAuthoritySettings.DamageMultiplier - DamageMultiplier.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.CarryMultiplier - CarryMultiplier.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.HealthBonus - HealthBonus.Value) > 0.001f) && !(Mathf.Abs(lastAuthoritySettings.StaminaBonus - StaminaBonus.Value) > 0.001f) && !(Mathf.Abs(lastAuthoritySettings.HealthRegenMultiplier - HealthRegenMultiplier.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.DamageReduction - DamageReduction.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.StaminaCostReduction - StaminaCostReduction.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.RunMultiplier - RunMultiplier.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.JumpMultiplier - JumpMultiplier.Value) > 0.0001f) && lastAuthoritySettings.GroundCircleEnabled == GroundCircleEnabled.Value && !(Mathf.Abs(lastAuthoritySettings.CircleRed - CircleRed.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.CircleGreen - CircleGreen.Value) > 0.0001f) && !(Mathf.Abs(lastAuthoritySettings.CircleBlue - CircleBlue.Value) > 0.0001f))
		{
			return !lastAuthoritySettings.DeniedPlayerIds.SetEquals(_deniedPlayerIds);
		}
		return true;
	}

	private static bool SettingsEqual(PowerSettings left, PowerSettings right)
	{
		if (left == right)
		{
			return true;
		}
		if (left == null || right == null)
		{
			return false;
		}
		if (left.PowerEnabled == right.PowerEnabled && Mathf.Abs(left.DamageMultiplier - right.DamageMultiplier) < 0.0001f && Mathf.Abs(left.CarryMultiplier - right.CarryMultiplier) < 0.0001f && Mathf.Abs(left.HealthBonus - right.HealthBonus) < 0.001f && Mathf.Abs(left.StaminaBonus - right.StaminaBonus) < 0.001f && Mathf.Abs(left.HealthRegenMultiplier - right.HealthRegenMultiplier) < 0.0001f && Mathf.Abs(left.DamageReduction - right.DamageReduction) < 0.0001f && Mathf.Abs(left.StaminaCostReduction - right.StaminaCostReduction) < 0.0001f && Mathf.Abs(left.RunMultiplier - right.RunMultiplier) < 0.0001f && Mathf.Abs(left.JumpMultiplier - right.JumpMultiplier) < 0.0001f && left.GroundCircleEnabled == right.GroundCircleEnabled && Mathf.Abs(left.CircleRed - right.CircleRed) < 0.0001f && Mathf.Abs(left.CircleGreen - right.CircleGreen) < 0.0001f && Mathf.Abs(left.CircleBlue - right.CircleBlue) < 0.0001f)
		{
			return left.DeniedPlayerIds.SetEquals(right.DeniedPlayerIds);
		}
		return false;
	}

	private void ApplySettingsToLocalPlayer(Player player, PowerSettings settings)
	{
		long localUserId = GetLocalUserId();
		bool flag = localUserId == 0L || !settings.DeniedPlayerIds.Contains(localUserId);
		bool flag2 = settings.PowerEnabled && flag;
		bool flag3 = (Object)(object)player != (Object)(object)_lastAppliedPlayer;
		bool flag4 = !_hasLocalRuntimeState || !SettingsEqual(settings, _localRuntimeSettings);
		bool flag5 = !_hasLocalRuntimeState || flag2 != _localRuntimePowerActive;
		bool flag6 = !_hasLocalRuntimeState || _localRuntimeSettings == null || Mathf.Abs(settings.HealthBonus - _localRuntimeSettings.HealthBonus) > 0.001f || Mathf.Abs(settings.StaminaBonus - _localRuntimeSettings.StaminaBonus) > 0.001f;
		_localRuntimeSettings = settings;
		_localRuntimePowerActive = flag2;
		_hasLocalRuntimeState = true;
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
		{
			if (!_warnedNoPlayerOwnership && (Object)(object)component != (Object)null && component.IsValid())
			{
				_warnedNoPlayerOwnership = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Local player ZDO ownership is not ready; applying replicated visual data when ownership arrives.");
			}
			if (flag3 || flag5 || (flag2 && flag6))
			{
				RefreshFoodStats(player);
			}
			_lastAppliedPlayer = player;
			_lastAppliedPowerActive = flag2;
			_lastAppliedSettings = settings;
			_hasAppliedLocalState = false;
			return;
		}
		ZDO zDO = component.GetZDO();
		if (zDO == null)
		{
			_lastAppliedPlayer = player;
			_lastAppliedPowerActive = flag2;
			_lastAppliedSettings = settings;
			_hasAppliedLocalState = false;
		}
		else
		{
			if (!flag3 && _hasAppliedLocalState && !flag4)
			{
				return;
			}
			flag6 = !_hasAppliedLocalState || _lastAppliedSettings == null || Mathf.Abs(settings.HealthBonus - _lastAppliedSettings.HealthBonus) > 0.001f || Mathf.Abs(settings.StaminaBonus - _lastAppliedSettings.StaminaBonus) > 0.001f;
			flag5 = !_hasAppliedLocalState || flag2 != _lastAppliedPowerActive;
			SetIfDifferent(zDO, "oftech.odinredpowermod.active", flag2);
			SetIfDifferent(zDO, "oftech.odinredpowermod.damage", settings.DamageMultiplier);
			SetIfDifferent(zDO, "oftech.odinredpowermod.carry", settings.CarryMultiplier);
			SetIfDifferent(zDO, "oftech.odinredpowermod.health", settings.HealthBonus);
			SetIfDifferent(zDO, "oftech.odinredpowermod.stamina", settings.StaminaBonus);
			SetIfDifferent(zDO, "oftech.odinredpowermod.healthregen", settings.HealthRegenMultiplier);
			SetIfDifferent(zDO, "oftech.odinredpowermod.damagereduction", settings.DamageReduction);
			SetIfDifferent(zDO, "oftech.odinredpowermod.staminacostreduction", settings.StaminaCostReduction);
			SetIfDifferent(zDO, "oftech.odinredpowermod.run", settings.RunMultiplier);
			SetIfDifferent(zDO, "oftech.odinredpowermod.jump", settings.JumpMultiplier);
			SetIfDifferent(zDO, "oftech.odinredpowermod.circle.enabled", settings.GroundCircleEnabled);
			SetIfDifferent(zDO, "oftech.odinredpowermod.circle.red", settings.CircleRed);
			SetIfDifferent(zDO, "oftech.odinredpowermod.circle.green", settings.CircleGreen);
			SetIfDifferent(zDO, "oftech.odinredpowermod.circle.blue", settings.CircleBlue);
			if (flag3 || flag5 || (flag2 && flag6))
			{
				RefreshFoodStats(player);
				if (flag2)
				{
					FillHealthAndStamina(player);
				}
			}
			_lastAppliedPlayer = player;
			_lastAppliedPowerActive = flag2;
			_lastAppliedSettings = settings;
			_hasAppliedLocalState = true;
			_warnedNoPlayerOwnership = false;
		}
	}

	private void KeepLocalPlayerDisabled(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		bool localRuntimePowerActive = _localRuntimePowerActive;
		bool flag = _localRuntimeSettings != null;
		_localRuntimeSettings = null;
		_localRuntimePowerActive = false;
		_hasLocalRuntimeState = true;
		if (localRuntimePowerActive || flag)
		{
			RefreshFoodStats(player);
		}
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner())
		{
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				SetIfDifferent(zDO, "oftech.odinredpowermod.active", value: false);
			}
			_lastAppliedPlayer = player;
			_lastAppliedPowerActive = false;
			_lastAppliedSettings = null;
			_hasAppliedLocalState = true;
		}
	}

	private void RefreshFoodStats(Player player)
	{
		if (_updateFoodMethod == null)
		{
			if (!_warnedFoodRefreshFailure)
			{
				_warnedFoodRefreshFailure = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Player.UpdateFood(float, bool) bulunamadı; yemek bonusları bir sonraki yemek güncellemesinde uygulanacak.");
			}
			return;
		}
		try
		{
			_updateFoodMethod.Invoke(player, new object[2] { 0f, true });
		}
		catch (Exception ex)
		{
			if (!_warnedFoodRefreshFailure)
			{
				_warnedFoodRefreshFailure = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Yemek kaynaklı can/dayanıklılık değerleri yenilenemedi: " + ex.GetBaseException().Message));
			}
		}
	}

	private static void FillHealthAndStamina(Player player)
	{
		float maxHealth = ((Character)player).GetMaxHealth();
		if (((Character)player).GetHealth() < maxHealth)
		{
			((Character)player).SetHealth(maxHealth);
		}
		float num = ((Character)player).GetMaxStamina() - player.GetStamina();
		if (num > 0.01f)
		{
			((Character)player).AddStamina(num);
		}
	}

	private void RefreshOnlinePlayers(bool force)
	{
		if (!IsServerAuthority || !IsMultiplayerSession || (Object)(object)ZNet.instance == (Object)null)
		{
			_onlinePlayers.Clear();
			return;
		}
		float unscaledTime = Time.unscaledTime;
		if (!force && unscaledTime < _nextPlayerRefreshTime)
		{
			return;
		}
		_nextPlayerRefreshTime = unscaledTime + 1f;
		_onlinePlayers.Clear();
		long localUserId = GetLocalUserId();
		_onlinePlayers.Add(new OnlinePlayer(localUserId, "Sunucu sahibi (sen)", isHost: true));
		List<ZNetPeer> peers = ZNet.instance.GetPeers();
		if (peers == null)
		{
			return;
		}
		for (int i = 0; i < peers.Count; i++)
		{
			ZNetPeer val = peers[i];
			if (val != null && val.IsReady() && val.m_uid != localUserId)
			{
				string name = (string.IsNullOrWhiteSpace(val.m_playerName) ? "Oyuncu" : val.m_playerName.Trim());
				_onlinePlayers.Add(new OnlinePlayer(val.m_uid, name, isHost: false));
			}
		}
	}

	private long GetLocalUserId()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNet.instance == (Object)null)
		{
			return 0L;
		}
		long uID = ZNet.GetUID();
		if (uID != 0L)
		{
			return uID;
		}
		ZDOID localPlayerCharacterID = ZNet.instance.LocalPlayerCharacterID;
		return ((ZDOID)(ref localPlayerCharacterID)).UserID;
	}

	private void SetPlayerAllowed(long playerId, bool allowed)
	{
		if (IsServerAuthority && playerId != 0L && (allowed ? _deniedPlayerIds.Remove(playerId) : _deniedPlayerIds.Add(playerId)))
		{
			SaveDeniedPlayerIds();
		}
	}

	private bool IsPlayerAllowed(long playerId)
	{
		if (playerId != 0L)
		{
			return !_deniedPlayerIds.Contains(playerId);
		}
		return true;
	}

	private void OnGUI()
	{
		if (_menuOpen)
		{
			SetPauseMenuUiButtonVisible(visible: false);
			DrawSettingsWindow();
		}
		else
		{
			DrawPauseMenuButton();
		}
	}

	private void OnDestroy()
	{
		StopListeningForLanguageChanges();
		if ((Object)(object)_pauseMenuUiButton != (Object)null)
		{
			Object.Destroy((Object)(object)_pauseMenuUiButton);
			_pauseMenuUiButton = null;
			_pauseMenuUiButtonParent = null;
		}
		if (_menuOpen)
		{
			SetMenuOpen(open: false);
		}
		try
		{
			((BaseUnityPlugin)this).Config.Save();
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Mod kapatılırken temizlik tamamlanamadı: " + ex.GetBaseException().Message));
		}
		DestroyGuiResources();
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	internal static bool IsPowerActive(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		if ((Object)(object)Instance != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer)
		{
			return Instance._localRuntimePowerActive;
		}
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			return false;
		}
		ZDO zDO = component.GetZDO();
		if (zDO != null)
		{
			return zDO.GetBool("oftech.odinredpowermod.active", false);
		}
		return false;
	}

	internal static float GetPlayerValue(Player player, string key, float fallback)
	{
		if ((Object)(object)player == (Object)null)
		{
			return fallback;
		}
		if ((Object)(object)Instance != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer && Instance._localRuntimeSettings != null)
		{
			PowerSettings localRuntimeSettings = Instance._localRuntimeSettings;
			switch (key)
			{
			case "oftech.odinredpowermod.damage":
				return localRuntimeSettings.DamageMultiplier;
			case "oftech.odinredpowermod.carry":
				return localRuntimeSettings.CarryMultiplier;
			case "oftech.odinredpowermod.health":
				return localRuntimeSettings.HealthBonus;
			case "oftech.odinredpowermod.stamina":
				return localRuntimeSettings.StaminaBonus;
			case "oftech.odinredpowermod.healthregen":
				return localRuntimeSettings.HealthRegenMultiplier;
			case "oftech.odinredpowermod.damagereduction":
				return localRuntimeSettings.DamageReduction;
			case "oftech.odinredpowermod.staminacostreduction":
				return localRuntimeSettings.StaminaCostReduction;
			case "oftech.odinredpowermod.run":
				return localRuntimeSettings.RunMultiplier;
			case "oftech.odinredpowermod.jump":
				return localRuntimeSettings.JumpMultiplier;
			case "oftech.odinredpowermod.circle.red":
				return localRuntimeSettings.CircleRed;
			case "oftech.odinredpowermod.circle.green":
				return localRuntimeSettings.CircleGreen;
			case "oftech.odinredpowermod.circle.blue":
				return localRuntimeSettings.CircleBlue;
			}
		}
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			return fallback;
		}
		ZDO zDO = component.GetZDO();
		if (zDO != null)
		{
			return zDO.GetFloat(key, fallback);
		}
		return fallback;
	}

	internal static bool GetPlayerBool(Player player, string key, bool fallback)
	{
		if ((Object)(object)player == (Object)null)
		{
			return fallback;
		}
		if ((Object)(object)Instance != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer && Instance._localRuntimeSettings != null)
		{
			if (key == "oftech.odinredpowermod.active")
			{
				return Instance._localRuntimePowerActive;
			}
			if (key == "oftech.odinredpowermod.circle.enabled")
			{
				return Instance._localRuntimeSettings.GroundCircleEnabled;
			}
		}
		ZNetView component = ((Component)player).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			return fallback;
		}
		ZDO zDO = component.GetZDO();
		if (zDO != null)
		{
			return zDO.GetBool(key, fallback);
		}
		return fallback;
	}

	internal static void LogWarning(string message)
	{
		if ((Object)(object)Instance != (Object)null)
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)message);
		}
	}

	internal static void UpdatePlayer(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		RedAuraVisual redAuraVisual = ((Component)player).GetComponent<RedAuraVisual>();
		if ((Object)(object)redAuraVisual == (Object)null)
		{
			if (!IsPowerActive(player))
			{
				return;
			}
			redAuraVisual = ((Component)player).gameObject.AddComponent<RedAuraVisual>();
		}
		redAuraVisual.RefreshFromPlayerData(player);
	}

	private static void SetIfDifferent(ZDO zdo, string key, bool value)
	{
		if (zdo.GetBool(key, !value) != value)
		{
			zdo.Set(key, value);
		}
	}

	private static void SetIfDifferent(ZDO zdo, string key, float value)
	{
		float num = zdo.GetFloat(key, float.NaN);
		if (float.IsNaN(num) || Mathf.Abs(num - value) > 0.0001f)
		{
			zdo.Set(key, value);
		}
	}

	private void InitializeWindow()
	{
		CenterWindow();
		EnsureLanguageChangeSubscription();
	}

	private void RefreshUiLanguage()
	{
		string text = null;
		try
		{
			text = PlayerPrefs.GetString("language", string.Empty);
			if (Localization.instance != null)
			{
				string selectedLanguage = Localization.instance.GetSelectedLanguage();
				if (!string.IsNullOrWhiteSpace(selectedLanguage))
				{
					text = selectedLanguage;
				}
			}
		}
		catch
		{
		}
		if (string.IsNullOrWhiteSpace(text))
		{
			text = "English";
		}
		text = text.Trim();
		UiLanguage uiLanguage = DetectUiLanguage(text);
		if (!string.Equals(text, _detectedGameLanguage, StringComparison.OrdinalIgnoreCase) || uiLanguage != _uiLanguage)
		{
			_detectedGameLanguage = text;
			_uiLanguage = uiLanguage;
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)("OdinRedPower interface language follows Valheim setting: " + text + "."));
			}
		}
	}

	private static UiLanguage DetectUiLanguage(string gameLanguage)
	{
		string text = (gameLanguage ?? string.Empty).Trim();
		if (text.Equals("tr", StringComparison.OrdinalIgnoreCase) || text.StartsWith("tr-", StringComparison.OrdinalIgnoreCase) || text.IndexOf("Turkish", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Türk", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			return UiLanguage.Turkish;
		}
		if (text.Equals("es", StringComparison.OrdinalIgnoreCase) || text.StartsWith("es-", StringComparison.OrdinalIgnoreCase) || text.IndexOf("Spanish", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Español", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			return UiLanguage.Spanish;
		}
		return UiLanguage.English;
	}

	private void EnsureLanguageChangeSubscription()
	{
		if (!_languageChangeSubscribed && Localization.instance != null)
		{
			Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnGameLanguageChanged));
			_languageChangeSubscribed = true;
			RefreshUiLanguage();
		}
	}

	private void OnGameLanguageChanged()
	{
		_detectedGameLanguage = null;
		RefreshUiLanguage();
	}

	private void StopListeningForLanguageChanges()
	{
		if (_languageChangeSubscribed)
		{
			Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(OnGameLanguageChanged));
			_languageChangeSubscribed = false;
		}
	}

	private string T(string key)
	{
		if (!UiStrings.TryGetValue(key, out var value) || value == null || value.Length <= (int)_uiLanguage)
		{
			return key;
		}
		return value[(int)_uiLanguage];
	}

	private void SetMenuOpen(bool open)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		if (_menuOpen == open || (open && !CanOpenMenu))
		{
			return;
		}
		if (open)
		{
			RefreshUiLanguage();
			_cursorWasVisible = Cursor.visible;
			_cursorWasRequested = ZCursor.IsRequested;
			_cursorLockWas = Cursor.lockState;
			_pausedByMod = false;
			_menuOpen = true;
			CenterWindow();
			RefreshOnlinePlayers(force: true);
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.IsSinglePlayer && (Object)(object)Game.instance != (Object)null && !Game.IsPaused())
			{
				try
				{
					Game.Pause();
					_pausedByMod = true;
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Oyun duraklatılamadı; ayar penceresi açık kalacak: " + ex.GetBaseException().Message));
				}
			}
			ForceCursorFree();
			((MonoBehaviour)this).StartCoroutine(ReleaseCursorAfterOpen());
			return;
		}
		_menuOpen = false;
		if (_pausedByMod && (Object)(object)Game.instance != (Object)null && Game.IsPaused())
		{
			try
			{
				Game.Unpause();
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Oyun devam ettirilemedi: " + ex2.GetBaseException().Message));
			}
		}
		_pausedByMod = false;
		if (_cursorWasRequested)
		{
			ZCursor.Show();
		}
		else
		{
			ZCursor.Hide();
		}
		ZCursor.LockState = _cursorLockWas;
		Cursor.lockState = _cursorLockWas;
		Cursor.visible = _cursorWasVisible;
		((BaseUnityPlugin)this).Config.Save();
	}

	private IEnumerator ReleaseCursorAfterOpen()
	{
		yield return null;
		if (_menuOpen)
		{
			ForceCursorFree();
			yield return (object)new WaitForEndOfFrame();
			if (_menuOpen)
			{
				ForceCursorFree();
			}
		}
	}

	private void DrawPauseMenuButton()
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if (!CanOpenMenu || (Object)(object)Menu.instance == (Object)null)
		{
			SetPauseMenuUiButtonVisible(visible: false);
			return;
		}
		if (!Menu.IsVisible())
		{
			SetPauseMenuUiButtonVisible(visible: false);
			return;
		}
		EnsureLanguageChangeSubscription();
		RefreshUiLanguage();
		EnsureStyles();
		if (EnsurePauseMenuUiButton(Menu.instance))
		{
			SetPauseMenuUiButtonVisible(visible: true);
			return;
		}
		int depth = GUI.depth;
		Color color = GUI.color;
		GUI.depth = -50;
		GUI.color = Color.white;
		if (GUI.Button(GetPauseMenuButtonRect(), T("pause_button"), _pauseMenuButtonStyle))
		{
			SetMenuOpen(open: true);
		}
		GUI.color = color;
		GUI.depth = depth;
	}

	private bool EnsurePauseMenuUiButton(Menu menu)
	{
		if ((Object)(object)menu == (Object)null || (Object)(object)menu.m_root == (Object)null)
		{
			return false;
		}
		if ((Object)(object)_pauseMenuUiButton != (Object)null && (Object)(object)_pauseMenuUiButtonParent != (Object)(object)menu.m_root)
		{
			Object.Destroy((Object)(object)_pauseMenuUiButton);
			_pauseMenuUiButton = null;
			_pauseMenuUiButtonParent = null;
		}
		if ((Object)(object)_pauseMenuUiButton == (Object)null)
		{
			if (Time.unscaledTime < _nextPauseMenuUiButtonAttempt)
			{
				return false;
			}
			_nextPauseMenuUiButtonAttempt = Time.unscaledTime + 2f;
			GameObject val = TryCreateValheimStyleButton(menu.m_root);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			_pauseMenuUiButton = val;
			_pauseMenuUiButtonParent = menu.m_root;
			_nextPauseMenuLayoutCheck = 0f;
		}
		UpdatePauseMenuUiButtonLabel();
		if (Time.unscaledTime >= _nextPauseMenuLayoutCheck)
		{
			PositionPauseMenuUiButton();
			_nextPauseMenuLayoutCheck = Time.unscaledTime + 0.5f;
		}
		return true;
	}

	private GameObject TryCreateValheimStyleButton(Transform parent)
	{
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				if (!(type == null))
				{
					break;
				}
				type = assemblies[i].GetType("Jotunn.Managers.GUIManager", throwOnError: false);
			}
			if (type == null)
			{
				return null;
			}
			PropertyInfo property = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
			MethodInfo method = type.GetMethod("CreateButton", BindingFlags.Instance | BindingFlags.Public, null, new Type[7]
			{
				typeof(string),
				typeof(Transform),
				typeof(Vector2),
				typeof(Vector2),
				typeof(Vector2),
				typeof(float),
				typeof(float)
			}, null);
			if (property == null || method == null)
			{
				return null;
			}
			object value = property.GetValue(null, null);
			if (value == null)
			{
				return null;
			}
			object? obj = method.Invoke(value, new object[7]
			{
				T("pause_button"),
				parent,
				(object)new Vector2(1f, 0f),
				(object)new Vector2(1f, 0f),
				(object)new Vector2(-20f, 20f),
				150f,
				38f
			});
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			((Object)val).name = "OdinRedPowerPauseMenuButton";
			if (!AttachPauseMenuButtonClickHandler(val))
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			return val;
		}
		catch (Exception ex)
		{
			if (!_pauseMenuUiButtonFailureLogged)
			{
				_pauseMenuUiButtonFailureLogged = true;
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Jötunn button styling is unavailable; using the built-in OdinRedPower button style. " + ex.GetBaseException().Message));
			}
			return null;
		}
	}

	private bool AttachPauseMenuButtonClickHandler(GameObject button)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		Type type = null;
		for (int i = 0; i < assemblies.Length; i++)
		{
			if (!(type == null))
			{
				break;
			}
			type = assemblies[i].GetType("UnityEngine.UI.Button", throwOnError: false);
		}
		if (type == null)
		{
			return false;
		}
		Component component = button.GetComponent(type);
		PropertyInfo property = type.GetProperty("onClick", BindingFlags.Instance | BindingFlags.Public);
		object obj = (((Object)(object)component != (Object)null && property != null) ? property.GetValue(component, null) : null);
		if (obj == null)
		{
			return false;
		}
		Type type2 = null;
		for (int j = 0; j < assemblies.Length; j++)
		{
			if (!(type2 == null))
			{
				break;
			}
			type2 = assemblies[j].GetType("UnityEngine.Events.UnityAction", throwOnError: false);
		}
		MethodInfo methodInfo = ((type2 != null) ? obj.GetType().GetMethod("AddListener", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { type2 }, null) : null);
		MethodInfo method = ((object)this).GetType().GetMethod("OnPauseMenuUiButtonClicked", BindingFlags.Instance | BindingFlags.NonPublic);
		if (methodInfo == null || method == null)
		{
			return false;
		}
		Delegate obj2 = Delegate.CreateDelegate(type2, this, method);
		methodInfo.Invoke(obj, new object[1] { obj2 });
		return true;
	}

	private void OnPauseMenuUiButtonClicked()
	{
		if (CanOpenMenu)
		{
			SetMenuOpen(open: true);
		}
	}

	private void UpdatePauseMenuUiButtonLabel()
	{
		if ((Object)(object)_pauseMenuUiButton == (Object)null)
		{
			return;
		}
		Component[] componentsInChildren = _pauseMenuUiButton.GetComponentsInChildren<Component>(true);
		foreach (Component val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && !(((object)val).GetType().Name != "Text") && !(((object)val).GetType().Namespace != "UnityEngine.UI"))
			{
				PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
				if (property != null && property.CanWrite)
				{
					property.SetValue(val, T("pause_button"), null);
				}
			}
		}
	}

	private void PositionPauseMenuUiButton()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_pauseMenuUiButton == (Object)null)
		{
			return;
		}
		Transform transform = _pauseMenuUiButton.transform;
		RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		val.anchorMin = new Vector2(1f, 0f);
		val.anchorMax = new Vector2(1f, 0f);
		val.pivot = new Vector2(1f, 0f);
		val.SetSizeWithCurrentAnchors((Axis)0, 150f);
		val.SetSizeWithCurrentAnchors((Axis)1, 38f);
		float num = (HasPotentialConfigButtonPlugin() ? 66f : 20f);
		MonoBehaviour[] array = Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0);
		foreach (MonoBehaviour val2 in array)
		{
			if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)(object)_pauseMenuUiButton || ((object)val2).GetType().Name != "Button" || ((object)val2).GetType().Namespace != "UnityEngine.UI")
			{
				continue;
			}
			Transform transform2 = ((Component)val2).transform;
			RectTransform val3 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
			if (!((Object)(object)val3 == (Object)null))
			{
				Vector2 val4 = RectTransformUtility.WorldToScreenPoint((Camera)null, ((Transform)val3).position);
				float x = val4.x;
				float num2 = (float)Screen.height - val4.y;
				Rect rect = val3.rect;
				float num3 = Mathf.Abs(((Rect)(ref rect)).height * ((Transform)val3).lossyScale.y);
				if (!(x < (float)Screen.width * 0.65f) && !(num2 < (float)Screen.height - 220f) && !(num2 > (float)Screen.height + 12f))
				{
					float num4 = Mathf.Max(0.01f, ((Transform)val).lossyScale.y);
					float num5 = ((float)Screen.height - num2 + num3 * 0.5f + 8f) / num4;
					num = Mathf.Max(num, num5);
				}
			}
		}
		val.anchoredPosition = new Vector2(-20f, num);
	}

	private void SetPauseMenuUiButtonVisible(bool visible)
	{
		if ((Object)(object)_pauseMenuUiButton != (Object)null && _pauseMenuUiButton.activeSelf != visible)
		{
			_pauseMenuUiButton.SetActive(visible);
		}
	}

	private Rect GetPauseMenuButtonRect()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if (Time.unscaledTime >= _nextPauseMenuLayoutCheck || ((Rect)(ref _pauseMenuButtonRect)).width <= 0f)
		{
			_pauseMenuButtonRect = CalculatePauseMenuButtonRect();
			_nextPauseMenuLayoutCheck = Time.unscaledTime + 0.5f;
		}
		return _pauseMenuButtonRect;
	}

	private Rect CalculatePauseMenuButtonRect()
	{
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Min(150f, Mathf.Max(120f, (float)Screen.width - 36f));
		float num2 = (float)Screen.width - num - 20f;
		float num3 = (float)Screen.height - 38f - 20f;
		float num4 = float.MaxValue;
		if (HasPotentialConfigButtonPlugin())
		{
			num4 = (float)Screen.height - 20f - 38f;
		}
		MonoBehaviour[] array = Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0);
		foreach (MonoBehaviour val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Type type = ((object)val).GetType();
			if (type.Name != "Button" || type.Namespace != "UnityEngine.UI")
			{
				continue;
			}
			Transform transform = ((Component)val).transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint((Camera)null, ((Transform)val2).position);
				float x = val3.x;
				float num5 = (float)Screen.height - val3.y;
				Rect rect = val2.rect;
				float num6 = Mathf.Abs(((Rect)(ref rect)).height * ((Transform)val2).lossyScale.y);
				if (!(x < (float)Screen.width * 0.65f) && !(num5 < (float)Screen.height - 220f) && !(num5 > (float)Screen.height + 12f))
				{
					num4 = Mathf.Min(num4, num5 - num6 * 0.5f);
				}
			}
		}
		if (num4 < float.MaxValue)
		{
			num3 = num4 - 38f - 8f;
			if (num3 < 20f)
			{
				num2 = (float)Screen.width - num * 2f - 20f - 8f;
				num3 = (float)Screen.height - 38f - 20f;
			}
		}
		num2 = Mathf.Clamp(num2, 20f, Mathf.Max(20f, (float)Screen.width - num - 20f));
		num3 = Mathf.Clamp(num3, 20f, Mathf.Max(20f, (float)Screen.height - 38f - 20f));
		return new Rect(num2, num3, num, 38f);
	}

	private static bool HasPotentialConfigButtonPlugin()
	{
		try
		{
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				if (value != null && value.Metadata != null)
				{
					string text = (value.Metadata.Name ?? string.Empty) + " " + (value.Metadata.GUID ?? string.Empty);
					if (text.IndexOf("config", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("jotunn", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static void ForceCursorFree()
	{
		ZCursor.Show();
		ZCursor.LockState = (CursorLockMode)0;
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
	}

	private void CenterWindow()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Min(860f, Mathf.Max(360f, (float)Screen.width - 40f));
		float num2 = Mathf.Min(720f, Mathf.Max(420f, (float)Screen.height - 40f));
		_windowRect = new Rect(((float)Screen.width - num) * 0.5f, ((float)Screen.height - num2) * 0.5f, num, num2);
	}

	private void DrawSettingsWindow()
	{
		//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_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		if (_menuOpen)
		{
			RefreshUiLanguage();
			if (!IsMultiplayerSession && _activeTab > 1)
			{
				_activeTab = 0;
			}
			ForceCursorFree();
			EnsureStyles();
			int depth = GUI.depth;
			GUI.depth = -100;
			Color color = GUI.color;
			GUI.color = Color.white;
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_shadeTexture);
			_windowRect = ClampWindowToScreen(_windowRect);
			_windowRect = GUI.Window(184326, _windowRect, new WindowFunction(DrawWindow), GUIContent.none, _windowStyle);
			GUI.color = color;
			GUI.depth = depth;
			if (_menuOpen)
			{
				ForceCursorFree();
			}
		}
	}

	private Rect ClampWindowToScreen(Rect rect)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Max(0f, (float)Screen.width - ((Rect)(ref rect)).width);
		float num2 = Mathf.Max(0f, (float)Screen.height - ((Rect)(ref rect)).height);
		((Rect)(ref rect)).x = Mathf.Clamp(((Rect)(ref rect)).x, 0f, num);
		((Rect)(ref rect)).y = Mathf.Clamp(((Rect)(ref rect)).y, 0f, num2);
		return rect;
	}

	private void DrawWindow(int windowId)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		DrawHeader();
		DrawTabs();
		float num = Mathf.Max(180f, ((Rect)(ref _windowRect)).height - 244f);
		_contentScroll = GUILayout.BeginScrollView(_contentScroll, false, true, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num) });
		if (_activeTab == 0)
		{
			DrawPowerTab();
		}
		else if (_activeTab == 1)
		{
			DrawVisualTab();
		}
		else
		{
			DrawPlayersTab();
		}
		GUILayout.EndScrollView();
		DrawFooter();
		GUILayout.EndVertical();
		GUI.DragWindow(new Rect(0f, 0f, Mathf.Max(0f, ((Rect)(ref _windowRect)).width - 76f), 56f));
	}

	private void DrawHeader()
	{
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Expected O, but got Unknown
		GUILayout.BeginHorizontal(_headerStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(84f) });
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		GUILayout.Label("ODIN  /  RED POWER", _titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) });
		GUILayout.Label(IsMultiplayerSession ? T("subtitle_host") : T("subtitle_single"), _subtitleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(20f) });
		GUILayout.EndVertical();
		GUILayout.FlexibleSpace();
		_statusStyle.normal.textColor = (PowerEnabled.Value ? new Color(0.53f, 0.84f, 0.63f, 1f) : new Color(0.78f, 0.57f, 0.5f, 1f));
		GUILayout.Label(PowerEnabled.Value ? T("enabled") : T("disabled"), _statusStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(140f),
			GUILayout.Height(30f)
		});
		if (GUILayout.Button(new GUIContent("×", T("close")), _closeButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(38f),
			GUILayout.Height(36f)
		}))
		{
			SetMenuOpen(open: false);
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
	}

	private void DrawTabs()
	{
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		DrawTabButton(0, T("tab_power"));
		DrawTabButton(1, T("tab_appearance"));
		if (IsMultiplayerSession)
		{
			DrawTabButton(2, T("tab_players"));
		}
		GUILayout.FlexibleSpace();
		GUILayout.EndHorizontal();
		GUILayout.Space(8f);
		GUILayout.Box(GUIContent.none, _accentStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.ExpandWidth(true),
			GUILayout.Height(2f)
		});
		GUILayout.Space(8f);
	}

	private void DrawTabButton(int tab, string title)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		GUIStyle val = ((_activeTab == tab) ? _activeTabStyle : _tabStyle);
		if (GUILayout.Button(title, val, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.MinWidth(132f),
			GUILayout.Height(40f)
		}))
		{
			_activeTab = tab;
			_contentScroll = Vector2.zero;
		}
	}

	private void DrawPowerTab()
	{
		BeginCard();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("power_section"), _sectionStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label(IsMultiplayerSession ? T("sync_desc") : T("solo_desc"), _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.EndVertical();
		GUILayout.FlexibleSpace();
		if (GUILayout.Button(PowerEnabled.Value ? T("disable_power") : T("enable_power"), PowerEnabled.Value ? _denyButtonStyle : _primaryButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(192f),
			GUILayout.Height(42f)
		}))
		{
			PowerEnabled.Value = !PowerEnabled.Value;
		}
		GUILayout.EndHorizontal();
		EndCard();
		GUILayout.Space(10f);
		BeginCard();
		GUILayout.Label(T("combat"), _sectionStyle, Array.Empty<GUILayoutOption>());
		DrawSlider(T("attack_damage"), DamageMultiplier, 1f, 3f, 0.05f, "× {0:0.00}");
		DrawSlider(T("carry"), CarryMultiplier, 1f, 4f, 0.1f, "× {0:0.0}");
		DrawSlider(T("run"), RunMultiplier, 1f, 1.5f, 0.05f, "× {0:0.00}");
		DrawSlider(T("jump"), JumpMultiplier, 1f, 2f, 0.05f, "× {0:0.00}");
		EndCard();
		GUILayout.Space(10f);
		BeginCard();
		GUILayout.Label(T("vitality"), _sectionStyle, Array.Empty<GUILayoutOption>());
		DrawSlider(T("health_bonus"), HealthBonus, 0f, 300f, 10f, "+{0:0}");
		DrawSlider(T("stamina_bonus"), StaminaBonus, 0f, 400f, 10f, "+{0:0}");
		DrawSlider(T("health_regen"), HealthRegenMultiplier, 1f, 3f, 0.05f, "× {0:0.00}");
		DrawSlider(T("damage_reduction"), DamageReduction, 0f, 0.75f, 0.01f, "{0:P0}");
		DrawSlider(T("stamina_reduction"), StaminaCostReduction, 0f, 0.75f, 0.01f, "{0:P0}");
		GUILayout.Label(T("food_refill"), _mutedStyle, Array.Empty<GUILayoutOption>());
		EndCard();
	}

	private void DrawVisualTab()
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		BeginCard();
		GUILayout.Label(T("appearance"), _sectionStyle, Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(_rowStyle, Array.Empty<GUILayoutOption>());
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("ground_circle"), _labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("circle_desc"), _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.EndVertical();
		GUILayout.FlexibleSpace();
		if (GUILayout.Button(GroundCircleEnabled.Value ? T("on") : T("off"), GroundCircleEnabled.Value ? _primaryButtonStyle : _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(104f),
			GUILayout.Height(32f)
		}))
		{
			GroundCircleEnabled.Value = !GroundCircleEnabled.Value;
		}
		Color color = GUI.color;
		GUI.color = GetConfiguredCircleColor();
		GUILayout.Box(GUIContent.none, _colorPreviewStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(34f),
			GUILayout.Height(24f)
		});
		GUI.color = color;
		GUILayout.EndHorizontal();
		EndCard();
		GUILayout.Space(10f);
		BeginCard();
		GUILayout.Label(T("circle_color"), _sectionStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("rgb_desc"), _mutedStyle, Array.Empty<GUILayoutOption>());
		DrawSlider(T("red"), CircleRed, 0f, 1f, 0.01f, "{0:0.00}");
		DrawSlider(T("green"), CircleGreen, 0f, 1f, 0.01f, "{0:0.00}");
		DrawSlider(T("blue"), CircleBlue, 0f, 1f, 0.01f, "{0:0.00}");
		EndCard();
	}

	private void DrawPlayersTab()
	{
		BeginCard();
		GUILayout.Label(T("permissions"), _sectionStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label(T("permission_desc"), _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(4f);
		if (_onlinePlayers.Count == 0)
		{
			GUILayout.Label(T("loading_players"), _labelStyle, Array.Empty<GUILayoutOption>());
		}
		else
		{
			for (int i = 0; i < _onlinePlayers.Count; i++)
			{
				DrawPlayerRow(_onlinePlayers[i]);
			}
		}
		EndCard();
	}

	private void DrawPlayerRow(OnlinePlayer player)
	{
		GUILayout.BeginHorizontal(_rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(52f) });
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		GUILayout.Label(player.Name, _labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label((player.IsHost ? T("host_role") : T("connected_role")) + " · ID " + player.Id.ToString("X"), _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.EndVertical();
		GUILayout.FlexibleSpace();
		bool flag = IsPlayerAllowed(player.Id);
		string obj = (flag ? T("allowed") : T("denied"));
		GUIStyle val = (flag ? _allowButtonStyle : _denyButtonStyle);
		if (GUILayout.Button(obj, val, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(156f),
			GUILayout.Height(34f)
		}))
		{
			SetPlayerAllowed(player.Id, !flag);
		}
		GUILayout.EndHorizontal();
	}

	private void DrawFooter()
	{
		GUILayout.Space(6f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(IsMultiplayerSession ? T("footer_host") : T("footer_toggle"), _subtitleStyle, Array.Empty<GUILayoutOption>());
		GUILayout.FlexibleSpace();
		if (GUILayout.Button(T("reset"), _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(156f),
			GUILayout.Height(34f)
		}))
		{
			ResetSettings();
		}
		GUILayout.EndHorizontal();
	}

	private void DrawSlider(string label, ConfigEntry<float> entry, float minimum, float maximum, float step, string valueFormat)
	{
		GUILayout.BeginVertical(_rowStyle, Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(label, _labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.FlexibleSpace();
		GUILayout.Label(string.Format(UiCultures[(int)_uiLanguage], valueFormat, entry.Value), _valueStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
		GUILayout.EndHorizontal();
		float num = GUILayout.HorizontalSlider(entry.Value, minimum, maximum, _sliderStyle, _sliderThumbStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.ExpandWidth(true),
			GUILayout.Height(18f)
		});
		num = Mathf.Clamp(Mathf.Round(num / step) * step, minimum, maximum);
		if (Mathf.Abs(num - entry.Value) > step * 0.2f)
		{
			entry.Value = num;
		}
		GUILayout.EndVertical();
	}

	private Color GetConfiguredCircleColor()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		return new Color(CircleRed.Value, CircleGreen.Value, CircleBlue.Value, 1f);
	}

	private void ResetSettings()
	{
		PowerEnabled.Value = false;
		DamageMultiplier.Value = 1.25f;
		CarryMultiplier.Value = 1.5f;
		HealthBonus.Value = 100f;
		StaminaBonus.Value = 200f;
		HealthRegenMultiplier.Value = 1.5f;
		DamageReduction.Value = 0.2f;
		StaminaCostReduction.Value = 0.2f;
		RunMultiplier.Value = 1.2f;
		JumpMultiplier.Value = 1.5f;
		GroundCircleEnabled.Value = true;
		CircleRed.Value = 0.86f;
		CircleGreen.Value = 0.055f;
		CircleBlue.Value = 0.045f;
	}

	private void BeginCard()
	{
		GUILayout.BeginVertical(_cardStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(2f);
	}

	private void EndCard()
	{
		GUILayout.Space(2f);
		GUILayout.EndVertical();
	}

	private void EnsureStyles()
	{
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Expected O, but got Unknown
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Expected O, but got Unknown
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Expected O, but got Unknown
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Expected O, but got Unknown
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Expected O, but got Unknown
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Expected O, but got Unknown
		//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0302: Expected O, but got Unknown
		//IL_0322: Unknown result type (might be due to invalid IL or missing references)
		//IL_032c: Expected O, but got Unknown
		//IL_0336: Unknown result type (might be due to invalid IL or missing references)
		//IL_0340: Expected O, but got Unknown
		//IL_034b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0355: Expected O, but got Unknown
		//IL_0373: Unknown result type (might be due to invalid IL or missing references)
		//IL_037d: Expected O, but got Unknown
		//IL_0387: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Expected O, but got Unknown
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Expected O, but got Unknown
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Expected O, but got Unknown
		//IL_0421: Unknown result type (might be due to invalid IL or missing references)
		//IL_043f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0449: Expected O, but got Unknown
		//IL_0481: Unknown result type (might be due to invalid IL or missing references)
		//IL_0496: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a0: Expected O, but got Unknown
		//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e0: Expected O, but got Unknown
		//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0516: Unknown result type (might be due to invalid IL or missing references)
		//IL_0520: Expected O, but got Unknown
		//IL_0558: Unknown result type (might be due to invalid IL or missing references)
		//IL_0575: Unknown result type (might be due to invalid IL or missing references)
		//IL_057f: Expected O, but got Unknown
		//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_060e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0623: Unknown result type (might be due to invalid IL or missing references)
		//IL_0635: Unknown result type (might be due to invalid IL or missing references)
		//IL_064a: Unknown result type (might be due to invalid IL or missing references)
		//IL_065f: Unknown result type (might be due to invalid IL or missing references)
		//IL_069a: Unknown result type (might be due to invalid IL or missing references)
		//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e6: Expected O, but got Unknown
		//IL_06f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06fa: Expected O, but got Unknown
		//IL_0719: Unknown result type (might be due to invalid IL or missing references)
		//IL_0742: Unknown result type (might be due to invalid IL or missing references)
		//IL_076b: Unknown result type (might be due to invalid IL or missing references)
		//IL_077b: Unknown result type (might be due to invalid IL or missing references)
		//IL_079e: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a8: Expected O, but got Unknown
		//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_07bd: Expected O, but got Unknown
		//IL_07ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f4: Expected O, but got Unknown
		//IL_0855: Unknown result type (might be due to invalid IL or missing references)
		//IL_085f: Expected O, but got Unknown
		//IL_087b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0885: Expected O, but got Unknown
		//IL_088f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0899: Expected O, but got Unknown
		//IL_08a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ae: Expected O, but got Unknown
		//IL_08ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d4: Expected O, but got Unknown
		//IL_08de: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e8: Expected O, but got Unknown
		//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_08fc: Expected O, but got Unknown
		//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
		if (_windowStyle == null)
		{
			Color center = default(Color);
			((Color)(ref center))..ctor(0.035f, 0.03f, 0.023f, 0.99f);
			Color color = default(Color);
			((Color)(ref color))..ctor(0.105f, 0.083f, 0.051f, 1f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.073f, 0.061f, 0.043f, 1f);
			Color color3 = default(Color);
			((Color)(ref color3))..ctor(0.112f, 0.094f, 0.066f, 1f);
			Color val = default(Color);
			((Color)(ref val))..ctor(0.84f, 0.66f, 0.34f, 1f);
			Color color4 = default(Color);
			((Color)(ref color4))..ctor(0.47f, 0.12f, 0.085f, 1f);
			Color color5 = default(Color);
			((Color)(ref color5))..ctor(0.62f, 0.17f, 0.11f, 1f);
			Color color6 = default(Color);
			((Color)(ref color6))..ctor(0.19f, 0.36f, 0.24f, 1f);
			Color color7 = default(Color);
			((Color)(ref color7))..ctor(0.25f, 0.47f, 0.3f, 1f);
			Color color8 = default(Color);
			((Color)(ref color8))..ctor(0.16f, 0.13f, 0.09f, 1f);
			Color color9 = default(Color);
			((Color)(ref color9))..ctor(0.24f, 0.19f, 0.12f, 1f);
			Color color10 = default(Color);
			((Color)(ref color10))..ctor(0.14f, 0.115f, 0.075f, 1f);
			Color textColor = default(Color);
			((Color)(ref textColor))..ctor(0.94f, 0.9f, 0.8f, 1f);
			Color textColor2 = default(Color);
			((Color)(ref textColor2))..ctor(0.69f, 0.63f, 0.5f, 1f);
			Texture2D background = CreateFrameTexture(center, val);
			Texture2D background2 = CreateTexture(color);
			Texture2D background3 = CreateTexture(color2);
			Texture2D background4 = CreateTexture(color3);
			Texture2D val2 = CreateTexture(val);
			Texture2D normal = CreateTexture(color4);
			Texture2D hover = CreateTexture(color5);
			Texture2D normal2 = CreateTexture(color6);
			Texture2D hover2 = CreateTexture(color7);
			Texture2D normal3 = CreateTexture(color8);
			Texture2D hover3 = CreateTexture(color9);
			Texture2D background5 = CreateTexture(color10);
			Texture2D background6 = CreateTexture(Color.white);
			Texture2D hover4 = CreateTexture(color5);
			_shadeTexture = CreateTexture(new Color(0.005f, 0.012f, 0.025f, 0.72f));
			_windowStyle = new GUIStyle(GUI.skin.window);
			_windowStyle.normal.background = background;
			_windowStyle.onNormal.background = background;
			_windowStyle.border = new RectOffset(1, 1, 1, 1);
			_windowStyle.padding = new RectOffset(22, 22, 20, 18);
			_headerStyle = new GUIStyle(GUI.skin.box);
			_headerStyle.normal.background = background2;
			_headerStyle.padding = new RectOffset(16, 12, 10, 10);
			_headerStyle.margin = new RectOffset(0, 0, 0, 0);
			_cardStyle = new GUIStyle(GUI.skin.box);
			_cardStyle.normal.background = background3;
			_cardStyle.padding = new RectOffset(16, 16, 14, 14);
			_cardStyle.margin = new RectOffset(0, 0, 2, 3);
			_rowStyle = new GUIStyle(GUI.skin.box);
			_rowStyle.normal.background = background4;
			_rowStyle.padding = new RectOffset(10, 10, 7, 6);
			_rowStyle.margin = new RectOffset(0, 0, 4, 4);
			_titleStyle = new GUIStyle(GUI.skin.label);
			_titleStyle.fontSize = 24;
			_titleStyle.fontStyle = (FontStyle)1;
			_titleStyle.normal.textColor = new Color(0.95f, 0.82f, 0.56f, 1f);
			_titleStyle.alignment = (TextAnchor)3;
			_subtitleStyle = new GUIStyle(GUI.skin.label);
			_subtitleStyle.fontSize = 12;
			_subtitleStyle.normal.textColor = textColor2;
			_subtitleStyle.alignment = (TextAnchor)3;
			_sectionStyle = new GUIStyle(GUI.skin.label);
			_sectionStyle.fontSize = 14;
			_sectionStyle.fontStyle = (FontStyle)1;
			_sectionStyle.normal.textColor = new Color(0.87f, 0.69f, 0.37f, 1f);
			_labelStyle = new GUIStyle(GUI.skin.label);
			_labelStyle.fontSize = 14;
			_labelStyle.normal.textColor = textColor;
			_labelStyle.alignment = (TextAnchor)3;
			_mutedStyle = new GUIStyle(GUI.skin.label);
			_mutedStyle.fontSize = 12;
			_mutedStyle.normal.textColor = textColor2;
			_mutedStyle.wordWrap = true;
			_valueStyle = new GUIStyle(GUI.skin.label);
			_valueStyle.fontSize = 14;
			_valueStyle.fontStyle = (FontStyle)1;
			_valueStyle.normal.textColor = new Color(0.95f, 0.77f, 0.42f, 1f);
			_valueStyle.alignment = (TextAnchor)5;
			_statusStyle = new GUIStyle(_sectionStyle);
			_statusStyle.alignment = (TextAnchor)4;
			_statusStyle.normal.textColor = ((PowerEnabled != null && PowerEnabled.Value) ? new Color(0.53f, 0.84f, 0.63f, 1f) : new Color(0.78f, 0.57f, 0.5f, 1f));
			_tabStyle = MakeButtonStyle(normal3, hover3, textColor2);
			_activeTabStyle = MakeButtonStyle(val2, val2, new Color(0.07f, 0.08f, 0.09f, 1f));
			_buttonStyle = MakeButtonStyle(normal3, hover3, textColor);
			_primaryButtonStyle = MakeButtonStyle(normal2, hover2, Color.white);
			_denyButtonStyle = MakeButtonStyle(normal, hover, Color.white);
			_allowButtonStyle = MakeButtonStyle(normal2, hover2, Color.white);
			Texture2D normal4 = CreateValheimButtonTexture(hovered: false);
			Texture2D hover5 = CreateValheimButtonTexture(hovered: true);
			_pauseMenuButtonStyle = MakeButtonStyle(normal4, hover5, new Color(1f, 0.59f, 0.22f, 1f));
			_pauseMenuButtonStyle.font = FindValheimButtonFont();
			_pauseMenuButtonStyle.fontSize = 14;
			_pauseMenuButtonStyle.fontStyle = (FontStyle)1;
			_pauseMenuButtonStyle.border = new RectOffset(8, 8, 7, 7);
			_pauseMenuButtonStyle.padding = new RectOffset(6, 6, 2, 3);
			_pauseMenuButtonStyle.normal.textColor = new Color(1f, 0.59f, 0.22f, 1f);
			_pauseMenuButtonStyle.hover.textColor = new Color(1f, 0.72f, 0.34f, 1f);
			_pauseMenuButtonStyle.active.textColor = new Color(1f, 0.72f, 0.34f, 1f);
			_closeButtonStyle = MakeButtonStyle(normal3, hover4, textColor);
			_closeButtonStyle.fontSize = 20;
			_closeButtonStyle.padding = new RectOffset(0, 0, 0, 3);
			_sliderStyle = new GUIStyle(GUI.skin.horizontalSlider);
			_sliderStyle.normal.background = background5;
			_sliderStyle.fixedHeight = 7f;
			_sliderThumbStyle = new GUIStyle(GUI.skin.horizontalSliderThumb);
			_sliderThumbStyle.normal.background = val2;
			_sliderThumbStyle.hover.background = val2;
			_sliderThumbStyle.active.background = val2;
			_sliderThumbStyle.fixedWidth = 18f;
			_sliderThumbStyle.fixedHeight = 18f;
			_colorPreviewStyle = new GUIStyle(GUI.skin.box);
			_colorPreviewStyle.normal.background = background6;
			_colorPreviewStyle.border = new RectOffset(1, 1, 1, 1);
			_colorPreviewStyle.padding = new RectOffset(0, 0, 0, 0);
			_accentStyle = new GUIStyle(GUI.skin.box);
			_accentStyle.normal.background = val2;
			_accentStyle.border = new RectOffset(0, 0, 0, 0);
			_accentStyle.padding = new RectOffset(0, 0, 0, 0);
			_accentStyle.margin = new RectOffset(0, 0, 0, 0);
		}
	}

	private GUIStyle MakeButtonStyle(Texture2D normal, Texture2D hover, Color textColor)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_0085: Expected O, but got Unknown
		GUIStyle val = new GUIStyle(GUI.skin.button);
		val.normal.background = normal;
		val.hover.background = hover;
		val.active.background = hover;
		val.normal.textColor = textColor;
		val.hover.textColor = Color.white;
		val.active.textColor = Color.white;
		val.fontSize = 12;
		val.fontStyle = (FontStyle)1;
		val.alignment = (TextAnchor)4;
		val.border = new RectOffset(4, 4, 4, 4);
		return val;
	}

	private Texture2D CreateTexture(Color color)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
		((Object)val).hideFlags = (HideFlags)61;
		val.SetPixel(0, 0, color);
		val.Apply();
		_guiTextures.Add(val);
		return val;
	}

	private Texture2D CreateFrameTexture(Color center, Color border)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(3, 3, (TextureFormat)4, false);
		((Object)val).hideFlags = (HideFlags)61;
		((Texture)val).filterMode = (FilterMode)0;
		((Texture)val).wrapMode = (TextureWrapMode)1;
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				bool flag = i == 0 || i == 2 || j == 0 || j == 2;
				val.SetPixel(i, j, flag ? border : center);
			}
		}
		val.Apply();
		_guiTextures.Add(val);
		return val;
	}

	private Texture2D CreateValheimButtonTexture(bool hovered)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(9, 9, (TextureFormat)4, false);
		((Object)val).hideFlags = (HideFlags)61;
		((Texture)val).filterMode = (FilterMode)1;
		((Texture)val).wrapMode = (TextureWrapMode)1;
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(0.13f, 0.075f, 0.035f, 1f);
		Color val3 = (hovered ? new Color(0.94f, 0.47f, 0.1f, 1f) : new Color(0.66f, 0.31f, 0.075f, 1f));
		Color val4 = (hovered ? new Color(0.4f, 0.2f, 0.075f, 1f) : new Color(0.28f, 0.15f, 0.065f, 1f));
		Color val5 = (hovered ? new Color(0.105f, 0.075f, 0.052f, 1f) : new Color(0.045f, 0.036f, 0.029f, 1f));
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				bool num = i == 0 || i == 8 || j == 0 || j == 8;
				bool flag = i == 1 || i == 7 || j == 1 || j == 7;
				bool flag2 = i == 2 || i == 6 || j == 2 || j == 6;
				Color val6 = (num ? val2 : (flag ? val3 : (flag2 ? val4 : val5)));
				if ((i == 0 || i == 8) && (j == 0 || j == 8))
				{
					((Color)(ref val6))..ctor(0.045f, 0.03f, 0.02f, 1f);
				}
				val.SetPixel(i, j, val6);
			}
		}
		val.Apply();
		_guiTextures.Add(val);
		return val;
	}

	private static Font FindValheimButtonFont()
	{
		try
		{
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf("AveriaSerifLibre-Bold", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return val;
				}
			}
		}
		catch
		{
		}
		if (!((Object)(object)GUI.skin != (Object)null) || GUI.skin.button == null)
		{
			return null;
		}
		return GUI.skin.button.font;
	}

	private void DestroyGuiResources()
	{
		for (int i = 0; i < _guiTextures.Count; i++)
		{
			if ((Object)(object)_guiTextures[i] != (Object)null)
			{
				Object.Destroy((Object)(object)_guiTextures[i]);
			}
		}
		_guiTextures.Clear();
		_windowStyle = null;
		_headerStyle = null;
		_cardStyle = null;
		_rowStyle = null;
		_pauseMenuButtonStyle = null;
		_shadeTexture = null;
	}
}
[HarmonyPatch(typeof(Player), "Update")]
internal static class PlayerUpdatePatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance)
	{
		Plugin.UpdatePlayer(__instance);
	}
}
[HarmonyPatch(typeof(Player), "SetMaxHealth", new Type[]
{
	typeof(float),
	typeof(bool)
})]
internal static class MaxHealthFoodPatch
{
	[HarmonyPrefix]
	private static void Prefix(Player __instance, ref float health)
	{
		if (Plugin.IsPowerActive(__instance))
		{
			health += Plugin.GetPlayerValue(__instance, "oftech.odinredpowermod.health", 100f);
		}
	}
}
[HarmonyPatch(typeof(Player), "SetMaxStamina", new Type[]
{
	typeof(float),
	typeof(bool)
})]
internal static class MaxStaminaFoodPatch
{
	[HarmonyPrefix]
	private static void Prefix(Player __instance, ref float stamina)
	{
		if (Plugin.IsPowerActive(__instance))
		{
			stamina += Plugin.GetPlayerValue(__instance, "oftech.odinredpowermod.stamina", 200f);
		}
	}
}
[HarmonyPatch(typeof(Player), "GetMaxCarryWeight")]
internal static class CarryWeightPatch
{
	[HarmonyPostfix]
	private static void Postfix(Player __instance, ref float __result)