mirror of
https://github.com/wess09/AzurLaneAutoScript.git
synced 2026-05-14 05:38:10 +08:00
Compare commits
12 Commits
3eb72757c2
...
2bedf4aaa1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bedf4aaa1 | ||
|
|
7f17c1c006 | ||
|
|
b95ef734ef | ||
|
|
73123f9027 | ||
|
|
a4d0945e1e | ||
|
|
506a1d12cf | ||
|
|
ad1e560e4b | ||
|
|
644181076a | ||
|
|
f7100a2568 | ||
|
|
71cb6f4c98 | ||
|
|
2de7cb7d44 | ||
|
|
982697e18f |
BIN
assets/cn/map/FLEET_SWITCH_CONFIRM.png
Normal file
BIN
assets/cn/map/FLEET_SWITCH_CONFIRM.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/cn/map/FLEET_WITHDRAW.png
Normal file
BIN
assets/cn/map/FLEET_WITHDRAW.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
@ -198,7 +198,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -276,7 +277,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -354,7 +356,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -447,7 +450,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -527,7 +531,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -607,7 +612,8 @@
|
||||
"UseAutoSearch": false,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -686,7 +692,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -764,7 +771,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -842,7 +850,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -924,7 +933,8 @@
|
||||
"UseAutoSearch": false,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -979,7 +989,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1084,7 +1095,8 @@
|
||||
"UseAutoSearch": false,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"Coalition": {
|
||||
"Mode": "hard",
|
||||
@ -1171,7 +1183,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1253,7 +1266,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1335,7 +1349,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1417,7 +1432,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1499,7 +1515,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1577,7 +1594,8 @@
|
||||
"UseAutoSearch": true,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1658,7 +1676,8 @@
|
||||
"UseAutoSearch": false,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"StopCondition": {
|
||||
"OilLimit": 1000,
|
||||
@ -1706,7 +1725,8 @@
|
||||
"UseAutoSearch": false,
|
||||
"Use2xBook": false,
|
||||
"AmbushEvade": true,
|
||||
"UseRecommendFleet": false
|
||||
"UseRecommendFleet": false,
|
||||
"DefeatWithdraw": true
|
||||
},
|
||||
"Coalition": {
|
||||
"Mode": "hard",
|
||||
|
||||
@ -7,13 +7,13 @@ imageio==2.27.0
|
||||
inflection
|
||||
jellyfish==0.11.2
|
||||
lz4
|
||||
mxnet==1.6.0
|
||||
mxnet==1.9.1
|
||||
numpy
|
||||
onepush==1.4.0
|
||||
pillow
|
||||
prettytable==2.2.1
|
||||
psutil==5.9.3
|
||||
pycryptodome==3.10.4
|
||||
pycryptodome==3.19.1
|
||||
pydantic
|
||||
pypresence==4.2.1
|
||||
pywebio==1.6.2
|
||||
@ -22,7 +22,7 @@ pyzmq==22.3.0
|
||||
retrying
|
||||
rich==11.2.0
|
||||
scipy==1.7.1
|
||||
starlette==0.14.2
|
||||
starlette==0.49.1
|
||||
tqdm
|
||||
uiautomator2==2.16.17
|
||||
uiautomator2cache==0.3.0.1
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Image processing
|
||||
numpy==1.16.6
|
||||
numpy==1.22.0
|
||||
scipy==1.4.1
|
||||
pillow
|
||||
opencv-python-headless
|
||||
@ -28,16 +28,16 @@ anyio==1.3.1
|
||||
|
||||
# Pushing
|
||||
onepush==1.4.0
|
||||
pycryptodome==3.9.9
|
||||
pycryptodome==3.19.1
|
||||
pypresence==4.2.1
|
||||
|
||||
# Ocr
|
||||
cnocr==1.2.2
|
||||
mxnet==1.6.0
|
||||
mxnet==1.9.1
|
||||
|
||||
# Webui
|
||||
pywebio==1.6.2
|
||||
starlette==0.14.2
|
||||
starlette==0.49.1
|
||||
uvicorn[standard]==0.17.6
|
||||
zerorpc==0.6.3
|
||||
pyzmq==22.3.0
|
||||
@ -1,7 +1,7 @@
|
||||
# Image processing
|
||||
numpy==1.17.4
|
||||
numpy==1.22.0
|
||||
scipy==1.4.1
|
||||
pillow==9.5.0
|
||||
pillow==12.2.0
|
||||
opencv-python-headless==4.7.0.72
|
||||
imageio==2.27.0
|
||||
|
||||
@ -28,16 +28,16 @@ anyio==1.3.1
|
||||
|
||||
# Pushing
|
||||
onepush==1.4.0
|
||||
pycryptodome==3.9.9
|
||||
pycryptodome==3.19.1
|
||||
pypresence==4.2.1
|
||||
|
||||
# Ocr
|
||||
cnocr==1.2.2
|
||||
mxnet==1.6.0
|
||||
mxnet==1.9.1
|
||||
|
||||
# Webui
|
||||
pywebio==1.6.2
|
||||
starlette==0.14.2
|
||||
starlette==0.49.1
|
||||
uvicorn[standard]==0.17.6
|
||||
zerorpc==0.6.3
|
||||
pyzmq==22.3.0
|
||||
@ -133,6 +133,7 @@ class CampaignBase(CampaignUI, Map, AutoSearchCombat):
|
||||
else:
|
||||
self.map = self.MAP
|
||||
self.battle_count = 0
|
||||
self.fleet_alive_multiple = self.config.Fleet_Fleet2 != 0
|
||||
self.lv_reset()
|
||||
self.lv_get()
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ from module.combat.combat import Combat
|
||||
from module.exception import CampaignEnd
|
||||
from module.handler.assets import AUTO_SEARCH_MAP_OPTION_ON, GET_MISSION
|
||||
from module.logger import logger
|
||||
from module.map.assets import WITHDRAW
|
||||
from module.map.assets import WITHDRAW, SWITCH_OVER, FLEET_WITHDRAW, FLEET_SWITCH_CONFIRM
|
||||
from module.map.map_operation import MapOperation
|
||||
|
||||
|
||||
@ -285,15 +285,23 @@ class AutoSearchCombat(MapOperation, Combat, CampaignStatus):
|
||||
if self.handle_get_ship():
|
||||
continue
|
||||
if self.appear_then_click(OPTS_INFO_D, offset=(30, 30), interval=2):
|
||||
if emotion_reduce:
|
||||
self.emotion.reduce(fleet_index, shipwreck=True)
|
||||
self._withdraw = True
|
||||
continue
|
||||
break
|
||||
if confirm_timer.reached():
|
||||
self._withdraw = True
|
||||
self.device.click(OPTS_INFO_D)
|
||||
if emotion_reduce:
|
||||
self.emotion.reduce(fleet_index, shipwreck=True)
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.appear(BATTLE_STATUS_S) or self.appear(BATTLE_STATUS_A) or self.appear(BATTLE_STATUS_B) \
|
||||
or self.appear(EXP_INFO_S) or self.appear(EXP_INFO_A) or self.appear(EXP_INFO_B) \
|
||||
break
|
||||
if self.appear(BATTLE_STATUS_A) or self.appear(BATTLE_STATUS_B) \
|
||||
or self.appear(EXP_INFO_A) or self.appear(EXP_INFO_B):
|
||||
if emotion_reduce:
|
||||
self.emotion.reduce(fleet_index, shipwreck=True)
|
||||
break
|
||||
if self.appear(BATTLE_STATUS_S) or self.appear(EXP_INFO_S) \
|
||||
or self.appear(GET_MISSION) or self.is_auto_search_running():
|
||||
self.device.screenshot_interval_set()
|
||||
break
|
||||
@ -325,10 +333,29 @@ class AutoSearchCombat(MapOperation, Combat, CampaignStatus):
|
||||
raise CampaignEnd
|
||||
|
||||
# Withdraw
|
||||
if self._withdraw and get_urgent_commission and self.appear(WITHDRAW, offset=(30, 30)):
|
||||
if self._withdraw:
|
||||
if self.appear_then_click(FLEET_SWITCH_CONFIRM, offset=(30, 30)):
|
||||
continue
|
||||
if not self.appear(WITHDRAW, offset=(30, 30)):
|
||||
continue
|
||||
|
||||
logger.info(f'fleet_alive_multiple: {self.fleet_alive_multiple}')
|
||||
self._withdraw = False
|
||||
self.withdraw()
|
||||
break
|
||||
if self.config.Campaign_DefeatWithdraw or not self.fleet_alive_multiple:
|
||||
self.withdraw()
|
||||
break
|
||||
elif get_urgent_commission:
|
||||
self.fleet_alive_multiple = False
|
||||
continue
|
||||
else:
|
||||
while True:
|
||||
self.device.screenshot()
|
||||
if self.appear_then_click(FLEET_WITHDRAW, offset=(30, 30)):
|
||||
break
|
||||
if self.appear_then_click(SWITCH_OVER, interval=2):
|
||||
continue
|
||||
self.fleet_alive_multiple = False
|
||||
continue
|
||||
|
||||
# Combat status
|
||||
if self.handle_get_ship():
|
||||
|
||||
@ -248,6 +248,10 @@ class Emotion:
|
||||
return 4
|
||||
else:
|
||||
return 2
|
||||
|
||||
@property
|
||||
def reduce_shipwreck(self):
|
||||
return 10
|
||||
|
||||
def _check_reduce(self, battle):
|
||||
"""
|
||||
@ -339,7 +343,7 @@ class Emotion:
|
||||
logger.attr('Wait until', recovered)
|
||||
sleep(60)
|
||||
|
||||
def reduce(self, fleet_index):
|
||||
def reduce(self, fleet_index, shipwreck=False):
|
||||
"""
|
||||
Reduce emotion of specific fleet.
|
||||
Should be called after battle executing.
|
||||
@ -347,6 +351,7 @@ class Emotion:
|
||||
|
||||
Args:
|
||||
fleet_index (int): 1 or 2.
|
||||
shipwreck (bool): Whether the fleet is at shipwreck.
|
||||
"""
|
||||
logger.hr('Emotion reduce')
|
||||
self.update()
|
||||
@ -356,8 +361,12 @@ class Emotion:
|
||||
else:
|
||||
fleet = self.fleets[fleet_index - 1]
|
||||
|
||||
fleet.current -= self.reduce_per_battle
|
||||
self.total_reduced += self.reduce_per_battle
|
||||
if not shipwreck:
|
||||
fleet.current -= self.reduce_per_battle
|
||||
self.total_reduced += self.reduce_per_battle
|
||||
else:
|
||||
fleet.current -= self.reduce_shipwreck
|
||||
self.total_reduced += self.reduce_shipwreck
|
||||
self.record()
|
||||
self.show()
|
||||
|
||||
|
||||
@ -468,7 +468,8 @@
|
||||
"option": [
|
||||
"auto",
|
||||
"cpu",
|
||||
"gpu"
|
||||
"gpu",
|
||||
"ane"
|
||||
]
|
||||
},
|
||||
"ScreenshotInterval": {
|
||||
@ -878,6 +879,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -1274,6 +1279,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -1670,6 +1679,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -2198,6 +2211,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -2693,6 +2710,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -3153,6 +3174,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -3589,6 +3614,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -4024,6 +4053,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -4458,6 +4491,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -4896,6 +4933,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -5167,6 +5208,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -5727,6 +5772,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"Coalition": {
|
||||
@ -6378,6 +6427,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -6825,6 +6878,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -7277,6 +7334,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -7729,6 +7790,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -8181,6 +8246,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -8623,6 +8692,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -9057,6 +9130,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
@ -9302,6 +9379,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"Coalition": {
|
||||
|
||||
@ -163,7 +163,7 @@ Error:
|
||||
Optimization:
|
||||
OcrDevice:
|
||||
value: auto
|
||||
option: [auto, cpu, gpu]
|
||||
option: [auto, cpu, gpu, ane]
|
||||
ScreenshotInterval: 0.3
|
||||
CombatScreenshotInterval: 1.0
|
||||
TaskHoardingDuration: 0
|
||||
@ -292,6 +292,7 @@ Campaign:
|
||||
Use2xBook: false
|
||||
AmbushEvade: true
|
||||
UseRecommendFleet: false
|
||||
DefeatWithdraw: true
|
||||
StopCondition:
|
||||
OilLimit: 1000
|
||||
CoinLimit: 0
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import copy
|
||||
import operator
|
||||
import platform
|
||||
import sys
|
||||
import threading
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@ -186,7 +188,12 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
|
||||
def ocr_device(self) -> str:
|
||||
val = self.Optimization_OcrDevice
|
||||
if val == 'auto':
|
||||
if sys.platform == 'darwin' and platform.machine() == 'arm64':
|
||||
return 'ane'
|
||||
return 'gpu' if is_good_gpu() else 'cpu'
|
||||
if val == 'ane' and sys.platform != 'darwin':
|
||||
logger.warning("当前系统非 macOS,不使用 Apple Neural Engine")
|
||||
return 'cpu'
|
||||
return val
|
||||
|
||||
@property
|
||||
|
||||
@ -113,7 +113,7 @@ class GeneratedConfig:
|
||||
Error_LlmModel = 'Nvidia/qwen/qwen2.5-coder-32b-instruct'
|
||||
|
||||
# Group `Optimization`
|
||||
Optimization_OcrDevice = 'auto' # auto, cpu, gpu
|
||||
Optimization_OcrDevice = 'auto' # auto, cpu, gpu, ane
|
||||
Optimization_ScreenshotInterval = 0.3
|
||||
Optimization_CombatScreenshotInterval = 1.0
|
||||
Optimization_TaskHoardingDuration = 0
|
||||
@ -178,6 +178,7 @@ class GeneratedConfig:
|
||||
Campaign_Use2xBook = False
|
||||
Campaign_AmbushEvade = True
|
||||
Campaign_UseRecommendFleet = False
|
||||
Campaign_DefeatWithdraw = True
|
||||
|
||||
# Group `StopCondition`
|
||||
StopCondition_OilLimit = 1000
|
||||
|
||||
@ -609,9 +609,10 @@
|
||||
"OcrDevice": {
|
||||
"name": "Optimization.OcrDevice.name",
|
||||
"help": "Optimization.OcrDevice.help",
|
||||
"auto": "auto",
|
||||
"cpu": "cpu",
|
||||
"gpu": "gpu"
|
||||
"auto": "Auto",
|
||||
"cpu": "CPU",
|
||||
"gpu": "GPU",
|
||||
"ane": "ANE (Apple)"
|
||||
},
|
||||
"ScreenshotInterval": {
|
||||
"name": "Slow Down Screenshot Speed to X Seconds per Frame",
|
||||
@ -1046,6 +1047,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"name": "Auto Fleet Composition",
|
||||
"help": "Use the game's built-in recommended fleet to automatically compose hard mode fleets"
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"name": "Retreat after defeat in Mob",
|
||||
"help": "The handling method for defeat in Mob during the journey. Upon initiation, exit the sea area directly; upon termination, attempt to have another team take over the subsequent battle."
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
|
||||
@ -607,11 +607,12 @@
|
||||
"help": ""
|
||||
},
|
||||
"OcrDevice": {
|
||||
"name": "Optimization.OcrDevice.name",
|
||||
"help": "Optimization.OcrDevice.help",
|
||||
"auto": "auto",
|
||||
"cpu": "cpu",
|
||||
"gpu": "gpu"
|
||||
"name": "OCR设备选择",
|
||||
"help": "",
|
||||
"auto": "自動",
|
||||
"cpu": "CPU",
|
||||
"gpu": "GPU",
|
||||
"ane": "ANE (Apple)"
|
||||
},
|
||||
"ScreenshotInterval": {
|
||||
"name": "スクリーンショット速度をX秒に1枚に減速",
|
||||
@ -1046,6 +1047,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"name": "自動編成",
|
||||
"help": "ゲーム内蔵の推奨編成を使用してハードステージの編成を自動的に完了します"
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"name": "道中での戦闘で敗北し撤退",
|
||||
"help": "道中戦闘で敗北した際の処理方法。オンの場合は海域から直接退出し、オフの場合は別のチームが引き継いで後続の戦闘を試みる。"
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
|
||||
@ -608,10 +608,11 @@
|
||||
},
|
||||
"OcrDevice": {
|
||||
"name": "OCR设备",
|
||||
"help": "选择OCR设备,不推荐任何没有独立显卡的用户使用GPU,除非你知道自己在做什么\n非Windows系统目前不支持GPU\n自动选择:当显存超过1G时使用GPU,否则使用CPU",
|
||||
"help": "选择OCR设备,不推荐任何没有独立显卡的用户使用GPU,除非你知道自己在做什么\nGPU 仅用于 Windows DirectML,ANE 仅用于 macOS Apple Neural Engine\n自动选择:Apple Silicon Mac 使用 ANE,Windows 显存超过1G时使用GPU,否则使用CPU",
|
||||
"auto": "自动选择",
|
||||
"cpu": "CPU",
|
||||
"gpu": "GPU"
|
||||
"gpu": "GPU",
|
||||
"ane": "ANE (Apple)"
|
||||
},
|
||||
"ScreenshotInterval": {
|
||||
"name": "放慢截图速度至 X 秒一张",
|
||||
@ -1046,6 +1047,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"name": "自动配队",
|
||||
"help": "使用游戏内置的推荐阵容自动完成困难图配队"
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"name": "道中战斗失败撤退",
|
||||
"help": "道中战斗战败时的处理方式。开启时直接退出海域,关闭时尝试由另一队接管后续战斗。"
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
|
||||
@ -608,10 +608,11 @@
|
||||
},
|
||||
"OcrDevice": {
|
||||
"name": "OCR设备选择 (´・ω・`)",
|
||||
"help": "OCR跑在CPU或GPU上。没独显别选GPU喵。自动:显存>1G用GPU否则CPU。非Windows无GPU。",
|
||||
"help": "OCR跑在CPU/GPU/ANE上。GPU仅用于Windows DirectML,ANE仅用于macOS Apple Neural Engine。自动:Apple Silicon Mac用ANE,Windows显存>1G用GPU,否则CPU。",
|
||||
"auto": "自动判断 (`・ω・´)",
|
||||
"cpu": "CPU喵",
|
||||
"gpu": "GPU喵"
|
||||
"gpu": "GPU喵",
|
||||
"ane": "ANE (Apple)喵"
|
||||
},
|
||||
"ScreenshotInterval": {
|
||||
"name": "放慢截图至 X 秒一张 (´-ω-`)zzz",
|
||||
@ -1046,6 +1047,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"name": "自动配队困难图 (`・ω・´)ゞ",
|
||||
"help": "使用游戏推荐阵容自动完成困难配队喵~"
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"name": "道中战斗失败撤退 (`・ω・´)",
|
||||
"help": "道中战斗战败时的处理方式喵。开启时直接退出海域,关闭时尝试由另一队接管后续战斗喵。"
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
|
||||
@ -610,8 +610,9 @@
|
||||
"name": "Optimization.OcrDevice.name",
|
||||
"help": "Optimization.OcrDevice.help",
|
||||
"auto": "auto",
|
||||
"cpu": "cpu",
|
||||
"gpu": "gpu"
|
||||
"cpu": "CPU",
|
||||
"gpu": "GPU",
|
||||
"ane": "ANE (Apple)"
|
||||
},
|
||||
"ScreenshotInterval": {
|
||||
"name": "放慢截圖速度至 X 秒一張",
|
||||
@ -1046,6 +1047,10 @@
|
||||
"UseRecommendFleet": {
|
||||
"name": "自動配隊",
|
||||
"help": "使用遊戲內建的推薦陣容自動完成困難圖配隊"
|
||||
},
|
||||
"DefeatWithdraw": {
|
||||
"name": "道中戰鬥失敗撤退",
|
||||
"help": "道中戰鬥戰敗時的處理方式。開啟時直接退出海域,關閉時嘗試由另一隊接管後續戰鬥。"
|
||||
}
|
||||
},
|
||||
"StopCondition": {
|
||||
|
||||
@ -1,23 +1,33 @@
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import cv2
|
||||
from rich.table import Table
|
||||
from rich.text import Text
|
||||
|
||||
from module.daemon.daemon_base import DaemonBase
|
||||
from module.config.config import AzurLaneConfig
|
||||
from module.exception import RequestHumanTakeover
|
||||
from module.logger import logger
|
||||
from module.ocr.al_ocr import AlOcr
|
||||
|
||||
|
||||
class OcrBenchmark(DaemonBase):
|
||||
class OcrBenchmark:
|
||||
# Each entry: (model_name, dataset_prefix, subfolder_name)
|
||||
BENCHMARKS = [
|
||||
('en', 'sets_num', 'sets_num'),
|
||||
('cn', 'sets_zhcn', 'sets_zhcn'),
|
||||
]
|
||||
|
||||
def __init__(self, config, device=None, task=None):
|
||||
if isinstance(config, AzurLaneConfig):
|
||||
self.config = config
|
||||
if task is not None:
|
||||
self.config.init_task(task)
|
||||
else:
|
||||
self.config = AzurLaneConfig(config, task=task)
|
||||
|
||||
def _find_archive(self, prefix):
|
||||
for ext in ['.zip', '.tar', '.tar.xz', '.tar.gz']:
|
||||
path = f'module/daemon/{prefix}{ext}'
|
||||
@ -54,12 +64,14 @@ class OcrBenchmark(DaemonBase):
|
||||
if avg_ms < 300.0: return 'Very Slow', 'red'
|
||||
return 'Ultra Slow', 'bold red'
|
||||
|
||||
def _run_single(self, model_name, dataset_prefix, subfolder, use_gpu=None):
|
||||
def _run_single(self, model_name, dataset_prefix, subfolder, use_gpu=None, ocr_device=None):
|
||||
logger.hr(f'Benchmark: {model_name.upper()} model | dataset: {dataset_prefix}', level=2)
|
||||
|
||||
# --- Dynamic GPU config ---
|
||||
if use_gpu is not None:
|
||||
self.config.override(Optimization_OcrDevice='gpu' if use_gpu else 'cpu')
|
||||
# --- Dynamic OCR device config ---
|
||||
if ocr_device is None and use_gpu is not None:
|
||||
ocr_device = 'gpu' if use_gpu else 'cpu'
|
||||
if ocr_device is not None:
|
||||
self.config.override(Optimization_OcrDevice=ocr_device)
|
||||
from module.ocr.al_ocr import reset_ocr_model
|
||||
reset_ocr_model()
|
||||
|
||||
@ -215,17 +227,22 @@ class OcrBenchmark(DaemonBase):
|
||||
def run_simple_ocr_benchmark(self):
|
||||
"""
|
||||
Returns:
|
||||
str: 'gpu' if accuracy is 100% on a simple test set, else 'cpu'.
|
||||
str: Best OCR device for this machine.
|
||||
"""
|
||||
logger.hr('Simple OCR Benchmark', level=1)
|
||||
logger.info('Testing OCR with GPU...')
|
||||
res = self._run_single('en', 'sets_num', 'sets_num', use_gpu=True)
|
||||
if sys.platform == 'darwin' and platform.machine() == 'arm64':
|
||||
logger.info('Testing OCR with ANE...')
|
||||
device = 'ane'
|
||||
else:
|
||||
logger.info('Testing OCR with GPU...')
|
||||
device = 'gpu'
|
||||
res = self._run_single('en', 'sets_num', 'sets_num', ocr_device=device)
|
||||
|
||||
if res and res['accuracy'] >= 100.0:
|
||||
logger.info('OCR accuracy is 100% with GPU, use GPU.')
|
||||
return 'gpu'
|
||||
logger.info(f'OCR accuracy is 100% with {device.upper()}, use {device.upper()}.')
|
||||
return device
|
||||
else:
|
||||
logger.info('OCR accuracy is not 100% with GPU or test failed, fallback to CPU.')
|
||||
logger.info(f'OCR accuracy is not 100% with {device.upper()} or test failed, fallback to CPU.')
|
||||
return 'cpu'
|
||||
|
||||
|
||||
@ -235,4 +252,4 @@ def run_ocr_benchmark(config):
|
||||
return True
|
||||
except RequestHumanTakeover:
|
||||
logger.critical('错误 请求人类接管')
|
||||
return False
|
||||
return False
|
||||
|
||||
@ -22,6 +22,8 @@ FLEET_NUM_2 = Button(area={'cn': (212, 75, 226, 101), 'en': (212, 75, 226, 101),
|
||||
FLEET_PREPARATION = Button(area={'cn': (1013, 558, 1141, 588), 'en': (1048, 569, 1086, 595), 'jp': (1046, 558, 1107, 587), 'tw': (1014, 557, 1142, 588)}, color={'cn': (242, 211, 160), 'en': (241, 201, 148), 'jp': (241, 205, 151), 'tw': (242, 208, 157)}, button={'cn': (980, 549, 1181, 612), 'en': (988, 556, 1145, 606), 'jp': (983, 549, 1185, 612), 'tw': (980, 548, 1180, 612)}, file={'cn': './assets/cn/map/FLEET_PREPARATION.png', 'en': './assets/en/map/FLEET_PREPARATION.png', 'jp': './assets/jp/map/FLEET_PREPARATION.png', 'tw': './assets/tw/map/FLEET_PREPARATION.png'})
|
||||
FLEET_PREPARATION_CHECK = Button(area={'cn': (1146, 107, 1174, 136), 'en': (1129, 111, 1158, 140), 'jp': (1146, 107, 1174, 136), 'tw': (1145, 106, 1175, 136)}, color={'cn': (180, 98, 111), 'en': (189, 105, 109), 'jp': (180, 98, 111), 'tw': (180, 90, 92)}, button={'cn': (1146, 107, 1174, 136), 'en': (1129, 111, 1158, 140), 'jp': (1146, 107, 1174, 136), 'tw': (1145, 106, 1175, 136)}, file={'cn': './assets/cn/map/FLEET_PREPARATION_CHECK.png', 'en': './assets/en/map/FLEET_PREPARATION_CHECK.png', 'jp': './assets/jp/map/FLEET_PREPARATION_CHECK.png', 'tw': './assets/tw/map/FLEET_PREPARATION_CHECK.png'})
|
||||
FLEET_SUPPORT_EMPTY = Button(area={'cn': (454, 470, 538, 540), 'en': (454, 470, 538, 540), 'jp': (454, 470, 538, 540), 'tw': (454, 470, 538, 540)}, color={'cn': (47, 54, 77), 'en': (47, 54, 77), 'jp': (47, 54, 77), 'tw': (47, 54, 77)}, button={'cn': (454, 470, 538, 540), 'en': (454, 470, 538, 540), 'jp': (454, 470, 538, 540), 'tw': (454, 470, 538, 540)}, file={'cn': './assets/cn/map/FLEET_SUPPORT_EMPTY.png', 'en': './assets/cn/map/FLEET_SUPPORT_EMPTY.png', 'jp': './assets/cn/map/FLEET_SUPPORT_EMPTY.png', 'tw': './assets/cn/map/FLEET_SUPPORT_EMPTY.png'})
|
||||
FLEET_SWITCH_CONFIRM = Button(area={'cn': (553, 481, 728, 541), 'en': (553, 481, 728, 541), 'jp': (553, 481, 728, 541), 'tw': (553, 481, 728, 541)}, color={'cn': (98, 144, 201), 'en': (98, 144, 201), 'jp': (98, 144, 201), 'tw': (98, 144, 201)}, button={'cn': (553, 481, 728, 541), 'en': (553, 481, 728, 541), 'jp': (553, 481, 728, 541), 'tw': (553, 481, 728, 541)}, file={'cn': './assets/cn/map/FLEET_SWITCH_CONFIRM.png', 'en': './assets/cn/map/FLEET_SWITCH_CONFIRM.png', 'jp': './assets/cn/map/FLEET_SWITCH_CONFIRM.png', 'tw': './assets/cn/map/FLEET_SWITCH_CONFIRM.png'})
|
||||
FLEET_WITHDRAW = Button(area={'cn': (714, 356, 773, 380), 'en': (714, 356, 773, 380), 'jp': (714, 356, 773, 380), 'tw': (714, 356, 773, 380)}, color={'cn': (175, 188, 201), 'en': (175, 188, 201), 'jp': (175, 188, 201), 'tw': (175, 188, 201)}, button={'cn': (714, 356, 773, 380), 'en': (714, 356, 773, 380), 'jp': (714, 356, 773, 380), 'tw': (714, 356, 773, 380)}, file={'cn': './assets/cn/map/FLEET_WITHDRAW.png', 'en': './assets/cn/map/FLEET_WITHDRAW.png', 'jp': './assets/cn/map/FLEET_WITHDRAW.png', 'tw': './assets/cn/map/FLEET_WITHDRAW.png'})
|
||||
MAP_CAT_ATTACK = Button(area={'cn': (1237, 103, 1252, 153), 'en': (1237, 103, 1252, 153), 'jp': (1237, 103, 1252, 153), 'tw': (1237, 103, 1252, 153)}, color={'cn': (43, 45, 52), 'en': (43, 45, 52), 'jp': (43, 45, 52), 'tw': (43, 45, 52)}, button={'cn': (1148, 653, 1262, 705), 'en': (1147, 651, 1263, 701), 'jp': (1149, 653, 1261, 704), 'tw': (1148, 653, 1262, 705)}, file={'cn': './assets/cn/map/MAP_CAT_ATTACK.png', 'en': './assets/en/map/MAP_CAT_ATTACK.png', 'jp': './assets/jp/map/MAP_CAT_ATTACK.png', 'tw': './assets/tw/map/MAP_CAT_ATTACK.png'})
|
||||
MAP_CAT_ATTACK_MIRROR = Button(area={'cn': (147, 145, 187, 157), 'en': (147, 145, 187, 157), 'jp': (147, 145, 187, 157), 'tw': (147, 145, 187, 157)}, color={'cn': (214, 191, 99), 'en': (214, 191, 99), 'jp': (214, 191, 99), 'tw': (214, 191, 99)}, button={'cn': (147, 145, 187, 157), 'en': (147, 145, 187, 157), 'jp': (147, 145, 187, 157), 'tw': (147, 145, 187, 157)}, file={'cn': './assets/cn/map/MAP_CAT_ATTACK_MIRROR.png', 'en': './assets/en/map/MAP_CAT_ATTACK_MIRROR.png', 'jp': './assets/jp/map/MAP_CAT_ATTACK_MIRROR.png', 'tw': './assets/tw/map/MAP_CAT_ATTACK_MIRROR.png'})
|
||||
MAP_MODE_SWITCH_HARD = Button(area={'cn': (341, 580, 374, 617), 'en': (341, 580, 374, 617), 'jp': (341, 580, 374, 617), 'tw': (341, 580, 374, 617)}, color={'cn': (234, 179, 179), 'en': (234, 179, 179), 'jp': (234, 179, 179), 'tw': (234, 179, 179)}, button={'cn': (341, 580, 374, 617), 'en': (341, 580, 374, 617), 'jp': (341, 580, 374, 617), 'tw': (341, 580, 374, 617)}, file={'cn': './assets/cn/map/MAP_MODE_SWITCH_HARD.png', 'en': './assets/cn/map/MAP_MODE_SWITCH_HARD.png', 'jp': './assets/cn/map/MAP_MODE_SWITCH_HARD.png', 'tw': './assets/cn/map/MAP_MODE_SWITCH_HARD.png'})
|
||||
|
||||
@ -378,6 +378,8 @@ class MapOperation(MysteryHandler, FleetPreparation, Retirement, FastForwardHand
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear_then_click(FLEET_SWITCH_CONFIRM, offset=(30, 30)):
|
||||
continue
|
||||
if self.handle_popup_confirm('WITHDRAW'):
|
||||
continue
|
||||
if self.appear_then_click(WITHDRAW, interval=5):
|
||||
|
||||
@ -111,6 +111,7 @@ class RecOnlyOCR(RapidOCR):
|
||||
self.use_rec = cfg.Global.use_rec
|
||||
cfg.Rec.engine_cfg = cfg.EngineConfig[cfg.Rec.engine_type.value]
|
||||
cfg.Rec.font_path = cfg.Global.font_path
|
||||
cfg.Rec.model_root_dir = cfg.Global.get("model_root_dir", os.getcwd())
|
||||
self.text_rec = TextRecognizer(cfg.Rec)
|
||||
|
||||
self.load_img = LoadImage()
|
||||
@ -124,7 +125,9 @@ class RecOnlyOCR(RapidOCR):
|
||||
|
||||
|
||||
def _create_ocr(model_path, rec_keys_path, ocr_version):
|
||||
use_gpu = config.ocr_device == 'gpu'
|
||||
ocr_device = config.ocr_device
|
||||
use_dml = os.name == 'nt' and ocr_device == 'gpu'
|
||||
use_coreml = ocr_device == 'ane'
|
||||
params = {
|
||||
"Global.use_det": False,
|
||||
"Global.use_cls": False,
|
||||
@ -133,7 +136,9 @@ def _create_ocr(model_path, rec_keys_path, ocr_version):
|
||||
"Rec.ocr_version": ocr_version,
|
||||
"Rec.model_path": model_path,
|
||||
"Rec.rec_keys_path": rec_keys_path,
|
||||
"EngineConfig.onnxruntime.use_dml": use_gpu,
|
||||
"EngineConfig.onnxruntime.use_dml": use_dml,
|
||||
"EngineConfig.onnxruntime.use_coreml": use_coreml,
|
||||
"EngineConfig.onnxruntime.coreml_ep_cfg.MLComputeUnits": "CPUAndNeuralEngine",
|
||||
}
|
||||
return RecOnlyOCR(params=params)
|
||||
|
||||
|
||||
@ -623,7 +623,7 @@ class AlasGUI(Frame):
|
||||
coins_legend_html += '<span style="display:flex; align-items:center; gap:4px;"><span style="width:12px; height:2px; background:#ce93d8; border-radius:1px; border-top:1px dashed #ce93d8;"></span>紫币</span>'
|
||||
|
||||
chart_id = f"ap_cv_{id(self)}"
|
||||
detail_controls_display = 'display:flex;' if is_detail_mode else 'display:none;'
|
||||
detail_controls_display = 'display:flex;' if current_view in ('line', 'detail') else 'display:none;'
|
||||
|
||||
html_tpl = read_webapp_template('ap_chart_panel.html')
|
||||
html = html_tpl.format(
|
||||
|
||||
@ -13,7 +13,7 @@ jellyfish
|
||||
pyyaml
|
||||
inflection
|
||||
pywebio
|
||||
starlette==0.49.1
|
||||
starlette==1.0.0
|
||||
anyio
|
||||
uvicorn[standard]
|
||||
aiofiles
|
||||
@ -31,13 +31,13 @@ typing_extensions>=4.8.0
|
||||
pydantic>=2.5.0
|
||||
rapidocr
|
||||
onnxruntime-directml>=1.24.4; sys_platform == "win32"
|
||||
onnxruntime>=1.24.4; sys_platform == "linux"
|
||||
onnxruntime @ https://files.pythonhosted.org/packages/fb/aa/04530bd38e31e26970fa1212346d76cf81705dc16a8ee5e6f4fb24634c11/onnxruntime-1.25.1-cp314-cp314-macosx_14_0_arm64.whl; sys_platform == "darwin" and platform_machine == "arm64"
|
||||
onnxruntime==1.26.0; sys_platform == "linux"
|
||||
onnxruntime @ https://files.pythonhosted.org/packages/40/89/17546c1c20f6bfc3ae41c22152378a26edfea918af3129e2139dcd7c99f3/onnxruntime-1.26.0-cp314-cp314-macosx_14_0_arm64.whl; sys_platform == "darwin" and platform_machine == "arm64"
|
||||
watchdog>=2.0.0
|
||||
numba
|
||||
pip
|
||||
lz4
|
||||
setuptools==75.8.2
|
||||
setuptools==78.1.1
|
||||
importlib_resources>=6.0.0
|
||||
importlib_metadata>=8.0.0
|
||||
openai
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements-in.txt --python-platform linux --python-version 3.14 --annotation-style=line --no-emit-index-url --output-file requirements-linux.txt
|
||||
# uv pip compile requirements-in.txt --annotation-style=line --python-platform linux --python-version 3.14 --output-file requirements-linux.txt
|
||||
adbutils==0.11.0 # via uiautomator2, -r requirements-in.txt
|
||||
aiofiles==23.1.0 # via -r requirements-in.txt
|
||||
annotated-types==0.7.0 # via pydantic
|
||||
@ -52,18 +52,17 @@ lxml==6.1.0 # via uiautomator2
|
||||
lz4==4.4.5 # via -r requirements-in.txt
|
||||
matplotlib==3.10.8 # via -r requirements-in.txt
|
||||
mcp==1.23.0 # via -r requirements-in.txt
|
||||
mpmath==1.3.0 # via sympy
|
||||
msgpack==1.0.4 # via zerorpc
|
||||
numba==0.64.0 # via -r requirements-in.txt
|
||||
numpy==2.4.3 # via contourpy, imageio, matplotlib, numba, onnxruntime, opencv-python, rapidocr, scipy, shapely, -r requirements-in.txt
|
||||
numpy==2.4.4 # via contourpy, imageio, matplotlib, numba, onnxruntime, opencv-python, rapidocr, scipy, shapely, -r requirements-in.txt
|
||||
omegaconf==2.3.0 # via rapidocr
|
||||
onepush==1.2.0 # via -r requirements-in.txt
|
||||
onnxruntime==1.24.4 # via -r requirements-in.txt
|
||||
onnxruntime==1.26.0 # via -r requirements-in.txt
|
||||
openai==2.30.0 # via -r requirements-in.txt
|
||||
opencv-python==4.13.0.92 # via rapidocr, -r requirements-in.txt
|
||||
packaging==20.9 # via deprecation, matplotlib, onnxruntime, uiautomator2
|
||||
pillow==12.2.0 # via imageio, matplotlib, rapidocr, uiautomator2, -r requirements-in.txt
|
||||
pip==26.0.1 # via -r requirements-in.txt
|
||||
pip==26.1 # via -r requirements-in.txt
|
||||
progress==1.6 # via uiautomator2
|
||||
protobuf==6.33.5 # via onnxruntime
|
||||
psutil==5.9.4 # via -r requirements-in.txt
|
||||
@ -81,7 +80,7 @@ pyparsing==3.0.9 # via matplotlib, packaging
|
||||
pypresence==4.2.1 # via -r requirements-in.txt
|
||||
python-dateutil==2.9.0.post0 # via matplotlib
|
||||
python-dotenv==1.2.2 # via pydantic-settings, uvicorn
|
||||
python-multipart==0.0.26 # via mcp
|
||||
python-multipart==0.0.27 # via mcp
|
||||
pywebio==1.7.1 # via -r requirements-in.txt
|
||||
pyyaml==6.0.3 # via omegaconf, rapidocr, uvicorn, -r requirements-in.txt
|
||||
pyzmq==27.1.0 # via zerorpc, -r requirements-in.txt
|
||||
@ -93,13 +92,12 @@ retrying==1.3.4 # via -r requirements-in.txt
|
||||
rich==11.2.0 # via -r requirements-in.txt
|
||||
rpds-py==0.30.0 # via jsonschema, referencing
|
||||
scipy==1.17.1 # via -r requirements-in.txt
|
||||
setuptools==75.8.2 # via zope-event, zope-interface, -r requirements-in.txt
|
||||
setuptools==78.1.1 # via zope-event, zope-interface, -r requirements-in.txt
|
||||
shapely==2.1.2 # via rapidocr
|
||||
six==1.16.0 # via adbutils, python-dateutil, rapidocr, retrying, uiautomator2
|
||||
sniffio==1.3.0 # via openai
|
||||
sse-starlette==3.0.3 # via mcp, -r requirements-in.txt
|
||||
starlette==0.49.1 # via mcp, -r requirements-in.txt
|
||||
sympy==1.14.0 # via onnxruntime
|
||||
starlette==1.0.0 # via mcp, -r requirements-in.txt
|
||||
tornado==6.5.5 # via pywebio
|
||||
tqdm==4.67.3 # via openai, rapidocr
|
||||
typing-extensions==4.15.0 # via mcp, openai, pydantic, pydantic-core, typing-inspection, -r requirements-in.txt
|
||||
@ -107,7 +105,7 @@ typing-inspection==0.4.2 # via mcp, pydantic, pydantic-settings
|
||||
ua-parser==0.16.1 # via user-agents
|
||||
uiautomator2==2.16.17 # via -r requirements-in.txt
|
||||
uiautomator2cache==0.3.0.1 # via -r requirements-in.txt
|
||||
urllib3==2.6.3 # via requests
|
||||
urllib3==2.7.0 # via requests
|
||||
user-agents==2.2.0 # via pywebio
|
||||
uvicorn==0.44.0 # via mcp, -r requirements-in.txt
|
||||
uvloop==0.22.1 # via uvicorn
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements-in.txt --annotation-style=line --python-platform aarch64-apple-darwin --python-version 3.14 --output-file requirements-macos.txt
|
||||
# uv pip compile requirements-in.txt --annotation-style=line --python-platform macos --python-version 3.14 --output-file requirements-macos.txt
|
||||
adbutils==0.16.2 # via uiautomator2, -r requirements-in.txt
|
||||
aiofiles==25.1.0 # via -r requirements-in.txt
|
||||
annotated-types==0.7.0 # via pydantic
|
||||
@ -56,12 +56,12 @@ numba==0.65.0 # via -r requirements-in.txt
|
||||
numpy==2.4.4 # via contourpy, imageio, matplotlib, numba, onnxruntime, opencv-python, rapidocr, scipy, shapely, -r requirements-in.txt
|
||||
omegaconf==2.3.0 # via rapidocr
|
||||
onepush==1.8.0 # via -r requirements-in.txt
|
||||
onnxruntime @ https://files.pythonhosted.org/packages/fb/aa/04530bd38e31e26970fa1212346d76cf81705dc16a8ee5e6f4fb24634c11/onnxruntime-1.25.1-cp314-cp314-macosx_14_0_arm64.whl # via -r requirements-in.txt
|
||||
onnxruntime @ https://files.pythonhosted.org/packages/40/89/17546c1c20f6bfc3ae41c22152378a26edfea918af3129e2139dcd7c99f3/onnxruntime-1.26.0-cp314-cp314-macosx_14_0_arm64.whl # via -r requirements-in.txt
|
||||
openai==2.31.0 # via -r requirements-in.txt
|
||||
opencv-python==4.13.0.92 # via rapidocr, -r requirements-in.txt
|
||||
packaging==20.9 # via deprecation, matplotlib, onnxruntime, uiautomator2
|
||||
pillow==12.2.0 # via adbutils, imageio, matplotlib, rapidocr, uiautomator2, -r requirements-in.txt
|
||||
pip==26.0.1 # via -r requirements-in.txt
|
||||
pip==26.1 # via -r requirements-in.txt
|
||||
progress==1.6.1 # via uiautomator2
|
||||
protobuf==7.34.1 # via onnxruntime
|
||||
psutil==7.2.2 # via -r requirements-in.txt
|
||||
@ -80,7 +80,7 @@ pypresence==4.6.1 # via -r requirements-in.txt
|
||||
pysocks==1.7.1 # via requests
|
||||
python-dateutil==2.9.0.post0 # via matplotlib
|
||||
python-dotenv==1.2.2 # via pydantic-settings, uvicorn
|
||||
python-multipart==0.0.26 # via mcp
|
||||
python-multipart==0.0.27 # via mcp
|
||||
pywebio==1.8.4 # via -r requirements-in.txt
|
||||
pyyaml==6.0.3 # via omegaconf, rapidocr, uvicorn, -r requirements-in.txt
|
||||
pyzmq==27.1.0 # via zerorpc, -r requirements-in.txt
|
||||
@ -92,12 +92,12 @@ retrying==1.4.2 # via -r requirements-in.txt
|
||||
rich==15.0.0 # via -r requirements-in.txt
|
||||
rpds-py==0.30.0 # via jsonschema, referencing
|
||||
scipy==1.17.1 # via -r requirements-in.txt
|
||||
setuptools==75.8.2 # via -r requirements-in.txt
|
||||
setuptools==78.1.1 # via -r requirements-in.txt
|
||||
shapely==2.1.2 # via rapidocr
|
||||
six==1.17.0 # via python-dateutil, rapidocr, uiautomator2
|
||||
sniffio==1.3.1 # via openai
|
||||
sse-starlette==3.0.3 # via mcp, -r requirements-in.txt
|
||||
starlette==0.49.1 # via mcp, -r requirements-in.txt
|
||||
starlette==1.0.0 # via mcp, -r requirements-in.txt
|
||||
tornado==6.5.5 # via pywebio
|
||||
tqdm==4.67.3 # via openai, rapidocr
|
||||
typing-extensions==4.15.0 # via mcp, openai, pydantic, pydantic-core, typing-inspection, -r requirements-in.txt
|
||||
@ -106,7 +106,7 @@ ua-parser==1.0.2 # via user-agents
|
||||
ua-parser-builtins==202603 # via ua-parser
|
||||
uiautomator2==2.12.2 # via -r requirements-in.txt
|
||||
uiautomator2cache==0.3.1 # via -r requirements-in.txt
|
||||
urllib3==2.6.3 # via requests
|
||||
urllib3==2.7.0 # via requests
|
||||
user-agents==2.2.0 # via pywebio
|
||||
uvicorn==0.44.0 # via mcp, -r requirements-in.txt
|
||||
uvloop==0.22.1 # via uvicorn
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --annotation-style=line --no-emit-index-url --output-file=requirements.txt --resolver=backtracking requirements-in.txt
|
||||
# uv pip compile requirements-in.txt --annotation-style=line --python-platform windows --python-version 3.14 --output-file requirements.txt
|
||||
adbutils==0.11.0 # via uiautomator2, -r requirements-in.txt
|
||||
aiofiles==23.1.0 # via -r requirements-in.txt
|
||||
annotated-types==0.7.0 # via pydantic
|
||||
@ -55,7 +55,7 @@ mcp==1.23.0 # via -r requirements-in.txt
|
||||
mpmath==1.3.0 # via sympy
|
||||
msgpack==1.0.4 # via zerorpc
|
||||
numba==0.64.0 # via -r requirements-in.txt
|
||||
numpy==2.4.3 # via contourpy, imageio, matplotlib, numba, onnxruntime-directml, opencv-python, rapidocr, scipy, shapely, -r requirements-in.txt
|
||||
numpy==2.4.4 # via contourpy, imageio, matplotlib, numba, onnxruntime-directml, opencv-python, rapidocr, scipy, shapely, -r requirements-in.txt
|
||||
omegaconf==2.3.0 # via rapidocr
|
||||
onepush==1.2.0 # via -r requirements-in.txt
|
||||
onnxruntime-directml==1.24.4 # via -r requirements-in.txt
|
||||
@ -63,7 +63,7 @@ openai==2.30.0 # via -r requirements-in.txt
|
||||
opencv-python==4.13.0.92 # via rapidocr, -r requirements-in.txt
|
||||
packaging==20.9 # via deprecation, matplotlib, onnxruntime-directml, uiautomator2
|
||||
pillow==12.2.0 # via imageio, matplotlib, rapidocr, uiautomator2, -r requirements-in.txt
|
||||
pip==26.0.1 # via -r requirements-in.txt
|
||||
pip==26.1 # via -r requirements-in.txt
|
||||
progress==1.6 # via uiautomator2
|
||||
protobuf==6.33.5 # via onnxruntime-directml
|
||||
psutil==5.9.4 # via -r requirements-in.txt
|
||||
@ -81,7 +81,7 @@ pyparsing==3.0.9 # via matplotlib, packaging
|
||||
pypresence==4.2.1 # via -r requirements-in.txt
|
||||
python-dateutil==2.9.0.post0 # via matplotlib
|
||||
python-dotenv==1.2.2 # via pydantic-settings, uvicorn
|
||||
python-multipart==0.0.26 # via mcp
|
||||
python-multipart==0.0.27 # via mcp
|
||||
pywebio==1.7.1 # via -r requirements-in.txt
|
||||
pywin32==311 # via mcp
|
||||
pyyaml==6.0.3 # via omegaconf, rapidocr, uvicorn, -r requirements-in.txt
|
||||
@ -94,12 +94,12 @@ retrying==1.3.4 # via -r requirements-in.txt
|
||||
rich==11.2.0 # via -r requirements-in.txt
|
||||
rpds-py==0.30.0 # via jsonschema, referencing
|
||||
scipy==1.17.1 # via -r requirements-in.txt
|
||||
setuptools==75.8.2 # via zope-event, zope-interface, -r requirements-in.txt
|
||||
setuptools==78.1.1 # via zope-event, zope-interface, -r requirements-in.txt
|
||||
shapely==2.1.2 # via rapidocr
|
||||
six==1.16.0 # via adbutils, python-dateutil, rapidocr, retrying, uiautomator2
|
||||
sniffio==1.3.0 # via openai
|
||||
sse-starlette==3.0.3 # via mcp, -r requirements-in.txt
|
||||
starlette==0.49.1 # via mcp, -r requirements-in.txt
|
||||
starlette==1.0.0 # via mcp, -r requirements-in.txt
|
||||
sympy==1.14.0 # via onnxruntime-directml
|
||||
tornado==6.5.5 # via pywebio
|
||||
tqdm==4.67.3 # via openai, rapidocr
|
||||
@ -108,7 +108,7 @@ typing-inspection==0.4.2 # via mcp, pydantic, pydantic-settings
|
||||
ua-parser==0.16.1 # via user-agents
|
||||
uiautomator2==2.16.17 # via -r requirements-in.txt
|
||||
uiautomator2cache==0.3.0.1 # via -r requirements-in.txt
|
||||
urllib3==2.6.3 # via requests
|
||||
urllib3==2.7.0 # via requests
|
||||
user-agents==2.2.0 # via pywebio
|
||||
uvicorn==0.44.0 # via mcp, -r requirements-in.txt
|
||||
watchdog==6.0.0 # via -r requirements-in.txt
|
||||
|
||||
@ -340,123 +340,75 @@
|
||||
oc.scale(dpr, dpr);
|
||||
|
||||
if (chartType === 'line') {
|
||||
var visibleStart = Math.max(0, Math.floor(panOffset));
|
||||
var visibleCount = Math.ceil(nn / zoomLevel);
|
||||
var visibleEnd = Math.min(nn, visibleStart + visibleCount);
|
||||
var visibleNn = visibleEnd - visibleStart;
|
||||
|
||||
var dMin = Infinity, dMax = -Infinity;
|
||||
for (var i = visibleStart; i < visibleEnd; i++) {
|
||||
if (ap[i] < dMin) dMin = ap[i];
|
||||
if (ap[i] > dMax) dMax = ap[i];
|
||||
}
|
||||
if (dMin === Infinity) dMin = 0;
|
||||
if (dMax === -Infinity) dMax = 100;
|
||||
var drng = dMax - dMin || 1;
|
||||
dMin -= drng * 0.1;
|
||||
dMax += drng * 0.1;
|
||||
|
||||
var xScale = gW / Math.max(visibleNn - 1, 1);
|
||||
var idx = Math.round(visibleStart + (mx_ - pad.l) / xScale);
|
||||
idx = Math.max(0, Math.min(nn - 1, idx));
|
||||
var px = pad.l + (idx - visibleStart) * xScale;
|
||||
var py = pad.t + gH - (ap[idx] - dMin) / (dMax - dMin) * gH;
|
||||
|
||||
oc.strokeStyle = "rgba(255,255,255,0.18)";
|
||||
oc.lineWidth = 1;
|
||||
oc.setLineDash([4, 3]);
|
||||
oc.beginPath(); oc.moveTo(px, pad.t); oc.lineTo(px, pad.t + gH); oc.stroke();
|
||||
oc.beginPath(); oc.moveTo(pad.l, py); oc.lineTo(W - pad.r, py); oc.stroke();
|
||||
oc.setLineDash([]);
|
||||
|
||||
oc.beginPath(); oc.arc(px, py, 6, 0, Math.PI * 2);
|
||||
oc.fillStyle = "rgba(100,181,246,0.3)"; oc.fill();
|
||||
oc.beginPath(); oc.arc(px, py, 4, 0, Math.PI * 2);
|
||||
oc.fillStyle = "#64b5f6"; oc.fill();
|
||||
oc.strokeStyle = "#fff"; oc.lineWidth = 2; oc.stroke();
|
||||
oc.setTransform(1, 0, 0, 1, 0, 0);
|
||||
|
||||
var diff = idx > 0 ? (ap[idx] - ap[idx - 1]) : 0;
|
||||
var isUp = diff >= 0;
|
||||
var dc = isUp ? "#ef5350" : "#26a69a";
|
||||
var ds = (isUp ? "+" : "") + diff;
|
||||
var tooltipRows = [
|
||||
{ style: { color: "#888", marginBottom: "4px", fontWeight: "600" }, parts: [{ type: 'text', value: labels[idx] }] },
|
||||
{ parts: [{ type: 'text', value: "体力: " }, { type: 'bold', value: String(ap[idx]), style: { color: "#64b5f6" } }] },
|
||||
{ parts: [{ type: 'text', value: "单次变化: " }, { type: 'bold', value: ds, style: { color: dc } }] }
|
||||
];
|
||||
|
||||
if (isDetailMode) {
|
||||
var visibleStart = Math.max(0, Math.floor(panOffset));
|
||||
var visibleCount = Math.ceil(nn / zoomLevel);
|
||||
var visibleEnd = Math.min(nn, visibleStart + visibleCount);
|
||||
var visibleNn = visibleEnd - visibleStart;
|
||||
|
||||
var dMin = Infinity, dMax = -Infinity;
|
||||
for (var i = visibleStart; i < visibleEnd; i++) {
|
||||
if (ap[i] < dMin) dMin = ap[i];
|
||||
if (ap[i] > dMax) dMax = ap[i];
|
||||
}
|
||||
if (dMin === Infinity) dMin = 0;
|
||||
if (dMax === -Infinity) dMax = 100;
|
||||
var drng = dMax - dMin || 1;
|
||||
dMin -= drng * 0.1;
|
||||
dMax += drng * 0.1;
|
||||
|
||||
var xScale = gW / visibleNn;
|
||||
var idx = Math.floor(panOffset + (mx_ - pad.l) / xScale);
|
||||
idx = Math.max(0, Math.min(nn - 1, idx));
|
||||
var px = pad.l + (idx - visibleStart) * xScale;
|
||||
var py = pad.t + gH - (ap[idx] - dMin) / (dMax - dMin) * gH;
|
||||
|
||||
oc.strokeStyle = "rgba(255,255,255,0.18)";
|
||||
oc.lineWidth = 1;
|
||||
oc.setLineDash([4, 3]);
|
||||
oc.beginPath(); oc.moveTo(px, pad.t); oc.lineTo(px, pad.t + gH); oc.stroke();
|
||||
oc.beginPath(); oc.moveTo(pad.l, py); oc.lineTo(W - pad.r, py); oc.stroke();
|
||||
oc.setLineDash([]);
|
||||
|
||||
oc.beginPath(); oc.arc(px, py, 6, 0, Math.PI * 2);
|
||||
oc.fillStyle = "rgba(100,181,246,0.3)"; oc.fill();
|
||||
oc.beginPath(); oc.arc(px, py, 4, 0, Math.PI * 2);
|
||||
oc.fillStyle = "#64b5f6"; oc.fill();
|
||||
oc.strokeStyle = "#fff"; oc.lineWidth = 2; oc.stroke();
|
||||
oc.setTransform(1, 0, 0, 1, 0, 0);
|
||||
|
||||
var diff = idx > 0 ? (ap[idx] - ap[idx - 1]) : 0;
|
||||
var isUp = diff >= 0;
|
||||
var dc = isUp ? "#ef5350" : "#26a69a";
|
||||
var ds = (isUp ? "+" : "") + diff;
|
||||
var source = sources && sources[idx] ? sources[idx] : '-';
|
||||
var sourceColor = source === 'cl1' ? '#64b5f6' : (source === 'meow' ? '#ff9800' : '#888');
|
||||
|
||||
var tooltipRows = [
|
||||
{ style: { color: "#888", marginBottom: "4px", fontWeight: "600" }, parts: [{ type: 'text', value: labels[idx] }] },
|
||||
{ parts: [{ type: 'text', value: "体力: " }, { type: 'bold', value: String(ap[idx]), style: { color: "#64b5f6" } }] },
|
||||
{ parts: [{ type: 'text', value: "单次变化: " }, { type: 'bold', value: ds, style: { color: dc } }] },
|
||||
{ parts: [{ type: 'text', value: "来源: " }, { type: 'bold', value: source, style: { color: sourceColor } }] }
|
||||
];
|
||||
|
||||
if (showCoins && yellowCoinsLen > 0 && idx < yellowCoinsLen && yellowCoins[idx] !== null && yellowCoins[idx] !== undefined) {
|
||||
var yc = yellowCoins[idx];
|
||||
var ycDiff = idx > 0 && yellowCoins[idx - 1] !== null && yellowCoins[idx - 1] !== undefined ? (yc - yellowCoins[idx - 1]) : 0;
|
||||
var ycColor = ycDiff >= 0 ? "#ef5350" : "#26a69a";
|
||||
var ycDiffStr = (ycDiff >= 0 ? "+" : "") + ycDiff;
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "黄币: " }, { type: 'bold', value: String(yc), style: { color: "#ffd54f" } }, { type: 'text', value: " (" + ycDiffStr + ")", style: { color: ycColor } }] });
|
||||
}
|
||||
|
||||
if (showCoins && purpleCoinsLen > 0 && idx < purpleCoinsLen && purpleCoins[idx] !== null && purpleCoins[idx] !== undefined) {
|
||||
var pc = purpleCoins[idx];
|
||||
var pcDiff = idx > 0 && purpleCoins[idx - 1] !== null && purpleCoins[idx - 1] !== undefined ? (pc - purpleCoins[idx - 1]) : 0;
|
||||
var pcColor = pcDiff >= 0 ? "#ef5350" : "#26a69a";
|
||||
var pcDiffStr = (pcDiff >= 0 ? "+" : "") + pcDiff;
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "紫币: " }, { type: 'bold', value: String(pc), style: { color: "#ce93d8" } }, { type: 'text', value: " (" + pcDiffStr + ")", style: { color: pcColor } }] });
|
||||
}
|
||||
|
||||
setTooltipContent(tipEl, tooltipRows);
|
||||
} else {
|
||||
var ratio = (mx_ - pad.l) / gW;
|
||||
var idx = Math.round(ratio * (nn - 1));
|
||||
idx = Math.max(0, Math.min(nn - 1, idx));
|
||||
var px = xOfLine(idx), py = yOf(ap[idx]);
|
||||
|
||||
oc.strokeStyle = "rgba(255,255,255,0.18)";
|
||||
oc.lineWidth = 1;
|
||||
oc.setLineDash([4, 3]);
|
||||
oc.beginPath(); oc.moveTo(px, pad.t); oc.lineTo(px, pad.t + gH); oc.stroke();
|
||||
oc.beginPath(); oc.moveTo(pad.l, py); oc.lineTo(W - pad.r, py); oc.stroke();
|
||||
oc.setLineDash([]);
|
||||
|
||||
oc.beginPath(); oc.arc(px, py, 6, 0, Math.PI * 2);
|
||||
oc.fillStyle = "rgba(100,181,246,0.3)"; oc.fill();
|
||||
oc.beginPath(); oc.arc(px, py, 4, 0, Math.PI * 2);
|
||||
oc.fillStyle = "#64b5f6"; oc.fill();
|
||||
oc.strokeStyle = "#fff"; oc.lineWidth = 2; oc.stroke();
|
||||
oc.setTransform(1, 0, 0, 1, 0, 0);
|
||||
|
||||
var diff = idx > 0 ? (ap[idx] - ap[idx - 1]) : 0;
|
||||
var isUp = diff >= 0;
|
||||
var dc = isUp ? "#ef5350" : "#26a69a";
|
||||
var ds = (isUp ? "+" : "") + diff;
|
||||
|
||||
var tooltipRows = [
|
||||
{ style: { color: "#888", marginBottom: "4px", fontWeight: "600" }, parts: [{ type: 'text', value: labels[idx] }] },
|
||||
{ parts: [{ type: 'text', value: "体力: " }, { type: 'bold', value: String(ap[idx]), style: { color: "#64b5f6" } }] },
|
||||
{ parts: [{ type: 'text', value: "单次变化: " }, { type: 'bold', value: ds, style: { color: dc } }] }
|
||||
];
|
||||
|
||||
if (showCoins && yellowCoinsLen > 0 && idx < yellowCoinsLen && yellowCoins[idx] !== null && yellowCoins[idx] !== undefined) {
|
||||
var yc = yellowCoins[idx];
|
||||
var ycDiff = idx > 0 && yellowCoins[idx - 1] !== null && yellowCoins[idx - 1] !== undefined ? (yc - yellowCoins[idx - 1]) : 0;
|
||||
var ycColor = ycDiff >= 0 ? "#ef5350" : "#26a69a";
|
||||
var ycDiffStr = (ycDiff >= 0 ? "+" : "") + ycDiff;
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "黄币: " }, { type: 'bold', value: String(yc), style: { color: "#ffd54f" } }, { type: 'text', value: " (" + ycDiffStr + ")", style: { color: ycColor } }] });
|
||||
}
|
||||
|
||||
if (showCoins && purpleCoinsLen > 0 && idx < purpleCoinsLen && purpleCoins[idx] !== null && purpleCoins[idx] !== undefined) {
|
||||
var pc = purpleCoins[idx];
|
||||
var pcDiff = idx > 0 && purpleCoins[idx - 1] !== null && purpleCoins[idx - 1] !== undefined ? (pc - purpleCoins[idx - 1]) : 0;
|
||||
var pcColor = pcDiff >= 0 ? "#ef5350" : "#26a69a";
|
||||
var pcDiffStr = (pcDiff >= 0 ? "+" : "") + pcDiff;
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "紫币: " }, { type: 'bold', value: String(pc), style: { color: "#ce93d8" } }, { type: 'text', value: " (" + pcDiffStr + ")", style: { color: pcColor } }] });
|
||||
}
|
||||
|
||||
setTooltipContent(tipEl, tooltipRows);
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "来源: " }, { type: 'bold', value: source, style: { color: sourceColor } }] });
|
||||
}
|
||||
|
||||
if (showCoins && yellowCoinsLen > 0 && idx < yellowCoinsLen && yellowCoins[idx] !== null && yellowCoins[idx] !== undefined) {
|
||||
var yc = yellowCoins[idx];
|
||||
var ycDiff = idx > 0 && yellowCoins[idx - 1] !== null && yellowCoins[idx - 1] !== undefined ? (yc - yellowCoins[idx - 1]) : 0;
|
||||
var ycColor = ycDiff >= 0 ? "#ef5350" : "#26a69a";
|
||||
var ycDiffStr = (ycDiff >= 0 ? "+" : "") + ycDiff;
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "黄币: " }, { type: 'bold', value: String(yc), style: { color: "#ffd54f" } }, { type: 'text', value: " (" + ycDiffStr + ")", style: { color: ycColor } }] });
|
||||
}
|
||||
|
||||
if (showCoins && purpleCoinsLen > 0 && idx < purpleCoinsLen && purpleCoins[idx] !== null && purpleCoins[idx] !== undefined) {
|
||||
var pc = purpleCoins[idx];
|
||||
var pcDiff = idx > 0 && purpleCoins[idx - 1] !== null && purpleCoins[idx - 1] !== undefined ? (pc - purpleCoins[idx - 1]) : 0;
|
||||
var pcColor = pcDiff >= 0 ? "#ef5350" : "#26a69a";
|
||||
var pcDiffStr = (pcDiff >= 0 ? "+" : "") + pcDiff;
|
||||
tooltipRows.push({ parts: [{ type: 'text', value: "紫币: " }, { type: 'bold', value: String(pc), style: { color: "#ce93d8" } }, { type: 'text', value: " (" + pcDiffStr + ")", style: { color: pcColor } }] });
|
||||
}
|
||||
|
||||
setTooltipContent(tipEl, tooltipRows);
|
||||
} else {
|
||||
var idx = Math.floor((mx_ - pad.l) / candleSpace);
|
||||
idx = Math.max(0, Math.min(nn - 1, idx));
|
||||
@ -529,7 +481,7 @@
|
||||
oc.clearRect(0, 0, ovCv.width, ovCv.height);
|
||||
});
|
||||
|
||||
if (isDetailMode) {
|
||||
if (chartType === 'line') {
|
||||
var zoomLevel = 1.0;
|
||||
var panOffset = 0;
|
||||
var maxZoom = 5.0;
|
||||
@ -583,7 +535,7 @@
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "top";
|
||||
|
||||
var xScale = gW / visibleNn;
|
||||
var xScale = gW / Math.max(visibleNn - 1, 1);
|
||||
function dxOf(i) { return pad.l + (i - visibleStart) * xScale; }
|
||||
function dyOf(v) { return pad.t + gH - (v - dMin) / (dMax - dMin) * gH; }
|
||||
|
||||
@ -650,7 +602,7 @@
|
||||
if (!isDragging) return;
|
||||
var dx = e.clientX - dragStartX;
|
||||
var visibleCount = Math.ceil(nn / zoomLevel);
|
||||
var xScale = gW / visibleCount;
|
||||
var xScale = gW / Math.max(visibleCount - 1, 1);
|
||||
var newPan = dragStartPan - dx / xScale;
|
||||
var maxPan = Math.max(0, nn - visibleCount);
|
||||
panOffset = Math.max(0, Math.min(maxPan, newPan));
|
||||
@ -673,10 +625,10 @@
|
||||
if (newZoom !== zoomLevel) {
|
||||
var visibleCountBefore = Math.ceil(nn / zoomLevel);
|
||||
var visibleCountAfter = Math.ceil(nn / newZoom);
|
||||
var xScaleBefore = gW / visibleCountBefore;
|
||||
var xScaleBefore = gW / Math.max(visibleCountBefore - 1, 1);
|
||||
var mouseIdx = panOffset + (mx - pad.l) / xScaleBefore;
|
||||
zoomLevel = newZoom;
|
||||
var xScaleAfter = gW / visibleCountAfter;
|
||||
var xScaleAfter = gW / Math.max(visibleCountAfter - 1, 1);
|
||||
panOffset = Math.max(0, mouseIdx - (mx - pad.l) / xScaleAfter);
|
||||
var maxPan = Math.max(0, nn - visibleCountAfter);
|
||||
panOffset = Math.max(0, Math.min(maxPan, panOffset));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user