using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using AutoPlantAllDirt.Localization;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
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("AutoPlantAllDirt")]
[assembly: AssemblyDescription("AutoPlantAllDirt mod for Old Market Simulator by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("AutoPlantAllDirt")]
[assembly: AssemblyCopyright("Copyright © 2025 Ice Box Studio All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0C41B86C-0C0D-4C0D-9A69-404CFB6F21B5")]
[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 AutoPlantAllDirt
{
[BepInPlugin("IceBoxStudio.AutoPlantAllDirt", "AutoPlantAllDirt", "1.0.0")]
public class AutoPlantAllDirt : BaseUnityPlugin
{
private static AutoPlantAllDirt _instance;
private Harmony _harmony;
private bool patchesApplied;
public static AutoPlantAllDirt Instance => _instance;
internal static ManualLogSource Logger { get; private set; }
private void Awake()
{
_instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
try
{
Logger.LogInfo((object)"=============================================");
Logger.LogInfo((object)("AutoPlantAllDirt " + LocalizationManager.Instance.GetLocalizedText("plugin.initializing")));
Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
ApplyPatches();
Logger.LogInfo((object)("AutoPlantAllDirt " + LocalizationManager.Instance.GetLocalizedText("plugin.initialized")));
Logger.LogInfo((object)"=============================================");
}
catch (Exception ex)
{
Logger.LogError((object)("AutoPlantAllDirt 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
}
}
private void ApplyPatches()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if (!patchesApplied)
{
try
{
_harmony = new Harmony("IceBoxStudio.AutoPlantAllDirt");
_harmony.PatchAll();
patchesApplied = true;
return;
}
catch (Exception ex)
{
Logger.LogError((object)("AutoPlantAllDirt 应用补丁错误: " + 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.AutoPlantAllDirt";
public const string PLUGIN_NAME = "AutoPlantAllDirt";
public const string PLUGIN_VERSION = "1.0.0";
public const string PLUGIN_AUTHOR = "Ice Box Studio";
public const string PLUGIN_DESCRIPTION = "一键自动种田!oh~yes~!";
}
}
namespace AutoPlantAllDirt.Patches
{
[HarmonyPatch(typeof(BlockDirt))]
public static class BlockDirtAutoPlantPatch
{
private static bool _isAutoPlanting;
private static readonly FieldInfo CurrentSeedField = AccessTools.Field(typeof(BlockDirt), "currentSeed");
private static readonly FieldInfo LocalPlayerInventoryField = AccessTools.Field(typeof(BlockDirt), "localPlayerInventory");
private static readonly FieldInfo CurrentSlotField = AccessTools.Field(typeof(PlayerInventory), "currentSlot");
[HarmonyPatch("Interact")]
[HarmonyPrefix]
private static void Interact_Prefix(BlockDirt __instance, ref bool __state)
{
__state = false;
if (!_isAutoPlanting && !((Object)(object)__instance == (Object)null))
{
PlayerInventory localPlayerInventory = GetLocalPlayerInventory();
if (!((Object)(object)localPlayerInventory == (Object)null) && localPlayerInventory.GetCurrentItemSO() is SeedSO && IsDirtEmpty(__instance))
{
__state = true;
}
}
}
[HarmonyPatch("Interact")]
[HarmonyPostfix]
private static void Interact_Postfix(BlockDirt __instance, bool __state)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (!__state || _isAutoPlanting)
{
return;
}
PlayerInventory localPlayerInventory = GetLocalPlayerInventory();
if ((Object)(object)localPlayerInventory == (Object)null)
{
return;
}
List<BlockDirt> list = FindConnectedDirts(__instance, Object.FindObjectsOfType<BlockDirt>());
if (list.Count > 1)
{
list = SortDirtsSnake(list, __instance, ((Component)localPlayerInventory).transform);
}
int num = 0;
if (!(localPlayerInventory.GetCurrentItemSO() is SeedSO))
{
return;
}
long num2 = -1L;
int currentSlotIndex = GetCurrentSlotIndex(localPlayerInventory);
if (currentSlotIndex != -1 && localPlayerInventory.slots != null && currentSlotIndex < localPlayerInventory.slots.Count)
{
num2 = localPlayerInventory.slots[currentSlotIndex].itemId;
}
if (num2 == -1)
{
return;
}
_isAutoPlanting = true;
try
{
foreach (BlockDirt item in list)
{
if (!((Object)(object)item == (Object)null) && item != __instance && IsDirtEmpty(item))
{
if (!HasSeedInCurrentSlot(localPlayerInventory, num2) && !SwitchToSlotWithSeed(localPlayerInventory, num2))
{
break;
}
EnsureLocalPlayerInventory(item, localPlayerInventory);
((Interactable)item).Interact();
num++;
}
}
}
finally
{
_isAutoPlanting = false;
}
}
private static List<BlockDirt> SortDirtsSnake(List<BlockDirt> dirts, BlockDirt startNode, Transform playerTransform)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: 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_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
Vector3 forward = SnapToGrid(playerTransform.forward);
Vector3 right = SnapToGrid(playerTransform.right);
if (forward == Vector3.zero)
{
forward = Vector3.forward;
}
if (right == Vector3.zero)
{
right = Vector3.right;
}
var list = (from d in dirts
group d by Mathf.RoundToInt(Vector3.Dot(((Component)d).transform.position - ((Component)startNode).transform.position, right) * 100f) into g
select new
{
Key = g.Key,
Dirts = g.ToList(),
Center = g.Average((BlockDirt d) => Vector3.Dot(((Component)d).transform.position, right))
} into g
orderby Mathf.Abs(g.Key)
select g).ToList();
List<BlockDirt> list2 = new List<BlockDirt>();
Vector3 position = ((Component)startNode).transform.position;
foreach (var item in list)
{
List<BlockDirt> dirts2 = item.Dirts;
if (dirts2.Count != 0)
{
List<BlockDirt> list3 = dirts2.OrderBy((BlockDirt d) => Vector3.Dot(((Component)d).transform.position, forward)).ToList();
BlockDirt obj = list3.First();
BlockDirt val = list3.Last();
Vector3 val2 = ((Component)obj).transform.position - position;
float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
val2 = ((Component)val).transform.position - position;
float sqrMagnitude2 = ((Vector3)(ref val2)).sqrMagnitude;
bool flag = true;
if (list2.Count != 0 && !(sqrMagnitude < sqrMagnitude2))
{
list3.Reverse();
}
list2.AddRange(list3);
position = ((Component)list3.Last()).transform.position;
}
}
return list2;
}
private static Vector3 SnapToGrid(Vector3 v)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: 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)
//IL_0048: 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)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if (Mathf.Abs(v.x) > Mathf.Abs(v.z))
{
return new Vector3(Mathf.Sign(v.x), 0f, 0f);
}
return new Vector3(0f, 0f, Mathf.Sign(v.z));
}
private static List<BlockDirt> FindConnectedDirts(BlockDirt startNode, BlockDirt[] allDirts)
{
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: 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)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
List<BlockDirt> list = new List<BlockDirt>();
if ((Object)(object)startNode == (Object)null)
{
return list;
}
Dictionary<Vector2Int, BlockDirt> dictionary = new Dictionary<Vector2Int, BlockDirt>();
Vector2Int key = default(Vector2Int);
foreach (BlockDirt val in allDirts)
{
if (!((Object)(object)val == (Object)null) && !(Mathf.Abs(((Component)val).transform.position.y - ((Component)startNode).transform.position.y) > 0.5f))
{
((Vector2Int)(ref key))..ctor(Mathf.FloorToInt(((Component)val).transform.position.x + 0.5f), Mathf.FloorToInt(((Component)val).transform.position.z + 0.5f));
if (!dictionary.ContainsKey(key))
{
dictionary.Add(key, val);
}
}
}
HashSet<BlockDirt> hashSet = new HashSet<BlockDirt>();
Queue<BlockDirt> queue = new Queue<BlockDirt>();
hashSet.Add(startNode);
queue.Enqueue(startNode);
list.Add(startNode);
Vector2Int[] array = (Vector2Int[])(object)new Vector2Int[4]
{
new Vector2Int(0, 1),
new Vector2Int(0, -1),
new Vector2Int(1, 0),
new Vector2Int(-1, 0)
};
Vector2Int val3 = default(Vector2Int);
while (queue.Count > 0)
{
BlockDirt val2 = queue.Dequeue();
((Vector2Int)(ref val3))..ctor(Mathf.FloorToInt(((Component)val2).transform.position.x + 0.5f), Mathf.FloorToInt(((Component)val2).transform.position.z + 0.5f));
Vector2Int[] array2 = array;
foreach (Vector2Int val4 in array2)
{
Vector2Int key2 = val3 + val4;
if (dictionary.TryGetValue(key2, out var value) && !hashSet.Contains(value))
{
hashSet.Add(value);
queue.Enqueue(value);
list.Add(value);
}
}
}
return list;
}
private static PlayerInventory GetLocalPlayerInventory()
{
NetworkManager singleton = NetworkManager.Singleton;
if ((Object)(object)singleton == (Object)null || !singleton.IsClient)
{
return null;
}
if (singleton.LocalClient == null || (Object)(object)singleton.LocalClient.PlayerObject == (Object)null)
{
return null;
}
return ((Component)singleton.LocalClient.PlayerObject).GetComponent<PlayerInventory>();
}
private static bool IsDirtEmpty(BlockDirt dirt)
{
if ((Object)(object)dirt == (Object)null || CurrentSeedField == null)
{
return false;
}
if (!(CurrentSeedField.GetValue(dirt) is NetworkVariable<long> val))
{
return false;
}
return val.Value == -1;
}
private static void EnsureLocalPlayerInventory(BlockDirt dirt, PlayerInventory inventory)
{
if (!((Object)(object)dirt == (Object)null) && !((Object)(object)inventory == (Object)null) && !(LocalPlayerInventoryField == null) && LocalPlayerInventoryField.GetValue(dirt) == null)
{
LocalPlayerInventoryField.SetValue(dirt, inventory);
}
}
private static int GetCurrentSlotIndex(PlayerInventory inventory)
{
if ((Object)(object)inventory == (Object)null || CurrentSlotField == null)
{
return -1;
}
object value = CurrentSlotField.GetValue(inventory);
if (value == null)
{
return -1;
}
PropertyInfo property = value.GetType().GetProperty("Value");
if (property == null)
{
return -1;
}
return (int)property.GetValue(value);
}
private static void SetCurrentSlotIndex(PlayerInventory inventory, int newIndex)
{
if ((Object)(object)inventory == (Object)null || CurrentSlotField == null)
{
return;
}
object value = CurrentSlotField.GetValue(inventory);
if (value != null)
{
PropertyInfo property = value.GetType().GetProperty("Value");
if (!(property == null))
{
property.SetValue(value, newIndex);
}
}
}
private static bool HasSeedInCurrentSlot(PlayerInventory inventory, long seedId)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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)
int currentSlotIndex = GetCurrentSlotIndex(inventory);
if (currentSlotIndex == -1 || inventory.slots == null || currentSlotIndex >= inventory.slots.Count)
{
return false;
}
InventorySlot val = inventory.slots[currentSlotIndex];
if (val.itemId == seedId)
{
return val.amount > 0;
}
return false;
}
private static bool SwitchToSlotWithSeed(PlayerInventory inventory, long seedId)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)inventory == (Object)null || inventory.slots == null)
{
return false;
}
for (int i = 0; i < inventory.slots.Count; i++)
{
InventorySlot val = inventory.slots[i];
if (val.itemId == seedId && val.amount > 0)
{
SetCurrentSlotIndex(inventory, i);
return true;
}
}
return false;
}
}
}
namespace AutoPlantAllDirt.Localization
{
public static class LocalizationHelper
{
public static Dictionary<string, string> GetDefaultTranslations(string language)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
switch (language)
{
case "zh":
dictionary.Add("plugin.initializing", "开始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初始化成功!");
dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
break;
case "zh-Hant":
dictionary.Add("plugin.initializing", "開始初始化...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初始化成功!");
dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
break;
case "en":
dictionary.Add("plugin.initializing", "is initializing...");
dictionary.Add("plugin.author_prefix", "Author: ");
dictionary.Add("plugin.initialized", "initialized successfully!");
dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
break;
case "fr":
dictionary.Add("plugin.initializing", "initialisation...");
dictionary.Add("plugin.author_prefix", "Auteur : ");
dictionary.Add("plugin.initialized", "initialisé avec succès !");
dictionary.Add("plugin.patches_skipped", "Correctifs déjà appliqués, ignoré...");
break;
case "de":
dictionary.Add("plugin.initializing", "wird initialisiert...");
dictionary.Add("plugin.author_prefix", "Autor: ");
dictionary.Add("plugin.initialized", "erfolgreich initialisiert!");
dictionary.Add("plugin.patches_skipped", "Patches bereits angewendet, überspringe...");
break;
case "ja":
dictionary.Add("plugin.initializing", "初期化中...");
dictionary.Add("plugin.author_prefix", "作者:");
dictionary.Add("plugin.initialized", "初期化に成功しました!");
dictionary.Add("plugin.patches_skipped", "パッチは既に適用されています。スキップします...");
break;
case "ko":
dictionary.Add("plugin.initializing", "초기화 중...");
dictionary.Add("plugin.author_prefix", "작성자: ");
dictionary.Add("plugin.initialized", "초기화 성공!");
dictionary.Add("plugin.patches_skipped", "패치가 이미 적용되었습니다. 건너뛰는 중...");
break;
case "pt":
dictionary.Add("plugin.initializing", "inicializando...");
dictionary.Add("plugin.author_prefix", "Autor: ");
dictionary.Add("plugin.initialized", "inicializado com sucesso!");
dictionary.Add("plugin.patches_skipped", "Patches já aplicados, pulando...");
break;
case "ru":
dictionary.Add("plugin.initializing", "инициализация...");
dictionary.Add("plugin.author_prefix", "Автор: ");
dictionary.Add("plugin.initialized", "инициализация прошла успешно!");
dictionary.Add("plugin.patches_skipped", "Патчи уже применены, пропуск...");
break;
case "es":
dictionary.Add("plugin.initializing", "inicializando...");
dictionary.Add("plugin.author_prefix", "Autor: ");
dictionary.Add("plugin.initialized", "¡inicializado con éxito!");
dictionary.Add("plugin.patches_skipped", "Parches ya aplicados, omitiendo...");
break;
case "tr":
dictionary.Add("plugin.initializing", "başlatılıyor...");
dictionary.Add("plugin.author_prefix", "Yazar: ");
dictionary.Add("plugin.initialized", "başarıyla başlatıldı!");
dictionary.Add("plugin.patches_skipped", "Yamalar zaten uygulandı, atlanıyor...");
break;
case "uk":
dictionary.Add("plugin.initializing", "ініціалізація...");
dictionary.Add("plugin.author_prefix", "Автор: ");
dictionary.Add("plugin.initialized", "ініціалізація пройшла успішно!");
dictionary.Add("plugin.patches_skipped", "Патчі вже застосовані, пропуск...");
break;
}
return dictionary;
}
}
public class LocalizationManager
{
private static LocalizationManager _instance;
private readonly 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"
};
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;
}
string[] supportedLanguages = SupportedLanguages;
foreach (string text in supportedLanguages)
{
Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text);
if (defaultTranslations != null && defaultTranslations.Count > 0)
{
_localizations[text] = defaultTranslations;
}
}
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;
}
else
{
_currentLocale = "en";
}
}
}
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;
}
}
}