using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Ewigschlag")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Ewigschlag")] [assembly: AssemblyTitle("Ewigschlag")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GoblinStudio.Ewigschlag { [BepInPlugin("GoblinStudio.Ewigschlag", "Ewigschlag", "0.1.0")] [BepInDependency("blacks7ar.FineWoodPieces", "1.6.5")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyAfter(new string[] { "blacks7ar.FineWoodPieces", "org.bepinex.helpers.ItemManager", "org.bepinex.helpers.PieceManager" })] private static class ObjectDBInitPatch { private static void Postfix(ObjectDB __instance) { TryInitialize(__instance); LogObjectDbState("ObjectDB.Awake/Postfix", __instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyAfter(new string[] { "blacks7ar.FineWoodPieces", "org.bepinex.helpers.ItemManager", "org.bepinex.helpers.PieceManager" })] private static class ObjectDbCopyDiagnosticPatch { private static void Postfix(ObjectDB __instance, ObjectDB __0) { LogObjectDbState("ObjectDB.CopyOtherDB/Postfix", __instance, __0); } } [HarmonyPatch(typeof(Player), "Awake")] private static class PlayerAwakePatch { private static void Postfix(Player __instance) { LogObjectDbState("Player.Awake", ObjectDB.instance); } } [HarmonyPatch(typeof(Player), "Load")] private static class PlayerLoadPatch { private static void Postfix(Player __instance) { RefreshKnownRecipes(__instance); } } [HarmonyPatch(typeof(InventoryGui), "SetupCrafting")] private static class CraftingVisibilityDiagnosticPatch { private static void Postfix() { LogObjectDbState("InventoryGui.SetupCrafting", ObjectDB.instance); if (!visibilityDiagnosticLogged && initialized && !((Object)(object)Player.m_localPlayer == (Object)null)) { visibilityDiagnosticLogged = true; DiagnoseCraftingVisibility(Player.m_localPlayer); } } } private sealed class PieceCollector { private readonly HashSet references = new HashSet(ReferenceEqualityComparer.Instance); private readonly Dictionary names = new Dictionary(StringComparer.Ordinal); public List Pieces { get; } = new List(); public int ReferenceDuplicates { get; private set; } public int NameDuplicates { get; private set; } public int NameConflicts { get; private set; } public void AddTable(PieceTable table) { foreach (GameObject piece in table.m_pieces) { if ((Object)(object)piece == (Object)null) { continue; } GameObject value; if (references.Contains(piece)) { ReferenceDuplicates++; } else if (names.TryGetValue(((Object)piece).name, out value)) { NameDuplicates++; if (value != piece) { NameConflicts++; Debug.LogWarning((object)("Ewigschlag: Namenskonflikt bei Piece '" + ((Object)piece).name + "'; erste Referenz bleibt erhalten.")); } } else { references.Add(piece); names.Add(((Object)piece).name, piece); Pieces.Add(piece); } } } } private sealed class ReferenceEqualityComparer : IEqualityComparer where T : class { public static readonly ReferenceEqualityComparer Instance = new ReferenceEqualityComparer(); public bool Equals(T x, T y) { return x == y; } public int GetHashCode(T obj) { return RuntimeHelpers.GetHashCode(obj); } } public const string PluginGuid = "GoblinStudio.Ewigschlag"; public const string PluginName = "Ewigschlag"; public const string PluginVersion = "0.1.0"; public const string FineWoodGuid = "blacks7ar.FineWoodPieces"; private const string VanillaHammerName = "Hammer"; private const string FineHammerName = "BFP_FineHammer"; private const string FineHammerTableName = "BFP_FineHammerPieceTable"; private const string EwigschlagName = "GoblinStudio_Ewigschlag"; private const string EwigschlagTableName = "GoblinStudio_EwigschlagPieceTable"; private const string EwigschlagBundleResourceName = "Ewigschlag.assets.ewigschlagbundle"; private const string EwigschlagPrefabAssetPath = "assets/generated/goblinstudio_ewigschlag.prefab"; private const string EwigschlagIconAssetPath = "assets/icons/everstrike_icon.png"; private static bool initialized; private static bool initializationInProgress; private static bool earlyLifecycleLogged; private static bool knownRecipesRefreshPending; private static bool knownRecipesRefreshCompleted; private static bool visibilityDiagnosticLogged; private static bool ewigschlagBundleLoadAttempted; private static AssetBundle ewigschlagBundle; private static GameObject ewigschlagAssetPrefab; private static ManualLogSource Log; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; new Harmony("GoblinStudio.Ewigschlag").PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Ewigschlag 0.1.0 geladen; Initialisierung wird nach ObjectDB.Awake versucht."); } private static void LogObjectDbState(string phase, ObjectDB concreteInstance, ObjectDB sourceInstance = null) { ObjectDB instance = ObjectDB.instance; bool value = (Object)(object)instance != (Object)null; bool num = (Object)(object)concreteInstance != (Object)null; int num2 = ((num && concreteInstance.m_recipes != null) ? concreteInstance.m_recipes.Count : (-1)); int num3 = ((num && concreteInstance.m_items != null) ? concreteInstance.m_items.Count : (-1)); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("Instanzdiagnose: Phase=" + phase + "; ObjectDB.instance != null=" + YesNo(value) + "; activeInstanceID=" + InstanceId(instance) + "; concreteInstanceID=" + InstanceId(concreteInstance) + "; m_recipes.Count=" + num2 + "; Ewigschlag-Rezept=" + YesNo(ContainsEwigschlagRecipe(concreteInstance)) + "; m_items.Count=" + num3 + "; Ewigschlag-Item=" + YesNo(ContainsEwigschlagItem(concreteInstance)) + (((Object)(object)sourceInstance == (Object)null) ? string.Empty : ("; sourceInstanceID=" + InstanceId(sourceInstance))) + ".")); } } private static string InstanceId(ObjectDB objectDb) { if (!((Object)(object)objectDb == (Object)null)) { return ((Object)objectDb).GetInstanceID().ToString(); } return ""; } private static string YesNo(bool value) { if (!value) { return "nein"; } return "ja"; } private static bool ContainsEwigschlagRecipe(ObjectDB objectDb) { if ((Object)(object)objectDb == (Object)null || objectDb.m_recipes == null) { return false; } foreach (Recipe recipe in objectDb.m_recipes) { if (recipe?.m_item?.m_itemData?.m_shared?.m_name == "$item_goblinstudio_ewigschlag") { return true; } } return false; } private static bool ContainsEwigschlagItem(ObjectDB objectDb) { if ((Object)(object)objectDb == (Object)null || objectDb.m_items == null) { return false; } foreach (GameObject item in objectDb.m_items) { if ((Object)(object)item != (Object)null && ((Object)item).name == "GoblinStudio_Ewigschlag") { return true; } } return false; } private static bool TryLoadEwigschlagPrefab(out GameObject prefab) { prefab = ewigschlagAssetPrefab; if ((Object)(object)prefab != (Object)null) { return true; } if (ewigschlagBundleLoadAttempted) { return false; } ewigschlagBundleLoadAttempted = true; try { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ewigschlag.assets.ewigschlagbundle")) { if (stream == null) { throw new FileNotFoundException("EmbeddedResource nicht gefunden.", "Ewigschlag.assets.ewigschlagbundle"); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); byte[] array = memoryStream.ToArray(); if (array.Length == 0) { throw new InvalidDataException("EmbeddedResource ist leer."); } ewigschlagBundle = AssetBundle.LoadFromMemory(array); } if ((Object)(object)ewigschlagBundle == (Object)null) { throw new InvalidDataException("AssetBundle konnte nicht aus dem EmbeddedResource geladen werden."); } ewigschlagAssetPrefab = ewigschlagBundle.LoadAsset("assets/generated/goblinstudio_ewigschlag.prefab"); if ((Object)(object)ewigschlagAssetPrefab == (Object)null || ((Object)ewigschlagAssetPrefab).name != "GoblinStudio_Ewigschlag") { throw new InvalidDataException("Ewigschlag-Prefab konnte unter dem erwarteten Assetpfad nicht geladen werden."); } ItemDrop component = ewigschlagAssetPrefab.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { throw new InvalidDataException("Ewigschlag-Prefab enthaelt keine gueltige ItemDrop/ItemData/SharedData-Struktur."); } prefab = ewigschlagAssetPrefab; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Ewigschlag AssetBundle geladen; Prefab geladen; Prefab Unity-gueltig; ItemDrop gueltig; ItemData vorhanden; SharedData vorhanden; Asset-Prefab nicht ueber Instantiate(Hammer) erzeugt."); } return true; } catch (Exception ex) { if ((Object)(object)ewigschlagBundle != (Object)null) { ewigschlagBundle.Unload(false); } ewigschlagBundle = null; ewigschlagAssetPrefab = null; prefab = null; LogFailClosed("Ewigschlag AssetBundle/Prefab konnte nicht geladen werden: " + ex.Message); return false; } } private static void ConfigureEwigschlagItemData(GameObject itemPrefab, ItemDrop itemDrop, ItemDrop vanillaHammer, PieceTable combinedTable) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) if ((Object)(object)itemPrefab == (Object)null || (Object)(object)itemDrop == (Object)null || itemDrop.m_itemData == null || itemDrop.m_itemData.m_shared == null || (Object)(object)vanillaHammer == (Object)null || vanillaHammer.m_itemData == null || vanillaHammer.m_itemData.m_shared == null || (Object)(object)combinedTable == (Object)null) { throw new InvalidDataException("Ewigschlag-Itemdaten konnten nicht sicher konfiguriert werden."); } SharedData shared = itemDrop.m_itemData.m_shared; SharedData shared2 = vanillaHammer.m_itemData.m_shared; shared.m_itemType = (ItemType)19; shared.m_name = "$item_goblinstudio_ewigschlag"; shared.m_description = "$item_goblinstudio_ewigschlag_description"; Sprite val = ewigschlagBundle.LoadAsset("assets/icons/everstrike_icon.png"); if ((Object)(object)val == (Object)null) { throw new InvalidDataException("Everstrike-Icon konnte nicht aus dem Embedded Bundle geladen werden."); } shared.m_icons = (Sprite[])(object)new Sprite[1] { val }; shared.m_equipDuration = shared2.m_equipDuration; shared.m_animationState = shared2.m_animationState; shared.m_attack.m_attackAnimation = shared2.m_attack.m_attackAnimation; shared.m_toolTier = shared2.m_toolTier; shared.m_centerCamera = shared2.m_centerCamera; shared.m_buildPieces = combinedTable; shared.m_useDurability = false; shared.m_useDurabilityDrain = 0f; shared.m_destroyBroken = false; itemDrop.m_itemData.m_dropPrefab = itemPrefab; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Ewigschlag-Itemdaten konfiguriert; ItemType=Tool; Vanilla-Animation und Icon uebernommen; eigene SharedData bleibt erhalten; PieceTable=GoblinStudio_EwigschlagPieceTable; Haltbarkeit deaktiviert."); } } private static void TryInitialize(ObjectDB objectDb) { if (initialized || initializationInProgress) { return; } if ((Object)(object)objectDb == (Object)null) { LogFailClosed("Die aktuelle ObjectDB-Instanz ist ungueltig."); return; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { if (!earlyLifecycleLogged) { earlyLifecycleLogged = true; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Ewigschlag Initialisierung noch nicht bereit; warte auf eine spaetere ObjectDB-Instanz."); } } return; } GameObject itemPrefab = objectDb.GetItemPrefab("Hammer"); GameObject itemPrefab2 = objectDb.GetItemPrefab("BFP_FineHammer"); GameObject prefab = instance.GetPrefab("BFP_FineHammerPieceTable"); if ((Object)(object)itemPrefab == (Object)null) { LogFailClosed("Vanilla-Hammer 'Hammer' nicht gefunden."); return; } if ((Object)(object)itemPrefab2 == (Object)null) { LogFailClosed("FineHammer 'BFP_FineHammer' nicht gefunden."); return; } if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent() == (Object)null) { LogFailClosed("FineHammer-PieceTable 'BFP_FineHammerPieceTable' nicht gefunden oder ungueltig."); return; } ItemDrop component = itemPrefab.GetComponent(); ItemDrop component2 = itemPrefab2.GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null || component2.m_itemData == null || component2.m_itemData.m_shared == null) { LogFailClosed("Hammer-ItemData konnte nicht gelesen werden."); return; } PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces; PieceTable buildPieces2 = component2.m_itemData.m_shared.m_buildPieces; PieceTable component3 = prefab.GetComponent(); if ((Object)(object)buildPieces == (Object)null) { LogFailClosed("Vanilla-PieceTable fehlt."); return; } if ((Object)(object)buildPieces2 == (Object)null) { LogFailClosed("FineHammer-PieceTable fehlt."); return; } if ((Object)(object)component3 == (Object)null) { LogFailClosed("Registrierte FineHammer-PieceTable fehlt."); return; } if (buildPieces.m_pieces == null || buildPieces.m_pieces.Count == 0) { LogFailClosed("Vanilla-PieceTable ist noch nicht befuellt."); return; } if (buildPieces2.m_pieces == null || buildPieces2.m_pieces.Count == 0) { LogFailClosed("FineHammer-PieceTable ist noch nicht befuellt."); return; } if (buildPieces2 != component3) { LogFailClosed("BFP_FineHammer verweist nicht auf die registrierte FineHammer-PieceTable."); return; } ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("Vanilla-Hammer gefunden: " + buildPieces.m_pieces.Count + " Pieces.")); } ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)("FineHammer gefunden: " + buildPieces2.m_pieces.Count + " Pieces.")); } initializationInProgress = true; GameObject val = null; GameObject prefab2 = null; bool flag = false; try { val = Object.Instantiate(((Component)buildPieces).gameObject); ((Object)val).name = "GoblinStudio_EwigschlagPieceTable"; PieceTable component4 = val.GetComponent(); if ((Object)(object)component4 == (Object)null) { LogFailClosed("Eigene PieceTable konnte nicht erzeugt werden."); Object.Destroy((Object)(object)val); return; } Object.DontDestroyOnLoad((Object)(object)val); CopyTableMetadata(buildPieces, buildPieces2, component4); PieceCollector pieceCollector = new PieceCollector(); pieceCollector.AddTable(buildPieces); pieceCollector.AddTable(buildPieces2); component4.m_pieces = pieceCollector.Pieces; if (!TryLoadEwigschlagPrefab(out prefab2)) { Object.Destroy((Object)(object)val); return; } ItemDrop component5 = prefab2.GetComponent(); if ((Object)(object)component5 == (Object)null || component5.m_itemData == null || component5.m_itemData.m_shared == null) { LogFailClosed("Geladenes Ewigschlag-AssetPrefab ist unvollstaendig."); Object.Destroy((Object)(object)val); return; } if (component5.m_itemData == component.m_itemData || component5.m_itemData.m_shared == component.m_itemData.m_shared) { LogFailClosed("Das technische ItemPrefab teilt ItemData oder SharedData mit dem Vanilla-Hammer."); Object.Destroy((Object)(object)val); return; } ConfigureEwigschlagItemData(prefab2, component5, component, component4); if (!objectDb.m_items.Contains(prefab2)) { objectDb.m_items.Add(prefab2); flag = true; ManualLogSource log4 = Log; if (log4 != null) { log4.LogInfo((object)"Ewigschlag zu ObjectDB.m_items hinzugefuegt."); } } UpdateObjectDbRegisters(objectDb); ManualLogSource log5 = Log; if (log5 != null) { log5.LogInfo((object)"ObjectDB.UpdateRegisters() ausgefuehrt."); } GameObject itemPrefab3 = objectDb.GetItemPrefab("GoblinStudio_Ewigschlag"); ItemDrop val2 = (((Object)(object)itemPrefab3 == (Object)null) ? null : itemPrefab3.GetComponent()); if (itemPrefab3 != prefab2 || val2 != component5) { LogFailClosed("Ewigschlag nach ObjectDB.UpdateRegisters() nicht ueber ObjectDB auffindbar."); if (flag) { RemoveObjectDbItem(objectDb, prefab2); } Object.Destroy((Object)(object)val); return; } ManualLogSource log6 = Log; if (log6 != null) { log6.LogInfo((object)"Ewigschlag nach Registerupdate ueber ObjectDB auffindbar: ja."); } if (!AddLocalization()) { LogFailClosed("Localization-Registrierung fehlgeschlagen."); if (flag) { RemoveObjectDbItem(objectDb, prefab2); } Object.Destroy((Object)(object)val); return; } ManualLogSource log7 = Log; if (log7 != null) { log7.LogInfo((object)"Localization erfolgreich registriert."); } if (!AddRecipe(objectDb, prefab2)) { LogFailClosed("Rezeptregistrierung fehlgeschlagen."); if (flag) { RemoveObjectDbItem(objectDb, prefab2); } Object.Destroy((Object)(object)val); return; } ManualLogSource log8 = Log; if (log8 != null) { log8.LogInfo((object)("Ewigschlag Piece-Anzahl: " + pieceCollector.Pieces.Count + "; Referenzduplikate: " + pieceCollector.ReferenceDuplicates + "; Namensduplikate: " + pieceCollector.NameDuplicates + "; Namenskonflikte: " + pieceCollector.NameConflicts + ".")); } ManualLogSource log9 = Log; if (log9 != null) { log9.LogInfo((object)"GoblinStudio_EwigschlagPieceTable erfolgreich; Originaltabellen wurden nur gelesen."); } ManualLogSource log10 = Log; if (log10 != null) { log10.LogInfo((object)"Ewigschlag registriert; Haltbarkeit deaktiviert."); } initialized = true; knownRecipesRefreshPending = true; if ((Object)(object)Player.m_localPlayer != (Object)null) { ManualLogSource log11 = Log; if (log11 != null) { log11.LogInfo((object)"Lokaler Player bereits vorhanden: ja."); } RefreshKnownRecipes(Player.m_localPlayer); return; } ManualLogSource log12 = Log; if (log12 != null) { log12.LogInfo((object)"Lokaler Player bereits vorhanden: nein."); } ManualLogSource log13 = Log; if (log13 != null) { log13.LogInfo((object)"KnownRecipe-Registrierung fuer Player.Load vorgemerkt."); } } catch (Exception ex) { if (flag) { RemoveObjectDbItem(objectDb, prefab2); } if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } LogFailClosed("Ausnahme waehrend der Initialisierung: " + ex); } finally { initializationInProgress = false; } } private static void RefreshKnownRecipes(Player player) { if (!initialized || !knownRecipesRefreshPending || knownRecipesRefreshCompleted || (Object)(object)player == (Object)null) { return; } try { if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer != player) { return; } Recipe val = FindEwigschlagRecipe(ObjectDB.instance); string text = val?.m_item?.m_itemData?.m_shared?.m_name; if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(text)) { throw new InvalidOperationException("Ewigschlag-Rezept ist fuer KnownRecipe-Registrierung nicht verfuegbar."); } FieldInfo field = typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.NonPublic); if (field?.GetValue(player) is HashSet hashSet && hashSet.Contains(text)) { knownRecipesRefreshPending = false; knownRecipesRefreshCompleted = true; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("KnownRecipe bereits vorhanden: " + text + ".")); } return; } MethodInfo? method = typeof(Player).GetMethod("AddKnownRecipe", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { throw new MissingMethodException(typeof(Player).FullName, "AddKnownRecipe"); } method.Invoke(player, new object[1] { val }); if (!(field?.GetValue(player) is HashSet hashSet2) || !hashSet2.Contains(text)) { throw new InvalidOperationException("Vanilla AddKnownRecipe hat den Ewigschlag-Schluessel nicht registriert."); } knownRecipesRefreshPending = false; knownRecipesRefreshCompleted = true; ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("KnownRecipe ueber Vanilla AddKnownRecipe registriert: " + text + ".")); } } catch (Exception ex) { LogFailClosed("KnownRecipes-Refresh fehlgeschlagen: " + ex); } } private static Recipe FindEwigschlagRecipe(ObjectDB objectDb) { if ((Object)(object)objectDb == (Object)null || objectDb.m_recipes == null) { return null; } foreach (Recipe recipe in objectDb.m_recipes) { if (recipe?.m_item?.m_itemData?.m_shared?.m_name == "$item_goblinstudio_ewigschlag") { return recipe; } } return null; } private static void DiagnoseCraftingVisibility(Player player) { try { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_recipes == null) { ManualLogSource log = Log; if (log != null) { log.LogError((object)"Sichtbarkeitsdiagnose: ObjectDB oder Rezeptliste fehlt."); } return; } GameObject itemPrefab = instance.GetItemPrefab("GoblinStudio_Ewigschlag"); ItemDrop val = (((Object)(object)itemPrefab == (Object)null) ? null : itemPrefab.GetComponent()); string text = val?.m_itemData?.m_shared?.m_name; Recipe val2 = null; if (!string.IsNullOrEmpty(text)) { foreach (Recipe recipe in instance.m_recipes) { if (recipe?.m_item?.m_itemData?.m_shared?.m_name == text) { val2 = recipe; break; } } } ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("Sichtbarkeitsdiagnose: Rezept in ObjectDB.m_recipes: " + (((Object)(object)val2 != (Object)null) ? "ja" : "nein") + ".")); } if ((Object)(object)val2 == (Object)null || (Object)(object)val == (Object)null) { return; } string text2 = (((Object)(object)val2.m_craftingStation == (Object)null) ? "" : val2.m_craftingStation.m_name); ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)("Sichtbarkeitsdiagnose: m_enabled=" + val2.m_enabled + "; m_item gueltig=" + ((Object)(object)val2.m_item != (Object)null) + "; CraftingStation gueltig=" + ((Object)(object)val2.m_craftingStation != (Object)null) + "; erwartete Station=piece_workbench; tatsaechliche Station=" + text2 + "; Mindestlevel=" + val2.m_minStationLevel + ".")); } ManualLogSource log4 = Log; if (log4 != null) { log4.LogInfo((object)("Sichtbarkeitsdiagnose: Recipe-Key=" + text + ".")); } FieldInfo? field = typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = typeof(Player).GetField("m_knownMaterial", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field3 = typeof(Player).GetField("m_knownStations", BindingFlags.Instance | BindingFlags.NonPublic); HashSet hashSet = field?.GetValue(player) as HashSet; HashSet hashSet2 = field2?.GetValue(player) as HashSet; Dictionary dictionary = field3?.GetValue(player) as Dictionary; bool flag = hashSet?.Contains(text) ?? false; ManualLogSource log5 = Log; if (log5 != null) { log5.LogInfo((object)("Sichtbarkeitsdiagnose: Player.m_knownRecipes enthaelt Recipe-Key=" + (flag ? "ja" : "nein") + ".")); } GameObject itemPrefab2 = instance.GetItemPrefab("Wood"); string text3 = (((Object)(object)itemPrefab2 == (Object)null) ? null : itemPrefab2.GetComponent())?.m_itemData?.m_shared?.m_name; bool flag2 = !string.IsNullOrEmpty(text3) && hashSet2 != null && hashSet2.Contains(text3); int num = 0; Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory != null && !string.IsNullOrEmpty(text3)) { num = inventory.CountItems(text3, -1, false); } ManualLogSource log6 = Log; if (log6 != null) { log6.LogInfo((object)("Sichtbarkeitsdiagnose: Wood-Key=" + (text3 ?? "") + "; KnownMaterial=" + (flag2 ? "ja" : "nein") + "; Inventarmenge=" + num + "; benoetigt=1.")); } CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); bool flag3 = !string.IsNullOrEmpty(text2) && dictionary != null && dictionary.ContainsKey(text2); ManualLogSource log7 = Log; if (log7 != null) { log7.LogInfo((object)("Sichtbarkeitsdiagnose: Werkbankkenntnis=" + (flag3 ? "ja" : "nein") + "; aktuelle CraftingStation=" + (((Object)(object)currentCraftingStation == (Object)null) ? "" : currentCraftingStation.m_name) + ".")); } List list = typeof(Player).GetField("s_FilterCraft", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as List; bool flag4 = list != null && list.Count > 0; bool flag5 = !flag4; if (flag4) { string text4 = ((Localization.instance == null) ? string.Empty : Localization.instance.Localize(text)); foreach (string item in list) { if (!string.IsNullOrEmpty(item)) { string value = item.ToLowerInvariant(); if ((((Object)itemPrefab).name ?? string.Empty).ToLowerInvariant().Contains(value) || text.ToLowerInvariant().Contains(value) || (text4 ?? string.Empty).ToLowerInvariant().Contains(value)) { flag5 = true; break; } } } } List list2 = new List(); player.GetAvailableRecipes(ref list2); bool flag6 = false; foreach (Recipe item2 in list2) { if ((Object)(object)item2 == (Object)(object)val2 || item2?.m_item?.m_itemData?.m_shared?.m_name == text) { flag6 = true; break; } } ManualLogSource log8 = Log; if (log8 != null) { log8.LogInfo((object)("Sichtbarkeitsdiagnose: GetAvailableRecipes enthaelt Ewigschlag=" + (flag6 ? "ja" : "nein") + "; Crafting-Filter aktiv=" + (flag4 ? "ja" : "nein") + "; Filter-Treffer=" + (flag5 ? "ja" : "nein") + ".")); } if (!flag6) { string text5 = "unbekannt"; if (!val2.m_enabled) { text5 = "Recipe.m_enabled ist false"; } else if ((Object)(object)val2.m_item == (Object)null) { text5 = "Recipe.m_item ist ungueltig"; } else if (flag4 && !flag5) { text5 = "aktiver Crafting-Filter passt nicht"; } else if (!flag) { text5 = "Recipe-Key fehlt in Player.m_knownRecipes"; } else if ((Object)(object)currentCraftingStation == (Object)null) { text5 = "keine aktuelle CraftingStation"; } else if (currentCraftingStation.m_name != text2) { text5 = "aktuelle CraftingStation stimmt nicht mit der Rezeptstation ueberein"; } ManualLogSource log9 = Log; if (log9 != null) { log9.LogInfo((object)("Sichtbarkeitsdiagnose: erster belegbarer Filtergrund=" + text5 + ".")); } } } catch (Exception ex) { ManualLogSource log10 = Log; if (log10 != null) { log10.LogError((object)("Sichtbarkeitsdiagnose fehlgeschlagen: " + ex)); } } } private static void RemoveObjectDbItem(ObjectDB objectDb, GameObject itemPrefab) { if ((Object)(object)objectDb == (Object)null || objectDb.m_items == null || (Object)(object)itemPrefab == (Object)null || !objectDb.m_items.Remove(itemPrefab)) { return; } try { UpdateObjectDbRegisters(objectDb); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Ewigschlag aus ObjectDB.m_items entfernt; Register wiederhergestellt."); } } catch (Exception ex) { LogFailClosed("ObjectDB-Register konnten nach Abbruch nicht wiederhergestellt werden: " + ex); } } private static void UpdateObjectDbRegisters(ObjectDB objectDb) { MethodInfo? method = typeof(ObjectDB).GetMethod("UpdateRegisters", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { throw new MissingMethodException(typeof(ObjectDB).FullName, "UpdateRegisters"); } method.Invoke(objectDb, null); } private static void CopyTableMetadata(PieceTable vanilla, PieceTable fineHammer, PieceTable target) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) target.m_canRemovePieces = vanilla.m_canRemovePieces; target.m_canRemoveFeasts = vanilla.m_canRemoveFeasts; target.m_selectedPiece = (Vector2Int[])(object)new Vector2Int[0]; target.m_lastSelectedPiece = (Vector2Int[])(object)new Vector2Int[0]; target.m_categories = new List(); target.m_categoryLabels = new List(); target.m_categoriesFolded = new List(); target.m_skill = vanilla.m_skill; AppendCategories(vanilla, target); AppendCategories(fineHammer, target); } private static void AppendCategories(PieceTable source, PieceTable target) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (source.m_categories == null) { return; } for (int i = 0; i < source.m_categories.Count; i++) { PieceCategory item = source.m_categories[i]; if (!target.m_categories.Contains(item)) { target.m_categories.Add(item); string item2 = ((source.m_categoryLabels != null && i < source.m_categoryLabels.Count) ? source.m_categoryLabels[i] : string.Empty); target.m_categoryLabels.Add(item2); } } } private static bool AddLocalization() { if (Localization.instance == null) { return false; } MethodInfo method = typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { return false; } method.Invoke(Localization.instance, new object[2] { "item_goblinstudio_ewigschlag", "Everstrike" }); method.Invoke(Localization.instance, new object[2] { "item_goblinstudio_ewigschlag_description", "Ein unzerstörbarer Bauhammer für große und kleine Wikingerprojekte." }); return true; } private static bool AddRecipe(ObjectDB objectDb, GameObject itemPrefab) { //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown ItemDrop itemDrop = itemPrefab.GetComponent(); if ((Object)(object)itemDrop == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogError((object)"Rezeptregistrierung: Ewigschlag-ItemDrop fehlt."); } return false; } if ((Object)(object)objectDb == (Object)null || objectDb.m_recipes == null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogError((object)"Rezeptregistrierung: ObjectDB-Rezeptliste fehlt."); } return false; } if (objectDb.m_recipes.Exists((Recipe recipe) => (Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item == (Object)(object)itemDrop)) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)"Rezept bereits vorhanden."); } return true; } GameObject itemPrefab2 = objectDb.GetItemPrefab("FineWood"); ItemDrop val = (((Object)(object)itemPrefab2 == (Object)null) ? null : itemPrefab2.GetComponent()); GameObject itemPrefab3 = objectDb.GetItemPrefab("RoundLog"); ItemDrop val2 = (((Object)(object)itemPrefab3 == (Object)null) ? null : itemPrefab3.GetComponent()); GameObject itemPrefab4 = objectDb.GetItemPrefab("Copper"); ItemDrop val3 = (((Object)(object)itemPrefab4 == (Object)null) ? null : itemPrefab4.GetComponent()); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogError((object)"Rezeptregistrierung: FineWood, RoundLog oder Copper fehlt in ObjectDB."); } return false; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { ManualLogSource log5 = Log; if (log5 != null) { log5.LogError((object)"Rezeptregistrierung: ZNetScene ist nicht verfuegbar."); } return false; } GameObject prefab = instance.GetPrefab("piece_workbench"); CraftingStation val4 = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent()); if ((Object)(object)val4 == (Object)null) { ManualLogSource log6 = Log; if (log6 != null) { log6.LogError((object)"Rezeptregistrierung: piece_workbench oder CraftingStation fehlt in ZNetScene."); } return false; } ManualLogSource log7 = Log; if (log7 != null) { log7.LogInfo((object)"Rezeptregistrierung: piece_workbench gefunden."); } Recipe val5 = ScriptableObject.CreateInstance(); if ((Object)(object)val5 == (Object)null) { ManualLogSource log8 = Log; if (log8 != null) { log8.LogError((object)"Rezeptregistrierung: Rezeptobjekt konnte nicht erzeugt werden."); } return false; } ((Object)val5).name = "Recipe_GoblinStudio_Ewigschlag"; val5.m_item = itemDrop; val5.m_amount = 1; val5.m_craftingStation = val4; val5.m_minStationLevel = 1; val5.m_resources = (Requirement[])(object)new Requirement[3] { new Requirement { m_resItem = val, m_amount = 10, m_amountPerLevel = 0, m_recover = true }, new Requirement { m_resItem = val2, m_amount = 5, m_amountPerLevel = 0, m_recover = true }, new Requirement { m_resItem = val3, m_amount = 3, m_amountPerLevel = 0, m_recover = true } }; if ((Object)(object)val5.m_item == (Object)null || (Object)(object)val5.m_craftingStation == (Object)null || val5.m_resources == null || val5.m_resources.Length != 3 || (Object)(object)val5.m_resources[0].m_resItem == (Object)null || (Object)(object)val5.m_resources[1].m_resItem == (Object)null || (Object)(object)val5.m_resources[2].m_resItem == (Object)null) { ManualLogSource log9 = Log; if (log9 != null) { log9.LogError((object)"Rezeptregistrierung: Rezeptobjekt ist unvollstaendig."); } Object.Destroy((Object)(object)val5); return false; } objectDb.m_recipes.Add(val5); ManualLogSource log10 = Log; if (log10 != null) { log10.LogInfo((object)"Rezept erfolgreich registriert: 10 FineWood, 5 RoundLog, 3 Copper an der Werkbank."); } return true; } private static void LogFailClosed(string message) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("Ewigschlag Initialisierung abgebrochen: " + message)); } } } }