Pythonフラグ

画像 Yo-ho-ho、Khabrovites!



ITコミュニティは暗号通貨とそのマイニングを熱心に監視していますが、私はクリプトとそれに関連するすべてが主流になるずっと前にマイニングされたものをマイニングすることにしました。 もちろん、これはMMOゲームのゲームゴールドに関するものです。



Python 3.6と仲間のプログラマーのアドバイスは、このアイデアの実現に役立ちました。 この記事は特定のゲームの例に基づいていますが、その目的はハックのストーリーを伝えることではなく、 Pythonを称賛し、 プログラマーではない人が何ができるのか、なぜそれがとてもクールなのかをまだマスターしていない人に見せることです





すぐに発言する価値があります:





タスクソルト



GuildWars2というゲームがあり、クリスマスイベント(ミニゲーム)を開始しました。これは、ベルだけのギターヒーローに非常に似ています。



画像



ゲームの意味は、どのトラックのどの円が中心になり、キャラクターが立っているかに応じて、ノートボタン1-2-3-4および6-7-8-9をタイムリーに押すことです。 非常に興味深い場合は、ギルドウォーズ2コーラスベルを入力して、YouTubeでビデオを見ることができます。



不正確ではありますが、完全に通過するために、彼らは市場で約5.5シルバーの価格で販売できる貴重なギフトの最大数を与えます。 私は、このイベントの連続通過の日のために、あなたは〜3300ギフトを作ることができ、これは180以上の純金であり、その価格はユニットあたり2ルーブルであると計算しました。 闇市場で。 絶対的にはコペックですが、同じ暗号マイニングと比較して非常に良いでしょう? 特に、このために高価なビデオカードや有料アカウントは必要ないと考えている場合。



一般的に、イデオロギー的なボトボドの私の小さな手は彼らの髪をとかし、少なくともスポーツの関心からは、この行動を自動化することにしました。



ステップ0。分析



自動化のために必要なものは、ピクセルの認識とボタンの押下の2つだけです。

ここでは、少し余談をし、プログラマーではない私が、C ++、C#、PHP、デルファイ、さらにはmasm32環境のアセンブラーでコーディングしようとしたと言う必要があります。 この段階でのPythonの選択はほぼランダムでした。 「Pythonでヒープを試してみませんか? より便利な場合はどうなりますか?」 何らかの情報に基づいた選択ではありませんでした。当時のPythonのクールさは想像もしていませんでした。



ピクセルの色にしがみつく方法を理解する必要があり、マウスポインターとそのRGB値の下に色を表示する簡単なスポイトを探し始めました。 ゲームから、分析のためにバンドにビデオを記録したので、フォトショップと画像編集者は適合しませんでした。 実際にビデオをスクリーンショットにカットしないでください。 リアルタイムで作業し、座標を表示するシンプルなものが必要でした。 残念ながら、Googleは適切なユーティリティを見つけられなかったため、自分で調理することにしました。 起こったことは次のとおりです。



スポイラーの下にピペットコードが隠されていた
from graphics import *#       ( ) import pyautogui #      (   ) import time #  . ( ) def main():#    win = GraphWin("pipetka", 200, 200, autoflush=True)#    200200     x, y = pyautogui.position()#  x, y   r, g, b = pyautogui.pixel(x, y)#   r, g, b  ColorDot = Circle(Point(100, 100), 25)#  ,   ColorDot.setFill(color_rgb(r, g, b))#        ColorDot.draw(win)#    win RGBtext = Entry(Point(win.getWidth()/2, 25), 10)#  RGB  RGBtext.draw(win)#    win RGBstring = Entry(Point(win.getWidth()/2, 45), 10)#    web  RGBstring.draw(win)#    win Coordstring = Entry(Point(win.getWidth() / 2, 185), 10)#    Coordstring.draw(win)#    win while True: #    time.sleep(0.1)#   0.1 ,       x, y = pyautogui.position()#  x, y   r, g, b = pyautogui.pixel(x, y)#   r, g, b  ColorDot.setFill(color_rgb(r, g, b))#  RGBtext.setText(pyautogui.pixel(x, y))# RGB RGBstring.setText(color_rgb(r, g, b))# web  Coordstring.setText(str(x)+" "+ str(y) )#  win.flush()#      #   . main()#  .
      
      







画像



アクションのタルサ。 私は彼女といじくり回しましたが、残念ながら、ピクセルをキャプチャするという私の最初のアイデアはすでに途中にあり、失敗でした。



1)色とプレスの約束を決定する少しの時間



2)円の色は非常に不均一です



3)カメラの位置のわずかなずれが大きく干渉します



しかし、もう少し掘り下げて、適切な色のピクセルではなく、適切な場所で明るさが変化するというアイデアを思いつきました。 ピペットの実験により、円は競技場の背景よりもR、GまたはBスケール(色に応じて)ではるかに高いことが示されました。 その結果、円が最大サイズになる8つのポイントを選択しました。



画像



ステップ1.サークル認識コード



アナライザーコード
 import time#   (  ) import pyautogui#  (   ) import winsound#  ,  ,    (  ) import keyboard#     (   ) def analyzer(): etalon = [pyautogui.pixel(355, 288), pyautogui.pixel(460, 200), pyautogui.pixel(600, 130),\ pyautogui.pixel(735, 112), pyautogui.pixel(875, 109), pyautogui.pixel(1000, 145), \ pyautogui.pixel(1139, 203), pyautogui.pixel(1260, 290) ]#   trigger = [0,0,0,0,0,0,0,0]# ,   while True: change = [pyautogui.pixel(355, 288), pyautogui.pixel(460, 200), pyautogui.pixel(600, 130),\ pyautogui.pixel(735, 112), pyautogui.pixel(875, 109), pyautogui.pixel(1000, 145), \ pyautogui.pixel(1139, 203), pyautogui.pixel(1260, 290) ] #   change     for nomer in range(0,8): if change[nomer][0] > etalon[nomer][0]+50 or change[nomer][1] > etalon[nomer][1]+50 or change[nomer][2] > etalon[nomer][2]+50: if trigger[nomer] == 0: #     R,G  B    +50     trigger[nomer] = 1#   else: if trigger[nomer] == 1: #      trigger[nomer] = 0 #   print("push " +str(nomer) + time.strftime(' %X')) #   . keyboard.wait(combination="home")#     "Home" winsound.Beep(1000, 100) #    analyzer()#  
      
      







アルゴリズムの分析:



  1. 競技場の背景色をエタロン配列に入れます。これにより、配列の色は後で変更されます



     keyboard.wait(combination="home")
          
          





    ゲームが既に展開されており、カメラが中央にあるときに、参照色をピックアップするために必要なだけです
  2. トリガーのトリガー配列を初期化します。 私たちはそれを必要とします。なぜなら、パイソンは何度も満たされる一方、クルグリアッシュは中心に向かって走るからです。 Kruglyashは大きく、測定値を取得するポイントは小さくなります。 つまり、同じラウンドアバウトを2回以上登録しないようにします。
  3. 無限ループを開始し、色の値を絶えず変更配列に取り込み、選択した各ポイントの色を参照色と比較します



     for nomer in range(0,8): if change[nomer][0] > etalon[nomer][0]+50 or change[nomer][1] > etalon[nomer][1]+50 or change[nomer][2] > etalon[nomer][2]+50:
          
          



  4. 前のIF'eで、番号がnomerのポイントの色がいずれかのRGB値で少なくとも50ユニットよりも明るいことがわかった場合、トリガーがこのポイントで点灯しているかどうかを確認し、点灯していない場合は点灯します



      if trigger[nomer] == 0: trigger[nomer] = 1
          
          



  5. 常に更新される変更の色が参照色に対応する場合、2つのオプションがあります。 すべてが静かで円がまだないか、円がチェックされているポイントからさらに移動しました。これがボタンを押す信号です。 最終的には、トリガーの状態によって決定されます。 トリガーが点灯している場合、ロータリーが去っていることを意味します。 トリガーをゼロにし、条件付きでボタンを押します。



      if trigger[nomer] == 1: trigger[nomer] = 0 print("push " +str(nomer) + time.strftime(' %X'))
          
          





ステップ2.実行してテストする



ゲームでは、正しい操作とデバッグを追跡するのは難しいので、ゲームウィンドウを再びバンディックスに記録してテストしました。



画像








左側はpythonの出力を生成したもの、右側はスローモーションでビデオを見ながら記録したものです。 ご覧のとおり、余分なタップ6および0の形式にエラーがあります。これらは、雪片であり、決して削除することはできません。 問題は、最初の目標であるギフトの継続的な収集のために、100%アカウントを必要としないことです。ゲームはプレイヤーに多くの間違いを許します。 そうでない場合は、白のチェックを追加するだけで済みます。



ステップ3.ストリームにプッシュボタンをコーディングする



実際には難解なものはありません。 ポイント番号を取得し、2秒後にボタンを押します。 なぜ2秒で? 私たちが発見した瞬間からクルグリアッシュは約2秒で真ん中に達するからです。 ここでの小さなコツは、ボタンを互いに独立して押す必要があることです。 クラシックスリープ()を適用してプログラムの実行を一時停止することはできません。 すべてがノックダウンされ、実際にkruglyashiは十分に速く飛ぶでしょう。 スレッドをキューに入れるか使用することができますが、これはよりエレガントなソリューションだと思います(もちろん、Pythonと多くのスレッドがPCでスローダウンしない限り)。



コードに追加



 from threading import Timer
      
      





および保留中のハンドラー自体



 def delaypress(keynum): if keynum < 4: keynum +=1 else: keynum +=2 t = Timer(2, keyboard.send, args=[str(keynum)]) t.start()
      
      





ポイント番号0-1-2-3が入力された場合、2秒後にポイント番号+ 1を押し、4-5-6-7が到着した場合、2秒後に番号+ 2を押します(ボタン5がアクティブになっていないため)ミニゲームで)



最終的なコードビュー:
 import time#   (  ) import pyautogui#  (   ) import winsound#  ,  ,    (  ) import keyboard#     (   ) from threading import Timer#     (  ) def delaypress(keynum): if keynum < 4: keynum +=1 else: keynum +=2 t = Timer(2, keyboard.send, args=[str(keynum)]) t.start() def analyzer(): etalon = [pyautogui.pixel(355, 288), pyautogui.pixel(460, 200), pyautogui.pixel(600, 130),\ pyautogui.pixel(735, 112), pyautogui.pixel(875, 109), pyautogui.pixel(1000, 145), \ pyautogui.pixel(1139, 203), pyautogui.pixel(1260, 290) ]#   trigger = [0,0,0,0,0,0,0,0]# ,   while True: change = [pyautogui.pixel(355, 288), pyautogui.pixel(460, 200), pyautogui.pixel(600, 130),\ pyautogui.pixel(735, 112), pyautogui.pixel(875, 109), pyautogui.pixel(1000, 145), \ pyautogui.pixel(1139, 203), pyautogui.pixel(1260, 290) ] #   change     for nomer in range(0,8): if change[nomer][0] > etalon[nomer][0]+50 or change[nomer][1] > etalon[nomer][1]+50 or change[nomer][2] > etalon[nomer][2]+50: if trigger[nomer] == 0: #     R,G  B    +50     trigger[nomer] = 1#   else: if trigger[nomer] == 1: #      trigger[nomer] = 0 #   #print("push " +str(nomer) + time.strftime(' %X'))#     delaypress(nomer) #   . keyboard.wait(combination="home")#     "Home" winsound.Beep(1000, 100) #    analyzer()#  
      
      







ステップ4. Rowぎの利益



画像






結論と参考文献



そして今、約束されたように、私はPythonを賞賛します(かなり合理的に願っています)。





Pyautoguiドキュメント

グラフィックドキュメント

キーボードモジュールのドキュメント



Pythonハックに関する興味深いアイデアがある場合は、個人で書いてください。



All Articles