Decompiled source of Bjurd v0.1.2

Bjurd.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
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("Bjurd")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Bjurd")]
[assembly: AssemblyTitle("Bjurd")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace Bjurd
{
	[BepInPlugin("talismon.bjurd", "Bjurd", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Player), "OnDeath")]
		private static class PlayerOnDeathPatch
		{
			private static void Prefix(Player __instance)
			{
				Inventory inventory = ((Humanoid)__instance).GetInventory();
				foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
				{
					if (item.m_equipped && !((Object)(object)item.m_dropPrefab == (Object)null) && !(((Object)item.m_dropPrefab).name != BjurdItemPrefabName))
					{
						item.m_equipped = false;
						HeldOverBjurdItems.Add(item);
						inventory.RemoveOneItem(item);
						Logger.LogInfo((object)"Holding Bjurd through player death.");
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private static class PlayerOnSpawnedPatch
		{
			private static void Postfix(Player __instance)
			{
				if (HeldOverBjurdItems.Count == 0)
				{
					return;
				}
				Inventory inventory = ((Humanoid)__instance).GetInventory();
				foreach (ItemData heldOverBjurdItem in HeldOverBjurdItems)
				{
					if (inventory.AddItem(heldOverBjurdItem))
					{
						((Humanoid)__instance).EquipItem(heldOverBjurdItem, true);
						Logger.LogInfo((object)"Restored and equipped Bjurd after respawn.");
					}
					else
					{
						Logger.LogWarning((object)"Could not restore Bjurd after respawn because the inventory rejected it.");
					}
				}
				HeldOverBjurdItems.Clear();
			}
		}

		[HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")]
		private static class BodyVisibilityPatch
		{
			private static readonly FieldInfo CurrentChestHashField = AccessTools.Field(typeof(VisEquipment), "m_currentChestItemHash");

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

			private static void Prefix(VisEquipment __instance)
			{
				PreviousChestHashes[((Object)__instance).GetInstanceID()] = (int)CurrentChestHashField.GetValue(__instance);
			}

			private static void Postfix(VisEquipment __instance, int hash, ref bool __result)
			{
				if (!__result || (Object)(object)__instance.m_bodyModel == (Object)null || (Object)(object)TransparentBodyMaterial == (Object)null)
				{
					return;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				PreviousChestHashes.TryGetValue(instanceID, out var value);
				Renderer bodyModel = (Renderer)(object)__instance.m_bodyModel;
				if (hash == BjurdItemHash)
				{
					bodyModel.material = TransparentBodyMaterial;
					bodyModel.materials = (Material[])(object)new Material[2] { TransparentBodyMaterial, TransparentBodyMaterial };
				}
				else if (value == BjurdItemHash && UsesBjurdTransparency(bodyModel))
				{
					int modelIndex = __instance.GetModelIndex();
					if (modelIndex >= 0 && modelIndex < __instance.m_models.Length)
					{
						bodyModel.material = __instance.m_models[modelIndex].m_baseMaterial;
					}
				}
				PreviousChestHashes.Remove(instanceID);
			}

			private static bool UsesBjurdTransparency(Renderer renderer)
			{
				Material[] sharedMaterials = renderer.sharedMaterials;
				foreach (Material val in sharedMaterials)
				{
					if ((Object)(object)val != (Object)null && ((Object)val).name.StartsWith("Bjurd Body Transparency", StringComparison.Ordinal))
					{
						return true;
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")]
		private static class ChestVisualDiagnostic
		{
			private static readonly HashSet<string> LoggedInstances = new HashSet<string>();

			private static void Postfix(VisEquipment __instance, int hash, bool __result)
			{
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0205: Unknown result type (might be due to invalid IL or missing references)
				//IL_020a: Unknown result type (might be due to invalid IL or missing references)
				//IL_020e: Unknown result type (might be due to invalid IL or missing references)
				//IL_022c: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0449: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_06de: Unknown result type (might be due to invalid IL or missing references)
				//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0701: Unknown result type (might be due to invalid IL or missing references)
				//IL_071b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0720: Unknown result type (might be due to invalid IL or missing references)
				//IL_0724: Unknown result type (might be due to invalid IL or missing references)
				//IL_0730: Unknown result type (might be due to invalid IL or missing references)
				//IL_0735: Unknown result type (might be due to invalid IL or missing references)
				//IL_0739: Unknown result type (might be due to invalid IL or missing references)
				ObjectDB instance = ObjectDB.instance;
				GameObject val = ((instance != null) ? instance.GetItemPrefab(hash) : null);
				if ((Object)(object)val == (Object)null || (((Object)val).name != "Bjurd" && ((Object)val).name != "Cackle01"))
				{
					return;
				}
				Transform val2 = val.transform.Find("attach_skin");
				SkinnedMeshRenderer[] array = (((Object)(object)val2 == (Object)null) ? Array.Empty<SkinnedMeshRenderer>() : ((Component)val2).GetComponentsInChildren<SkinnedMeshRenderer>(true));
				if (!(AccessTools.Field(typeof(VisEquipment), "m_chestItemInstances")?.GetValue(__instance) is List<GameObject> list))
				{
					return;
				}
				for (int i = 0; i < list.Count; i++)
				{
					GameObject val3 = list[i];
					string item = ((Object)val).name + ":" + ((Object)val3).GetInstanceID();
					if (!LoggedInstances.Add(item))
					{
						continue;
					}
					SkinnedMeshRenderer[] componentsInChildren = val3.GetComponentsInChildren<SkinnedMeshRenderer>(true);
					Logger.LogInfo((object)($"VISUAL COMPARISON: item={((Object)val).name}, result={__result}, " + "sourceAttach=" + (((Object)(object)val2 == (Object)null) ? "missing" : "found") + ", " + $"sourceRenderers={array.Length}, attachedInstances={list.Count}"));
					string[] obj = new string[7]
					{
						$"VISUAL INSTANCE {((Object)val).name}:{i}: name={((Object)val3).name}, ",
						$"activeSelf={val3.activeSelf}, activeInHierarchy={val3.activeInHierarchy}, ",
						null,
						null,
						null,
						null,
						null
					};
					object arg = val3.transform.position;
					Quaternion val4 = val3.transform.rotation;
					obj[2] = $"position={arg}, rotation={((Quaternion)(ref val4)).eulerAngles}, ";
					obj[3] = $"localPosition={val3.transform.localPosition}, ";
					val4 = val3.transform.localRotation;
					obj[4] = $"localRotation={((Quaternion)(ref val4)).eulerAngles}, ";
					obj[5] = $"localScale={val3.transform.localScale}, ";
					obj[6] = $"renderers={componentsInChildren.Length}";
					Logger.LogInfo((object)string.Concat(obj));
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						SkinnedMeshRenderer val5 = componentsInChildren[j];
						int num = 0;
						List<string> list2 = new List<string>();
						SkinnedMeshRenderer val6 = null;
						SkinnedMeshRenderer[] array2 = array;
						foreach (SkinnedMeshRenderer val7 in array2)
						{
							if (((Object)val7).name == ((Object)val5).name)
							{
								val6 = val7;
								break;
							}
						}
						Dictionary<int, int> dictionary = new Dictionary<int, int>();
						if ((Object)(object)val5.sharedMesh != (Object)null)
						{
							BoneWeight[] boneWeights = val5.sharedMesh.boneWeights;
							for (int k = 0; k < boneWeights.Length; k++)
							{
								BoneWeight val8 = boneWeights[k];
								AddBoneUse(dictionary, ((BoneWeight)(ref val8)).boneIndex0, ((BoneWeight)(ref val8)).weight0);
								AddBoneUse(dictionary, ((BoneWeight)(ref val8)).boneIndex1, ((BoneWeight)(ref val8)).weight1);
								AddBoneUse(dictionary, ((BoneWeight)(ref val8)).boneIndex2, ((BoneWeight)(ref val8)).weight2);
								AddBoneUse(dictionary, ((BoneWeight)(ref val8)).boneIndex3, ((BoneWeight)(ref val8)).weight3);
							}
						}
						Transform[] bones = val5.bones;
						for (int l = 0; l < bones.Length; l++)
						{
							if ((Object)(object)bones[l] == (Object)null)
							{
								num++;
								object obj2;
								if (!((Object)(object)val6 != (Object)null) || l >= val6.bones.Length)
								{
									obj2 = "unavailable";
								}
								else
								{
									Transform obj3 = val6.bones[l];
									obj2 = ((obj3 != null) ? ((Object)obj3).name : null) ?? "null";
								}
								string arg2 = (string)obj2;
								dictionary.TryGetValue(l, out var value);
								list2.Add($"index={l},source={arg2},weightedVertices={value}");
							}
						}
						List<string> list3 = new List<string>();
						Material[] sharedMaterials = ((Renderer)val5).sharedMaterials;
						foreach (Material val9 in sharedMaterials)
						{
							if ((Object)(object)val9 == (Object)null)
							{
								list3.Add("null");
								continue;
							}
							Shader shader = val9.shader;
							float num2 = (val9.HasProperty("_Color") ? val9.GetColor("_Color").a : (-1f));
							Texture val10 = (val9.HasProperty("_MainTex") ? val9.GetTexture("_MainTex") : null);
							list3.Add(((Object)val9).name + "[shader=" + (((shader != null) ? ((Object)shader).name : null) ?? "null") + "," + $"supported={shader != null && shader.isSupported},queue={val9.renderQueue}," + string.Format("colorA={0:F2},mainTex={1}]", num2, ((val10 != null) ? ((Object)val10).name : null) ?? "null"));
						}
						string[] obj4 = new string[23]
						{
							$"VISUAL RENDERER {((Object)val).name}:{i}:{j}: ",
							$"name={((Object)val5).name}, layer={((Component)val5).gameObject.layer}, ",
							$"enabled={((Renderer)val5).enabled}, active={((Component)val5).gameObject.activeInHierarchy}, ",
							$"forceRenderingOff={((Renderer)val5).forceRenderingOff}, visible={((Renderer)val5).isVisible}, ",
							"mesh=",
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null
						};
						Mesh sharedMesh = val5.sharedMesh;
						obj4[5] = ((sharedMesh != null) ? ((Object)sharedMesh).name : null) ?? "null";
						obj4[6] = ", ";
						Mesh sharedMesh2 = val5.sharedMesh;
						obj4[7] = $"vertices={((sharedMesh2 != null) ? sharedMesh2.vertexCount : 0)}, ";
						obj4[8] = $"bones={bones.Length}, nullBones={num}, ";
						obj4[9] = "nullBoneDetails=[";
						obj4[10] = string.Join(";", list2);
						obj4[11] = "], ";
						Mesh sharedMesh3 = val5.sharedMesh;
						obj4[12] = $"bindPoses={((sharedMesh3 != null) ? sharedMesh3.bindposes.Length : 0)}, ";
						obj4[13] = "rootBone=";
						Transform rootBone = val5.rootBone;
						obj4[14] = ((rootBone != null) ? ((Object)rootBone).name : null) ?? "null";
						obj4[15] = ", ";
						obj4[16] = $"localPosition={((Component)val5).transform.localPosition}, ";
						val4 = ((Component)val5).transform.localRotation;
						obj4[17] = $"localRotation={((Quaternion)(ref val4)).eulerAngles}, ";
						obj4[18] = $"localScale={((Component)val5).transform.localScale}, ";
						Bounds bounds = ((Renderer)val5).bounds;
						object arg3 = ((Bounds)(ref bounds)).center;
						bounds = ((Renderer)val5).bounds;
						obj4[19] = $"boundsCenter={arg3}, boundsSize={((Bounds)(ref bounds)).size}, ";
						obj4[20] = $"updateWhenOffscreen={val5.updateWhenOffscreen}, ";
						obj4[21] = "materials=";
						obj4[22] = string.Join(";", list3);
						Logger.LogInfo((object)string.Concat(obj4));
					}
				}
			}

			private static void AddBoneUse(Dictionary<int, int> weightedVertexUses, int boneIndex, float weight)
			{
				if (!(weight <= 0f))
				{
					weightedVertexUses.TryGetValue(boneIndex, out var value);
					weightedVertexUses[boneIndex] = value + 1;
				}
			}
		}

		public const string PluginGuid = "talismon.bjurd";

		public const string PluginName = "Bjurd";

		public const string PluginVersion = "0.1.2";

		private const string TransparentBodyMaterialName = "Bjurd Body Transparency";

		private static Material? TransparentBodyMaterial;

		private static int BjurdItemHash;

		private static string BjurdItemPrefabName = "Bjurd";

		private static readonly List<ItemData> HeldOverBjurdItems = new List<ItemData>();

		private void Awake()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			try
			{
				AssetBundle val = AssetUtils.LoadAssetBundleFromResources("bjurd", Assembly.GetExecutingAssembly());
				GameObject val2 = val.LoadAsset<GameObject>("Assets/Bjurd/Prefabs/Bjurd.prefab");
				if ((Object)(object)val2 == (Object)null)
				{
					throw new InvalidOperationException("The Bjurd prefab was not found in the embedded asset bundle.");
				}
				BjurdItemPrefabName = ((Object)val2).name;
				BjurdItemHash = StringExtensionMethods.GetStableHashCode(((Object)val2).name);
				TransparentBodyMaterial = new Material(Shader.Find("Standard"))
				{
					name = "Bjurd Body Transparency",
					renderQueue = 2450
				};
				TransparentBodyMaterial.SetColor("_Color", Color.clear);
				TransparentBodyMaterial.SetFloat("_Mode", 1f);
				TransparentBodyMaterial.SetInt("_SrcBlend", 1);
				TransparentBodyMaterial.SetInt("_DstBlend", 0);
				TransparentBodyMaterial.EnableKeyword("_ALPHATEST_ON");
				ItemDrop component = val2.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null)
				{
					throw new InvalidOperationException("The Bjurd prefab does not contain an ItemDrop component.");
				}
				component.m_itemData.m_quality = 1;
				component.m_itemData.m_shared.m_maxQuality = 4;
				component.m_itemData.m_shared.m_variants = 1;
				BoneReorder.ApplyOnEquipmentChanged();
				Harmony.CreateAndPatchAll(typeof(BodyVisibilityPatch), "talismon.bjurd.body-visibility");
				Harmony.CreateAndPatchAll(typeof(PlayerOnDeathPatch), "talismon.bjurd.death-persistence");
				Harmony.CreateAndPatchAll(typeof(PlayerOnSpawnedPatch), "talismon.bjurd.spawn-persistence");
				ItemConfig val3 = new ItemConfig();
				val3.Name = "Bjurd";
				val3.Description = "Forged in Feathers. -For Lari ♥";
				val3.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
				{
					new RequirementConfig
					{
						Item = "Wood",
						Amount = 0,
						AmountPerLevel = 10
					},
					new RequirementConfig
					{
						Item = "Feathers",
						Amount = 1,
						AmountPerLevel = 5
					}
				};
				ItemConfig val4 = val3;
				ItemManager.Instance.AddItem(new CustomItem(val2, true, val4));
				val.Unload(false);
				try
				{
					Harmony.CreateAndPatchAll(typeof(ChestVisualDiagnostic), "talismon.bjurd");
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Bjurd item registered, but visual diagnostics could not be enabled: " + ex.Message));
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)"BJURD IS ALIVE! Item and recipe registered.");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to register Bjurd: {arg}");
			}
		}
	}
}