Decompiled source of AzNean Lib v0.1.3

plugins/AzNeanLib.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AzNean.SotfCommon;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Sons.Crafting;
using Sons.Cutscenes;
using Sons.Inventory;
using Sons.Items.Core;
using TheForest.Items.Inventory;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AzNeanLib")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3+04f969363884d50e104bc4139452770beb67c5b6")]
[assembly: AssemblyProduct("AzNeanLib")]
[assembly: AssemblyTitle("AzNeanLib")]
[assembly: AssemblyVersion("0.1.3.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 AzNean.SotfCommon
{
	internal static class ModLog
	{
		private static ManualLogSource _log;

		private static ConfigEntry<bool> _full;

		private static readonly HashSet<string> _once = new HashSet<string>();

		private static readonly Dictionary<(int, string), int> _state = new Dictionary<(int, string), int>();

		internal static bool Full => _full.Value;

		internal static void Init(ManualLogSource log, ConfigEntry<bool> full)
		{
			_log = log;
			_full = full;
		}

		internal static void Trace(string message)
		{
			if (_full.Value)
			{
				_log.LogInfo((object)message);
			}
		}

		internal static bool Changed(int id, string what, int state)
		{
			if (!_full.Value || (_state.TryGetValue((id, what), out var value) && value == state))
			{
				return false;
			}
			_state[(id, what)] = state;
			return true;
		}

		internal static void Once(string key, string message, LogLevel level = (LogLevel)16)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (_once.Add(key))
			{
				_log.Log(level, (object)message);
			}
		}
	}
}
namespace AzNeanLib
{
	public static class Backpack
	{
		public static int JoinLists(string mod, PlayerInventory inventory, InventoryLayoutItemGroup template, IList<InventoryLayoutItemGroup> ours, string copyPrefix)
		{
			//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)
			InventoryCutscene val = (((Object)(object)inventory != (Object)null) ? inventory._inventoryCutscene : null);
			int dropped = 0;
			int num = Join(((Object)(object)val != (Object)null) ? val._inventoryLayoutItemGroups : null, template, ours, copyPrefix, ref dropped) + Join(((Object)(object)val != (Object)null) ? val._creativeModeLayoutItemGroups : null, template, ours, copyPrefix, ref dropped);
			int num2 = 0;
			foreach (InventoryEnableLayoutGroups item in Resources.FindObjectsOfTypeAll<InventoryEnableLayoutGroups>())
			{
				Scene scene = ((Component)item).gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					int num3 = Join(item._layoutGroups, template, ours, copyPrefix, ref dropped);
					if (num3 > 0)
					{
						num2++;
					}
					num += num3;
				}
			}
			string text = $"{mod}: backpack lists: cutscene {(((Object)(object)val != (Object)null) ? $"found ({val._inventoryLayoutItemGroups?.Count ?? 0} places)" : "not found")}, {num2} on/off list(s) holding {((template != null) ? ((Object)template).name : null)}; {num} entr(ies) added for {ours.Count} place(s), {dropped} old or dead entr(ies) dropped.";
			if (num == 0 && ours.Count > 0)
			{
				Plugin.Logger.LogWarning((object)(text + " Nothing joined: the template is in none of the game's backpack lists."));
			}
			else
			{
				ModLog.Trace(text);
			}
			return num;
		}

		private static int Join(List<InventoryLayoutItemGroup> list, InventoryLayoutItemGroup template, IList<InventoryLayoutItemGroup> ours, string copyPrefix, ref int dropped)
		{
			if (list == null || (Object)(object)template == (Object)null || !list.Contains(template))
			{
				return 0;
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)list[num] == (Object)null || ((Object)list[num]).name.StartsWith(copyPrefix))
				{
					list.RemoveAt(num);
					dropped++;
				}
			}
			foreach (InventoryLayoutItemGroup our in ours)
			{
				if ((Object)(object)our != (Object)null)
				{
					list.Add(our);
				}
			}
			return ours.Count;
		}
	}
	public static class GameItems
	{
		private static readonly Dictionary<int, string> Owners = new Dictionary<int, string>();

		public static bool Ready => (Object)(object)ItemDatabaseManager._instance != (Object)null;

		public static string Language
		{
			get
			{
				Locale selectedLocale = LocalizationSettings.SelectedLocale;
				if (selectedLocale == null)
				{
					return null;
				}
				return selectedLocale.Identifier.Code;
			}
		}

		public static ItemData Add(string mod, int id, ItemData template, string name)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			bool flag = default(bool);
			if (!Ready || (Object)(object)template == (Object)null)
			{
				ManualLogSource logger = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(23, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(mod);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": item ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") not added: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)template == (Object)null) ? "no template item" : "the game's item database is not ready");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				logger.LogError(val);
				return null;
			}
			if (ItemDatabaseManager._itemsCache.ContainsKey(id))
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(47, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(mod);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": item id ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" for ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is already used by ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Owners.TryGetValue(id, out var value) ? value : "the game or a mod without AzNeanLib");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": not added.");
				}
				logger2.LogError(val);
				return null;
			}
			ItemData val2 = Object.Instantiate<ItemData>(template);
			((Object)val2).hideFlags = (HideFlags)32;
			string text = (val2._editorName = name);
			string name2 = (val2._name = text);
			((Object)val2).name = name2;
			val2._id = id;
			val2._uiData._itemId = id;
			val2._uiData._translationKey = "I_" + name;
			ItemDatabaseManager._itemsCache.Add(id, val2);
			ItemDatabaseManager._instance._itemDataList.Add(val2);
			Owners[id] = mod;
			ModLog.Trace($"{mod}: item {id} {name} added (copy of {template._name} {template._id}).");
			return val2;
		}

		public static bool SetTexts(ItemData data, string name, string plural, string description)
		{
			StringTable val = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase)?.GetTable(TableReference.op_Implicit(ItemUiData.ItemsTableReference), (Locale)null);
			if ((Object)(object)val == (Object)null || (Object)(object)data == (Object)null)
			{
				int num = (((Object)(object)data != (Object)null) ? data._id : 0);
				if (ModLog.Changed(num, "texts", 0))
				{
					ModLog.Trace($"Item {num} {name}: texts not set yet: {(((Object)(object)data == (Object)null) ? "no item given" : "the game's Items text table is not loaded")}.");
				}
				return false;
			}
			string translationKey = data._uiData._translationKey;
			((DetailedLocalizationTable<StringTableEntry>)(object)val).AddEntry(translationKey, name);
			((DetailedLocalizationTable<StringTableEntry>)(object)val).AddEntry(translationKey + ItemUiData.PluralTranslationKeySuffix, plural);
			((DetailedLocalizationTable<StringTableEntry>)(object)val).AddEntry(translationKey + ItemUiData.DescriptionTranslationKeySuffix, description);
			data._uiData._hasDescription = !string.IsNullOrEmpty(description);
			data._uiData._title = name;
			if (ModLog.Changed(data._id, "texts", name.GetHashCode()))
			{
				ModLog.Trace($"Item {data._id} {name}: texts set in the game's Items table ({Language}).");
			}
			return true;
		}
	}
	[BepInPlugin("aznan.sotf.azneanlib", "AzNeanLib", "0.1.3")]
	public class Plugin : BasePlugin
	{
		public const string Guid = "aznan.sotf.azneanlib";

		internal const string Version = "0.1.3";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<bool> FullLogging;

		public override void Load()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			FullLogging = ((BasePlugin)this).Config.Bind<bool>("Debug", "FullLogging", false, "True = the BepInEx log gets every item, text, recipe and backpack place added through this library, with the mod that asked. False = only loading, version and errors.");
			ModLog.Init(Logger, FullLogging);
			ManualLogSource logger = Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AzNeanLib ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.3");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			logger.LogInfo(val);
		}
	}
	public static class Recipes
	{
		private const int DefaultTemplate = 455;

		public static bool Add(string mod, CraftingSystem crafting, string recipeName, int resultId, int resultCount, IList<(int Id, int Count)> parts, bool first = true)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Expected O, but got Unknown
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Expected O, but got Unknown
			object obj;
			if (crafting == null)
			{
				obj = null;
			}
			else
			{
				CraftingRecipeDatabase recipeDatabase = crafting._recipeDatabase;
				obj = ((recipeDatabase != null) ? recipeDatabase._recipes : null);
			}
			List<CraftingRecipe> val = (List<CraftingRecipe>)obj;
			bool flag = default(bool);
			if (val == null)
			{
				ManualLogSource logger = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(50, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(mod);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": no crafting mat recipe list: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(recipeName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" cannot be crafted.");
				}
				logger.LogError(val2);
				return false;
			}
			CraftingSystem instance = CraftingSystem.Instance;
			if ((Object)(object)instance != (Object)null && ((Il2CppObjectBase)instance).Pointer != ((Il2CppObjectBase)crafting).Pointer)
			{
				ModLog.Once($"other mat {((Il2CppObjectBase)crafting).Pointer} {recipeName}", mod + ": recipe " + recipeName + " added to a crafting mat that is not the game's live one: its ingredients may stay greyed.", (LogLevel)4);
			}
			Enumerator<CraftingRecipe> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				CraftingRecipe current = enumerator.Current;
				if ((Object)(object)current != (Object)null && ((Object)current).name == recipeName)
				{
					if (ModLog.Changed(((Object)crafting).GetInstanceID(), recipeName, 1))
					{
						ModLog.Trace($"{mod}: recipe {recipeName} already in the recipe list of the mat {((Il2CppObjectBase)crafting).Pointer}: not added again.");
					}
					return true;
				}
			}
			CraftingRecipe val3 = null;
			enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				CraftingRecipe current2 = enumerator.Current;
				if ((Object)(object)current2 != (Object)null && current2._resultingItems != null && current2._resultingItems.Count > 0 && current2._resultingItems[0].Id == 455)
				{
					val3 = current2;
				}
			}
			if ((Object)(object)val3 == (Object)null)
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(65, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(mod);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": the game's health mix recipe was not found: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(recipeName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" cannot be crafted.");
				}
				logger2.LogError(val2);
				return false;
			}
			CraftingRecipe val4 = Object.Instantiate<CraftingRecipe>(val3);
			((Object)val4).hideFlags = (HideFlags)32;
			((Object)val4).name = recipeName;
			val4._ingredients = new List<CraftingIngredient>();
			foreach (var (num, count) in parts)
			{
				val4._ingredients.Add(new CraftingIngredient
				{
					ItemId = num,
					Count = count,
					IsReusable = false
				});
				MarkAsMaterial(mod, num);
			}
			val4._resultingItems = new List<ResultingItem>();
			for (int i = 0; i < resultCount; i++)
			{
				val4._resultingItems.Add(new ResultingItem
				{
					Id = resultId
				});
			}
			val4._generatedResultingItems = null;
			val4._recipeType = (Type)0;
			val4._weaponMod = null;
			val4._useContainerDataForResultingItems = false;
			val4._containerItemData = null;
			val4._hasCustomName = false;
			if (first)
			{
				val.Insert(0, val4);
			}
			else
			{
				val.Add(val4);
			}
			if (!ModLog.Full)
			{
				return true;
			}
			List<string> list = new List<string>();
			foreach (var part in parts)
			{
				int item = part.Id;
				int item2 = part.Count;
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(4, 3);
				defaultInterpolatedStringHandler.AppendFormatted(item2);
				defaultInterpolatedStringHandler.AppendLiteral("x");
				defaultInterpolatedStringHandler.AppendFormatted(item);
				defaultInterpolatedStringHandler.AppendLiteral(" (");
				ItemData obj2 = ItemDatabaseManager.ItemById(item);
				defaultInterpolatedStringHandler.AppendFormatted(((obj2 != null) ? obj2._name : null) ?? "unknown item");
				defaultInterpolatedStringHandler.AppendLiteral(")");
				list.Add(defaultInterpolatedStringHandler.ToStringAndClear());
			}
			DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(57, 8);
			defaultInterpolatedStringHandler2.AppendFormatted(mod);
			defaultInterpolatedStringHandler2.AppendLiteral(": recipe added to the recipe list ");
			defaultInterpolatedStringHandler2.AppendFormatted(((Il2CppObjectBase)crafting._recipeDatabase).Pointer);
			defaultInterpolatedStringHandler2.AppendLiteral(" of the mat ");
			defaultInterpolatedStringHandler2.AppendFormatted(((Il2CppObjectBase)crafting).Pointer);
			IntPtr pointer = ((Il2CppObjectBase)crafting).Pointer;
			CraftingSystem instance2 = CraftingSystem.Instance;
			defaultInterpolatedStringHandler2.AppendFormatted((pointer == ((instance2 != null) ? ((Il2CppObjectBase)instance2).Pointer : IntPtr.Zero)) ? " (the game's own)" : "");
			defaultInterpolatedStringHandler2.AppendLiteral(": ");
			defaultInterpolatedStringHandler2.AppendFormatted(string.Join(" + ", list));
			defaultInterpolatedStringHandler2.AppendLiteral(" -> ");
			defaultInterpolatedStringHandler2.AppendFormatted(resultCount);
			defaultInterpolatedStringHandler2.AppendLiteral("x ");
			ItemData obj3 = ItemDatabaseManager.ItemById(resultId);
			defaultInterpolatedStringHandler2.AppendFormatted(((obj3 != null) ? obj3._name : null) ?? resultId.ToString());
			defaultInterpolatedStringHandler2.AppendLiteral(" (");
			defaultInterpolatedStringHandler2.AppendFormatted(recipeName);
			defaultInterpolatedStringHandler2.AppendLiteral(")");
			ModLog.Trace(defaultInterpolatedStringHandler2.ToStringAndClear());
			return true;
		}

		public static void MarkAsMaterial(string mod, int id)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = ItemDatabaseManager.ItemById(id);
			if ((Object)(object)val == (Object)null)
			{
				ModLog.Once("material" + id, $"{mod}: ingredient item {id} is not in the game's item database: it cannot be laid on the crafting mat.", (LogLevel)4);
			}
			else if ((val._type & 4) == 0)
			{
				val._type = (Types)(val._type | 4);
				ModLog.Trace($"{mod}: item {id} ({val._name}) marked as a crafting material: the game lays only those on the mat.");
			}
		}
	}
}