/// <summary> /// 放置位置まで移動する /// </summary> public void Move( FEZWindow window ) { // 現在の実装では、掲示板横に移動する var screenShot = window.CaptureWindow(); Point mapHeaderPosition = Point.Empty; while( !stopRequested ) { try { mapHeaderPosition = ImageComparator.Find( screenShot, Resource.map_move_handle ); break; } catch( FEZBotException e ) { screenShot.Save( GetType() + "_Move_" + DateTime.Now.ToFileTime() + ".png", ImageFormat.Png ); Console.WriteLine( "マップがどこに表示されているか見つけられなかった。リトライする。" ); } screenShot = window.CaptureWindow(); } var mapImageGeometry = FEZWindow.GetMapGeometry( mapHeaderPosition ); var detector = new CurrentPositionDetector( mapImageGeometry ); // マップが「全体」モードで表示されている場合、「周囲」モードに切り替える window.Activate(); var mapScaleButtonGeometry = FEZWindow.GetMapScaleButtonGeometry( mapHeaderPosition ); var mapScaleButtonImage = screenShot.Clone( mapScaleButtonGeometry, screenShot.PixelFormat ); if( ImageComparator.CompareStrict( mapScaleButtonImage, Resource.chat_log_plus_button ) ) { int x = mapScaleButtonGeometry.Left + mapScaleButtonGeometry.Width / 2; int y = mapScaleButtonGeometry.Top + mapScaleButtonGeometry.Height / 2; window.Click( new Point( x, y ) ); } VMultiKeyboardClient client = null; try { client = new VMultiKeyboardClient(); client.ClearKey(); // 2回左ステップ Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); InputKey( client, (byte)'Q' ); Thread.Sleep( TimeSpan.FromSeconds( 10 ) ); InputKey( client, (byte)'Q' ); Thread.Sleep( TimeSpan.FromSeconds( 2 ) ); // しばらくWキーで前進 while( !stopRequested ) { client.SetKey( (byte)'W' ); Thread.Sleep( TimeSpan.FromSeconds( 5 ) ); client.ClearKey(); try { screenShot = window.CaptureWindow(); var position = detector.Detect( screenShot ); if( position.Y <= -36 ) { break; } } catch( FEZBotException e ) { Console.Error.WriteLine( "座標が検出できない。とりあえず前進し続ける" ); } } // 右ステップ InputKey( client, (byte)'E' ); Thread.Sleep( TimeSpan.FromSeconds( 2 ) ); // 1歩後ろ InputKey( client, (byte)'S' ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); // 1歩右 InputKey( client, (byte)'D' ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); } catch( Exception e ) { Console.Error.WriteLine( e.Message ); } finally { if( client != null ) { client.Dispose(); } } }
/// <summary> /// クライアントのログイン処理を行う /// </summary> private void Login( FEZWindow window ) { // ログインウィンドウが出現するまで,startボタンの位置をクリックし続ける var startButtonGeometry = window.GetLoginStartButtonGeometry(); int x = startButtonGeometry.Left + startButtonGeometry.Width / 2; int y = startButtonGeometry.Top + startButtonGeometry.Height / 2; var loginGeometry = window.GetLoginDialogGeometry(); while( stopRequested == false ) { Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); var login = window.CaptureWindow( loginGeometry ); if( ImageComparator.Compare( login, Resource.login ) ) { break; } window.Click( new Point( x, y ) ); } // ログインID入力 //TODO: 大文字・が来た時の処理 //TODO: ログインIDを保存する,のオプションのチェックを外した状態にする var idInputGeometry = window.GetLoginDialogIDInputGeometry(); int idClickX = idInputGeometry.Right - 5; int idClickY = idInputGeometry.Top + idInputGeometry.Height / 2; window.Click( new Point( idClickX, idClickY ) ); Thread.Sleep( TimeSpan.FromMilliseconds( 200 ) ); for( int i = 0; i < 16; i++ ) { WindowsAPI.keybd_event( WindowsAPI.VK_BACK_SPACE, 0, 0, UIntPtr.Zero ); WindowsAPI.keybd_event( WindowsAPI.VK_BACK_SPACE, 0, WindowsAPI.KEYEVENTF_KEYUP, UIntPtr.Zero ); } foreach( char c in loginId.ToUpper().ToCharArray() ) { WindowsAPI.keybd_event( (byte)c, 0, 0, UIntPtr.Zero ); WindowsAPI.keybd_event( (byte)c, 0, WindowsAPI.KEYEVENTF_KEYUP, UIntPtr.Zero ); } Thread.Sleep( TimeSpan.FromMilliseconds( 200 ) ); // ログインPASS入力 window.Click( window.GetLoginDialogPasswordPosition() ); foreach( char c in loginPassword.ToUpper().ToCharArray() ) { WindowsAPI.keybd_event( (byte)c, 0, 0, UIntPtr.Zero ); WindowsAPI.keybd_event( (byte)c, 0, WindowsAPI.KEYEVENTF_KEYUP, UIntPtr.Zero ); } Thread.Sleep( TimeSpan.FromMilliseconds( 200 ) ); // ログインボタンを押す window.Click( window.GetLoginDialogLoginButtonPosition() ); // キャラクタ選択ダイアログが表示されるまで待つ var characterSelectDialog = window.GetCharacterSelectDialogGeometry(); while( !ImageComparator.Compare( window.CaptureWindow( characterSelectDialog ), Resource.character_select_dialog ) ) { var screenShot = window.CaptureWindow(); // メンテナンス中はログイン出来ないため、その旨メッセージダイアログが出る var maintenanceLoginErrorDialogGeometry = window.GetLoginMaintenanceErrorDialogGeometry(); var maintenanceLoginErrorDialogImage = screenShot.Clone( maintenanceLoginErrorDialogGeometry, screenShot.PixelFormat ); if( ImageComparator.CompareStrict( maintenanceLoginErrorDialogImage, Resource.maintenance_login_error ) ) { const int waitMinutes = 10; Console.WriteLine( "メンテナンス中のためログインできなかった。" + waitMinutes + "分待って再試行します。" ); Thread.Sleep( TimeSpan.FromMinutes( waitMinutes ) ); // okボタン押す window.Click( window.GetLoginMaintenanceErrorDialogOkButtonPosition() ); throw new FEZBotException( GetType() + "の例外: メンテナンスのためログインできなかった。" ); } // ログインボタン押し下げ後、何らかのお知らせダイアログが表示されることがあるので、 // 「閉じる」ボタンが見つからなくなるまで押し続ける try { var position = FindButton( screenShot, Resource.close_button ); window.Click( position ); } catch( FEZBotException e ) { } Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); } // 指定したキャラクタ名がダイアログに表示されるまで、別キャラクタを表示させる while( true ) { try { var characterName = GetCharacterName( window ); if( characterName == loginCharacterName ) { break; } } catch( FEZBotException e ) { Console.WriteLine( "ClientLaunchTaskの例外: " + e.Message ); } window.Click( window.GetCharacterSelectNextRightPosition() ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); } // ログインボタンを押す window.Click( window.GetCharacterSelectButtonPosition() ); Thread.Sleep( TimeSpan.FromMilliseconds( 200 ) ); window.Click( window.GetCharacterSelectConfirmDialogOKButtonPosition() ); Thread.Sleep( TimeSpan.FromMilliseconds( 200 ) ); // エイケルナル大陸をクリック // 初心者云々のダイアログが表示されている可能性があるので、2回クリックする var cecedriaContinentPosition = Point.Empty; while( true ) { try { cecedriaContinentPosition = FindButton( window.CaptureWindow(), Resource.map_akelnar ); break; } catch( FEZBotException e ) { Console.WriteLine( "本土大陸の位置を検出できなかった" ); } // チャット欄が最大化されていて、大陸名がグレーアウトしている可能性がある window.CloseChatDialog(); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); } // アズルウッド首都をクリック var cecedriaCapitalPosition = Point.Empty; while( true ) { try { cecedriaCapitalPosition = FindButton( window.CaptureWindow(), Resource.map_capital_azelwood ); break; } catch( FEZBotException e ) { Console.WriteLine( "首都の位置を検出できなかった" ); } window.Click( cecedriaContinentPosition ); Thread.Sleep( TimeSpan.FromMilliseconds( 200 ) ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); } // フィールドインボタンをクリック var fieldInPosition = Point.Empty; while( true ) { try { fieldInPosition = FindButton( window.CaptureWindow(), Resource.field_in_button ); break; } catch( FEZBotException e ) { Console.WriteLine( "フィールドインボタンを検出できなかった" ); } window.Click( cecedriaCapitalPosition ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); } window.OpenChatDialog(); window.Click( fieldInPosition ); Thread.Sleep( TimeSpan.FromSeconds( 1 ) ); }