The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of BugleMaestro v1.0.2
com.github.alexandria-p.BugleMaestro.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Logging; using BugleMaestro.Helpers; using BugleMaestro.MonoBehaviors; using BugleMaestro.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.alexandria-p.BugleMaestro")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e18b8f032308438539236c54a96f28b58b5f44f4")] [assembly: AssemblyProduct("com.github.alexandria-p.BugleMaestro")] [assembly: AssemblyTitle("BugleMaestro")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BugleMaestro { [BepInPlugin("com.github.alexandria-p.BugleMaestro", "BugleMaestro", "1.0.0")] public class Plugin : BaseUnityPlugin { private Harmony? _harmonyInstance; public static readonly string TEAM_NAME = "alexandria_p"; public static readonly string MOD_NAME = "BugleMaestro"; public static readonly string LOG_PREFIX = MOD_NAME; public static readonly string DEFAULT_CHARACTER_NAME = "DEFAULT_NAME"; public Dictionary<ScaleEnum, AudioClip> baseBugleClips = new Dictionary<ScaleEnum, AudioClip>(); public GUIManager guiManager; public TextMeshProUGUI itemInfoDisplayTextMesh; public Dictionary<string, string> fontColors = new Dictionary<string, string>(); public float fontSize; public float outlineWidth; public float lineSpacing; public float sizeDeltaX; public const string Id = "com.github.alexandria-p.BugleMaestro"; public static Plugin Instance { get; private set; } = null; internal static ManualLogSource Log { get; private set; } = null; public static string Name => "BugleMaestro"; public static string Version => "1.0.0"; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; UIHelper.SetupUIElements(); ClipHelper.SetupBaseBugleClips(); _harmonyInstance = Harmony.CreateAndPatchAll(typeof(CharacterMovementPatch), (string)null); _harmonyInstance = Harmony.CreateAndPatchAll(typeof(BugleSFXPatch), (string)null); _harmonyInstance = Harmony.CreateAndPatchAll(typeof(CharacterItemsPatch), (string)null); Log.LogInfo((object)(LOG_PREFIX + ": Plugin " + Name + " is loaded!")); } private void OnDestroy() { Log.LogInfo((object)(LOG_PREFIX + ": Plugin destroying...")); Log.LogDebug((object)(LOG_PREFIX + ": Removing harmony patches...")); if (_harmonyInstance != null) { _harmonyInstance.UnpatchSelf(); } else { Log.LogInfo((object)(LOG_PREFIX + ": null harmony instance OnDestroy")); } Log.LogInfo((object)(LOG_PREFIX + ": Plugin destroyed!")); } } } namespace BugleMaestro.Patches { [HarmonyPatch(typeof(BugleSFX))] public class BugleSFXPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start_Postfix(BugleSFX __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance.item).gameObject.GetComponent<BugleMaestroBehaviour>())) { ((Component)__instance.item).gameObject.AddComponent<BugleMaestroBehaviour>(); } } [HarmonyPatch("RPC_StartToot")] [HarmonyPostfix] private static void RPC_StartToot_Postfix(BugleSFX __instance, int clip, float pitch) { BugleMaestroBehaviour component = ((Component)__instance.item).gameObject.GetComponent<BugleMaestroBehaviour>(); __instance.bugle = (AudioClip[])(object)new AudioClip[1] { ClipHelper.ChangePitch(component.RPC_CurrentNote) }; __instance.currentClip = 0; __instance.currentPitch = 1f; Item item = __instance.item; object obj; if (item == null) { obj = null; } else { Character holderCharacter = item.holderCharacter; obj = ((holderCharacter != null) ? holderCharacter.characterName : null); } if (obj == null) { obj = Plugin.DEFAULT_CHARACTER_NAME; } string text = (string)obj; Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + text + " made a TOOOOOT! " + component.RPC_CurrentNote)); } [HarmonyPatch("RPC_EndToot")] [HarmonyPostfix] private static void RPC_EndToot_Postfix(BugleSFX __instance) { Item item = __instance.item; object obj; if (item == null) { obj = null; } else { Character holderCharacter = item.holderCharacter; obj = ((holderCharacter != null) ? holderCharacter.characterName : null); } if (obj == null) { obj = Plugin.DEFAULT_CHARACTER_NAME; } string text = (string)obj; Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + text + " ended toot now.")); } } [HarmonyPatch(typeof(CharacterItems))] public class CharacterItemsPatch { [HarmonyPatch("DropItemRpc")] [HarmonyPrefix] private static bool DropItemRpc_Prefix(ref CharacterItems __instance, float throwCharge, byte slotID, Vector3 spawnPos, Vector3 velocity, Quaternion rotation, ItemInstanceData itemInstanceData) { Item currentItem = __instance.character.data.currentItem; BugleMaestroBehaviour bugleMaestroBehaviour = ((currentItem != null) ? ((Component)currentItem).gameObject.GetComponent<BugleMaestroBehaviour>() : null); BugleSFX val = ((currentItem != null) ? ((Component)currentItem).gameObject.GetComponent<BugleSFX>() : null); if (!Object.op_Implicit((Object)(object)currentItem) || (Object)(object)bugleMaestroBehaviour == (Object)null || (Object)(object)val == (Object)null) { return true; } if (val.item.holderCharacter.IsLocal) { UIHelper.HideUI(); } return true; } [HarmonyPatch("DoUsing")] [HarmonyPrefix] private static bool DoUsing_Prefix(ref CharacterItems __instance) { if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)__instance.character == (Object)null || (Object)(object)__instance.character.data == (Object)null || (Object)(object)__instance.character.data.currentItem == (Object)null) { return true; } BugleMaestroBehaviour buglemb = ((Component)__instance.character.data.currentItem).gameObject.GetComponent<BugleMaestroBehaviour>(); BugleSFX buglesfx = ((Component)__instance.character.data.currentItem).gameObject.GetComponent<BugleSFX>(); if ((Object)(object)buglemb == (Object)null || (Object)(object)buglesfx == (Object)null) { return true; } if (Object.op_Implicit((Object)(object)buglesfx.magicBugle) && buglesfx.magicBugle.currentFuel <= 0.02f) { CancelBugle(); return true; } if (buglesfx.item.holderCharacter.data.passedOut || buglesfx.item.holderCharacter.data.fullyPassedOut) { CancelBugle(); return true; } bool rPC_IsANoteInputBeingPressedByThePlayer = buglemb.RPC_IsANoteInputBeingPressedByThePlayer; bool isUsingPrimary = buglesfx.item.isUsingPrimary; if (buglemb.IsANewNoteChangePendingForLocalPlayer && isUsingPrimary) { CancelBugle(); } if (rPC_IsANoteInputBeingPressedByThePlayer) { if (!isUsingPrimary && buglesfx.item.holderCharacter.data.currentItem.CanUsePrimary()) { StartBugle(); return false; } if (isUsingPrimary && buglesfx.item.holderCharacter.data.currentItem.CanUsePrimary()) { ContinueBugle(); return false; } } else if (!rPC_IsANoteInputBeingPressedByThePlayer && isUsingPrimary) { CancelBugle(); return false; } return true; void CancelBugle() { if (buglesfx.item.holderCharacter.IsLocal) { UIHelper.HideUI(); } buglesfx.item.CancelUsePrimary(); } void ContinueBugle() { buglesfx.item.ContinueUsePrimary(); } void StartBugle() { if (buglesfx.item.holderCharacter.IsLocal) { UIHelper.DisplayBugleNote(buglemb.RPC_CurrentNote); } buglesfx.item.StartUsePrimary(); buglemb.UpdateLocalIsNotePending(newValue: false); } } } [HarmonyPatch(typeof(CharacterMovement))] public class CharacterMovementPatch { [HarmonyPatch("SetMovementState")] [HarmonyPrefix] private static bool SetMovementState_Prefix(ref CharacterMovement __instance) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) if (!__instance.character.refs.view.IsMine) { return true; } Character character = __instance.character; object obj; if (character == null) { obj = null; } else { CharacterData data = character.data; obj = ((data != null) ? data.currentItem : null); } Item val = (Item)obj; BugleMaestroBehaviour bugleMaestroBehaviour = default(BugleMaestroBehaviour); if ((Object)(object)__instance.character == (Object)null || (Object)(object)val == (Object)null || !((Component)val).TryGetComponent<BugleMaestroBehaviour>(ref bugleMaestroBehaviour) || !bugleMaestroBehaviour.RPC_IsANoteInputBeingPressedByThePlayer) { return true; } bool flag = false; Enumerator<InputBinding> enumerator = CharacterInput.action_move.bindings.GetEnumerator(); try { while (enumerator.MoveNext()) { InputBinding current = enumerator.Current; InputControl val2 = InputSystem.FindControl(((InputBinding)(ref current)).path); ButtonControl val3 = (ButtonControl)(object)((val2 is ButtonControl) ? val2 : null); if (val3 != null && val3.isPressed && ((InputBinding)(ref current)).path != "<Keyboard>/upArrow" && ((InputBinding)(ref current)).path != "<Keyboard>/downArrow" && ((InputBinding)(ref current)).path != "<Keyboard>/leftArrow" && ((InputBinding)(ref current)).path != "<Keyboard>/rightArrow") { flag = true; } } } finally { ((IDisposable)enumerator).Dispose(); } if (!flag) { __instance.character.input.movementInput = Vector2.zero; } return true; } } } namespace BugleMaestro.MonoBehaviors { internal class BugleMaestroBehaviour : MonoBehaviourPun { private Item? _bugleItemInstance; public bool IsPlaying => RPC_IsANoteInputBeingPressedByThePlayer; public ScaleEnum RPC_CurrentNote { get; private set; } = ScaleHelper.DEFAULT_NOTE; public bool RPC_IsANoteInputBeingPressedByThePlayer { get; private set; } public bool IsANewNoteChangePendingForLocalPlayer { get; private set; } public RawNoteInputEnum Local_CurrentRawNote { get; set; } = ScaleHelper.DEFAULT_RAW_NOTE; private OctaveEnum Local_CurrentOctave { get; set; } = ScaleHelper.DEFAULT_OCTAVE; private SemitoneModifierEnum Local_CurrentSemitoneModifier { get; set; } = ScaleHelper.DEFAULT_SEMITONE_MODIFIER; private HashSet<OctaveEnum> Local_LastFrameOctaveInput { get; set; } = new HashSet<OctaveEnum>(); private HashSet<SemitoneModifierEnum> Local_LastFrameSemitoneInput { get; set; } = new HashSet<SemitoneModifierEnum>(); private List<RawNoteInputEnum> Local_LastFrameRawNoteInput { get; set; } = new List<RawNoteInputEnum>(); private void LocalPlayerSetsNote(ScaleEnum newNote) { if (((MonoBehaviourPun)this).photonView.IsMine) { ((MonoBehaviourPun)this).photonView.RPC("RPC_UpdateNotePlaying", (RpcTarget)0, new object[1] { newNote }); } } [PunRPC] private void RPC_UpdateNotePlaying(ScaleEnum newNote) { if (!RPC_IsANoteInputBeingPressedByThePlayer || RPC_CurrentNote != newNote) { RPC_CurrentNote = newNote; IsANewNoteChangePendingForLocalPlayer = true; } RPC_IsANoteInputBeingPressedByThePlayer = true; Item? bugleItemInstance = _bugleItemInstance; object obj; if (bugleItemInstance == null) { obj = null; } else { Character holderCharacter = bugleItemInstance.holderCharacter; obj = ((holderCharacter != null) ? holderCharacter.characterName : null); } if (obj == null) { obj = Plugin.DEFAULT_CHARACTER_NAME; } string text = (string)obj; } private void LocalStopInput() { if (((MonoBehaviourPun)this).photonView.IsMine && IsPlaying) { ((MonoBehaviourPun)this).photonView.RPC("RPC_StopNotePlaying", (RpcTarget)0, Array.Empty<object>()); } } [PunRPC] private void RPC_StopNotePlaying() { if (IsPlaying) { ResetBugleState(); } } public void ResetBugleState() { IsANewNoteChangePendingForLocalPlayer = false; ResetToDefaultPitch(); RPC_CurrentNote = ScaleHelper.DEFAULT_NOTE; RPC_IsANoteInputBeingPressedByThePlayer = false; } public void UpdateLocalIsNotePending(bool newValue) { IsANewNoteChangePendingForLocalPlayer = newValue; } private void Awake() { _bugleItemInstance = ((Component)this).gameObject.GetComponent<BugleSFX>()?.item; } private void Update() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 if ((Object)(object)_bugleItemInstance == (Object)null) { _bugleItemInstance = ((Component)this).gameObject.GetComponent<BugleSFX>()?.item; return; } if (!_bugleItemInstance.isUsingPrimary && IsPlaying) { ResetBugleState(); } if ((int)_bugleItemInstance.itemState != 1 || (Object)(object)_bugleItemInstance.holderCharacter == (Object)null || !_bugleItemInstance.holderCharacter.IsLocal) { return; } HashSet<OctaveEnum> octavesBeingPressedThisFrame = new HashSet<OctaveEnum>(); HashSet<SemitoneModifierEnum> semitonesBeingPressedThisFrame = new HashSet<SemitoneModifierEnum>(); HashSet<RawNoteInputEnum> rawNotesBeingPressedThisFrame = new HashSet<RawNoteInputEnum>(); if (Input.GetKey((KeyCode)274)) { octavesBeingPressedThisFrame.Add(OctaveEnum.Lowest); SetOctave(OctaveEnum.Lowest); } if (Input.GetKey((KeyCode)273)) { octavesBeingPressedThisFrame.Add(OctaveEnum.Highest); SetOctave(OctaveEnum.Highest); } if (!Input.GetKey((KeyCode)273) && !Input.GetKey((KeyCode)274)) { octavesBeingPressedThisFrame.Add(OctaveEnum.Neutral); SetOctave(OctaveEnum.Neutral); } if (Input.GetKey((KeyCode)276)) { semitonesBeingPressedThisFrame.Add(SemitoneModifierEnum.Flat); SetSemitoneModifier(SemitoneModifierEnum.Flat); } if (Input.GetKey((KeyCode)275)) { semitonesBeingPressedThisFrame.Add(SemitoneModifierEnum.Sharp); SetSemitoneModifier(SemitoneModifierEnum.Sharp); } if (!Input.GetKey((KeyCode)276) && !Input.GetKey((KeyCode)275)) { semitonesBeingPressedThisFrame.Add(SemitoneModifierEnum.Natural); SetSemitoneModifier(SemitoneModifierEnum.Natural); } if (Input.GetKey((KeyCode)122)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.C); } if (Input.GetKey((KeyCode)120)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.D); } if (Input.GetKey((KeyCode)99)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.E); } if (Input.GetKey((KeyCode)118)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.F); } if (Input.GetKey((KeyCode)98)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.G); } if (Input.GetKey((KeyCode)110)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.A); } if (Input.GetKey((KeyCode)109)) { rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.B); } if (!Input.GetKey((KeyCode)122) && !Input.GetKey((KeyCode)120) && !Input.GetKey((KeyCode)99) && !Input.GetKey((KeyCode)118) && !Input.GetKey((KeyCode)98) && !Input.GetKey((KeyCode)110) && !Input.GetKey((KeyCode)109)) { LocalStopInput(); return; } RawNoteInputEnum? rawNoteInputEnum = FindNewTootRawNote(); if (rawNoteInputEnum.HasValue) { SetRawNote(rawNoteInputEnum.Value); ScaleEnum newNote = ScaleHelper.CalculateScaleNote(Local_CurrentRawNote, Local_CurrentOctave, Local_CurrentSemitoneModifier); LocalPlayerSetsNote(newNote); } UpdateKeyInputTracking(); RawNoteInputEnum? FindNewTootRawNote() { if (!rawNotesBeingPressedThisFrame.Any()) { return null; } foreach (RawNoteInputEnum item in rawNotesBeingPressedThisFrame) { if (!RPC_IsANoteInputBeingPressedByThePlayer || !Local_LastFrameRawNoteInput.Contains(item)) { return item; } } if (Local_LastFrameOctaveInput.SetEquals(octavesBeingPressedThisFrame) && Local_LastFrameSemitoneInput.SetEquals(semitonesBeingPressedThisFrame)) { if (rawNotesBeingPressedThisFrame.Contains(Local_CurrentRawNote)) { return null; } for (int num = Local_LastFrameRawNoteInput.Count - 1; num >= 0; num--) { RawNoteInputEnum rawNoteInputEnum2 = Local_LastFrameRawNoteInput[num]; if (rawNotesBeingPressedThisFrame.Contains(rawNoteInputEnum2)) { return rawNoteInputEnum2; } } } else if (rawNotesBeingPressedThisFrame.Any()) { if (rawNotesBeingPressedThisFrame.Contains(Local_CurrentRawNote)) { return Local_CurrentRawNote; } for (int num2 = Local_LastFrameRawNoteInput.Count - 1; num2 >= 0; num2--) { RawNoteInputEnum rawNoteInputEnum3 = Local_LastFrameRawNoteInput[num2]; if (rawNotesBeingPressedThisFrame.Contains(rawNoteInputEnum3)) { return rawNoteInputEnum3; } } } return null; } void UpdateKeyInputTracking() { Local_LastFrameOctaveInput.RemoveWhere((OctaveEnum _) => !octavesBeingPressedThisFrame.Contains(_)); Local_LastFrameSemitoneInput.RemoveWhere((SemitoneModifierEnum _) => !semitonesBeingPressedThisFrame.Contains(_)); Local_LastFrameRawNoteInput.RemoveAll((RawNoteInputEnum _) => !rawNotesBeingPressedThisFrame.Contains(_)); foreach (OctaveEnum item2 in octavesBeingPressedThisFrame) { Local_LastFrameOctaveInput.Add(item2); } foreach (SemitoneModifierEnum item3 in semitonesBeingPressedThisFrame) { Local_LastFrameSemitoneInput.Add(item3); } foreach (RawNoteInputEnum item4 in rawNotesBeingPressedThisFrame) { if (!Local_LastFrameRawNoteInput.Contains(item4)) { Local_LastFrameRawNoteInput.Add(item4); } } } } private void SetOctave(OctaveEnum newOctave) { if (Local_CurrentOctave != newOctave) { Local_CurrentOctave = newOctave; } } private void SetSemitoneModifier(SemitoneModifierEnum newModifier) { if (Local_CurrentSemitoneModifier != newModifier) { Local_CurrentSemitoneModifier = newModifier; } } private void SetRawNote(RawNoteInputEnum newNote) { if (Local_CurrentRawNote != newNote) { Local_CurrentRawNote = newNote; } } private void ResetToDefaultPitch() { Local_CurrentRawNote = ScaleHelper.DEFAULT_RAW_NOTE; Local_CurrentOctave = ScaleHelper.DEFAULT_OCTAVE; Local_CurrentSemitoneModifier = ScaleHelper.DEFAULT_SEMITONE_MODIFIER; } } } namespace BugleMaestro.Helpers { public class ClipHelper { public static AudioClip ChangePitch(ScaleEnum targetScaleNote) { foreach (KeyValuePair<ScaleEnum, AudioClip> baseBugleClip in Plugin.Instance.baseBugleClips) { if (targetScaleNote == baseBugleClip.Key) { return baseBugleClip.Value; } } AudioClip baseClipToModify = Plugin.Instance.baseBugleClips.GetValueOrDefault(ScaleHelper.HIGHEST_NOTE); int num = targetScaleNote - ScaleHelper.HIGHEST_NOTE; foreach (KeyValuePair<ScaleEnum, AudioClip> baseBugleClip2 in Plugin.Instance.baseBugleClips) { int num2 = targetScaleNote - baseBugleClip2.Key; if (num2 <= 6) { baseClipToModify = baseBugleClip2.Value; num = num2; break; } } return CreateNewAudioClipByPitchShifting(baseClipToModify, num); } private static AudioClip CreateNewAudioClipByPitchShifting(AudioClip baseClipToModify, float numOfSemitoneDifferenceFromBaseClip) { float num = Mathf.Pow(2f, 1f * numOfSemitoneDifferenceFromBaseClip / 12f); int channels = baseClipToModify.channels; int num2 = Mathf.CeilToInt((float)baseClipToModify.samples / num); float[] array = new float[baseClipToModify.samples * channels]; baseClipToModify.GetData(array, 0); float[] array2 = new float[num2 * channels]; for (int i = 0; i < num2; i++) { float num3 = (float)i * num; int num4 = (int)num3; int num5 = Mathf.Min(num4 + 1, baseClipToModify.samples - 1); float num6 = num3 - (float)num4; for (int j = 0; j < channels; j++) { float num7 = array[num4 * channels + j]; float num8 = array[num5 * channels + j]; array2[i * channels + j] = Mathf.Lerp(num7, num8, num6); } } AudioClip val = AudioClip.Create(((Object)baseClipToModify).name + "_Pitched", num2, channels, baseClipToModify.frequency, false); val.SetData(array2, 0); return val; } public static async void SetupBaseBugleClips() { Dictionary<ScaleEnum, string> dictionary = new Dictionary<ScaleEnum, string>(); dictionary.Add(ScaleEnum.C2, "c2_bugle.mp3"); dictionary.Add(ScaleEnum.C3, "c3_bugle.mp3"); dictionary.Add(ScaleEnum.C4, "c4_bugle.mp3"); dictionary.Add(ScaleEnum.B4, "b4_bugle.mp3"); foreach (KeyValuePair<ScaleEnum, string> item in dictionary) { AudioClip value = await CreateAudioClipFromMp3(item.Value); Plugin.Instance.baseBugleClips.Add(item.Key, value); } } public static async Task<AudioClip> CreateAudioClipFromMp3(string filename) { string mp3Path = Path.Combine(Paths.PluginPath, Plugin.TEAM_NAME + "-" + Plugin.MOD_NAME, filename); Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + Paths.PluginPath)); string text = "file:///" + mp3Path; UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)13); Awaiter val = AsyncOperationAwaitableExtensions.GetAwaiter((AsyncOperation)(object)www.SendWebRequest()); if (!((Awaiter)(ref val)).IsCompleted) { await val; Awaiter val2 = default(Awaiter); val = val2; } ((Awaiter)(ref val)).GetResult(); if ((int)www.result != 1) { Plugin.Log.LogError((object)(Plugin.LOG_PREFIX + ": Error loading " + filename + " MP3 from " + mp3Path + ". Check whether the MP3 file from the mod exists at this filepath. Full error: " + www.error)); } AudioClip content = DownloadHandlerAudioClip.GetContent(www); float[] array = new float[content.samples * content.channels]; content.GetData(array, 0); AudioClip val3 = AudioClip.Create("EditableBugleClip", content.samples, content.channels, content.frequency, false); val3.SetData(array, 0); Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + filename + " MP3 loaded into editable AudioClip with " + val3.samples + " samples, " + val3.channels + " channels, " + val3.frequency + " Hz")); return val3; } } public class ScaleHelper { public static readonly ScaleEnum DEFAULT_NOTE = ScaleEnum.C3; public const float FundamentalFrequency = 130.813f; public static readonly RawNoteInputEnum DEFAULT_RAW_NOTE = RawNoteInputEnum.C; public static readonly OctaveEnum DEFAULT_OCTAVE = OctaveEnum.Neutral; public static readonly SemitoneModifierEnum DEFAULT_SEMITONE_MODIFIER = SemitoneModifierEnum.Natural; public static ScaleEnum LOWEST_NOTE => (from ScaleEnum x in Enum.GetValues(typeof(ScaleEnum)) orderby x select x).First(); public static ScaleEnum HIGHEST_NOTE => (from ScaleEnum x in Enum.GetValues(typeof(ScaleEnum)) orderby x select x).Last(); public static ScaleEnum CalculateScaleNote(RawNoteInputEnum rawInput, OctaveEnum octaveInput, SemitoneModifierEnum semitoneInput) { ScaleEnum scaleEnumFromAttributes = GetScaleEnumFromAttributes(rawInput, octaveInput); switch (semitoneInput) { case SemitoneModifierEnum.Natural: return scaleEnumFromAttributes; case SemitoneModifierEnum.Flat: if (scaleEnumFromAttributes == LOWEST_NOTE) { return LOWEST_NOTE; } return scaleEnumFromAttributes - 1; case SemitoneModifierEnum.Sharp: if (scaleEnumFromAttributes == HIGHEST_NOTE) { return HIGHEST_NOTE; } return scaleEnumFromAttributes + 1; default: Plugin.Log.LogError((object)$"{Plugin.LOG_PREFIX}: Could not find scale enum for RawNoteInputEnum {rawInput} and Semitone Modifier {semitoneInput} and Octave {octaveInput}."); return DEFAULT_NOTE; } } public static ScaleEnum GetScaleEnumFromAttributes(RawNoteInputEnum note, OctaveEnum octave) { Type typeFromHandle = typeof(ScaleEnum); FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { OctaveAttribute customAttribute = fieldInfo.GetCustomAttribute<OctaveAttribute>(); NamedNoteAttribute customAttribute2 = fieldInfo.GetCustomAttribute<NamedNoteAttribute>(); if (customAttribute != null && customAttribute.Octave == octave && customAttribute2 != null && customAttribute2.RawNote == note) { return (ScaleEnum)fieldInfo.GetValue(null); } } Plugin.Log.LogError((object)$"{Plugin.LOG_PREFIX}: Could not find scale enum for RawNoteInputEnum {note} and OctaveEnum {octave}."); return DEFAULT_NOTE; } public static TAttribute GetAttributeOfScaleNote<TAttribute>(ScaleEnum value) where TAttribute : Attribute { Type type = value.GetType(); string name = Enum.GetName(type, value); return type.GetField(name).GetCustomAttributes(inherit: false).OfType<TAttribute>() .Single(); } } public enum RawNoteInputEnum { C, D, E, F, G, A, B } public enum OctaveEnum { Lowest, Neutral, Highest } public enum SemitoneModifierEnum { Flat, Sharp, Natural } public class NamedNoteAttribute : Attribute { public RawNoteInputEnum RawNote { get; private set; } public NamedNoteAttribute(RawNoteInputEnum note) { RawNote = note; } } public class OctaveAttribute : Attribute { public OctaveEnum Octave { get; private set; } public OctaveAttribute(OctaveEnum oct) { Octave = oct; } } public class FrequencyAttribute : Attribute { public float Frequency { get; private set; } public FrequencyAttribute(float freq) { Frequency = freq; } } public class UIDisplayNameAttribute : Attribute { public string UIDisplayName { get; private set; } public UIDisplayNameAttribute(string name) { UIDisplayName = name; } } public enum ScaleEnum { [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.C)] [Frequency(65.406f)] [UIDisplayName("C2")] C2 = 1, [Frequency(69.296f)] [UIDisplayName("C♯2")] CSharp2, [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.D)] [Frequency(73.416f)] [UIDisplayName("D2")] D2, [Frequency(77.782f)] [UIDisplayName("Eâ™2")] EFlat2, [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.E)] [Frequency(82.406f)] [UIDisplayName("E2")] E2, [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.F)] [Frequency(87.308f)] [UIDisplayName("F2")] F2, [Frequency(92.498f)] [UIDisplayName("F♯2")] FSharp2, [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.G)] [Frequency(97.998f)] [UIDisplayName("G2")] G2, [Frequency(103.826f)] [UIDisplayName("Aâ™2")] AFlat2, [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.A)] [Frequency(110f)] [UIDisplayName("A2")] A2, [Frequency(116.541f)] [UIDisplayName("Bâ™2")] BFlat2, [Octave(OctaveEnum.Lowest)] [NamedNote(RawNoteInputEnum.B)] [Frequency(123.471f)] [UIDisplayName("B2")] B2, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.C)] [Frequency(261.626f)] [UIDisplayName("C3")] C3, [Frequency(138.592f)] [UIDisplayName("C♯3")] CSharp3, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.D)] [Frequency(146.832f)] [UIDisplayName("D3")] D3, [Frequency(155.563f)] [UIDisplayName("Eâ™3")] EFlat3, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.E)] [Frequency(164.814f)] [UIDisplayName("E3")] E3, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.F)] [Frequency(174.614f)] [UIDisplayName("F3")] F3, [Frequency(184.997f)] [UIDisplayName("F♯3")] FSharp3, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.G)] [Frequency(195.998f)] [UIDisplayName("G3")] G3, [Frequency(207.652f)] [UIDisplayName("Aâ™3")] AFlat3, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.A)] [Frequency(220f)] [UIDisplayName("A3")] A3, [Frequency(233.082f)] [UIDisplayName("Bâ™3")] BFlat3, [Octave(OctaveEnum.Neutral)] [NamedNote(RawNoteInputEnum.B)] [Frequency(246.942f)] [UIDisplayName("B3")] B3, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.C)] [Frequency(261.626f)] [UIDisplayName("C4")] C4, [Frequency(277.182f)] [UIDisplayName("C♯4")] CSharp4, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.D)] [Frequency(293.664f)] [UIDisplayName("D4")] D4, [Frequency(311.126f)] [UIDisplayName("Eâ™4")] EFlat4, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.E)] [Frequency(329.628f)] [UIDisplayName("E4")] E4, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.F)] [Frequency(349.228f)] [UIDisplayName("F4")] F4, [Frequency(369.994f)] [UIDisplayName("F♯4")] FSharp4, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.G)] [Frequency(391.996f)] [UIDisplayName("G4")] G4, [Frequency(415.304f)] [UIDisplayName("Aâ™4")] AFlat4, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.A)] [Frequency(440f)] [UIDisplayName("A4")] A4, [Frequency(466.164f)] [UIDisplayName("Bâ™4")] BFlat4, [Octave(OctaveEnum.Highest)] [NamedNote(RawNoteInputEnum.B)] [Frequency(493.884f)] [UIDisplayName("B4")] B4 } public class UIHelper { public static readonly float DEFAULT_FONTSIZE = 35f; public static readonly float DEFAULT_OUTLINEWIDTH = 0.08f; public static readonly float DEFAULT_LINESPACING = -35f; public static readonly float DEFAULT_SIZEDELTAX = 650f; public static void AddDisplayObject() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("GAME/GUIManager"); Plugin.Instance.guiManager = val.GetComponent<GUIManager>(); TMP_FontAsset font = ((TMP_Text)Plugin.Instance.guiManager.heroDayText).font; GameObject gameObject = ((Component)val.transform.Find("Canvas_HUD/Prompts/ItemPromptLayout")).gameObject; GameObject val2 = new GameObject("BugleMaestroDisplay"); val2.transform.SetParent(gameObject.transform); Plugin.Instance.itemInfoDisplayTextMesh = val2.AddComponent<TextMeshProUGUI>(); RectTransform rectTransform = ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).rectTransform; rectTransform.sizeDelta = new Vector2(Plugin.Instance.sizeDeltaX, 0f); ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).font = font; ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).fontSize = Plugin.Instance.fontSize; ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).alignment = (TextAlignmentOptions)260; ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).lineSpacing = Plugin.Instance.lineSpacing; ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text = ""; ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).outlineWidth = Plugin.Instance.outlineWidth; } public static void SetupUIElements() { InitEffectColors(Plugin.Instance.fontColors); Plugin.Instance.fontSize = DEFAULT_FONTSIZE; Plugin.Instance.outlineWidth = DEFAULT_OUTLINEWIDTH; Plugin.Instance.lineSpacing = DEFAULT_LINESPACING; Plugin.Instance.sizeDeltaX = DEFAULT_SIZEDELTAX; } public static void InitEffectColors(Dictionary<string, string> dict) { dict.Add("Note", "<#FFBD16>"); } public static void DisplayBugleNote(ScaleEnum note) { string uIDisplayName = ScaleHelper.GetAttributeOfScaleNote<UIDisplayNameAttribute>(note).UIDisplayName; string message = "Currently playing: " + uIDisplayName; DisplayMessage(message, "Note"); } public static void HideUI() { if ((Object)(object)Plugin.Instance.guiManager == (Object)null) { AddDisplayObject(); } if (((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.activeSelf) { ((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.SetActive(false); } } public static void DisplayMessage(string message, string colourKey) { if ((Object)(object)Plugin.Instance.guiManager == (Object)null) { AddDisplayObject(); } if (!((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.activeSelf) { ((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.SetActive(true); } ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text = ""; TextMeshProUGUI itemInfoDisplayTextMesh = Plugin.Instance.itemInfoDisplayTextMesh; ((TMP_Text)itemInfoDisplayTextMesh).text = ((TMP_Text)itemInfoDisplayTextMesh).text + Plugin.Instance.fontColors[colourKey] + " " + message + "</color>\n"; ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text = ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text.Replace("\n\n\n", "\n\n"); } } }