Decompiled source of ItemStandFix v0.3.9

plugins/ItemStandFix.dll

Decompiled 6 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 BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ItemStandFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.8.0")]
[assembly: AssemblyInformationalVersion("0.3.8")]
[assembly: AssemblyProduct("ItemStandFix")]
[assembly: AssemblyTitle("ItemStandFix")]
[assembly: AssemblyVersion("0.3.8.0")]
namespace ItemStandFix;

[HarmonyPatch(typeof(ItemStand), "DropItem")]
internal static class ItemStandDropItemPatch
{
	private static void Postfix(ZNetView ___m_nview)
	{
		if (!((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && ___m_nview.IsOwner())
		{
			ZDO zDO = ___m_nview.GetZDO();
			if (zDO != null && zDO.GetInt(ZDOVars.s_item, 0) == 0 && ItemStandMetadata.ClearVisualMetadata(zDO))
			{
				Plugin.Log.LogDebug((object)"Cleared visual metadata from an empty item stand.");
			}
		}
	}
}
internal static class ItemStandStyleRestore
{
	private static readonly HashSet<WearNTear> Pending = new HashSet<WearNTear>();

	private static readonly MaterialPropertyBlock PropertyBlock = new MaterialPropertyBlock();

	private static readonly int StyleProperty = Shader.PropertyToID("_Style");

	internal static void Queue(WearNTear wearNTear)
	{
		if ((Object)(object)wearNTear != (Object)null && (Object)(object)((Component)wearNTear).GetComponent<ItemStand>() != (Object)null)
		{
			Pending.Add(wearNTear);
		}
	}

	internal static void RestorePending()
	{
		foreach (WearNTear item in Pending)
		{
			if ((Object)(object)item == (Object)null)
			{
				continue;
			}
			ZNetView component = ((Component)item).GetComponent<ZNetView>();
			ItemStyle componentInChildren = ((Component)item).GetComponentInChildren<ItemStyle>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && !((Object)(object)componentInChildren == (Object)null))
			{
				int num = component.GetZDO().GetInt(ZDOVars.s_variant, 0);
				Renderer[] componentsInChildren = ((Component)componentInChildren).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer obj in componentsInChildren)
				{
					PropertyBlock.Clear();
					obj.GetPropertyBlock(PropertyBlock);
					PropertyBlock.SetInt(StyleProperty, num);
					obj.SetPropertyBlock(PropertyBlock);
				}
			}
		}
		Pending.Clear();
	}
}
[HarmonyPatch(typeof(ItemStand), "SetVisualItem")]
internal static class ItemStandSetVisualItemPatch
{
	private static readonly MethodInfo RegisterRenderers = AccessTools.Method(typeof(MaterialMan), "RegisterRenderers", new Type[2]
	{
		typeof(GameObject),
		typeof(bool)
	}, (Type[])null);

	private static void Prefix(GameObject ___m_visualItem, out GameObject __state)
	{
		__state = ___m_visualItem;
	}

	private static void Postfix(ItemStand __instance, GameObject ___m_visualItem, GameObject __state)
	{
		if (!((Object)(object)__state == (Object)(object)___m_visualItem) && !((Object)(object)MaterialMan.instance == (Object)null))
		{
			RegisterRenderers.Invoke(MaterialMan.instance, new object[2]
			{
				((Component)__instance).gameObject,
				true
			});
		}
	}
}
[HarmonyPatch(typeof(WearNTear), "Highlight")]
internal static class WearNTearHighlightPatch
{
	private static void Postfix(WearNTear __instance)
	{
		ItemStandStyleRestore.Queue(__instance);
	}
}
[HarmonyPatch(typeof(WearNTear), "ResetHighlight")]
internal static class WearNTearResetHighlightPatch
{
	private static void Postfix(WearNTear __instance)
	{
		ItemStandStyleRestore.Queue(__instance);
	}
}
[HarmonyPatch(typeof(MaterialMan), "Update")]
internal static class MaterialManUpdatePatch
{
	private static void Postfix()
	{
		ItemStandStyleRestore.RestorePending();
	}
}
internal static class ItemStandMetadata
{
	internal static bool IsItemStand(ZDO zdo)
	{
		if (zdo == null || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return false;
		}
		GameObject prefab = ZNetScene.instance.GetPrefab(zdo.GetPrefab());
		if ((Object)(object)prefab != (Object)null)
		{
			return (Object)(object)prefab.GetComponent<ItemStand>() != (Object)null;
		}
		return false;
	}

	internal static bool ClearVisualMetadata(ZDO zdo)
	{
		bool num = zdo.RemoveInt(ZDOVars.s_quality);
		bool flag = zdo.RemoveInt(ZDOVars.s_variant);
		return num || flag;
	}

	internal static void ForceServerSync(ZDO zdo)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		if (ZDOMan.instance != null)
		{
			ZDOMan.instance.ForceSendZDO(zdo.m_uid);
		}
	}
}
[HarmonyPatch(typeof(ItemStand), "UpdateAttach")]
internal static class ItemStandUpdateAttachPatch
{
	private sealed class PlacementState
	{
		public ZDO Zdo;

		public int PreviousItemHash;

		public GameObject ExpectedItemPrefab;

		public int Quality;

		public int Variant;
	}

	private static void Prefix(ItemData ___m_queuedItem, ZNetView ___m_nview, out PlacementState __state)
	{
		__state = null;
		if (___m_queuedItem != null && !((Object)(object)___m_queuedItem.m_dropPrefab == (Object)null) && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid())
		{
			ZDO zDO = ___m_nview.GetZDO();
			if (zDO != null)
			{
				__state = new PlacementState
				{
					Zdo = zDO,
					PreviousItemHash = zDO.GetInt(ZDOVars.s_item, 0),
					ExpectedItemPrefab = ___m_queuedItem.m_dropPrefab,
					Quality = ___m_queuedItem.m_quality,
					Variant = ___m_queuedItem.m_variant
				};
			}
		}
	}

	private static void Postfix(PlacementState __state)
	{
		if (__state == null || __state.PreviousItemHash != 0)
		{
			return;
		}
		int num = __state.Zdo.GetInt(ZDOVars.s_item, 0);
		if (num != 0 && !((Object)(object)ObjectDB.instance == (Object)null))
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(num);
			if (!((Object)(object)itemPrefab == (Object)null) && !((Object)(object)itemPrefab != (Object)(object)__state.ExpectedItemPrefab))
			{
				int num2 = __state.Zdo.GetInt(ZDOVars.s_quality, 1);
				int num3 = __state.Zdo.GetInt(ZDOVars.s_variant, 0);
				__state.Zdo.Set(ZDOVars.s_quality, __state.Quality, false);
				__state.Zdo.Set(ZDOVars.s_variant, __state.Variant, false);
				Plugin.Log.LogDebug((object)("Stored item stand visual metadata: " + $"quality {num2}->{__state.Quality}, " + $"variant {num3}->{__state.Variant}."));
			}
		}
	}
}
[BepInPlugin("com.github.whosteenie.itemstandfix", "Item Stand Fix", "0.3.8")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.github.whosteenie.itemstandfix";

	public const string PluginName = "Item Stand Fix";

	public const string PluginVersion = "0.3.8";

	private Harmony _harmony;

	internal static ManualLogSource Log { get; private set; }

	private void Awake()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		_harmony = new Harmony("com.github.whosteenie.itemstandfix");
		_harmony.PatchAll();
		Log.LogInfo((object)"Item Stand Fix 0.3.8 loaded.");
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
[HarmonyPatch(typeof(ZDO), "Deserialize")]
internal static class ZdoDeserializePatch
{
	private static void Postfix(ZDO __instance)
	{
		if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
		{
			return;
		}
		int num = __instance.GetInt(ZDOVars.s_item, 0);
		if (num == 0 || __instance.GetByteArray(ZDOVars.s_itemData, (byte[])null) == null || (Object)(object)ObjectDB.instance == (Object)null || !ItemStandMetadata.IsItemStand(__instance))
		{
			return;
		}
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(num);
		if ((Object)(object)itemPrefab == (Object)null)
		{
			return;
		}
		ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		try
		{
			ItemData val = component.m_itemData.Clone();
			ItemDrop.LoadFromZDO(val, __instance, -1);
			int num2 = __instance.GetInt(ZDOVars.s_quality, 1);
			int num3 = __instance.GetInt(ZDOVars.s_variant, 0);
			if (num2 != val.m_quality || num3 != val.m_variant)
			{
				__instance.Set(ZDOVars.s_quality, val.m_quality, false);
				__instance.Set(ZDOVars.s_variant, val.m_variant, false);
				ItemStandMetadata.ForceServerSync(__instance);
				Plugin.Log.LogDebug((object)("Server repaired item stand visual metadata: " + $"quality {num2}->{val.m_quality}, " + $"variant {num3}->{val.m_variant}."));
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Server could not read item stand metadata: " + ex.Message));
		}
	}
}