├── core ├── __init__.py ├── client.py ├── adb.py ├── auto.py └── tool.py ├── start.bat ├── requirements.txt ├── adb ├── README.txt ├── adb.exe ├── AdbWinApi.dll ├── AdbWinUsbApi.dll └── nox │ ├── AdbWinApi.dll │ ├── nox_adb.exe │ └── AdbWinUsbApi.dll ├── images ├── again.jpg ├── 天聖女的凱旋.jpg ├── 超砂獸的靈帝牙.jpg ├── 飛艇隆瓦裡歐號.jpg └── 海盜船雷古尼斯號.jpg ├── example_image ├── again.jpg ├── setup.png ├── start.png ├── example.jpg ├── example2.png ├── start1.png └── start2.png ├── setup.bat ├── .gitignore ├── LICENSE ├── Cloudia.py └── readme.md /core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /start.bat: -------------------------------------------------------------------------------- 1 | python Cloudia.py 2 | pause -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # pip install -r requirements.txt 2 | opencv-python -------------------------------------------------------------------------------- /adb/README.txt: -------------------------------------------------------------------------------- 1 | Android ADB Commands Manual 2 | 3 | https://adbshell.com -------------------------------------------------------------------------------- /adb/adb.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/adb/adb.exe -------------------------------------------------------------------------------- /images/again.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/images/again.jpg -------------------------------------------------------------------------------- /adb/AdbWinApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/adb/AdbWinApi.dll -------------------------------------------------------------------------------- /images/天聖女的凱旋.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/images/天聖女的凱旋.jpg -------------------------------------------------------------------------------- /images/超砂獸的靈帝牙.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/images/超砂獸的靈帝牙.jpg -------------------------------------------------------------------------------- /images/飛艇隆瓦裡歐號.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/images/飛艇隆瓦裡歐號.jpg -------------------------------------------------------------------------------- /adb/AdbWinUsbApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/adb/AdbWinUsbApi.dll -------------------------------------------------------------------------------- /adb/nox/AdbWinApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/adb/nox/AdbWinApi.dll -------------------------------------------------------------------------------- /adb/nox/nox_adb.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/adb/nox/nox_adb.exe -------------------------------------------------------------------------------- /images/海盜船雷古尼斯號.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/images/海盜船雷古尼斯號.jpg -------------------------------------------------------------------------------- /example_image/again.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/again.jpg -------------------------------------------------------------------------------- /example_image/setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/setup.png -------------------------------------------------------------------------------- /example_image/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/start.png -------------------------------------------------------------------------------- /setup.bat: -------------------------------------------------------------------------------- 1 | pip install -r requirements.txt 2 | pause 3 | def requirements.txt 4 | del setup.bat -------------------------------------------------------------------------------- /adb/nox/AdbWinUsbApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/adb/nox/AdbWinUsbApi.dll -------------------------------------------------------------------------------- /example_image/example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/example.jpg -------------------------------------------------------------------------------- /example_image/example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/example2.png -------------------------------------------------------------------------------- /example_image/start1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/start1.png -------------------------------------------------------------------------------- /example_image/start2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhen-Bo/Cloudia/HEAD/example_image/start2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | core/__pycache__ 3 | log.txt 4 | screenshots.png 5 | tempCodeRunnerFile.py 6 | build/ 7 | screenshots.png 8 | dist/ 9 | __pycache__/app.cpython-37.pyc 10 | app.spec 11 | *.spec 12 | test.py 13 | *.pyc 14 | publish.py 15 | screenshot.png 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Zhen-Bo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Cloudia.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import traceback 3 | import os 4 | __author__ = "Paver(Zhen_Bo)" 5 | 6 | # ============================================================================ 7 | # 原始解析度 1920x1080 8 | # ============================================================================ 9 | 10 | print( 11 | "\033[31mScrpit made by\033[0m \033[41;37mPaver\033[0m,github:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 12 | print( 13 | "\033[31m此腳本作者為\033[0m \033[41;37mPaver\033[0m,github頁面:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 14 | print( 15 | "請問是否為NOX模擬器\n是的話請輸入\033[1;36m\"1\"\033[0m\n不是的話請按\033[1;31mEnter\033[0m") 16 | NOX = input("模式:") 17 | if NOX == "1": 18 | NOX = True 19 | else: 20 | NOX = False 21 | 22 | try: 23 | from core.auto import auto 24 | from core import client 25 | path = os.path.dirname(os.path.abspath(__file__)) 26 | device = client.get_devices(path, NOX) 27 | bot = auto(device, NOX) 28 | bot.bot_start() 29 | except Exception as e: 30 | error_class = e.__class__.__name__ 31 | detail = e.args[0] 32 | cl, exe, tb = sys.exc_info() 33 | lastCallStack = traceback.extract_tb(tb)[-1] 34 | fileName = lastCallStack[0] 35 | lineNum = lastCallStack[1] 36 | funcName = lastCallStack[2] 37 | errMsg = "File \"{}\", line {}, in {}: [{}] {}".format( 38 | fileName, lineNum, funcName, error_class, detail) 39 | print(errMsg) 40 | input("按下Enter結束執行") 41 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 台版最後的克勞迪亞刷首抽腳本,設定為刷到"海盜船+飛艇+沙蟲"停止 2 | 3 | 詳細的 log 會記錄在同一資料夾的 log.txt 內 4 | 5 | --- 6 | 7 | ## 說明 8 | 9 | 為後台腳本,開啟後使用者可以把模擬器最小化後,腳本依然會進行。 10 | 11 | 雖然感覺很扯不會有人這樣做,不過還是說一下,請勿把它拿來作為 **商業用途** 12 | 13 | #### 發問前五大訴求: 14 | ## 1.請看完readme後再發問,如果EXE不行請改執行源碼 15 | ## 2.非BS模擬器問題請別來問我,我只用BS其他模擬器沒再用,所以出問題也不知道是code問題還是模擬器問題,一樣,用其他模擬器可以的話請先執行源碼,EXE跟源碼都不行再問 16 | 17 | ## 3.所有沒有標明免費的東西都不是免費的 18 | 19 | ## 4.源碼100%可以執行,無法執行的話只可能是你環境有問題 20 | 21 | ## 5.所有沒有註明免費的東西都不是免費的,如果需要我幫你認真回答你的非技術性問題,這屬於收費諮詢範疇,你買的是我的時間跟精力,我不是24小時都無所事事只會尻尻的,我有我的事情需要去做 22 | 23 | --- 24 | 25 | ## 測試環境 26 | 27 | #### bluestacks 4.220.0.8005(android 5) 28 | 29 | #### 建議為 540x960 解析度,理論上來說支援所有 9x16 解析度 30 | 31 | #### 但是解析度過高會導致執行效率過慢&其他問題 32 | 33 | 只要"模擬器"設定為 540x960 即可,模擬器的大小可以隨意縮放無所謂 34 | android5 版本的 bs 需要下載最新版的 BS 後,使用多開管理器新建多開引擎->全新多開引擎->Lollipop 32-bit 35 | 36 | #### python 3.7.9 37 | 38 | --- 39 | 40 | ## 使用方法 41 | 42 | # 0.5 版本 43 | 44 | 1.先去下載壓縮檔後解壓縮 45 | 46 | |--------重要部分--------| 47 | 48 | ### 2.然後到"再抽一次"的畫面 49 | 50 | ![](https://github.com/Zhen-Bo/Cloudia/blob/master/example_image/example.jpg) 51 | 52 | 是以"![](https://github.com/Zhen-Bo/Cloudia/blob/master/example_image/again.jpg)"為判斷基準 53 | 54 | 補充:用夜神模擬器的使用者,你們好像要找到夜神專用的 nox_adb.exe,找到後複製一份出來重新命名成 adb.exe,然後覆蓋程式目錄下的 adb 資料夾中的 adb.exe 55 | 56 | |-----------------------------| 57 | 58 | 3.點開"Cloudia.exe",即可開始腳本 59 | 60 | --- 61 | 62 | # 0.6 版本 63 | 64 | 1.下載源碼後解壓縮 65 | 66 | |--------重要部分--------| 67 | 68 | ### 2.然後到"再抽一次"的畫面 69 | 70 | ![](https://github.com/Zhen-Bo/Cloudia/blob/master/example_image/example.jpg) 71 | 72 | 是以"![](https://github.com/Zhen-Bo/Cloudia/blob/master/example_image/again.jpg)"為判斷基準 73 | 74 | |-----------------------------| 75 | 76 | 3.點擊 start.bat,確認目標設備是否有在選單,沒有的話可以自行添加(可以填入設備名稱,或是全數字的 port 號) 77 | 78 | - BS 多開的 port 號,可以去設定->偏好設定->往下拉到 ADB 勾選的那欄->下面黃字有寫說你可以在 127.0.0.1:多少連接,新增 port 號只需輸入":"後面的數字即可 79 | 80 | 4.如果需要多開則可以再點擊一次 start.bat 並新增腳本工作 81 | 82 | - 示範影片:https://youtu.be/o6FgN0pgPgQ 83 | 84 | --- 85 | 86 | ## 實際執行圖 87 | 88 | ![](https://github.com/Zhen-Bo/Cloudia/blob/master/example_image/example2.png) 89 | -------------------------------------------------------------------------------- /core/client.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import os 3 | 4 | 5 | def read_devices(path, NOX=False): 6 | if NOX: 7 | adb_path = "{}/adb/nox/nox_adb.exe".format(path) 8 | else: 9 | adb_path = "{}/adb/adb.exe".format(path) 10 | devices = subprocess.Popen("{0} devices".format( 11 | adb_path), shell=True, stdout=subprocess.PIPE).stdout.read().decode("utf-8") 12 | lists = devices.split("\n") 13 | devicesNames = [] 14 | for item in lists: 15 | if(item.strip() == ""): 16 | continue 17 | elif (item.startswith("List of")): 18 | continue 19 | else: 20 | devicesNames.append(item.split("\t")[0]) 21 | return devicesNames 22 | 23 | 24 | def select_devices(path, devicesIds, NOX=False): 25 | if NOX: 26 | adb_path = "{}/adb/nox/nox_adb.exe".format(path) 27 | else: 28 | adb_path = "{}/adb/adb.exe".format(path) 29 | os.system('cls') 30 | print("\033[31mScrpit made by\033[0m \033[41;37mPaver\033[0m,github:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 31 | print( 32 | "\033[31m此腳本作者為\033[0m \033[41;37mPaver\033[0m,github頁面:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 33 | print("請選擇你要控制的設備:") 34 | i = 1 35 | for deviceId in devicesIds: 36 | print("\033[1;34m {0}:{1}\033[0m".format(i, deviceId)) 37 | i += 1 38 | print("\033[1;36m a: 新增\033[0m") 39 | print("\033[1;31m e: 離開\033[0m") 40 | try: 41 | inputIndex = input( 42 | "請輸入編號 [1 ~ {0}]:".format(i-1)) 43 | value = int(inputIndex) 44 | if value < 1 or value >= i: 45 | raise Exception("編號過大") 46 | return devicesIds[value - 1] 47 | except (KeyboardInterrupt, SystemExit): 48 | raise Exception("KeyboardInterrupt") 49 | except Exception as e: 50 | if "e" == inputIndex.lower(): 51 | return -1 52 | elif "a" == inputIndex.lower(): 53 | port = input("請輸入設備名稱或連接在127.0.0.1的port: ") 54 | if port.isdigit(): 55 | os.system("{0} connect 127.0.0.1:{1}".format(adb_path, port)) 56 | else: 57 | os.system("{0} connect {1}".format(adb_path, port)) 58 | input("輸入enter繼續") 59 | return select_devices(path, read_devices(path), NOX) 60 | else: 61 | print( 62 | "\033[1;31m編號輸入錯誤,請在試一次\033[0m") 63 | input("請輸入enter繼續") 64 | return select_devices(path, devicesIds) 65 | 66 | 67 | def get_devices(path, NOX=False): 68 | devices = read_devices(path, NOX) 69 | client = select_devices(path, devices, NOX) 70 | if client == -1: 71 | raise Exception("使用者終止") 72 | return client 73 | -------------------------------------------------------------------------------- /core/adb.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import numpy as np 4 | import time 5 | from cv2 import cv2 6 | 7 | 8 | class adbKit(object): 9 | def __init__(self) -> None: 10 | self.path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 11 | os.system("{0}/adb/adb.exe kill-server".format(self.path)) 12 | os.system("{0}/adb/adb.exe start-server".format(self.path)) 13 | print("等待10秒讓ADB載入模擬器") 14 | for i in range(11): 15 | print(10-i, " ", end='\r') 16 | time.sleep(1) 17 | print(" ") 18 | os.system("{0}/adb/adb.exe devices".format(self.path)) 19 | self.capmuti = float(1) 20 | 21 | def debug_get(self): 22 | t1 = time.time() 23 | pipe = subprocess.Popen("{0}/adb/adb.exe shell screencap -p".format(self.path), 24 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) 25 | image_bytes = pipe.stdout.read() 26 | print(image_bytes[0:10]) 27 | image_bytes = image_bytes.replace(b'\r\n', b'\n') 28 | print(image_bytes[0:10]) 29 | image = cv2.imdecode(np.frombuffer( 30 | image_bytes, dtype='uint8'), cv2.IMREAD_COLOR) 31 | t2 = time.time() 32 | print(t2-t1) 33 | try: 34 | if int(image.shape[0]) % 16 != 0 or int(image.shape[1] % 9) != 0: 35 | print("我草尼碼,我不是叫你看readme了???,眼瞎是不是,你模擬器解析度不是9:16") 36 | print("還是說你在拉小提琴頭歪一邊以為16:9是9:16????") 37 | print("你螢幕解析度是{0} x {1}".format( 38 | int(image.shape[1] % 9), int(image.shape[0]))) 39 | elif image.shape[0] != 1920 and image.shape[1] != 1080: 40 | print("模擬器解析度原圖為: {0} x {1}".format( 41 | image.shape[1], image.shape[0])) 42 | image = self.reimage(image) 43 | except: 44 | print("你模擬器截取出來的圖片爆炸了,有兩個建議選項,一個重灌電腦一個重灌模擬器一個想辦法自己解決") 45 | raw = input("按Enter鍵關閉視窗") 46 | 47 | def get_width_muti(self): 48 | sample = self.screenshots(raw=True) 49 | try: 50 | self.capmuti = sample.shape[0] / 1920 51 | except: 52 | print("無法取得解析度") 53 | 54 | def screenshots(self, raw=False): 55 | pipe = subprocess.Popen("{0}/adb/adb.exe shell screencap -p".format(self.path), 56 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) 57 | image_bytes = pipe.stdout.read() 58 | image_bytes = image_bytes.replace(b'\r\r\n', b'\n') 59 | time.sleep(0.5) 60 | image = cv2.imdecode(np.frombuffer( 61 | image_bytes, dtype='uint8'), cv2.IMREAD_COLOR) 62 | if image.shape[0] != 1920 and image.shape[1] != 1080 and not raw: 63 | image = self.reimage(image) 64 | return image 65 | 66 | # DONE 多解析度支援 67 | 68 | def reimage(self, images): 69 | images = cv2.resize(images, (1080, 1920)) 70 | return images 71 | 72 | def click(self, pointx, pointy, raw=False): 73 | if raw: 74 | Px = str(pointx) 75 | Py = str(pointy) 76 | else: 77 | Px = str(int(pointx)*self.capmuti) 78 | Py = str(int(pointy)*self.capmuti) 79 | os.system( 80 | "{0}/adb/adb.exe shell input tap ".format(self.path) + ' ' + Px + ' ' + Py) 81 | -------------------------------------------------------------------------------- /core/auto.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from datetime import datetime 4 | from core.tool import tool 5 | 6 | 7 | class auto(): 8 | def __init__(self, device, NOX=False): 9 | try: 10 | port = device.split(":")[1] 11 | except: 12 | port = device 13 | self.log = open('log-{0}.txt'.format(port), 'a') 14 | self.line = "//================================================\n" 15 | self.ship_flag = False 16 | self.space_flag = False 17 | self.sand_flag = False 18 | self.times = 0 19 | self.path = os.path.dirname( 20 | os.path.dirname(os.path.abspath(__file__))) + "/images" 21 | self.adbtool = tool(device, NOX) 22 | self.start = None 23 | self.end = None 24 | 25 | def log_info(self, str): 26 | self.log.write(str) 27 | print(str, end='') 28 | 29 | def bot_start(self): 30 | os.system('cls') 31 | print("\033[31mScrpit made by\033[0m \033[41;37mPaver\033[0m,github:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 32 | print( 33 | "\033[31m此腳本作者為\033[0m \033[41;37mPaver\033[0m,github頁面:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 34 | self.log_info(self.line) 35 | self.start = datetime.now() 36 | self.log_info("開始運行,開始時間: {}\n".format( 37 | datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) 38 | print("已鎖定:", end='') 39 | i = 0 40 | for ark in self.adbtool.ark: 41 | print("\033[1;{0}m{1}\033[0m\t".format( 42 | 33+i, ark.split('.')[0]), end='') 43 | i += 1 44 | self.log_info("\n{}".format(self.line)) 45 | POG = [] 46 | again = False 47 | again = self.adbtool.compare( 48 | ["{0}/again.jpg".format(self.path)], self.path) 49 | try: 50 | self.adbtool.tap(again, raw=True) 51 | except: 52 | raise Exception("沒有偵測到\"再抽一次\",或是解析度不是9x16的解析度\n退出程式") 53 | time.sleep(0.5) 54 | while len(POG) != len(self.adbtool.ark): 55 | t_start = time.time() 56 | POG = [] 57 | again = False 58 | while not again: 59 | again = self.adbtool.compare( 60 | ["{0}/again.jpg".format(self.path)], gach=True) 61 | if not again: 62 | self.adbtool.tap((960, 70)) 63 | POG = again[1] 64 | t_end = time.time() 65 | cost_time = round(t_end-t_start, 2) 66 | if self.times == 0: 67 | self.times += 1 68 | elif self.times != 0 and cost_time > 5: 69 | self.log_info("第{0}次結果:\n".format(self.times)) 70 | if len(POG) > 0: 71 | self.log_info('命中數量: {0}\n'.format(len(POG))) 72 | for i in range(len(POG)): 73 | self.log_info("{0}.{1}\t".format( 74 | i+1, POG[i].split('.')[0])) 75 | self.log_info('\n') 76 | else: 77 | self.log_info('命中數量: 0\n') 78 | self.log_info("耗時 {0} 秒\n".format(cost_time)) 79 | self.log_info(self.line) 80 | if len(POG) != len(self.adbtool.ark): 81 | self.adbtool.tap(again[0], raw=True) 82 | time.sleep(1) 83 | self.times += 1 84 | elif len(POG) == len(self.adbtool.ark): 85 | self.end = datetime.now() 86 | print( 87 | "執行結束,總共執行 {0} 次, 結束時間 {1} ,共花費 {2} ".format(self.times, self.end, str(self.end-self.start))) 88 | input("請輸入enter繼續") 89 | break 90 | -------------------------------------------------------------------------------- /core/tool.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import numpy as np 4 | from cv2 import cv2 5 | import time 6 | 7 | 8 | class adbKit(): 9 | def __init__(self, device, NOX=False, debug=False) -> None: 10 | self.path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 11 | self.debug = debug 12 | self.capmuti = 1 13 | self.device = device 14 | if NOX: 15 | self.adb_path = "{}/adb/nox/nox_adb.exe".format(self.path) 16 | else: 17 | self.adb_path = "{}/adb/adb.exe".format(self.path) 18 | self.breakline = self.get_SDK().encode('utf-8') 19 | 20 | def debug_get_write(self): 21 | t1 = time.time() 22 | pipe = subprocess.Popen("{0} -s {1} shell screencap -p".format(self.adb_path, self.device), 23 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) 24 | image_bytes = pipe.stdout.read() 25 | print(image_bytes[0:10]) 26 | image_bytes = image_bytes.replace(self.breakline, b'\n') 27 | print(image_bytes[0:10]) 28 | t2 = time.time() 29 | image = cv2.imdecode(np.frombuffer( 30 | image_bytes, dtype='uint8'), cv2.IMREAD_COLOR) 31 | print("耗時 {0} 秒".format(round(t2-t1, 2))) 32 | cv2.imwrite("screenshot.png", image) 33 | input("按Enter鍵關閉視窗") 34 | 35 | def get_SDK(self): 36 | SDK_version = subprocess.Popen("{0} -s {1} shell getprop ro.build.version.release".format( 37 | self.adb_path, self.device), stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) 38 | SDK_version = SDK_version.stdout.read().decode("utf-8") 39 | if int(SDK_version[0]) >= 7: 40 | return '\r\n' 41 | elif int(SDK_version[0]) <= 5: 42 | return '\r\r\n' 43 | else: 44 | print("不是android5或android7") 45 | 46 | def screenshots(self, raw=False): 47 | pipe = subprocess.Popen("{0} -s {1} shell screencap -p".format(self.adb_path, self.device), 48 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) 49 | image_bytes = pipe.stdout.read() 50 | image_bytes = image_bytes.replace(self.breakline, b'\n') 51 | image = cv2.imdecode(np.frombuffer( 52 | image_bytes, dtype='uint8'), cv2.IMREAD_COLOR) 53 | if image.shape[0] != 1920 and image.shape[1] != 1080 and not raw: 54 | image = self.reimage(image) 55 | return image 56 | 57 | def reimage(self, images): 58 | images = cv2.resize(images, (1080, 1920)) 59 | return images 60 | 61 | def click(self, pointx, pointy, raw=False): 62 | if raw: 63 | Px = str(pointx) 64 | Py = str(pointy) 65 | else: 66 | Px = str(int(pointx)*self.capmuti) 67 | Py = str(int(pointy)*self.capmuti) 68 | if self.debug: 69 | print('[ADB]adb shell input tap ' + Px + ' ' + Py) 70 | os.system( 71 | '{0} -s {1} shell input tap {2} {3}'.format(self.adb_path, self.device, Px, Py)) 72 | 73 | def swipe(self, x1, y1, x2, y2, delay): 74 | cmdSwipe = '{0} -s {1} shell input swipe {2} {3} {4} {5} {6}'.format( 75 | self.adb_path, self.device, int(x1), int(y1), int(x2), int(y2), int(delay*1000)) 76 | if self.debug: 77 | print('[ADB]adb shell swipe from X:{0} Y:{1} to X:{2} Y:{3} Delay:{4}'.format( 78 | int(x1), int(y1), int(x2), int(y2), int(delay*1000))) 79 | os.system(cmdSwipe) 80 | 81 | 82 | class tool(): 83 | def __init__(self, device, NOX, img_path=os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "images"), debug=False) -> None: 84 | self.debug = debug 85 | self.adbkit = adbKit(device, NOX) 86 | self.adbkit.capmuti = self.get_width_muti() 87 | self.screenshot = None 88 | self.ark = self.get_ark(img_path) 89 | self.template = self.load_template(img_path, self.ark) 90 | 91 | def get_width_muti(self): 92 | sample = self.adbkit.screenshots(raw=True) 93 | return sample.shape[0] / 1920 94 | 95 | def get_ark(self, path): 96 | arks = [] 97 | for img in os.listdir(path): 98 | arks.append(img) 99 | arks.remove("again.jpg") 100 | choose = [] 101 | while True: 102 | os.system('cls') 103 | print( 104 | "\033[31mScrpit made by\033[0m \033[41;37mPaver\033[0m,github:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 105 | print( 106 | "\033[31m此腳本作者為\033[0m \033[41;37mPaver\033[0m,github頁面:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 107 | i = 1 108 | print("目前候選名單: ", end='') 109 | for ark in arks: 110 | print("{0}.{1} ".format(i, ark.split('.')[0]), end='') 111 | i += 1 112 | print("\n目前已選名單: ", end='') 113 | j = 1 114 | for ark in choose: 115 | print("{0}.{1} ".format(j, ark.split('.')[0]), end='') 116 | j += 1 117 | print("\n輸入a為全部添加,輸入e離開") 118 | index = input("請輸入要鎖定的聖物編號: ") 119 | try: 120 | index = int(index) 121 | if index > len(arks): 122 | print("超出最大編號") 123 | input("請按enter繼續選擇") 124 | continue 125 | choose.append(arks[index-1]) 126 | arks.remove(arks[index-1]) 127 | except: 128 | if index.lower() == 'a': 129 | for ark in arks: 130 | choose.append(ark) 131 | arks = [] 132 | elif index.lower() == 'e': 133 | os.system('cls') 134 | print( 135 | "\033[31mScrpit made by\033[0m \033[41;37mPaver\033[0m,github:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 136 | print( 137 | "\033[31m此腳本作者為\033[0m \033[41;37mPaver\033[0m,github頁面:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 138 | print("\n目前已選名單: ", end='') 139 | j = 1 140 | for ark in choose: 141 | print("{0}.{1} ".format( 142 | j, ark.split('.')[0]), end='') 143 | j += 1 144 | ctr = input("\n確定選擇請按enter,重新選擇請輸入'n': ") 145 | if str(ctr).lower() == 'n': 146 | return self.get_ark(path) 147 | else: 148 | return choose 149 | else: 150 | continue 151 | finally: 152 | if len(arks) == 0: 153 | os.system('cls') 154 | print( 155 | "\033[31mScrpit made by\033[0m \033[41;37mPaver\033[0m,github:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 156 | print( 157 | "\033[31m此腳本作者為\033[0m \033[41;37mPaver\033[0m,github頁面:\033[37;34mhttps://github.com/Zhen-Bo\033[0m") 158 | print("\n目前已選名單: ", end='') 159 | j = 1 160 | for ark in choose: 161 | print("{0}.{1} ".format( 162 | j, ark.split('.')[0]), end='') 163 | j += 1 164 | ctr = input("\n確定選擇請按enter,重新選擇請輸入'n': ") 165 | if str(ctr).lower() == 'n': 166 | return self.get_ark(path) 167 | else: 168 | return choose 169 | 170 | def load_template(self, img_path, template_list): 171 | imgs = [] 172 | for template in template_list: 173 | img = os.path.join(img_path, template) 174 | imgs.append(self.cv_read(img)) 175 | return imgs 176 | 177 | def compare(self, img_list, gach=False, acc=0.85): 178 | imgs = [] 179 | self.screenshot = self.adbkit.screenshots() 180 | for item in img_list: 181 | imgs.append(cv2.imread(item)) 182 | for img in imgs: 183 | find_height, find_width = img.shape[:2:] 184 | result = cv2.matchTemplate( 185 | self.screenshot, img, cv2.TM_CCOEFF_NORMED) 186 | reslist = cv2.minMaxLoc(result) 187 | if self.debug: 188 | cv2.rectangle(self.screenshot, reslist[3], ( 189 | reslist[3][0]+find_width, reslist[3][1]+find_height), color=(0, 250, 0), thickness=2) 190 | if reslist[1] > acc: 191 | if self.debug: 192 | print("[Detect]acc rate:", round(reslist[1], 2)) 193 | pos = [reslist[3][0], reslist[3][1]] 194 | pos = [x*self.adbkit.capmuti for x in pos] 195 | if gach == True: 196 | return pos, self.gatcha() 197 | else: 198 | return pos 199 | return False 200 | 201 | def cv_read(self, file_path): 202 | img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1) 203 | return img 204 | 205 | def gatcha(self): 206 | gatcha = [] 207 | for index in range(len(self.template)): 208 | result = cv2.matchTemplate( 209 | self.screenshot, self.template[index], cv2.TM_CCOEFF_NORMED) 210 | result = cv2.minMaxLoc(result) 211 | if result[1] > 0.9: 212 | gatcha.append(self.ark[index]) 213 | return gatcha 214 | 215 | def tap(self, pos, raw=False): 216 | if raw: 217 | self.adbkit.click(pos[0], pos[1], raw=True) 218 | else: 219 | self.adbkit.click(pos[0], pos[1]) 220 | 221 | def swipe(self, x1, y1, x2, y2, delay): 222 | self.adbkit.swipe(x1, y1, x2, y2, delay) 223 | --------------------------------------------------------------------------------