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.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 Aktiviert { get; private set; } internal static ConfigEntry SchmelzofenRadius { get; private set; } internal static ConfigEntry SchmelzofenErzeAufnehmen { get; private set; } internal static ConfigEntry KohlenmeilerRadius { get; private set; } internal static ConfigEntry HochofenRadius { get; private set; } internal static ConfigEntry HochofenRohstoffeAufnehmen { get; private set; } internal static ConfigEntry SteinofenRadius { get; private set; } internal static ConfigEntry SteinofenRohstoffeAufnehmen { get; private set; } internal static ConfigEntry SchmelzofenRadiusTaste { get; private set; } internal static ConfigEntry KohlenmeilerRadiusTaste { get; private set; } internal static ConfigEntry HochofenRadiusTaste { get; private set; } internal static ConfigEntry SteinofenRadiusTaste { get; private set; } internal static ConfigEntry SchmelzofenRadiusFarbe { get; private set; } internal static ConfigEntry KohlenmeilerRadiusFarbe { get; private set; } internal static ConfigEntry HochofenRadiusFarbe { get; private set; } internal static ConfigEntry SteinofenRadiusFarbe { get; private set; } internal static ConfigEntry AutomatischeRadiusAnzeige { get; private set; } internal static ConfigEntry AutomatischeAnzeigeDauer { get; private set; } internal static ConfigEntry Pruefintervall { get; private set; } internal static ConfigEntry 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("Allgemein", "Aktiviert", true, "Schaltet die automatische Ressourcenaufnahme aller Anlagen ein oder aus."); SchmelzofenRadius = ((BaseUnityPlugin)this).Config.Bind("Schmelzofen", "Radius", 2.5f, new ConfigDescription("Kohle- und Erz-Aufnahmeradius des Schmelzofens in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 50f), Array.Empty())); SchmelzofenErzeAufnehmen = ((BaseUnityPlugin)this).Config.Bind("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("Kohlenmeiler", "Radius", 2.5f, new ConfigDescription("Holz-Aufnahmeradius des Kohlenmeilers in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 50f), Array.Empty())); HochofenRadius = ((BaseUnityPlugin)this).Config.Bind("Hochofen", "Radius", 2.5f, new ConfigDescription("Kohle- und Rohstoff-Aufnahmeradius des Hochofens in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 50f), Array.Empty())); HochofenRohstoffeAufnehmen = ((BaseUnityPlugin)this).Config.Bind("Hochofen", "RohstoffeVomBodenAufnehmen", true, "Nimmt Kohle und alle unverarbeiteten Materialien auf, die der Hochofen laut seinen Rezepten verarbeiten kann."); SteinofenRadius = ((BaseUnityPlugin)this).Config.Bind("Steinofen", "Radius", 2.5f, new ConfigDescription("Holz- und Zutaten-Aufnahmeradius des Steinofens in Metern.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 50f), Array.Empty())); SteinofenRohstoffeAufnehmen = ((BaseUnityPlugin)this).Config.Bind("Steinofen", "RohstoffeVomBodenAufnehmen", true, "Nimmt Holz und alle ungebackenen Speisen auf, die der Steinofen laut seinen Rezepten verarbeiten kann."); Pruefintervall = ((BaseUnityPlugin)this).Config.Bind("Allgemein", "PruefintervallSekunden", 0.25f, new ConfigDescription("Zeit zwischen zwei Suchlaeufen nach Ressourcen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 2f), Array.Empty())); SchmelzofenRadiusTaste = ((BaseUnityPlugin)this).Config.Bind("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("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("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("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("Anzeige", "SchmelzofenRadiusFarbe", "#FF0000", "Kreisfarbe als HTML-Farbwert, zum Beispiel #FF0000 fuer Rot."); KohlenmeilerRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind("Anzeige", "KohlenmeilerRadiusFarbe", "#FFFFFF", "Kreisfarbe als HTML-Farbwert, zum Beispiel #FFFFFF fuer Weiss."); HochofenRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind("Anzeige", "HochofenRadiusFarbe", "#FF8C00", "Kreisfarbe als HTML-Farbwert, Standard ist Orange."); SteinofenRadiusFarbe = ((BaseUnityPlugin)this).Config.Bind("Anzeige", "SteinofenRadiusFarbe", "#00BFFF", "Kreisfarbe als HTML-Farbwert, Standard ist Hellblau."); AutomatischeRadiusAnzeige = ((BaseUnityPlugin)this).Config.Bind("Anzeige", "AutomatischFuenfSekundenAnzeigen", true, "Zeigt den passenden Kreis automatisch bei neu erkannten oder angesehenen Anlagen."); AutomatischeAnzeigeDauer = ((BaseUnityPlugin)this).Config.Bind("Anzeige", "AutomatischeAnzeigedauerSekunden", 5f, new ConfigDescription("Dauer der automatischen Radiusanzeige.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); Diagnose = ((BaseUnityPlugin)this).Config.Bind("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 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((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()); } 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(); 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 list = new List(); 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((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(); 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 Circles = new Dictionary(); private static readonly HashSet Seen = new HashSet(); 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 liveIds = new HashSet(); 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 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(); 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(); 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(val, station.transform); ((Object)val2).name = GetName(kind) + "_Radius"; val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; CircleProjector component = val2.GetComponent(); 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(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() : 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(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(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(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)(object)new KeyCode[1] { (KeyCode)(int)otherShift }).ToArray()); return ((KeyboardShortcut)(ref val)).IsDown(); } return true; } internal static int MigrateLegacyDefaults(ConfigFile config, ConfigEntry smelter, ConfigEntry kiln, ConfigEntry blastFurnace, ConfigEntry stoneOven) { ConfigEntry val = config.Bind("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 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()))) { return 0; } entry.Value = Default(next); return 1; } } internal static class SmelterFinder { internal static List FindAll() { return Object.FindObjectsByType((FindObjectsSortMode)0).Where(IsNormalSmelter).ToList(); } internal static List FindAllKilns() { return Object.FindObjectsByType((FindObjectsSortMode)0).Where(IsCharcoalKiln).ToList(); } internal static List FindAllBlastFurnaces() { return Object.FindObjectsByType((FindObjectsSortMode)0).Where(IsBlastFurnace).ToList(); } internal static List FindAllStoneOvens() { return Object.FindObjectsByType((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 list = SmelterFinder.FindAllStoneOvens(); if (list.Count == 0) { return; } ItemDrop[] array = Object.FindObjectsByType((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()); } 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(); 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 list = SmelterFinder.FindAllKilns(); if (list.Count == 0) { return; } ItemDrop[] array = Object.FindObjectsByType((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(); 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(); } } } }