using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using AutoRestockFishFixed.Configuration;
using AutoRestockFishFixed.Localization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Newtonsoft.Json;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AutoRestockFishFixed")]
[assembly: AssemblyDescription("AutoRestockFishFixed mod for Old Market Simulator by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("AutoRestockFishFixed")]
[assembly: AssemblyCopyright("Copyright © 2025 Ice Box Studio All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("D7F52A81-4B3C-48E9-9A5D-12C3F8E940B2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AutoRestockFishFixed
{
[BepInPlugin("IceBoxStudio.AutoRestockFishFixed", "AutoRestockFishFixed", "1.0.0")]
[BepInIncompatibility("xuthics.autoFish")]
public class AutoRestockFishFixed : BaseUnityPlugin
{
private static AutoRestockFishFixed _instance;
private Harmony _harmony;
private bool patchesApplied;
internal static ManualLogSource Logger { get; private set; }
public static AutoRestockFishFixed Instance => _instance;
private void Awake()
{
_instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
try
{
_ = LocalizationManager.Instance;
Logger.LogInfo((object)"=============================================");
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.initializing"));
Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
ApplyPatches();
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.initialized"));
Logger.LogInfo((object)"=============================================");
}
catch (Exception ex)
{
Logger.LogError((object)("AutoRestockFishFixed 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
}
}
private void ApplyPatches()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
if (!patchesApplied)
{
try
{
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.applying_patches"));
_harmony = new Harmony("IceBoxStudio.AutoRestockFishFixed");
_harmony.PatchAll();
patchesApplied = true;
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_applied"));
return;
}
catch (Exception ex)
{
Logger.LogError((object)("AutoRestockFishFixed 应用补丁错误: " + ex.Message + "\n" + ex.StackTrace));
return;
}
}
Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "IceBoxStudio.AutoRestockFishFixed";
public const string PLUGIN_NAME = "AutoRestockFishFixed";
public const string PLUGIN_VERSION = "1.0.0";
public const string PLUGIN_AUTHOR = "Ice Box Studio";
public const string PLUGIN_DESCRIPTION = "自动从地窖中补充鱼。AutoRestockFish 的重写修复版。Xuthics 原创模组,Krissy 为 East Town 鱼类更新,Ice Box Studio 为模组重写与修复。";
}
}
namespace AutoRestockFishFixed.Patches
{
[HarmonyPatch(typeof(Item))]
public static class ItemPatches
{
[HarmonyPatch("BuyProductServer")]
[HarmonyPrefix]
public static bool BuyProductServer_Prefix(Item __instance, ref bool __result)
{
try
{
if (!ConfigManager.ShouldAutoRestock())
{
return true;
}
if (!((NetworkBehaviour)__instance).IsServer)
{
__result = false;
return false;
}
NetworkVariable<int> amount = __instance.amount;
if (amount != null && amount.Value <= 0)
{
__result = false;
return false;
}
List<string> fishNames = ConfigManager.GetFishNames();
ItemSO itemSO = __instance.itemSO;
string text = ((itemSO != null) ? ((Object)itemSO).name : null);
ItemSO itemSO2 = __instance.itemSO;
string text2 = ((itemSO2 != null) ? itemSO2.GetLocalizedName() : null);
long itemID = __instance.itemSO?.id ?? 0;
if (!string.IsNullOrEmpty(text) && fishNames.Contains(text))
{
List<Item> list = Object.FindObjectsOfType<Item>().Where(delegate(Item x)
{
if ((Object)(object)x != (Object)null && x.itemSO is ProductSO)
{
NetworkVariable<int> amount4 = x.amount;
if (amount4 != null && amount4.Value > 0 && x.IsInFreezer())
{
ItemSO itemSO3 = x.itemSO;
if (itemSO3 != null && itemSO3.id == itemID)
{
return !x.IsExpired();
}
}
}
return false;
}).ToList();
if (list.Count > 0)
{
Item val = list.First();
if (((NetworkBehaviour)__instance).IsServer && (Object)(object)val != (Object)null && val.dayCounter != null)
{
__instance.dayCounter.Value = val.dayCounter.Value;
}
Object.Destroy((Object)(object)((Component)val).gameObject);
if (ConfigManager.ShowRestockNotifications.Value)
{
string localizedText = LocalizationManager.Instance.GetLocalizedText("restock.fish_restocked", text2);
try
{
AccessTools.Method(typeof(GameManager), "ShowNotificationClientRpc", new Type[4]
{
typeof(string),
typeof(bool),
typeof(float),
typeof(bool)
}, (Type[])null)?.Invoke(GameManager.Instance, new object[4] { localizedText, false, 3f, false });
}
catch (Exception ex)
{
AutoRestockFishFixed.Logger.LogWarning((object)("无法显示游戏内通知: " + ex.Message));
}
}
}
else
{
if (__instance.amount != null)
{
NetworkVariable<int> amount2 = __instance.amount;
int value = amount2.Value;
amount2.Value = value - 1;
}
if (ConfigManager.ShowRestockNotifications.Value)
{
string localizedText2 = LocalizationManager.Instance.GetLocalizedText("restock.no_cellar_stock", text2);
try
{
AccessTools.Method(typeof(GameManager), "ShowNotificationClientRpc", new Type[4]
{
typeof(string),
typeof(bool),
typeof(float),
typeof(bool)
}, (Type[])null)?.Invoke(GameManager.Instance, new object[4] { localizedText2, false, 3f, false });
}
catch (Exception ex2)
{
AutoRestockFishFixed.Logger.LogWarning((object)("无法显示游戏内通知: " + ex2.Message));
}
}
}
__result = true;
}
else
{
if (__instance.amount != null)
{
NetworkVariable<int> amount3 = __instance.amount;
int value = amount3.Value;
amount3.Value = value - 1;
}
__result = true;
}
return false;
}
catch (Exception ex3)
{
AutoRestockFishFixed.Logger.LogError((object)("BuyProductServer_Prefix 错误: " + ex3.Message + "\n" + ex3.StackTrace));
return true;
}
}
}
}
namespace AutoRestockFishFixed.Localization
{
public class LocalizationManager
{
private static LocalizationManager _instance;
private Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();
private string _currentLocale = "zh";
public static readonly string[] SupportedLanguages = new string[12]
{
"zh", "zh-Hant", "en", "fr", "de", "ja", "ko", "pt", "ru", "es",
"tr", "uk"
};
private static readonly string[] DefaultTranslationLanguages = new string[3] { "zh", "zh-Hant", "en" };
public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());
private LocalizationManager()
{
Initialize();
}
public void Initialize()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)LocalizationSettings.SelectedLocale != (Object)null)
{
LocaleIdentifier identifier = LocalizationSettings.SelectedLocale.Identifier;
_currentLocale = ((LocaleIdentifier)(ref identifier)).Code;
}
LocalizationHelper.InitializeLanguageFiles();
string path = Path.Combine(Paths.ConfigPath, "AutoRestockFishFixed", "Localization");
string[] supportedLanguages = SupportedLanguages;
foreach (string text in supportedLanguages)
{
string filePath = Path.Combine(path, text + ".json");
LoadLanguageFile(text, filePath);
}
LocalizationSettings.SelectedLocaleChanged += OnGameLanguageChanged;
}
private void OnGameLanguageChanged(Locale locale)
{
//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)
if ((Object)(object)locale != (Object)null)
{
LocaleIdentifier identifier = locale.Identifier;
string code = ((LocaleIdentifier)(ref identifier)).Code;
if (_localizations.ContainsKey(code))
{
_currentLocale = code;
return;
}
_currentLocale = "en";
AutoRestockFishFixed.Logger.LogInfo((object)GetLocalizedText("plugin.language_fallback", code));
}
}
private void LoadLanguageFile(string language, string filePath)
{
if (File.Exists(filePath))
{
try
{
Dictionary<string, string> value = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(filePath));
_localizations[language] = value;
return;
}
catch
{
if (Array.IndexOf(DefaultTranslationLanguages, language) >= 0)
{
_localizations[language] = GetDefaultTranslations(language);
}
return;
}
}
if (Array.IndexOf(DefaultTranslationLanguages, language) >= 0)
{
_localizations[language] = GetDefaultTranslations(language);
}
}
private Dictionary<string, string> GetDefaultTranslations(string language)
{
MethodInfo methodInfo = AccessTools.Method(typeof(LocalizationHelper), "GetDefaultTranslations", (Type[])null, (Type[])null);
if (methodInfo != null)
{
return methodInfo.Invoke(null, new object[1] { language }) as Dictionary<string, string>;
}
return new Dictionary<string, string>();
}
public string GetLocalizedText(string key, params object[] args)
{
if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
{
_currentLocale = "en";
}
if (_localizations.ContainsKey(_currentLocale) && _localizations[_currentLocale].TryGetValue(key, out var value))
{
if (args.Length == 0)
{
return value;
}
return string.Format(value, args);
}
if (_currentLocale != "en" && _localizations.ContainsKey("en") && _localizations["en"].TryGetValue(key, out var value2))
{
if (args.Length == 0)
{
return value2;
}
return string.Format(value2, args);
}
if (_localizations.ContainsKey("zh") && _localizations["zh"].TryGetValue(key, out var value3))
{
if (args.Length == 0)
{
return value3;
}
return string.Format(value3, args);
}
return key;
}
}
public static class LocalizationHelper
{
private static readonly string[] DefaultTranslationLanguages = new string[3] { "zh", "zh-Hant", "en" };
public static void InitializeLanguageFiles()
{
string text = Path.Combine(Paths.ConfigPath, "AutoRestockFishFixed", "Localization");
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
string[] defaultTranslationLanguages = DefaultTranslationLanguages;
foreach (string text2 in defaultTranslationLanguages)
{
string filePath = Path.Combine(text, text2 + ".json");
EnsureLanguageFile(text2, filePath);
}
}
private static void EnsureLanguageFile(string language, string filePath)
{
Dictionary<string, string> defaultTranslations = GetDefaultTranslations(language);
if (File.Exists(filePath))
{
try
{
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(filePath));
bool flag = false;
foreach (KeyValuePair<string, string> item in defaultTranslations)
{
if (!dictionary.ContainsKey(item.Key))
{
dictionary[item.Key] = item.Value;
flag = true;
}
}
if (flag)
{
string contents = JsonConvert.SerializeObject((object)dictionary, (Formatting)1);
File.WriteAllText(filePath, contents);
}
return;
}
catch
{
CreateLanguageFile(language, filePath, defaultTranslations);
return;
}
}
CreateLanguageFile(language, filePath, defaultTranslations);
}
private static void CreateLanguageFile(string language, string filePath, Dictionary<string, string> translations)
{
string contents = JsonConvert.SerializeObject((object)translations, (Formatting)1);
File.WriteAllText(filePath, contents);
}
public static Dictionary<string, string> GetDefaultTranslations(string language)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
switch (language)
{
case "zh":
dictionary.Add("plugin.initializing", "AutoRestockFishFixed 开始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "AutoRestockFishFixed 初始化成功!");
dictionary.Add("plugin.applying_patches", "正在应用 AutoRestockFishFixed 补丁...");
dictionary.Add("plugin.patches_applied", "AutoRestockFishFixed 补丁已成功应用!");
dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
dictionary.Add("plugin.language_fallback", "不支持的语言 {0},使用英语作为备用。");
dictionary.Add("config.enable_mod_desc", "是否启用 AutoRestockFishFixed 模组功能");
dictionary.Add("config.enable_auto_restock_desc", "是否启用自动鱼类补货功能");
dictionary.Add("config.show_restock_notifications_desc", "是否显示鱼类补货成功的提示信息");
dictionary.Add("config.fish_item_names_desc", "鱼类物品名称列表,用逗号分隔(例如:Regular Fish,Brown Fish,Carp)");
dictionary.Add("restock.fish_restocked", "从地窖补充了鱼类:{0}。");
dictionary.Add("restock.no_cellar_stock", "地窖中没有鱼类 {0} 的库存,无法补充。");
break;
case "zh-Hant":
dictionary.Add("plugin.initializing", "AutoRestockFishFixed 開始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "AutoRestockFishFixed 初始化成功!");
dictionary.Add("plugin.applying_patches", "正在應用 AutoRestockFishFixed 補丁...");
dictionary.Add("plugin.patches_applied", "AutoRestockFishFixed 補丁已成功應用!");
dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
dictionary.Add("plugin.language_fallback", "不支持的語言 {0},使用英語作為備用。");
dictionary.Add("config.enable_mod_desc", "是否啟用 AutoRestockFishFixed 模組功能");
dictionary.Add("config.enable_auto_restock_desc", "是否啟用自動魚類補貨功能");
dictionary.Add("config.show_restock_notifications_desc", "是否顯示魚類補貨成功的提示信息");
dictionary.Add("config.fish_item_names_desc", "魚類物品名稱列表,用逗號分隔(例如:Regular Fish,Brown Fish,Carp)");
dictionary.Add("restock.fish_restocked", "從地窖補充了魚類:{0}。");
dictionary.Add("restock.no_cellar_stock", "地窖中沒有魚類 {0} 的庫存,無法補充。");
break;
case "en":
dictionary.Add("plugin.initializing", "AutoRestockFishFixed is initializing...");
dictionary.Add("plugin.author_prefix", "Author: ");
dictionary.Add("plugin.initialized", "AutoRestockFishFixed initialized successfully!");
dictionary.Add("plugin.applying_patches", "Applying AutoRestockFishFixed patches...");
dictionary.Add("plugin.patches_applied", "AutoRestockFishFixed patches applied successfully!");
dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
dictionary.Add("plugin.language_fallback", "Unsupported language {0}, using English as fallback.");
dictionary.Add("config.enable_mod_desc", "Whether to enable AutoRestockFishFixed mod functionality");
dictionary.Add("config.enable_auto_restock_desc", "Whether to enable automatic fish restocking");
dictionary.Add("config.show_restock_notifications_desc", "Whether to show fish restock success notifications");
dictionary.Add("config.fish_item_names_desc", "List of fish item names, separated by commas (e.g., Regular Fish,Brown Fish,Carp)");
dictionary.Add("restock.fish_restocked", "Restocked fish from cellar: {0}.");
dictionary.Add("restock.no_cellar_stock", "No stock of fish {0} in cellar, unable to restock.");
break;
}
return dictionary;
}
}
}
namespace AutoRestockFishFixed.Configuration
{
public static class ConfigManager
{
public static ConfigEntry<bool> EnableMod { get; private set; }
public static ConfigEntry<bool> EnableAutoRestock { get; private set; }
public static ConfigEntry<string> FishItemNames { get; private set; }
public static ConfigEntry<bool> ShowRestockNotifications { get; private set; }
public static List<string> GetFishNames()
{
if (string.IsNullOrEmpty(FishItemNames.Value))
{
return new List<string>();
}
return (from name in FishItemNames.Value.Split(new char[1] { ',' })
select name.Trim() into name
where !string.IsNullOrEmpty(name)
select name).ToList();
}
public static void Initialize(ConfigFile config)
{
EnableMod = config.Bind<bool>("General", "EnableMod", true, LocalizationManager.Instance.GetLocalizedText("config.enable_mod_desc"));
EnableAutoRestock = config.Bind<bool>("General", "EnableAutoRestock", true, LocalizationManager.Instance.GetLocalizedText("config.enable_auto_restock_desc"));
ShowRestockNotifications = config.Bind<bool>("General", "ShowRestockNotifications", true, LocalizationManager.Instance.GetLocalizedText("config.show_restock_notifications_desc"));
string text = "Regular Fish,Brown Fish,Grey Fish,Green Fish,Orange Roughy,Carp,Swordfish,Octopus,Baby Shark,Trout,Lobster,Tuna,Ray,Goby";
FishItemNames = config.Bind<string>("General", "FishItemNames", text, LocalizationManager.Instance.GetLocalizedText("config.fish_item_names_desc"));
}
public static bool ShouldAutoRestock()
{
if (EnableMod.Value)
{
return EnableAutoRestock.Value;
}
return false;
}
}
}