public static void ShowTitleCard( string title, int tryCount, DateTime recordingTime) { if (window == null) { window = new TitleCardView(); } window.VideoTitle = title; window.TryCount = tryCount; window.RecordingTime = recordingTime; window.Show(); if (!window.Config.IsAlwaysShow) { WPFHelper.BeginInvoke(async() => { await Task.Delay(TimeSpan.FromSeconds(2.7)); window.Close(); window = null; }); } }
private void AppendLogLine( string message, Exception ex = null, bool err = false) { // UIに出力する var text = $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}] {message}"; if (ex != null) { text += Environment.NewLine + ex.ToString(); } this.log.AppendLine(text); WPFHelper.BeginInvoke(() => this.RaisePropertyChanged(nameof(this.Log))); // NLogに出力する var log = $"[DISCORD] {message}"; if (ex == null && !err) { this.Logger.Trace(log); } else { this.Logger.Error(ex, log); } }
public static void LoadTTSCache() { if (Settings.Default.Player != WavePlayerTypes.WASAPIBuffered) { return; } var volume = Settings.Default.WaveVolume / 100f; WPFHelper.BeginInvoke(() => { }, DispatcherPriority.SystemIdle).Task.ContinueWith((_) => Task.Run(() => { var count = 0; try { Logger.Info("Started loading TTS caches."); BufferedWavePlayer.PlayerSet.LoadTTSHistory(); count = BufferedWavePlayer.Instance.BufferWaves(volume); } finally { Logger.Info($"Completed loading TTS caches. {count} files has loaded."); } })); }
public TimelineManagerView() { this.InitializeComponent(); this.SetLocale(Settings.Default.UILocale); this.LoadConfigViewResources(); if (!WPFHelper.IsDesignMode) { if (this.TimelineConfig.Enabled) { WPFHelper.BeginInvoke(async() => { try { await Task.Run(() => TimelineManager.Instance.LoadTimelineModels()); } catch (Exception ex) { TimelineModel.ShowRazorDumpFile(); ModernMessageBox.ShowDialog( ex.Message, "Timeline Loader", MessageBoxButton.OK, ex.InnerException); } }); } } this.StyleListView.SelectionChanged += (x, y) => { if (this.TimelineConfig.DesignMode) { var selectedStyle = this.StyleListView.SelectedItem as TimelineStyle; TimelineOverlay.HideDesignOverlay(false); TimelineOverlay.ShowDesignOverlay(selectedStyle); TimelineNoticeOverlay.HideDesignOverlay(); TimelineNoticeOverlay.ShowDesignOverlay(selectedStyle); } }; this.timer.Tick += (x, y) => { if (TimelineController.CurrentController != null) { // ついでにスタートボタンのラベルを切り替える this.StartButtonLabel = TimelineController.CurrentController.IsRunning ? StopString : StartString; } }; this.timer.Start(); }
public MainSimpleViewModel() { AppLog.AppendedLog += (s, e) => { WPFHelper.BeginInvoke(() => { this.RaisePropertyChanged(nameof(this.Messages)); }); }; }
public void RefreshNotices() { if (!this.Config.IsTimelineLiveUpdate) { WPFHelper.BeginInvoke(() => { this.noticesSource?.View?.Refresh(); }, DispatcherPriority.Background); } }
public void NotifyProperties() { var pis = this.GetType().GetProperties(); WPFHelper.BeginInvoke(() => { foreach (var pi in pis) { this.RaisePropertyChanged(pi.Name); } }); }
private void LogTextChanged(object sender, TextChangedEventArgs e) { var textBox = sender as TextBox; if (textBox != null) { WPFHelper.BeginInvoke(() => { textBox.CaretIndex = textBox.Text.Length; textBox.ScrollToEnd(); }); } }
private void BeginAnimation() { this.IsVisibleSyncIndicator = true; (this.View as MPTickerView)?.BeginAnimation(); WPFHelper.BeginInvoke(async() => { await Task.Delay(1200); this.IsVisibleSyncIndicator = false; }, DispatcherPriority.Normal); }
public void SelectedChanged() { if (this.isInitialize) { return; } Task.Run(() => { var mustStartIDs = new List <Guid>(); mustStartIDs.AddRange(this.ActiveSpells.Where(x => x.IsSelected).Select(x => x.ID)); mustStartIDs.AddRange(this.ActiveTickers.Where(x => x.IsSelected).Select(x => x.ID)); var mustStopIDs = new List <Guid>(); mustStopIDs.AddRange(this.InactiveSpells.Where(x => x.IsSelected).Select(x => x.ID)); mustStopIDs.AddRange(this.InactiveTickers.Where(x => x.IsSelected).Select(x => x.ID)); if (this.Spell != null) { this.Spell.TimersMustRunningForStart = mustStartIDs.ToArray(); this.Spell.TimersMustStoppingForStart = mustStopIDs.ToArray(); WPFHelper.BeginInvoke(() => this.RaisePropertyChanged(nameof(this.IsFiltered))); } else { if (this.Ticker != null) { this.Ticker.TimersMustRunningForStart = mustStartIDs.ToArray(); this.Ticker.TimersMustStoppingForStart = mustStopIDs.ToArray(); WPFHelper.BeginInvoke(() => this.RaisePropertyChanged(nameof(this.IsFiltered))); } } }); }
public void InitPluginCore( TabPage pluginScreenSpace, Label pluginStatusText) { // タイトルをセットする pluginScreenSpace.Text = "SPESPE"; WPFHelper.Start(); WPFHelper.BeginInvoke(async() => { // FFXIV_MemoryReaderを先にロードさせる await FFXIVReader.Instance.WaitForReaderToStartedAsync(); this.PluginStatusLabel = pluginStatusText; AppLog.LoadConfiguration(AppLog.HojoringConfig); this.AppLogger.Trace(Assembly.GetExecutingAssembly().GetName().ToString() + " start."); try { Logger.Init(); Logger.Write("[SPESPE] Start InitPlugin"); // .NET FrameworkとOSのバージョンを確認する if (!UpdateChecker.IsAvailableDotNet() || !UpdateChecker.IsAvailableWindows()) { return; } // メイン設定ファイルを読み込む Settings.Default.Load(); Settings.Default.ApplyRenderMode(); // 最小化する? if (Settings.Default.IsMinimizeOnStart) { ActGlobals.oFormActMain.WindowState = FormWindowState.Minimized; Application.DoEvents(); } // HojoringのSplashを表示する UpdateChecker.ShowSplash(); // 自身の場所を格納しておく var plugin = ActGlobals.oFormActMain.PluginGetSelfData(this.PluginRoot); if (plugin != null) { this.Location = plugin.pluginFile.DirectoryName; } // 設定ファイルを読み込む SpellPanelTable.Instance.Load(); SpellTable.Instance.Load(); TickerTable.Instance.Load(); TagTable.Instance.Load(); await Task.Run(() => { SpellPanelTable.Instance.Backup(); SpellTable.Instance.Backup(); TickerTable.Instance.Backup(); TagTable.Instance.Backup(); }); TTSDictionary.Instance.Load(); // 設定Panelを追加する var baseView = new BaseView(pluginScreenSpace.Font); pluginScreenSpace.Controls.Add(new ElementHost() { Child = baseView, Dock = DockStyle.Fill, Font = pluginScreenSpace.Font, }); // 本体を開始する PluginMainWorker.Instance.Begin(); TimelineController.Init(); // 付加情報オーバーレイを表示する LPSView.ShowLPS(); POSView.ShowPOS(); this.SetSwitchVisibleButton(); this.PluginStatusLabel.Text = "Plugin Started"; Logger.Write("[SPESPE] End InitPlugin"); // アップデートを確認する await Task.Run(() => this.Update()); } catch (Exception ex) { Logger.Write("InitPlugin error.", ex); if (this.PluginStatusLabel != null) { this.PluginStatusLabel.Text = "Plugin Initialize Error"; } ModernMessageBox.ShowDialog( "Plugin init error !", "ACT.SpecialSpellTimer", System.Windows.MessageBoxButton.OK, ex); } }); }
public static void LoadTTSCache( bool isNow = false) { if (Settings.Default.Player != WavePlayerTypes.WASAPIBuffered) { return; } var volume = Settings.Default.WaveVolume / 100f; WPFHelper.BeginInvoke(() => { }, DispatcherPriority.ContextIdle).Task.ContinueWith((_) => { if (!isNow) { Thread.Sleep(TimeSpan.FromSeconds(60)); } else { Thread.Sleep(TimeSpan.FromMilliseconds(100)); } var dirs = new[] { Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"anoyetta\ACT\tts cache"), DirectoryHelper.FindSubDirectory(@"resources\wav"), }; var files = new List <string>(); foreach (var dir in dirs) { if (!Directory.Exists(dir)) { continue; } files.AddRange(Directory.GetFiles(dir, "*.wav")); files.AddRange(Directory.GetFiles(dir, "*.mp3")); } if (files.Count > 0) { try { Logger.Info("Load TTS caches."); BufferedWavePlayer.Instance.BufferWaves( files, volume); } finally { Logger.Info("Load TTS caches, done."); } } }); }
protected override async void GetCombatant() { if ((DateTime.Now - this.combatantsTimestamp).TotalMilliseconds < Settings.Instance.MobList.RefreshRateMin) { return; } this.combatantsTimestamp = DateTime.Now; #region Test Mode // テストモード? if (Settings.Instance.MobList.TestMode) { var dummyPlayer = new Combatant() { ID = 1, PosX = 0, PosY = 0, PosZ = 0, }; var dummyTargets = new List <MobInfo>(); dummyTargets.Add(new MobInfo() { Name = "TEST:シルバーの吉田直樹", Rank = "EX", Combatant = new Combatant() { ID = 1, Name = "TEST:シルバーの吉田直樹", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 0, PosY = 10, PosZ = 10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new Combatant() { ID = 2, Name = "TEST:イクシオン", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new Combatant() { ID = 21, Name = "TEST:イクシオン", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:ソルト・アンド・ライト", Rank = "S", Combatant = new Combatant() { ID = 3, Name = "TEST:ソルト・アンド・ライト", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 10, PosY = 0, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:オルクス", Rank = "A", Combatant = new Combatant() { ID = 4, Name = "TEST:オルクス", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 100, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:宵闇のヤミニ", Rank = "B", Combatant = new Combatant() { ID = 5, Name = "TEST:宵闇のヤミニ", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 0, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:どこかのヒメちゃん", Rank = string.Empty, Combatant = new Combatant() { ID = 6, Name = "TEST:どこかのヒメちゃん", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = -100, PosY = -100, PosZ = 0, }, }); lock (this.TargetInfoLock) { this.TargetInfo = dummyTargets.First().Combatant; this.targetMobList = dummyTargets; } return; } #endregion Test Mode var combatants = FFXIVPlugin.Instance.GetCombatantList(); // 画面ダンプ用のCombatantsを更新する CombatantsViewModel.RefreshCombatants(combatants); var targets = default(IEnumerable <MobInfo>); await Task.Run(() => { targets = from x in combatants where ((x.MaxHP <= 0) || (x.MaxHP > 0 && x.CurrentHP > 0)) && Settings.Instance.MobList.TargetMobList.ContainsKey(x.Name) select new MobInfo() { Name = x.Name, Combatant = x, Rank = Settings.Instance.MobList.TargetMobList[x.Name].Rank, MaxDistance = Settings.Instance.MobList.TargetMobList[x.Name].MaxDistance, TTSEnabled = Settings.Instance.MobList.TargetMobList[x.Name].TTSEnabled, }; // 距離で絞り込む targets = targets.Where(x => x.Distance <= x.MaxDistance); }); lock (this.TargetInfoLock) { this.targetMobList = targets.ToList(); this.TargetInfo = this.targetMobList.FirstOrDefault()?.Combatant; if (this.TargetInfo == null) { var model = this.Model as MobListModel; if (model != null && model.MobList.Any()) { WPFHelper.BeginInvoke(model.ClearMobList); } } } }
public Task <FFXIVReaderStartingResult> WaitForReaderToStartedAsync( TabPage baseTabPage) => Task.Run(() => { var result = new FFXIVReaderStartingResult(); lock (this) { // 旧の単独DLL版が存在したら念のため削除する var dll = Path.Combine( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "FFXIV_MemoryReader.dll"); if (File.Exists(dll)) { var message = new StringBuilder(); try { File.Delete(dll); message.Clear(); message.AppendLine($@"""FFXIV_MemoryReader.dll"" was deleted."); message.AppendLine($@"Please, restart ACT."); WPFHelper.BeginInvoke(() => ModernMessageBox.ShowDialog( message.ToString(), "Warning", MessageBoxButton.OK)); } catch (Exception) { } if (File.Exists(dll)) { message.Clear(); message.AppendLine($@"""FFXIV_MemoryReader.dll"" is exists yet."); message.AppendLine($@"You should delete ""FFXIV_MemoryReader.dll""."); message.AppendLine(); message.AppendLine("Path:"); message.AppendLine(dll); WPFHelper.BeginInvoke(() => ModernMessageBox.ShowDialog( message.ToString(), "Warning", MessageBoxButton.OK)); } } if (this.MemoryPlugin != null) { result.Status = FFXIVReaderStartingStatus.AlreadyStarted; return(result); } var succeeded = false; WPFHelper.Invoke(() => { var parentTabControl = baseTabPage.Parent as TabControl; if (parentTabControl == null) { return; } var memoryReaderTabPage = new TabPage(); var dummyLabel = new Label(); parentTabControl.TabPages.Add(memoryReaderTabPage); this.tab = parentTabControl; this.tabPage = memoryReaderTabPage; try { this.MemoryPlugin = new MemoryPlugin(); this.MemoryPlugin.InitPlugin(memoryReaderTabPage, dummyLabel); succeeded = dummyLabel.Text.ContainsIgnoreCase("Started"); if (succeeded) { result.Status = FFXIVReaderStartingStatus.Started; } else { result.Status = FFXIVReaderStartingStatus.Error; result.Message = "Error occurred initializing FFXIV_MemoryReader."; this.MemoryPlugin?.DeInitPlugin(); this.MemoryPlugin = null; } } catch (Exception ex) { result.Status = FFXIVReaderStartingStatus.Error; result.Message = "Fatal error occurred initializing FFXIV_MemoryReader."; result.Exception = ex; ModernMessageBox.ShowDialog( result.Message, "Fatal Error", MessageBoxButton.OK, ex); } }, DispatcherPriority.Normal); this.IsAvailable = succeeded; } return(result); });
private void RefreshCombatants() { var player = default(Combatant); var party = default(IReadOnlyList <Combatant>); lock (SimulationLocker) { if (this.InSimulation && this.SimulationPlayer != null && this.SimulationParty.Any()) { player = this.SimulationPlayer; party = this.SimulationParty; } else { player = FFXIVPlugin.Instance?.GetPlayer(); party = FFXIVPlugin.Instance?.GetPartyList(); } } if (player != null) { this.player = player; } if (party != null) { var newList = new List <Combatant>(party); if (newList.Count < 1 && !string.IsNullOrEmpty(this.player?.Name)) { newList.Add(this.player); } // パーティリストを入れ替える this.partyList.Clear(); this.partyList.AddRange(newList); // 読み仮名リストをメンテナンスする var newPhonetics = from x in newList select new PCPhonetic() { ID = x.ID, NameFI = x.NameFI, NameIF = x.NameIF, NameII = x.NameII, Name = x.Name, JobID = x.JobID, }; WPFHelper.BeginInvoke(() => { var phonetics = TTSDictionary.Instance.Phonetics; var toAdd = newPhonetics.Where(x => !phonetics.Any(y => y.Name == x.Name)); phonetics.AddRange(toAdd); var toRemove = phonetics.Where(x => !newPhonetics.Any(y => y.Name == x.Name)).ToArray(); foreach (var item in toRemove) { phonetics.Remove(item); } }); } }
public void StartPlugin( TabPage pluginScreenSpace, Label pluginStatusText) { this.isLoaded = false; // タイトルをセットする pluginScreenSpace.Text = "ULTRA SCOUTER"; EnvironmentMigrater.Migrate(); MasterFilePublisher.Publish(); WPFHelper.Start(); WPFHelper.BeginInvoke(async() => { AppLog.LoadConfiguration(AppLog.HojoringConfig); this.Logger?.Trace(Assembly.GetExecutingAssembly().GetName().ToString() + " start."); try { this.PluginTabPage = pluginScreenSpace; this.PluginStatusLabel = pluginStatusText; if (!EnvironmentHelper.IsValidPluginLoadOrder()) { if (pluginStatusText != null) { pluginStatusText.Text = "Plugin Initialize Error"; } return; } EnvironmentHelper.GarbageLogs(); EnvironmentHelper.StartActivator(() => { BaseView.Instance.SetActivationStatus(false); this.EndPlugin(); }); this.Logger.Trace("[ULTRA SCOUTER] Start InitPlugin"); // .NET FrameworkとOSのバージョンを確認する if (!UpdateChecker.IsAvailableDotNet() || !UpdateChecker.IsAvailableWindows()) { NotSupportedView.AddAndShow(pluginScreenSpace); return; } // FFXIV.Framework.config を読み込ませる lock (FFXIV.Framework.Config.ConfigBlocker) { _ = FFXIV.Framework.Config.Instance; } // HojoringのSplashを表示する UpdateChecker.ShowSplash(); // 外部リソースをダウンロードする await ResourcesDownloader.Instance.DownloadAsync(); // 設定ファイルを読み込む Settings.Instance.Load(); Settings.Instance.MPTicker.UpdateUnlockMPSync(); // 設定ファイルをバックアップする await EnvironmentHelper.BackupFilesAsync( Settings.Instance.FileName); // 各種ファイルを読み込む await Task.Run(() => { TTSDictionary.Instance.Load(); Settings.Instance.MobList.LoadTargetMobList(); }); EnvironmentHelper.WaitInitActDone(); // FFXIVプラグインへのアクセスを開始する await Task.Run(() => { XIVPluginHelper.Instance.Start( Settings.Instance.PollingRate, Settings.Instance.FFXIVLocale); }); // ターゲット情報ワーカを開始する MainWorker.Instance.Start(); // タブページを登録する this.SetupPluginTabPages(pluginScreenSpace); // テキストコマンドの購読を追加する this.SubscribeTextCommands(); if (this.PluginStatusLabel != null) { this.PluginStatusLabel.Text = "Plugin started."; } this.Logger.Trace("[ULTRA SCOUTER] End InitPlugin"); // 共通ビューを追加する CommonViewHelper.Instance.AddCommonView( pluginScreenSpace.Parent as TabControl); this.isLoaded = true; // FFLogsの統計データベースをロードする StatisticsDatabase.Instance.Logger = Logger; await StatisticsDatabase.Instance.LoadAsync(); // アップデートを確認する await Task.Run(() => this.Update()); } catch (Exception ex) { this.Logger.Fatal(ex, "InitPlugin error."); this.ShowMessage("InitPlugin error.", ex); } }); }
public void StartPlugin( TabPage pluginScreenSpace, Label pluginStatusText) { // タイトルをセットする pluginScreenSpace.Text = "ULTRA SCOUTER"; WPFHelper.Start(); WPFHelper.BeginInvoke(async() => { // FFXIV_MemoryReaderを先にロードさせる await FFXIVReader.Instance.WaitForReaderToStartedAsync(); AppLog.LoadConfiguration(AppLog.HojoringConfig); this.Logger.Trace(Assembly.GetExecutingAssembly().GetName().ToString() + " start."); try { this.Logger.Trace("[ULTRA SCOUTER] Start InitPlugin"); this.PluginTabPage = pluginScreenSpace; this.PluginStatusLabel = pluginStatusText; // .NET FrameworkとOSのバージョンを確認する if (!UpdateChecker.IsAvailableDotNet() || !UpdateChecker.IsAvailableWindows()) { NotSupportedView.AddAndShow(pluginScreenSpace); return; } // 設定ファイルを読み込む Settings.Instance.Load(); // HojoringのSplashを表示する WPFHelper.Start(); UpdateChecker.ShowSplash(); // 各種ファイルを読み込む await Task.Run(() => { TTSDictionary.Instance.Load(); Settings.Instance.MobList.LoadTargetMobList(); }); // FFXIVプラグインへのアクセスを開始する await Task.Run(() => FFXIVPlugin.Instance.Start( Settings.Instance.PollingRate, Settings.Instance.FFXIVLocale)); // ターゲット情報ワーカを開始する MainWorker.Instance.Start(); // タブページを登録する this.SetupPluginTabPages(pluginScreenSpace); this.PluginStatusLabel.Text = "Plugin started."; this.Logger.Trace("[ULTRA SCOUTER] End InitPlugin"); // アップデートを確認する await Task.Run(() => this.Update()); } catch (Exception ex) { this.Logger.Fatal(ex, "InitPlugin error."); this.ShowMessage("InitPlugin error.", ex); } }); }
public TriggerTesterView() { this.InitializeComponent(); this.SetLocale(Settings.Default.UILocale); this.LoadConfigViewResources(); // ウィンドウのスタート位置を決める this.WindowStartupLocation = WindowStartupLocation.CenterScreen; this.MouseLeftButtonDown += (x, y) => this.DragMove(); this.Loaded += async(x, y) => { await WPFHelper.InvokeAsync(() => { this.MessageLabel.Content = "Loading, Please wait..."; this.MessageLabel.Visibility = Visibility.Visible; }, DispatcherPriority.Normal); // シミュレーションモードをONにする PluginMainWorker.Instance.InSimulation = true; TableCompiler.Instance.InSimulation = true; await Task.Delay(TimeSpan.FromSeconds(0.5)); await WPFHelper.BeginInvoke(() => { this.MessageLabel.Content = string.Empty; this.MessageLabel.Visibility = Visibility.Collapsed; }, DispatcherPriority.ApplicationIdle); }; this.CloseButton.Click += (x, y) => { this.testTimer.Stop(); this.Close(); }; this.Closed += (x, y) => { PluginMainWorker.Instance.InSimulation = false; TableCompiler.Instance.InSimulation = false; this.ClearTestCondition(); }; this.testTimer.Tick += this.TestTimer_Tick; this.RunButton.Click += async(x, y) => { // インスタンススペルを消去する SpellTable.Instance.RemoveInstanceSpellsAll(); await Task.Run(() => { lock (this) { this.testTimer.Stop(); this.isPause = false; foreach (var log in this.Logs) { log.IsDone = false; } this.prevTestTimestamp = DateTime.Now; this.TestTime = TimeSpan.Zero; this.testTimer.Start(); } }); }; this.PauseButton.Click += (x, y) => { this.isPause = !this.isPause; this.PauseButton.Content = this.isPause ? "Resume" : "Pause"; }; this.StopButton.Click += async(x, y) => { await Task.Run(() => { lock (this) { this.testTimer.Stop(); foreach (var log in this.Logs) { log.IsDone = false; } this.prevTestTimestamp = DateTime.MinValue; } PluginMainWorker.Instance.InSimulation = false; ChatLogWorker.Instance?.Write(true); }); // インスタンススペルを消去する SpellTable.Instance.RemoveInstanceSpellsAll(); }; this.OpenButton.Click += (x, y) => { var result = this.openFileDialog.ShowDialog(ActGlobals.oFormActMain); if (result != System.Windows.Forms.DialogResult.OK) { return; } this.LogFile = this.openFileDialog.FileName; this.LoadLog(); }; this.ApplyButton.Click += async(x, y) => { await WPFHelper.InvokeAsync(() => { this.MessageLabel.Content = "Loading, Please wait..."; this.MessageLabel.Visibility = Visibility.Visible; }, DispatcherPriority.Normal); await Task.Run(() => { // インスタンススペルを消去する SpellTable.Instance.RemoveInstanceSpellsAll(); // テスト条件を適用する this.ApplyTestCondition(); }); ModernMessageBox.ShowDialog( "Test Condition was applied.", "Trigger Simulator"); await Task.Delay(TimeSpan.FromSeconds(0.5)); await WPFHelper.BeginInvoke(() => { this.MessageLabel.Content = string.Empty; this.MessageLabel.Visibility = Visibility.Collapsed; }, DispatcherPriority.ApplicationIdle); }; this.ClearButton.Click += async(x, y) => { await WPFHelper.InvokeAsync(() => { this.MessageLabel.Content = "Loading, Please wait..."; this.MessageLabel.Visibility = Visibility.Visible; }, DispatcherPriority.Normal); await Task.Run(() => { // インスタンススペルを消去する SpellTable.Instance.RemoveInstanceSpellsAll(); // テスト条件を解除する this.ClearTestCondition(); }); ModernMessageBox.ShowDialog( "Test Condition was cleard.", "Trigger Simulator"); await Task.Delay(TimeSpan.FromSeconds(0.5)); await WPFHelper.BeginInvoke(() => { this.MessageLabel.Content = string.Empty; this.MessageLabel.Visibility = Visibility.Collapsed; }, DispatcherPriority.ApplicationIdle); }; // AddLogLine this.AddLogLineButton.Click += async(x, y) => await this.AddLogLineAsync(); this.AddLogLineTextBox.KeyDown += async(x, y) => { if (y.Key == Key.Enter) { if (!string.IsNullOrEmpty(this.AddLogLineTextBox.Text)) { this.LogLine = this.AddLogLineTextBox.Text; } await this.AddLogLineAsync(); } }; }
protected override async void GetCombatant() { if ((DateTime.Now - this.combatantsTimestamp).TotalMilliseconds < Settings.Instance.MobList.RefreshRateMin) { return; } this.combatantsTimestamp = DateTime.Now; #region Test Mode // テストモード? if (Settings.Instance.MobList.TestMode) { var dummyPlayer = new Combatant() { ID = 1, PosX = 0, PosY = 0, PosZ = 0, }; var dummyTargets = new List <MobInfo>(); dummyTargets.Add(new MobInfo() { Name = "TEST:シルバーの吉田直樹", Rank = "EX", Combatant = new Combatant() { ID = 1, Name = "TEST:シルバーの吉田直樹", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 0, PosY = 10, PosZ = 10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new Combatant() { ID = 2, Name = "TEST:イクシオン", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new Combatant() { ID = 21, Name = "TEST:イクシオン", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:ソルト・アンド・ライト", Rank = "S", Combatant = new Combatant() { ID = 3, Name = "TEST:ソルト・アンド・ライト", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 10, PosY = 0, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:オルクス", Rank = "A", Combatant = new Combatant() { ID = 4, Name = "TEST:オルクス", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 100, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:宵闇のヤミニ", Rank = "B", Combatant = new Combatant() { ID = 5, Name = "TEST:宵闇のヤミニ", type = ObjectType.Monster, MaxHP = 1, Player = dummyPlayer, PosX = 0, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = Combatant.NameToInitial("Himeko Flower", ConfigBridge.Instance.PCNameStyle), Rank = "DEAD", Combatant = new Combatant() { ID = 7, Name = Combatant.NameToInitial("Himeko Flower", ConfigBridge.Instance.PCNameStyle), type = ObjectType.PC, Job = (byte)JobIDs.BLM, MaxHP = 43462, Player = dummyPlayer, PosX = -100, PosY = -100, PosZ = 0, }, }); lock (this.TargetInfoLock) { this.TargetInfo = dummyTargets.First().Combatant; this.targetMobList = dummyTargets; } return; } #endregion Test Mode var combatants = FFXIVPlugin.Instance.GetCombatantList(); // 画面ダンプ用のCombatantsを更新する CombatantsViewModel.RefreshCombatants(combatants); var targets = default(IEnumerable <MobInfo>); await Task.Run(() => { targets = from x in combatants where ((x.MaxHP <= 0) || (x.MaxHP > 0 && x.CurrentHP > 0)) && Settings.Instance.MobList.TargetMobList.ContainsKey(x.Name) select new MobInfo() { Name = x.Name, Combatant = x, Rank = Settings.Instance.MobList.TargetMobList[x.Name].Rank, MaxDistance = Settings.Instance.MobList.TargetMobList[x.Name].MaxDistance, TTSEnabled = Settings.Instance.MobList.TargetMobList[x.Name].TTSEnabled, }; // 戦闘不能者を検出する? if (Settings.Instance.MobList.IsEnabledDetectDeadmen) { var deadmenInfo = Settings.Instance.MobList.GetDetectDeadmenInfo; var party = FFXIVPlugin.Instance.GetPartyList(); var deadmen = from x in party where !x.IsPlayer && x.MaxHP > 0 && x.CurrentHP <= 0 select new MobInfo() { Name = x.NameForDisplay, Combatant = x, Rank = deadmenInfo.Rank, MaxDistance = deadmenInfo.MaxDistance, TTSEnabled = deadmenInfo.TTSEnabled, }; targets = targets.Concat(deadmen); } // 距離で絞り込む targets = targets.Where(x => x.Distance <= x.MaxDistance); }); lock (this.TargetInfoLock) { this.targetMobList = targets.ToList(); this.TargetInfo = this.targetMobList.FirstOrDefault()?.Combatant; if (this.TargetInfo == null) { var model = this.Model as MobListModel; if (model != null && model.MobList.Any()) { WPFHelper.BeginInvoke(model.ClearMobList); } } } }
protected override void GetCombatant() { lock (this.TargetInfoLock) { var now = DateTime.Now; if ((now - this.combatantsTimestamp).TotalMilliseconds < Settings.Instance.MobList.RefreshRateMin) { return; } this.combatantsTimestamp = now; } #region Test Mode // テストモード? if (Settings.Instance.MobList.TestMode) { var dummyTargets = new List <MobInfo>(); dummyTargets.Add(new MobInfo() { Name = "TEST:シルバーの吉田直樹", Rank = "EX", Combatant = new CombatantEx() { ID = 1, Name = "TEST:シルバーの吉田直樹", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 0, PosY = 10, PosZ = 10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new CombatantEx() { ID = 2, Name = "TEST:イクシオン", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new CombatantEx() { ID = 21, Name = "TEST:イクシオン", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:ソルト・アンド・ライト", Rank = "S", Combatant = new CombatantEx() { ID = 3, Name = "TEST:ソルト・アンド・ライト", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 10, PosY = 0, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:オルクス", Rank = "A", Combatant = new CombatantEx() { ID = 4, Name = "TEST:オルクス", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 100, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:宵闇のヤミニ", Rank = "B", Combatant = new CombatantEx() { ID = 5, Name = "TEST:宵闇のヤミニ", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 0, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = CombatantEx.NameToInitial("TEST:Hime Hana", ConfigBridge.Instance.PCNameStyle), Rank = "DEAD", Combatant = new CombatantEx() { ID = 7, Name = CombatantEx.NameToInitial("TEST:Hime Hana", ConfigBridge.Instance.PCNameStyle), Type = (byte)Actor.Type.Monster, Job = (byte)JobIDs.BLM, MaxHP = 43462, PosX = -100, PosY = -100, PosZ = 0, }, }); lock (this.TargetInfoLock) { this.TargetInfo = dummyTargets.First().Combatant; this.targetMobList = dummyTargets; } return; } #endregion Test Mode if ((CombatantsManager.Instance.CombatantsMainCount + CombatantsManager.Instance.CombatantsOtherCount) <= 0) { return; } var targets = default(IEnumerable <MobInfo>); var combatants = CombatantsManager.Instance.GetCombatants(); // モブを検出する IEnumerable <MobInfo> GetTargetMobs() { foreach (var x in combatants) { if (string.IsNullOrEmpty(x?.Name)) { continue; } if (x.ActorType == Actor.Type.PC || x.ActorType == Actor.Type.Monster) { if (x.MaxHP <= 0 || (x.MaxHP > 0 && x.CurrentHP <= 0)) { continue; } } var targetInfo = Settings.Instance.MobList.GetTargetMobInfo(x.Name); if (string.IsNullOrEmpty(targetInfo.Name)) { continue; } yield return(new MobInfo() { Name = x.Name, Combatant = x, Rank = targetInfo.Rank, MaxDistance = targetInfo.MaxDistance, TTSEnabled = targetInfo.TTSEnabled, }); } } targets = GetTargetMobs(); // 戦闘不能者を検出する? var deadmenInfo = Settings.Instance.MobList.GetDetectDeadmenInfo; if (!string.IsNullOrEmpty(deadmenInfo.Name)) { var party = CombatantsManager.Instance.GetPartyList(); var deadmen = from x in party where x != null && !x.IsPlayer && x.ActorType == Actor.Type.PC && x.MaxHP > 0 && x.CurrentHP <= 0 select new MobInfo() { Name = x.NameForDisplay, Combatant = x, Rank = deadmenInfo.Rank, MaxDistance = deadmenInfo.MaxDistance, TTSEnabled = deadmenInfo.TTSEnabled, }; targets = targets.Concat(deadmen); } // クエリを実行する targets = targets.ToArray(); lock (this.TargetInfoLock) { this.targetMobList = targets .Where(x => x.Distance <= x.MaxDistance) .ToList(); this.TargetInfo = this.targetMobList.FirstOrDefault()?.Combatant; if (this.TargetInfo == null) { var model = this.Model as MobListModel; if (model != null && model.MobList.Any()) { WPFHelper.BeginInvoke(model.ClearMobList); } } } if (combatants != null) { CombatantsViewModel.RefreshCombatants(combatants.ToArray()); } }
public void InitPluginCore( TabPage pluginScreenSpace, Label pluginStatusText) { // タイトルをセットする pluginScreenSpace.Text = "SPESPE"; EnvironmentMigrater.Migrate(); MasterFilePublisher.Publish(); WPFHelper.Start(); WPFHelper.BeginInvoke(async() => { AppLog.LoadConfiguration(AppLog.HojoringConfig); this.AppLogger?.Trace(Assembly.GetExecutingAssembly().GetName().ToString() + " start."); try { this.PluginStatusLabel = pluginStatusText; if (!EnvironmentHelper.IsValidPluginLoadOrder()) { pluginStatusText.Text = "Plugin Initialize Error"; return; } EnvironmentHelper.GarbageLogs(); EnvironmentHelper.StartActivator(() => { BaseView.Instance.SetActivationStatus(false); this.DeInitPluginCore(); }); Logger.Init(); Logger.Write("[SPESPE] Start InitPlugin"); // .NET FrameworkとOSのバージョンを確認する if (!UpdateChecker.IsAvailableDotNet() || !UpdateChecker.IsAvailableWindows()) { NotSupportedView.AddAndShow(pluginScreenSpace); return; } // メイン設定ファイルを読み込む Settings.Default.Load(); Settings.Default.ApplyRenderMode(); Settings.Default.StartAutoSave(); // 最小化する? if (Settings.Default.IsMinimizeOnStart) { ActGlobals.oFormActMain.WindowState = FormWindowState.Minimized; } // HojoringのSplashを表示する UpdateChecker.ShowSplash(); // 自身の場所を格納しておく var plugin = ActGlobals.oFormActMain.PluginGetSelfData(this.PluginRoot); if (plugin != null) { this.Location = plugin.pluginFile.DirectoryName; } // 設定ファイルを読み込む SpellPanelTable.Instance.Load(); SpellTable.Instance.Load(); TickerTable.Instance.Load(); TagTable.Instance.Load(); // 設定ファイルをバックアップする await EnvironmentHelper.BackupFilesAsync( Settings.Default.FileName, SpellPanelTable.Instance.DefaultFile, SpellTable.Instance.DefaultFile, TickerTable.Instance.DefaultFile, TagTable.Instance.DefaultFile, FFXIV.Framework.Config.FileName); TTSDictionary.Instance.Load(); // 設定Panelを追加する var baseView = new BaseView(pluginScreenSpace.Font); pluginScreenSpace.Controls.Add(new ElementHost() { Child = baseView, Dock = DockStyle.Fill, Font = pluginScreenSpace.Font, }); EnvironmentHelper.WaitInitActDone(); // 本体を開始する PluginMainWorker.Instance.Begin(); TimelineController.Init(); // 付加情報オーバーレイを表示する LPSView.ShowLPS(); POSView.ShowPOS(); this.SetSwitchVisibleButton(); this.PluginStatusLabel.Text = "Plugin Started"; Logger.Write("[SPESPE] End InitPlugin"); // 共通ビューを追加する CommonViewHelper.Instance.AddCommonView( pluginScreenSpace.Parent as TabControl); this.isLoaded = true; // アップデートを確認する await Task.Run(() => this.Update()); } catch (Exception ex) { Logger.Write("InitPlugin error.", ex); if (this.PluginStatusLabel != null) { this.PluginStatusLabel.Text = "Plugin Initialize Error"; } ModernMessageBox.ShowDialog( "Plugin init error !", "ACT.SpecialSpellTimer", System.Windows.MessageBoxButton.OK, ex); } }); }
private void NotifyTrigger( TimelineTriggerModel tri) { if (string.IsNullOrEmpty(tri.Name) && string.IsNullOrEmpty(tri.Text) && string.IsNullOrEmpty(tri.Notice)) { return; } var now = DateTime.Now; var log = $"{TLSymbol} Notice from TL. " + $"name={tri.Name}, text={tri.TextReplaced}, notice={tri.NoticeReplaced}"; var notice = tri.NoticeReplaced ?? string.Empty; notice = TimelineExpressionsModel.ReplaceText(notice); if (string.Equals(notice, "auto", StringComparison.OrdinalIgnoreCase)) { notice = !string.IsNullOrEmpty(tri.Text) ? tri.Text : tri.Name; if (!string.IsNullOrEmpty(notice)) { notice += "。"; } } var isSync = (TimelineRazorModel.Instance?.SyncTTS ?? false) || tri.NoticeSync.Value; RaiseLog(log); NotifySoundAsync(notice, tri.NoticeDevice.GetValueOrDefault(), isSync, tri.NoticeVolume, tri.NoticeOffset); var vnotices = tri.VisualNoticeStatements .Where(x => x.Enabled.GetValueOrDefault()); var inotices = tri.ImageNoticeStatements .Where(x => x.Enabled.GetValueOrDefault()); if (!vnotices.Any() && !inotices.Any()) { return; } var placeholders = TimelineManager.Instance.GetPlaceholders(); foreach (var v in vnotices) { // ヒットしたログのシーケンスを格納する // ソート用 v.LogSeq = tri.LogSeq; switch (v.Text) { case TimelineVisualNoticeModel.ParentTextPlaceholder: v.TextToDisplay = tri.TextReplaced; break; case TimelineVisualNoticeModel.ParentNoticePlaceholder: v.TextToDisplay = tri.NoticeReplaced; break; default: v.TextToDisplay = tri.SyncMatch != null && tri.SyncMatch.Success ? tri.SyncMatch.Result(v.Text) : v.Text; break; } if (string.IsNullOrEmpty(v.TextToDisplay)) { continue; } v.TextToDisplay = TimelineExpressionsModel.ReplaceText(v.TextToDisplay); // PC名をルールに従って置換する v.TextToDisplay = XIVPluginHelper.Instance.ReplacePartyMemberName( v.TextToDisplay, Settings.Default.PCNameInitialOnDisplayStyle); WPFHelper.BeginInvoke(async() => { if (v.Delay > 0) { await Task.Delay(TimeSpan.FromSeconds(v.Delay ?? 0)); } TimelineNoticeOverlay.NoticeView?.AddNotice(v); v.SetSyncToHide(placeholders); v.AddSyncToHide(); }); } foreach (var i in inotices) { WPFHelper.BeginInvoke(async() => { if (i.Delay > 0) { await Task.Delay(TimeSpan.FromSeconds(i.Delay ?? 0)); } i.StartNotice(); i.SetSyncToHide(placeholders); i.AddSyncToHide(); }); } }
private void NotifyActivity( TimelineActivityModel act) { if (string.IsNullOrEmpty(act.Name) && string.IsNullOrEmpty(act.Text) && string.IsNullOrEmpty(act.Notice)) { act.IsNotified = true; return; } var now = DateTime.Now; var offset = this.CurrentTime - act.Time; var log = $"{TLSymbol} Notice from TL. " + $"name={act.Name}, text={act.TextReplaced}, notice={act.NoticeReplaced}, offset={offset.TotalSeconds:N1}"; var notice = act.NoticeReplaced ?? string.Empty; notice = TimelineExpressionsModel.ReplaceText(notice); if (string.Equals(notice, "auto", StringComparison.OrdinalIgnoreCase)) { notice = !string.IsNullOrEmpty(act.TextReplaced) ? act.TextReplaced : act.Name; if (offset.TotalSeconds <= -1.0) { var offsetText = (offset.TotalSeconds * -1).ToString("N0"); notice += $" まで、あと{offsetText}秒"; } if (!string.IsNullOrEmpty(notice)) { notice += "。"; } } var isSync = (TimelineRazorModel.Instance?.SyncTTS ?? false) || act.NoticeSync.Value; RaiseLog(log); NotifySoundAsync(notice, act.NoticeDevice.GetValueOrDefault(), isSync, act.NoticeVolume); var vnotices = act.VisualNoticeStatements .Where(x => x.Enabled.GetValueOrDefault()) .Select(x => x.Clone()); var inotices = act.ImageNoticeStatements .Where(x => x.Enabled.GetValueOrDefault()); if (!vnotices.Any() && !inotices.Any()) { return; } var placeholders = TimelineManager.Instance.GetPlaceholders(); foreach (var v in vnotices) { // ソート用にログ番号を格納する // 優先順位は最後尾とする v.LogSeq = long.MaxValue; v.Timestamp = DateTime.Now; switch (v.Text) { case TimelineVisualNoticeModel.ParentTextPlaceholder: v.TextToDisplay = act.TextReplaced; break; case TimelineVisualNoticeModel.ParentNoticePlaceholder: v.TextToDisplay = act.NoticeReplaced; break; default: v.TextToDisplay = act.SyncMatch != null && act.SyncMatch.Success ? act.SyncMatch.Result(v.Text) : v.Text; break; } if (string.IsNullOrEmpty(v.TextToDisplay)) { continue; } v.TextToDisplay = TimelineExpressionsModel.ReplaceText(v.TextToDisplay); // PC名をルールに従って置換する v.TextToDisplay = XIVPluginHelper.Instance.ReplacePartyMemberName( v.TextToDisplay, Settings.Default.PCNameInitialOnDisplayStyle); WPFHelper.BeginInvoke(async() => { if (v.Delay > 0) { await Task.Delay(TimeSpan.FromSeconds(v.Delay ?? 0)); } TimelineNoticeOverlay.NoticeView?.AddNotice(v); v.SetSyncToHide(placeholders); v.AddSyncToHide(); }); } foreach (var i in inotices) { WPFHelper.BeginInvoke(async() => { if (i.Delay > 0) { await Task.Delay(TimeSpan.FromSeconds(i.Delay ?? 0)); } i.StartNotice(); i.SetSyncToHide(placeholders); i.AddSyncToHide(); }); } }