Decompiled source of ProsperityTweaks v1.0.1

BepInEx/plugins/ProsperityTweaks.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.NET.Common;
using Candide;
using Candide.GameModels.Helpers;
using CandideServer;
using CandideServer.Game;
using CandideServer.Helpers;
using CandideServer.Models;
using CandideServer.Models.Buildings;
using CandideServer.Models.Citizen;
using CandideServer.Server;
using CandideServer.ServerControllers;
using CandideServer.ServerManagers;
using CandideServer.ServerServices;
using CandideServer.ServerSystems;
using CandideServer.SimulationModels;
using CandideServer.SyncStrategies;
using HarmonyLib;
using Microsoft.Xna.Framework;
using ModSettingsMenu.Api;
using ProsperityTweaks.Configuration;
using ProsperityTweaks.Localizations;
using Shared.Models;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Prosperity Tweaks")]
[assembly: AssemblyDescription("Prosperity Tweaks for Romestead by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("Prosperity Tweaks")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("8e19e628-4eff-442f-9b7f-f4b975d0b306")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace ProsperityTweaks
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.Romestead.ProsperityTweaks";

		public const string PLUGIN_NAME = "Prosperity Tweaks";

		public const string PLUGIN_VERSION = "1.0.0";

		public const string PLUGIN_AUTHOR = "Ice Box Studio";

		public const string PLUGIN_AUTHOR_URL = "https://steamcommunity.com/id/ibox666/";
	}
	[BepInPlugin("IceBoxStudio.Romestead.ProsperityTweaks", "Prosperity Tweaks", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ProsperityTweaks : BasePlugin
	{
		public static ProsperityTweaks _Instance;

		private Harmony _harmony;

		public static ProsperityTweaks Instance => _Instance;

		internal static ManualLogSource Logger { get; private set; }

		public override void Load()
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			_Instance = this;
			Logger = ((BasePlugin)this).Log;
			bool flag = default(bool);
			try
			{
				Logger.LogInfo((object)"=============================================");
				ManualLogSource logger = Logger;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Prosperity Tweaks");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" initializing...");
				}
				logger.LogInfo(val);
				ManualLogSource logger2 = Logger;
				val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Author: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Ice Box Studio");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("https://steamcommunity.com/id/ibox666/");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
				}
				logger2.LogInfo(val);
				ConfigManager.Init(((BasePlugin)this).Config);
				ModSettingsMenuRegistration.Register(((BasePlugin)this).Config);
				_harmony = new Harmony("IceBoxStudio.Romestead.ProsperityTweaks");
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				ManualLogSource logger3 = Logger;
				val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Prosperity Tweaks");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" initialized.");
				}
				logger3.LogInfo(val);
				Logger.LogInfo((object)"=============================================");
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Prosperity Tweaks");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" initialization error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\n");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.StackTrace);
				}
				logger4.LogError(val2);
			}
		}
	}
}
namespace ProsperityTweaks.Patches
{
	internal static class AlwaysWetFarmland
	{
		private static readonly List<Point> ChangedTiles = new List<Point>();

		private static bool _wasEnabled;

		private static bool _needsCatchUp = true;

		private static int _lastCropCount = -1;

		public static bool Enabled => PatchHelper.ShouldApply && ConfigManager.KeepFarmlandWet;

		public static void Tick()
		{
			if (!Enabled)
			{
				_wasEnabled = false;
				_needsCatchUp = true;
				_lastCropCount = -1;
				return;
			}
			if (!CanUseWorldState())
			{
				_needsCatchUp = true;
				return;
			}
			int count = ServerGameState.Crops.Count;
			if (!_wasEnabled || _needsCatchUp || count != _lastCropCount)
			{
				WetAllCropTiles();
				_lastCropCount = ServerGameState.Crops.Count;
				_needsCatchUp = false;
			}
			_wasEnabled = true;
		}

		public static void MarkDirty()
		{
			_needsCatchUp = true;
		}

		public static void WetCropTile(CropServerModel crop, bool notify)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled || crop == null)
			{
				return;
			}
			if (!CanUseWorldState())
			{
				MarkDirty();
				return;
			}
			ChangedTiles.Clear();
			WetCropTile(crop, new FarmlandStatusModel(ServerGameState.Time), ChangedTiles);
			if (notify)
			{
				SendChangedTiles();
			}
			if (!_needsCatchUp)
			{
				_lastCropCount = ServerGameState.Crops.Count;
			}
		}

		private static void WetAllCropTiles()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			ChangedTiles.Clear();
			FarmlandStatusModel status = default(FarmlandStatusModel);
			((FarmlandStatusModel)(ref status))..ctor(ServerGameState.Time);
			foreach (CropServerModel value in ServerGameState.Crops.Values)
			{
				WetCropTile(value, status, ChangedTiles);
			}
			SendChangedTiles();
		}

		private static void WetCropTile(CropServerModel crop, FarmlandStatusModel status, List<Point> changedTiles)
		{
			//IL_0002: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetFarmTile(crop.TilePosition, out var ground))
			{
				bool flag = false;
				Point tilePosition = crop.TilePosition;
				if ((int)ground == 3)
				{
					WorldTilesServerController.SetTile(tilePosition, (GroundType?)(GroundType)4, (StructureType?)null);
					flag = true;
				}
				ServerGameState.WetFarmlands[tilePosition] = status;
				if (!crop.IsWatered)
				{
					CropServerController.WaterCrop(crop);
					flag = true;
				}
				if (flag)
				{
					changedTiles.Add(tilePosition);
				}
			}
		}

		private static bool TryGetFarmTile(Point point, out GroundType ground)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected I4, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			ground = (GroundType)0;
			WorldTile[,] worldTiles = ServerGameState.WorldTiles;
			if (worldTiles == null || point.X < 0 || point.Y < 0 || point.X >= worldTiles.GetLength(0) || point.Y >= worldTiles.GetLength(1))
			{
				return false;
			}
			ground = (GroundType)(int)worldTiles[point.X, point.Y].Ground;
			return (int)ground == 3 || (int)ground == 4;
		}

		private static void SendChangedTiles()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (ChangedTiles.Count > 0 && CanNotifyClients())
			{
				CropServerService.SendWaterCrops(Vector2.Zero, ChangedTiles);
			}
		}

		private static bool CanUseWorldState()
		{
			return ServerGameState.WorldTiles != null && ServerGameState.Crops != null && ServerGameState.WetFarmlands != null;
		}

		private static bool CanNotifyClients()
		{
			return ServerRunState.OutsideWorld != null;
		}
	}
	[HarmonyPatch(typeof(CropServerSystem), "UpdateWetFarmlandCheck", new Type[] { typeof(float) })]
	internal static class WetFarmlandDryPatch
	{
		private static bool Prefix()
		{
			return !AlwaysWetFarmland.Enabled;
		}
	}
	[HarmonyPatch(typeof(CropServerSystem), "Update", new Type[] { typeof(GameTime) })]
	internal static class AlwaysWetFarmlandUpdatePatch
	{
		private static void Postfix()
		{
			AlwaysWetFarmland.Tick();
		}
	}
	[HarmonyPatch(typeof(CropServerManager), "SpawnCrop", new Type[]
	{
		typeof(string),
		typeof(Point),
		typeof(bool),
		typeof(SyncStrategy)
	})]
	internal static class SpawnCropWaterSyncPatch
	{
		private static void Postfix(CropServerModel __result)
		{
			AlwaysWetFarmland.WetCropTile(__result, notify: true);
		}
	}
	[HarmonyPatch(typeof(CropServerController), "AfterWorldGameStateLoaded")]
	internal static class LoadedCropsWetFarmlandPatch
	{
		private static void Postfix()
		{
			AlwaysWetFarmland.MarkDirty();
		}
	}
	[HarmonyPatch(typeof(BuildingSimulationModel), "Update", new Type[] { typeof(float) })]
	internal static class BuildingTickPatch
	{
		private static void Prefix(ref float dt)
		{
			if (PatchHelper.ShouldApply)
			{
				dt *= ConfigManager.BuildingTick;
			}
		}
	}
	[HarmonyPatch(typeof(CropServerSystem), "Update", new Type[] { typeof(GameTime) })]
	internal static class CropServerSystemPatch
	{
		private static void Prefix(out ConfigScaleState __state)
		{
			float original;
			bool changed = PatchHelper.TryScaleConfig(ConfigManager.CropGrowth, ConfigField.CropGrowthSpeedMultiplier, out original);
			__state = new ConfigScaleState(changed, original);
		}

		private static void Postfix(ConfigScaleState __state)
		{
			PatchHelper.RestoreConfig(ConfigField.CropGrowthSpeedMultiplier, __state.Original, __state.Changed);
		}

		private static Exception Finalizer(Exception __exception, ConfigScaleState __state)
		{
			PatchHelper.RestoreConfig(ConfigField.CropGrowthSpeedMultiplier, __state.Original, __state.Changed);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(BuildingFurnaceHelper), "Tick", new Type[]
	{
		typeof(BuildingSimulationModel),
		typeof(SourceModel),
		typeof(bool)
	})]
	internal static class FuelPatch
	{
		private static void Prefix(out ConfigScaleState __state)
		{
			float original;
			bool changed = PatchHelper.TryScaleConfig(ConfigManager.FuelDrain, ConfigField.FuelDrainMultiplier, out original);
			__state = new ConfigScaleState(changed, original);
		}

		private static void Postfix(ConfigScaleState __state)
		{
			PatchHelper.RestoreConfig(ConfigField.FuelDrainMultiplier, __state.Original, __state.Changed);
		}

		private static Exception Finalizer(Exception __exception, ConfigScaleState __state)
		{
			PatchHelper.RestoreConfig(ConfigField.FuelDrainMultiplier, __state.Original, __state.Changed);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(JobHelper), "GetJobTickForCurrentJob", new Type[]
	{
		typeof(CitizenModel),
		typeof(float)
	})]
	internal static class JobHelperPatch
	{
		private static void Postfix(ref float __result)
		{
			if (PatchHelper.ShouldApply)
			{
				__result *= ConfigManager.JobProgress;
			}
		}
	}
	internal static class PatchHelper
	{
		public static bool ShouldApply => ConfigManager.Active && IsServerRunning;

		private static bool IsServerRunning
		{
			get
			{
				BaseServer instance = BaseServer.Instance;
				return instance.Running || instance.Updating || ServerGlobals.StandAlone;
			}
		}

		public static bool TryScaleConfig(float multiplier, ConfigField field, out float original)
		{
			original = 1f;
			if (!ShouldApply || multiplier == 1f || ServerGameState.Config == null)
			{
				return false;
			}
			GameConfig config = ServerGameState.Config;
			original = Get(config, field);
			Set(config, field, original * multiplier);
			return true;
		}

		public static void RestoreConfig(ConfigField field, float original, bool changed)
		{
			if (changed && ServerGameState.Config != null)
			{
				Set(ServerGameState.Config, field, original);
			}
		}

		private static float Get(GameConfig config, ConfigField field)
		{
			return field switch
			{
				ConfigField.CropGrowthSpeedMultiplier => config.CropGrowthSpeedMultiplier, 
				ConfigField.FuelDrainMultiplier => config.FuelDrainMultiplier, 
				_ => 1f, 
			};
		}

		private static void Set(GameConfig config, ConfigField field, float value)
		{
			switch (field)
			{
			case ConfigField.CropGrowthSpeedMultiplier:
				config.CropGrowthSpeedMultiplier = value;
				break;
			case ConfigField.FuelDrainMultiplier:
				config.FuelDrainMultiplier = value;
				break;
			}
		}
	}
	internal enum ConfigField
	{
		CropGrowthSpeedMultiplier,
		FuelDrainMultiplier
	}
	internal readonly struct ConfigScaleState
	{
		public bool Changed { get; }

		public float Original { get; }

		public ConfigScaleState(bool changed, float original)
		{
			Changed = changed;
			Original = original;
		}
	}
	[HarmonyPatch(typeof(TradeRoutesHelper), "Server_GetRouteTime", new Type[]
	{
		typeof(BuildingInstanceModel),
		typeof(BuildingInstanceModel),
		typeof(CitizenModel),
		typeof(GameConfig),
		typeof(float)
	})]
	internal static class TradeRoutesPatch
	{
		private static void Postfix(ref float __result)
		{
			if (PatchHelper.ShouldApply)
			{
				__result /= ConfigManager.TradeRouteSpeed;
			}
		}
	}
}
namespace ProsperityTweaks.Localizations
{
	internal static class LocalizationHelper
	{
		public static readonly string[] SupportedLanguages = new string[4] { "zh_CN", "zh_TW", "en", "ja_JP" };

		public static Dictionary<string, string> GetDefaultTranslations(string language)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			switch (language)
			{
			case "zh_CN":
				dictionary.Add("mod.name", "繁荣调整");
				dictionary.Add("mod.description", "调整农业、农田湿润、生产、燃料和贸易路线速度,让定居点发展更轻松。");
				dictionary.Add("section.general", "通用");
				dictionary.Add("section.production", "生产");
				dictionary.Add("section.resources", "资源");
				dictionary.Add("section.trade", "贸易");
				dictionary.Add("entry.enabled", "启用模组");
				dictionary.Add("entry.crop_growth", "作物成长倍率");
				dictionary.Add("entry.always_wet_farmland", "永湿农田");
				dictionary.Add("entry.building_tick", "建筑生产倍率");
				dictionary.Add("entry.job_progress", "工作进度倍率");
				dictionary.Add("entry.fuel_drain", "燃料消耗倍率");
				dictionary.Add("entry.trade_route_speed", "贸易路线速度倍率");
				dictionary.Add("config.enabled.description", "繁荣调整总开关。");
				dictionary.Add("config.crop_growth.description", "额外作用于作物成长速度的倍率。");
				dictionary.Add("config.always_wet_farmland.description", "作物所在的农田会自动保持湿润,并阻止湿农田自然变干。");
				dictionary.Add("config.building_tick.description", "额外作用于建筑生产速度的倍率。");
				dictionary.Add("config.job_progress.description", "额外作用于村民单次工作进度的倍率,会和建筑生产倍率叠加。");
				dictionary.Add("config.fuel_drain.description", "额外作用于炉子燃料消耗的倍率。数值越低,燃料越耐烧。");
				dictionary.Add("config.trade_route_speed.description", "额外作用于贸易路线速度的倍率。");
				break;
			case "zh_TW":
				dictionary.Add("mod.name", "繁榮調整");
				dictionary.Add("mod.description", "調整農業、農田濕潤、生產、燃料和貿易路線速度,讓聚落發展更輕鬆。");
				dictionary.Add("section.general", "通用");
				dictionary.Add("section.production", "生產");
				dictionary.Add("section.resources", "資源");
				dictionary.Add("section.trade", "貿易");
				dictionary.Add("entry.enabled", "啟用模組");
				dictionary.Add("entry.crop_growth", "作物成長倍率");
				dictionary.Add("entry.always_wet_farmland", "永濕農田");
				dictionary.Add("entry.building_tick", "建築生產倍率");
				dictionary.Add("entry.job_progress", "工作進度倍率");
				dictionary.Add("entry.fuel_drain", "燃料消耗倍率");
				dictionary.Add("entry.trade_route_speed", "貿易路線速度倍率");
				dictionary.Add("config.enabled.description", "繁榮調整總開關。");
				dictionary.Add("config.crop_growth.description", "額外作用於作物成長速度的倍率。");
				dictionary.Add("config.always_wet_farmland.description", "作物所在的農田會自動保持濕潤,並阻止濕農田自然變乾。");
				dictionary.Add("config.building_tick.description", "額外作用於建築生產速度的倍率。");
				dictionary.Add("config.job_progress.description", "額外作用於村民單次工作進度的倍率,會和建築生產倍率疊加。");
				dictionary.Add("config.fuel_drain.description", "額外作用於爐子燃料消耗的倍率。數值越低,燃料越耐燒。");
				dictionary.Add("config.trade_route_speed.description", "額外作用於貿易路線速度的倍率。");
				break;
			case "ja_JP":
				dictionary.Add("mod.name", "Prosperity Tweaks");
				dictionary.Add("mod.description", "農業、畑の湿り具合、生産、燃料、交易ルートの速度を調整し、集落の発展を楽にします。");
				dictionary.Add("section.general", "全般");
				dictionary.Add("section.production", "生産");
				dictionary.Add("section.resources", "資源");
				dictionary.Add("section.trade", "交易");
				dictionary.Add("entry.enabled", "MODを有効化");
				dictionary.Add("entry.crop_growth", "作物成長倍率");
				dictionary.Add("entry.always_wet_farmland", "畑を常に湿らせる");
				dictionary.Add("entry.building_tick", "建物生産倍率");
				dictionary.Add("entry.job_progress", "作業進行倍率");
				dictionary.Add("entry.fuel_drain", "燃料消費倍率");
				dictionary.Add("entry.trade_route_speed", "交易ルート速度倍率");
				dictionary.Add("config.enabled.description", "Prosperity Tweaks のマスタースイッチ。");
				dictionary.Add("config.crop_growth.description", "作物の成長速度に追加で適用される倍率。");
				dictionary.Add("config.always_wet_farmland.description", "作物が植えられている畑を自動的に湿らせ、湿った畑が自然に乾かないようにします。");
				dictionary.Add("config.building_tick.description", "建物の作業速度に追加で適用される倍率。");
				dictionary.Add("config.job_progress.description", "住民の 1 tick あたりの作業進行量に追加で適用される倍率。建物生産倍率と重なります。");
				dictionary.Add("config.fuel_drain.description", "炉の燃料消費に追加で適用される倍率。低いほど燃料が長持ちします。");
				dictionary.Add("config.trade_route_speed.description", "交易ルート速度に追加で適用される倍率。");
				break;
			case "en":
				dictionary.Add("mod.name", "Prosperity Tweaks");
				dictionary.Add("mod.description", "Tune farming, farmland wetness, production, fuel, and trade route speed to make settlement growth smoother.");
				dictionary.Add("section.general", "General");
				dictionary.Add("section.production", "Production");
				dictionary.Add("section.resources", "Resources");
				dictionary.Add("section.trade", "Trade");
				dictionary.Add("entry.enabled", "Enable Mod");
				dictionary.Add("entry.crop_growth", "Crop Growth Multiplier");
				dictionary.Add("entry.always_wet_farmland", "Always Wet Farmland");
				dictionary.Add("entry.building_tick", "Building Production Multiplier");
				dictionary.Add("entry.job_progress", "Job Progress Multiplier");
				dictionary.Add("entry.fuel_drain", "Fuel Drain Multiplier");
				dictionary.Add("entry.trade_route_speed", "Trade Route Speed Multiplier");
				dictionary.Add("config.enabled.description", "Master switch for Prosperity Tweaks.");
				dictionary.Add("config.crop_growth.description", "Extra multiplier applied to crop growth speed.");
				dictionary.Add("config.always_wet_farmland.description", "Automatically keeps farmland with crops wet and prevents wet farmland from drying naturally.");
				dictionary.Add("config.building_tick.description", "Extra multiplier applied to building work speed.");
				dictionary.Add("config.job_progress.description", "Extra multiplier applied to citizen work progress per tick. This stacks with Building Production Multiplier.");
				dictionary.Add("config.fuel_drain.description", "Extra multiplier applied to furnace fuel drain. Lower values make fuel last longer.");
				dictionary.Add("config.trade_route_speed.description", "Extra multiplier applied to trade route speed.");
				break;
			}
			return dictionary;
		}
	}
	internal sealed class LocalizationManager
	{
		private static LocalizationManager _instance;

		private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

		private string _currentLocale = "en";

		public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());

		public string CurrentLocale => _currentLocale;

		public event Action LanguageChanged;

		private LocalizationManager()
		{
			Initialize();
		}

		public void Initialize()
		{
			_localizations.Clear();
			string[] supportedLanguages = LocalizationHelper.SupportedLanguages;
			foreach (string text in supportedLanguages)
			{
				Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text);
				if (defaultTranslations.Count > 0)
				{
					_localizations[text] = defaultTranslations;
				}
			}
			RefreshLanguage(forceNotify: false);
		}

		public void RefreshLanguage(bool forceNotify = true)
		{
			string text = DetectLocale();
			if (!_localizations.ContainsKey(text))
			{
				text = "en";
			}
			bool flag = !string.Equals(_currentLocale, text, StringComparison.OrdinalIgnoreCase);
			_currentLocale = text;
			if (flag || forceNotify)
			{
				this.LanguageChanged?.Invoke();
			}
		}

		public string GetText(string key, params object[] args)
		{
			RefreshLanguage(forceNotify: false);
			string text = TryGetText(_currentLocale, key) ?? TryGetText("en", key) ?? TryGetText("zh_CN", key) ?? key;
			return (args != null && args.Length != 0) ? string.Format(text, args) : text;
		}

		private string TryGetText(string locale, string key)
		{
			Dictionary<string, string> value;
			string value2;
			return (_localizations.TryGetValue(locale, out value) && value.TryGetValue(key, out value2)) ? value2 : null;
		}

		private static string DetectLocale()
		{
			if (!string.IsNullOrWhiteSpace(Globals.LanguageCode))
			{
				return NormalizeLocale(Globals.LanguageCode);
			}
			string text = ReadSavedLocale();
			if (!string.IsNullOrWhiteSpace(text))
			{
				return NormalizeLocale(text);
			}
			return NormalizeLocale(CultureInfo.CurrentCulture.Name);
		}

		private static string ReadSavedLocale()
		{
			try
			{
				string path = Path.Combine(GamePathHelper.GetFolderPath((GameFolder)1, false), "localization.json");
				if (!File.Exists(path))
				{
					return null;
				}
				using FileStream utf8Json = File.OpenRead(path);
				using JsonDocument jsonDocument = JsonDocument.Parse((Stream)utf8Json, new JsonDocumentOptions
				{
					AllowTrailingCommas = true,
					CommentHandling = JsonCommentHandling.Skip
				});
				JsonElement value;
				return (jsonDocument.RootElement.TryGetProperty("LanguageCode", out value) && value.ValueKind == JsonValueKind.String) ? value.GetString() : null;
			}
			catch
			{
				return null;
			}
		}

		private static string NormalizeLocale(string languageCode)
		{
			switch ((languageCode ?? string.Empty).Replace('-', '_'))
			{
			case "zh_CN":
			case "zh_Hans":
				return "zh_CN";
			case "zh_TW":
			case "zh_HK":
			case "zh_MO":
			case "zh_Hant":
				return "zh_TW";
			case "ja_JP":
			case "ja":
				return "ja_JP";
			case "en":
			case "en_US":
			case "en_GB":
				return "en";
			default:
				return "en";
			}
		}
	}
}
namespace ProsperityTweaks.Configuration
{
	internal static class ConfigManager
	{
		public const string GeneralSection = "General";

		public const string ProductionSection = "Production";

		public const string ResourcesSection = "Resources";

		public const string TradeSection = "Trade";

		public static ConfigEntry<bool> Enabled { get; private set; }

		public static ConfigEntry<float> CropGrowthMultiplier { get; private set; }

		public static ConfigEntry<bool> AlwaysWetFarmland { get; private set; }

		public static ConfigEntry<float> BuildingTickMultiplier { get; private set; }

		public static ConfigEntry<float> JobProgressMultiplier { get; private set; }

		public static ConfigEntry<float> FuelDrainMultiplier { get; private set; }

		public static ConfigEntry<float> TradeRouteSpeedMultiplier { get; private set; }

		public static float CropGrowth => GetMultiplier(CropGrowthMultiplier);

		public static bool KeepFarmlandWet => AlwaysWetFarmland?.Value ?? false;

		public static float BuildingTick => GetMultiplier(BuildingTickMultiplier);

		public static float JobProgress => GetMultiplier(JobProgressMultiplier);

		public static float FuelDrain => GetMultiplier(FuelDrainMultiplier);

		public static float TradeRouteSpeed => GetMultiplier(TradeRouteSpeedMultiplier);

		public static bool Active => Enabled?.Value ?? false;

		public static void Init(ConfigFile config)
		{
			Enabled = config.Bind<bool>("General", "Enabled", true, Text("config.enabled.description"));
			CropGrowthMultiplier = config.Bind<float>("Production", "CropGrowthMultiplier", 1f, Range("config.crop_growth.description", 0.1f, 50f));
			AlwaysWetFarmland = config.Bind<bool>("Production", "AlwaysWetFarmland", false, Text("config.always_wet_farmland.description"));
			BuildingTickMultiplier = config.Bind<float>("Production", "BuildingTickMultiplier", 1f, Range("config.building_tick.description", 0.1f, 50f));
			JobProgressMultiplier = config.Bind<float>("Production", "JobProgressMultiplier", 1f, Range("config.job_progress.description", 0.1f, 50f));
			FuelDrainMultiplier = config.Bind<float>("Resources", "FuelDrainMultiplier", 1f, Range("config.fuel_drain.description", 0f, 1f));
			TradeRouteSpeedMultiplier = config.Bind<float>("Trade", "TradeRouteSpeedMultiplier", 1f, Range("config.trade_route_speed.description", 0.1f, 50f));
		}

		private static ConfigDescription Range(string descriptionKey, float min, float max)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return new ConfigDescription(Text(descriptionKey), (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>());
		}

		private static float GetMultiplier(ConfigEntry<float> entry)
		{
			return entry?.Value ?? 1f;
		}

		private static string Text(string key)
		{
			return LocalizationManager.Instance.GetText(key);
		}
	}
	internal static class ModSettingsMenuRegistration
	{
		private static ConfigFile _config;

		private static string _locale;

		private static bool _subscribed;

		public static void Register(ConfigFile config)
		{
			_config = config;
			if (!_subscribed)
			{
				ModSettingsRegistry.RefreshRequested += Refresh;
				_subscribed = true;
			}
			RegisterCurrent(config);
		}

		public static void Refresh()
		{
			if (_config != null)
			{
				LocalizationManager.Instance.RefreshLanguage(forceNotify: false);
				string currentLocale = LocalizationManager.Instance.CurrentLocale;
				ModSettingsRegistration val = default(ModSettingsRegistration);
				if (!(_locale == currentLocale) || !ModSettingsRegistry.TryGet("IceBoxStudio.Romestead.ProsperityTweaks", ref val))
				{
					RegisterCurrent(_config);
				}
			}
		}

		private static void RegisterCurrent(ConfigFile config)
		{
			ModSettingsRegistry.Register("IceBoxStudio.Romestead.ProsperityTweaks", Text("mod.name"), config, (Action<ModSettingsRegistration>)delegate(ModSettingsRegistration registration)
			{
				registration.Icon = "cog";
				registration.Version = "1.0.0";
				registration.Author = "Ice Box Studio";
				registration.Description = Text("mod.description");
				registration.NexusModsId = 22;
				registration.UpdateManifestUrl = "https://fastly.jsdelivr.net/gh/ibox233/MyMod_Version@main/ProsperityTweaks.json";
				registration.Order = -80;
				registration.ConfigureSection("General", (Action<ModSettingsSectionOptions>)delegate(ModSettingsSectionOptions section)
				{
					section.DisplayName = Text("section.general");
					section.Order = 10;
				});
				registration.ConfigureSection("Production", (Action<ModSettingsSectionOptions>)delegate(ModSettingsSectionOptions section)
				{
					section.DisplayName = Text("section.production");
					section.Order = 20;
				});
				registration.ConfigureSection("Resources", (Action<ModSettingsSectionOptions>)delegate(ModSettingsSectionOptions section)
				{
					section.DisplayName = Text("section.resources");
					section.Order = 30;
				});
				registration.ConfigureSection("Trade", (Action<ModSettingsSectionOptions>)delegate(ModSettingsSectionOptions section)
				{
					section.DisplayName = Text("section.trade");
					section.Order = 40;
				});
				registration.ConfigureEntry("General", "Enabled", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.enabled");
					entry.Description = Text("config.enabled.description");
					entry.Order = 1;
				});
				registration.ConfigureEntry("Production", "CropGrowthMultiplier", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.crop_growth");
					entry.Description = Text("config.crop_growth.description");
					entry.SliderStep = 0.1;
					entry.Order = 1;
				});
				registration.ConfigureEntry("Production", "AlwaysWetFarmland", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.always_wet_farmland");
					entry.Description = Text("config.always_wet_farmland.description");
					entry.Order = 2;
				});
				registration.ConfigureEntry("Production", "BuildingTickMultiplier", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.building_tick");
					entry.Description = Text("config.building_tick.description");
					entry.SliderStep = 0.1;
					entry.Order = 3;
				});
				registration.ConfigureEntry("Production", "JobProgressMultiplier", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.job_progress");
					entry.Description = Text("config.job_progress.description");
					entry.SliderStep = 0.1;
					entry.Order = 4;
				});
				registration.ConfigureEntry("Resources", "FuelDrainMultiplier", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.fuel_drain");
					entry.Description = Text("config.fuel_drain.description");
					entry.SliderStep = 0.1;
					entry.Order = 1;
				});
				registration.ConfigureEntry("Trade", "TradeRouteSpeedMultiplier", (Action<ModSettingsEntryOptions>)delegate(ModSettingsEntryOptions entry)
				{
					entry.DisplayName = Text("entry.trade_route_speed");
					entry.Description = Text("config.trade_route_speed.description");
					entry.SliderStep = 0.1;
					entry.Order = 1;
				});
			});
			_locale = LocalizationManager.Instance.CurrentLocale;
		}

		private static string Text(string key)
		{
			return LocalizationManager.Instance.GetText(key);
		}
	}
}