Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AutoProduktion v1.0.0
plugins/AutoProduktion.dll
Decompiled 2 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AutoProduktion")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AutoProduktion")] [assembly: AssemblyTitle("AutoProduktion")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Schachio.AutoProduktion { [BepInPlugin("AutoProduktion", "Auto-Produktion", "1.0.0")] public sealed class AutoProduktionPlugin : BaseUnityPlugin { public const string PluginGuid = "AutoProduktion"; public const string PluginName = "Auto-Produktion"; public const string PluginVersion = "1.0.0"; private float _nextScan; private float _nextConfigCheck; private DateTime _configWriteTimeUtc; internal static AutoProduktionPlugin Instance { get; private set; } internal static ConfigEntry<bool> Aktiviert { get; private set; } internal static ConfigEntry<float> SchmelzofenRadius { get; private set; } internal static ConfigEntry<bool> SchmelzofenErzeAufnehmen { get; private set; } internal static ConfigEntry<float> KohlenmeilerRadius { get; private set; } internal static ConfigEntry<float> HochofenRadius { get; private set; } internal static ConfigEntry<bool> HochofenRohstoffeAufnehmen { get; private set; } internal static ConfigEntry<float> SteinofenRadius { get; private set; } internal static ConfigEntry<bool> SteinofenRohstoffeAufnehmen { get; private set; } internal static ConfigEntry<KeyboardShortcut> SchmelzofenRadiusTaste { get; private set; } internal static ConfigEntry<KeyboardShortcut> KohlenmeilerRadiusTaste { get; private set; } internal static ConfigEntry<KeyboardShortcut> HochofenRadiusTaste { get; private set; } internal static ConfigEntry<KeyboardShortcut> SteinofenRadiusTaste { get; private set; } internal static ConfigEntry<string> SchmelzofenRadiusFarbe { get; private set; } internal static ConfigEntry<string> KohlenmeilerRadiusFarbe { get; private set; } internal static ConfigEntry<string> HochofenRadiusFarbe { get; private set; } internal static ConfigEntry<string> SteinofenRadiusFarbe { get; private set; } internal static ConfigEntry<bool> AutomatischeRadiusAnzeige { get; private set; } internal static ConfigEntry<float> AutomatischeAnzeigeDauer { get; private set; } internal static ConfigEntry<float> Pruefintervall { get; private set; } internal static ConfigEntry<bool> Diagnose { get; private set; } private void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Expected O, but got Unknown Instance = this; Aktiviert = ((BaseUnityPlugin)this).Config.Bind<bool>("Allgemein", "Aktiviert", true, "Schaltet die automatische Ressourcenaufnahme aller Anlagen ein oder aus."); SchmelzofenRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Schmelzofen", "Radius", 2.5f, new ConfigDescription("Kohle- und Erz-Aufnahmeradius des Schmelzofens in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>())); SchmelzofenErzeAufnehmen = ((BaseUnityPlugin)this).Config.Bind<bool>("Schmelzofen", "ErzeVomBodenAufnehmen", true, "Nimmt alle unverarbeiteten Materialien auf, die der Schmelzofen laut seinen Rezepten verarbeiten kann. Barren werden nicht aufgenommen."); KohlenmeilerRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Kohlenmeiler", "Radius", 2.5f, new ConfigDescription("Holz-Aufnahmeradius des Kohlenmeilers in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>())); HochofenRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Hochofen", "Radius", 2.5f, new ConfigDescription("Kohle- und Rohstoff-Aufnahmeradius des Hochofens in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>())); HochofenRohstoffeAufnehmen = ((BaseUnityPlugin)this).Config.Bind<bool>("Hochofen", "RohstoffeVomBodenAufnehmen", true, "Nimmt Kohle und alle unverarbeiteten Materialien auf, die der Hochofen laut seinen Rezepten verarbeiten kann."); SteinofenRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Steinofen", "Radius", 2.5f, new ConfigDescription("Holz- und Zutaten-Aufnahmeradius des Steinofens in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>())); SteinofenRohstoffeAufnehmen = ((BaseUnityPlugin)this).Config.Bind<bool>("Steinofen", "RohstoffeVomBodenAufnehmen", true, "Nimmt Holz und alle ungebackenen Speisen auf, die der Steinofen laut seinen Rezepten verarbeiten kann."); Pruefintervall = ((BaseUnityPlugin)this).Config.Bind<float>("Allgemein", "PruefintervallSekunden", 0.25f, new ConfigDescription("Zeit zwischen zwei Suchlaeufen nach Ressourcen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())); SchmelzofenRadiusTaste = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Anzeige", "SchmelzofenRadiusTaste", RadiusHotkeys.Default((KeyCode)282), "Schaltet die Schmelzofen-Kreise dauerhaft ein oder aus. Standard: Shift + F1; linke oder rechte Shift-Taste."); KohlenmeilerRadiusTaste = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Anzeige", "KohlenmeilerRadiusTaste", RadiusHotkeys.Default((KeyCode)283), "Schaltet die Kohlenmeiler-Kreise dauerhaft ein oder aus. Standard: Shift + F2; linke oder rechte Shift-Taste."); HochofenRadiusTaste = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Anzeige", "HochofenRadiusTaste", RadiusHotkeys.Default((KeyCode)284), "Schaltet die Hochofen-Kreise dauerhaft ein oder aus. Standard: Shift + F3; linke oder rechte Shift-Taste."); SteinofenRadiusTaste = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Anzeige", "SteinofenRadiusTaste", RadiusHotkeys.Default((KeyCode)285), "Schaltet die Steinofen-Kreise dauerhaft ein oder aus. Standard: Shift + F4; linke oder rechte Shift-Taste."); SchmelzofenRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind<string>("Anzeige", "SchmelzofenRadiusFarbe", "#FF0000", "Kreisfarbe als HTML-Farbwert, zum Beispiel #FF0000 fuer Rot."); KohlenmeilerRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind<string>("Anzeige", "KohlenmeilerRadiusFarbe", "#FFFFFF", "Kreisfarbe als HTML-Farbwert, zum Beispiel #FFFFFF fuer Weiss."); HochofenRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind<string>("Anzeige", "HochofenRadiusFarbe", "#FF8C00", "Kreisfarbe als HTML-Farbwert, Standard ist Orange."); SteinofenRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind<string>("Anzeige", "SteinofenRadiusFarbe", "#00BFFF", "Kreisfarbe als HTML-Farbwert, Standard ist Hellblau."); AutomatischeRadiusAnzeige = ((BaseUnityPlugin)this).Config.Bind<bool>("Anzeige", "AutomatischFuenfSekundenAnzeigen", true, "Zeigt den passenden Kreis automatisch bei neu erkannten oder angesehenen Anlagen."); AutomatischeAnzeigeDauer = ((BaseUnityPlugin)this).Config.Bind<float>("Anzeige", "AutomatischeAnzeigedauerSekunden", 5f, new ConfigDescription("Dauer der automatischen Radiusanzeige.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); Diagnose = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnose", "AusfuehrlichesProtokoll", false, "Schreibt erkannte Anlagen und Ressourcentransfers in das BepInEx-Protokoll."); int num = RadiusHotkeys.MigrateLegacyDefaults(((BaseUnityPlugin)this).Config, SchmelzofenRadiusTaste, KohlenmeilerRadiusTaste, HochofenRadiusTaste, SteinofenRadiusTaste); if (num > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{num} bisherige Radiustasten auf Shift + F1 bis F4 umgestellt. Eigene Belegungen bleiben erhalten."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Auto-Produktion 1.0.0 geladen. " + $"Schmelzofen {SchmelzofenRadius.Value:0.##} m, " + $"Kohlenmeiler {KohlenmeilerRadius.Value:0.##} m, " + $"Hochofen {HochofenRadius.Value:0.##} m, " + $"Steinofen {SteinofenRadius.Value:0.##} m.")); if (File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { _configWriteTimeUtc = File.GetLastWriteTimeUtc(((BaseUnityPlugin)this).Config.ConfigFilePath); } } private void Update() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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) ReloadConfigIfChanged(); if (RadiusHotkeys.IsDown(SchmelzofenRadiusTaste.Value)) { bool flag = RadiusDisplay.ToggleSmelters(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Schmelzofen-Radiustaste erkannt: " + (flag ? "AN" : "AUS") + ".")); ShowMessage(string.Format("Schmelzofen-Radius {0} ({1:0.##} m)", flag ? "AN" : "AUS", SchmelzofenRadius.Value)); } if (RadiusHotkeys.IsDown(KohlenmeilerRadiusTaste.Value)) { bool flag2 = RadiusDisplay.ToggleKilns(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Kohlenmeiler-Radiustaste erkannt: " + (flag2 ? "AN" : "AUS") + ".")); ShowMessage(string.Format("Kohlenmeiler-Radius {0} ({1:0.##} m)", flag2 ? "AN" : "AUS", KohlenmeilerRadius.Value)); } if (RadiusHotkeys.IsDown(HochofenRadiusTaste.Value)) { bool flag3 = RadiusDisplay.ToggleBlastFurnaces(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Hochofen-Radiustaste erkannt: " + (flag3 ? "AN" : "AUS") + ".")); ShowMessage(string.Format("Hochofen-Radius {0} ({1:0.##} m)", flag3 ? "AN" : "AUS", HochofenRadius.Value)); } if (RadiusHotkeys.IsDown(SteinofenRadiusTaste.Value)) { bool flag4 = RadiusDisplay.ToggleStoneOvens(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Steinofen-Radiustaste erkannt: " + (flag4 ? "AN" : "AUS") + ".")); ShowMessage(string.Format("Steinofen-Radius {0} ({1:0.##} m)", flag4 ? "AN" : "AUS", SteinofenRadius.Value)); } RadiusDisplay.Update(); if (Aktiviert.Value && !(Time.time < _nextScan)) { _nextScan = Time.time + Mathf.Clamp(Pruefintervall.Value, 0.1f, 2f); CoalCollector.Scan(); if (SchmelzofenErzeAufnehmen.Value || HochofenRohstoffeAufnehmen.Value) { OreCollector.Scan(); } WoodCollector.Scan(); if (SteinofenRohstoffeAufnehmen.Value) { StoneOvenCollector.Scan(); } } } internal static void LogDiagnostic(string message) { if (Diagnose.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } } internal static void LogInfo(string message) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } private void ReloadConfigIfChanged() { if (Time.unscaledTime < _nextConfigCheck) { return; } _nextConfigCheck = Time.unscaledTime + 1f; if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) || File.GetLastWriteTimeUtc(((BaseUnityPlugin)this).Config.ConfigFilePath) <= _configWriteTimeUtc) { return; } try { ((BaseUnityPlugin)this).Config.Reload(); _configWriteTimeUtc = File.GetLastWriteTimeUtc(((BaseUnityPlugin)this).Config.ConfigFilePath); ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Config neu geladen: Schmelzofen {SchmelzofenRadius.Value:0.##} m, " + $"Kohlenmeiler {KohlenmeilerRadius.Value:0.##} m, " + $"Hochofen {HochofenRadius.Value:0.##} m, " + $"Steinofen {SteinofenRadius.Value:0.##} m.")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Config konnte noch nicht neu geladen werden: " + ex.Message)); } } private static void ShowMessage(string message) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null); } } } internal static class CoalCollector { private sealed class Target { internal Smelter Station { get; } internal float Radius { get; } internal string Name { get; } internal Target(Smelter station, float radius, string name) { Station = station; Radius = radius; Name = name; } } private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo NetworkViewField = typeof(Smelter).GetField("m_nview", PrivateInstance); private static readonly MethodInfo GetFuelMethod = typeof(Smelter).GetMethod("GetFuel", PrivateInstance); internal static void Scan() { List<Target> list = (from station in SmelterFinder.FindAll() select new Target(station, Mathf.Clamp(AutoProduktionPlugin.SchmelzofenRadius.Value, 2f, 50f), "Schmelzofen")).ToList(); if (AutoProduktionPlugin.HochofenRohstoffeAufnehmen.Value) { list.AddRange(from station in SmelterFinder.FindAllBlastFurnaces() select new Target(station, Mathf.Clamp(AutoProduktionPlugin.HochofenRadius.Value, 2f, 50f), "Hochofen")); } list = list.Where((Target target) => UsesCoal(target.Station)).ToList(); if (list.Count == 0) { return; } foreach (ItemDrop coal in Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0).Where(IsCoal).ToList()) { if (!EnsureItemOwnership(coal)) { continue; } foreach (Target item in (from candidate in list where SmelterFinder.HorizontalDistance(((Component)coal).transform.position, ((Component)candidate.Station).transform.position) <= candidate.Radius orderby SmelterFinder.HorizontalDistance(((Component)coal).transform.position, ((Component)candidate.Station).transform.position) select candidate).ToList()) { int num = InsertCoal(item.Station, coal.m_itemData.m_stack); if (num > 0) { AutoProduktionPlugin.LogDiagnostic($"{num} Kohle vom Boden in {item.Name} eingefuellt."); RemoveFromGround(coal, num); if ((Object)(object)coal == (Object)null || coal.m_itemData == null || coal.m_itemData.m_stack <= 0) { break; } } } } } private static bool UsesCoal(Smelter station) { ItemDrop fuelItem = station.m_fuelItem; if ((Object)(object)fuelItem == (Object)null || fuelItem.m_itemData == null) { return false; } string a = SmelterFinder.CleanName(((Object)((Component)fuelItem).gameObject).name); string a2 = fuelItem.m_itemData.m_shared?.m_name ?? string.Empty; if (!string.Equals(a, "Coal", StringComparison.OrdinalIgnoreCase)) { return string.Equals(a2, "$item_coal", StringComparison.OrdinalIgnoreCase); } return true; } private static int InsertCoal(Smelter smelter, int available) { if (available <= 0 || smelter.m_maxFuel <= 0) { return 0; } object? value = NetworkViewField.GetValue(smelter); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { return 0; } float num = (float)(GetFuelMethod.Invoke(smelter, null) ?? ((object)0f)); int val2 = Math.Max(0, smelter.m_maxFuel - Mathf.CeilToInt(num)); int num2 = Math.Min(available, val2); for (int i = 0; i < num2; i++) { val.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } return num2; } private static bool IsCoal(ItemDrop drop) { if ((Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_stack <= 0) { return false; } GameObject dropPrefab = drop.m_itemData.m_dropPrefab; string a = SmelterFinder.CleanName(((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? ((Object)((Component)drop).gameObject).name); string a2 = drop.m_itemData.m_shared?.m_name ?? string.Empty; if (!string.Equals(a, "Coal", StringComparison.OrdinalIgnoreCase)) { return string.Equals(a2, "$item_coal", StringComparison.OrdinalIgnoreCase); } return true; } private static bool EnsureItemOwnership(ItemDrop drop) { ZNetView component = ((Component)drop).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } if (!component.IsOwner()) { component.ClaimOwnership(); } return component.IsOwner(); } private static void RemoveFromGround(ItemDrop drop, int amount) { for (int i = 0; i < amount; i++) { if (!((Object)(object)drop != (Object)null)) { break; } if (drop.m_itemData.m_stack <= 0) { break; } drop.RemoveOne(); } } } internal static class OreCollector { private sealed class Target { internal Smelter Station { get; } internal float Radius { get; } internal string Name { get; } internal Target(Smelter station, float radius, string name) { Station = station; Radius = radius; Name = name; } } private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo NetworkViewField = typeof(Smelter).GetField("m_nview", PrivateInstance); private static readonly MethodInfo GetQueueSizeMethod = typeof(Smelter).GetMethod("GetQueueSize", PrivateInstance); internal static void Scan() { List<Target> list = new List<Target>(); if (AutoProduktionPlugin.SchmelzofenErzeAufnehmen.Value) { list.AddRange(from station in SmelterFinder.FindAll() select new Target(station, Mathf.Clamp(AutoProduktionPlugin.SchmelzofenRadius.Value, 2f, 50f), "Schmelzofen")); } if (AutoProduktionPlugin.HochofenRohstoffeAufnehmen.Value) { list.AddRange(from station in SmelterFinder.FindAllBlastFurnaces() select new Target(station, Mathf.Clamp(AutoProduktionPlugin.HochofenRadius.Value, 2f, 50f), "Hochofen")); } if (list.Count == 0) { return; } ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0); foreach (ItemDrop item in array) { if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_stack <= 0 || !EnsureItemOwnership(item)) { continue; } foreach (Target item2 in (from candidate in list where SmelterFinder.HorizontalDistance(((Component)item).transform.position, ((Component)candidate.Station).transform.position) <= candidate.Radius orderby SmelterFinder.HorizontalDistance(((Component)item).transform.position, ((Component)candidate.Station).transform.position) select candidate).ToList()) { string text = FindAcceptedInput(item2.Station, item); if (text == null) { continue; } int num2 = InsertOre(item2.Station, text, item.m_itemData.m_stack); if (num2 > 0) { AutoProduktionPlugin.LogDiagnostic($"{num2}x {text} vom Boden in {item2.Name} eingefuellt."); RemoveFromGround(item, num2); if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_stack <= 0) { break; } } } } } private static string? FindAcceptedInput(Smelter smelter, ItemDrop item) { if (smelter.m_conversion == null) { return null; } GameObject dropPrefab = item.m_itemData.m_dropPrefab; string a = SmelterFinder.CleanName(((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? ((Object)((Component)item).gameObject).name); string a2 = item.m_itemData.m_shared?.m_name ?? string.Empty; foreach (ItemConversion item2 in smelter.m_conversion) { if (!((Object)(object)item2?.m_from == (Object)null)) { string text = SmelterFinder.CleanName(((Object)((Component)item2.m_from).gameObject).name); string b = item2.m_from.m_itemData?.m_shared?.m_name ?? string.Empty; if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase) || string.Equals(a2, b, StringComparison.OrdinalIgnoreCase)) { return text; } } } return null; } private static int InsertOre(Smelter smelter, string prefabName, int available) { if (available <= 0) { return 0; } object? value = NetworkViewField.GetValue(smelter); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { return 0; } int num = (int)(GetQueueSizeMethod.Invoke(smelter, null) ?? ((object)0)); int val2 = Math.Max(0, smelter.m_maxOre - num); int num2 = Math.Min(available, val2); for (int i = 0; i < num2; i++) { val.InvokeRPC("RPC_AddOre", new object[1] { prefabName }); } return num2; } private static bool EnsureItemOwnership(ItemDrop item) { ZNetView component = ((Component)item).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } if (!component.IsOwner()) { component.ClaimOwnership(); } return component.IsOwner(); } private static void RemoveFromGround(ItemDrop item, int amount) { for (int i = 0; i < amount; i++) { if (!((Object)(object)item != (Object)null)) { break; } if (item.m_itemData.m_stack <= 0) { break; } item.RemoveOne(); } } } internal static class RadiusDisplay { private enum StationKind { Smelter, Kiln, BlastFurnace, StoneOven } private sealed class Circle { internal GameObject Marker { get; } internal CircleProjector Projector { get; } internal GameObject SegmentTemplate { get; } internal Color Color { get; set; } internal float Radius { get; set; } internal float VisibleUntil { get; set; } internal Circle(GameObject marker, CircleProjector projector, GameObject segmentTemplate, Color color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Marker = marker; Projector = projector; SegmentTemplate = segmentTemplate; Color = color; Radius = -1f; } } private static readonly Dictionary<int, Circle> Circles = new Dictionary<int, Circle>(); private static readonly HashSet<int> Seen = new HashSet<int>(); private static bool _smeltersPersistent; private static bool _kilnsPersistent; private static bool _blastFurnacesPersistent; private static bool _stoneOvensPersistent; private static float _nextRefresh; private static GameObject? _segmentTemplateRoot; internal static bool ToggleSmelters() { return _smeltersPersistent = !_smeltersPersistent; } internal static bool ToggleKilns() { return _kilnsPersistent = !_kilnsPersistent; } internal static bool ToggleBlastFurnaces() { return _blastFurnacesPersistent = !_blastFurnacesPersistent; } internal static bool ToggleStoneOvens() { return _stoneOvensPersistent = !_stoneOvensPersistent; } internal static void Update() { if (Time.time < _nextRefresh) { return; } _nextRefresh = Time.time + 0.2f; HashSet<int> liveIds = new HashSet<int>(); foreach (Smelter item in SmelterFinder.FindAll()) { UpdateStation((Component)(object)item, StationKind.Smelter, _smeltersPersistent, liveIds); } foreach (Smelter item2 in SmelterFinder.FindAllKilns()) { UpdateStation((Component)(object)item2, StationKind.Kiln, _kilnsPersistent, liveIds); } foreach (Smelter item3 in SmelterFinder.FindAllBlastFurnaces()) { UpdateStation((Component)(object)item3, StationKind.BlastFurnace, _blastFurnacesPersistent, liveIds); } foreach (CookingStation item4 in SmelterFinder.FindAllStoneOvens()) { UpdateStation((Component)(object)item4, StationKind.StoneOven, _stoneOvensPersistent, liveIds); } ShowHoveredStation(); foreach (int item5 in Circles.Keys.Where((int id) => !liveIds.Contains(id)).ToList()) { Circle circle = Circles[item5]; if ((Object)(object)circle.Marker != (Object)null) { Object.Destroy((Object)(object)circle.Marker); } if ((Object)(object)circle.SegmentTemplate != (Object)null) { Object.Destroy((Object)(object)circle.SegmentTemplate); } Circles.Remove(item5); Seen.Remove(item5); } } private static void UpdateStation(Component station, StationKind kind, bool persistent, HashSet<int> liveIds) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)station).GetInstanceID(); liveIds.Add(instanceID); Circle orCreate = GetOrCreate(station, kind); if (orCreate != null) { if (Seen.Add(instanceID) && AutoProduktionPlugin.AutomatischeRadiusAnzeige.Value) { orCreate.VisibleUntil = Time.time + AutoProduktionPlugin.AutomatischeAnzeigeDauer.Value; } float num = Mathf.Clamp(GetRadius(kind), 2f, 50f); orCreate.Projector.m_radius = num; if (!Mathf.Approximately(orCreate.Radius, num)) { orCreate.Radius = num; AutoProduktionPlugin.LogInfo($"{GetName(kind)}-Kreis auf {num:0.##} m aktualisiert."); } Color color = GetColor(kind); if (orCreate.Color != color) { Recolor(orCreate.SegmentTemplate, color); Recolor(orCreate.Marker, color); orCreate.Color = color; AutoProduktionPlugin.LogInfo(GetName(kind) + "-Kreisfarbe auf #" + ColorUtility.ToHtmlStringRGB(color) + " aktualisiert."); } orCreate.Marker.SetActive(persistent || Time.time < orCreate.VisibleUntil); } } private static void ShowHoveredStation() { if (!AutoProduktionPlugin.AutomatischeRadiusAnzeige.Value || (Object)(object)Player.m_localPlayer == (Object)null) { return; } GameObject hoverObject = ((Humanoid)Player.m_localPlayer).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return; } Smelter componentInParent = hoverObject.GetComponentInParent<Smelter>(); if ((Object)(object)componentInParent != (Object)null) { if (SmelterFinder.IsNormalSmelter(componentInParent)) { ShowHovered((Component)(object)componentInParent, StationKind.Smelter); } else if (SmelterFinder.IsCharcoalKiln(componentInParent)) { ShowHovered((Component)(object)componentInParent, StationKind.Kiln); } else if (SmelterFinder.IsBlastFurnace(componentInParent)) { ShowHovered((Component)(object)componentInParent, StationKind.BlastFurnace); } } else { CookingStation componentInParent2 = hoverObject.GetComponentInParent<CookingStation>(); if ((Object)(object)componentInParent2 != (Object)null && SmelterFinder.IsStoneOven(componentInParent2)) { ShowHovered((Component)(object)componentInParent2, StationKind.StoneOven); } } } private static void ShowHovered(Component station, StationKind kind) { Circle orCreate = GetOrCreate(station, kind); if (orCreate != null) { float radius = Mathf.Clamp(GetRadius(kind), 2f, 50f); orCreate.Projector.m_radius = radius; orCreate.Radius = radius; orCreate.VisibleUntil = Time.time + AutoProduktionPlugin.AutomatischeAnzeigeDauer.Value; orCreate.Marker.SetActive(true); } } private static Circle? GetOrCreate(Component station, StationKind kind) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)station).GetInstanceID(); if (Circles.TryGetValue(instanceID, out Circle value) && (Object)(object)value.Marker != (Object)null) { return value; } GameObject val = FindNativeAreaMarker(); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(val, station.transform); ((Object)val2).name = GetName(kind) + "_Radius"; val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; CircleProjector component = val2.GetComponent<CircleProjector>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return null; } Color color = GetColor(kind); GameObject val3 = CreateSegmentTemplate(component.m_prefab, color, GetName(kind)); if ((Object)(object)val3 == (Object)null) { Object.Destroy((Object)(object)val2); return null; } component.m_prefab = val3; Recolor(val2, color); val2.SetActive(false); value = new Circle(val2, component, val3, color); Circles[instanceID] = value; AutoProduktionPlugin.LogInfo("Originaler Valheim-Radius fuer " + GetName(kind) + " mit Farbe #" + ColorUtility.ToHtmlStringRGB(color) + " erstellt."); return value; } private static GameObject? CreateSegmentTemplate(GameObject original, Color color, string stationName) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if ((Object)(object)original == (Object)null) { return null; } if ((Object)(object)_segmentTemplateRoot == (Object)null) { _segmentTemplateRoot = new GameObject("AutoProduktion_RadiusVorlagen"); Object.DontDestroyOnLoad((Object)(object)_segmentTemplateRoot); _segmentTemplateRoot.SetActive(false); } GameObject obj = Object.Instantiate<GameObject>(original, _segmentTemplateRoot.transform); ((Object)obj).name = stationName + "_FarbigesKreissegment"; Recolor(obj, color); return obj; } private static GameObject? FindNativeAreaMarker() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { return null; } GameObject prefab = instance.GetPrefab("piece_workbench"); CraftingStation val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CraftingStation>() : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.m_areaMarker; } private static float GetRadius(StationKind kind) { return kind switch { StationKind.Kiln => AutoProduktionPlugin.KohlenmeilerRadius.Value, StationKind.BlastFurnace => AutoProduktionPlugin.HochofenRadius.Value, StationKind.StoneOven => AutoProduktionPlugin.SteinofenRadius.Value, _ => AutoProduktionPlugin.SchmelzofenRadius.Value, }; } private static Color GetColor(StationKind kind) { //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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) return (Color)(kind switch { StationKind.Kiln => ParseColor(AutoProduktionPlugin.KohlenmeilerRadiusFarbe.Value, Color.white), StationKind.BlastFurnace => ParseColor(AutoProduktionPlugin.HochofenRadiusFarbe.Value, new Color(1f, 0.55f, 0f)), StationKind.StoneOven => ParseColor(AutoProduktionPlugin.SteinofenRadiusFarbe.Value, new Color(0f, 0.75f, 1f)), _ => ParseColor(AutoProduktionPlugin.SchmelzofenRadiusFarbe.Value, Color.red), }); } private static Color ParseColor(string configured, Color fallback) { //IL_0035: 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) string text = (configured ?? string.Empty).Trim(); if (!text.StartsWith("#")) { text = "#" + text; } Color result = default(Color); if (!ColorUtility.TryParseHtmlString(text, ref result)) { return fallback; } return result; } private static string GetName(StationKind kind) { return kind switch { StationKind.Kiln => "Kohlenmeiler", StationKind.BlastFurnace => "Hochofen", StationKind.StoneOven => "Steinofen", _ => "Schmelzofen", }; } private static void Recolor(GameObject marker, Color color) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)marker == (Object)null) { return; } Renderer[] componentsInChildren = marker.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] materials = componentsInChildren[i].materials; foreach (Material val in materials) { val.color = color; if (val.HasProperty("_Color")) { val.SetColor("_Color", color); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", color); } if (val.HasProperty("_TintColor")) { val.SetColor("_TintColor", color); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", color); } } } ParticleSystem[] componentsInChildren2 = marker.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { MainModule main = componentsInChildren2[i].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(color); } Light[] componentsInChildren3 = marker.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].color = color; } } } internal static class RadiusHotkeys { internal static KeyboardShortcut Default(KeyCode functionKey) { //IL_0000: 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) return new KeyboardShortcut(functionKey, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }); } internal static bool IsDown(KeyboardShortcut shortcut) { //IL_0008: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected I4, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !UnityInput.Current.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return false; } if (((KeyboardShortcut)(ref shortcut)).IsDown()) { return true; } if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 304 || (int)((KeyboardShortcut)(ref shortcut)).MainKey == 303) { return false; } KeyCode[] array = ((KeyboardShortcut)(ref shortcut)).Modifiers.ToArray(); bool flag = array.Contains((KeyCode)304); bool flag2 = array.Contains((KeyCode)303); if (flag == flag2) { return false; } KeyCode configuredShift = (KeyCode)(flag ? 304 : 303); KeyCode otherShift = (KeyCode)(flag ? 303 : 304); KeyCode[] array2 = array.Select((KeyCode key) => (key != configuredShift) ? key : otherShift).ToArray(); KeyboardShortcut val = new KeyboardShortcut(((KeyboardShortcut)(ref shortcut)).MainKey, array2); if (!((KeyboardShortcut)(ref val)).IsDown()) { val = new KeyboardShortcut(((KeyboardShortcut)(ref shortcut)).MainKey, array.Concat((IEnumerable<KeyCode>)(object)new KeyCode[1] { (KeyCode)(int)otherShift }).ToArray()); return ((KeyboardShortcut)(ref val)).IsDown(); } return true; } internal static int MigrateLegacyDefaults(ConfigFile config, ConfigEntry<KeyboardShortcut> smelter, ConfigEntry<KeyboardShortcut> kiln, ConfigEntry<KeyboardShortcut> blastFurnace, ConfigEntry<KeyboardShortcut> stoneOven) { ConfigEntry<int> val = config.Bind<int>("Intern", "HotkeySchemaVersion", 0, "Interne einmalige Umstellung der alten Standardtasten. Nicht manuell aendern."); if (val.Value >= 1) { return 0; } bool saveOnConfigSet = config.SaveOnConfigSet; config.SaveOnConfigSet = false; int result; try { result = MigrateEntry(smelter, (KeyCode)289, (KeyCode)282) + MigrateEntry(kiln, (KeyCode)290, (KeyCode)283) + MigrateEntry(blastFurnace, (KeyCode)291, (KeyCode)284) + MigrateEntry(stoneOven, (KeyCode)292, (KeyCode)285); val.Value = 1; } finally { config.SaveOnConfigSet = saveOnConfigSet; } config.Save(); return result; } private static int MigrateEntry(ConfigEntry<KeyboardShortcut> entry, KeyCode previous, KeyCode next) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0029: 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) if (!((object)entry.Value/*cast due to .constrained prefix*/).Equals((object)new KeyboardShortcut(previous, Array.Empty<KeyCode>()))) { return 0; } entry.Value = Default(next); return 1; } } internal static class SmelterFinder { internal static List<Smelter> FindAll() { return Object.FindObjectsByType<Smelter>((FindObjectsSortMode)0).Where(IsNormalSmelter).ToList(); } internal static List<Smelter> FindAllKilns() { return Object.FindObjectsByType<Smelter>((FindObjectsSortMode)0).Where(IsCharcoalKiln).ToList(); } internal static List<Smelter> FindAllBlastFurnaces() { return Object.FindObjectsByType<Smelter>((FindObjectsSortMode)0).Where(IsBlastFurnace).ToList(); } internal static List<CookingStation> FindAllStoneOvens() { return Object.FindObjectsByType<CookingStation>((FindObjectsSortMode)0).Where(IsStoneOven).ToList(); } internal static bool IsNormalSmelter(Smelter station) { if ((Object)(object)station == (Object)null) { return false; } return string.Equals(CleanName(((Object)((Component)station).gameObject).name), "smelter", StringComparison.OrdinalIgnoreCase); } internal static bool IsCharcoalKiln(Smelter station) { if ((Object)(object)station == (Object)null) { return false; } return string.Equals(CleanName(((Object)((Component)station).gameObject).name), "charcoal_kiln", StringComparison.OrdinalIgnoreCase); } internal static bool IsBlastFurnace(Smelter station) { if ((Object)(object)station != (Object)null) { return HasPrefabName(((Component)station).transform, "blastfurnace", "blast_furnace"); } return false; } internal static bool IsStoneOven(CookingStation station) { if ((Object)(object)station != (Object)null) { return HasPrefabName(((Component)station).transform, "piece_oven"); } return false; } private static bool HasPrefabName(Transform start, params string[] acceptedNames) { Transform val = start; while ((Object)(object)val != (Object)null) { string currentName = CleanName(((Object)((Component)val).gameObject).name); if (acceptedNames.Any((string name) => string.Equals(currentName, name, StringComparison.OrdinalIgnoreCase))) { return true; } val = val.parent; } return false; } internal static string CleanName(string name) { return (name ?? string.Empty).Replace("(Clone)", string.Empty).Trim(); } internal static float HorizontalDistance(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = a.x - b.x; float num2 = a.z - b.z; return Mathf.Sqrt(num * num + num2 * num2); } } internal static class StoneOvenCollector { private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo NetworkViewField = typeof(CookingStation).GetField("m_nview", PrivateInstance); private static readonly MethodInfo GetFuelMethod = typeof(CookingStation).GetMethod("GetFuel", PrivateInstance); internal static void Scan() { float radius = Mathf.Clamp(AutoProduktionPlugin.SteinofenRadius.Value, 2f, 50f); List<CookingStation> list = SmelterFinder.FindAllStoneOvens(); if (list.Count == 0) { return; } ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0); foreach (ItemDrop item in array) { if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_stack <= 0 || !EnsureItemOwnership(item)) { continue; } foreach (CookingStation item2 in (from station in list where SmelterFinder.HorizontalDistance(((Component)item).transform.position, ((Component)station).transform.position) <= radius orderby SmelterFinder.HorizontalDistance(((Component)item).transform.position, ((Component)station).transform.position) select station).ToList()) { int num; string arg; if (item2.m_useFuel && Matches(item2.m_fuelItem, item)) { num = InsertFuel(item2, item.m_itemData.m_stack); arg = "Holz"; } else { string text = FindAcceptedInput(item2, item); if (text == null) { continue; } num = InsertFood(item2, text, item.m_itemData.m_stack); arg = text; } if (num > 0) { AutoProduktionPlugin.LogDiagnostic($"{num}x {arg} vom Boden in Steinofen eingefuellt."); RemoveFromGround(item, num); if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_stack <= 0) { break; } } } } } private static string? FindAcceptedInput(CookingStation oven, ItemDrop item) { if (oven.m_conversion == null) { return null; } foreach (ItemConversion item2 in oven.m_conversion) { if ((Object)(object)item2?.m_from != (Object)null && Matches(item2.m_from, item)) { return SmelterFinder.CleanName(((Object)((Component)item2.m_from).gameObject).name); } } return null; } private static bool Matches(ItemDrop accepted, ItemDrop groundItem) { if ((Object)(object)accepted == (Object)null || accepted.m_itemData == null || (Object)(object)groundItem == (Object)null || groundItem.m_itemData == null) { return false; } GameObject dropPrefab = groundItem.m_itemData.m_dropPrefab; string a = SmelterFinder.CleanName(((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? ((Object)((Component)groundItem).gameObject).name); string b = SmelterFinder.CleanName(((Object)((Component)accepted).gameObject).name); string a2 = groundItem.m_itemData.m_shared?.m_name ?? string.Empty; string b2 = accepted.m_itemData.m_shared?.m_name ?? string.Empty; if (!string.Equals(a, b, StringComparison.OrdinalIgnoreCase)) { return string.Equals(a2, b2, StringComparison.OrdinalIgnoreCase); } return true; } private static int InsertFuel(CookingStation oven, int available) { ZNetView networkView = GetNetworkView(oven); if (available <= 0 || (Object)(object)networkView == (Object)null || oven.m_maxFuel <= 0) { return 0; } float num = (float)(GetFuelMethod.Invoke(oven, null) ?? ((object)0f)); int val = Math.Max(0, oven.m_maxFuel - Mathf.CeilToInt(num)); int num2 = Math.Min(available, val); for (int i = 0; i < num2; i++) { networkView.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } return num2; } private static int InsertFood(CookingStation oven, string prefabName, int available) { ZNetView networkView = GetNetworkView(oven); if (available <= 0 || (Object)(object)networkView == (Object)null || oven.m_slots == null) { return 0; } int num = 0; for (int i = 0; i < oven.m_slots.Length; i++) { if (string.IsNullOrEmpty(networkView.GetZDO().GetString("slot" + i, ""))) { num++; } } int num2 = Math.Min(available, num); for (int j = 0; j < num2; j++) { networkView.InvokeRPC("RPC_AddItem", new object[1] { prefabName }); } return num2; } private static ZNetView? GetNetworkView(CookingStation oven) { object? value = NetworkViewField.GetValue(oven); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); if (!((Object)(object)val != (Object)null) || !val.IsValid()) { return null; } return val; } private static bool EnsureItemOwnership(ItemDrop item) { ZNetView component = ((Component)item).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } if (!component.IsOwner()) { component.ClaimOwnership(); } return component.IsOwner(); } private static void RemoveFromGround(ItemDrop item, int amount) { for (int i = 0; i < amount; i++) { if (!((Object)(object)item != (Object)null)) { break; } if (item.m_itemData.m_stack <= 0) { break; } item.RemoveOne(); } } } internal static class WoodCollector { private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo NetworkViewField = typeof(Smelter).GetField("m_nview", PrivateInstance); private static readonly MethodInfo GetQueueSizeMethod = typeof(Smelter).GetMethod("GetQueueSize", PrivateInstance); private static readonly MethodInfo QueueOreMethod = typeof(Smelter).GetMethod("QueueOre", PrivateInstance); internal static void Scan() { float radius = Mathf.Clamp(AutoProduktionPlugin.KohlenmeilerRadius.Value, 2f, 50f); List<Smelter> list = SmelterFinder.FindAllKilns(); if (list.Count == 0) { return; } ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0); foreach (ItemDrop item in array) { if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_stack <= 0 || !EnsureItemOwnership(item)) { continue; } foreach (Smelter item2 in (from station in list where SmelterFinder.HorizontalDistance(((Component)item).transform.position, ((Component)station).transform.position) <= radius orderby SmelterFinder.HorizontalDistance(((Component)item).transform.position, ((Component)station).transform.position) select station).ToList()) { string text = FindAcceptedInput(item2, item); if (text == null) { continue; } int num = InsertWood(item2, text, item.m_itemData.m_stack); if (num > 0) { AutoProduktionPlugin.LogDiagnostic($"{num}x {text} vom Boden in Kohlenmeiler eingefuellt."); RemoveFromGround(item, num); if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_stack <= 0) { break; } } } } } private static string? FindAcceptedInput(Smelter kiln, ItemDrop item) { if (kiln.m_conversion == null) { return null; } GameObject dropPrefab = item.m_itemData.m_dropPrefab; string a = SmelterFinder.CleanName(((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? ((Object)((Component)item).gameObject).name); string a2 = item.m_itemData.m_shared?.m_name ?? string.Empty; foreach (ItemConversion item2 in kiln.m_conversion) { if (!((Object)(object)item2?.m_from == (Object)null)) { string text = SmelterFinder.CleanName(((Object)((Component)item2.m_from).gameObject).name); string b = item2.m_from.m_itemData?.m_shared?.m_name ?? string.Empty; if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase) || string.Equals(a2, b, StringComparison.OrdinalIgnoreCase)) { return text; } } } return null; } private static int InsertWood(Smelter kiln, string prefabName, int available) { if (available <= 0 || !EnsureKilnOwnership(kiln)) { return 0; } int num = (int)(GetQueueSizeMethod.Invoke(kiln, null) ?? ((object)0)); int val = Math.Max(0, kiln.m_maxOre - num); int num2 = Math.Min(available, val); for (int i = 0; i < num2; i++) { QueueOreMethod.Invoke(kiln, new object[1] { prefabName }); } return num2; } private static bool EnsureItemOwnership(ItemDrop item) { ZNetView component = ((Component)item).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } if (!component.IsOwner()) { component.ClaimOwnership(); } return component.IsOwner(); } private static bool EnsureKilnOwnership(Smelter kiln) { object? value = NetworkViewField.GetValue(kiln); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { return false; } if (!val.IsOwner()) { val.ClaimOwnership(); } return val.IsOwner(); } private static void RemoveFromGround(ItemDrop item, int amount) { for (int i = 0; i < amount; i++) { if (!((Object)(object)item != (Object)null)) { break; } if (item.m_itemData.m_stack <= 0) { break; } item.RemoveOne(); } } } }