├── shield ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 2.png ├── 20.png ├── 21.png ├── 22.png ├── 23.png ├── 24.png ├── 25.png ├── 26.png ├── 27.png ├── 28.png ├── 29.png ├── 3.png ├── 30.png ├── 31.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── 10_1.png ├── 11_1.png ├── 12_1.png ├── 13_1.png ├── 14_1.png ├── 15_1.png ├── 16_1.png ├── 17_1.png ├── 18_1.png ├── 19_1.png ├── 1_1.png ├── 1_2.png ├── 1_3.png ├── 20_1.png ├── 21_1.png ├── 22_1.png ├── 23_1.png ├── 24_1.png ├── 25_1.png ├── 26_1.png ├── 27_1.png ├── 28_1.png ├── 29_1.png ├── 2_1.png ├── 30_1.png ├── 31_1.png ├── 3_1.png ├── 4_1.png ├── 5_1.png ├── 6_1.png ├── 7_1.png ├── 8_1.png ├── 9_1.png ├── QQ20250704-010727.png ├── QQ20250704-041129.png ├── QQ20250704-214017.png ├── QQ20250705-015752.png ├── QQ20250705-030345.png ├── QQ20250705-030540.png ├── QQ20250705-034129.png ├── QQ20250705-045828.png ├── QQ20250705-055332.png ├── QQ20250705-164114.png ├── QQ20250705-164238.png ├── QQ20250705-174815.png ├── QQ20250706-012249.png ├── QQ20250706-012326.png ├── QQ20250706-013215.png ├── QQ20250706-013244.png ├── 联想截图_20250717203349.png ├── 联想截图_20250717204046.png ├── 屏幕截图 2025-07-17 203154.png ├── 屏幕截图 2025-07-17 203411.png ├── 屏幕截图 2025-07-17 203508.png ├── 屏幕截图 2025-07-17 203640.png ├── 屏幕截图 2025-07-17 203748.png ├── 屏幕截图 2025-07-17 203837.png ├── 屏幕截图 2025-07-17 203855.png ├── 屏幕截图 2025-07-17 203936.png ├── 屏幕截图 2025-07-17 204140.png ├── 屏幕截图 2025-07-17 204339.png ├── 屏幕截图 2025-07-17 204402.png ├── 03835ba7f601cdfe564eacc090fa0fe5.png ├── 190A7E4382F5F2C17C5CC2A031380755.png ├── 1c9046994f324b5b94b8528666aed157.jpg ├── 3e5fcb22647a3bebd87277c8690ae2be.jpg ├── 3eab4f3f98b1b8282c1a27fdf1a2201c.png ├── 4e70ebed9d5f5b6ebf80df0a1f55bc22.jpg ├── 690957613d9b90950bddb2235e523f56.png ├── 6ECCF60A72AE9A9AE41F148B4661C6FC.png ├── 7D28F988866FA61E68F98F51486C1FBC.png ├── 7e60222b58d71a4474f7dd9a13ecab8a.png ├── 947A76CBEA20B61F8DFC1FE794F88906.png ├── 9bd533b8db6597d6502a5f1eff6a553e.png ├── a79d3d0a49bc409153a28ec50903689e.png ├── b263ad960fda061bd039164fe9a7d367.png ├── be2343db66b870f88c2fde7f468eb6e3.png ├── c90fa9c07bcba0bf0093f1814d30f811.jpg ├── ec9d6b3570d67a43e030b56ad004d77c.png ├── 329dcf66-b002-47a9-96d5-b7b688ce3400.png ├── 378ac81d-7d78-4752-b30c-511789bd1c4f.png ├── 38aac6ca-b46c-4d1a-9a92-7ea697edb869.png ├── 3ace49eb-e35c-4c4a-82a4-924188a1460d.png ├── 45bfe177-2acb-4f16-9212-80b3ef7d7845.png ├── 5f54f4af-9623-4c20-bee0-338c8c6573db.png ├── 83c0117e-fcc3-475d-a157-c19b95b9e176.png ├── 88a5f1b1-8891-458e-97fb-273694c0c882.png ├── a8e4cc4f-73bf-4d92-b14b-a3068f016b32.png ├── a906ee61-1f26-4c1f-b022-0c8c00fa50d9.png ├── b7041906-ff76-4f80-a8af-fc748a37b3d9.png ├── c9c6ddd8-faeb-45d2-99be-fd3ced8c2988.png ├── d54d3ed4-c51b-49a4-a89a-ead6c3a1a755.png ├── d9174a23-e7c5-413e-918a-eeb30a4f5042.png ├── d929dd91-f0c1-472b-b188-1b4e55fa75d9.png ├── dbcd4111-ab1b-427d-a79d-d0c92b8dbdd2.png ├── dc2cd93c-4a14-4372-843a-03a04adb209d.png ├── e1674f3d-34dd-43e2-b193-ba4791b53a2c.png ├── e56f27d8-229d-4edc-9142-96775cdd5423.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRVNjZIaG81dW9DRGchIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRVNzZIaG9SUnNKRGchIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRVQTVYaG9CWFZlR0EhIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRVZDUzaG8uOTZaT0EhIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRVZDUzaG9sTm1nT0EhIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRXNXpIaG84Smw4Q3chIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRXNXpIaG9GR09FQ3chIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRXNnpIaG81VW1WQ3chIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRXNnpIaG9BVG1NQ3chIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRXczVIaG80KkprRXchIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRXczVIaG9UWGhkRXchIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRYKjVIaG9CdlJXR0EhIQUAcXVuZ3o!.png ├── NR8AVjViQ1FBNU5qYzJNekkyTVRYZzZIaG83bGJsRnchIQUAcXVuZ3o!.png └── NR8AVjViQ1FBNU5qYzJNekkyTVRYZzZIaG9IZXZzRnchIQUAcXVuZ3o!.png ├── requirements.txt ├── 国服覆盖资源 ├── templates │ ├── Ok.png │ ├── Yes.png │ ├── end.png │ ├── rank.png │ ├── war.png │ ├── close1.png │ ├── close2.png │ ├── groupUp.png │ ├── rankUp.png │ ├── LoginPage.png │ ├── MuMuPage.png │ ├── backMain.png │ ├── backTitle.png │ ├── dailyCard.png │ ├── decision.png │ ├── end_round.png │ ├── enterGame.png │ ├── evolution.png │ ├── mainPage.png │ ├── screenshot.png │ ├── enemy_round.png │ ├── error_retry.png │ ├── errorBackMain.png │ ├── super_evolution.png │ └── missionCompleted.png └── extra_templates │ ├── No.png │ ├── Ok.png │ ├── Yes.png │ ├── end.png │ ├── rank.png │ ├── war.png │ ├── rankUp.png │ ├── LoginPage.png │ ├── MuMuPage.png │ ├── MuMuPage2.jpg │ ├── backMain.png │ ├── backTitle.png │ ├── decision.png │ ├── end_round.png │ ├── enterGame.png │ ├── evolution.png │ ├── groupUp.png │ ├── mainPage.png │ ├── enemy_round.png │ ├── error_retry.png │ ├── screenshot.png │ ├── missionCompleted.png │ └── super_evolution.png ├── templates_cost ├── cost_1.png ├── cost_2.png ├── cost_3.png ├── cost_4.png └── cost_5.png ├── 国际服覆盖资源 ├── templates │ ├── Ok.png │ ├── Yes.png │ ├── end.png │ ├── rank.png │ ├── war.png │ ├── close1.png │ ├── close2.png │ ├── rankUp.png │ ├── LoginPage.png │ ├── MuMuPage.png │ ├── backMain.png │ ├── backTitle.png │ ├── dailyCard.png │ ├── decision.png │ ├── end_round.png │ ├── enterGame.png │ ├── evolution.png │ ├── groupUp.png │ ├── mainPage.png │ ├── enemy_round.png │ ├── error_retry.png │ ├── screenshot.png │ ├── errorBackMain.png │ ├── missionCompleted.png │ └── super_evolution.png └── extra_templates │ ├── Ok.png │ ├── Yes.png │ ├── end.png │ ├── tap.png │ ├── war.png │ ├── rank.png │ ├── MuMuPage.png │ ├── backMain.png │ ├── decision.png │ ├── groupUp.png │ ├── mainPage.png │ ├── rankUp.png │ ├── LoginPage.png │ ├── MuMuPage2.png │ ├── backTitle.png │ ├── end_round.png │ ├── enterGame.png │ ├── evolution.png │ ├── screenshot.png │ ├── enemy_round.png │ ├── error_retry.png │ ├── super_evolution.png │ └── missionCompleted.png ├── config-template.json ├── run.bat ├── .vscode └── launch.json ├── 使用说明.txt ├── sv-auto.spec ├── LICENSE ├── init.bat ├── README.md ├── .gitignore └── sv-auto.py /shield/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/1.png -------------------------------------------------------------------------------- /shield/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/10.png -------------------------------------------------------------------------------- /shield/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/11.png -------------------------------------------------------------------------------- /shield/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/12.png -------------------------------------------------------------------------------- /shield/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/13.png -------------------------------------------------------------------------------- /shield/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/14.png -------------------------------------------------------------------------------- /shield/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/15.png -------------------------------------------------------------------------------- /shield/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/16.png -------------------------------------------------------------------------------- /shield/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/17.png -------------------------------------------------------------------------------- /shield/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/18.png -------------------------------------------------------------------------------- /shield/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/19.png -------------------------------------------------------------------------------- /shield/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/2.png -------------------------------------------------------------------------------- /shield/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/20.png -------------------------------------------------------------------------------- /shield/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/21.png -------------------------------------------------------------------------------- /shield/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/22.png -------------------------------------------------------------------------------- /shield/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/23.png -------------------------------------------------------------------------------- /shield/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/24.png -------------------------------------------------------------------------------- /shield/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/25.png -------------------------------------------------------------------------------- /shield/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/26.png -------------------------------------------------------------------------------- /shield/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/27.png -------------------------------------------------------------------------------- /shield/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/28.png -------------------------------------------------------------------------------- /shield/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/29.png -------------------------------------------------------------------------------- /shield/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/3.png -------------------------------------------------------------------------------- /shield/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/30.png -------------------------------------------------------------------------------- /shield/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/31.png -------------------------------------------------------------------------------- /shield/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/4.png -------------------------------------------------------------------------------- /shield/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/5.png -------------------------------------------------------------------------------- /shield/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/6.png -------------------------------------------------------------------------------- /shield/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/7.png -------------------------------------------------------------------------------- /shield/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/8.png -------------------------------------------------------------------------------- /shield/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/9.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | adbutils 2 | uiautomator2 3 | opencv-python 4 | numpy 5 | pyinstaller 6 | PyQt5 -------------------------------------------------------------------------------- /shield/10_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/10_1.png -------------------------------------------------------------------------------- /shield/11_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/11_1.png -------------------------------------------------------------------------------- /shield/12_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/12_1.png -------------------------------------------------------------------------------- /shield/13_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/13_1.png -------------------------------------------------------------------------------- /shield/14_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/14_1.png -------------------------------------------------------------------------------- /shield/15_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/15_1.png -------------------------------------------------------------------------------- /shield/16_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/16_1.png -------------------------------------------------------------------------------- /shield/17_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/17_1.png -------------------------------------------------------------------------------- /shield/18_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/18_1.png -------------------------------------------------------------------------------- /shield/19_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/19_1.png -------------------------------------------------------------------------------- /shield/1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/1_1.png -------------------------------------------------------------------------------- /shield/1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/1_2.png -------------------------------------------------------------------------------- /shield/1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/1_3.png -------------------------------------------------------------------------------- /shield/20_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/20_1.png -------------------------------------------------------------------------------- /shield/21_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/21_1.png -------------------------------------------------------------------------------- /shield/22_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/22_1.png -------------------------------------------------------------------------------- /shield/23_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/23_1.png -------------------------------------------------------------------------------- /shield/24_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/24_1.png -------------------------------------------------------------------------------- /shield/25_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/25_1.png -------------------------------------------------------------------------------- /shield/26_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/26_1.png -------------------------------------------------------------------------------- /shield/27_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/27_1.png -------------------------------------------------------------------------------- /shield/28_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/28_1.png -------------------------------------------------------------------------------- /shield/29_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/29_1.png -------------------------------------------------------------------------------- /shield/2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/2_1.png -------------------------------------------------------------------------------- /shield/30_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/30_1.png -------------------------------------------------------------------------------- /shield/31_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/31_1.png -------------------------------------------------------------------------------- /shield/3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/3_1.png -------------------------------------------------------------------------------- /shield/4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/4_1.png -------------------------------------------------------------------------------- /shield/5_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/5_1.png -------------------------------------------------------------------------------- /shield/6_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/6_1.png -------------------------------------------------------------------------------- /shield/7_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/7_1.png -------------------------------------------------------------------------------- /shield/8_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/8_1.png -------------------------------------------------------------------------------- /shield/9_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/9_1.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/Ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/Ok.png -------------------------------------------------------------------------------- /templates_cost/cost_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/templates_cost/cost_1.png -------------------------------------------------------------------------------- /templates_cost/cost_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/templates_cost/cost_2.png -------------------------------------------------------------------------------- /templates_cost/cost_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/templates_cost/cost_3.png -------------------------------------------------------------------------------- /templates_cost/cost_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/templates_cost/cost_4.png -------------------------------------------------------------------------------- /templates_cost/cost_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/templates_cost/cost_5.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/Yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/Yes.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/end.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/rank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/rank.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/war.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/war.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/Ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/Ok.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/Yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/Yes.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/end.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/rank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/rank.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/war.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/war.png -------------------------------------------------------------------------------- /shield/QQ20250704-010727.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250704-010727.png -------------------------------------------------------------------------------- /shield/QQ20250704-041129.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250704-041129.png -------------------------------------------------------------------------------- /shield/QQ20250704-214017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250704-214017.png -------------------------------------------------------------------------------- /shield/QQ20250705-015752.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-015752.png -------------------------------------------------------------------------------- /shield/QQ20250705-030345.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-030345.png -------------------------------------------------------------------------------- /shield/QQ20250705-030540.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-030540.png -------------------------------------------------------------------------------- /shield/QQ20250705-034129.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-034129.png -------------------------------------------------------------------------------- /shield/QQ20250705-045828.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-045828.png -------------------------------------------------------------------------------- /shield/QQ20250705-055332.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-055332.png -------------------------------------------------------------------------------- /shield/QQ20250705-164114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-164114.png -------------------------------------------------------------------------------- /shield/QQ20250705-164238.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-164238.png -------------------------------------------------------------------------------- /shield/QQ20250705-174815.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250705-174815.png -------------------------------------------------------------------------------- /shield/QQ20250706-012249.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250706-012249.png -------------------------------------------------------------------------------- /shield/QQ20250706-012326.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250706-012326.png -------------------------------------------------------------------------------- /shield/QQ20250706-013215.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250706-013215.png -------------------------------------------------------------------------------- /shield/QQ20250706-013244.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/QQ20250706-013244.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/close1.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/close2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/close2.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/groupUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/groupUp.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/rankUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/rankUp.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/close1.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/close2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/close2.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/rankUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/rankUp.png -------------------------------------------------------------------------------- /shield/联想截图_20250717203349.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/联想截图_20250717203349.png -------------------------------------------------------------------------------- /shield/联想截图_20250717204046.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/联想截图_20250717204046.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/No.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/No.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/Ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/Ok.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/Yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/Yes.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/end.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/rank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/rank.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/war.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/war.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/LoginPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/LoginPage.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/MuMuPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/MuMuPage.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/backMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/backMain.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/backTitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/backTitle.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/dailyCard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/dailyCard.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/decision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/decision.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/end_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/end_round.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/enterGame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/enterGame.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/evolution.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/mainPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/mainPage.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/screenshot.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/Ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/Ok.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/Yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/Yes.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/end.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/tap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/tap.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/war.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/war.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/LoginPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/LoginPage.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/MuMuPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/MuMuPage.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/backMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/backMain.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/backTitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/backTitle.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/dailyCard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/dailyCard.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/decision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/decision.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/end_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/end_round.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/enterGame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/enterGame.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/evolution.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/groupUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/groupUp.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/mainPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/mainPage.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203154.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203154.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203411.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203411.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203508.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203508.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203640.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203748.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203748.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203837.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203855.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203855.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 203936.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 203936.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 204140.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 204140.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 204339.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 204339.png -------------------------------------------------------------------------------- /shield/屏幕截图 2025-07-17 204402.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/屏幕截图 2025-07-17 204402.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/rankUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/rankUp.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/enemy_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/enemy_round.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/error_retry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/error_retry.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/rank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/rank.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/enemy_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/enemy_round.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/error_retry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/error_retry.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/screenshot.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/LoginPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/LoginPage.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/MuMuPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/MuMuPage.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/MuMuPage2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/MuMuPage2.jpg -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/backMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/backMain.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/backTitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/backTitle.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/decision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/decision.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/end_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/end_round.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/enterGame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/enterGame.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/evolution.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/groupUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/groupUp.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/mainPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/mainPage.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/errorBackMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/errorBackMain.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/super_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/super_evolution.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/MuMuPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/MuMuPage.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/backMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/backMain.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/decision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/decision.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/groupUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/groupUp.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/mainPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/mainPage.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/rankUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/rankUp.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/errorBackMain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/errorBackMain.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/enemy_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/enemy_round.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/error_retry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/error_retry.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/screenshot.png -------------------------------------------------------------------------------- /国服覆盖资源/templates/missionCompleted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/templates/missionCompleted.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/LoginPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/LoginPage.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/MuMuPage2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/MuMuPage2.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/backTitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/backTitle.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/end_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/end_round.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/enterGame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/enterGame.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/evolution.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/screenshot.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/missionCompleted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/missionCompleted.png -------------------------------------------------------------------------------- /国际服覆盖资源/templates/super_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/templates/super_evolution.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/enemy_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/enemy_round.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/error_retry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/error_retry.png -------------------------------------------------------------------------------- /shield/03835ba7f601cdfe564eacc090fa0fe5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/03835ba7f601cdfe564eacc090fa0fe5.png -------------------------------------------------------------------------------- /shield/190A7E4382F5F2C17C5CC2A031380755.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/190A7E4382F5F2C17C5CC2A031380755.png -------------------------------------------------------------------------------- /shield/1c9046994f324b5b94b8528666aed157.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/1c9046994f324b5b94b8528666aed157.jpg -------------------------------------------------------------------------------- /shield/3e5fcb22647a3bebd87277c8690ae2be.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/3e5fcb22647a3bebd87277c8690ae2be.jpg -------------------------------------------------------------------------------- /shield/3eab4f3f98b1b8282c1a27fdf1a2201c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/3eab4f3f98b1b8282c1a27fdf1a2201c.png -------------------------------------------------------------------------------- /shield/4e70ebed9d5f5b6ebf80df0a1f55bc22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/4e70ebed9d5f5b6ebf80df0a1f55bc22.jpg -------------------------------------------------------------------------------- /shield/690957613d9b90950bddb2235e523f56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/690957613d9b90950bddb2235e523f56.png -------------------------------------------------------------------------------- /shield/6ECCF60A72AE9A9AE41F148B4661C6FC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/6ECCF60A72AE9A9AE41F148B4661C6FC.png -------------------------------------------------------------------------------- /shield/7D28F988866FA61E68F98F51486C1FBC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/7D28F988866FA61E68F98F51486C1FBC.png -------------------------------------------------------------------------------- /shield/7e60222b58d71a4474f7dd9a13ecab8a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/7e60222b58d71a4474f7dd9a13ecab8a.png -------------------------------------------------------------------------------- /shield/947A76CBEA20B61F8DFC1FE794F88906.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/947A76CBEA20B61F8DFC1FE794F88906.png -------------------------------------------------------------------------------- /shield/9bd533b8db6597d6502a5f1eff6a553e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/9bd533b8db6597d6502a5f1eff6a553e.png -------------------------------------------------------------------------------- /shield/a79d3d0a49bc409153a28ec50903689e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/a79d3d0a49bc409153a28ec50903689e.png -------------------------------------------------------------------------------- /shield/b263ad960fda061bd039164fe9a7d367.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/b263ad960fda061bd039164fe9a7d367.png -------------------------------------------------------------------------------- /shield/be2343db66b870f88c2fde7f468eb6e3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/be2343db66b870f88c2fde7f468eb6e3.png -------------------------------------------------------------------------------- /shield/c90fa9c07bcba0bf0093f1814d30f811.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/c90fa9c07bcba0bf0093f1814d30f811.jpg -------------------------------------------------------------------------------- /shield/ec9d6b3570d67a43e030b56ad004d77c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/ec9d6b3570d67a43e030b56ad004d77c.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/missionCompleted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/missionCompleted.png -------------------------------------------------------------------------------- /国服覆盖资源/extra_templates/super_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国服覆盖资源/extra_templates/super_evolution.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/super_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/super_evolution.png -------------------------------------------------------------------------------- /国际服覆盖资源/extra_templates/missionCompleted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/国际服覆盖资源/extra_templates/missionCompleted.png -------------------------------------------------------------------------------- /shield/329dcf66-b002-47a9-96d5-b7b688ce3400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/329dcf66-b002-47a9-96d5-b7b688ce3400.png -------------------------------------------------------------------------------- /shield/378ac81d-7d78-4752-b30c-511789bd1c4f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/378ac81d-7d78-4752-b30c-511789bd1c4f.png -------------------------------------------------------------------------------- /shield/38aac6ca-b46c-4d1a-9a92-7ea697edb869.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/38aac6ca-b46c-4d1a-9a92-7ea697edb869.png -------------------------------------------------------------------------------- /shield/3ace49eb-e35c-4c4a-82a4-924188a1460d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/3ace49eb-e35c-4c4a-82a4-924188a1460d.png -------------------------------------------------------------------------------- /shield/45bfe177-2acb-4f16-9212-80b3ef7d7845.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/45bfe177-2acb-4f16-9212-80b3ef7d7845.png -------------------------------------------------------------------------------- /shield/5f54f4af-9623-4c20-bee0-338c8c6573db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/5f54f4af-9623-4c20-bee0-338c8c6573db.png -------------------------------------------------------------------------------- /shield/83c0117e-fcc3-475d-a157-c19b95b9e176.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/83c0117e-fcc3-475d-a157-c19b95b9e176.png -------------------------------------------------------------------------------- /shield/88a5f1b1-8891-458e-97fb-273694c0c882.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/88a5f1b1-8891-458e-97fb-273694c0c882.png -------------------------------------------------------------------------------- /shield/a8e4cc4f-73bf-4d92-b14b-a3068f016b32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/a8e4cc4f-73bf-4d92-b14b-a3068f016b32.png -------------------------------------------------------------------------------- /shield/a906ee61-1f26-4c1f-b022-0c8c00fa50d9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/a906ee61-1f26-4c1f-b022-0c8c00fa50d9.png -------------------------------------------------------------------------------- /shield/b7041906-ff76-4f80-a8af-fc748a37b3d9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/b7041906-ff76-4f80-a8af-fc748a37b3d9.png -------------------------------------------------------------------------------- /shield/c9c6ddd8-faeb-45d2-99be-fd3ced8c2988.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/c9c6ddd8-faeb-45d2-99be-fd3ced8c2988.png -------------------------------------------------------------------------------- /shield/d54d3ed4-c51b-49a4-a89a-ead6c3a1a755.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/d54d3ed4-c51b-49a4-a89a-ead6c3a1a755.png -------------------------------------------------------------------------------- /shield/d9174a23-e7c5-413e-918a-eeb30a4f5042.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/d9174a23-e7c5-413e-918a-eeb30a4f5042.png -------------------------------------------------------------------------------- /shield/d929dd91-f0c1-472b-b188-1b4e55fa75d9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/d929dd91-f0c1-472b-b188-1b4e55fa75d9.png -------------------------------------------------------------------------------- /shield/dbcd4111-ab1b-427d-a79d-d0c92b8dbdd2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/dbcd4111-ab1b-427d-a79d-d0c92b8dbdd2.png -------------------------------------------------------------------------------- /shield/dc2cd93c-4a14-4372-843a-03a04adb209d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/dc2cd93c-4a14-4372-843a-03a04adb209d.png -------------------------------------------------------------------------------- /shield/e1674f3d-34dd-43e2-b193-ba4791b53a2c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/e1674f3d-34dd-43e2-b193-ba4791b53a2c.png -------------------------------------------------------------------------------- /shield/e56f27d8-229d-4edc-9142-96775cdd5423.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/e56f27d8-229d-4edc-9142-96775cdd5423.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVNjZIaG81dW9DRGchIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVNjZIaG81dW9DRGchIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVNzZIaG9SUnNKRGchIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVNzZIaG9SUnNKRGchIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVQTVYaG9CWFZlR0EhIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVQTVYaG9CWFZlR0EhIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVZDUzaG8uOTZaT0EhIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVZDUzaG8uOTZaT0EhIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVZDUzaG9sTm1nT0EhIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRVZDUzaG9sTm1nT0EhIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNXpIaG84Smw4Q3chIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNXpIaG84Smw4Q3chIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNXpIaG9GR09FQ3chIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNXpIaG9GR09FQ3chIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNnpIaG81VW1WQ3chIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNnpIaG81VW1WQ3chIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNnpIaG9BVG1NQ3chIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXNnpIaG9BVG1NQ3chIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXczVIaG80KkprRXchIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXczVIaG80KkprRXchIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXczVIaG9UWGhkRXchIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRXczVIaG9UWGhkRXchIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRYKjVIaG9CdlJXR0EhIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRYKjVIaG9CdlJXR0EhIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRYZzZIaG83bGJsRnchIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRYZzZIaG83bGJsRnchIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /shield/NR8AVjViQ1FBNU5qYzJNekkyTVRYZzZIaG9IZXZzRnchIQUAcXVuZ3o!.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarWishLXH/ShadowVerseWB-auto/HEAD/shield/NR8AVjViQ1FBNU5qYzJNekkyTVRYZzZIaG9IZXZzRnchIQUAcXVuZ3o!.png -------------------------------------------------------------------------------- /config-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "emulator_port": 16384, 3 | "scan_interval": 2, 4 | "evolution_threshold": 0.85, 5 | "extra_templates_dir": "extra_templates", 6 | "extra_drag_delay": 0.01, 7 | "app_package": "jp.co.cygames.ShadowverseWorldsBeyond" 8 | } 9 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: 设置命令行编码为 UTF-8,避免出现乱码 3 | chcp 65001 4 | 5 | SET VENV_DIR=venv 6 | 7 | :: Step 2: 激活虚拟环境 8 | echo 激活虚拟环境... 9 | call %VENV_DIR%\Scripts\activate.bat 10 | 11 | :: Step 4: 执行 Python 脚本 12 | echo 执行 sv-auto.py 脚本... 13 | python sv-auto.py 14 | 15 | :: Step 5: 退出虚拟环境 16 | deactivate 17 | 18 | echo 完成! 19 | pause 20 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python 调试程序: 当前文件", 9 | "type": "debugpy", 10 | "request": "launch", 11 | "program": "${file}", 12 | "console": "integratedTerminal" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /使用说明.txt: -------------------------------------------------------------------------------- 1 | github项目地址:https://github.com/StarWishLXH/ShadowVerseWB-auto 2 | 1、请使用1280x720分辨率,然后将对战场地设置成简易场地 3 | 2、额外需要自动点击的图片可放在 extra_templates 文件夹里 4 | 3、敌方护盾没识别到的请替换或添加 shield 文件夹里的截图 5 | 4、模拟器端口可在 config.json 中修改,在mumu模拟器的诊断信息中查看ADB端口号,填写到配置文件的emulator_port配置中 6 | 5、默认国服,根据服务器自行选择附带的资源替换 templates 和 extra_templates 文件夹,如有按钮无法识别请自行替换素材 7 | 6、阶位对战图片在不同分段均不相同,第一次使用时请自行截图替换 templates 中的 mainPage.png 8 | 7、自动跳过每日免费卡包,请记得自行领取 9 | 8、国际服使用mumu模拟器如果发现游戏亮度过低,请在模拟器配置中将亮度拉到最高 10 | 9、如果模拟器第一次打开游戏卡在设备优化界面,在模拟器设置中配置使用DirectX而非Vulkan 11 | 10、使用前需要在游戏设置中关闭回合结束提示 12 | 11、自己不要带盾,检测到己方带盾会自动暂停脚本 13 | 12、如果遇到操作漏刀的情况,可以尝试调高配置文件中的 extra_drag_delay(单位是秒,建议0.01-0.1之间) 14 | 13、自动关闭功能需要先点击开始,然后在点击设置 15 | 14、如遇上拖动脚本窗口卡顿现象,可将Image文件夹中的UI背景文件移除 16 | -------------------------------------------------------------------------------- /sv-auto.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | a = Analysis( 5 | ['sv-auto.py'], 6 | pathex=[], 7 | binaries=[], 8 | datas=[ 9 | ('.venv/Lib/site-packages/uiautomator2/assets/u2.jar', 'uiautomator2/assets') 10 | ], 11 | hiddenimports=[], 12 | hookspath=[], 13 | hooksconfig={}, 14 | runtime_hooks=[], 15 | excludes=[], 16 | noarchive=False, 17 | optimize=0, 18 | ) 19 | 20 | pyz = PYZ(a.pure) 21 | 22 | exe = EXE( 23 | pyz, 24 | a.scripts, 25 | a.binaries, 26 | a.datas, 27 | [], 28 | name='ShadowverseAutomation', 29 | icon='app_icon.ico', 30 | debug=False, 31 | bootloader_ignore_signals=False, 32 | strip=False, 33 | upx=True, 34 | upx_exclude=[], 35 | runtime_tmpdir=None, 36 | console=False, 37 | disable_windowed_traceback=False, 38 | argv_emulation=False, 39 | target_arch=None, 40 | codesign_identity=None, 41 | entitlements_file=None, 42 | ) 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 StarWish 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 | -------------------------------------------------------------------------------- /init.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: 设置命令行编码为 UTF-8,避免出现乱码 3 | chcp 65001 4 | 5 | SET VENV_DIR=venv 6 | SET REQUIREMENTS_FILE=requirements.txt 7 | 8 | :: Step 1: 检查虚拟环境是否存在 9 | IF NOT EXIST "%VENV_DIR%\Scripts\activate.bat" ( 10 | echo 虚拟环境不存在,正在创建... 11 | python -m venv %VENV_DIR% 12 | IF %ERRORLEVEL% NEQ 0 ( 13 | echo 创建虚拟环境失败!请检查是否安装了 Python。 14 | exit /b 1 15 | ) 16 | ) 17 | 18 | :: Step 2: 激活虚拟环境 19 | echo 激活虚拟环境... 20 | call %VENV_DIR%\Scripts\activate.bat 21 | 22 | :: Step 3: 检查并安装所需依赖 23 | IF NOT EXIST "%REQUIREMENTS_FILE%" ( 24 | echo 未找到 requirements.txt 文件,请确保其存在。 25 | exit /b 1 26 | ) 27 | 28 | echo 检查并安装依赖... 29 | pip install --upgrade pip 30 | pip install -r %REQUIREMENTS_FILE% -i https://mirrors.aliyun.com/pypi/simple/ 31 | 32 | :: Step 4: 检查并生成配置文件 33 | IF NOT EXIST "config.json" ( 34 | echo 未找到config.json,从模板生成... 35 | COPY "config-template.json" "config.json" 36 | IF %ERRORLEVEL% NEQ 0 ( 37 | echo 生成config.json失败! 38 | exit /b 1 39 | ) 40 | ) 41 | 42 | :: Step 5: 检查并复制模板资源 43 | SET RESOURCE_DIR=国服覆盖资源 44 | 45 | IF NOT EXIST "templates" ( 46 | echo 未找到templates文件夹,从资源目录复制... 47 | XCOPY /E /I "%RESOURCE_DIR%\templates" "templates" 48 | IF %ERRORLEVEL% NEQ 0 ( 49 | echo 复制templates文件夹失败! 50 | exit /b 1 51 | ) 52 | ) 53 | 54 | IF NOT EXIST "extra_templates" ( 55 | echo 未找到extra_templates文件夹,从资源目录复制... 56 | XCOPY /E /I "%RESOURCE_DIR%\extra_templates" "extra_templates" 57 | IF %ERRORLEVEL% NEQ 0 ( 58 | echo 复制extra_templates文件夹失败! 59 | exit /b 1 60 | ) 61 | ) 62 | 63 | echo 初始化检查完成! -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shadowverse Automation 2 | 3 | 一个用于Shadowverse: Worlds Beyond游戏的自动化脚本工具,提供图形界面操作,支持多服务器配置、换牌策略选择和战斗自动化功能。 4 | 5 | ## 基础功能 6 | 7 | Shadowverse Automation 提供以下核心功能: 8 | 9 | - **设备连接**:通过ADB协议连接安卓模拟器或真实设备 10 | - **多服务器支持**:完美适配国服与国际服游戏环境 11 | - **智能战斗系统**: 12 | - 自动识别战斗场景与卡牌 13 | - 支持多种换牌策略选择 14 | - 自动执行攻击、拖拽和回合结束操作 15 | - **实时监控**:显示当前回合、总运行时间、对战次数和总回合数 16 | - **参数自定义**:可调整攻击延迟、拖拽延迟等操作参数 17 | - **自动关闭**:设置挂机时长后自动结束程序 18 | - **日志系统**:记录操作过程与异常信息 19 | 20 | ## 简易安装与使用 21 | 22 | ### 安装步骤 23 | 1. 下载并解压项目压缩包 24 | 2. 双击运行 `ShadowverseAutomation.exe` 启动程序 25 | 26 | ### 快速上手 27 | 1. 在设备连接区域选择服务器并输入ADB端口 28 | 2. 点击"开始"按钮连接设备 29 | 3. 在策略配置区域选择合适的换牌策略 30 | 4. 调整攻击延迟和拖拽延迟参数 31 | 5. 点击"恢复"按钮开始自动化流程 32 | 33 | ## 安装说明 34 | 35 | ### 环境要求 36 | - Python 3.13+ 37 | - Windows 10/11 操作系统 38 | - 安卓模拟器或真实设备(开启USB调试) 39 | 40 | ### 手动安装(高级用户) 41 | 42 | 1. 创建并激活虚拟环境 43 | ```powershell 44 | python -m venv .venv 45 | .venv\Scripts\activate 46 | ``` 47 | 48 | 2. 安装依赖 49 | ```powershell 50 | pip install -r requirements.txt 51 | ``` 52 | 53 | 3. 运行应用 54 | ```powershell 55 | python sv-auto.py 56 | ``` 57 | 58 | 4. 生成可执行文件 59 | ```powershell 60 | pyinstaller sv-auto.spec 61 | ``` 62 | 63 | ## 开发者指南 64 | 65 | ### 打包与发布 66 | 67 | 1. 确保已完成环境配置和依赖安装 68 | 2. 执行打包命令生成可执行文件: 69 | ```powershell 70 | pyinstaller sv-auto.spec 71 | ``` 72 | 3. 打包完成后,可执行文件将位于`dist`目录下 73 | 4. 发布时需包含以下文件: 74 | - 可执行文件 75 | - Image/目录 76 | - assets/目录 77 | - 各模板目录(templates/, templates2/, etc.) 78 | 79 | ### 命令行安装与使用 80 | 81 | #### 安装开发环境 82 | ```powershell 83 | # 克隆仓库 84 | git clone https://github.com/StarWishLXH/ShadowVerseWB-auto.git 85 | cd ShadowVerseWB-auto 86 | 87 | # 创建并激活虚拟环境 88 | python -m venv .venv 89 | .venv\Scripts\activate 90 | 91 | # 安装依赖 92 | pip install -r requirements.txt 93 | ``` 94 | 95 | ## 使用方法 96 | 97 | 1. 启动应用程序后,在左侧设备连接区域: 98 | - 选择服务器(国服/国际服) 99 | - 输入ADB端口号 100 | - 点击"开始"按钮连接设备 101 | 102 | 2. 在策略配置区域: 103 | - 选择合适的换牌策略 104 | - 设置攻击延迟和拖拽延迟参数 105 | 106 | 3. 点击主控制区域的"恢复"按钮开始自动化流程 107 | 108 | 4. 监控区域将显示实时统计信息: 109 | - 当前回合数 110 | - 总运行时间 111 | - 对战次数 112 | - 总回合数 113 | 114 | ## KNOWN ISSUE 115 | 116 | 1. **字体警告**: 启动时可能出现"qt.qpa.fonts: Unable to enumerate family 'WenYue XinQingNianTi'"警告,不影响功能使用 117 | 2. **布局警告**: 部分环境可能出现"QLayout::addChildLayout: layout "" already has a parent"警告,已通过删除空布局修复 118 | 3. **ADB连接问题**: 部分模拟器需要手动配置端口映射或使用特定ADB版本 119 | 4. **分辨率适配**: 目前仅支持1080p分辨率的游戏窗口,其他分辨率可能导致识别错误 120 | 121 | ## TODO 122 | 123 | 1. 添加卡牌识别优化算法 124 | 2. 增加更多换牌策略模板 125 | 3. 添加多语言支持 126 | 127 | ## 重要更新 128 | 129 | ### ShadowverseAutomation-fix14(2025-07-05) 130 | - 初始版本发布,包含基础战斗自动化功能 131 | - 支持国服与国际服双服务器 132 | 133 | ### ShadowverseAutomation-fix20(2025-07-06) 134 | - 修改UI 135 | 136 | ### ShadowverseAutomation-fix21(2025-07-30) 137 | - 根据ranran佬重构UI排版 138 | - 新增三种换牌策略 139 | - 新增攻击延迟、拖拽延迟、扫描间隔设置 140 | - 新增挂机时长设置 141 | 142 | ## 注意事项 143 | - 使用前请确保已安装安卓模拟器并开启USB调试 144 | - 不同电脑配置可能需要调整延迟参数以获得最佳效果 145 | - 请勿过度使用自动化功能,以免影响游戏公平性(如被封禁,本脚本不负责) 146 | 147 | ## 许可证 148 | 本项目采用MIT许可证 - 详见LICENSE文件 149 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[codz] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | #poetry.toml 110 | 111 | # pdm 112 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 113 | # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. 114 | # https://pdm-project.org/en/latest/usage/project/#working-with-version-control 115 | #pdm.lock 116 | #pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # pixi 121 | # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. 122 | #pixi.lock 123 | # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one 124 | # in the .venv directory. It is recommended not to include this directory in version control. 125 | .pixi 126 | 127 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 128 | __pypackages__/ 129 | 130 | # Celery stuff 131 | celerybeat-schedule 132 | celerybeat.pid 133 | 134 | # SageMath parsed files 135 | *.sage.py 136 | 137 | # Environments 138 | .env 139 | .envrc 140 | .venv 141 | env/ 142 | venv/ 143 | ENV/ 144 | env.bak/ 145 | venv.bak/ 146 | 147 | # Spyder project settings 148 | .spyderproject 149 | .spyproject 150 | 151 | # Rope project settings 152 | .ropeproject 153 | 154 | # mkdocs documentation 155 | /site 156 | 157 | # mypy 158 | .mypy_cache/ 159 | .dmypy.json 160 | dmypy.json 161 | 162 | # Pyre type checker 163 | .pyre/ 164 | 165 | # pytype static type analyzer 166 | .pytype/ 167 | 168 | # Cython debug symbols 169 | cython_debug/ 170 | 171 | # PyCharm 172 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 173 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 174 | # and can be added to the global gitignore or merged into this file. For a more nuclear 175 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 176 | #.idea/ 177 | 178 | # Abstra 179 | # Abstra is an AI-powered process automation framework. 180 | # Ignore directories containing user credentials, local state, and settings. 181 | # Learn more at https://abstra.io/docs 182 | .abstra/ 183 | 184 | # Visual Studio Code 185 | # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore 186 | # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore 187 | # and can be added to the global gitignore or merged into this file. However, if you prefer, 188 | # you could uncomment the following to ignore the entire vscode folder 189 | # .vscode/ 190 | 191 | # Ruff stuff: 192 | .ruff_cache/ 193 | 194 | # PyPI configuration file 195 | .pypirc 196 | 197 | # Cursor 198 | # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to 199 | # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data 200 | # refer to https://docs.cursor.com/context/ignore-files 201 | .cursorignore 202 | .cursorindexingignore 203 | 204 | # Marimo 205 | marimo/_static/ 206 | marimo/_lsp/ 207 | __marimo__/ 208 | 209 | # custom 210 | config.json 211 | /build 212 | /dist 213 | /release 214 | /extra_templates 215 | /templates 216 | /test_resource 217 | round_statistics.json 218 | sv-auto.exe 219 | -------------------------------------------------------------------------------- /sv-auto.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import logging 4 | import time 5 | import json 6 | import cv2 7 | import numpy as np 8 | import queue 9 | import datetime 10 | import random 11 | import io 12 | import ctypes 13 | from ctypes import wintypes 14 | from ctypes import windll 15 | 16 | from PyQt5.QtWidgets import ( 17 | QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, 18 | QLineEdit, QPushButton, QTextEdit, QFrame, QGridLayout, QGroupBox, 19 | QComboBox, QMessageBox, QSizePolicy, QStackedWidget, QDialog, QFormLayout 20 | ) 21 | from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer 22 | from PyQt5.QtGui import QPalette, QColor, QPixmap, QBrush, QDoubleValidator 23 | from PyQt5.QtWidgets import QMessageBox 24 | from PyQt5.QtGui import QIntValidator 25 | 26 | # 当前版本号 27 | CURRENT_VERSION = "1.2.0" 28 | 29 | # 背景图片路径 30 | BACKGROUND_IMAGE = os.path.join("Image", "ui背景.jpg") if os.path.exists("Image") else None 31 | 32 | # 随从的位置坐标(720P分辨率) 33 | follower_positions = [ 34 | (310, 398), 35 | (389, 398), 36 | (468, 398), 37 | (547, 398), 38 | (626, 398), 39 | (705, 398), 40 | (784, 398), 41 | (863, 398), 42 | (942, 398), 43 | ] 44 | reversed_follower_positions = follower_positions[::-1] 45 | 46 | DEFAULT_CONFIG = { 47 | "emulator_port": 16384, 48 | "scan_interval": 2, 49 | "evolution_threshold": 0.85, 50 | "extra_templates_dir": "extra_templates", 51 | "server": "国服", # 默认服务器 52 | "version": CURRENT_VERSION, # 当前版本 53 | "attack_delay": 0.25, # 新增:攻击延迟默认值 54 | "extra_drag_delay": 0.05, # 新增:拖拽操作后的额外延迟 55 | "inactivity_timeout": 300, # 新增:挂机时长默认5分钟 56 | "inactivity_timeout_hours": 0, # 新增:挂机时长小时数 57 | "inactivity_timeout_minutes": 5, # 新增:挂机时长分钟数 58 | "inactivity_timeout_seconds": 0, # 新增:挂机时长秒数 59 | } 60 | 61 | def load_config(): 62 | """加载配置文件""" 63 | config_file = "config.json" 64 | 65 | # 如果配置文件不存在,创建默认配置 66 | if not os.path.exists(config_file): 67 | logger.info(f"创建默认配置文件: {config_file}") 68 | with open(config_file, 'w', encoding='utf-8') as f: 69 | json.dump(DEFAULT_CONFIG, f, indent=2) 70 | return DEFAULT_CONFIG.copy() 71 | 72 | try: 73 | with open(config_file, 'r', encoding='utf-8') as f: 74 | config = json.load(f) 75 | # 合并默认配置和用户配置 76 | for key in DEFAULT_CONFIG: 77 | if key not in config: 78 | config[key] = DEFAULT_CONFIG[key] 79 | return config 80 | except Exception as e: 81 | logger.error(f"加载配置文件失败: {str(e)},使用默认配置") 82 | return DEFAULT_CONFIG.copy() 83 | 84 | # 配置日志 85 | logger = logging.getLogger(__name__) 86 | logger.setLevel(logging.INFO) 87 | 88 | # 创建文件日志处理器 89 | file_handler = logging.FileHandler("script_log.log") 90 | file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') 91 | file_handler.setFormatter(file_formatter) 92 | 93 | # 创建控制台日志处理器 94 | if sys.stdout is not None: 95 | sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') 96 | if sys.stderr is not None: 97 | sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') 98 | console_handler = logging.StreamHandler(sys.stdout) 99 | console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') 100 | console_handler.setFormatter(console_formatter) 101 | 102 | # 添加处理器 103 | logger.addHandler(file_handler) 104 | logger.addHandler(console_handler) 105 | 106 | # 回合统计相关变量 107 | current_round_count = 1 # 当前对战的回合数 108 | match_start_time = None # 当前对战开始时间 109 | match_history = [] # 存储所有对战记录 110 | round_stats_file = "round_statistics.json" # 统计数据保存文件 111 | current_run_matches = 0 # 本次运行的对战次数 112 | current_run_start_time = None # 本次脚本启动时间 113 | 114 | # 创建Tkinter消息队列 115 | notification_queue = queue.Queue() 116 | 117 | # 模板目录 118 | TEMPLATES_DIR = "templates" # 国服模板目录 119 | TEMPLATES_DIR_INTERNATIONAL = "templates2" # 国际服模板目录 120 | TEMPLATES_DIR_COST = "templates_cost" # 费用模板目录 121 | 122 | # 进化按钮模板(全局) 123 | evolution_template = None 124 | super_evolution_template = None 125 | 126 | # 命令队列 127 | command_queue = queue.Queue() 128 | 129 | # 全局设备对象 130 | device = None 131 | 132 | # 随从基准背景色 133 | base_colors = None 134 | 135 | # 是否在对战中 136 | in_match = False 137 | 138 | # UI日志信号 139 | ui_log_signal = pyqtSignal(str) 140 | 141 | # ================== 核心功能函数 ================== 142 | def take_screenshot(): 143 | """获取设备截图 - 使用全局设备对象""" 144 | global device # 使用全局设备对象 145 | 146 | if device is None: 147 | logger.error("设备未初始化") 148 | return None 149 | 150 | try: 151 | return device.screenshot() 152 | except Exception as e: 153 | logger.error(f"截图失败: {str(e)}") 154 | return None 155 | 156 | def load_template(templates_dir, filename): 157 | """加载模板图像并返回灰度图""" 158 | path = os.path.join(templates_dir, filename) 159 | if not os.path.exists(path): 160 | logger.error(f"模板文件不存在: {path}") 161 | return None 162 | 163 | template = cv2.imread(path, cv2.IMREAD_GRAYSCALE) 164 | if template is None: 165 | logger.error(f"无法加载模板: {path}") 166 | return template 167 | 168 | def create_template_info(template, name, threshold=0.85): 169 | """创建模板信息字典""" 170 | if template is None: 171 | return None 172 | 173 | h, w = template.shape 174 | return { 175 | 'name': name, 176 | 'template': template, 177 | 'w': w, 178 | 'h': h, 179 | 'threshold': threshold 180 | } 181 | 182 | def match_template(gray_image, template_info): 183 | """执行模板匹配并返回结果""" 184 | if not template_info: 185 | return None, 0 186 | 187 | result = cv2.matchTemplate(gray_image, template_info['template'], cv2.TM_CCOEFF_NORMED) 188 | _, max_val, _, max_loc = cv2.minMaxLoc(result) 189 | return max_loc, max_val 190 | 191 | def scan_shield_targets(): 192 | """扫描指定矩形区域(247,151)-(1028,312)内的护盾随从(彩色匹配),最多返回一个置信度最高的目标""" 193 | shield_dir = "shield" 194 | shield_targets = [] # 存储所有检测到的护盾目标及其置信度 195 | 196 | # 确保shield目录存在 197 | if not os.path.exists(shield_dir) or not os.path.isdir(shield_dir): 198 | return [] 199 | 200 | screenshot_shield = take_screenshot() 201 | if screenshot_shield is None: 202 | return [] 203 | 204 | # 将PIL截图转为OpenCV格式 205 | screenshot_np = np.array(screenshot_shield) 206 | screenshot_cv = cv2.cvtColor(screenshot_np, cv2.COLOR_RGB2BGR) # RGB转BGR格式 207 | 208 | # 定义扫描区域 (247,151) 到 (1028,312) 209 | x1, y1 = 247, 151 210 | x2, y2 = 1028, 312 211 | width = x2 - x1 212 | height = y2 - y1 213 | 214 | # 只扫描指定矩形区域 215 | roi = screenshot_cv[y1:y2, x1:x2] 216 | 217 | # 加载所有护盾模板(彩色) 218 | shield_templates = [] 219 | for filename in os.listdir(shield_dir): 220 | if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): 221 | path = os.path.join(shield_dir, filename) 222 | template = cv2.imread(path) # 以彩色模式读取模板 223 | if template is not None: 224 | shield_templates.append(template) 225 | 226 | # 扫描匹配护盾模板并记录置信度 227 | for template in shield_templates: 228 | h, w = template.shape[:2] # 获取彩色模板的高度和宽度 229 | 230 | # 执行彩色模板匹配 231 | result = cv2.matchTemplate(roi, template, cv2.TM_CCOEFF_NORMED) 232 | threshold = 0.75 # 匹配阈值 233 | 234 | # 获取所有匹配位置及其置信度 235 | loc = np.where(result >= threshold) 236 | for pt in zip(*loc[::-1]): # 遍历所有匹配位置 237 | confidence = result[pt[1], pt[0]] # 获取当前匹配位置的置信度 238 | 239 | # 将相对坐标转换为绝对坐标 240 | abs_x = int(pt[0] + x1 + w // 2) 241 | abs_y = int(pt[1] + y1 + h // 2) 242 | 243 | # 添加到目标列表(包含坐标和置信度) 244 | shield_targets.append({ 245 | 'x': abs_x, 246 | 'y': abs_y, 247 | 'confidence': confidence 248 | }) 249 | 250 | # 按置信度从高到低排序 251 | shield_targets.sort(key=lambda t: t['confidence'], reverse=True) 252 | 253 | # 只取置信度最高的一个目标 254 | if len(shield_targets) > 1: 255 | shield_targets = shield_targets[:1] 256 | # 提取坐标列表 257 | coordinates = [(target['x'], target['y']) for target in shield_targets] 258 | 259 | return coordinates 260 | 261 | def save_round_statistics(): 262 | """保存回合统计数据到文件""" 263 | try: 264 | with open(round_stats_file, 'w', encoding='utf-8') as f: 265 | json.dump(match_history, f, ensure_ascii=False, indent=2) 266 | except Exception as e: 267 | logger.error(f"保存统计数据失败: {str(e)}") 268 | 269 | def load_round_statistics(): 270 | """从文件加载回合统计数据""" 271 | global match_history 272 | 273 | if not os.path.exists(round_stats_file): 274 | return 275 | 276 | try: 277 | with open(round_stats_file, 'r', encoding='utf-8') as f: 278 | match_history = json.load(f) 279 | except Exception as e: 280 | logger.error(f"加载统计数据失败: {str(e)}") 281 | 282 | def curved_drag(u2_device, start_x, start_y, end_x, end_y, duration, extra_delay, steps=3): 283 | """ 284 | 模拟曲线拖拽操作 285 | :param u2_device: 设备对象 286 | :param start_x: 起始点x坐标 287 | :param start_y: 起始点y坐标 288 | :param end_x: 结束点x坐标 289 | :param end_y: 结束点y坐标 290 | :param duration: 拖拽持续时间(秒) 291 | :param steps: 拖拽路径中的步骤数 292 | """ 293 | u2_device.touch.down(start_x, start_y) 294 | time.sleep(extra_delay) 295 | 296 | for i in range(1, steps + 1): 297 | t = i / steps 298 | # 模拟抛物线 299 | xi = start_x + (end_x - start_x) * t 300 | yi = start_y + (end_y - start_y) * (t ** 0.85) 301 | 302 | u2_device.touch.move(int(xi), int(yi)) 303 | time.sleep(duration / steps) 304 | 305 | u2_device.touch.move(end_x, end_y) 306 | time.sleep(extra_delay) 307 | u2_device.touch.up(end_x, end_y) 308 | 309 | def load_evolution_template(server): 310 | """加载进化按钮模板""" 311 | global evolution_template 312 | 313 | # 根据服务器选择模板目录 314 | templates_dir = TEMPLATES_DIR if server == "国服" else TEMPLATES_DIR_INTERNATIONAL 315 | 316 | if evolution_template is None: 317 | # 使用全局定义的 TEMPLATES_DIR 318 | template_img = load_template(templates_dir, 'evolution.png') 319 | if template_img is None: 320 | logger.error("无法加载进化按钮模板") 321 | return None 322 | 323 | evolution_template = create_template_info( 324 | template_img, 325 | "进化按钮", 326 | threshold=0.85 327 | ) 328 | return evolution_template 329 | 330 | def load_super_evolution_template(server): 331 | """加载超进化按钮模板""" 332 | global super_evolution_template 333 | 334 | # 根据服务器选择模板目录 335 | templates_dir = TEMPLATES_DIR if server == "国服" else TEMPLATES_DIR_INTERNATIONAL 336 | 337 | if super_evolution_template is None: 338 | # 使用全局定义的 TEMPLATES_DIR 339 | template_img = load_template(templates_dir, 'super_evolution.png') 340 | if template_img is None: 341 | logger.error("无法加载超进化按钮模板") 342 | return None 343 | 344 | super_evolution_template = create_template_info( 345 | template_img, 346 | "超进化按钮", 347 | threshold=0.85 348 | ) 349 | return super_evolution_template 350 | 351 | def detect_evolution_button(gray_screenshot, server): 352 | """检测进化按钮是否出现""" 353 | evolution_info = load_evolution_template(server) 354 | if not evolution_info: 355 | return None, 0 356 | 357 | max_loc, max_val = match_template(gray_screenshot, evolution_info) 358 | return max_loc, max_val 359 | 360 | def detect_super_evolution_button(gray_screenshot, server): 361 | """检测超进化按钮是否出现""" 362 | evolution_info = load_super_evolution_template(server) 363 | if not evolution_info: 364 | return None, 0 365 | 366 | max_loc, max_val = match_template(gray_screenshot, evolution_info) 367 | return max_loc, max_val 368 | 369 | def perform_follower_attacks(u2_device, screenshot, base_colors, config): 370 | """检测并执行随从攻击(优先攻击护盾目标)(从右往左尝试攻击)""" 371 | # 对面主人位置(默认攻击目标) 372 | default_target = (646, 64) 373 | need_scan_shield = True 374 | 375 | # 颜色检测不够准确,先使用旧逻辑 376 | if False: 377 | for i, pos in enumerate(reversed_follower_positions): 378 | x, y = pos 379 | attackDelay = 0.03 380 | # 获取当前位置的色彩 381 | current_color1 = screenshot.getpixel((x, y)) 382 | # 获取Y轴向下20个像素点的色彩 383 | current_color2 = screenshot.getpixel((x, y + 20)) 384 | 385 | # 检查基准背景色是否存在 386 | if i >= len(base_colors): 387 | continue 388 | # 获取基准背景色(两个点) 389 | base_color1, base_color2 = base_colors[i] 390 | 391 | # 计算当前位置的色彩差异(RGB欧氏距离) 392 | r_diff1 = abs(current_color1[0] - base_color1[0]) 393 | g_diff1 = abs(current_color1[1] - base_color1[1]) 394 | b_diff1 = abs(current_color1[2] - base_color1[2]) 395 | color_diff1 = (r_diff1 + g_diff1 + b_diff1) / 3 396 | 397 | # 计算下方20像素点的色彩差异 398 | r_diff2 = abs(current_color2[0] - base_color2[0]) 399 | g_diff2 = abs(current_color2[1] - base_color2[1]) 400 | b_diff2 = abs(current_color2[2] - base_color2[2]) 401 | color_diff2 = (r_diff2 + g_diff2 + b_diff2) / 3 402 | 403 | # 如果两个位置中有一个色彩差异超过阈值,则认为有随从 404 | if color_diff1 > 25 or color_diff2 > 25: 405 | # 扫描护盾目标 406 | if need_scan_shield: 407 | shield_targets = scan_shield_targets() 408 | 409 | if shield_targets: 410 | logger.info(f"检测到护盾目标,优先攻击") 411 | target_x, target_y = shield_targets[0] 412 | attackDelay = 1 413 | else: 414 | need_scan_shield = False 415 | logger.info(f"未检测到护盾,直接攻击主战者") 416 | target_x, target_y = default_target 417 | 418 | # 确保坐标是整数 419 | target_x = int(target_x) 420 | target_y = int(target_y) 421 | curved_drag(u2_device, x, y, target_x, target_y, 0.03, config["extra_drag_delay"], 3) 422 | time.sleep(attackDelay) 423 | else: 424 | # 后备方案:执行简易坐标 425 | # 固定攻击 426 | # logger.warning("未找到基准背景色,执行默认攻击") 427 | for i, pos in enumerate(reversed_follower_positions): 428 | x, y = pos 429 | attackDelay = 0.03 430 | 431 | if need_scan_shield: 432 | logger.info(f"开始检测护盾") 433 | shield_targets = scan_shield_targets() 434 | else: 435 | logger.info(f"跳过护盾检测") 436 | 437 | if shield_targets: 438 | logger.info(f"检测到护盾目标,优先攻击") 439 | target_x, target_y = shield_targets[0] 440 | attackDelay = 2.1 441 | else: 442 | need_scan_shield = False 443 | logger.info(f"未检测到护盾,直接攻击主战者") 444 | target_x, target_y = default_target 445 | # 确保坐标是整数 446 | target_x = int(target_x) 447 | target_y = int(target_y) 448 | curved_drag(u2_device, x, y, target_x, target_y, 0.03, config["extra_drag_delay"], 3) 449 | time.sleep(attackDelay) 450 | 451 | # 避免攻击被卡掉 - 使用传入的自定义延迟参数 452 | time.sleep(config["attack_delay"]) 453 | 454 | def save_round_statistics(): 455 | """保存回合统计数据到文件""" 456 | try: 457 | with open(round_stats_file, 'w', encoding='utf-8') as f: 458 | json.dump(match_history, f, ensure_ascii=False, indent=2) 459 | except Exception as e: 460 | logger.error(f"保存统计数据失败: {str(e)}") 461 | 462 | def perform_evolution_actions(u2_device, screenshot, base_colors, server): 463 | """ 464 | 执行进化/超进化操作(带检测)- 复用颜色检测逻辑 465 | :param u2_device: u2设备对象 466 | :param screenshot: 当前截图 467 | :param base_colors: 基准背景色列表 468 | :param server: 服务器名称 469 | :return: 是否检测到进化按钮 470 | """ 471 | global device 472 | 473 | evolution_detected = False 474 | 475 | # 基准背景色检测并不准确,先固定使用旧逻辑 476 | return perform_evolution_actions_fallback(u2_device, server) 477 | 478 | # 如果无法获取截图,回退到旧逻辑 479 | if screenshot is None: 480 | logger.warning("无法获取截图,使用旧逻辑进行进化操作") 481 | return perform_evolution_actions_fallback(u2_device, server) 482 | 483 | # 如果没有基准背景色,使用旧逻辑 484 | if not base_colors: 485 | logger.warning("没有基准背景色,使用旧逻辑进行进化操作") 486 | return perform_evolution_actions_fallback(u2_device, server) 487 | 488 | # 有护盾时从右侧开始进化,没有护盾时从左侧开始进化 489 | exist_shield = scan_shield_targets() 490 | if exist_shield: 491 | evolve_positions = reversed_follower_positions 492 | else: 493 | evolve_positions = follower_positions 494 | 495 | # 遍历每个随从位置 496 | for i, pos in enumerate(evolve_positions): 497 | x, y = pos 498 | 499 | # 检查基准背景色是否存在 500 | if i >= len(base_colors): 501 | continue 502 | 503 | # 获取当前位置的色彩 504 | current_color1 = screenshot.getpixel((x, y)) 505 | # 获取Y轴向下20个像素点的色彩 506 | current_color2 = screenshot.getpixel((x, y + 20)) 507 | base_color1, base_color2 = base_colors[i] 508 | 509 | # 计算当前位置的色彩差异 510 | r_diff1 = abs(current_color1[0] - base_color1[0]) 511 | g_diff1 = abs(current_color1[1] - base_color1[1]) 512 | b_diff1 = abs(current_color1[2] - base_color1[2]) 513 | color_diff1 = (r_diff1 + g_diff1 + b_diff1) / 3 514 | 515 | # 计算下方20像素点的色彩差异 516 | r_diff2 = abs(current_color2[0] - base_color2[0]) 517 | g_diff2 = abs(current_color2[1] - base_color2[1]) 518 | b_diff2 = abs(current_color2[2] - base_color2[2]) 519 | color_diff2 = (r_diff2 + g_diff2 + b_diff2) / 3 520 | 521 | # 如果两个位置中有一个色彩差异超过阈值,则认为有随从 522 | if color_diff1 > 25 or color_diff2 > 25: 523 | # 点击该位置 524 | u2_device.click(x, y) 525 | time.sleep(0.1) # 等待进化按钮出现 526 | 527 | # 获取新截图检测进化按钮 528 | new_screenshot = take_screenshot() 529 | if new_screenshot is None: 530 | logger.warning(f"位置 {i} 无法获取截图,跳过检测") 531 | continue 532 | 533 | # 转换为OpenCV格式 534 | new_screenshot_np = np.array(new_screenshot) 535 | new_screenshot_cv = cv2.cvtColor(new_screenshot_np, cv2.COLOR_RGB2BGR) 536 | gray_screenshot = cv2.cvtColor(new_screenshot_cv, cv2.COLOR_BGR2GRAY) 537 | 538 | # 同时检查两个检测函数 539 | max_loc, max_val = detect_super_evolution_button(gray_screenshot, server) 540 | if max_val >= 0.825: 541 | template_info = load_super_evolution_template(server) 542 | if template_info: 543 | center_x = max_loc[0] + template_info['w'] // 2 544 | center_y = max_loc[1] + template_info['h'] // 2 545 | u2_device.click(center_x, center_y) 546 | logger.info(f"检测到超进化按钮并点击 ") 547 | evolution_detected = True 548 | break 549 | 550 | max_loc1, max_val1 = detect_evolution_button(gray_screenshot, server) 551 | if max_val1 >= 0.90: 552 | template_info = load_evolution_template(server) 553 | if template_info: 554 | center_x = max_loc1[0] + template_info['w'] // 2 555 | center_y = max_loc1[1] + template_info['h'] // 2 556 | u2_device.click(center_x, center_y) 557 | logger.info(f"检测到进化按钮并点击 ") 558 | evolution_detected = True 559 | break 560 | 561 | return evolution_detected 562 | 563 | def perform_evolution_actions_fallback(u2_device, server, is_super=False): 564 | """ 565 | 执行进化/超进化操作的旧逻辑(遍历所有位置) 566 | :param device: 设备对象 567 | :param server: 服务器名称 568 | """ 569 | evolution_detected = False 570 | logger_word = False 571 | 572 | # 有护盾时从右侧开始进化,没有护盾时从左侧开始进化 573 | exist_shield = scan_shield_targets() 574 | if exist_shield: 575 | evolve_positions = reversed_follower_positions 576 | else: 577 | evolve_positions = follower_positions 578 | 579 | # 遍历所有位置 580 | for i, pos in enumerate(evolve_positions): 581 | follower_x, follower_y = pos 582 | u2_device.click(follower_x, follower_y) 583 | time.sleep(0.5) 584 | 585 | # 尝试检测进化按钮 586 | screenshot = take_screenshot() 587 | if screenshot is None: 588 | logger.warning(f"位置 {i} 无法获取截图,跳过检测") 589 | time.sleep(0.1) 590 | continue 591 | 592 | # 转换为OpenCV格式 593 | screenshot_np = np.array(screenshot) 594 | screenshot_cv = cv2.cvtColor(screenshot_np, cv2.COLOR_RGB2BGR) 595 | gray_screenshot = cv2.cvtColor(screenshot_cv, cv2.COLOR_BGR2GRAY) 596 | 597 | max_loc, max_val = detect_super_evolution_button(gray_screenshot, server) 598 | if max_val >= 0.825: 599 | template_info = load_super_evolution_template(server) 600 | center_x = max_loc[0] + template_info['w'] // 2 601 | center_y = max_loc[1] + template_info['h'] // 2 602 | u2_device.click(center_x, center_y) 603 | logger.info(f"检测到超进化按钮并点击") 604 | evolution_detected = True 605 | break 606 | 607 | max_loc1, max_val1 = detect_evolution_button(gray_screenshot, server) 608 | if max_val1 >= 0.90: # 检测阈值 609 | template_info = load_evolution_template(server) 610 | center_x = max_loc1[0] + template_info['w'] // 2 611 | center_y = max_loc1[1] + template_info['h'] // 2 612 | u2_device.click(center_x, center_y) 613 | if not logger_word: 614 | logger.info(f"检测到进化按钮并点击") 615 | logger_word = True 616 | evolution_detected = True 617 | break 618 | 619 | return evolution_detected 620 | 621 | def perform_full_actions(u2_device, round_count, base_colors, config): 622 | """720P分辨率下的出牌攻击操作""" 623 | # 不管是不是后手先点能量点的位置再说 624 | u2_device.click(1173, 500) 625 | time.sleep(0.1) 626 | 627 | # 展牌 628 | u2_device.click(1049, 646) 629 | time.sleep(0.25) 630 | 631 | # 出牌拖拽(大于6回合时从中心向两侧) 632 | start_y = 672 + random.randint(-2, 2) 633 | end_y = 400 + random.randint(-2, 2) 634 | duration = 0.03 635 | if round_count >= 6: 636 | drag_points_x = [600, 700, 684, 551, 830, 501, 900, 405, 959] 637 | else: 638 | drag_points_x = [405, 501, 551, 600, 684, 700, 830, 900, 959] 639 | for x in drag_points_x: 640 | curved_drag(u2_device, x + random.randint(-2, 2), start_y, x + random.randint(-2, 2), end_y, duration, config["extra_drag_delay"], 3) 641 | time.sleep(0.05) 642 | time.sleep(0.5) 643 | 644 | # 执行随从攻击(使用统一函数 645 | screenshot = take_screenshot() 646 | if screenshot: 647 | perform_follower_attacks( 648 | u2_device, 649 | screenshot, 650 | base_colors, 651 | config, 652 | ) 653 | else: 654 | logger.error("无法获取截图,跳过攻击操作") 655 | time.sleep(0.1) 656 | 657 | def perform_fullPlus_actions(u2_device, round_count, base_colors, config): 658 | """720P分辨率下执行进化/超进化与攻击操作""" 659 | # 不管是不是后手先点能力点的位置再说 660 | u2_device.click(1173, 500) 661 | time.sleep(0.1) 662 | 663 | # 展牌 664 | u2_device.click(1049, 646) 665 | time.sleep(0.25) 666 | 667 | # 出牌拖拽(大于6回合时从中心向两侧) 668 | start_y = 672 + random.randint(-2, 2) 669 | end_y = 400 + random.randint(-2, 2) 670 | duration = 0.03 671 | if round_count >= 6: 672 | drag_points_x = [600, 700, 684, 551, 830, 501, 900, 405, 959] 673 | else: 674 | drag_points_x = [405, 501, 551, 600, 684, 700, 830, 900, 959] 675 | 676 | for x in drag_points_x: 677 | curved_drag(u2_device, x + random.randint(-2, 2), start_y, x + random.randint(-2, 2), end_y, duration, config["extra_drag_delay"], 3) 678 | time.sleep(0.05) 679 | time.sleep(0.5) 680 | 681 | # 获取当前截图 682 | screenshot = take_screenshot() 683 | # 执行进化操作 684 | if screenshot is not None: 685 | evolved = perform_evolution_actions( 686 | u2_device, 687 | screenshot, 688 | base_colors, 689 | config.get("server", "国服") # 添加 server 参数 690 | ) 691 | if evolved: 692 | # 等待最终进化/超进化动画完成 693 | time.sleep(6.5) 694 | 695 | # 点击空白处关闭面板 696 | u2_device.click(1026 + random.randint(-2, 2), 178 + random.randint(-2, 2)) 697 | time.sleep(0.1) 698 | 699 | # 执行随从攻击 700 | screenshot = take_screenshot() 701 | if screenshot: 702 | perform_follower_attacks( 703 | u2_device, 704 | screenshot, 705 | base_colors, 706 | config, 707 | ) 708 | else: 709 | logger.error("无法获取截图,遍历攻击操作") 710 | time.sleep(0.1) 711 | 712 | def scan_self_shield_targets(): 713 | """扫描己方随从区域的护盾目标(彩色匹配),返回置信度最高的目标""" 714 | shield_dir = "shield" 715 | shield_targets = [] # 存储所有检测到的护盾目标及其置信度 716 | 717 | # 确保shield目录存在 718 | if not os.path.exists(shield_dir) or not os.path.isdir(shield_dir): 719 | return [] 720 | 721 | screenshot_shield = take_screenshot() 722 | if screenshot_shield is None: 723 | return [] 724 | 725 | # 将PIL截图转为OpenCV格式 726 | screenshot_np = np.array(screenshot_shield) 727 | screenshot_cv = cv2.cvtColor(screenshot_np, cv2.COLOR_RGB2BGR) # RGB转BGR格式 728 | 729 | # 定义扫描区域 (254, 320) 到 (1063, 484) - 己方随从区域 730 | x1, y1 = 254, 320 731 | x2, y2 = 1063, 484 732 | width = x2 - x1 733 | height = y2 - y1 734 | 735 | # 只扫描指定矩形区域 736 | roi = screenshot_cv[y1:y2, x1:x2] 737 | 738 | # 加载所有护盾模板(彩色) 739 | shield_templates = [] 740 | for filename in os.listdir(shield_dir): 741 | if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): 742 | path = os.path.join(shield_dir, filename) 743 | template = cv2.imread(path) # 以彩色模式读取模板 744 | if template is not None: 745 | shield_templates.append(template) 746 | 747 | # 扫描匹配护盾模板并记录置信度 748 | for template in shield_templates: 749 | h, w = template.shape[:2] # 获取彩色模板的高度和宽度 750 | 751 | # 执行彩色模板匹配 752 | result = cv2.matchTemplate(roi, template, cv2.TM_CCOEFF_NORMED) 753 | threshold = 0.75 # 匹配阈值 754 | 755 | # 获取所有匹配位置及其置信度 756 | loc = np.where(result >= threshold) 757 | for pt in zip(*loc[::-1]): # 遍历所有匹配位置 758 | confidence = result[pt[1], pt[0]] # 获取当前匹配位置的置信度 759 | 760 | # 将相对坐标转换为绝对坐标 761 | abs_x = int(pt[0] + x1 + w // 2) 762 | abs_y = int(pt[1] + y1 + h // 2) 763 | 764 | # 添加到目标列表(包含坐标和置信度) 765 | shield_targets.append({ 766 | 'x': abs_x, 767 | 'y': abs_y, 768 | 'confidence': confidence 769 | }) 770 | 771 | # 按置信度从高到低排序 772 | shield_targets.sort(key=lambda t: t['confidence'], reverse=True) 773 | 774 | # 返回所有检测到的目标 775 | return shield_targets 776 | 777 | def enable_ansi_support(): 778 | if sys.platform != "win32": 779 | return # 非Windows系统无需处理 780 | 781 | # 调用Windows API启用虚拟终端处理 782 | kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) 783 | handle = kernel32.GetStdHandle(wintypes.DWORD(-11)) # STD_OUTPUT_HANDLE (-11) 784 | mode = wintypes.DWORD() 785 | if not kernel32.GetConsoleMode(handle, ctypes.byref(mode)): 786 | return 787 | # 启用 ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x0004) 788 | if not kernel32.SetConsoleMode(handle, mode.value | 0x0004): 789 | return 790 | 791 | # 新增:换牌功能函数 792 | def perform_card_replacement(strategy, device, templates_cost): 793 | """ 794 | 执行换牌操作:根据选择的策略检测手牌并替换不符合条件的牌 795 | 796 | Args: 797 | strategy: 换牌策略 ('3费档次', '4费档次', '5费档次') 798 | """ 799 | try: 800 | logger.info(f"开始执行换牌检测 - 策略: {strategy}") 801 | time.sleep(1) 802 | 803 | # 重新截图用于费用检测 804 | card_screenshot = take_screenshot() 805 | if card_screenshot is None: 806 | logger.info("无法获取换牌截图") 807 | return 808 | 809 | # 转换为OpenCV格式 810 | card_screenshot_np = np.array(card_screenshot) 811 | card_screenshot_cv = cv2.cvtColor(card_screenshot_np, cv2.COLOR_RGB2BGR) 812 | gray_card_screenshot = cv2.cvtColor(card_screenshot_cv, cv2.COLOR_BGR2GRAY) 813 | 814 | # 定义四张手牌的费用检测区域 815 | hand_card_regions = [ 816 | (177, 408, 214, 447), # 第1张牌的费用区域 817 | (382, 411, 421, 453), # 第2张牌的费用区域 818 | (590, 411, 624, 450), # 第3张牌的费用区域 819 | (797, 411, 831, 450), # 第4张牌的费用区域 820 | ] 821 | 822 | # 定义手牌中心位置(用于向上滑动) 823 | hand_card_centers = [ 824 | (274, 518), (477, 527), (681, 521), (884, 524) 825 | ] 826 | 827 | # 检测每张手牌的费用 828 | hand_costs = [] 829 | for i, region in enumerate(hand_card_regions): 830 | x1, y1, x2, y2 = region 831 | card_region = gray_card_screenshot[y1:y2, x1:x2] 832 | 833 | # 调试:保存调试图片(可选) 834 | # cv2.imwrite(f"debug_card_{i+1}_region.jpg", card_region) 835 | 836 | # 图像预处理 837 | card_region_enhanced = cv2.equalizeHist(card_region) 838 | 839 | detected_cost = None 840 | max_confidence = 0 841 | 842 | # 检测费用(1-5费) 843 | for cost in range(1, 6): 844 | cost_type = f'cost_{cost}' 845 | if cost_type in templates_cost and templates_cost[cost_type]: 846 | # 对原始和增强图像都进行匹配 847 | max_loc1, max_val1 = match_template(card_region, templates_cost[cost_type]) 848 | max_loc2, max_val2 = match_template(card_region_enhanced, templates_cost[cost_type]) 849 | 850 | max_val = max(max_val1, max_val2) 851 | threshold = templates_cost[cost_type]['threshold'] 852 | 853 | logger.info(f"第{i+1}张牌检测{cost}费: 匹配度{max_val:.3f}, 阈值{threshold:.3f}") 854 | 855 | if max_val >= threshold and max_val > max_confidence: 856 | max_confidence = max_val 857 | detected_cost = cost 858 | 859 | # 如果没有检测到1-5费中的任何一种,默认为6费以上 860 | if detected_cost is None: 861 | detected_cost = 6 862 | logger.info(f"第{i+1}张牌未识别出具体费用,默认为6费+") 863 | else: 864 | logger.info(f"第{i+1}张牌检测为{detected_cost}费") 865 | 866 | hand_costs.append(detected_cost) 867 | 868 | # 根据策略决定是否需要换牌 869 | cards_to_replace = _determine_cards_to_replace(hand_costs, strategy) 870 | 871 | # 执行换牌操作 872 | if cards_to_replace: 873 | logger.info(f"需要替换的手牌: {[i+1 for i in cards_to_replace]}") 874 | for card_index in cards_to_replace: 875 | center_x, center_y = hand_card_centers[card_index] 876 | # 向上滑动替换手牌 877 | device.swipe(center_x, center_y, center_x, center_y - 300, duration=0.3) 878 | logger.info(f"已替换第{card_index+1}张牌") 879 | time.sleep(0.5) 880 | else: 881 | logger.info("当前手牌符合策略要求,无需替换") 882 | 883 | time.sleep(1) 884 | 885 | except Exception as e: 886 | logger.info(f"换牌操作出错: {str(e)}") 887 | 888 | def _determine_cards_to_replace(hand_costs, strategy): 889 | """ 890 | 根据策略和手牌费用决定哪些牌需要替换 891 | 892 | Args: 893 | hand_costs: 4张手牌的费用列表 894 | strategy: 换牌策略 895 | 896 | Returns: 897 | 需要替换的牌的索引列表 898 | """ 899 | logger.info(f"当前手牌费用: {hand_costs}") 900 | 901 | # 根据策略检查,使用向下兼容 902 | if strategy == '5费档次': 903 | result = _check_5_cost_strategy(hand_costs) 904 | if result is not None: 905 | return result 906 | logger.info("5费档次条件不满足,检查4费档次") 907 | strategy = '4费档次' 908 | 909 | if strategy == '4费档次': 910 | result = _check_4_cost_strategy(hand_costs) 911 | if result is not None: 912 | return result 913 | logger.info("4费档次条件不满足,检查3费档次") 914 | strategy = '3费档次' 915 | 916 | if strategy == '3费档次': 917 | return _check_3_cost_strategy(hand_costs) 918 | 919 | return [] 920 | 921 | def _check_3_cost_strategy(hand_costs): 922 | """ 923 | 检查3费档次策略 924 | 条件:前三张牌组合为[1,2,3],否则前2张必须有一张是3费牌 925 | """ 926 | front_three = sorted(hand_costs[:3]) 927 | 928 | # 检查是否满足[1,2,3]组合 929 | if front_three == [1, 2, 3]: 930 | logger.info("满足3费档次最优组合[1,2,3],保留所有牌") 931 | return [] 932 | 933 | # 统计3费牌数量 934 | cost_3_count = hand_costs.count(3) 935 | # 统计2费牌数量 936 | cost_2_count = hand_costs.count(2) 937 | # 统计1费牌数量 938 | cost_1_count = hand_costs.count(1) 939 | 940 | # 3费牌位置 941 | cost_3_positions = [i for i, value in enumerate(hand_costs) if value == 3] 942 | # 2费牌位置 943 | cost_2_positions = [i for i, value in enumerate(hand_costs) if value == 2] 944 | # 1费牌位置 945 | cost_1_positions = [i for i, value in enumerate(hand_costs) if value == 1] 946 | 947 | # 3费牌过多处理 948 | if cost_3_count == 4: 949 | # 3费牌=4张:前两张都更换 950 | logger.info("3费牌过多(4张),替换前两张牌") 951 | return [0, 1] 952 | 953 | if cost_3_count == 3: 954 | # 3费牌=3张:更换最右的3费牌,如果非3费牌费用高于3,也一起换掉 955 | not_3_pos = [i for i in [0,1,2,3] if i not in cost_3_positions][0] 956 | if hand_costs[not_3_pos] > 3: 957 | logger.info(f"3费牌过多(3张),替换第{cost_3_positions[-1]+1}张牌,同时替换一张{hand_costs[not_3_pos]}费牌") 958 | return [cost_3_positions[-1], not_3_pos] 959 | else: 960 | logger.info(f"3费牌过多(3张),替换第{cost_3_positions[-1]+1}张牌") 961 | return [cost_3_positions[-1]] 962 | 963 | # 2费牌过多处理 964 | if cost_2_count == 4: 965 | # 2费牌=4张:更换前两张2费牌 966 | logger.info("2费牌过多(4张),替换前两张2费牌") 967 | return [0, 1] 968 | 969 | if cost_2_count == 3: 970 | # 2费牌=3张:更换最左的2费牌,如果非2费牌费用高于3,也一起换掉 971 | not_2_pos = [i for i in [0,1,2,3] if i not in cost_2_positions][0] 972 | if hand_costs[not_2_pos] > 3: 973 | logger.info(f"2费牌过多(3张),替换第{cost_2_positions[0]+1}张牌,同时替换一张{hand_costs[not_2_pos]}费牌") 974 | return [cost_2_positions[0], not_2_pos] 975 | else: 976 | logger.info(f"2费牌过多(3张),替换第{cost_2_positions[0]+1}张牌") 977 | return [cost_2_positions[0]] 978 | 979 | # 1费牌过多处理 980 | if cost_1_count == 4: 981 | # 1费牌=4张:更换前两张1费牌 982 | logger.info("1费牌过多(4张),替换前两张1费牌") 983 | return [0, 1] 984 | 985 | if cost_1_count == 3: 986 | # 1费牌=3张:更换最左的1费牌,如果非1费牌费用高于3,也一起换掉 987 | not_1_pos = [i for i in [0,1,2,3] if i not in cost_1_positions][0] 988 | if hand_costs[not_1_pos] > 3: 989 | logger.info(f"1费牌过多(3张),替换第{cost_1_positions[0]+1}张牌,同时替换一张{hand_costs[not_1_pos]}费牌") 990 | return [cost_1_positions[0], not_1_pos] 991 | else: 992 | logger.info(f"1费牌过多(3张),替换第{cost_1_positions[0]+1}张牌") 993 | return [cost_1_positions[0]] 994 | 995 | combination_2x2 = [] 996 | if cost_3_count == 2 and cost_2_count == 2: 997 | # 3费牌=2张,2费牌=2张:3费和2费牌都更换1张 998 | combination_2x2.append(cost_3_positions[-1]) 999 | combination_2x2.append(cost_2_positions[1]) 1000 | return combination_2x2 1001 | elif cost_3_count == 2 and cost_1_count == 2: 1002 | # 3费牌=2张,1费牌=2张:3费和1费牌都更换1张 1003 | combination_2x2.append(cost_3_positions[-1]) 1004 | combination_2x2.append(cost_1_positions[1]) 1005 | return combination_2x2 1006 | elif cost_2_count == 2 and cost_1_count == 2: 1007 | # 2费牌=2张,1费牌=2张:2费牌更换1张,1费牌更换1张 1008 | combination_2x2.append(cost_2_positions[1]) 1009 | combination_2x2.append(cost_1_positions[1]) 1010 | return combination_2x2 1011 | 1012 | # 不满足3费档次条件 1013 | logger.info("不满足3费档次条件,需要调整手牌") 1014 | 1015 | return [i for i, cost in enumerate(hand_costs) if cost > 3] 1016 | 1017 | def _check_4_cost_strategy(hand_costs): 1018 | """ 1019 | 检查4费档次策略 1020 | 条件:组合[1,2,3,4],否则前三张为[2,3,4]或[2,2,4] 1021 | """ 1022 | sorted_hand = sorted(hand_costs) 1023 | 1024 | # 检查是否满足[1,2,3,4]组合 1025 | if sorted_hand == [1, 2, 3, 4]: 1026 | logger.info("满足4费档次最优组合[1,2,3,4],保留所有牌") 1027 | return [] 1028 | 1029 | # 检查前三张是否为[2,3,4]或[2,2,4] 1030 | front_three = sorted(set(hand_costs)) 1031 | # 位置2、3均为4费 1032 | if hand_costs[1] == 4 and hand_costs[2] == 4: 1033 | if hand_costs == [2, 3, 4] or hand_costs == [2, 4]: 1034 | logger.info(f"组合[{sorted(hand_costs)}符合4费档次要求") 1035 | # 无需换牌 1036 | return [] 1037 | # 位置1、2均为4费 1038 | if hand_costs[0] == 4 or hand_costs[1] == 4: 1039 | if sorted(front_three[:3]) == [2, 3, 4] or sorted(hand_costs[:3]) == [2, 2, 4]: 1040 | logger.info(f"组合{hand_costs}符合4费档次要求") 1041 | # 替换大于4费的牌 1042 | return [i for i, cost in enumerate(hand_costs) if cost > 4] 1043 | # 位置3为4费 1044 | if hand_costs[2] == 4: 1045 | if sorted(hand_costs[:3]) == [2, 3, 4] or sorted(hand_costs[:3]) == [2, 2, 4]: 1046 | logger.info(f"组合{hand_costs}符合4费档次要求") 1047 | # 替换大于4费的牌 1048 | return [i for i, cost in enumerate(hand_costs) if cost > 4] 1049 | 1050 | # 不满足4费档次条件 1051 | logger.info("不满足4费档次条件") 1052 | return None 1053 | 1054 | def _check_5_cost_strategy(hand_costs): 1055 | """ 1056 | 检查5费档次策略 1057 | 优先级:[2,3,4,5] > [2,3,3,5] > [2,2,3,5] > [2,2,2,5] 1058 | """ 1059 | sorted_hand = sorted(hand_costs) 1060 | 1061 | # 定义5费档次的优先组合 1062 | preferred_combinations = [ 1063 | [2, 3, 4, 5], 1064 | [2, 3, 3, 5], 1065 | [2, 2, 3, 5], 1066 | [2, 2, 2, 5] 1067 | ] 1068 | 1069 | for i, combination in enumerate(preferred_combinations): 1070 | if sorted_hand == combination: 1071 | logger.info(f"满足5费档次组合{combination}(优先级{i+1}),保留所有牌") 1072 | return [] 1073 | 1074 | logger.info("不满足5费档次任何组合") 1075 | return None 1076 | 1077 | # ================== UI 相关类 ================== 1078 | class UILogHandler(logging.Handler): 1079 | def __init__(self, log_signal): 1080 | super().__init__() 1081 | self.log_signal = log_signal 1082 | 1083 | def emit(self, record): 1084 | log_entry = self.format(record) 1085 | self.log_signal.emit(log_entry) 1086 | 1087 | class ScriptThread(QThread): 1088 | log_signal = pyqtSignal(str) 1089 | status_signal = pyqtSignal(str) 1090 | connected_signal = pyqtSignal(bool) 1091 | stats_signal = pyqtSignal(dict) 1092 | error_signal = pyqtSignal(str) 1093 | 1094 | def __init__(self, config, parent=None): 1095 | super().__init__(parent) 1096 | self.config = config 1097 | self.running = True 1098 | self.paused = False 1099 | self.start_time = 0 1100 | self.battle_count = 0 1101 | self.turn_count = 0 1102 | self.current_turn = 0 1103 | self.adb_port = config["emulator_port"] 1104 | self.scan_interval = config["scan_interval"] 1105 | self.server = config["server"] # 当前选择的服务器 1106 | # 从配置中获取换牌策略 1107 | self.card_replacement_strategy = config.get("card_replacement", {}).get("strategy", "3费档次") 1108 | # 初始化设备对象 1109 | self.u2_device = None 1110 | self.adb_device = None 1111 | 1112 | # 模板字典 1113 | self.templates = {} 1114 | 1115 | # 设置日志处理器 1116 | ui_handler = UILogHandler(self.log_signal) 1117 | ui_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) 1118 | logger.removeHandler(console_handler) 1119 | logger.addHandler(ui_handler) 1120 | 1121 | def run(self): 1122 | try: 1123 | global device, current_round_count 1124 | global match_start_time, current_run_matches, current_run_start_time 1125 | global in_match, evolution_template, super_evolution_template, base_colors 1126 | 1127 | self.start_time = time.time() 1128 | self.status_signal.emit("运行中") 1129 | self.log_signal.emit("===== 脚本开始运行 =====") 1130 | 1131 | # 加载配置 1132 | EMULATOR_PORT = self.config["emulator_port"] 1133 | SCAN_INTERVAL = self.config["scan_interval"] 1134 | 1135 | # 新增:活动监控变量 1136 | last_activity_time = time.time() # 记录最后一次有效操作时间 1137 | INACTIVITY_TIMEOUT = 300 # 5分钟无操作超时(300秒) 1138 | 1139 | # 初始化设备对象 1140 | device = None 1141 | 1142 | # 初始化进化模板 1143 | evolution_template = None 1144 | super_evolution_template = None 1145 | 1146 | # 记录脚本启动时间 1147 | current_run_start_time = datetime.datetime.now() 1148 | current_run_matches = 0 1149 | in_match = False # 是否在对战中 1150 | 1151 | #其余初始化 1152 | match_start_time = None 1153 | base_colors = None 1154 | 1155 | # 加载历史统计数据 1156 | load_round_statistics() 1157 | 1158 | # 1. 加载所有模板 1159 | self.log_signal.emit("正在加载模板...") 1160 | 1161 | # 根据服务器选择模板目录 1162 | templates_dir = TEMPLATES_DIR if self.server == "国服" else TEMPLATES_DIR_INTERNATIONAL 1163 | 1164 | self.templates = { 1165 | 'dailyCard': create_template_info(load_template(templates_dir, 'dailyCard.png'), "每日卡包"), 1166 | 'missionCompleted': create_template_info(load_template(templates_dir, 'missionCompleted.png'), "任务完成"), 1167 | 'backTitle': create_template_info(load_template(templates_dir, 'backTitle.png'), "返回标题"), 1168 | 'errorBackMain': create_template_info(load_template(templates_dir, 'errorBackMain.png'), "遇到错误,返回主页面"), 1169 | 'error_retry': create_template_info(load_template(templates_dir, 'error_retry.png'), "重试"), 1170 | 'Ok': create_template_info(load_template(templates_dir, 'Ok.png'), "好的"), 1171 | 'decision': create_template_info(load_template(templates_dir, 'decision.png'), "决定"), 1172 | 'end_round': create_template_info(load_template(templates_dir, 'end_round.png'), "结束回合"), 1173 | 'enemy_round': create_template_info(load_template(templates_dir, 'enemy_round.png'), "敌方回合"), 1174 | 'end': create_template_info(load_template(templates_dir, 'end.png'), "结束"), 1175 | 'war': create_template_info(load_template(templates_dir, 'war.png'), "决斗"), 1176 | 'mainPage': create_template_info(load_template(templates_dir, 'mainPage.png'), "游戏主页面"), 1177 | 'MuMuPage': create_template_info(load_template(templates_dir, 'MuMuPage.png'), "MuMu主页面"), 1178 | 'LoginPage': create_template_info(load_template(templates_dir, 'LoginPage.png'), "排队主界面", threshold=0.35), 1179 | 'enterGame': create_template_info(load_template(templates_dir, 'enterGame.png'), "排队进入"), 1180 | 'yes': create_template_info(load_template(templates_dir, 'Yes.png'), "继续中断的对战"), 1181 | 'close1': create_template_info(load_template(templates_dir, 'close1.png'), "关闭卡组预览/编辑"), 1182 | 'close2': create_template_info(load_template(templates_dir, 'close2.png'), "关闭卡组预览/编辑"), 1183 | 'backMain': create_template_info(load_template(templates_dir, 'backMain.png'), "返回主页面"), 1184 | 'rankUp': create_template_info(load_template(templates_dir, 'rankUp.png'), "阶位提升"), 1185 | 'groupUp': create_template_info(load_template(templates_dir, 'groupUp.png'), "分组升级"), 1186 | 'rank': create_template_info(load_template(templates_dir, 'rank.png'), "阶级积分"), 1187 | } 1188 | 1189 | self.templates_cost = { 1190 | 'cost_1': create_template_info(load_template(TEMPLATES_DIR_COST, 'cost_1.png'), "费用1"), 1191 | 'cost_2': create_template_info(load_template(TEMPLATES_DIR_COST, 'cost_2.png'), "费用2"), 1192 | 'cost_3': create_template_info(load_template(TEMPLATES_DIR_COST, 'cost_3.png'), "费用3"), 1193 | 'cost_4': create_template_info(load_template(TEMPLATES_DIR_COST, 'cost_4.png'), "费用4"), 1194 | 'cost_5': create_template_info(load_template(TEMPLATES_DIR_COST, 'cost_5.png'), "费用5"), 1195 | } 1196 | 1197 | extra_dir = self.config.get("extra_templates_dir", "") 1198 | if extra_dir and os.path.isdir(extra_dir): 1199 | self.log_signal.emit(f"开始加载额外模板目录: {extra_dir}") 1200 | 1201 | # 支持的图片扩展名 1202 | valid_extensions = ['.png', '.jpg', '.jpeg', '.bmp'] 1203 | 1204 | for filename in os.listdir(extra_dir): 1205 | filepath = os.path.join(extra_dir, filename) 1206 | 1207 | # 检查是否是图片文件 1208 | if os.path.isfile(filepath) and os.path.splitext(filename)[1].lower() in valid_extensions: 1209 | template_name = os.path.splitext(filename)[0] # 使用文件名作为模板名称 1210 | 1211 | # 加载模板 1212 | template_img = load_template(extra_dir, filename) 1213 | if template_img is None: 1214 | self.log_signal.emit(f"无法加载额外模板: {filename}") 1215 | continue 1216 | 1217 | # 创建模板信息(使用全局阈值) 1218 | template_info = create_template_info( 1219 | template_img, 1220 | f"额外模板-{template_name}", 1221 | threshold=self.config["evolution_threshold"] 1222 | ) 1223 | 1224 | # 添加到模板字典(如果已存在则跳过) 1225 | if template_name not in self.templates: 1226 | self.templates[template_name] = template_info 1227 | self.log_signal.emit(f"已添加额外模板: {template_name} (来自: {filename})") 1228 | 1229 | self.log_signal.emit("模板加载完成") 1230 | 1231 | # 2. 连接设备 1232 | self.log_signal.emit("正在连接设备...") 1233 | try: 1234 | import adbutils 1235 | from adbutils import adb, AdbClient 1236 | import uiautomator2 as u2 1237 | 1238 | # 创建 adb 客户端 1239 | client = AdbClient(host="127.0.0.1") 1240 | 1241 | # 目标设备序列号 1242 | target_serial = f"127.0.0.1:{EMULATOR_PORT}" 1243 | 1244 | # 检查是否已连接目标模拟器 1245 | devices_list = client.device_list() 1246 | emulator_connected = any(d.serial == target_serial for d in devices_list) 1247 | 1248 | if not emulator_connected: 1249 | self.log_signal.emit(f"尝试自动连接模拟器({target_serial})...") 1250 | try: 1251 | adb.connect(target_serial) 1252 | time.sleep(2) # 等待连接稳定 1253 | devices_list = client.device_list() 1254 | emulator_connected = any(d.serial == target_serial for d in devices_list) 1255 | if emulator_connected: 1256 | self.log_signal.emit(f"模拟器连接成功: {target_serial}") 1257 | else: 1258 | self.log_signal.emit(f"连接模拟器失败: 未出现在 device_list 中") 1259 | except Exception as conn_err: 1260 | self.log_signal.emit(f"adbutils 连接失败: {conn_err}") 1261 | 1262 | # 获取设备列表(再次获取以确保最新) 1263 | devices_list = client.device_list() 1264 | if not devices_list: 1265 | raise RuntimeError("未找到连接的设备,请确保模拟器已启动") 1266 | 1267 | # 查找目标设备 1268 | target_device = None 1269 | for d in devices_list: 1270 | if d.serial == target_serial: 1271 | target_device = d 1272 | break 1273 | 1274 | if not target_device: 1275 | target_device = devices_list[0] 1276 | self.log_signal.emit(f"未找到配置的模拟器({target_serial}),使用第一个设备: {target_device.serial}") 1277 | 1278 | # 获取 adbutils 设备对象 1279 | device = adb.device(serial=target_device.serial) 1280 | self.log_signal.emit(f"已连接设备: {target_device.serial}") 1281 | 1282 | # 获取 uiautomator2 设备对象 1283 | u2_device = u2.connect(target_device.serial) 1284 | self.u2_device = u2_device 1285 | self.adb_device = device 1286 | self.log_signal.emit("设备连接成功") 1287 | except Exception as e: 1288 | self.log_signal.emit(f"设备连接失败: {str(e)}") 1289 | self.status_signal.emit("连接失败") 1290 | return 1291 | 1292 | def restart_app(): 1293 | """根据配置的服务器重启对应应用""" 1294 | try: 1295 | # 从配置中获取当前服务器设置 1296 | current_server = self.config.get("server", "国际服") # 默认为国际服 1297 | 1298 | # 根据服务器选择目标包名 1299 | if current_server == "国服": 1300 | target_package = self.config.get("CNapp_package", "com.netease.yzs") 1301 | server_name = "国服" 1302 | else: # 默认处理国际服 1303 | target_package = self.config.get("app_package", "jp.co.cygames.ShadowverseWorldsBeyond") 1304 | server_name = "国际服" 1305 | 1306 | self.log_signal.emit(f"检测到5分钟无活动,正在重启{server_name}应用...") 1307 | 1308 | # 强制停止目标应用 1309 | self.adb_device.shell(f"am force-stop {target_package}") 1310 | time.sleep(2) 1311 | 1312 | # 重新启动目标应用 1313 | self.adb_device.shell(f"monkey -p {target_package} -c android.intent.category.LAUNCHER 1") 1314 | time.sleep(5) # 等待应用启动 1315 | 1316 | self.log_signal.emit(f"{server_name}应用重启完成") 1317 | return True 1318 | except Exception as e: 1319 | # 在异常处理中使用配置值作为后备 1320 | current_server = self.config.get("server", "国际服") 1321 | server_name = "国服" if current_server == "国服" else "国际服" 1322 | self.log_signal.emit(f"重启{server_name}应用失败: {str(e)}") 1323 | return False 1324 | 1325 | # 新增:重置活动计时器的函数 1326 | def reset_activity_timer(): 1327 | """重置活动计时器""" 1328 | nonlocal last_activity_time 1329 | last_activity_time = time.time() 1330 | 1331 | # 新增:检查是否需要重启应用 1332 | def check_inactivity(): 1333 | """检查是否超过无活动时间限制""" 1334 | current_time = time.time() 1335 | inactive_duration = current_time - last_activity_time 1336 | 1337 | if inactive_duration >= INACTIVITY_TIMEOUT: 1338 | return True 1339 | return False 1340 | 1341 | # 3. 检测脚本启动时是否已经在对战中 1342 | self.log_signal.emit("检测当前游戏状态...") 1343 | init_screenshot = take_screenshot() 1344 | if init_screenshot is not None: 1345 | # 转换为OpenCV格式 1346 | init_screenshot_np = np.array(init_screenshot) 1347 | init_screenshot_cv = cv2.cvtColor(init_screenshot_np, cv2.COLOR_RGB2BGR) 1348 | gray_init_screenshot = cv2.cvtColor(init_screenshot_cv, cv2.COLOR_BGR2GRAY) 1349 | 1350 | # 检测是否已经在游戏中 1351 | end_round_info = self.templates['end_round'] 1352 | enemy_round_info = self.templates['enemy_round'] 1353 | decision_info = self.templates['decision'] 1354 | 1355 | # 检测换牌开场 1356 | if decision_info: 1357 | max_loc, max_val = match_template(gray_init_screenshot, decision_info) 1358 | if max_val >= decision_info['threshold']: 1359 | in_match = True 1360 | match_start_time = time.time() 1361 | current_round_count = 1 1362 | self.log_signal.emit("脚本启动时检测到已处于换牌阶段,自动设置回合数为1") 1363 | 1364 | # 检测我方回合 1365 | if end_round_info: 1366 | max_loc, max_val = match_template(gray_init_screenshot, end_round_info) 1367 | if max_val >= end_round_info['threshold']: 1368 | in_match = True 1369 | match_start_time = time.time() 1370 | current_round_count = 2 1371 | self.log_signal.emit("脚本启动时检测到已处于我方回合,自动设置回合数为2") 1372 | 1373 | # 检测敌方回合 1374 | if enemy_round_info: 1375 | max_loc, max_val = match_template(gray_init_screenshot, enemy_round_info) 1376 | if max_val >= enemy_round_info['threshold']: 1377 | in_match = True 1378 | match_start_time = time.time() 1379 | current_round_count = 2 1380 | self.log_signal.emit("脚本启动时检测到已处于敌方回合,自动设置回合数为2") 1381 | 1382 | else: 1383 | self.log_signal.emit("无法获取初始截图,跳过状态检测") 1384 | 1385 | last_detected_button = None 1386 | base_colors = None 1387 | 1388 | # 5. 主循环 1389 | self.log_signal.emit("脚本初始化完成,开始运行...") 1390 | self.log_signal.emit("模拟器请调成1280x720分辨率") 1391 | 1392 | # 防倒卖声明 1393 | red_start = "" 1394 | red_end = "" 1395 | message = f""" 1396 | {red_start} 1397 | 【提示】本脚本为免费开源项目,您无需付费即可获取。 1398 | 若您通过付费渠道购买,可能已遭遇误导。 1399 | 免费版本请加群: 967632615,1070074638 1400 | 警惕倒卖行为! 1401 | {red_end} 1402 | """ 1403 | self.log_signal.emit(message.strip()) 1404 | 1405 | needLogPause = True 1406 | needAddRoundCount = True 1407 | 1408 | while self.running: 1409 | start_time = time.time() 1410 | 1411 | # 检查脚本暂停状态 1412 | if self.paused: 1413 | if needLogPause: 1414 | # 记录暂停信息 1415 | self.log_signal.emit("脚本暂停中...") 1416 | needLogPause = False 1417 | # 在暂停状态下每1秒检查一次,并重置活动计时器 1418 | reset_activity_timer() 1419 | time.sleep(1) 1420 | continue 1421 | 1422 | # 新增:检查无活动超时 1423 | if check_inactivity(): 1424 | if restart_app(): 1425 | reset_activity_timer() 1426 | # 重启后等待一段时间让应用完全加载 1427 | time.sleep(20) 1428 | # 重置相关状态 1429 | in_match = False 1430 | last_detected_button = None 1431 | base_colors = None 1432 | continue 1433 | else: 1434 | self.error_signal.emit("重启应用失败,请检查模拟器是否正常运行") 1435 | 1436 | # 获取截图 1437 | needLogPause = True 1438 | screenshot = take_screenshot() 1439 | # debug 1440 | # from PIL import Image 1441 | # screenshot = Image.open('./test_resource/1.png') 1442 | 1443 | if screenshot is None: 1444 | time.sleep(SCAN_INTERVAL) 1445 | continue 1446 | 1447 | # 转换为OpenCV格式 1448 | screenshot_np = np.array(screenshot) 1449 | screenshot_cv = cv2.cvtColor(screenshot_np, cv2.COLOR_RGB2BGR) 1450 | gray_screenshot = cv2.cvtColor(screenshot_cv, cv2.COLOR_BGR2GRAY) 1451 | 1452 | # 检查其他按钮 1453 | button_detected = False 1454 | for key, template_info in self.templates.items(): # 遍历所有模板(包括动态加载的) 1455 | if not template_info: 1456 | continue 1457 | 1458 | max_loc, max_val = match_template(gray_screenshot, template_info) 1459 | if max_val >= template_info['threshold']: 1460 | if key != last_detected_button: 1461 | reset_activity_timer() # 重置活动计时器 1462 | if key == 'end_round' and in_match: 1463 | self.log_signal.emit(f"已发现'结束回合'按钮 (当前回合: {current_round_count})") 1464 | 1465 | if key == 'decision': 1466 | self.log_signal.emit("检测到换牌界面,开始执行换牌逻辑") 1467 | # 执行换牌操作 1468 | perform_card_replacement(self.card_replacement_strategy, self.u2_device, self.templates_cost) # 换牌完成后点击决定按钮 1469 | center_x = max_loc[0] + template_info['w'] // 2 1470 | center_y = max_loc[1] + template_info['h'] // 2 1471 | self.u2_device.click(center_x + random.randint(-2, 2), center_y + random.randint(-2, 2)) 1472 | self.log_signal.emit("换牌完成,点击决定按钮") 1473 | last_detected_button = key 1474 | button_detected = True 1475 | time.sleep(1) 1476 | break 1477 | 1478 | # 处理每日卡包 1479 | if key == 'dailyCard': 1480 | #点击固定位置跳过 1481 | self.log_signal.emit("检测到每日卡包,尝试跳过") 1482 | self.u2_device.click(717, 80) 1483 | 1484 | # 处理对战开始/结束逻辑 1485 | if key == 'war': 1486 | # 检测到"决斗"按钮,表示新对战开始 1487 | if in_match: 1488 | # 如果已经在战斗中,先结束当前对战 1489 | self.end_current_match() 1490 | self.log_signal.emit("检测到新对战开始,结束上一场对战") 1491 | # 开始新的对战 1492 | base_colors = None # 重置开局基准背景色 1493 | self.start_new_match() 1494 | in_match = True 1495 | self.log_signal.emit("检测到新对战开始") 1496 | 1497 | if key == 'enemy_round': 1498 | if key != last_detected_button: 1499 | # 敌方回合开始时重置needAddRoundCount 1500 | self.log_signal.emit("检测到敌方回合") 1501 | needAddRoundCount = True 1502 | last_detected_button = key 1503 | time.sleep(1) 1504 | continue 1505 | 1506 | if key == 'end_round' and in_match: 1507 | # 新增:在第一回合且未出牌时记录基准背景色 1508 | if current_round_count == 1 and base_colors is None: 1509 | base_colors = [] 1510 | for pos in follower_positions: 1511 | x, y = pos 1512 | # 记录当前位置的色彩 1513 | color1 = screenshot.getpixel((x, y)) 1514 | # 记录Y轴向下20个像素点的色彩 1515 | color2 = screenshot.getpixel((x, y + 20)) 1516 | base_colors.append((color1, color2)) 1517 | self.log_signal.emit("第1回合,记录基准背景色完成") 1518 | 1519 | self_shield_targets = scan_self_shield_targets() 1520 | if self_shield_targets: 1521 | # 暂停脚本并通知用户 1522 | self.paused = True 1523 | self.log_signal.emit(f"检测到己方护盾目标!脚本已暂停") 1524 | 1525 | # 获取最高置信度的目标 1526 | best_target = self_shield_targets[0] 1527 | self.log_signal.emit( 1528 | f"检测到己方护盾随从!位置: ({best_target['x']}, {best_target['y']}), " 1529 | f"置信度: {best_target['confidence']:.2f}\n" 1530 | "脚本已暂停,请手动处理。" 1531 | ) 1532 | 1533 | # 跳过后续操作 1534 | last_detected_button = key 1535 | button_detected = True 1536 | break 1537 | 1538 | if current_round_count in (4, 5, 6, 7, 8): # 第4 ,5,6 ,7,8回合 1539 | self.log_signal.emit(f"第{current_round_count}回合,执行进化/超进化") 1540 | perform_fullPlus_actions(self.u2_device, current_round_count, base_colors, self.config) 1541 | elif current_round_count > 30: #30回合以上弃权防止烧绳 1542 | self.log_signal.emit(f"30回合以上,直接弃权") 1543 | time.sleep(0.5) 1544 | self.u2_device.click(57, 63) 1545 | time.sleep(0.5) 1546 | self.u2_device.click(642, 148) 1547 | time.sleep(0.5) 1548 | self.u2_device.click(773, 560) 1549 | time.sleep(1) 1550 | else: 1551 | self.log_signal.emit(f"第{current_round_count}回合,执行正常操作") 1552 | perform_full_actions(self.u2_device, current_round_count, base_colors, self.config) 1553 | 1554 | if needAddRoundCount: 1555 | current_round_count += 1 1556 | needAddRoundCount = False 1557 | 1558 | # 计算中心点并点击 1559 | center_x = max_loc[0] + template_info['w'] // 2 1560 | center_y = max_loc[1] + template_info['h'] // 2 1561 | self.u2_device.click(center_x + random.randint(-2, 2), center_y + random.randint(-2, 2)) 1562 | button_detected = True 1563 | 1564 | if key != last_detected_button: 1565 | self.log_signal.emit(f"检测到按钮并点击: {template_info['name']} ") 1566 | # 更新状态跟踪 1567 | last_detected_button = key 1568 | time.sleep(0.5) 1569 | break 1570 | 1571 | # 如果没有检测到任何按钮,但截图成功,也算作一种活动(证明游戏还在响应) 1572 | if not button_detected: 1573 | # 可以选择性地更新活动时间,但频率不要太高 1574 | # 这里我们选择不更新,让无操作计时器继续计时 1575 | pass 1576 | 1577 | # 更新统计信息 1578 | stats = { 1579 | 'current_turn': current_round_count, 1580 | 'run_time': int(time.time() - self.start_time), 1581 | 'battle_count': current_run_matches, 1582 | 'turn_count': current_round_count * current_run_matches 1583 | } 1584 | self.stats_signal.emit(stats) 1585 | 1586 | # 计算处理时间并调整等待 1587 | process_time = time.time() - start_time 1588 | sleep_time = max(0, SCAN_INTERVAL - process_time) 1589 | time.sleep(sleep_time) 1590 | 1591 | # 结束当前对战(如果正在进行) 1592 | if in_match: 1593 | self.end_current_match() 1594 | 1595 | # 保存统计数据 1596 | save_round_statistics() 1597 | 1598 | # 结束信息 1599 | run_duration = datetime.datetime.now() - current_run_start_time 1600 | hours, remainder = divmod(run_duration.total_seconds(), 3600) 1601 | minutes, seconds = divmod(remainder, 60) 1602 | 1603 | self.log_signal.emit("\n===== 本次运行总结 =====") 1604 | self.log_signal.emit(f"脚本启动时间: {current_run_start_time.strftime('%Y-%m-%d %H:%M:%S')}") 1605 | self.log_signal.emit(f"运行时长: {int(hours)}小时{int(minutes)}分钟{int(seconds)}秒") 1606 | self.log_signal.emit(f"完成对战次数: {current_run_matches}") 1607 | self.log_signal.emit("===== 脚本结束运行 =====") 1608 | self.status_signal.emit("已停止") 1609 | except Exception as e: 1610 | error_msg = f"脚本运行出错: {str(e)}" 1611 | logger.error(error_msg) 1612 | self.status_signal.emit("已停止") 1613 | self.error_signal.emit(f"{str(e)}") 1614 | return 1615 | 1616 | def start_new_match(self): 1617 | """开始新的对战""" 1618 | global current_round_count, match_start_time, current_run_matches 1619 | 1620 | # 重置回合计数器 1621 | current_round_count = 1 1622 | match_start_time = time.time() 1623 | current_run_matches += 1 1624 | self.log_signal.emit(f"===== 开始新的对战 =====") 1625 | self.log_signal.emit(f"本次运行对战次数: {current_run_matches}") 1626 | 1627 | def end_current_match(self): 1628 | """结束当前对战并记录统计数据""" 1629 | global current_round_count, match_start_time, match_history 1630 | 1631 | if match_start_time is None: 1632 | return 1633 | 1634 | match_duration = time.time() - match_start_time 1635 | minutes, seconds = divmod(match_duration, 60) 1636 | 1637 | match_record = { 1638 | "date": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 1639 | "rounds": current_round_count, 1640 | "duration": f"{int(minutes)}分{int(seconds)}秒", 1641 | "run_id": current_run_start_time.strftime("%Y%m%d%H%M%S") 1642 | } 1643 | 1644 | match_history.append(match_record) 1645 | 1646 | # 保存统计数据到文件 1647 | save_round_statistics() 1648 | 1649 | self.log_signal.emit(f"===== 对战结束 =====") 1650 | self.log_signal.emit(f"回合数: {current_round_count}, 持续时间: {int(minutes)}分{int(seconds)}秒") 1651 | 1652 | # 重置对战状态 1653 | match_start_time = None 1654 | current_round_count = 1 1655 | 1656 | def stop(self): 1657 | self.running = False 1658 | 1659 | def pause(self): 1660 | self.paused = True 1661 | self.status_signal.emit("已暂停") 1662 | 1663 | def resume(self): 1664 | self.paused = False 1665 | self.status_signal.emit("运行中") 1666 | 1667 | from PyQt5.QtWidgets import ( 1668 | QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, 1669 | QLineEdit, QPushButton, QTextEdit, QFrame, QGridLayout, QGroupBox, 1670 | QComboBox, QMessageBox, QSizePolicy, QStackedWidget 1671 | ) 1672 | from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer 1673 | from PyQt5.QtGui import QPalette, QColor, QPixmap, QBrush, QDoubleValidator, QFont 1674 | 1675 | # ================== UI 相关类 ================== 1676 | class SettingsPage(QWidget): 1677 | def __init__(self, parent=None): 1678 | super().__init__(parent) 1679 | self.parent = parent 1680 | self.config = parent.config 1681 | self.setup_ui() 1682 | 1683 | def setup_ui(self): 1684 | layout = QVBoxLayout(self) 1685 | layout.setSpacing(15) 1686 | layout.setContentsMargins(15, 15, 15, 15) 1687 | 1688 | # === 策略设置 === 1689 | strategy_group = QGroupBox("策略设置") 1690 | strategy_layout = QVBoxLayout() 1691 | 1692 | # 换牌策略 1693 | strategy_row = QHBoxLayout() 1694 | strategy_label = QLabel("换牌策略:") 1695 | self.strategy_combo = QComboBox() 1696 | self.strategy_combo.addItems(['3费档次', '4费档次', '5费档次']) 1697 | strategy_row.addWidget(strategy_label) 1698 | strategy_row.addWidget(self.strategy_combo) 1699 | strategy_row.addStretch() 1700 | 1701 | # 策略说明按钮 1702 | self.strategy_help_btn = QPushButton("说明") 1703 | self.strategy_help_btn.setFixedWidth(60) 1704 | self.strategy_help_btn.setToolTip("点击查看换牌策略说明") 1705 | self.strategy_help_btn.clicked.connect(self.show_strategy_help) 1706 | strategy_row.addWidget(self.strategy_help_btn) 1707 | 1708 | strategy_layout.addLayout(strategy_row) 1709 | 1710 | # 设置初始值 1711 | strategy_index = self.strategy_combo.findText(self.config.get("card_replacement", {}).get("strategy", "3费档次")) 1712 | if strategy_index >= 0: 1713 | self.strategy_combo.setCurrentIndex(strategy_index) 1714 | 1715 | strategy_group.setLayout(strategy_layout) 1716 | layout.addWidget(strategy_group) 1717 | 1718 | # === 延迟设置 === 1719 | delay_group = QGroupBox("延迟设置") 1720 | delay_layout = QFormLayout() 1721 | delay_layout.setHorizontalSpacing(20) 1722 | delay_layout.setVerticalSpacing(10) 1723 | 1724 | # 攻击延迟 1725 | self.attack_delay_input = QLineEdit(str(self.config.get("attack_delay", 0.25))) 1726 | self.attack_delay_input.setValidator(QDoubleValidator(0.1, 2.0, 2, self)) 1727 | delay_layout.addRow("攻击延迟 (秒):", self.attack_delay_input) 1728 | 1729 | # 拖拽延迟 1730 | self.drag_delay_input = QLineEdit(str(self.config.get("extra_drag_delay", 0.05))) 1731 | self.drag_delay_input.setValidator(QDoubleValidator(0.01, 0.5, 3, self)) 1732 | delay_layout.addRow("拖拽延迟 (秒):", self.drag_delay_input) 1733 | 1734 | # 扫描间隔 1735 | self.scan_interval_input = QLineEdit(str(self.config.get("scan_interval", 2))) 1736 | self.scan_interval_input.setValidator(QIntValidator(1, 10, self)) 1737 | delay_layout.addRow("扫描间隔 (秒):", self.scan_interval_input) 1738 | 1739 | delay_group.setLayout(delay_layout) 1740 | layout.addWidget(delay_group) 1741 | 1742 | # === 自动关闭设置 === 1743 | close_group = QGroupBox("自动关闭设置") 1744 | close_layout = QVBoxLayout() # 使用垂直布局作为主布局 1745 | close_layout.setSpacing(8) # 设置较小的间距 1746 | 1747 | # 第一行:标题标签 1748 | title_layout = QHBoxLayout() 1749 | title_label = QLabel("挂机时长:") 1750 | title_layout.addWidget(title_label) 1751 | title_layout.addStretch() # 添加弹性空间使标签靠左 1752 | 1753 | close_layout.addLayout(title_layout) 1754 | 1755 | # 第二行:时间输入框 1756 | time_layout = QHBoxLayout() 1757 | time_layout.setSpacing(5) # 设置较小的间距使输入框紧凑 1758 | 1759 | # 小时输入 1760 | time_layout.addWidget(QLabel("小时:")) 1761 | self.close_hours_input = QLineEdit(str(self.config.get("inactivity_timeout_hours", 0))) 1762 | self.close_hours_input.setValidator(QIntValidator(0, 23, self)) 1763 | self.close_hours_input.setFixedWidth(50) # 设置固定宽度 1764 | time_layout.addWidget(self.close_hours_input) 1765 | 1766 | # 分钟输入 1767 | time_layout.addWidget(QLabel("分钟:")) 1768 | self.close_minutes_input = QLineEdit(str(self.config.get("inactivity_timeout_minutes", 5))) 1769 | self.close_minutes_input.setValidator(QIntValidator(0, 59, self)) 1770 | self.close_minutes_input.setFixedWidth(50) 1771 | time_layout.addWidget(self.close_minutes_input) 1772 | 1773 | # 秒输入 1774 | time_layout.addWidget(QLabel("秒:")) 1775 | self.close_seconds_input = QLineEdit(str(self.config.get("inactivity_timeout_seconds", 0))) 1776 | self.close_seconds_input.setValidator(QIntValidator(0, 59, self)) 1777 | self.close_seconds_input.setFixedWidth(50) 1778 | time_layout.addWidget(self.close_seconds_input) 1779 | 1780 | time_layout.addStretch() # 添加弹性空间使输入框靠左 1781 | close_layout.addLayout(time_layout) 1782 | 1783 | # 第三行:提示文字 1784 | hint_layout = QHBoxLayout() 1785 | hint_label = QLabel("默认不设置时,脚本则会一直运行(全设为0即可)") 1786 | hint_label.setObjectName("HintLabel") # 应用小字号样式 1787 | hint_layout.addWidget(hint_label) 1788 | hint_layout.addStretch() # 添加弹性空间使标签靠左 1789 | close_layout.addLayout(hint_layout) 1790 | 1791 | close_group.setLayout(close_layout) 1792 | layout.addWidget(close_group) 1793 | 1794 | # === 按钮区域 === 1795 | button_layout = QHBoxLayout() 1796 | save_btn = QPushButton("保存设置") 1797 | save_btn.setFixedHeight(35) 1798 | save_btn.clicked.connect(self.save_settings) 1799 | button_layout.addWidget(save_btn) 1800 | 1801 | cancel_btn = QPushButton("返回主界面") 1802 | cancel_btn.setFixedHeight(35) 1803 | cancel_btn.clicked.connect(self.return_to_main) 1804 | button_layout.addWidget(cancel_btn) 1805 | 1806 | layout.addLayout(button_layout) 1807 | layout.addStretch() 1808 | 1809 | def show_strategy_help(self): 1810 | """显示换牌策略说明""" 1811 | help_text = """ 1812 | 换牌策略说明: 1813 | 1814 | 【3费档次】 1815 | • 最优:前三张牌组合为 [1,2,3] 1816 | • 次优:牌序为2,3 1817 | • 目标:确保3费时能准时打出 1818 | 1819 | 【4费档次】(向下兼容3费档次) 1820 | • 最优:四张牌组合为 [1,2,3,4] 1821 | • 次优:牌序为 [2,3,4] 或 [2,2,4] 1822 | • 目标:确保4费时能有效展开 1823 | 1824 | 【5费档次】(向下兼容4费、3费档次) 1825 | • 优先级组合(从高到低): 1826 | [2,3,4,5] > [2,3,3,5] > [2,2,3,5] > [2,2,2,5] 1827 | • 目标:确保5费时能打出关键牌 1828 | 1829 | 注意:高档次策略条件不满足时会自动检查低档次策略 1830 | """ 1831 | 1832 | msg = QMessageBox() 1833 | msg.setWindowTitle("换牌策略说明") 1834 | msg.setText(help_text) 1835 | msg.setIcon(QMessageBox.Information) 1836 | msg.exec_() 1837 | 1838 | def save_settings(self): 1839 | """保存设置到配置文件""" 1840 | try: 1841 | # 换牌策略 1842 | strategy = self.strategy_combo.currentText() 1843 | self.config["card_replacement"] = { 1844 | "strategy": strategy 1845 | } 1846 | 1847 | # 延迟设置 1848 | self.config["attack_delay"] = float(self.attack_delay_input.text()) 1849 | self.config["extra_drag_delay"] = float(self.drag_delay_input.text()) 1850 | self.config["scan_interval"] = int(self.scan_interval_input.text()) 1851 | 1852 | # 自动关闭设置 1853 | hours = int(self.close_hours_input.text()) 1854 | minutes = int(self.close_minutes_input.text()) 1855 | seconds = int(self.close_seconds_input.text()) 1856 | self.config["inactivity_timeout_hours"] = hours 1857 | self.config["inactivity_timeout_minutes"] = minutes 1858 | self.config["inactivity_timeout_seconds"] = seconds 1859 | self.config["inactivity_timeout"] = hours * 3600 + minutes * 60 + seconds 1860 | 1861 | # 保存到文件 1862 | with open("config.json", 'w', encoding='utf-8') as f: 1863 | json.dump(self.config, f, indent=2) 1864 | 1865 | self.parent.log_output.append("设置已保存") 1866 | QMessageBox.information(self, "保存成功", "设置已成功保存!") 1867 | except Exception as e: 1868 | self.parent.log_output.append(f"保存设置失败: {str(e)}") 1869 | QMessageBox.critical(self, "保存失败", f"保存设置时出错:\n{str(e)}") 1870 | 1871 | def return_to_main(self): 1872 | self.parent.stacked_widget.setCurrentIndex(0) 1873 | 1874 | class ShadowverseAutomationUI(QMainWindow): 1875 | def __init__(self): 1876 | super().__init__() 1877 | # 移除窗口边框和标题栏 1878 | self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.FramelessWindowHint) 1879 | self.setWindowTitle("Shadowverse 自动化脚本") 1880 | self.setGeometry(100, 100, 900, 700) 1881 | 1882 | # 加载配置 1883 | self.config = load_config() 1884 | 1885 | # 设置窗口背景 1886 | self.set_background() 1887 | 1888 | # 初始化UI 1889 | self.init_ui() 1890 | 1891 | # 工作线程 1892 | self.script_thread = None 1893 | self.run_time = 0 1894 | self.timer = QTimer(self) 1895 | self.timer.timeout.connect(self.update_run_time) 1896 | 1897 | # 窗口控制按钮状态 1898 | self.is_maximized = False 1899 | 1900 | def set_background(self): 1901 | # 创建调色板 1902 | palette = self.palette() 1903 | 1904 | # 检查背景图片是否存在 1905 | if BACKGROUND_IMAGE and os.path.exists(BACKGROUND_IMAGE): 1906 | # 加载背景图片并缩放以适应窗口 1907 | background = QPixmap(BACKGROUND_IMAGE).scaled( 1908 | self.size(), 1909 | Qt.IgnoreAspectRatio, 1910 | Qt.SmoothTransformation 1911 | ) 1912 | palette.setBrush(QPalette.Window, QBrush(background)) 1913 | else: 1914 | # 如果图片不存在,使用半透明黑色背景 1915 | palette.setColor(QPalette.Window, QColor(30, 30, 40, 180)) 1916 | 1917 | self.setPalette(palette) 1918 | 1919 | def resizeEvent(self, event): 1920 | # 当窗口大小改变时,重新设置背景图片 1921 | self.set_background() 1922 | super().resizeEvent(event) 1923 | 1924 | def init_ui(self): 1925 | # 主控件 1926 | central_widget = QWidget() 1927 | central_widget.setObjectName("CentralWidget") 1928 | central_widget.setStyleSheet(""" 1929 | #CentralWidget { 1930 | background-color: rgba(30, 30, 40, 180); 1931 | border-radius: 15px; 1932 | padding: 15px; 1933 | } 1934 | QLabel { 1935 | color: #E0E0FF; 1936 | font-weight: bold; 1937 | font-size: 12px; 1938 | } 1939 | QLineEdit { 1940 | background-color: rgba(50, 50, 70, 200); 1941 | color: #FFFFFF; 1942 | border: 1px solid #5A5A8F; 1943 | border-radius: 5px; 1944 | padding: 5px; 1945 | font-size: 12px; 1946 | } 1947 | QPushButton { 1948 | background-color: #4A4A7F; 1949 | color: #FFFFFF; 1950 | border: none; 1951 | border-radius: 5px; 1952 | padding: 8px 15px; 1953 | font-weight: bold; 1954 | min-width: 80px; 1955 | font-size: 12px; 1956 | } 1957 | QPushButton:hover { 1958 | background-color: #5A5A9F; 1959 | } 1960 | QPushButton:pressed { 1961 | background-color: #3A3A6F; 1962 | } 1963 | QTextEdit { 1964 | background-color: rgba(25, 25, 35, 220); 1965 | color: #66AAFF; 1966 | border: 1px solid #444477; 1967 | border-radius: 5px; 1968 | font-size: 12px; 1969 | } 1970 | #StatsFrame { 1971 | background-color: rgba(40, 40, 60, 200); 1972 | border: 1px solid #555588; 1973 | border-radius: 8px; 1974 | padding: 10px; 1975 | } 1976 | .StatLabel { 1977 | color: #AACCFF; 1978 | font-size: 12px; 1979 | } 1980 | .StatValue { 1981 | color: #FFFF88; 1982 | font-size: 12px; 1983 | font-weight: bold; 1984 | } 1985 | #TitleLabel { 1986 | font-size: 18px; 1987 | color: #88AAFF; 1988 | font-weight: bold; 1989 | padding: 10px 0; 1990 | } 1991 | #WindowControlButton { 1992 | background: transparent; 1993 | border: none; 1994 | min-width: 30px; 1995 | max-width: 30px; 1996 | min-height: 30px; 1997 | max-height: 30px; 1998 | padding: 0; 1999 | margin: 0; 2000 | font-size: 14px; 2001 | } 2002 | #WindowControlButton:hover { 2003 | background-color: rgba(255, 255, 255, 30); 2004 | } 2005 | #CloseButton:hover { 2006 | background-color: rgba(255, 0, 0, 100); 2007 | } 2008 | QComboBox { 2009 | background-color: rgba(50, 50, 70, 200); 2010 | color: #FFFFFF; 2011 | border: 1px solid #5A5A8F; 2012 | border-radius: 5px; 2013 | padding: 5px; 2014 | min-width: 100px; 2015 | font-size: 12px; 2016 | } 2017 | QGroupBox { 2018 | background-color: rgba(40, 40, 60, 180); 2019 | border: 1px solid #555588; 2020 | border-radius: 8px; 2021 | margin-top: 10px; 2022 | padding: 10px; 2023 | } 2024 | QGroupBox::title { 2025 | color: #88AAFF; 2026 | subcontrol-origin: margin; 2027 | subcontrol-position: top left; 2028 | padding: 0 5px; 2029 | font-weight: bold; 2030 | font-size: 12px; 2031 | } 2032 | QTabWidget::pane { 2033 | border: 1px solid #555588; 2034 | border-radius: 5px; 2035 | background-color: rgba(30, 30, 40, 180); 2036 | } 2037 | QTabBar::tab { 2038 | background-color: #4A4A7F; 2039 | color: #FFFFFF; 2040 | padding: 8px 15px; 2041 | border-top-left-radius: 5px; 2042 | border-top-right-radius: 5px; 2043 | margin-right: 2px; 2044 | font-size: 12px; 2045 | } 2046 | QTabBar::tab:selected { 2047 | background-color: #5A5A9F; 2048 | } 2049 | QTabBar::tab:hover { 2050 | background-color: #6A6AAF; 2051 | } 2052 | .HintLabel { 2053 | color: #AAAAFF; 2054 | font-size: 10px; 2055 | font-style: italic; 2056 | margin-top: 3px; 2057 | } 2058 | """) 2059 | 2060 | # 创建主布局 2061 | main_layout = QVBoxLayout(central_widget) 2062 | main_layout.setSpacing(10) 2063 | main_layout.setContentsMargins(10, 10, 10, 10) 2064 | 2065 | # === 顶部控制栏 === 2066 | top_bar = QWidget() 2067 | top_bar_layout = QHBoxLayout(top_bar) 2068 | top_bar_layout.setContentsMargins(0, 0, 0, 0) 2069 | 2070 | # 标题 2071 | title_label = QLabel("Shadowverse 自动化脚本[免费]") 2072 | title_label.setObjectName("TitleLabel") 2073 | top_bar_layout.addWidget(title_label) 2074 | 2075 | # 添加弹性空间 2076 | top_bar_layout.addStretch() 2077 | 2078 | # 窗口控制按钮 2079 | self.minimize_btn = QPushButton("-") 2080 | self.minimize_btn.setObjectName("WindowControlButton") 2081 | self.minimize_btn.clicked.connect(self.showMinimized) 2082 | top_bar_layout.addWidget(self.minimize_btn) 2083 | 2084 | self.maximize_btn = QPushButton("□") 2085 | self.maximize_btn.setObjectName("WindowControlButton") 2086 | self.maximize_btn.clicked.connect(self.toggle_maximize) 2087 | top_bar_layout.addWidget(self.maximize_btn) 2088 | 2089 | self.close_btn = QPushButton("×") 2090 | self.close_btn.setObjectName("WindowControlButton") 2091 | self.close_btn.setObjectName("CloseButton") 2092 | self.close_btn.clicked.connect(self.close) 2093 | top_bar_layout.addWidget(self.close_btn) 2094 | 2095 | main_layout.addWidget(top_bar) 2096 | 2097 | # === 主内容区域 - 使用堆叠窗口 === 2098 | self.stacked_widget = QStackedWidget() 2099 | main_layout.addWidget(self.stacked_widget) 2100 | 2101 | # 创建主页面 2102 | self.main_page = self.create_main_page() 2103 | self.stacked_widget.addWidget(self.main_page) 2104 | 2105 | # 创建设置页面 2106 | self.settings_page = self.create_settings_page() 2107 | self.stacked_widget.addWidget(self.settings_page) 2108 | 2109 | # 默认显示主页面 2110 | self.stacked_widget.setCurrentIndex(0) 2111 | 2112 | self.setCentralWidget(central_widget) 2113 | 2114 | # 初始化按钮状态 2115 | self.resume_btn.setEnabled(False) 2116 | self.pause_btn.setEnabled(False) 2117 | self.stop_btn.setEnabled(False) 2118 | 2119 | # 设置服务器选择框的初始值 2120 | server_index = self.server_combo.findText(self.config["server"]) 2121 | if server_index >= 0: 2122 | self.server_combo.setCurrentIndex(server_index) 2123 | 2124 | def create_main_page(self): 2125 | """创建主页面""" 2126 | page = QWidget() 2127 | layout = QVBoxLayout(page) 2128 | layout.setSpacing(10) 2129 | 2130 | # === 状态和控制区域 === 2131 | control_widget = QWidget() 2132 | control_layout = QHBoxLayout(control_widget) 2133 | control_layout.setSpacing(15) 2134 | 2135 | # 左侧:状态和连接 2136 | status_widget = QWidget() 2137 | status_layout = QVBoxLayout(status_widget) 2138 | status_layout.setSpacing(10) 2139 | 2140 | # 连接状态 2141 | status_frame = QFrame() 2142 | status_frame.setObjectName("StatsFrame") 2143 | frame_layout = QVBoxLayout(status_frame) 2144 | 2145 | server_layout = QHBoxLayout() 2146 | server_label = QLabel("服务器:") 2147 | self.server_combo = QComboBox() 2148 | self.server_combo.addItems(["国服", "国际服"]) 2149 | self.server_combo.currentTextChanged.connect(self.server_changed) 2150 | server_layout.addWidget(server_label) 2151 | server_layout.addWidget(self.server_combo) 2152 | server_layout.addStretch() 2153 | 2154 | frame_layout.addLayout(server_layout) 2155 | 2156 | adb_layout = QHBoxLayout() 2157 | adb_label = QLabel("ADB 端口:") 2158 | self.adb_input = QLineEdit(f"127.0.0.1:{self.config['emulator_port']}") 2159 | self.adb_input.setFixedWidth(120) 2160 | adb_layout.addWidget(adb_label) 2161 | adb_layout.addWidget(self.adb_input) 2162 | adb_layout.addStretch() 2163 | 2164 | frame_layout.addLayout(adb_layout) 2165 | 2166 | # 状态显示 2167 | status_layout.addWidget(status_frame) 2168 | 2169 | # 开始按钮 2170 | self.start_btn = QPushButton("开始运行") 2171 | self.start_btn.setFixedHeight(35) 2172 | self.start_btn.clicked.connect(self.start_script) 2173 | status_layout.addWidget(self.start_btn) 2174 | 2175 | # 添加到控制布局 2176 | control_layout.addWidget(status_widget) 2177 | 2178 | # 中间:统计信息 2179 | stats_widget = QWidget() 2180 | stats_layout = QVBoxLayout(stats_widget) 2181 | 2182 | stats_frame = QFrame() 2183 | stats_frame.setObjectName("StatsFrame") 2184 | grid_layout = QGridLayout(stats_frame) 2185 | 2186 | # 统计信息 2187 | grid_layout.addWidget(QLabel("当前状态:"), 0, 0) 2188 | self.status_label = QLabel("未连接") 2189 | self.status_label.setStyleSheet("color: #FF5555;") 2190 | grid_layout.addWidget(self.status_label, 0, 1) 2191 | 2192 | grid_layout.addWidget(QLabel("当前回合:"), 1, 0) 2193 | self.current_turn_label = QLabel("0") 2194 | self.current_turn_label.setObjectName("StatValue") 2195 | grid_layout.addWidget(self.current_turn_label, 1, 1) 2196 | 2197 | grid_layout.addWidget(QLabel("对战次数:"), 2, 0) 2198 | self.battle_count_label = QLabel("0") 2199 | self.battle_count_label.setObjectName("StatValue") 2200 | grid_layout.addWidget(self.battle_count_label, 2, 1) 2201 | 2202 | grid_layout.addWidget(QLabel("回合总数:"), 3, 0) 2203 | self.turn_count_label = QLabel("0") 2204 | self.turn_count_label.setObjectName("StatValue") 2205 | grid_layout.addWidget(self.turn_count_label, 3, 1) 2206 | 2207 | # 添加运行时间标签 2208 | grid_layout.addWidget(QLabel("运行时间:"), 4, 0) 2209 | self.run_time_label = QLabel("00:00:00") 2210 | self.run_time_label.setObjectName("StatValue") 2211 | grid_layout.addWidget(self.run_time_label, 4, 1) 2212 | 2213 | stats_layout.addWidget(stats_frame) 2214 | control_layout.addWidget(stats_widget) 2215 | 2216 | # 右侧:控制按钮 2217 | btn_widget = QWidget() 2218 | btn_layout = QVBoxLayout(btn_widget) 2219 | btn_layout.setSpacing(8) 2220 | 2221 | self.resume_btn = QPushButton("恢复运行") 2222 | self.resume_btn.setFixedHeight(35) 2223 | self.resume_btn.clicked.connect(self.resume_script) 2224 | btn_layout.addWidget(self.resume_btn) 2225 | 2226 | self.pause_btn = QPushButton("暂停运行") 2227 | self.pause_btn.setFixedHeight(35) 2228 | self.pause_btn.clicked.connect(self.pause_script) 2229 | btn_layout.addWidget(self.pause_btn) 2230 | 2231 | self.settings_btn = QPushButton("参数设置") 2232 | self.settings_btn.setFixedHeight(35) 2233 | self.settings_btn.clicked.connect(self.show_settings) 2234 | btn_layout.addWidget(self.settings_btn) 2235 | 2236 | self.stop_btn = QPushButton("停止/关闭") 2237 | self.stop_btn.setFixedHeight(35) 2238 | self.stop_btn.clicked.connect(self.stop_script) 2239 | btn_layout.addWidget(self.stop_btn) 2240 | 2241 | control_layout.addWidget(btn_widget) 2242 | 2243 | layout.addWidget(control_widget) 2244 | 2245 | # === 运行日志区域 === 2246 | log_widget = QWidget() 2247 | log_layout = QVBoxLayout(log_widget) 2248 | 2249 | log_label = QLabel("运行日志:") 2250 | log_layout.addWidget(log_label) 2251 | 2252 | self.log_output = QTextEdit() 2253 | self.log_output.setReadOnly(True) 2254 | self.log_output.setMinimumHeight(200) 2255 | log_layout.addWidget(self.log_output) 2256 | 2257 | layout.addWidget(log_widget, 1) 2258 | 2259 | return page 2260 | 2261 | def create_settings_page(self): 2262 | """创建设置页面""" 2263 | page = QWidget() 2264 | layout = QVBoxLayout(page) 2265 | layout.setSpacing(15) 2266 | layout.setContentsMargins(15, 15, 15, 15) 2267 | 2268 | # 标题 2269 | title_label = QLabel("参数设置") 2270 | title_label.setObjectName("TitleLabel") 2271 | title_label.setAlignment(Qt.AlignCenter) 2272 | layout.addWidget(title_label) 2273 | 2274 | # 返回按钮 2275 | back_btn = QPushButton("返回主界面") 2276 | back_btn.setFixedHeight(35) 2277 | back_btn.clicked.connect(self.show_main) 2278 | layout.addWidget(back_btn) 2279 | 2280 | # === 策略设置 === 2281 | strategy_group = QGroupBox("策略设置") 2282 | strategy_layout = QVBoxLayout(strategy_group) 2283 | strategy_layout.setSpacing(10) 2284 | 2285 | # 换牌策略 2286 | strategy_row = QHBoxLayout() 2287 | strategy_label = QLabel("换牌策略:") 2288 | self.strategy_combo = QComboBox() 2289 | self.strategy_combo.addItems(['3费档次', '4费档次', '5费档次']) 2290 | strategy_row.addWidget(strategy_label) 2291 | strategy_row.addWidget(self.strategy_combo) 2292 | strategy_row.addStretch() 2293 | 2294 | # 策略说明按钮 2295 | self.strategy_help_btn = QPushButton("说明") 2296 | self.strategy_help_btn.setFixedWidth(60) 2297 | self.strategy_help_btn.setToolTip("点击查看换牌策略说明") 2298 | self.strategy_help_btn.clicked.connect(self.show_strategy_help) 2299 | strategy_row.addWidget(self.strategy_help_btn) 2300 | 2301 | strategy_layout.addLayout(strategy_row) 2302 | 2303 | # 设置初始值 2304 | strategy_index = self.strategy_combo.findText(self.config.get("card_replacement", {}).get("strategy", "3费档次")) 2305 | if strategy_index >= 0: 2306 | self.strategy_combo.setCurrentIndex(strategy_index) 2307 | 2308 | layout.addWidget(strategy_group) 2309 | 2310 | # === 延迟设置 === 2311 | delay_group = QGroupBox("延迟设置") 2312 | delay_layout = QGridLayout(delay_group) 2313 | delay_layout.setHorizontalSpacing(20) 2314 | delay_layout.setVerticalSpacing(10) 2315 | 2316 | # 攻击延迟 2317 | delay_layout.addWidget(QLabel("攻击延迟 (秒):"), 0, 0) 2318 | self.attack_delay_input = QLineEdit(str(self.config.get("attack_delay", 0.25))) 2319 | self.attack_delay_input.setValidator(QDoubleValidator(0.1, 2.0, 2, self)) 2320 | delay_layout.addWidget(self.attack_delay_input, 0, 1) 2321 | 2322 | # 攻击延迟提示 2323 | attack_hint = QLabel("设定范围推荐0.6~0.9秒") 2324 | attack_hint.setObjectName("HintLabel") 2325 | delay_layout.addWidget(attack_hint, 0, 2) 2326 | 2327 | # 拖拽延迟 2328 | delay_layout.addWidget(QLabel("拖拽延迟 (秒):"), 1, 0) 2329 | self.drag_delay_input = QLineEdit(str(self.config.get("extra_drag_delay", 0.05))) 2330 | self.drag_delay_input.setValidator(QDoubleValidator(0.01, 0.5, 3, self)) 2331 | delay_layout.addWidget(self.drag_delay_input, 1, 1) 2332 | 2333 | # 拖拽延迟提示 2334 | drag_hint = QLabel("推荐参数0.1秒") 2335 | drag_hint.setObjectName("HintLabel") 2336 | delay_layout.addWidget(drag_hint, 1, 2) 2337 | 2338 | # 扫描间隔 2339 | delay_layout.addWidget(QLabel("扫描间隔 (秒):"), 2, 0) 2340 | self.scan_interval_input = QLineEdit(str(self.config.get("scan_interval", 2))) 2341 | self.scan_interval_input.setValidator(QIntValidator(1, 10, self)) 2342 | delay_layout.addWidget(self.scan_interval_input, 2, 1) 2343 | 2344 | # 扫描间隔提示 2345 | scan_hint = QLabel("推荐1-2秒") 2346 | scan_hint.setObjectName("HintLabel") 2347 | delay_layout.addWidget(scan_hint, 2, 2) 2348 | 2349 | layout.addWidget(delay_group) 2350 | 2351 | # === 自动关闭设置 === 2352 | close_group = QGroupBox("自动关闭设置") 2353 | close_layout = QVBoxLayout() # 使用垂直布局作为主布局 2354 | close_layout.setSpacing(8) # 设置较小的间距 2355 | 2356 | # 第一行:标题标签 2357 | title_layout = QHBoxLayout() 2358 | title_label = QLabel("挂机时长:") 2359 | title_layout.addWidget(title_label) 2360 | title_layout.addStretch() # 添加弹性空间使标签靠左 2361 | 2362 | close_layout.addLayout(title_layout) 2363 | 2364 | # 第二行:时间输入框 2365 | time_layout = QHBoxLayout() 2366 | time_layout.setSpacing(5) # 设置较小的间距使输入框紧凑 2367 | 2368 | # 小时输入 2369 | time_layout.addWidget(QLabel("小时:")) 2370 | self.close_hours_input = QLineEdit(str(self.config.get("inactivity_timeout_hours", 0))) 2371 | self.close_hours_input.setValidator(QIntValidator(0, 23, self)) 2372 | self.close_hours_input.setFixedWidth(50) # 设置固定宽度 2373 | time_layout.addWidget(self.close_hours_input) 2374 | 2375 | # 分钟输入 2376 | time_layout.addWidget(QLabel("分钟:")) 2377 | self.close_minutes_input = QLineEdit(str(self.config.get("inactivity_timeout_minutes", 5))) 2378 | self.close_minutes_input.setValidator(QIntValidator(0, 59, self)) 2379 | self.close_minutes_input.setFixedWidth(50) 2380 | time_layout.addWidget(self.close_minutes_input) 2381 | 2382 | # 秒输入 2383 | time_layout.addWidget(QLabel("秒:")) 2384 | self.close_seconds_input = QLineEdit(str(self.config.get("inactivity_timeout_seconds", 0))) 2385 | self.close_seconds_input.setValidator(QIntValidator(0, 59, self)) 2386 | self.close_seconds_input.setFixedWidth(50) 2387 | time_layout.addWidget(self.close_seconds_input) 2388 | 2389 | time_layout.addStretch() # 添加弹性空间使输入框靠左 2390 | close_layout.addLayout(time_layout) 2391 | 2392 | # 第三行:提示文字 2393 | hint_layout = QHBoxLayout() 2394 | hint_label = QLabel("默认设置为 0 时,脚本则会一直运行") 2395 | hint_label.setObjectName("HintLabel") # 应用小字号样式 2396 | hint_layout.addWidget(hint_label) 2397 | hint_layout.addStretch() # 添加弹性空间使标签靠左 2398 | close_layout.addLayout(hint_layout) 2399 | 2400 | close_group.setLayout(close_layout) 2401 | layout.addWidget(close_group) 2402 | 2403 | # 保存按钮 2404 | save_btn = QPushButton("保存设置") 2405 | save_btn.setFixedHeight(40) 2406 | save_btn.clicked.connect(self.save_settings) 2407 | layout.addWidget(save_btn) 2408 | 2409 | # 添加弹性空间 2410 | layout.addStretch() 2411 | 2412 | return page 2413 | 2414 | def save_settings(self): 2415 | """保存设置到配置文件""" 2416 | try: 2417 | # 换牌策略 2418 | strategy = self.strategy_combo.currentText() 2419 | self.config["card_replacement"] = { 2420 | "strategy": strategy 2421 | } 2422 | 2423 | # 延迟设置 2424 | self.config["attack_delay"] = float(self.attack_delay_input.text()) 2425 | self.config["extra_drag_delay"] = float(self.drag_delay_input.text()) 2426 | self.config["scan_interval"] = int(self.scan_interval_input.text()) 2427 | 2428 | # 自动关闭设置 2429 | hours = int(self.close_hours_input.text()) 2430 | minutes = int(self.close_minutes_input.text()) 2431 | seconds = int(self.close_seconds_input.text()) 2432 | self.config["inactivity_timeout_hours"] = hours 2433 | self.config["inactivity_timeout_minutes"] = minutes 2434 | self.config["inactivity_timeout_seconds"] = seconds 2435 | self.config["inactivity_timeout"] = hours * 3600 + minutes * 60 + seconds 2436 | 2437 | # 保存到文件 2438 | with open("config.json", 'w', encoding='utf-8') as f: 2439 | json.dump(self.config, f, indent=2) 2440 | 2441 | self.log_output.append("设置已保存") 2442 | self.show_main() 2443 | except Exception as e: 2444 | self.log_output.append(f"保存设置失败: {str(e)}") 2445 | 2446 | def show_settings(self): 2447 | """显示设置页面""" 2448 | self.stacked_widget.setCurrentIndex(1) 2449 | 2450 | def show_main(self): 2451 | """显示主页面""" 2452 | self.stacked_widget.setCurrentIndex(0) 2453 | 2454 | def toggle_maximize(self): 2455 | """切换窗口最大化和恢复""" 2456 | if self.isMaximized(): 2457 | self.showNormal() 2458 | self.maximize_btn.setText("□") 2459 | else: 2460 | self.showMaximized() 2461 | self.maximize_btn.setText("❐") 2462 | 2463 | def server_changed(self, server): 2464 | """服务器选择改变事件""" 2465 | self.log_output.append(f"服务器已更改为: {server}") 2466 | self.config["server"] = server 2467 | 2468 | # 保存配置 2469 | try: 2470 | with open("config.json", 'w', encoding='utf-8') as f: 2471 | json.dump(self.config, f, indent=2) 2472 | except Exception as e: 2473 | self.log_output.append(f"保存配置失败: {str(e)}") 2474 | 2475 | def start_script(self): 2476 | self.log_output.append("正在连接设备...") 2477 | self.start_btn.setEnabled(False) 2478 | 2479 | # 加载配置 2480 | config = self.config 2481 | try: 2482 | config["emulator_port"] = int(self.adb_input.text().split(":")[-1]) 2483 | except: 2484 | config["emulator_port"] = 16384 2485 | 2486 | # 创建工作线程 2487 | self.script_thread = ScriptThread(config) 2488 | self.script_thread.log_signal.connect(self.log_output.append) 2489 | self.script_thread.status_signal.connect(self.update_status) 2490 | self.script_thread.stats_signal.connect(self.update_stats) 2491 | self.script_thread.error_signal.connect(self.handle_script_error) 2492 | self.script_thread.start() 2493 | 2494 | # 更新按钮状态 2495 | self.resume_btn.setEnabled(False) 2496 | self.stop_btn.setEnabled(True) 2497 | self.pause_btn.setEnabled(True) 2498 | self.timer.start(1000) # 每秒更新一次运行时间 2499 | 2500 | def resume_script(self): 2501 | if self.script_thread: 2502 | self.script_thread.resume() 2503 | self.resume_btn.setEnabled(False) 2504 | 2505 | def handle_script_error(self, error_msg): 2506 | self.log_output.append(f"脚本线程错误,请关闭并重启脚本后尝试,错误信息:\n {error_msg}") 2507 | if self.script_thread: 2508 | self.script_thread.stop() 2509 | self.script_thread.wait() 2510 | # 重置按钮状态 2511 | self.start_btn.setEnabled(True) 2512 | self.resume_btn.setEnabled(False) 2513 | self.stop_btn.setEnabled(False) 2514 | self.pause_btn.setEnabled(False) 2515 | self.update_status("已停止") 2516 | 2517 | def stop_script(self): 2518 | if self.script_thread: 2519 | self.log_output.append(f"脚本已停止") 2520 | self.script_thread.stop() 2521 | self.script_thread.wait() 2522 | self.start_btn.setEnabled(True) 2523 | self.resume_btn.setEnabled(False) 2524 | self.stop_btn.setEnabled(False) 2525 | self.pause_btn.setEnabled(False) 2526 | self.timer.stop() 2527 | self.update_status("已停止") 2528 | 2529 | def pause_script(self): 2530 | if self.script_thread: 2531 | self.script_thread.pause() 2532 | self.resume_btn.setEnabled(True) 2533 | 2534 | def show_strategy_help(self): 2535 | """显示换牌策略说明""" 2536 | help_text = """ 2537 | 换牌策略说明: 2538 | 2539 | 【3费档次】 2540 | • 最优:前三张牌组合为 [1,2,3] 2541 | • 次优:牌序为2,3 2542 | • 目标:确保3费时能准时打出 2543 | 2544 | 【4费档次】(向下兼容3费档次) 2545 | • 最优:四张牌组合为 [1,2,3,4] 2546 | • 次优:牌序为 [2,3,4] 或 [2,2,4] 2547 | • 目标:确保4费时能有效展开 2548 | 2549 | 【5费档次】(向下兼容4费、3费档次) 2550 | • 优先级组合(从高到低): 2551 | [2,3,4,5] > [2,3,3,5] > [2,2,3,5] > [2,2,2,5] 2552 | • 目标:确保5费时能打出关键牌 2553 | 2554 | 注意:高档次策略条件不满足时会自动检查低档次策略 2555 | """ 2556 | 2557 | msg = QMessageBox() 2558 | msg.setWindowTitle("换牌策略说明") 2559 | msg.setText(help_text) 2560 | msg.setIcon(QMessageBox.Information) 2561 | msg.exec_() 2562 | 2563 | def update_status(self, status): 2564 | self.status_label.setText(status) 2565 | if status == "运行中": 2566 | self.status_label.setStyleSheet("color: #55FF55;") 2567 | elif status == "已暂停": 2568 | self.status_label.setStyleSheet("color: #FFFF55;") 2569 | else: 2570 | self.status_label.setStyleSheet("color: #FF5555;") 2571 | 2572 | def update_stats(self, stats): 2573 | self.current_turn_label.setText(str(stats['current_turn'])) 2574 | self.run_time = stats['run_time'] 2575 | self.update_run_time() 2576 | self.battle_count_label.setText(str(stats['battle_count'])) 2577 | self.turn_count_label.setText(str(stats['turn_count'])) 2578 | 2579 | def update_run_time(self): 2580 | """更新运行时间显示""" 2581 | hours = self.run_time // 3600 2582 | minutes = (self.run_time % 3600) // 60 2583 | seconds = self.run_time % 60 2584 | self.run_time_label.setText(f"{hours:02d}:{minutes:02d}:{seconds:02d}") 2585 | 2586 | # 添加鼠标事件处理以实现窗口拖动 2587 | def mousePressEvent(self, event): 2588 | if event.button() == Qt.LeftButton: 2589 | self.drag_position = event.globalPos() - self.frameGeometry().topLeft() 2590 | event.accept() 2591 | 2592 | def mouseMoveEvent(self, event): 2593 | if hasattr(self, 'drag_position') and event.buttons() == Qt.LeftButton: 2594 | self.move(event.globalPos() - self.drag_position) 2595 | event.accept() 2596 | 2597 | def closeEvent(self, event): 2598 | if self.script_thread: 2599 | self.script_thread.stop() 2600 | self.script_thread.wait() 2601 | event.accept() 2602 | 2603 | if __name__ == "__main__": 2604 | try: 2605 | app = QApplication(sys.argv) 2606 | window = ShadowverseAutomationUI() 2607 | window.show() 2608 | sys.exit(app.exec_()) 2609 | except Exception as e: 2610 | # 弹窗提示错误 2611 | QMessageBox.critical(None, "错误", f"程序崩溃: {e}") 2612 | --------------------------------------------------------------------------------