private void OnPlayStatusChange(Object o, bool playing) { if (!playing) { if (tempPlaying) { ChatLogAll.AppendRtf(BmpChatParser.FormatRtf("Playback paused.")); tempPlaying = false; } if (LocalOrchestra.OrchestraEnabled) { LocalOrchestra.PerformerPlay(false); } FFXIV.hook.ClearLastPerformanceKeybinds(); } else { if (!tempPlaying) { ChatLogAll.AppendRtf(BmpChatParser.FormatRtf("Playback resumed.")); tempPlaying = true; } if (LocalOrchestra.OrchestraEnabled) { LocalOrchestra.PerformerPlay(true); } Statistics.Restart(); if (Properties.Settings.Default.OpenFFXIV) { FFXIV.hook.FocusWindow(); } } }
public BmpMain() { InitializeComponent(); this.UpdatePerformance(); BmpUpdate update = new BmpUpdate(); if (!Program.programOptions.DisableUpdate) { updateResult = update.ShowDialog(); if (updateResult == DialogResult.Yes) { updateTitle = update.version.updateTitle; updateText = update.version.updateText; updateResult = DialogResult.Yes; } if (updateResult == DialogResult.Ignore) { string log = " This is a preview of a future version of BMP! Please be kind and report any bugs or unexpected behaviors to discord channel."; ChatLogAll.AppendRtf(BmpChatParser.FormatRtf(log, Color.LightYellow, true)); } if (!string.IsNullOrEmpty(update.version.updateLog)) { string log = string.Format("= BMP Update =\n {0} \n", update.version.updateLog); ChatLogAll.AppendRtf(BmpChatParser.FormatRtf(log, Color.LightGreen, true)); } } this.Text = update.version.ToString(); // Clear local orchestra InfoTabs.TabPages.Remove(localOrchestraTab); LocalOrchestra.onMemoryCheck += delegate(Object o, bool status) { if (status) { this.FFXIV.memory.StopThread(); } else { this.FFXIV.memory.StartThread(); } }; FFXIV.findProcessRequest += delegate(Object o, EventArgs empty) { this.Invoke(t => t.FindProcess()); }; FFXIV.findProcessError += delegate(Object o, BmpHook.ProcessError error) { this.Invoke(t => t.ErrorProcess(error)); }; FFXIV.hotkeys.OnFileLoad += delegate(Object o, EventArgs empty) { this.Invoke(t => t.Hotkeys_OnFileLoad(FFXIV.hotkeys)); }; FFXIV.hook.OnKeyPressed += Hook_OnKeyPressed; FFXIV.memory.OnProcessReady += delegate(object o, Process proc) { this.Log(string.Format("[{0}] Process scanned and ready.", proc.Id)); if (Sharlayan.Reader.CanGetActors()) { if (!Sharlayan.Reader.CanGetCharacterId()) { this.Log("[MEMORY] Cannot get Character ID.\n Key bindings won't be loaded, load it manually by selecting an ID in the bottom right."); } if (!Sharlayan.Reader.CanGetChatInput()) { this.Log("[MEMORY] Cannot get chat input status.\n Automatic pausing when chatting won't work."); } if (!Sharlayan.Reader.CanGetPerformance()) { this.Log("[MEMORY] Cannot get performance status.\n Performance detection will not work. Force it to work by ticking Settings > Force playback."); } } else { List <Sharlayan.Models.Signature> signatures = Sharlayan.Signatures.Resolve().ToList(); int sigCount = signatures.Count; foreach (Sharlayan.Models.Signature sig in signatures) { if (Sharlayan.Scanner.Instance.Locations.ContainsKey(sig.Key)) { sigCount--; } else { Console.WriteLine(string.Format("Could not find signature {0}", sig.Key)); } } if (sigCount == signatures.Count) { this.Log(string.Format("[MEMORY] Cannot read memory ({0}/{1}). Functionality will be severely limited.", sigCount, signatures.Count)); this.Invoke(t => t.ErrorProcess(BmpHook.ProcessError.ProcessNonAccessible)); } else { this.Log("[MEMORY] Cannot read actors. Local performance will be broken."); } } }; FFXIV.memory.OnProcessLost += delegate(object o, EventArgs arg) { this.Log("Attached process exited."); }; FFXIV.memory.OnChatReceived += delegate(object o, ChatLogItem item) { this.Invoke(t => t.Memory_OnChatReceived(item)); }; FFXIV.memory.OnPerformanceChanged += delegate(object o, List <uint> ids) { this.Invoke(t => t.LocalOrchestraUpdate((o as FFXIVMemory).GetActorItems(ids))); }; FFXIV.memory.OnPerformanceReadyChanged += delegate(object o, bool performance) { this.Invoke(t => t.Memory_OnPerformanceReadyChanged(performance)); }; FFXIV.memory.OnCurrentPlayerJobChange += delegate(object o, CurrentPlayerResult res) { this.Invoke(t => t.Memory_OnCurrentPlayerJobChange(res)); }; FFXIV.memory.OnCurrentPlayerLogin += delegate(object o, CurrentPlayerResult res) { string world = string.Empty; if (Sharlayan.Reader.CanGetWorld()) { world = Sharlayan.Reader.GetWorld(); } if (string.IsNullOrEmpty(world)) { this.Log(string.Format("Character [{0}] logged in.", res.CurrentPlayer.Name)); } else { this.Log(string.Format("Character [{0}] logged in at [{1}].", res.CurrentPlayer.Name, world)); } if (!Program.programOptions.DisableUpdate) { BmpDonationChecker don = new BmpDonationChecker(res.CurrentPlayer.Name, world); don.OnDonatorResponse += delegate(Object obj, BmpDonationChecker.DonatorResponse donres) { if (donres.donator) { if (!string.IsNullOrEmpty(donres.donationMessage)) { this.Log(donres.donationMessage); } } this.Invoke(t => t.DonationStatus = donres.donator); }; } this.Invoke(t => t.UpdatePerformance()); }; FFXIV.memory.OnCurrentPlayerLogout += delegate(object o, CurrentPlayerResult res) { string format = string.Format("Character [{0}] logged out.", res.CurrentPlayer.Name); this.Log(format); }; FFXIV.memory.OnPartyChanged += delegate(object o, PartyResult res) { this.Invoke(t => t.LocalOrchestraUpdate()); }; Player.OnStatusChange += delegate(object o, PlayerStatus status) { this.Invoke(t => t.UpdatePerformance()); }; Player.OnSongSkip += OnSongSkip; Player.OnMidiProgressChange += OnPlayProgressChange; Player.OnMidiStatusChange += OnPlayStatusChange; Player.OnMidiStatusEnded += OnPlayStatusEnded; Player.OnMidiNote += OnMidiVoice; Player.OffMidiNote += OffMidiVoice; Player.Player.OpenInputDevice(Settings.GetMidiInput().name); Settings.OnMidiInputChange += delegate(object o, MidiInput input) { Player.Player.CloseInputDevice(); if (input.id != -1) { Player.Player.OpenInputDevice(input.name); Log(string.Format("Switched to {0} ({1})", input.name, input.id)); } }; Settings.OnKeyboardTest += delegate(object o, EventArgs arg) { foreach (FFXIVKeybindDat.Keybind keybind in FFXIV.hotkeys.GetPerformanceKeybinds()) { FFXIV.hook.SendSyncKeybind(keybind); Thread.Sleep(100); } }; Settings.OnForcedOpen += delegate(object o, bool open) { this.Invoke(t => { if (open) { Log(string.Format("Forced playback was enabled. You will not be able to use keybinds, such as spacebar.")); WarningLog("Forced playback enabled."); } t.UpdatePerformance(); }); }; Explorer.OnBrowserVisibleChange += delegate(object o, bool visible) { MainTable.SuspendLayout(); MainTable.RowStyles[MainTable.GetRow(ChatPlaylistTable)].Height = visible ? 0 : 100; MainTable.RowStyles[MainTable.GetRow(ChatPlaylistTable)].SizeType = visible ? SizeType.Absolute : SizeType.Percent; //ChatPlaylistTable.Invoke(t => t.Visible = !visible); MainTable.RowStyles[MainTable.GetRow(Explorer)].Height = visible ? 100 : 30; MainTable.RowStyles[MainTable.GetRow(Explorer)].SizeType = visible ? SizeType.Percent : SizeType.Absolute; MainTable.ResumeLayout(true); }; Explorer.OnBrowserSelect += Browser_OnMidiSelect; Playlist.OnMidiSelect += Playlist_OnMidiSelect; Playlist.OnPlaylistRequestAdd += Playlist_OnPlaylistRequestAdd; Playlist.OnPlaylistManualRequestAdd += Playlist_OnPlaylistManualRequestAdd; this.ResizeBegin += (s, e) => { LocalOrchestra.SuspendLayout(); }; this.ResizeEnd += (s, e) => { LocalOrchestra.ResumeLayout(true); }; if (Properties.Settings.Default.SaveLog) { FileTarget target = new NLog.Targets.FileTarget("chatlog") { FileName = "logs/ff14log.txt", Layout = @"${date:format=yyyy-MM-dd HH\:mm\:ss} ${message}", ArchiveDateFormat = "${shortdate}", ArchiveEvery = FileArchivePeriod.Day, ArchiveFileName = "logs/ff14log-${shortdate}.txt", Encoding = Encoding.UTF8, KeepFileOpen = true, }; var config = new NLog.Config.LoggingConfiguration(); config.AddRule(LogLevel.Info, LogLevel.Info, target); NLog.LogManager.Configuration = config; } string upath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming).FilePath; //Console.WriteLine(string.Format(".config: [{0}]", upath)); Settings.RefreshMidiInput(); Log("Bard Music Player initialized."); }
public void Log(string format) { ChatLogAll.AppendRtf(BmpChatParser.FormatRtf("[SYSTEM] " + format)); }
public void LogMidi(string format) { ChatLogAll.AppendRtf(BmpChatParser.FormatRtf("[MIDI] " + format, Color.LightPink)); }
// OnMidiVoice + OffMidiVoice is called with correct octave shift private void OnMidiVoice(Object o, NoteEvent onNote) { Statistics.AddNoteCount(); if (Properties.Settings.Default.Verbose) { FFXIVKeybindDat.Keybind keybind = FFXIV.hotkeys.GetKeybindFromNoteByte(onNote.note); if (keybind == null) { string ns = FFXIVKeybindDat.RawNoteByteToPianoKey(onNote.note); if (!string.IsNullOrEmpty(ns)) { string str = string.Format("Note {0} is out of range, it will not be played.", ns); ChatLogAll.AppendRtf(BmpChatParser.FormatRtf(str, "\\red255\\green200\\blue200")); } } } if (LocalOrchestra.OrchestraEnabled) { LocalOrchestra.ProcessOnNote(onNote); return; } if (Player.Status == PlayerStatus.Conducting) { return; } if (!Player.Player.IsPlaying) { return; } if (!FFXIV.IsPerformanceReady()) { return; } if (onNote.track != null) { // If from midi file if (onNote.track != Player.Player.LoadedTrack) { return; } } if (!FFXIV.memory.ChatInputOpen) { if (WantsSlow) { if (FFXIV.hotkeys.GetKeybindFromNoteByte(onNote.note) is FFXIVKeybindDat.Keybind keybind) { int delay = Decimal.ToInt32(Properties.Settings.Default.PlayHold); // Slow play Player.Player.InternalClock.Stop(); FFXIV.hook.SendSyncKey(keybind.GetKey(), true, true, false); //Bmp.Player.InternalClock.Sleep(delay); Thread.Sleep(delay); FFXIV.hook.SendSyncKey(keybind.GetKey(), true, false, true); Player.Player.InternalClock.Continue(); return; } } if (Properties.Settings.Default.AutoArpeggiate) { if (chordNotes.OnKey(onNote)) { // Chord detected and queued Console.WriteLine("Delay " + onNote + " by 100ms"); } } if (!chordNotes.HasTimer(onNote)) { if (FFXIV.hotkeys.GetKeybindFromNoteByte(onNote.note) is FFXIVKeybindDat.Keybind keybind) { if (WantsHold) { FFXIV.hook.SendKeybindDown(keybind); } else { FFXIV.hook.SendAsyncKeybind(keybind); } } } } }
public void LogMidi(string format) { ChatLogAll.AppendRtf(BmpChatParser.FormatRtf("[MIDI] " + format, "\\red255\\green180\\blue255")); }