// 位置ズレ自動調整 private async Task AutoGetGameWindowPositionAsync() { try { // 再び自動座標検出を行う var rectList = await ScreenShotProvider.GetGameWindowPositionAsync().ConfigureAwait(false); // その結果によって処理を分岐させる switch (rectList.Count) { case 0: { // 候補なしと表示する ScreenShotProvider.GameWindowRect = null; PutLog($"位置ズレ自動修正 : 失敗"); SaveScreenshotFlg.Value = false; } break; case 1: { // 即座にその候補で確定させる ScreenShotProvider.GameWindowRect = rectList[0]; PutLog("位置ズレ自動修正 : 成功"); PutLog($"ゲーム座標 : {Utility.GetRectStr((Rectangle)ScreenShotProvider.GameWindowRect)}"); SaveScreenshotFlg.Value = true; } break; default: { // 元の座標に最も近いものに合わせる int distance = int.MaxValue; Rectangle?nearestRect = null; foreach (var rect in rectList) { int diffX = ScreenShotProvider.GameWindowRect.Value.X - rect.X; int diffY = ScreenShotProvider.GameWindowRect.Value.Y - rect.Y; int diff = (diffX * diffX) + (diffY * diffY); if (distance > diff) { distance = diff; nearestRect = rect; } } ScreenShotProvider.GameWindowRect = nearestRect; PutLog("位置ズレ自動修正 : 成功"); PutLog($"ゲーム座標 : {Utility.GetRectStr((Rectangle)ScreenShotProvider.GameWindowRect)}"); SaveScreenshotFlg.Value = true; } break; } } catch { ScreenShotProvider.GameWindowRect = null; PutLog($"位置ズレ自動修正 : 失敗"); SaveScreenshotFlg.Value = false; } }
// 毎秒ごとの処理を行う private async void HelperTaskS() { if (SaveScreenshotFlg.Value) { // ズレ検出・修正処理 if (!ScreenShotProvider.CanGetScreenshot()) { // スクショが取得できなくなったのでその旨を通知する PutLog("エラー:ゲーム画面の位置ズレを検出しました"); await AutoGetGameWindowPositionAsync(); return; } // スクショから得られる情報を用いた修正 using (var screenShot = ScreenShotProvider.GetScreenshot()) { switch (SceneRecognition.JudgeGameScene(screenShot)) { case "戦闘中": MainModel.SetBattleBombTimer(screenShot, ref oldGauge, ref remainTime); break; case "委託": MainModel.SetConsignTimer(screenShot); break; case "戦術教室": MainModel.SetLectureTimer(screenShot); break; case "寮舎": MainModel.SetFoodTimer(screenShot); break; } } } else { // 常時座標認識 if (AutoSearchPositionFlg.Value) { GetGameWindowPosition(); } } }
// 定期的にスクリーンショットを取得し、そこに起因する処理を行う private void HelperTaskF() { if (!SaveScreenshotFlg.Value) { return; } using (var screenShot = ScreenShotProvider.GetScreenshot()) { // スクショが取得できるとscreenShotがnullにならない if (screenShot != null) { // シーン文字列を取得し、表示する string judgedScene = SceneRecognition.JudgeGameScene(screenShot); JudgedScene.Value = $"シーン判定 : {judgedScene}"; // 資材量を取得する // (戦闘中なら各種ボムの分量と残り秒数を読み取る) if (SupplyStore.SupplyListEachScene.ContainsKey(judgedScene)) { foreach (string supplyName in SupplyStore.SupplyListEachScene[judgedScene]) { if (SupplyStore.UpdateSupplyValue(screenShot, supplyName, AutoSupplyScreenShotFlg.Value, PutCharacterRecognitionFlg.Value)) { PutLog($"資材量追記:{supplyName}"); } } } // 戦闘中でなくなった場合、速やかにボムタイマーをリセットする if (judgedScene != "戦闘中" && judgedScene != "不明") { SettingsStore.BombChageTime1 = null; SettingsStore.BombChageTime2 = null; SettingsStore.BombChageTime3 = null; } } else { // スクショが取得できなくなったのでその旨を通知する PutLog("エラー:スクショが取得できなくなりました"); SaveScreenshotFlg.Value = false; } } }
public GameScreenSelectViewModel(List <Rectangle> rectList, SelectGameWindowAction dg) { this.rectList = rectList; this.dg = dg; // プロパティを設定 PageInfoStr = RectIndex.Select(x => $"[{x + 1}/{rectList.Count}] {Utility.GetRectStr(rectList[x])}").ToReadOnlyReactiveProperty(); GameWindowPage = RectIndex.Select(x => (BitmapSource)ScreenShotProvider.GetScreenBitmap(rectList[x]).ToImageSource()).ToReadOnlyReactiveProperty(); // コマンドを設定 PrevPageCommand.Subscribe(_ => { RectIndex.Value = (rectList.Count + RectIndex.Value - 1) % rectList.Count; }); NextPageCommand.Subscribe(_ => { RectIndex.Value = (rectList.Count + RectIndex.Value + 1) % rectList.Count; }); SelectPageCommand.Subscribe(_ => { dg(rectList[RectIndex.Value]); CloseWindow.Value = true; }); CancelCommand.Subscribe(_ => { dg(null); CloseWindow.Value = true; }); }
// コンストラクタ public MainViewModel() { // picフォルダが存在しない場合は作成する if (!Directory.Exists(@"pic\")) { Directory.CreateDirectory(@"pic\"); } // debugフォルダが存在しない場合は作成する if (!Directory.Exists(@"debug\")) { Directory.CreateDirectory(@"debug\"); } // 設定項目を初期化する if (!SettingsStore.Initialize()) { MessageBox.Show("設定を読み込めませんでした。\nデフォルトの設定で起動します。", Utility.SoftwareName, MessageBoxButton.OK, MessageBoxImage.Exclamation); } // 資材データベースを初期化する SupplyStore.Initialize(); // 設定内容を画面に反映する SetSettings(); // プロパティを設定 ForTwitterFlg.Subscribe(x => { SettingsStore.ForTwitterFlg = x; }); MainWindowPositionLeft.Subscribe(x => { SettingsStore.MainWindowRect[0] = x; SettingsStore.ChangeSettingFlg = true; }); MainWindowPositionTop.Subscribe(x => { SettingsStore.MainWindowRect[1] = x; SettingsStore.ChangeSettingFlg = true; }); MainWindowPositionWidth.Subscribe(x => { SettingsStore.MainWindowRect[2] = x; SettingsStore.ChangeSettingFlg = true; }); MainWindowPositionHeight.Subscribe(x => { SettingsStore.MainWindowRect[3] = x; SettingsStore.ChangeSettingFlg = true; }); MemoryWindowPositionFlg.Subscribe(x => { SettingsStore.MemoryWindowPositionFlg = x; }); AutoSearchPositionFlg.Subscribe(x => { SettingsStore.AutoSearchPositionFlg = x; }); AutoSupplyScreenShotFlg.Subscribe(x => { SettingsStore.AutoSupplyScreenShotFlg = x; }); PutCharacterRecognitionFlg.Subscribe(x => { SettingsStore.PutCharacterRecognitionFlg = x; }); DragAndDropPictureFlg.Subscribe(x => { SettingsStore.DragAndDropPictureFlg = x; }); // コマンドを設定 GetGameWindowPositionCommand.Subscribe(_ => GetGameWindowPosition()); SaveScreenshotCommand.Subscribe(_ => { try { string fileName = $"{Utility.GetTimeStrLong()}.png"; ScreenShotProvider.GetScreenshot(ForTwitterFlg.Value).Save($"pic\\{fileName}"); PutLog($"スクリーンショット : 成功"); PutLog($"ファイル名 : {fileName}"); } catch (Exception) { PutLog($"スクリーンショット : 失敗"); } }); CloseCommand.Subscribe(_ => { CloseWindow.Value = true; }); SoftwareInfoCommand.Subscribe(_ => { // ソフトの情報を返す // 参考→http://dobon.net/vb/dotnet/file/myversioninfo.html var assembly = Assembly.GetExecutingAssembly(); // AssemblyTitle string asmttl = ((AssemblyTitleAttribute) Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute))).Title; // AssemblyCopyright string asmcpy = ((AssemblyCopyrightAttribute) Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute))).Copyright; // AssemblyProduct string asmprd = ((AssemblyProductAttribute) Attribute.GetCustomAttribute(assembly, typeof(AssemblyProductAttribute))).Product; // AssemblyVersion var asmver = assembly.GetName().Version; MessageBox.Show( $"{asmttl} Ver.{asmver}\n{asmcpy}\n{asmprd}", Utility.SoftwareName, MessageBoxButton.OK, MessageBoxImage.Information); }); ImportSettingsCommand.Subscribe(_ => { // インスタンスを作成 var ofd = new OpenFileDialog { // ファイルの種類を設定 Filter = "設定ファイル(*.json)|*.json|全てのファイル (*.*)|*.*" }; // ダイアログを表示 if ((bool)ofd.ShowDialog()) { // 設定をインポート if (!SettingsStore.LoadSettings(ofd.FileName)) { PutLog("エラー:設定を読み込めませんでした"); } else { PutLog("設定を読み込みました"); } SetSettings(); } }); ExportSettingsCommand.Subscribe(_ => { // インスタンスを作成 var sfd = new SaveFileDialog { // ファイルの種類を設定 Filter = "設定ファイル(*.json)|*.json|全てのファイル (*.*)|*.*" }; // ダイアログを表示 if ((bool)sfd.ShowDialog()) { // 設定をエクスポート if (!SettingsStore.SaveSettings(sfd.FileName)) { PutLog("エラー:設定を保存できませんでした"); } else { PutLog("設定を保存しました"); } } }); OpenPicFolderCommand.Subscribe(_ => System.Diagnostics.Process.Start(@"pic\")); OpenSupplyViewCommand.Subscribe(_ => { if (SettingsStore.ShowSupplyWindowFlg) { return; } var vm = new SupplyViewModel(); var view = new Views.SupplyView { DataContext = vm }; view.Show(); SettingsStore.ShowSupplyWindowFlg = true; }).AddTo(Disposable); OpenTimerViewCommand.Subscribe(_ => { if (SettingsStore.ShowTimerWindowFlg) { return; } var vm = new TimerViewModel(); var view = new Views.TimerView { DataContext = vm }; view.Show(); SettingsStore.ShowTimerWindowFlg = true; }).AddTo(Disposable); ImportMainSupplyCommand.Subscribe(async _ => { // 資材のインポート機能(燃料・資金・ダイヤ) // インスタンスを作成 var ofd = new OpenFileDialog { // ファイルの種類を設定 Filter = "設定ファイル(*.csv)|*.csv|全てのファイル (*.*)|*.*", FileName = "MainSupply.csv" }; // ダイアログを表示 if ((bool)ofd.ShowDialog()) { // 資材をインポート PutLog("資材データを読み込み開始..."); if (await SupplyStore.ImportOldMainSupplyDataAsync(ofd.FileName)) { PutLog("資材データを読み込みました"); } else { PutLog("エラー:資材データを読み込めませんでした"); } } }); ImportSubSupply1Command.Subscribe(async _ => await ImportSubSupplyAsync(0)); ImportSubSupply2Command.Subscribe(async _ => await ImportSubSupplyAsync(1)); ImportSubSupply3Command.Subscribe(async _ => await ImportSubSupplyAsync(2)); ImportSubSupply4Command.Subscribe(async _ => await ImportSubSupplyAsync(3)); // タイマーを初期化し、定時タスクを登録して実行する // http://takachan.hatenablog.com/entry/2017/09/09/225342 var timer = new Timer(200); timer.Elapsed += (sender, e) => { try{ timer.Stop(); HelperTaskF(); } finally{ timer.Start(); } }; timer.Start(); var timer2 = new Timer(1000); timer2.Elapsed += (sender, e) => { try { timer2.Stop(); HelperTaskS(); } finally { timer2.Start(); } }; timer2.Start(); // ウィンドウ表示関係 if (SettingsStore.AutoSupplyWindowFlg) { OpenSupplyViewCommand.Execute(); } if (SettingsStore.AutoTimerWindowFlg) { OpenTimerViewCommand.Execute(); } // 最新版をチェックする CheckSoftwareVer(); }
// ゲーム画面の座標を取得する private async void GetGameWindowPosition() { PutLog("座標取得開始..."); try { // ゲーム画面の座標候補を検出する var rectList = await ScreenShotProvider.GetGameWindowPositionAsync().ConfigureAwait(false); // 候補数によって処理を分岐させる switch (rectList.Count) { case 0: { // 候補なしと表示する ScreenShotProvider.GameWindowRect = null; PutLog("座標取得 : 失敗"); SaveScreenshotFlg.Value = false; } break; case 1: { // 即座にその候補で確定させる ScreenShotProvider.GameWindowRect = rectList[0]; PutLog("座標取得 : 成功"); PutLog($"ゲーム座標 : {Utility.GetRectStr((Rectangle)ScreenShotProvider.GameWindowRect)}"); SaveScreenshotFlg.Value = true; } break; default: { // 各座標についてシーン認識を行い、認識可能だった座標が // 0個→従来通りの選択画面を表示する // 1個→その結果で確定させる // 2個以上→認識可能だった座標だけで選択画面を表示する var rectList2 = rectList.Where(rect => { var bitmap = ScreenShotProvider.GetScreenBitmap(rect); string scene = SceneRecognition.JudgeGameScene(bitmap); return(scene != "不明"); }).ToList(); switch (rectList2.Count) { case 0: { // 選択画面を表示する // http://blogs.wankuma.com/naka/archive/2009/02/12/168020.aspx var dispatcher = Application.Current.Dispatcher; if (dispatcher.CheckAccess()) { ShowSelectGameWindow(rectList); } else { dispatcher.Invoke(() => { ShowSelectGameWindow(rectList); }); } } break; case 1: { // 即座にその候補で確定させる ScreenShotProvider.GameWindowRect = rectList2[0]; PutLog("座標取得 : 成功"); PutLog($"ゲーム座標 : {Utility.GetRectStr((Rectangle)ScreenShotProvider.GameWindowRect)}"); SaveScreenshotFlg.Value = true; } break; default: { // 選択画面を表示する // http://blogs.wankuma.com/naka/archive/2009/02/12/168020.aspx var dispatcher = Application.Current.Dispatcher; if (dispatcher.CheckAccess()) { ShowSelectGameWindow(rectList2); } else { dispatcher.Invoke(() => { ShowSelectGameWindow(rectList2); }); } } break; } } break; } } catch (Exception) { PutLog($"座標取得 : 失敗"); } }