1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-14 07:39:25 +08:00

add: migrate power limit and exercise delay

This commit is contained in:
0O0o0oOoO00
2025-09-14 17:57:06 +08:00
parent a5b77b50dd
commit ff4026fa91
51 changed files with 1630 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -93,6 +93,7 @@
},
"PowerLimit": {
"PowerLimit": {
"Enable": true,
"Exercise": 25000,
"Raid": 25000,
"Ash": 25000
@@ -2069,6 +2070,7 @@
"ServerUpdate": "00:00, 12:00, 18:00"
},
"Exercise": {
"DelayUntilHoursBeforeNextUpdate": 12,
"OpponentChooseMode": "max_exp",
"OpponentTrial": 1,
"ExerciseStrategy": "aggressive",

View File

@@ -157,3 +157,28 @@ class Timer:
return f'Timer(limit={round(self.current(), 3)}/{self.limit}, count={self._reach_count}/{self.count})'
__repr__ = __str__
def timeout(_function, timeout_sec=30.0, *args, **kwargs):
"""Won't kill that task until it finishes"""
from threading import Thread
from module.logger import logger
def function_timeout(_func):
t0 = time.time()
success = True
p = Thread(target=_func, args=args, kwargs=kwargs)
p.start()
p.join(timeout_sec)
if p.is_alive():
success = False
t1 = time.time()
if t1 - t0 < 10:
success = False
_success = 'Done' if success else 'Failed'
logger.hr(f'{_func.__name__}: {_success} in {str(round(t1 - t0, 1))}s', 1)
if not success:
return True
return False
return function_timeout(_function)

View File

@@ -462,6 +462,10 @@
},
"PowerLimit": {
"PowerLimit": {
"Enable": {
"type": "checkbox",
"value": true
},
"Exercise": {
"type": "input",
"value": 25000
@@ -14686,6 +14690,18 @@
}
},
"Exercise": {
"DelayUntilHoursBeforeNextUpdate": {
"type": "select",
"value": 12,
"option": [
1,
2,
3,
4,
5,
12
]
},
"OpponentChooseMode": {
"type": "select",
"value": "max_exp",

View File

@@ -650,6 +650,9 @@ Hard:
value: 1
option: [ 1, 2 ]
Exercise:
DelayUntilHoursBeforeNextUpdate:
value: 12
option: [ 1, 2, 3, 4, 5, 12]
OpponentChooseMode:
value: max_exp
option: [ max_exp, easiest, leftmost, easiest_else_exp ]
@@ -879,6 +882,7 @@ Misc:
# ==================== Cheat ====================
PowerLimit:
Enable: true
Exercise: 25000
Raid: 25000
Ash: 25000

View File

@@ -371,6 +371,7 @@ class GeneratedConfig:
Hard_HardFleet = 1 # 1, 2
# Group `Exercise`
Exercise_DelayUntilHoursBeforeNextUpdate = 12 # 1, 2, 3, 4, 5, 12
Exercise_OpponentChooseMode = 'max_exp' # max_exp, easiest, leftmost, easiest_else_exp
Exercise_OpponentTrial = 1
Exercise_ExerciseStrategy = 'aggressive' # aggressive, fri18, sat0, sat12, sat18, sun0, sun12, sun18
@@ -535,6 +536,7 @@ class GeneratedConfig:
Misc_SkipBattleCelebrate = False
# Group `PowerLimit`
PowerLimit_Enable = True
PowerLimit_Exercise = 25000
PowerLimit_Raid = 25000
PowerLimit_Ash = 25000

View File

@@ -68,6 +68,7 @@ class FullGeneratedConfig:
Restart_Storage_Storage = None
# Task `PowerLimit`
PowerLimit_PowerLimit_Enable = None
PowerLimit_PowerLimit_Exercise = None
PowerLimit_PowerLimit_Raid = None
PowerLimit_PowerLimit_Ash = None
@@ -1540,6 +1541,7 @@ class FullGeneratedConfig:
Exercise_Scheduler_SuccessInterval = None
Exercise_Scheduler_FailureInterval = None
Exercise_Scheduler_ServerUpdate = None
Exercise_Exercise_DelayUntilHoursBeforeNextUpdate = None
Exercise_Exercise_OpponentChooseMode = None
Exercise_Exercise_OpponentTrial = None
Exercise_Exercise_ExerciseStrategy = None

View File

@@ -2303,6 +2303,16 @@
"name": "Exercise Settings",
"help": "Runs exercise and automatically retreats when sum HP volume is low"
},
"DelayUntilHoursBeforeNextUpdate": {
"name": "Exercise.DelayUntilHoursBeforeNextUpdate.name",
"help": "Exercise.DelayUntilHoursBeforeNextUpdate.help",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"12": "12"
},
"OpponentChooseMode": {
"name": "Opponent Choose Mode",
"help": "",
@@ -3077,6 +3087,10 @@
"name": "PowerLimit._info.name",
"help": "PowerLimit._info.help"
},
"Enable": {
"name": "PowerLimit.Enable.name",
"help": "PowerLimit.Enable.help"
},
"Exercise": {
"name": "PowerLimit.Exercise.name",
"help": "PowerLimit.Exercise.help"

View File

@@ -2303,6 +2303,16 @@
"name": "Exercise._info.name",
"help": "Exercise._info.help"
},
"DelayUntilHoursBeforeNextUpdate": {
"name": "Exercise.DelayUntilHoursBeforeNextUpdate.name",
"help": "Exercise.DelayUntilHoursBeforeNextUpdate.help",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"12": "12"
},
"OpponentChooseMode": {
"name": "Exercise.OpponentChooseMode.name",
"help": "Exercise.OpponentChooseMode.help",
@@ -3077,6 +3087,10 @@
"name": "PowerLimit._info.name",
"help": "PowerLimit._info.help"
},
"Enable": {
"name": "PowerLimit.Enable.name",
"help": "PowerLimit.Enable.help"
},
"Exercise": {
"name": "PowerLimit.Exercise.name",
"help": "PowerLimit.Exercise.help"

View File

@@ -2303,6 +2303,16 @@
"name": "演习",
"help": "打演习,血量过低时自动撤退"
},
"DelayUntilHoursBeforeNextUpdate": {
"name": "推迟演习至下次更新次数前 X 小时",
"help": "",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"12": "不推迟"
},
"OpponentChooseMode": {
"name": "对手选择模式",
"help": "",
@@ -3077,6 +3087,10 @@
"name": "战力限制",
"help": "敏感项目前的最后一道保险\n若前排战力高于此值强制重启并视为需要使用GG打开GG开关以及GG自动重启倍率开关"
},
"Enable": {
"name": "启用",
"help": ""
},
"Exercise": {
"name": "演习",
"help": ""

View File

@@ -2303,6 +2303,16 @@
"name": "演習",
"help": "打演習,血量過低時自動撤退"
},
"DelayUntilHoursBeforeNextUpdate": {
"name": "Exercise.DelayUntilHoursBeforeNextUpdate.name",
"help": "Exercise.DelayUntilHoursBeforeNextUpdate.help",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"12": "12"
},
"OpponentChooseMode": {
"name": "對手選擇模式",
"help": "",
@@ -3077,6 +3087,10 @@
"name": "PowerLimit._info.name",
"help": "PowerLimit._info.help"
},
"Enable": {
"name": "PowerLimit.Enable.name",
"help": "PowerLimit.Enable.help"
},
"Exercise": {
"name": "PowerLimit.Exercise.name",
"help": "PowerLimit.Exercise.help"

View File

@@ -0,0 +1,36 @@
from module.base.button import Button
from module.base.template import Template
# This file was automatically generated by dev_tools/button_extract.py.
# Don't modify it manually.
BUTTON_GEM = Button(area={'cn': (991, 26, 1013, 45), 'en': (991, 26, 1013, 45), 'jp': (991, 26, 1013, 45), 'tw': (991, 26, 1013, 45)}, color={'cn': (239, 72, 110), 'en': (239, 72, 110), 'jp': (239, 72, 110), 'tw': (239, 72, 110)}, button={'cn': (991, 26, 1013, 45), 'en': (991, 26, 1013, 45), 'jp': (991, 26, 1013, 45), 'tw': (991, 26, 1013, 45)}, file={'cn': './assets/cn/gg_handler/BUTTON_GEM.png', 'en': './assets/cn/gg_handler/BUTTON_GEM.png', 'jp': './assets/cn/gg_handler/BUTTON_GEM.png', 'tw': './assets/cn/gg_handler/BUTTON_GEM.png'})
BUTTON_GG_APP_CHOOSE = Button(area={'cn': (338, 114, 381, 152), 'en': (338, 114, 381, 152), 'jp': (338, 114, 381, 152), 'tw': (338, 114, 381, 152)}, color={'cn': (211, 168, 176), 'en': (211, 168, 176), 'jp': (211, 168, 176), 'tw': (211, 168, 176)}, button={'cn': (338, 114, 381, 152), 'en': (338, 114, 381, 152), 'jp': (338, 114, 381, 152), 'tw': (338, 114, 381, 152)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_APP_CHOOSE.png', 'en': './assets/cn/gg_handler/BUTTON_GG_APP_CHOOSE.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_APP_CHOOSE.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_APP_CHOOSE.png'})
BUTTON_GG_CONFIRM = Button(area={'cn': (1222, 695, 1249, 715), 'en': (1222, 695, 1249, 715), 'jp': (1222, 695, 1249, 715), 'tw': (1222, 695, 1249, 715)}, color={'cn': (125, 125, 125), 'en': (125, 125, 125), 'jp': (125, 125, 125), 'tw': (125, 125, 125)}, button={'cn': (1222, 695, 1249, 715), 'en': (1222, 695, 1249, 715), 'jp': (1222, 695, 1249, 715), 'tw': (1222, 695, 1249, 715)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_CONFIRM.png', 'en': './assets/cn/gg_handler/BUTTON_GG_CONFIRM.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_CONFIRM.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_CONFIRM.png'})
BUTTON_GG_CONFIRM_POS = Button(area={'cn': (1220, 693, 1250, 717), 'en': (1220, 693, 1250, 717), 'jp': (1220, 693, 1250, 717), 'tw': (1220, 693, 1250, 717)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1220, 693, 1250, 717), 'en': (1220, 693, 1250, 717), 'jp': (1220, 693, 1250, 717), 'tw': (1220, 693, 1250, 717)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_CONFIRM_POS.png', 'en': './assets/cn/gg_handler/BUTTON_GG_CONFIRM_POS.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_CONFIRM_POS.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_CONFIRM_POS.png'})
BUTTON_GG_ENTER_POS = Button(area={'cn': (558, 15, 603, 61), 'en': (558, 15, 603, 61), 'jp': (558, 15, 603, 61), 'tw': (558, 15, 603, 61)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (558, 15, 603, 61), 'en': (558, 15, 603, 61), 'jp': (558, 15, 603, 61), 'tw': (558, 15, 603, 61)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_ENTER_POS.png', 'en': './assets/cn/gg_handler/BUTTON_GG_ENTER_POS.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_ENTER_POS.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_ENTER_POS.png'})
BUTTON_GG_EXIT_POS = Button(area={'cn': (1224, 18, 1264, 56), 'en': (1224, 18, 1264, 56), 'jp': (1224, 18, 1264, 56), 'tw': (1224, 18, 1264, 56)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1224, 18, 1264, 56), 'en': (1224, 18, 1264, 56), 'jp': (1224, 18, 1264, 56), 'tw': (1224, 18, 1264, 56)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_EXIT_POS.png', 'en': './assets/cn/gg_handler/BUTTON_GG_EXIT_POS.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_EXIT_POS.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_EXIT_POS.png'})
BUTTON_GG_RESTART_ERROR = Button(area={'cn': (337, 310, 459, 351), 'en': (337, 310, 459, 351), 'jp': (337, 310, 459, 351), 'tw': (337, 310, 459, 351)}, color={'cn': (96, 96, 96), 'en': (96, 96, 96), 'jp': (96, 96, 96), 'tw': (96, 96, 96)}, button={'cn': (337, 310, 459, 351), 'en': (337, 310, 459, 351), 'jp': (337, 310, 459, 351), 'tw': (337, 310, 459, 351)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_RESTART_ERROR.png', 'en': './assets/cn/gg_handler/BUTTON_GG_RESTART_ERROR.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_RESTART_ERROR.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_RESTART_ERROR.png'})
BUTTON_GG_SCRIPT_END = Button(area={'cn': (1155, 375, 1227, 420), 'en': (1155, 375, 1227, 420), 'jp': (1155, 375, 1227, 420), 'tw': (1155, 375, 1227, 420)}, color={'cn': (85, 85, 85), 'en': (85, 85, 85), 'jp': (85, 85, 85), 'tw': (85, 85, 85)}, button={'cn': (1155, 375, 1227, 420), 'en': (1155, 375, 1227, 420), 'jp': (1155, 375, 1227, 420), 'tw': (1155, 375, 1227, 420)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_END.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_END.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_END.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_END.png'})
BUTTON_GG_SCRIPT_ENTER_CONFIRM = Button(area={'cn': (284, 104, 395, 136), 'en': (284, 104, 395, 136), 'jp': (284, 104, 395, 136), 'tw': (284, 104, 395, 136)}, color={'cn': (112, 112, 112), 'en': (112, 112, 112), 'jp': (112, 112, 112), 'tw': (112, 112, 112)}, button={'cn': (284, 104, 395, 136), 'en': (284, 104, 395, 136), 'jp': (284, 104, 395, 136), 'tw': (284, 104, 395, 136)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_CONFIRM.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_CONFIRM.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_CONFIRM.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_CONFIRM.png'})
BUTTON_GG_SCRIPT_ENTER_POS = Button(area={'cn': (1225, 127, 1269, 170), 'en': (1225, 127, 1269, 170), 'jp': (1225, 127, 1269, 170), 'tw': (1225, 127, 1269, 170)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1225, 127, 1269, 170), 'en': (1225, 127, 1269, 170), 'jp': (1225, 127, 1269, 170), 'tw': (1225, 127, 1269, 170)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_POS.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_POS.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_POS.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_ENTER_POS.png'})
BUTTON_GG_SCRIPT_FATAL = Button(area={'cn': (63, 622, 117, 655), 'en': (63, 622, 117, 655), 'jp': (63, 622, 117, 655), 'tw': (63, 622, 117, 655)}, color={'cn': (100, 100, 100), 'en': (100, 100, 100), 'jp': (100, 100, 100), 'tw': (100, 100, 100)}, button={'cn': (63, 622, 117, 655), 'en': (63, 622, 117, 655), 'jp': (63, 622, 117, 655), 'tw': (63, 622, 117, 655)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_FATAL.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_FATAL.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_FATAL.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_FATAL.png'})
BUTTON_GG_SCRIPT_MENU_A = Button(area={'cn': (344, 289, 449, 320), 'en': (344, 289, 449, 320), 'jp': (344, 289, 449, 320), 'tw': (344, 289, 449, 320)}, color={'cn': (113, 113, 113), 'en': (113, 113, 113), 'jp': (113, 113, 113), 'tw': (113, 113, 113)}, button={'cn': (344, 289, 449, 320), 'en': (344, 289, 449, 320), 'jp': (344, 289, 449, 320), 'tw': (344, 289, 449, 320)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_A.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_A.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_A.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_A.png'})
BUTTON_GG_SCRIPT_MENU_B = Button(area={'cn': (347, 358, 446, 393), 'en': (347, 358, 446, 393), 'jp': (347, 358, 446, 393), 'tw': (347, 358, 446, 393)}, color={'cn': (110, 110, 110), 'en': (110, 110, 110), 'jp': (110, 110, 110), 'tw': (110, 110, 110)}, button={'cn': (347, 358, 446, 393), 'en': (347, 358, 446, 393), 'jp': (347, 358, 446, 393), 'tw': (347, 358, 446, 393)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_B.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_B.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_B.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MENU_B.png'})
BUTTON_GG_SCRIPT_MODE_A_CONFIRM = Button(area={'cn': (100, 145, 189, 172), 'en': (100, 145, 189, 172), 'jp': (100, 145, 189, 172), 'tw': (100, 145, 189, 172)}, color={'cn': (114, 114, 114), 'en': (114, 114, 114), 'jp': (114, 114, 114), 'tw': (114, 114, 114)}, button={'cn': (100, 145, 189, 172), 'en': (100, 145, 189, 172), 'jp': (100, 145, 189, 172), 'tw': (100, 145, 189, 172)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_A_CONFIRM.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_A_CONFIRM.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_A_CONFIRM.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_A_CONFIRM.png'})
BUTTON_GG_SCRIPT_MODE_B_CONFIRM = Button(area={'cn': (105, 146, 190, 168), 'en': (105, 146, 190, 168), 'jp': (105, 146, 190, 168), 'tw': (105, 146, 190, 168)}, color={'cn': (127, 127, 127), 'en': (127, 127, 127), 'jp': (127, 127, 127), 'tw': (127, 127, 127)}, button={'cn': (105, 146, 190, 168), 'en': (105, 146, 190, 168), 'jp': (105, 146, 190, 168), 'tw': (105, 146, 190, 168)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_B_CONFIRM.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_B_CONFIRM.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_B_CONFIRM.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_MODE_B_CONFIRM.png'})
BUTTON_GG_SCRIPT_PANEL_NUM0 = Button(area={'cn': (916, 336, 947, 376), 'en': (916, 336, 947, 376), 'jp': (916, 336, 947, 376), 'tw': (916, 336, 947, 376)}, color={'cn': (59, 69, 74), 'en': (59, 69, 74), 'jp': (59, 69, 74), 'tw': (59, 69, 74)}, button={'cn': (916, 336, 947, 376), 'en': (916, 336, 947, 376), 'jp': (916, 336, 947, 376), 'tw': (916, 336, 947, 376)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM0.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM0.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM0.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM0.png'})
BUTTON_GG_SCRIPT_PANEL_NUM1 = Button(area={'cn': (913, 119, 947, 158), 'en': (913, 119, 947, 158), 'jp': (913, 119, 947, 158), 'tw': (913, 119, 947, 158)}, color={'cn': (49, 60, 65), 'en': (49, 60, 65), 'jp': (49, 60, 65), 'tw': (49, 60, 65)}, button={'cn': (913, 119, 947, 158), 'en': (913, 119, 947, 158), 'jp': (913, 119, 947, 158), 'tw': (913, 119, 947, 158)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM1.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM1.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM1.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM1.png'})
BUTTON_GG_SCRIPT_PANEL_NUM2 = Button(area={'cn': (986, 120, 1021, 158), 'en': (986, 120, 1021, 158), 'jp': (986, 120, 1021, 158), 'tw': (986, 120, 1021, 158)}, color={'cn': (55, 66, 71), 'en': (55, 66, 71), 'jp': (55, 66, 71), 'tw': (55, 66, 71)}, button={'cn': (986, 120, 1021, 158), 'en': (986, 120, 1021, 158), 'jp': (986, 120, 1021, 158), 'tw': (986, 120, 1021, 158)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM2.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM2.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM2.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM2.png'})
BUTTON_GG_SCRIPT_PANEL_NUM3 = Button(area={'cn': (1056, 119, 1093, 158), 'en': (1056, 119, 1093, 158), 'jp': (1056, 119, 1093, 158), 'tw': (1056, 119, 1093, 158)}, color={'cn': (55, 65, 70), 'en': (55, 65, 70), 'jp': (55, 65, 70), 'tw': (55, 65, 70)}, button={'cn': (1056, 119, 1093, 158), 'en': (1056, 119, 1093, 158), 'jp': (1056, 119, 1093, 158), 'tw': (1056, 119, 1093, 158)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM3.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM3.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM3.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM3.png'})
BUTTON_GG_SCRIPT_PANEL_NUM4 = Button(area={'cn': (914, 190, 950, 232), 'en': (914, 190, 950, 232), 'jp': (914, 190, 950, 232), 'tw': (914, 190, 950, 232)}, color={'cn': (54, 65, 70), 'en': (54, 65, 70), 'jp': (54, 65, 70), 'tw': (54, 65, 70)}, button={'cn': (914, 190, 950, 232), 'en': (914, 190, 950, 232), 'jp': (914, 190, 950, 232), 'tw': (914, 190, 950, 232)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM4.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM4.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM4.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM4.png'})
BUTTON_GG_SCRIPT_PANEL_NUM5 = Button(area={'cn': (981, 192, 1025, 232), 'en': (981, 192, 1025, 232), 'jp': (981, 192, 1025, 232), 'tw': (981, 192, 1025, 232)}, color={'cn': (52, 63, 68), 'en': (52, 63, 68), 'jp': (52, 63, 68), 'tw': (52, 63, 68)}, button={'cn': (981, 192, 1025, 232), 'en': (981, 192, 1025, 232), 'jp': (981, 192, 1025, 232), 'tw': (981, 192, 1025, 232)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM5.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM5.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM5.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM5.png'})
BUTTON_GG_SCRIPT_PANEL_NUM6 = Button(area={'cn': (1056, 191, 1097, 231), 'en': (1056, 191, 1097, 231), 'jp': (1056, 191, 1097, 231), 'tw': (1056, 191, 1097, 231)}, color={'cn': (53, 64, 69), 'en': (53, 64, 69), 'jp': (53, 64, 69), 'tw': (53, 64, 69)}, button={'cn': (1056, 191, 1097, 231), 'en': (1056, 191, 1097, 231), 'jp': (1056, 191, 1097, 231), 'tw': (1056, 191, 1097, 231)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM6.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM6.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM6.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM6.png'})
BUTTON_GG_SCRIPT_PANEL_NUM7 = Button(area={'cn': (910, 262, 950, 303), 'en': (910, 262, 950, 303), 'jp': (910, 262, 950, 303), 'tw': (910, 262, 950, 303)}, color={'cn': (48, 59, 65), 'en': (48, 59, 65), 'jp': (48, 59, 65), 'tw': (48, 59, 65)}, button={'cn': (910, 262, 950, 303), 'en': (910, 262, 950, 303), 'jp': (910, 262, 950, 303), 'tw': (910, 262, 950, 303)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM7.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM7.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM7.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM7.png'})
BUTTON_GG_SCRIPT_PANEL_NUM8 = Button(area={'cn': (987, 263, 1021, 304), 'en': (987, 263, 1021, 304), 'jp': (987, 263, 1021, 304), 'tw': (987, 263, 1021, 304)}, color={'cn': (59, 69, 74), 'en': (59, 69, 74), 'jp': (59, 69, 74), 'tw': (59, 69, 74)}, button={'cn': (987, 263, 1021, 304), 'en': (987, 263, 1021, 304), 'jp': (987, 263, 1021, 304), 'tw': (987, 263, 1021, 304)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM8.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM8.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM8.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM8.png'})
BUTTON_GG_SCRIPT_PANEL_NUM9 = Button(area={'cn': (1053, 266, 1098, 301), 'en': (1053, 266, 1098, 301), 'jp': (1053, 266, 1098, 301), 'tw': (1053, 266, 1098, 301)}, color={'cn': (54, 65, 70), 'en': (54, 65, 70), 'jp': (54, 65, 70), 'tw': (54, 65, 70)}, button={'cn': (1053, 266, 1098, 301), 'en': (1053, 266, 1098, 301), 'jp': (1053, 266, 1098, 301), 'tw': (1053, 266, 1098, 301)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM9.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM9.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM9.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_PANEL_NUM9.png'})
BUTTON_GG_SCRIPT_START = Button(area={'cn': (906, 557, 965, 596), 'en': (906, 557, 965, 596), 'jp': (906, 557, 965, 596), 'tw': (906, 557, 965, 596)}, color={'cn': (87, 87, 87), 'en': (87, 87, 87), 'jp': (87, 87, 87), 'tw': (87, 87, 87)}, button={'cn': (906, 557, 965, 596), 'en': (906, 557, 965, 596), 'jp': (906, 557, 965, 596), 'tw': (906, 557, 965, 596)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START.png'})
BUTTON_GG_SCRIPT_START_PROCESS = Button(area={'cn': (1088, 561, 1147, 599), 'en': (1088, 561, 1147, 599), 'jp': (1088, 561, 1147, 599), 'tw': (1088, 561, 1147, 599)}, color={'cn': (93, 93, 93), 'en': (93, 93, 93), 'jp': (93, 93, 93), 'tw': (93, 93, 93)}, button={'cn': (1088, 561, 1147, 599), 'en': (1088, 561, 1147, 599), 'jp': (1088, 561, 1147, 599), 'tw': (1088, 561, 1147, 599)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START_PROCESS.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START_PROCESS.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START_PROCESS.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SCRIPT_START_PROCESS.png'})
BUTTON_GG_SEARCH_MODE_CONFIRM = Button(area={'cn': (337, 68, 605, 73), 'en': (337, 68, 605, 73), 'jp': (337, 68, 605, 73), 'tw': (337, 68, 605, 73)}, color={'cn': (77, 122, 119), 'en': (77, 122, 119), 'jp': (77, 122, 119), 'tw': (77, 122, 119)}, button={'cn': (337, 68, 605, 73), 'en': (337, 68, 605, 73), 'jp': (337, 68, 605, 73), 'tw': (337, 68, 605, 73)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_SEARCH_MODE_CONFIRM.png', 'en': './assets/cn/gg_handler/BUTTON_GG_SEARCH_MODE_CONFIRM.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_SEARCH_MODE_CONFIRM.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_SEARCH_MODE_CONFIRM.png'})
BUTTON_GG_TAB_SEARCH_POS = Button(area={'cn': (445, 11, 491, 59), 'en': (445, 11, 491, 59), 'jp': (445, 11, 491, 59), 'tw': (445, 11, 491, 59)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (445, 11, 491, 59), 'en': (445, 11, 491, 59), 'jp': (445, 11, 491, 59), 'tw': (445, 11, 491, 59)}, file={'cn': './assets/cn/gg_handler/BUTTON_GG_TAB_SEARCH_POS.png', 'en': './assets/cn/gg_handler/BUTTON_GG_TAB_SEARCH_POS.png', 'jp': './assets/cn/gg_handler/BUTTON_GG_TAB_SEARCH_POS.png', 'tw': './assets/cn/gg_handler/BUTTON_GG_TAB_SEARCH_POS.png'})
OCR_PRE_BATTLE_CHECK = Button(area={'cn': (736, 518, 979, 582), 'en': (736, 518, 979, 582), 'jp': (736, 518, 979, 582), 'tw': (736, 518, 979, 582)}, color={'cn': (90, 100, 119), 'en': (90, 100, 119), 'jp': (90, 100, 119), 'tw': (90, 100, 119)}, button={'cn': (736, 518, 979, 582), 'en': (736, 518, 979, 582), 'jp': (736, 518, 979, 582), 'tw': (736, 518, 979, 582)}, file={'cn': './assets/cn/gg_handler/OCR_PRE_BATTLE_CHECK.png', 'en': './assets/cn/gg_handler/OCR_PRE_BATTLE_CHECK.png', 'jp': './assets/cn/gg_handler/OCR_PRE_BATTLE_CHECK.png', 'tw': './assets/cn/gg_handler/OCR_PRE_BATTLE_CHECK.png'})

View File

@@ -0,0 +1,80 @@
from module.logger import logger
from module.config.config import deep_get
from module.base.base import ModuleBase
import uiautomator2 as u2
class ChangeAttribute(ModuleBase):
def __init__(self, config, device):
super().__init__(config, device)
self.d = u2.connect(self.device.serial)
self.gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
def GetShipData(self):
DataList: str = deep_get(self.config.data, "GameManager.ChangeAttribute.ShipData").split("\n")
DataString = "|".join(DataList)
return DataString
def PushLua(self):
IsPush = deep_get(self.config.data, keys='GameManager.ChangeAttribute.PushLua')
if IsPush:
self.device.adb_shell("mkdir /sdcard/Notes")
self.device.sleep(0.5)
self.device.adb_shell("rm /sdcard/Notes/ShipFucker.lua")
self.device.sleep(0.5)
self.device.adb_push("bin/Lua/ShipFucker.lua", "/sdcard/Notes/ShipFucker.lua")
self.device.sleep(0.5)
logger.info('Lua Pushed')
def ChangeAttribute(self):
if not deep_get(self.config.data, "GameManager.ChangeAttribute.Enable"):
return 0
_set = False
_confirmed = False
while 1:
if self.d(resourceId=f"{self.gg_package_name}:id/search_toolbar").exists:
self.d.xpath(
f'//*[@resource-id="{self.gg_package_name}'
f':id/search_toolbar"]/android.widget.ImageView[last()]'
).click()
self.device.sleep(1)
if self.d(resourceId=f"{self.gg_package_name}:id/file").exists:
self.d(resourceId=f"{self.gg_package_name}:id/file").send_keys("/sdcard/Notes/ShipFucker.lua")
logger.info('Lua path set')
if self.d.xpath('//*[@text="执行"]').exists:
self.d.xpath('//*[@text="执行"]').click()
logger.info('Click Run')
self.device.sleep(0.5)
if self.d.xpath('//*[contains(@text,"改属性")]').exists:
self.d.xpath('//*[contains(@text,"改属性")]').click()
logger.info('Click Change Statistic')
self.device.sleep(0.5)
if self.d(resourceId=f"{self.gg_package_name}:id/edit").exists:
ShipDataString = self.GetShipData()
self.d(resourceId=f"{self.gg_package_name}:id/edit")[0].send_keys(ShipDataString)
self.device.sleep(0.5)
_set = True
if _set and self.d.xpath('//*[@text="确定"]').exists:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
self.device.sleep(0.5)
_confirmed = True
if _confirmed:
self.d.wait_timeout = deep_get(self.config.data, "GameManager.ChangeAttribute.Timeout")
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
try:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
self.device.sleep(0.5)
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
except Exception as e:
pass
self.d.wait_timeout = 3
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
break
else:
return 0

View File

@@ -0,0 +1,138 @@
from enum import Enum
from uiautomator2 import UiObjectNotFoundError
from module.logger import logger
from module.gg_handler.gg_data import GGData
from module.config.config import deep_get
from module.base.base import ModuleBase
import uiautomator2 as u2
class ShipData:
def __init__(self, DataStr: str):
DataList = DataStr.split(";")
self.ShipId = DataList[0]
self.Rarity = DataList[1]
self.Star = DataList[2]
self.ShipType = DataList[3]
self.TargetType = DataList[4]
class ChangeShip(ModuleBase):
def __init__(self, config, device):
super().__init__(config, device)
self.d = u2.connect(self.device.serial)
self.gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
def GetShipData(self):
DataList = list()
vanguard_setting = deep_get(self.config.data, keys='GameManager.ChangeShip.Vanguard')
capitalship_setting = deep_get(self.config.data, keys='GameManager.ChangeShip.CapitalShip')
_to_split = ""
if vanguard_setting == "downes_and_cassin_to_ca":
_to_split = "\n101041;2;1;1;3\n101031;2;1;1;3\n"
elif vanguard_setting == "downes_and_cassin_to_cl":
_to_split = "\n101041;2;1;1;2\n101031;2;1;1;2\n"
elif vanguard_setting == "custom" and capitalship_setting != "custom":
_to_split = deep_get(self.config.data, "GameManager.ChangeShip.ShipData")
if capitalship_setting == "cvl_to_bc":
_to_split += "\n106021;2;1;6;4\n107041;2;1;6;4\n206011;2;1;6;4\n107011;2;1;6;4\n\n105011;2;1;5;19\n105021;2;1;5;19\n"
elif capitalship_setting == "cvl_to_bb":
_to_split += "\n106021;2;1;6;5\n107041;2;1;6;5\n206011;2;1;6;5\n107011;2;1;6;5\n\n105011;2;1;5;19\n105021;2;1;5;19\n"
elif capitalship_setting == "cvl_to_cv":
_to_split += "\n106021;2;1;6;7\n107041;2;1;6;7\n206011;2;1;6;7\n107011;2;1;6;7\n"
elif capitalship_setting == "custom":
_to_split += deep_get(self.config.data, "GameManager.ChangeShip.ShipData")
for i in _to_split.split("\n"):
if i:
DataList.append(ShipData(i))
return DataList
def PushLua(self):
IsPush = deep_get(self.config.data, keys='GameManager.ChangeShip.PushLua')
if IsPush:
self.device.adb_shell("mkdir /sdcard/Notes")
self.device.sleep(0.5)
self.device.adb_shell("rm /sdcard/Notes/ShipChanger.lua")
self.device.sleep(0.5)
self.device.adb_push("bin/Lua/ShipChanger.lua", "/sdcard/Notes/ShipChanger.lua")
self.device.sleep(0.5)
logger.info('Lua Pushed')
def ChangeShipType(self):
if not deep_get(self.config.data, "GameManager.ChangeShip.Enable"):
return 0
HARDMODEMAPS = [
'd1', 'd2', 'd3',
'ht4', 'ht5', 'ht6',
]
if not self.config.is_task_enabled("GemsFarming") or deep_get(self.config.data,
"GemsFarming.Campaign.Name").lower() not in HARDMODEMAPS:
return 0
_set = False
_confirmed = False
while 1:
if self.d(resourceId=f"{self.gg_package_name}:id/search_toolbar").exists:
self.d.xpath(
f'//*[@resource-id="{self.gg_package_name}'
f':id/search_toolbar"]/android.widget.ImageView[last()]'
).click()
self.device.sleep(1)
if self.d(resourceId=f"{self.gg_package_name}:id/file").exists:
self.d(resourceId=f"{self.gg_package_name}:id/file").send_keys("/sdcard/Notes/ShipChanger.lua")
logger.info('Lua path set')
if self.d.xpath('//*[@text="执行"]').exists:
self.d.xpath('//*[@text="执行"]').click()
logger.info('Click Run')
self.device.sleep(0.5)
if self.d.xpath('//*[contains(@text,"改船")]').exists:
self.d.xpath('//*[contains(@text,"改船")]').click()
logger.info('Click Change Statistic')
self.device.sleep(0.5)
if self.d(resourceId=f"{self.gg_package_name}:id/edit").exists:
ShipDataList = self.GetShipData()
ShipIdStr = ";".join([str(i.ShipId) for i in ShipDataList])
ShipRarityStr = ";".join([str(i.Rarity) for i in ShipDataList])
ShipStarStr = ";".join([str(i.Star) for i in ShipDataList])
CurrentShipTypeStr = ";".join([str(i.ShipType) for i in ShipDataList])
TargetShipTypeStr = ";".join([str(i.TargetType) for i in ShipDataList])
while 1:
try:
self.d(resourceId=f"{self.gg_package_name}:id/edit")[0].send_keys(ShipIdStr)
self.d(resourceId=f"{self.gg_package_name}:id/edit")[1].send_keys(ShipRarityStr)
self.d(resourceId=f"{self.gg_package_name}:id/edit")[2].send_keys(ShipStarStr)
self.d(resourceId=f"{self.gg_package_name}:id/edit")[3].send_keys(CurrentShipTypeStr)
self.d(resourceId=f"{self.gg_package_name}:id/edit")[4].send_keys(TargetShipTypeStr)
break
except UiObjectNotFoundError:
self.d(className="android.widget.ScrollView")[0].scroll.toEnd()
self.device.sleep(0.5)
_set = True
if _set and self.d.xpath('//*[@text="确定"]').exists:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
self.device.sleep(0.5)
_confirmed = True
if _confirmed:
self.d.wait_timeout = deep_get(self.config.data, "GameManager.ChangeShip.Timeout")
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
try:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
self.device.sleep(0.5)
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
except Exception as e:
pass
self.d.wait_timeout = 3
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
break
else:
return 0

172
module/gg_handler/gg_adb.py Normal file
View File

@@ -0,0 +1,172 @@
# import subprocess
#
# from module.logger import logger
# from module.gg_handler.gg_data import GGData
# from module.config.config import deep_get
# from module.base.base import ModuleBase as Base
# from module.base.utils import point2str, random_rectangle_point
# from module.device.method.adb import Adb
# from module.device.method.utils import (RETRY_TRIES, retry_sleep,
# HierarchyButton, handle_adb_error)
# from module.exception import GameStuckError
#
# class GGADB(Adb):
#
# def __init__(self, config):
# super().__init__(config)
# self.factor = 200
# self.config = config
# self.adb_reconnect()
# self.gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
#
# def appear(self, xpath):
# return bool(HierarchyButton(self.h, xpath))
#
# def appear_then_click(self, xpath):
# b = HierarchyButton(self.h, xpath)
# if b:
# point = random_rectangle_point(b.button)
# logger.info(f'Click {point2str(*point)} @ {b}')
# self.click_adb(*point)
# return True
# else:
# return False
#
# def exit(self):
# self.app_stop_adb(f'{self.gg_package_name}')
# logger.attr('GG', 'Killed')
#
# def skip_error(self):
# _skipped = 0
# self.h = self.dump_hierarchy_adb()
# if self.appear('//*[@text="重启游戏"]'):
# _skipped = 1
# logger.hr('Game died with GG panel')
# logger.info('No matter GG panel exists or not, Kill GG')
# self.exit()
# return _skipped
#
# def set_on(self, factor=200):
# self.factor = factor
# ggdata = GGData(self.config).get_data()
# for _i in range(1):
# try:
# if ggdata['gg_on']:
# logger.attr('GG', 'Enabled')
# pass
# else:
# chosen = False
# self.h = self.dump_hierarchy_adb()
# if self.appear_then_click(f'//*[@resource-id="com.ucr.tx:id/hot_frame"]'):
# logger.info('Open GG panel')
# Base.device.sleep(0.5)
# else:
# self.app_start_adb(self.gg_package_name)
# logger.info('Starting GG')
# logger.info('In GG overview')
# Base.device.sleep(3)
# while 1:
# Base.device.sleep(0.5)
# self.h = self.dump_hierarchy_adb()
# if self.appear_then_click('//*[@text="忽略"]'):
# logger.info("Click ignore")
# continue
# if self.appear_then_click(f'//*[@resource-id="{self.gg_package_name}:id/btn_start_usage"]'):
# logger.info('Click GG start button')
# logger.attr('GG', 'Started')
# continue
# if self.appear_then_click(f'//*[@resource-id="{self.gg_package_name}:id/hot_point_icon"]'):
# logger.info('Open GG panel')
# continue
# if self.appear(f'//*[@resource-id="{self.gg_package_name}:id/search_tab"]') \
# and not self.appear(f'//*[@resource-id="{self.gg_package_name}:id/search_toolbar"]'):
# self.appear_then_click(f'//*[@resource-id="{self.gg_package_name}:id/search_tab"]')
# logger.info('Switch to search tab')
# continue
# if self.appear_then_click(
# f'//*[@package="{self.gg_package_name}" '
# f'and @resource-id="android:id/text1" '
# f'and contains(@text,"碧蓝航线")]'
# ):
# logger.info('Choose APP: AzurLane')
# chosen = True
# continue
# if not chosen and self.appear(f'//*[@resource-id="{self.gg_package_name}:id/app_icon"]'):
# self.appear_then_click(f'//*[@resource-id="{self.gg_package_name}:id/app_icon"]')
# logger.info('Click APP choosing tag')
# continue
# if self.appear(f'//*[@resource-id="{self.gg_package_name}:id/search_toolbar"]'):
# self.appear_then_click(f'//*[@resource-id="{self.gg_package_name}:id/search_toolbar"]/'
# f'android.widget.ImageView[last()]'
# )
# logger.info('Click run Scripts')
# if self._run():
# return 1
# if self.appear_then_click('//*[@text="取消"]'):
# logger.info("Cancel exists but not running script, click cancel")
# continue
# if self.appear_then_click('//*[@text="确定"]'):
# # and self.d.xpath('//*[contains(@text,"脚本已结束")]').exists:
# logger.info("Confirm exists but script crashed, click confirm")
# continue
# if self.appear_then_click('//*[@text="重启游戏"]'):
# logger.info('GG Panel after game died exists, restart the game')
# logger.info('Click Restart')
# continue
# finally:
# pass
#
# def _run(self):
# _run = 0
# _set = 0
# _confirmed = 0
# while 1:
# self.h = self.dump_hierarchy_adb()
# if self.appear(f'//*[@resource-id="{self.gg_package_name}:id/file"]'):
# self.adb_shell(['input', 'text', "/sdcard/Notes/Multiplier.lua"])
# logger.info('Lua path set')
# import os
# _pop = os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" '
# f'-s {self.device.serial} shell mkdir /sdcard/Notes')
# _pop = os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" '
# f'-s {self.device.serial} shell rm /sdcard/Notes/Multiplier.lua')
# _pop = os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" '
# f'-s {self.device.serial} push "Multiplier.lua" /sdcard/Notes/Multiplier.lua')
# Base.device.sleep(0.5)
# if self.appear_then_click('//*[@text="执行"]'):
# logger.info('Click Run')
# Base.device.sleep(0.5)
# if self.appear_then_click('//*[contains(@text,"修改面板")]'):
# logger.info('Click Change Statistic')
# if self.appear_then_click(f'//*[@resource-id="{self.gg_package_name}:id/edit"]'):
# logger.info('Factor Set')
# Base.device.sleep(0.5)
# _set = 1
# if _set and self.appear('//*[@text="确定"]'):
# self.appear_then_click('//*[@text="确定"]')
# logger.info("Click confirm")
# Base.device.sleep(0.5)
# _confirmed = 1
#
# from module.base.timer import Timer
# timeout = Timer(90, count=90).start()
# if _set and _confirmed:
# try:
# while 1:
# if self.appear_then_click('//*[@text="确定"]'):
# GGData(self.config).set_data(target='gg_on', value=True)
# break
# if timeout.reached():
# raise GameStuckError
# finally:
# pass
# GGData(self.config).set_data(target='gg_on', value='True')
# logger.attr('GG', 'Enabled')
# logger.info("Close the script")
# if _set and _confirmed:
# break
# else:
# return 0
# logger.hr('GG Enabled', level=2)
# self.app_stop_adb(self.gg_package_name)
# return 1

View File

@@ -0,0 +1,85 @@
from module.config.config import deep_get
from module.base.base import ModuleBase
class GGData(ModuleBase):
gg_on = False
gg_enable = False
gg_auto = False
gg_type = False
ggdata = {}
def __init__(self, config=None):
self.config = config
import os
if not os.path.exists('./config/gg_handler'):
os.mkdir('./config/gg_handler')
with open(file=f'./config/gg_handler/gg_data_{self.config.config_name}.tmp',
mode='a+',
encoding='utf-8') as tmp:
tmp.close()
tmp = open(file=f'./config/gg_handler/gg_data_{self.config.config_name}.tmp',
mode='r',
encoding='utf-8')
line = tmp.readline()
if line[:-1] != self.config.config_name:
tmp.close()
tmp = open(file=f'./config/gg_handler/gg_data_{self.config.config_name}.tmp',
mode='w',
encoding='utf-8')
tmp.write(f'{self.config.config_name}\n')
tmp.write('gg_on=False\n')
self.ggdata['gg_on'] = False
self.ggdata['gg_type'] = False
self.ggdata['gg_enable'] = deep_get(d=self.config.data,
keys='GameManager.GGHandler.Enabled',
default=False)
self.ggdata['gg_auto'] = deep_get(d=self.config.data,
keys='GameManager.GGHandler.AutoRestartGG',
default=False)
tmp.write('gg_enable=' + str(self.ggdata['gg_enable']) + '\n')
tmp.write('gg_auto=' + str(self.ggdata['gg_auto']) + '\n')
tmp.write('gg_type=' + str(self.ggdata['gg_type']) + '\n')
tmp.close()
else:
for i in range(4):
line = tmp.readline()
if i == 3 and line == '':
line = 'gg_type=False\n'
line1, line2 = line.split('=')
self.ggdata[line1] = True if line2[:-1] == 'True' else False
tmp.close()
def get_data(self):
# Return a dict of data
return self.ggdata
def set_data(self, target=None, value=None):
self.target = target
self.value = value
self.ggdata[self.target] = self.value
self.update_data()
def update_data(self):
with open(file=f'./config/gg_handler/gg_data_{self.config.config_name}.tmp',
mode='w',
encoding='utf-8') as tmp:
tmp.write(f'{self.config.config_name}\n')
for t in self.ggdata:
tmp.write(t + '=' + str(self.ggdata[t]) + '\n')
tmp.close()
def dele(self):
with open(file=f'./config/gg_handler/gg_data_{self.config.config_name}.tmp',
mode='w',
encoding='utf-8') as tmp:
tmp.write('啊吧啊吧')
tmp.close()
# if __name__ == '__main__':
# config = AzurLaneConfig(config_name='alas')
# print(gg_data(config).get_data())
# gg_data(config=config, target='gg_on', value=True).set_data()
# print(gg_data(config).get_data())
# gg_data().dele()

View File

@@ -0,0 +1,393 @@
from module.gg_handler.gg_data import GGData
from module.gg_handler.gg_u2 import GGU2
# from module.gg_handler.gg_screenshot import GGScreenshot
from module.config.deep import deep_get, deep_set
from module.logger import logger
from module.base.timer import timeout
from module.config.full_config import AzurLaneFullConfig
class GGHandler:
"""
A module to handle needs of cheaters
Args:
config: AzurlaneConfig
device: Device
"""
def __init__(self, config=None, device=None):
self.task = ''
self.config = config
self.device = device
self.factor = deep_get(self.config.data,
'GameManager.GGHandler.GGMultiplyingFactor',
default=200)
self.method = deep_get(self.config.data,
'GameManager.GGHandler.GGMethod',
default='screenshot')
ggu2 = GGU2(config=self.config, device=self.device)
self.GGData = GGData(config=self.config)
self.gg = ggu2
lua_enable = deep_get(d=self.config.data, keys='Hook.HookGeneral.Enable', default=False)
if lua_enable:
self.GGData.set_data('gg_enable', False)
logger.info('LuaHook enabled, ignoring GG')
def restart(self, crashed=False):
from module.handler.login import LoginHandler
from module.exception import GameStuckError
_crashed = crashed
for _ in range(2):
try:
if _crashed:
timeout(self.handle_u2_restart, timeout_sec=60)
if not timeout(LoginHandler(config=self.config, device=self.device).app_restart, timeout_sec=600):
break
raise RuntimeError
except GameStuckError as e:
pass
except Exception as e:
logger.exception(e)
if _crashed:
logger.critical('Maybe your emulator died, trying to restart it')
self.device.emulator_start()
_crashed = True
def set(self, mode=True):
"""
Set the GG status to True/False.
Args:
mode: bool
"""
gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
if mode:
logger.hr('Enabling GG')
# if self.method == 'screenshot' or gg_package_name == 'com.':
# GGScreenshot(config=self.config, device=self.device) \
# .gg_set(mode=True, factor=self.factor)
# elif self.method == 'u2':
# GGU2(config=self.config, device=self.device) \
# .set_on(factor=self.factor)
self.handle_u2_restart()
success = self.change_attribute()
success = self.multiplier() and success
success = self.speed_up() and success
# if not success:
# from module.exception import GameStuckError
# raise GameStuckError
# Not support screenshot anymore
else:
self.gg_reset()
def skip_error(self) -> bool:
"""
Close all the windows of GG.
Often to be used when game restarts with GG enabled.
Returns:
bool: Whether GG error panel occurs
"""
gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
# if self.method == 'screenshot' or gg_package_name == 'com.':
# return \
# GGScreenshot(config=self.config, device=self.device).skip_error()
# elif self.method == 'u2':
# return \
# GGU2(config=self.config, device=self.device).skip_error()
return self.gg.skip_error() # Not support screenshot anymore
def check_config(self) -> dict:
"""
Reset GG config to the user's config and return gg_data.
Returns:
gg_data: dict = {
'gg_enable' : bool = Whether GG manager enabled,
'gg_auto' : bool = Whether to start GG before tasks,
'gg_on' : bool = Whether multiplier is on now}
"""
gg_enable = deep_get(d=self.config.data, keys='GameManager.GGHandler.Enabled', default=False)
gg_auto = deep_get(d=self.config.data, keys='GameManager.GGHandler.AutoRestartGG', default=False)
lua_enable = deep_get(d=self.config.data, keys='Hook.HookGeneral.Enable', default=False)
if lua_enable:
gg_enable = False
logger.info('LuaHook enabled, ignoring GG')
self.GGData.set_data(target='gg_enable', value=gg_enable)
self.GGData.set_data(target='gg_auto', value=gg_auto)
gg_data = self.GGData.get_data()
logger.info(f'GG status:')
logger.info(
f'Enabled={gg_data["gg_enable"]} AutoRestart={gg_data["gg_auto"]} Current stage={gg_data["gg_on"]} Type Changed={gg_data["gg_type"]}')
return gg_data
def handle_u2_restart(self):
_need_restart_atx = deep_get(d=self.config.data, keys='GameManager.GGHandler.RestartATX')
if _need_restart_atx:
try:
timeout(self.device.restart_atx, 60)
except Exception:
logger.critical('Maybe your emulator died, trying to restart it')
self.device.emulator_start()
import uiautomator2 as u2
logger.info('Reset UiAutomator')
try:
u2.connect(self.device.serial).reset_uiautomator()
except Exception:
logger.critical('Maybe your emulator died, trying to restart it')
self.device.emulator_start()
def handle_restart(self):
"""
Handle the restart errors of GG.
"""
gg_data = self.GGData.get_data()
gg_enable = gg_data['gg_enable']
if gg_enable:
self.GGData.set_data(target='gg_on', value=False)
self.GGData.set_data(target='gg_type', value=False)
logger.info(f'GG status:')
logger.info(
f'Enabled={gg_data["gg_enable"]} AutoRestart={gg_data["gg_auto"]} Current stage={gg_data["gg_on"]} Type Changed={gg_data["gg_type"]}')
if not self.skip_error():
logger.hr('Assume game died without GG panel')
def gg_reset(self):
"""
Force restart the game to reset GG status to False
"""
gg_data = self.GGData.get_data()
if gg_data['gg_enable'] and gg_data['gg_on']:
logger.hr('Disabling GG')
self.restart()
logger.attr('GG', 'Disabled')
def check_status(self, mode=True):
"""
A check before a task begins to decide whether to enable GG and set it.
Args:
mode: The multiplier status when finish the check.
"""
gg_data = self.GGData.get_data()
if gg_data['gg_enable']:
gg_auto = mode if deep_get(d=self.config.data,
keys='GameManager.GGHandler.AutoRestartGG',
default=False) else False
logger.info(f'Check GG status:')
logger.info(
f'Enabled={gg_data["gg_enable"]} AutoRestart={gg_data["gg_auto"]} Current stage={gg_data["gg_on"]} '
f'Type Changed={gg_data["gg_type"]}')
if gg_auto:
if not gg_data['gg_on']:
self.set(True)
if not gg_data['gg_type']:
self.change_ship_type(task=self.task)
self.gg.exit()
elif gg_data['gg_on']:
self.gg_reset()
def power_limit(self, task=''):
"""
Forced final check before some dangerous tasks for cheaters.
If power is too high, disable the multiplier and assume the user need GG to be Enabled before the other tasks.
Args:
task: str = What task it is to limit power, default limit is 17000 for front ships.
"""
full_config: AzurLaneFullConfig = self.config.full_config
if not full_config.PowerLimit_PowerLimit_Enable:
return
from module.gg_handler.assets import OCR_PRE_BATTLE_CHECK
from module.ocr.ocr import Digit
self.device.screenshot()
OCR_CHECK = Digit(OCR_PRE_BATTLE_CHECK, letter=(255, 255, 255), threshold=128)
ocr = OCR_CHECK.ocr(self.device.image)
from module.config.deep import deep_get
limit = deep_get(self.config.data, keys=f'PowerLimit.PowerLimit.{task}', default=25000)
logger.attr('Power Limit', limit)
if ocr >= limit:
logger.critical('There''s high chance that GG is on, restart to disable it')
from module.gg_handler.gg_data import GGData
self.GGData.set_data(target='gg_on', value=False)
self.GGData.set_data(target='gg_enable', value=True)
deep_set(d=self.config.data, keys='GameManager.GGHandler.Enabled', value=True)
deep_set(d=self.config.data, keys='GameManager.GGHandler.AutoRestartGG', value=True)
self.config.task_call('Restart')
self.config.task_delay(minute=0.5)
self.config.task_stop('Restart for sake of safty')
def handle_restart_before_tasks(self) -> bool:
"""
Check if user need to restart everytime alas starts before tasks, and handle it.
Returns:
bool: If it needs restart first
"""
gg_data = self.GGData.get_data()
if (deep_get(d=self.config.data,
keys='GameManager.GGHandler.RestartEverytime',
default=True)
and gg_data['gg_enable']):
logger.info('Restart to reset GG status.')
self.restart()
return True
return False
def check_then_set_gg_status(self, task=''):
"""
If task is in list _disabled or _group_enabled defined in this function,
set gg to the defined status
Args:
task : str = the next task to run
"""
self.task = task
_disabled_task = deep_get(self.config.data, 'GameManager.GGHandler.DisabledTask')
"""
'disable_all_dangerous_task'
'disable_meta_and_exercise'
'disable_exercise'
'enable_all'
"""
_disabled = [
'minigame'
]
_group_exercise = [
'exercise'
]
_group_meta = [
'opsi_ash_assist',
'opsi_ash_beacon'
]
_group_raid = [
'raid',
'raid_daily',
'coalition',
'coalition_sp'
]
_group_personal_choice = [
'guild'
]
_group_enabled = [
'hard',
'sos',
'war_archives',
'event_a',
'event_b',
'event_c',
'event_d',
'event_sp',
'maritime_escort',
'opsi_explore',
'opsi_daily',
'opsi_obscure',
'opsi_month_boss',
'opsi_abyssal',
'opsi_archive',
'opsi_stronghold',
'opsi_meowfficer_farming',
'opsi_hazard1_leveling',
'opsi_cross_month',
'research_farm',
'research_farm2',
'research_farm3',
'research_farm4',
'research_farm5',
'research_farm6',
'main',
'main2',
'main3',
'main4',
'main5',
'main6',
'event',
'event2',
'event3',
'event4',
'event5',
'event6',
'gems_farming',
'c72_mystery_farming',
'c122_medium_leveling',
'c124_large_leveling',
'hospital'
]
# Handle ignorance
if _disabled_task == 'disable_meta_and_exercise':
_disabled += _group_exercise + _group_meta
_enabled = _group_enabled + _group_raid + _group_personal_choice
elif _disabled_task == 'disable_exercise':
_disabled += _group_exercise
_enabled = _group_enabled + _group_personal_choice + _group_raid + _group_meta
elif _disabled_task == 'enable_all':
_enabled = _group_enabled + _group_personal_choice + _group_raid + _group_meta + _group_exercise
# _disabled = []
elif _disabled_task == 'disable_guild_and_dangerous':
_disabled += _group_exercise + _group_meta + _group_raid + _group_personal_choice
_enabled = _group_enabled
else: # _disabled_task == 'disable_all_dangerous_task':
_disabled += _group_exercise + _group_meta + _group_raid
_enabled = _group_enabled + _group_personal_choice
if task in _disabled:
self.check_status(False)
elif task in _enabled:
self.check_status(True)
def change_ship_type(self, task):
if task == 'gems_farming':
if not deep_get(self.config.data, "GameManager.ChangeShip.Enable"):
return True
HARDMODEMAPS = [
'd1', 'd2', 'd3',
'ht4', 'ht5', 'ht6',
]
if not self.config.is_task_enabled("GemsFarming") or deep_get(self.config.data,
"GemsFarming.Campaign.Name").lower() not in HARDMODEMAPS:
return 0
self._change_ship_type()
return True
return False
def _change_ship_type(self):
logger.hr('GG Ship Type', level=2)
success = timeout(self.gg.set_on,
timeout_sec=deep_get(self.config.data, "GameManager.GGHandler.Timeout"),
func='change_type',
factor=self.factor)
self.GGData.set_data(target='gg_on', value=True)
self.GGData.set_data(target='gg_type', value=True)
# success = self.gg.set_on('change_type')
def change_attribute(self):
if not deep_get(self.config.data, "GameManager.ChangeAttribute.Enable"):
return False
logger.hr('GG Attribute', level=2)
success = timeout(self.gg.set_on,
timeout_sec=deep_get(self.config.data, "GameManager.GGHandler.Timeout"),
func='change_attribute',
factor=self.factor)
self.GGData.set_data(target='gg_on', value=True)
# self.gg.set_on('change_attribute')
return True
def speed_up(self):
if not deep_get(self.config.data, "GameManager.SpeedUp.Enable"):
return False
success = timeout(self.gg.set_on,
timeout_sec=deep_get(self.config.data, "GameManager.GGHandler.Timeout"),
func='speedup',
factor=self.factor)
self.GGData.set_data(target='gg_on', value=True)
# success = self.gg.set_on(factor=self.factor)
return True
def multiplier(self):
logger.hr('GG Multiplier', level=2)
success = timeout(self.gg.set_on,
timeout_sec=deep_get(self.config.data, "GameManager.GGHandler.Timeout"),
func='multiplier',
factor=self.factor)
self.GGData.set_data(target='gg_on', value=True)
# success = self.gg.set_on(factor=self.factor)
return True

View File

@@ -0,0 +1,263 @@
from module.config.deep import deep_get
from module.logger import logger
from module.gg_handler.assets import *
from module.base.base import ModuleBase as Base
from module.gg_handler.gg_data import GGData
class GGScreenshot(Base):
def __init__(self, config, device):
super().__init__(config, device)
self.device = device
self.config = config
self.gg_panel_confirm_time = 5
# self.gg_panel_confirm_time = deep_get(self.config.data, 'GameManager.GGHandler.GGPanelConfirmTime')
def skip_error(self):
"""
Page:
in: Game down error
out: restart
"""
skip_first_screenshot = False
count = 0
logger.attr('Confirm Time', f'{self.gg_panel_confirm_time}S')
times = self.gg_panel_confirm_time * 2
for i in range(times):
skipped = 0
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.5)
self.device.screenshot()
if self.appear(button=BUTTON_GG_RESTART_ERROR, offset=(50, 50)):
logger.hr('Game died with GG panel')
logger.info('Close GG restart error')
self.device.click(BUTTON_GG_RESTART_ERROR)
skipped = 1
count += 1
if count >= 2:
break
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.3)
self.device.screenshot()
if self.appear(button=BUTTON_GG_RESTART_ERROR, offset=(50, 50)):
logger.hr('Game died with GG panel')
logger.info('Close GG restart error')
skipped = 1
self.device.click(BUTTON_GG_RESTART_ERROR)
elif self.appear(button=BUTTON_GG_SCRIPT_END, offset=(50, 50)):
logger.info('Close previous script')
skipped = 1
self.device.click(BUTTON_GG_SCRIPT_END)
elif self.appear(button=BUTTON_GG_SCRIPT_FATAL, offset=(50, 50)):
logger.info('Restart previous script')
skipped = 1
self.device.click(BUTTON_GG_SCRIPT_FATAL)
elif self.appear(button=BUTTON_GG_APP_CHOOSE, offset=(150, 500)):
logger.info('APP choose')
skipped = 1
self.device.click(BUTTON_GG_APP_CHOOSE)
elif self.appear(button=BUTTON_GG_SCRIPT_MENU_A, offset=(50, 50)):
skipped = 1
logger.info('Close previous script')
self.device.click(BUTTON_GG_EXIT_POS)
elif not self.appear(button=BUTTON_GG_CONFIRM, offset=(50, 50)):
logger.hr('GG Panel Disappearance Confirmed')
break
elif self.appear(button=BUTTON_GG_SEARCH_MODE_CONFIRM, offset=(10, 10), threshold=0.999):
logger.info('At GG main panel, click GG exit')
skipped = 1
self.device.click(BUTTON_GG_EXIT_POS)
elif self.appear(button=BUTTON_GG_CONFIRM, offset=(50, 50)) and \
not self.appear(button=BUTTON_GG_CONFIRM, offset=10):
self.device.click(BUTTON_GG_TAB_SEARCH_POS)
skipped = 1
logger.info('Enter search mode')
elif self.appear(button=BUTTON_GG_CONFIRM, offset=10):
logger.info('Unexpected GG page, Try GG exit')
self.device.click(BUTTON_GG_EXIT_POS)
skipped = 1
return skipped
def _enter_gg(self):
"""
Page:
in: any
out: any GG
"""
self.device.click(BUTTON_GG_ENTER_POS)
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.3)
self.device.screenshot()
if self.appear(button=BUTTON_GG_CONFIRM, offset=(50, 50)):
logger.info('Entered GG')
break
self.device.click(BUTTON_GG_ENTER_POS)
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.3)
self.device.screenshot()
if not self.appear(button=BUTTON_GG_APP_CHOOSE, offset=(150, 500)):
from module.ui.assets import BACK_ARROW
self.device.click(BACK_ARROW)
logger.info('Actually APP choosing button')
else:
self.appear_then_click(button=BUTTON_GG_APP_CHOOSE, offset=(150, 500))
logger.info('APP Choose')
break
def _gg_enter_script(self):
"""
Page:
in: any GG
out: GG ready to start script
"""
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.5)
self.device.screenshot()
if self.appear(button=BUTTON_GG_SCRIPT_ENTER_CONFIRM, offset=(50, 50)):
logger.info('GG script ready to start')
break
elif self.appear(button=BUTTON_GG_SCRIPT_END, offset=(50, 50)):
logger.info('Close previous script')
self.device.click(BUTTON_GG_SCRIPT_END)
elif self.appear(button=BUTTON_GG_SCRIPT_FATAL, offset=(50, 50)):
logger.info('Stop previous script')
self.device.click(BUTTON_GG_SCRIPT_FATAL)
elif self.appear(button=BUTTON_GG_APP_CHOOSE, offset=(150, 500)):
logger.info('APP choose')
self.device.click(BUTTON_GG_APP_CHOOSE)
elif self.appear(button=BUTTON_GG_SEARCH_MODE_CONFIRM, offset=(10, 10), threshold=0.95):
self.device.click(BUTTON_GG_SCRIPT_ENTER_POS)
logger.info('Enter script choose')
else:
self.device.click(BUTTON_GG_TAB_SEARCH_POS)
logger.info('Enter search mode')
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.5)
self.device.screenshot()
if self.appear(button=BUTTON_GG_SCRIPT_START, offset=(50, 50)):
self.device.click(BUTTON_GG_SCRIPT_START)
return 1
def _gg_mode(self):
"""
Page:
in: GG Script Menu
out: GG GG input panel
"""
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.5)
self.device.screenshot()
if self.appear(button=BUTTON_GG_SCRIPT_MENU_A, offset=(50, 50), threshold=0.8):
method = [BUTTON_GG_SCRIPT_MENU_B, BUTTON_GG_SCRIPT_MENU_A]
self.device.click(method[int(self._mode)])
break
def _gg_handle_factor(self):
"""
Page:
in: GG input panel
out:factor set(Not ensured yet)
"""
self.wait_until_appear(button=BUTTON_GG_SCRIPT_START_PROCESS, skip_first_screenshot=True)
logger.info(f'Factor={self._factor}')
if self._factor == 200:
logger.info('Skip factor input')
return 0
method = [
BUTTON_GG_SCRIPT_PANEL_NUM0,
BUTTON_GG_SCRIPT_PANEL_NUM1,
BUTTON_GG_SCRIPT_PANEL_NUM2,
BUTTON_GG_SCRIPT_PANEL_NUM3,
BUTTON_GG_SCRIPT_PANEL_NUM4,
BUTTON_GG_SCRIPT_PANEL_NUM5,
BUTTON_GG_SCRIPT_PANEL_NUM6,
BUTTON_GG_SCRIPT_PANEL_NUM7,
BUTTON_GG_SCRIPT_PANEL_NUM8,
BUTTON_GG_SCRIPT_PANEL_NUM9,
]
for i in str(self._factor):
self.appear_then_click(button=method[int(i)], offset=(50, 50))
self.device.sleep(0.5)
logger.info('Input success')
def _gg_script_run(self):
"""
Page:
in: GG factor set
out: GG Menu
"""
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.5)
self.device.screenshot()
if self.appear_then_click(button=BUTTON_GG_SCRIPT_START_PROCESS, offset=(50, 50), threshold=0.9):
break
logger.info('Waiting for end')
skip_first_screenshot = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.sleep(0.5)
self.device.screenshot()
if self.appear_then_click(button=BUTTON_GG_SCRIPT_END, offset=(50, 50), threshold=0.9):
return 1
def gg_set(self, mode=True, factor=200):
import os
os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
f' {self.device.serial} shell mkdir /sdcard/Notes')
self.device.sleep(0.5)
os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
f' {self.device.serial} shell rm /sdcard/Notes/Multiplier.lua')
self.device.sleep(0.5)
os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
f' {self.device.serial} push "bin/Lua/Multiplier.lua" /sdcard/Notes/Multiplier.lua')
self.device.sleep(0.5)
logger.info('Lua Pushed')
# self._gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
# if self._gg_package_name != 'com.':
# os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
# f' {self.device.serial} shell am start -n {self._gg_package_name}')
self._mode = mode
self._factor = factor
self._enter_gg()
self._gg_enter_script()
self._gg_mode()
self._gg_handle_factor()
self._gg_script_run()
GGData(self.config).set_data(target='gg_on', value=self._mode)
self.skip_error()
logger.attr('GG', 'Enabled')

258
module/gg_handler/gg_u2.py Normal file
View File

@@ -0,0 +1,258 @@
from module.gg_handler.speedup import SpeedUp
from module.logger import logger
from module.gg_handler.gg_data import GGData
from module.config.config import deep_get
from module.base.base import ModuleBase as Base
import uiautomator2 as u2
from module.gg_handler.change_ship import ChangeShip
from module.gg_handler.change_attribute import ChangeAttribute
class GGU2(Base):
def __init__(self, config, device):
super().__init__(config, device)
self.factor = 200
self.config = config
self.device = device
self.d = u2.connect(self.device.serial)
self.gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
self.d.wait_timeout = 10.0
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
def exit(self):
self.d.app_stop(f'{self.gg_package_name}')
logger.attr('GG', 'Killed')
def skip_error(self):
_skipped = 0
if self.d.xpath('//*[@text="重启游戏"]').exists:
_skipped = 1
logger.hr('Game died with GG panel')
logger.info('No matter GG panel exists or not, Kill GG')
self.exit()
return _skipped
def set_on(self, func='multiplier', factor=200):
"""
func : 'multiplier' or 'change_type' or 'change_attribute' or 'speedup'
factor : factor used in multiplier
"""
_name_dict = {
'en': 'Azur Lane',
'cn': '碧蓝航线',
'jp': 'アズールレーン',
'tw': '碧藍航線'
}
_server = self.config.SERVER
_name = _name_dict[_server]
self.factor = factor
ggdata = GGData(self.config).get_data()
for _i in range(1):
try:
if ggdata['gg_on'] and func == 'multiplier':
logger.attr('GG', 'Enabled')
pass
elif ggdata['gg_type'] and func == 'change_type':
logger.attr('Type', 'Changed')
pass
else:
chosen = False
if self.d(resourceId=f"{self.gg_package_name}:id/hot_point_icon").exists:
self.d(resourceId=f"{self.gg_package_name}:id/hot_point_icon").click()
logger.info('Open GG panel')
self.device.sleep(0.5)
else:
self.d.app_start(self.gg_package_name)
logger.info('Starting GG')
logger.info('In GG overview')
self.device.sleep(3)
while 1:
self.device.sleep(0.5)
if self.d.xpath('//*[@text="忽略"]').exists:
self.d.xpath('//*[@text="忽略"]').click()
logger.info("Click ignore")
self.device.sleep(0.3)
continue
if self.d(resourceId=f"{self.gg_package_name}:id/btn_start_usage").exists:
self.d(resourceId=f"{self.gg_package_name}:id/btn_start_usage").click()
logger.info('Click GG start button')
logger.attr('GG', 'Started')
self.device.sleep(0.3)
continue
if self.d(resourceId=f"{self.gg_package_name}:id/hot_point_icon").exists:
self.d(resourceId=f"{self.gg_package_name}:id/hot_point_icon").click()
logger.info('Open GG panel')
self.device.sleep(0.3)
continue
if self.d(resourceId=f"{self.gg_package_name}:id/search_tab").exists \
and not self.d(resourceId=f"{self.gg_package_name}:id/search_toolbar").exists:
self.d(resourceId=f"{self.gg_package_name}:id/search_tab").click()
logger.info('Switch to search tab')
self.device.sleep(0.3)
continue
if self.d.xpath(
f'//*[@package="{self.gg_package_name}" '
f'and @resource-id="android:id/text1" '
f'and contains(@text,"{_name}")]'
).exists:
self.d.xpath(f'//*[contains(@text,"{_name}")]').click()
logger.info('Choose APP: AzurLane')
self.device.sleep(0.3)
chosen = True
continue
if not chosen and self.d(resourceId=f"{self.gg_package_name}:id/app_icon").exists:
self.d(resourceId=f"{self.gg_package_name}:id/app_icon").click()
logger.info('Click APP choosing tag')
self.device.sleep(0.3)
continue
if self.d(resourceId=f"{self.gg_package_name}:id/search_toolbar").exists:
self.d.xpath(
f'//*[@resource-id="{self.gg_package_name}'
f':id/search_toolbar"]/android.widget.ImageView[last()]'
).click()
logger.info('Click run Scripts')
self.device.sleep(0.3)
self.__getattribute__(func)()
return 1
if self.d.xpath('//*[@text="取消"]').exists:
self.d.xpath('//*[@text="取消"]').click()
logger.info("Cancel exists but not running script, click cancel")
self.device.sleep(0.3)
continue
if self.d.xpath('//*[@text="确定"]').exists:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Confirm exists but script crashed, click confirm")
self.device.sleep(0.3)
continue
if self.d.xpath('//*[@text="重启游戏"]').exists:
self.d.xpath('//*[@text="重启游戏"]').click()
logger.info('GG Panel after game died exists, restart the game')
logger.info('Click Restart')
self.device.sleep(0.3)
continue
except Exception as e:
pass
def change_type(self):
ShipChanger = ChangeShip(self.config, self.device)
ShipChanger.PushLua()
ShipChanger.ChangeShipType()
try:
GGData(self.config).set_data(target='gg_on', value=True)
self.d.xpath('//*[@text="确定"]').click()
except Exception as e:
pass
GGData(self.config).set_data(target='gg_type', value=True)
# self.d.app_stop(self.gg_package_name)
logger.hr('GG Enabled: Type Changed', level=2)
return 1
def change_attribute(self):
AttributeChanger = ChangeAttribute(self.config, self.device)
AttributeChanger.PushLua()
AttributeChanger.ChangeAttribute()
try:
GGData(self.config).set_data(target='gg_on', value=True)
self.d.xpath('//*[@text="确定"]').click()
except Exception as e:
pass
# self.d.app_stop(self.gg_package_name)
return 1
def speedup(self):
speedup = SpeedUp(self.config, self.device)
speedup.Run()
def multiplier(self):
_run = False
_set = False
_confirmed = False
import os
_repush = deep_get(self.config.data, keys='GameManager.GGHandler.RepushLua')
if _repush:
# os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
# f' {self.device.serial} shell mkdir /sdcard/Notes')
# self.device.sleep(0.5)
# os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
# f' {self.device.serial} shell rm /sdcard/Notes/Multiplier.lua')
# self.device.sleep(0.5)
# os.popen(f'"toolkit/Lib/site-packages/adbutils/binaries/adb.exe" -s'
# f' {self.device.serial} push "bin/Lua/Multiplier.lua" /sdcard/Notes/Multiplier.lua')
# self.device.sleep(0.5)
self.device.adb_shell("mkdir /sdcard/Notes")
self.device.sleep(0.5)
self.device.adb_shell("rm /sdcard/Notes/Multiplier.lua")
self.device.sleep(0.5)
self.device.adb_push("bin/Lua/Multiplier.lua", "/sdcard/Notes/Multiplier.lua")
self.device.sleep(0.5)
logger.info('Lua Pushed')
while 1:
self.device.sleep(1)
if self.d(resourceId=f"{self.gg_package_name}:id/search_toolbar").exists:
self.d.xpath(
f'//*[@resource-id="{self.gg_package_name}'
f':id/search_toolbar"]/android.widget.ImageView[last()]'
).click()
logger.info('Click run Scripts')
self.device.sleep(0.3)
if self.d(resourceId=f"{self.gg_package_name}:id/file").exists:
self.d(resourceId=f"{self.gg_package_name}:id/file").send_keys("/sdcard/Notes/Multiplier.lua")
logger.info('Lua path set')
if self.d.xpath('//*[@text="执行"]').exists:
self.d.xpath('//*[@text="执行"]').click()
logger.info('Click Run')
self.device.sleep(0.5)
if self.d.xpath('//*[contains(@text,"修改面板")]').exists:
self.d.xpath('//*[contains(@text,"修改面板")]').click()
logger.info('Click Change Statistic')
self.device.sleep(0.5)
if self.d(resourceId=f"{self.gg_package_name}:id/edit").exists:
self.d(resourceId=f"{self.gg_package_name}:id/edit").send_keys(f"{self.factor}")
logger.info(f'Factor Set: {self.factor}')
self.device.sleep(0.5)
_set = True
if _set and self.d.xpath('//*[@text="确定"]').exists:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
self.device.sleep(0.5)
_confirmed = True
if _confirmed:
self.d.wait_timeout = deep_get(self.config.data, "GameManager.GGHandler.Timeout")
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
try:
GGData(self.config).set_data(target='gg_on', value=True)
self.d.xpath('//*[@text="确定"]').click()
except Exception as e:
pass
GGData(self.config).set_data(target='gg_on', value=True)
logger.attr('GG', 'Enabled')
logger.info("Close the script")
self.d.wait_timeout = 3
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
break
else:
return 0
logger.hr('GG Enabled: Multiplied', level=2)
# self.d.app_stop(self.gg_package_name)
return 1
if __name__ == '__main__':
from module.config.config import AzurLaneConfig
from module.device.device import Device
config = AzurLaneConfig('主号')
device = Device(config)
ggu2 = GGU2(config, device)
try:
ggu2.set_on(func='change_type')
except Exception as e:
pass
print(GGData(config).get_data())

View File

@@ -0,0 +1,81 @@
from module.gg_handler.gg_data import GGData
from module.logger import logger
from module.config.deep import deep_get, deep_set
from module.base.base import ModuleBase
import uiautomator2 as u2
class SpeedUp(ModuleBase):
def __init__(self, config, device):
super().__init__(config, device)
self.d = u2.connect(self.device.serial)
self.gg_package_name = deep_get(self.config.data, keys='GameManager.GGHandler.GGPackageName')
def Run(self):
_run = False
_set = False
_confirmed = False
import os
rate = float(deep_get(self.config.data, keys='GameManager.SpeedUp.Rate', default=5.0))
_repush = deep_get(self.config.data, keys='GameManager.SpeedUp.PushLua')
if _repush:
self.device.adb_shell("mkdir /sdcard/Notes")
self.device.sleep(0.5)
self.device.adb_shell("rm /sdcard/Notes/SpeedUp.lua")
self.device.sleep(0.5)
self.device.adb_push("bin/Lua/SpeedUp.lua", "/sdcard/Notes/SpeedUp.lua")
self.device.sleep(0.5)
logger.info('Lua Pushed')
while 1:
self.device.sleep(1)
if self.d(resourceId=f"{self.gg_package_name}:id/search_toolbar").exists:
self.d.xpath(
f'//*[@resource-id="{self.gg_package_name}'
f':id/search_toolbar"]/android.widget.ImageView[last()]'
).click()
logger.info('Click run Scripts')
self.device.sleep(0.3)
if self.d(resourceId=f"{self.gg_package_name}:id/file").exists:
self.d(resourceId=f"{self.gg_package_name}:id/file").send_keys("/sdcard/Notes/SpeedUp.lua")
logger.info('Lua path set')
if self.d.xpath('//*[@text="执行"]').exists:
self.d.xpath('//*[@text="执行"]').click()
logger.info('Click Run')
self.device.sleep(0.5)
if self.d.xpath('//*[contains(@text,"设置倍速")]').exists:
self.d.xpath('//*[contains(@text,"设置倍速")]').click()
logger.info('Click Change Statistic')
self.device.sleep(0.5)
if self.d(resourceId=f"{self.gg_package_name}:id/edit").exists:
self.d(resourceId=f"{self.gg_package_name}:id/edit").send_keys(f"{rate}")
logger.info(f'Factor Set: {rate}')
self.device.sleep(0.5)
_set = True
if _set and self.d.xpath('//*[@text="确定"]').exists:
self.d.xpath('//*[@text="确定"]').click()
logger.info("Click confirm")
self.device.sleep(0.5)
_confirmed = True
if _confirmed:
self.d.wait_timeout = deep_get(self.config.data, "GameManager.SpeedUp.Timeout")
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
try:
# GGData(self.config).set_data(target='gg_on', value=True)
self.d.xpath('//*[@text="确定"]').click()
except Exception as e:
pass
# GGData(self.config).set_data(target='gg_on', value=True)
logger.attr('GG', 'Enabled')
logger.info("Close the script")
self.d.wait_timeout = 3
logger.info(f'Xpath timeout set to {self.d.wait_timeout} seconds')
if _set and _confirmed:
break
else:
return 0
logger.hr('GG Enabled: SpeedUp', level=2)
# self.d.app_stop(self.gg_package_name)
return 1

View File

@@ -82,6 +82,17 @@ class AshCombat(Combat):
pass
class AshCombat(AshCombat):
def handle_battle_preparation(self):
if self.appear(BATTLE_PREPARATION, offset=(20, 20)):
self.device.sleep(0.5)
self.device.screenshot()
# Power limit check
from module.gg_handler.gg_handler import GGHandler
GGHandler(config=self.config, device=self.device).power_limit('Ash')
super().handle_battle_preparation()
class OSAsh(UI, MapEventHandler):
_ash_fully_collected = False

View File

@@ -395,3 +395,9 @@ class Raid(MapOperation, RaidCombat, CampaignEvent):
self.device.swipe_vector((-900, 0), box=(0, 130, 1280, 440))
interval.reset()
continue
class Raid(Raid):
def combat_preparation(self, *args, **kwargs):
from module.gg_handler.gg_handler import GGHandler
GGHandler(config=self.config, device=self.device).power_limit('Raid')
super().combat_preparation(*args, **kwargs)