Decompiled source of Skald Of Camelot v1.0.6

plugins\SkaldOfCamelot.dll

Decompiled 8 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("SkaldOfCamelot")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SkaldOfCamelot")]
[assembly: AssemblyTitle("SkaldOfCamelot")]
[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 SkaldOfCamelot
{
	[BepInPlugin("com.soukboy.skaldofcamelot", "Skald Of Camelot", "1.0.6")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SkaldOfCamelotPlugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.soukboy.skaldofcamelot");

		public static Dictionary<string, float> _lastPlayTimes = new Dictionary<string, float>();

		private const float COOLDOWN_SECONDS = 900f;

		private void Awake()
		{
			try
			{
				CleanupSongsDirectly();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("SongLibrary cleanup failed: " + ex));
			}
			try
			{
				PatchAudio();
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Audio patch failed: " + ex2));
			}
			try
			{
				PatchRecipes();
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Recipes patch failed: " + ex3));
			}
			try
			{
				PatchBuff();
			}
			catch (Exception ex4)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Buff patch failed: " + ex4));
			}
			try
			{
				AddInstruments();
			}
			catch (Exception ex5)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Add instruments failed: " + ex5));
			}
			try
			{
				PatchSongSelectUI();
			}
			catch (Exception ex6)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("SongSelectUI patch failed: " + ex6));
			}
		}

		private void CleanupSongsDirectly()
		{
			Type type = AccessTools.TypeByName("Bragi.SongLibrary");
			if (!(type != null))
			{
				return;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, "_songs");
			if (!(fieldInfo != null) || !(fieldInfo.GetValue(null) is IList list))
			{
				return;
			}
			List<object> list2 = new List<object>();
			foreach (object item in list)
			{
				string text = (string)AccessTools.Property(item.GetType(), "Id").GetValue(item);
				if (text != "epic_flute_custom" && text != "tambour_midgard_custom" && text != "lyre_hibernia_custom")
				{
					list2.Add(item);
				}
			}
			foreach (object item2 in list2)
			{
				list.Remove(item2);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[SkaldOfCamelot] Cleaned up default Bragi songs. Custom songs loaded: {list.Count}");
		}

		private void PatchAudio()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("UnityEngine.Networking.UnityWebRequestMultimedia");
			Type type2 = AccessTools.TypeByName("UnityEngine.AudioType");
			if (type != null && type2 != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "GetAudioClip", new Type[2]
				{
					typeof(string),
					type2
				}, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(SkaldOfCamelotPlugin), "GetAudioClipPrefix", (Type[])null, (Type[])null);
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public static void GetAudioClipPrefix(ref string uri)
		{
			if (uri != null && uri.StartsWith("file:///") && uri.Contains(" "))
			{
				uri = Uri.EscapeUriString(uri);
			}
		}

		private void PatchRecipes()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(SkaldOfCamelotPlugin), "ObjectDBAwakePostfix", (Type[])null, (Type[])null);
			_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static Sprite GetIconFromObjectDB(ObjectDB db, string prefabName)
		{
			if ((Object)(object)db == (Object)null)
			{
				return null;
			}
			GameObject itemPrefab = db.GetItemPrefab(prefabName);
			if ((Object)(object)itemPrefab != (Object)null)
			{
				ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null)
				{
					return (component.m_itemData.m_shared.m_icons.Length != 0) ? component.m_itemData.m_shared.m_icons[0] : null;
				}
			}
			return null;
		}

		public static void ObjectDBAwakePostfix(ObjectDB __instance)
		{
			if ((Object)(object)__instance != (Object)null && __instance.m_recipes != null)
			{
				__instance.m_recipes.RemoveAll((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && (Object)(object)((Component)r.m_item).gameObject != (Object)null && ((Object)((Component)r.m_item).gameObject).name.StartsWith("Bragi"));
			}
			if (__instance.m_StatusEffects == null)
			{
				return;
			}
			if (!__instance.m_StatusEffects.Exists((StatusEffect se) => ((Object)se).name == "Bardheim_CarryBuff"))
			{
				SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val).name = "Bardheim_CarryBuff";
				((StatusEffect)val).m_name = "Tambours de Midgard";
				((StatusEffect)val).m_tooltip = "Capacite de charge +150";
				val.m_addMaxCarryWeight = 150f;
				((StatusEffect)val).m_ttl = 300f;
				((StatusEffect)val).m_icon = GetIconFromObjectDB(__instance, "BeltStrength");
				__instance.m_StatusEffects.Add((StatusEffect)(object)val);
			}
			else
			{
				StatusEffect? obj = __instance.m_StatusEffects.Find((StatusEffect se) => ((Object)se).name == "Bardheim_CarryBuff");
				SE_Stats val2 = (SE_Stats)(object)((obj is SE_Stats) ? obj : null);
				if ((Object)(object)val2 != (Object)null)
				{
					((StatusEffect)val2).m_ttl = 300f;
					((StatusEffect)val2).m_tooltip = "Capacite de charge +150";
					((StatusEffect)val2).m_icon = GetIconFromObjectDB(__instance, "BeltStrength");
				}
			}
			if (!__instance.m_StatusEffects.Exists((StatusEffect se) => ((Object)se).name == "Bardheim_HealBuff"))
			{
				SE_Stats val3 = ScriptableObject.CreateInstance<SE_Stats>();
				((Object)val3).name = "Bardheim_HealBuff";
				((StatusEffect)val3).m_name = "Aura de Guerison";
				((StatusEffect)val3).m_tooltip = "Regeneration de vie +200%";
				val3.m_healthRegenMultiplier = 3f;
				((StatusEffect)val3).m_ttl = 60f;
				((StatusEffect)val3).m_icon = GetIconFromObjectDB(__instance, "MeadHealthMedium");
				__instance.m_StatusEffects.Add((StatusEffect)(object)val3);
			}
			else
			{
				StatusEffect? obj2 = __instance.m_StatusEffects.Find((StatusEffect se) => ((Object)se).name == "Bardheim_HealBuff");
				SE_Stats val4 = (SE_Stats)(object)((obj2 is SE_Stats) ? obj2 : null);
				if ((Object)(object)val4 != (Object)null)
				{
					((StatusEffect)val4).m_ttl = 60f;
					((StatusEffect)val4).m_tooltip = "Regeneration de vie +200%";
					((StatusEffect)val4).m_icon = GetIconFromObjectDB(__instance, "MeadHealthMedium");
				}
			}
		}

		private void PatchBuff()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("Bragi.BardBuff");
			if (type != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "ExtendRestBuff", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					MethodInfo methodInfo2 = AccessTools.Method(typeof(SkaldOfCamelotPlugin), "ExtendRestBuffPostfix", (Type[])null, (Type[])null);
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		public static void ExtendRestBuffPostfix(Player player)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player != (Object)null) || !((Object)(object)ZNetScene.instance != (Object)null) || !((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return;
			}
			string text = "";
			foreach (ItemData equippedItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetEquippedItems())
			{
				if ((Object)(object)equippedItem.m_dropPrefab != (Object)null)
				{
					string name = ((Object)equippedItem.m_dropPrefab).name;
					if (name.StartsWith("Bardheim_"))
					{
						text = name;
						break;
					}
				}
			}
			if (text == "Bardheim_Drum")
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("vfx_sledge_iron_hit");
				if ((Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab, ((Component)player).transform.position + Vector3.up, Quaternion.identity);
				}
				((Character)player).GetSEMan().AddStatusEffect("Bardheim_CarryBuff".GetHashCode(), true, 0, 0f, (short)(-1));
			}
			else if (text == "Bardheim_Lyre")
			{
				GameObject prefab2 = ZNetScene.instance.GetPrefab("vfx_Potion_health_medium");
				if ((Object)(object)prefab2 != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab2, ((Component)player).transform.position + Vector3.up, Quaternion.identity);
				}
				((Character)player).GetSEMan().AddStatusEffect("Bardheim_HealBuff".GetHashCode(), true, 0, 0f, (short)(-1));
			}
			else
			{
				GameObject prefab3 = ZNetScene.instance.GetPrefab("vfx_Potion_stamina_medium");
				if ((Object)(object)prefab3 != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab3, ((Component)player).transform.position + Vector3.up, Quaternion.identity);
				}
			}
		}

		private void AddInstruments()
		{
			Type type = AccessTools.TypeByName("Bragi.InstrumentDefinitions");
			if (!(type != null))
			{
				return;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, "ItemNameToType");
			if (!(fieldInfo != null))
			{
				return;
			}
			IDictionary dictionary = (IDictionary)fieldInfo.GetValue(null);
			if (dictionary != null)
			{
				if (!dictionary.Contains("Bardheim_Lyre"))
				{
					dictionary.Add("Bardheim_Lyre", 0);
				}
				if (!dictionary.Contains("Bardheim_Flute"))
				{
					dictionary.Add("Bardheim_Flute", 1);
				}
				if (!dictionary.Contains("Bardheim_Drum"))
				{
					dictionary.Add("Bardheim_Drum", 2);
				}
			}
		}

		private void PatchSongSelectUI()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("Bragi.SongSelectUI");
			if (type != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					MethodInfo methodInfo2 = AccessTools.Method(typeof(SkaldOfCamelotPlugin), "SongSelectUI_Update_Prefix", (Type[])null, (Type[])null);
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		public static bool SongSelectUI_Update_Prefix(MonoBehaviour __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Type type = ((object)__instance).GetType();
				KeyCode val = (KeyCode)AccessTools.Method(type, "GetMenuKey", (Type[])null, (Type[])null).Invoke(__instance, null);
				Type type2 = AccessTools.TypeByName("UnityEngine.Input");
				if ((bool)AccessTools.Method(type2, "GetKeyDown", new Type[1] { typeof(KeyCode) }, (Type[])null).Invoke(null, new object[1] { val }))
				{
					if ((bool)AccessTools.Method(type, "IsInstrumentEquipped", (Type[])null, (Type[])null).Invoke(null, null))
					{
						Type type3 = AccessTools.TypeByName("Bragi.SongPlayer");
						object value = AccessTools.Property(type3, "Instance").GetValue(null);
						if (value != null)
						{
							if ((bool)AccessTools.Property(type3, "IsPlaying").GetValue(value))
							{
								AccessTools.Method(type3, "StopPlaying", (Type[])null, (Type[])null).Invoke(value, null);
							}
							else
							{
								object obj = AccessTools.Method(type, "GetEquippedInstrumentType", (Type[])null, (Type[])null).Invoke(null, null);
								if (obj != null)
								{
									string text = obj.ToString();
									if (!_lastPlayTimes.ContainsKey(text))
									{
										_lastPlayTimes[text] = -9999f;
									}
									float num = Time.time - _lastPlayTimes[text];
									if (num < 900f)
									{
										float num2 = 900f - num;
										int num3 = Mathf.FloorToInt(num2 / 60f);
										int num4 = Mathf.FloorToInt(num2 % 60f);
										if ((Object)(object)Player.m_localPlayer != (Object)null)
										{
											((Character)Player.m_localPlayer).Message((MessageType)2, $"L'instrument {text} doit se recharger... {num3}m {num4}s", 0, (Sprite)null, false);
										}
									}
									else
									{
										Type type4 = AccessTools.TypeByName("Bragi.SongLibrary");
										if (AccessTools.Method(type4, "GetSongsForInstrument", (Type[])null, (Type[])null).Invoke(null, new object[1] { obj }) is IList { Count: >0 } list)
										{
											object obj2 = list[0];
											AccessTools.Method(type3, "StartNewSession", (Type[])null, (Type[])null).Invoke(value, new object[1] { obj2 });
											_lastPlayTimes[text] = Time.time;
										}
										else if ((Object)(object)Player.m_localPlayer != (Object)null)
										{
											((Character)Player.m_localPlayer).Message((MessageType)2, "Aucune musique trouvée pour l'instrument " + text, 0, (Sprite)null, false);
										}
									}
								}
							}
						}
					}
					return false;
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Error in SongSelectUI Prefix: " + ex));
			}
			return true;
		}
	}
}