Decompiled source of SledgeMajsterLateFix v1.0.4

SledgeMajsterLateFix.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[BepInPlugin("fix.sledgemajster.lateload", "SledgeMajsterLateFix", "1.0.4")]
public class SledgeMajsterLateFix : BaseUnityPlugin
{
	private bool applied = false;

	private bool waiting = false;

	private void Awake()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"SledgeMajster Late Fix loaded - will apply after world init");
	}

	private void Update()
	{
		if (!applied && !waiting && !((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)ObjectDB.instance == (Object)null))
		{
			waiting = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ZNetScene + ObjectDB detected, waiting 15s for mods to finish registering...");
			((MonoBehaviour)this).StartCoroutine(DelayedApply());
		}
	}

	private IEnumerator DelayedApply()
	{
		yield return (object)new WaitForSeconds(15f);
		if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Lost ZNetScene/ObjectDB during wait, will retry on next join");
			waiting = false;
		}
		else
		{
			ApplyFix();
			applied = true;
		}
	}

	private void ApplyFix()
	{
		ZNetScene instance = ZNetScene.instance;
		ObjectDB instance2 = ObjectDB.instance;
		GameObject prefab = instance.GetPrefab("SledgeIron");
		if ((Object)(object)prefab == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"SledgeIron not found - is sledgemajster installed?");
			return;
		}
		ItemDrop component = prefab.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		Attack attack = component.m_itemData.m_shared.m_attack;
		if (attack == null || string.IsNullOrEmpty(attack.m_attackAnimation))
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"SledgeIron primary attack has no animation - sledgemajster may not have run");
			return;
		}
		string attackAnimation = attack.m_attackAnimation;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Reference animation from SledgeIron: " + attackAnimation));
		int num = 0;
		HashSet<string> hashSet = new HashSet<string>();
		if (instance.m_prefabs != null)
		{
			foreach (GameObject prefab2 in instance.m_prefabs)
			{
				if (TryFixSledge(prefab2, attackAnimation, attack))
				{
					hashSet.Add(((Object)prefab2).name);
					num++;
				}
			}
		}
		try
		{
			FieldInfo field = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && field.GetValue(instance) is IDictionary dictionary)
			{
				foreach (object value in dictionary.Values)
				{
					GameObject current = (GameObject)((value is GameObject) ? value : null);
					if ((Object)(object)current != (Object)null && !hashSet.Contains(((Object)current).name) && TryFixSledge(current, attackAnimation, attack))
					{
						hashSet.Add(((Object)current).name);
						num++;
					}
				}
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not scan m_namedPrefabs: " + ex.Message));
		}
		if ((Object)(object)instance2 != (Object)null && instance2.m_items != null)
		{
			foreach (GameObject item in instance2.m_items)
			{
				if ((Object)(object)item != (Object)null && !hashSet.Contains(((Object)item).name) && TryFixSledge(item, attackAnimation, attack))
				{
					hashSet.Add(((Object)item).name);
					num++;
				}
			}
		}
		try
		{
			FieldInfo field2 = typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 != null && (Object)(object)instance2 != (Object)null && field2.GetValue(instance2) is IDictionary dictionary2)
			{
				foreach (object value2 in dictionary2.Values)
				{
					GameObject current = (GameObject)((value2 is GameObject) ? value2 : null);
					if ((Object)(object)current != (Object)null && !hashSet.Contains(((Object)current).name) && TryFixSledge(current, attackAnimation, attack))
					{
						hashSet.Add(((Object)current).name);
						num++;
					}
				}
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not scan m_itemByHash: " + ex.Message));
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("SledgeMajster Late Fix complete: patched " + num + " additional sledge(s)"));
	}

	private bool TryFixSledge(GameObject go, string battleaxeAnim, Attack refAttack)
	{
		if ((Object)(object)go == (Object)null)
		{
			return false;
		}
		string name = ((Object)go).name;
		if (name.IndexOf("sledge", StringComparison.OrdinalIgnoreCase) < 0)
		{
			return false;
		}
		if (name.IndexOf("Anchor", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			return false;
		}
		ItemDrop component = go.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		SharedData shared = component.m_itemData.m_shared;
		if (shared == null || shared.m_attack == null)
		{
			return false;
		}
		if (shared.m_attack.m_attackAnimation == battleaxeAnim)
		{
			return false;
		}
		shared.m_secondaryAttack = shared.m_attack;
		shared.m_attack = CloneAttack(refAttack);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Late-fixed sledge: " + name));
		return true;
	}

	private static Attack CloneAttack(Attack src)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		if (src == null)
		{
			return new Attack();
		}
		MethodInfo method = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
		return (Attack)method.Invoke(src, null);
	}
}