1
0
mirror of https://github.com/TheFunny/ArisuAutoSweeper synced 2026-06-23 22:44:51 +00:00

74 Commits

Author SHA1 Message Date
YoursFunny 0d1c936541 fix: update assets file 2025-09-23 20:03:39 +08:00
YoursFunny 6581511e1a fix: update configs to enable new bounty stage for OVERSEA server 2025-09-23 20:03:20 +08:00
YoursFunny c562913778 fix: update ui assets for en 2025-09-23 20:03:19 +08:00
YoursFunny 95148d2548 fix: update assets file 2025-08-09 13:20:45 +08:00
YoursFunny 44605f42cd fix: update ui assets for OVERSEA server 2025-08-09 13:20:21 +08:00
YoursFunny fdc50c77a5 fix: update assets file 2025-07-22 20:21:06 +08:00
YoursFunny 15ebf70681 fix: update ui assets for jp 2025-07-22 20:20:36 +08:00
YoursFunny b34c37a4b7 fix: update configs 2025-05-18 19:58:36 +08:00
YoursFunny 92408edd79 fix(bounty): update stage select option 2025-05-18 19:58:35 +08:00
YoursFunny 49c0894227 fix: update assets file 2025-05-13 21:56:02 +08:00
YoursFunny 1497a0a825 fix(cafe): update ui assets for jp & en 2025-05-13 21:55:42 +08:00
YoursFunny e41b8bf54a fix(cafe): synchronize Cafe No.2 for global server 2025-05-13 21:55:41 +08:00
YoursFunny cae02d62ec fix: update assets file 2025-04-22 19:54:32 +08:00
YoursFunny b16d25f9f5 fix: update ui assets for jp 2025-04-22 19:53:39 +08:00
YoursFunny 6cd0ded0c9 fix(cafe): correct invitation detection of Cafe No.2 in OVERSEA server 2025-03-08 18:44:34 +08:00
YoursFunny 62c147fdab fix(cafe): adjust timer of Cafe No.2 2025-01-22 19:40:43 +08:00
YoursFunny 5d4c5f939b fix(cafe): adjust click template offset 2025-01-22 19:40:32 +08:00
YoursFunny e6649762c8 fix: update assets file 2025-01-20 23:19:29 +08:00
YoursFunny 8cb4803f80 fix(cafe): update ui assets for jp 2025-01-20 23:18:06 +08:00
YoursFunny 51c7a5fed2 fix(cafe): update latest Cafe No.2 switch for jp 2025-01-20 23:17:39 +08:00
YoursFunny e7ecf0e94f fix: update assets file 2024-11-12 18:16:45 +08:00
YoursFunny 2a1394d733 fix(cafe): update ui assets for en 2024-11-12 18:16:45 +08:00
YoursFunny 164dee90d9 lang(cafe): correct Cafe No.2 description 2024-11-12 18:16:44 +08:00
YoursFunny f0da132f4e fix(cafe): enable Cafe No.2 for OVERSEA server 2024-11-12 18:03:30 +08:00
YoursFunny 191c3b31dc fix: update assets file 2024-10-23 23:32:55 +08:00
YoursFunny a5d20a95be fix: update ui assets for en 2024-10-23 23:32:47 +08:00
YoursFunny 7f0b2ff73f fix: update assets file 2024-09-24 14:07:02 +08:00
YoursFunny daf55b76e2 fix: update ui assets for en 2024-09-24 14:06:27 +08:00
YoursFunny 5b2e22163a fix: update assets file 2024-07-24 17:27:50 +08:00
YoursFunny 2ec7e45172 fix: update ui assets and circle for en 2024-07-24 17:27:38 +08:00
YoursFunny cd27718801 fix: update assets file 2024-07-11 18:03:37 +08:00
YoursFunny 2b12f51110 fix: update jp ui assets 2024-07-11 18:02:45 +08:00
YoursFunny a059394b71 fix: update assets file 2024-07-09 16:05:05 +08:00
YoursFunny cdccc85207 fix: update en ui assets 2024-07-09 16:04:18 +08:00
YoursFunny 9a1d8f101d fix: update assets file 2024-05-04 20:15:01 +08:00
YoursFunny bb5224d721 fix: update en ui assets 2024-05-04 20:11:50 +08:00
YoursFunny 573d742c03 fix: update assets file 2024-05-04 19:55:41 +08:00
YoursFunny f9076ae537 fix: update en ui assets 2024-05-04 19:54:57 +08:00
YoursFunny 9d9e3c0f91 fix: update ui assets for jp 2024-04-24 19:38:24 +08:00
YoursFunny c6063a4f3d fix: update ui assets for jp 2024-03-27 20:35:23 +08:00
YoursFunny b9cf5aa910 fix: update ui assets for jp 2024-02-21 18:26:00 +08:00
YoursFunny d082df0f03 fix: update ui assets and circle for jp 2024-01-25 19:40:09 +08:00
Cheong Sik Feng 2f44074400 Fix Tactical Challenge button mask image
With the addition of the Grand Assault, the Joint Firing Drill button was moved to the top half of where the Tactical Challenge button previously was, and the new Tactical Challenge button is only the lower half.
2023-12-25 16:26:57 +08:00
YoursFunny 0f6dd93608 fix(sweep): remove index if equal 0 2023-12-09 21:22:11 +08:00
YoursFunny f5cf0a7fbe fix(tc): add handle ui_additional 2023-12-07 18:24:09 +08:00
YoursFunny 16d78e1e16 fix(sweep): correct load index situation 2023-12-07 13:04:05 +08:00
YoursFunny 7b707be841 refactor(scrimmage): use stage ap count 2023-12-06 17:11:50 +08:00
YoursFunny 93bf1f73e2 feat: separate stage ap count 2023-12-05 16:21:19 +08:00
YoursFunny 71da6fd996 feat: add auto select for bounty and scrimmage 2023-11-30 14:21:19 +08:00
YoursFunny ecd4ba0a7c doc: update readme 2023-11-29 18:38:59 +08:00
YoursFunny d684fd79f6 feat(sweep): support finding max sweepable index 2023-11-29 14:55:55 +08:00
YoursFunny 6ae785634c refactor(sweep): separate sweepable check and search_box generate 2023-11-29 14:11:51 +08:00
YoursFunny a0d3fd75af refactor(sweep): change current_indexes 2023-11-29 14:05:50 +08:00
YoursFunny 257e092936 refactor(sweep): use regex for index match 2023-11-29 13:54:55 +08:00
YoursFunny 32cee3f6b5 fix(cafe): adjust name of invitation 2023-11-29 12:39:51 +08:00
YoursFunny 659f58db38 fix(cafe): add check of null invitation name 2023-11-28 21:46:21 +08:00
YoursFunny 6dac8a1de2 feat(cafe): add invitation assets for en 2023-11-28 20:53:24 +08:00
YoursFunny b1aeb64768 lang: change option description 2023-11-28 20:53:01 +08:00
YoursFunny 88e8a98b76 fix(cafe): apply config of choice only when not set before 2023-11-28 16:18:34 +08:00
YoursFunny 39d00ac549 fix(cafe): correct target name check 2023-11-28 16:11:50 +08:00
YoursFunny 11d2a6ef7e feat(cafe): add invitation condition check 2023-11-28 14:04:37 +08:00
YoursFunny 1f5b68d095 feat(webui): add invitation condition options 2023-11-28 14:04:07 +08:00
YoursFunny 5f3ff140dd feat(cafe): add invitation 2023-11-27 22:02:50 +08:00
YoursFunny 8698fa20c2 feat(webui): add config of invitation options 2023-11-27 20:48:37 +08:00
YoursFunny b426c6caac feat(cafe): add invitation assets for jp 2023-11-27 15:44:56 +08:00
YoursFunny 8d83ec1657 fix: add swipe name 2023-11-27 15:26:27 +08:00
YoursFunny 7fcda15329 perf(sweep): improve list insight logic 2023-11-27 13:17:29 +08:00
YoursFunny 54aa1bafb5 refactor(sweep): simplify list enter match 2023-11-26 18:54:26 +08:00
YoursFunny d756b0dc3f perf: reduce config save times 2023-11-25 15:28:57 +08:00
YoursFunny e71118c09e fix: improve data update stability 2023-11-25 15:28:07 +08:00
YoursFunny 44b6d5cdf8 fix: expand ticket ocr region 2023-11-25 14:27:01 +08:00
YoursFunny f92dba92c9 fix(sweep): use swipe instead of drag in list 2023-11-24 14:30:43 +08:00
YoursFunny 86ce04cff9 fix(sweep): extend timer stable 2023-11-24 13:59:39 +08:00
YoursFunny f2065507c2 fix(ui): change task order 2023-11-23 16:37:16 +08:00
105 changed files with 1117 additions and 395 deletions
+1 -1
View File
@@ -12,7 +12,7 @@
The script is still under active development. The following features have been implemented: The script is still under active development. The following features have been implemented:
- [x] **Cafe** Claim rewards / Interact / Second floor - [x] **Cafe** Claim rewards / Interact / Invitation / Second floor
- [x] **Club** Claim AP - [x] **Club** Claim AP
- [x] **Mailbox** Claim rewards - [x] **Mailbox** Claim rewards
- [x] **Bounty** Auto sweep - [x] **Bounty** Auto sweep
+1 -1
View File
@@ -12,7 +12,7 @@
当前脚本还在活跃开发中,已经实现的功能有: 当前脚本还在活跃开发中,已经实现的功能有:
- [x] **咖啡厅** 领取奖励 / 互动 / 第二咖啡厅 - [x] **咖啡厅** 领取奖励 / 互动 / 邀请 / 第二咖啡厅
- [x] **公会** 领取体力 - [x] **公会** 领取体力
- [x] **邮箱** 领取奖励 - [x] **邮箱** 领取奖励
- [x] **悬赏通缉** 自动扫荡 - [x] **悬赏通缉** 自动扫荡
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

+20 -13
View File
@@ -45,14 +45,13 @@
"Touch": true, "Touch": true,
"AutoAdjust": true, "AutoAdjust": true,
"SecondCafe": true "SecondCafe": true
} },
}, "Invitation": {
"Mail": {
"Scheduler": {
"Enable": true, "Enable": true,
"NextRun": "2020-01-01 00:00:00", "WaitingHour": 0,
"Command": "Mail", "Choice": "list_top",
"ServerUpdate": "04:00" "Name": null,
"Substitute": false
} }
}, },
"Circle": { "Circle": {
@@ -63,6 +62,14 @@
"ServerUpdate": "04:00" "ServerUpdate": "04:00"
} }
}, },
"Mail": {
"Scheduler": {
"Enable": true,
"NextRun": "2020-01-01 00:00:00",
"Command": "Mail",
"ServerUpdate": "04:00"
}
},
"Bounty": { "Bounty": {
"Scheduler": { "Scheduler": {
"Enable": true, "Enable": true,
@@ -74,15 +81,15 @@
"OnError": "skip" "OnError": "skip"
}, },
"Highway": { "Highway": {
"Stage": 1, "Stage": 0,
"Count": 2 "Count": 2
}, },
"DesertRailroad": { "DesertRailroad": {
"Stage": 1, "Stage": 0,
"Count": 2 "Count": 2
}, },
"Schoolhouse": { "Schoolhouse": {
"Stage": 1, "Stage": 0,
"Count": 2 "Count": 2
} }
}, },
@@ -97,15 +104,15 @@
"OnError": "skip" "OnError": "skip"
}, },
"Trinity": { "Trinity": {
"Stage": 1, "Stage": 0,
"Count": 2 "Count": 2
}, },
"Gehenna": { "Gehenna": {
"Stage": 1, "Stage": 0,
"Count": 2 "Count": 2
}, },
"Millennium": { "Millennium": {
"Stage": 1, "Stage": 0,
"Count": 2 "Count": 2
} }
}, },
+69 -28
View File
@@ -205,32 +205,37 @@
"type": "checkbox", "type": "checkbox",
"value": true "value": true
} }
} },
}, "Invitation": {
"Mail": {
"Scheduler": {
"Enable": { "Enable": {
"type": "checkbox", "type": "checkbox",
"value": true, "value": true
},
"WaitingHour": {
"type": "select",
"value": 0,
"option": [ "option": [
true, 0,
false 3,
6,
9
] ]
}, },
"NextRun": { "Choice": {
"type": "datetime", "type": "select",
"value": "2020-01-01 00:00:00", "value": "list_top",
"validate": "datetime" "option": [
"list_top",
"by_name"
]
}, },
"Command": { "Name": {
"type": "input", "type": "textarea",
"value": "Mail", "value": null
"display": "hide"
}, },
"ServerUpdate": { "Substitute": {
"type": "input", "type": "checkbox",
"value": "04:00", "value": false
"display": "hide"
} }
} }
}, },
@@ -261,6 +266,33 @@
} }
} }
}, },
"Mail": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"value": true,
"option": [
true,
false
]
},
"NextRun": {
"type": "datetime",
"value": "2020-01-01 00:00:00",
"validate": "datetime"
},
"Command": {
"type": "input",
"value": "Mail",
"display": "hide"
},
"ServerUpdate": {
"type": "input",
"value": "04:00",
"display": "hide"
}
}
},
"Bounty": { "Bounty": {
"Scheduler": { "Scheduler": {
"Enable": { "Enable": {
@@ -300,8 +332,9 @@
"Highway": { "Highway": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 1, "value": 0,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@@ -310,7 +343,8 @@
6, 6,
7, 7,
8, 8,
9 9,
10
] ]
}, },
"Count": { "Count": {
@@ -321,8 +355,9 @@
"DesertRailroad": { "DesertRailroad": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 1, "value": 0,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@@ -331,7 +366,8 @@
6, 6,
7, 7,
8, 8,
9 9,
10
] ]
}, },
"Count": { "Count": {
@@ -342,8 +378,9 @@
"Schoolhouse": { "Schoolhouse": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 1, "value": 0,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@@ -352,7 +389,8 @@
6, 6,
7, 7,
8, 8,
9 9,
10
] ]
}, },
"Count": { "Count": {
@@ -400,8 +438,9 @@
"Trinity": { "Trinity": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 1, "value": 0,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@@ -416,8 +455,9 @@
"Gehenna": { "Gehenna": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 1, "value": 0,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@@ -432,8 +472,9 @@
"Millennium": { "Millennium": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 1, "value": 0,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
+24 -12
View File
@@ -80,6 +80,18 @@ Cafe:
Touch: true Touch: true
AutoAdjust: true AutoAdjust: true
SecondCafe: true SecondCafe: true
Invitation:
Enable: true
WaitingHour:
value: 0
option: [ 0, 3, 6, 9 ]
Choice:
value: list_top
option: [ list_top, by_name ]
Name:
value: null
type: textarea
Substitute: false
Bounty: Bounty:
OnError: OnError:
@@ -88,18 +100,18 @@ Bounty:
Highway: Highway:
Stage: Stage:
value: 1 value: 0
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] option: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Count: 2 Count: 2
DesertRailroad: DesertRailroad:
Stage: Stage:
value: 1 value: 0
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] option: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Count: 2 Count: 2
Schoolhouse: Schoolhouse:
Stage: Stage:
value: 1 value: 0
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] option: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Count: 2 Count: 2
Scrimmage: Scrimmage:
@@ -109,18 +121,18 @@ Scrimmage:
Trinity: Trinity:
Stage: Stage:
value: 1 value: 0
option: [ 1, 2, 3, 4 ] option: [ 0, 1, 2, 3, 4 ]
Count: 2 Count: 2
Gehenna: Gehenna:
Stage: Stage:
value: 1 value: 0
option: [ 1, 2, 3, 4 ] option: [ 0, 1, 2, 3, 4 ]
Count: 2 Count: 2
Millennium: Millennium:
Stage: Stage:
value: 1 value: 0
option: [ 1, 2, 3, 4 ] option: [ 0, 1, 2, 3, 4 ]
Count: 2 Count: 2
TacticalChallenge: TacticalChallenge:
+1 -1
View File
@@ -12,8 +12,8 @@
"page": "setting", "page": "setting",
"tasks": [ "tasks": [
"Cafe", "Cafe",
"Mail",
"Circle", "Circle",
"Mail",
"Bounty", "Bounty",
"Scrimmage", "Scrimmage",
"TacticalChallenge", "TacticalChallenge",
+3 -2
View File
@@ -25,10 +25,11 @@ Daily:
Cafe: Cafe:
- Scheduler - Scheduler
- Cafe - Cafe
Mail: - Invitation
- Scheduler
Circle: Circle:
- Scheduler - Scheduler
Mail:
- Scheduler
Bounty: Bounty:
- Scheduler - Scheduler
- Bounty - Bounty
+13 -6
View File
@@ -45,34 +45,41 @@ class GeneratedConfig:
Cafe_AutoAdjust = True Cafe_AutoAdjust = True
Cafe_SecondCafe = True Cafe_SecondCafe = True
# Group `Invitation`
Invitation_Enable = True
Invitation_WaitingHour = 0 # 0, 3, 6, 9
Invitation_Choice = 'list_top' # list_top, by_name
Invitation_Name = None
Invitation_Substitute = False
# Group `Bounty` # Group `Bounty`
Bounty_OnError = 'skip' # stop, skip Bounty_OnError = 'skip' # stop, skip
# Group `Highway` # Group `Highway`
Highway_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9 Highway_Stage = 0 # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Highway_Count = 2 Highway_Count = 2
# Group `DesertRailroad` # Group `DesertRailroad`
DesertRailroad_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9 DesertRailroad_Stage = 0 # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
DesertRailroad_Count = 2 DesertRailroad_Count = 2
# Group `Schoolhouse` # Group `Schoolhouse`
Schoolhouse_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9 Schoolhouse_Stage = 0 # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Schoolhouse_Count = 2 Schoolhouse_Count = 2
# Group `Scrimmage` # Group `Scrimmage`
Scrimmage_OnError = 'skip' # stop, skip Scrimmage_OnError = 'skip' # stop, skip
# Group `Trinity` # Group `Trinity`
Trinity_Stage = 1 # 1, 2, 3, 4 Trinity_Stage = 0 # 0, 1, 2, 3, 4
Trinity_Count = 2 Trinity_Count = 2
# Group `Gehenna` # Group `Gehenna`
Gehenna_Stage = 1 # 1, 2, 3, 4 Gehenna_Stage = 0 # 0, 1, 2, 3, 4
Gehenna_Count = 2 Gehenna_Count = 2
# Group `Millennium` # Group `Millennium`
Millennium_Stage = 1 # 1, 2, 3, 4 Millennium_Stage = 0 # 0, 1, 2, 3, 4
Millennium_Count = 2 Millennium_Count = 2
# Group `TacticalChallenge` # Group `TacticalChallenge`
+49 -8
View File
@@ -22,14 +22,14 @@
"name": "Cafe", "name": "Cafe",
"help": "" "help": ""
}, },
"Mail": {
"name": "Mailbox",
"help": ""
},
"Circle": { "Circle": {
"name": "Club", "name": "Club",
"help": "" "help": ""
}, },
"Mail": {
"name": "Mailbox",
"help": ""
},
"Bounty": { "Bounty": {
"name": "Bounty", "name": "Bounty",
"help": "" "help": ""
@@ -218,7 +218,39 @@
}, },
"SecondCafe": { "SecondCafe": {
"name": "Second Floor", "name": "Second Floor",
"help": "JP server only\nEnable auto switch to second floor and perform interaction" "help": "Enable auto switch to second floor and perform interaction"
}
},
"Invitation": {
"_info": {
"name": "Invitation Settings",
"help": ""
},
"Enable": {
"name": "Enable",
"help": "Enable cafe invitation"
},
"WaitingHour": {
"name": "Invitation Condition",
"help": "Choose whether to invite students based on the remaining time before next cafe refresh\nThis is for obtaining maximum student interation and maximum affection when AFK. Recommended option:\n24*7 AFK:\t\t Choose \"If 9 more hours remaining\"\nNormal usage:\t Choose \"Invite immediately\"",
"0": "Invite immediately",
"3": "If 3 more hours remaining",
"6": "If 6 more hours remaining",
"9": "If 9 more hours remaining"
},
"Choice": {
"name": "Choose Inviting Student",
"help": "Top first student of list: Invite the student at the top first of the list\nBy name: Invite the student with the name you set below",
"list_top": "Top first student of list",
"by_name": "By name"
},
"Name": {
"name": "Inviting Student Name",
"help": "Fill in the name of the student to be invited. Use in-game text language. Use > to connect multiple students. Example:\nJP: ホシノ(水着) > 御坂美琴 > ユズ\nOVERSEA: Hoshino(Swimsuit) > Yuuka > Kayoko(New Year)"
},
"Substitute": {
"name": "Replace existing student",
"help": "Whether to replace the existing student with their alt.\nIf not, try to match the next student"
} }
}, },
"Bounty": { "Bounty": {
@@ -241,6 +273,7 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Overpass A", "1": "01 - Overpass A",
"2": "02 - Overpass B", "2": "02 - Overpass B",
"3": "03 - Overpass C", "3": "03 - Overpass C",
@@ -249,7 +282,8 @@
"6": "06 - Overpass F", "6": "06 - Overpass F",
"7": "07 - Overpass G", "7": "07 - Overpass G",
"8": "08 - Overpass H", "8": "08 - Overpass H",
"9": "09 - Overpass I" "9": "09 - Overpass I",
"10": "10 - Overpass J"
}, },
"Count": { "Count": {
"name": "Sweep X times", "name": "Sweep X times",
@@ -264,6 +298,7 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Abandoned Train A", "1": "01 - Abandoned Train A",
"2": "02 - Abandoned Train B", "2": "02 - Abandoned Train B",
"3": "03 - Abandoned Train C", "3": "03 - Abandoned Train C",
@@ -272,7 +307,8 @@
"6": "06 - Abandoned Train F", "6": "06 - Abandoned Train F",
"7": "07 - Abandoned Train G", "7": "07 - Abandoned Train G",
"8": "08 - Abandoned Train H", "8": "08 - Abandoned Train H",
"9": "09 - Abandoned Train I" "9": "09 - Abandoned Train I",
"10": "10 - Abandoned Train J"
}, },
"Count": { "Count": {
"name": "Sweep X times", "name": "Sweep X times",
@@ -287,6 +323,7 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Besieged Classroom A", "1": "01 - Besieged Classroom A",
"2": "02 - Besieged Classroom B", "2": "02 - Besieged Classroom B",
"3": "03 - Besieged Classroom C", "3": "03 - Besieged Classroom C",
@@ -295,7 +332,8 @@
"6": "06 - Besieged Classroom F", "6": "06 - Besieged Classroom F",
"7": "07 - Besieged Classroom G", "7": "07 - Besieged Classroom G",
"8": "08 - Besieged Classroom H", "8": "08 - Besieged Classroom H",
"9": "09 - Besieged Classroom I" "9": "09 - Besieged Classroom I",
"10": "10 - Besieged Classroom J"
}, },
"Count": { "Count": {
"name": "Sweep X times", "name": "Sweep X times",
@@ -322,6 +360,7 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Trinity A", "1": "01 - Trinity A",
"2": "02 - Trinity B", "2": "02 - Trinity B",
"3": "03 - Trinity C", "3": "03 - Trinity C",
@@ -340,6 +379,7 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Gehenna A", "1": "01 - Gehenna A",
"2": "02 - Gehenna B", "2": "02 - Gehenna B",
"3": "03 - Gehenna C", "3": "03 - Gehenna C",
@@ -358,6 +398,7 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Millennium A", "1": "01 - Millennium A",
"2": "02 - Millennium B", "2": "02 - Millennium B",
"3": "03 - Millennium C", "3": "03 - Millennium C",
+49 -8
View File
@@ -22,14 +22,14 @@
"name": "咖啡厅", "name": "咖啡厅",
"help": "" "help": ""
}, },
"Mail": {
"name": "邮箱",
"help": ""
},
"Circle": { "Circle": {
"name": "公会", "name": "公会",
"help": "社团 / 小组" "help": "社团 / 小组"
}, },
"Mail": {
"name": "邮箱",
"help": ""
},
"Bounty": { "Bounty": {
"name": "悬赏通缉", "name": "悬赏通缉",
"help": "" "help": ""
@@ -218,7 +218,39 @@
}, },
"SecondCafe": { "SecondCafe": {
"name": "第二咖啡厅", "name": "第二咖啡厅",
"help": "仅支持日服\n自动切换第二咖啡厅进行互动点击" "help": "自动切换第二咖啡厅进行互动点击"
}
},
"Invitation": {
"_info": {
"name": "邀请设置",
"help": ""
},
"Enable": {
"name": "启用",
"help": "是否启用咖啡厅邀请功能"
},
"WaitingHour": {
"name": "邀请条件",
"help": "根据距离下一次咖啡厅刷新的时长,选择是否邀请学生\n此项设立是为了后台挂机最大化收益,使得邀请券能被最大化利用。推荐选项:\n常驻挂机:\t选择“离下次刷新 9 小时以上”\n非常驻挂机:\t选择“不等待刷新,立即邀请”,或根据自己挂机时长选择",
"0": "不等待刷新,立即邀请",
"3": "离下次刷新 3 小时以上",
"6": "离下次刷新 6 小时以上",
"9": "离下次刷新 9 小时以上"
},
"Choice": {
"name": "选择邀请学生",
"help": "按列表第一个:优先邀请列表中第一个学生,若失败则则尝试下一个\n按名字:优先邀请下方填写学生名的第一个,若失败则尝试下一个",
"list_top": "按列表第一个",
"by_name": "按名字"
},
"Name": {
"name": "邀请学生名",
"help": "填写要邀请的学生的名字,使用游戏内语言填写,多个学生使用 > 连接。例:\n日服:\tホシノ(水着) > 御坂美琴 > ユズ\n国际服:\tHoshino(Swimsuit) > Yuuka > Kayoko(New Year)"
},
"Substitute": {
"name": "是否替换已存在学生",
"help": "若咖啡厅已存在所邀请学生的不同服装,选择是否替换该学生\n若不替换,则尝试匹配下一位学生"
} }
}, },
"Bounty": { "Bounty": {
@@ -241,6 +273,7 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 高架公路 A", "1": "01 - 高架公路 A",
"2": "02 - 高架公路 B", "2": "02 - 高架公路 B",
"3": "03 - 高架公路 C", "3": "03 - 高架公路 C",
@@ -249,7 +282,8 @@
"6": "06 - 高架公路 F", "6": "06 - 高架公路 F",
"7": "07 - 高架公路 G", "7": "07 - 高架公路 G",
"8": "08 - 高架公路 H", "8": "08 - 高架公路 H",
"9": "09 - 高架公路 I" "9": "09 - 高架公路 I",
"10": "10 - 高架公路 J"
}, },
"Count": { "Count": {
"name": "扫荡次数", "name": "扫荡次数",
@@ -264,6 +298,7 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 被遗弃的列车 A", "1": "01 - 被遗弃的列车 A",
"2": "02 - 被遗弃的列车 B", "2": "02 - 被遗弃的列车 B",
"3": "03 - 被遗弃的列车 C", "3": "03 - 被遗弃的列车 C",
@@ -272,7 +307,8 @@
"6": "06 - 被遗弃的列车 F", "6": "06 - 被遗弃的列车 F",
"7": "07 - 被遗弃的列车 G", "7": "07 - 被遗弃的列车 G",
"8": "08 - 被遗弃的列车 H", "8": "08 - 被遗弃的列车 H",
"9": "09 - 被遗弃的列车 I" "9": "09 - 被遗弃的列车 I",
"10": "10 - 被遗弃的列车 J"
}, },
"Count": { "Count": {
"name": "扫荡次数", "name": "扫荡次数",
@@ -287,6 +323,7 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 被袭击的教室 A", "1": "01 - 被袭击的教室 A",
"2": "02 - 被袭击的教室 B", "2": "02 - 被袭击的教室 B",
"3": "03 - 被袭击的教室 C", "3": "03 - 被袭击的教室 C",
@@ -295,7 +332,8 @@
"6": "06 - 被袭击的教室 F", "6": "06 - 被袭击的教室 F",
"7": "07 - 被袭击的教室 G", "7": "07 - 被袭击的教室 G",
"8": "08 - 被袭击的教室 H", "8": "08 - 被袭击的教室 H",
"9": "09 - 被袭击的教室 I" "9": "09 - 被袭击的教室 I",
"10": "10 - 被袭击的教室 J"
}, },
"Count": { "Count": {
"name": "扫荡次数", "name": "扫荡次数",
@@ -322,6 +360,7 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 三一 A", "1": "01 - 三一 A",
"2": "02 - 三一 B", "2": "02 - 三一 B",
"3": "03 - 三一 C", "3": "03 - 三一 C",
@@ -340,6 +379,7 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 格黑娜 A", "1": "01 - 格黑娜 A",
"2": "02 - 格黑娜 B", "2": "02 - 格黑娜 B",
"3": "03 - 格黑娜 C", "3": "03 - 格黑娜 C",
@@ -358,6 +398,7 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 千年 A", "1": "01 - 千年 A",
"2": "02 - 千年 B", "2": "02 - 千年 B",
"3": "03 - 千年 C", "3": "03 - 千年 C",
+72 -72
View File
@@ -51,17 +51,17 @@ CAFE_CHECK = ButtonWrapper(
name='CAFE_CHECK', name='CAFE_CHECK',
jp=Button( jp=Button(
file='./assets/jp/base/page/CAFE_CHECK.png', file='./assets/jp/base/page/CAFE_CHECK.png',
area=(264, 11, 337, 35), area=(108, 11, 182, 36),
search=(244, 0, 357, 55), search=(88, 0, 202, 56),
color=(188, 197, 205), color=(191, 200, 208),
button=(264, 11, 337, 35), button=(108, 11, 182, 36),
), ),
en=Button( en=Button(
file='./assets/en/base/page/CAFE_CHECK.png', file='./assets/en/base/page/CAFE_CHECK.png',
area=(196, 8, 259, 37), area=(106, 12, 167, 36),
search=(176, 0, 279, 57), search=(86, 0, 187, 56),
color=(188, 197, 206), color=(173, 184, 194),
button=(196, 8, 259, 37), button=(106, 12, 167, 36),
), ),
) )
CIRCLE_CHECK = ButtonWrapper( CIRCLE_CHECK = ButtonWrapper(
@@ -183,10 +183,10 @@ MAIN_GO_TO_CIRCLE = ButtonWrapper(
name='MAIN_GO_TO_CIRCLE', name='MAIN_GO_TO_CIRCLE',
share=Button( share=Button(
file='./assets/share/base/page/MAIN_GO_TO_CIRCLE.png', file='./assets/share/base/page/MAIN_GO_TO_CIRCLE.png',
area=(540, 631, 583, 660), area=(542, 630, 581, 665),
search=(520, 611, 603, 680), search=(522, 610, 601, 685),
color=(131, 204, 234), color=(163, 225, 242),
button=(540, 631, 583, 660), button=(542, 630, 581, 665),
), ),
) )
MAIN_GO_TO_CRAFTING = ButtonWrapper( MAIN_GO_TO_CRAFTING = ButtonWrapper(
@@ -233,10 +233,10 @@ MAIN_GO_TO_PURCHASE = ButtonWrapper(
name='MAIN_GO_TO_PURCHASE', name='MAIN_GO_TO_PURCHASE',
share=Button( share=Button(
file='./assets/share/base/page/MAIN_GO_TO_PURCHASE.png', file='./assets/share/base/page/MAIN_GO_TO_PURCHASE.png',
area=(148, 204, 183, 253), area=(147, 214, 179, 254),
search=(128, 184, 203, 273), search=(127, 194, 199, 274),
color=(172, 214, 239), color=(171, 216, 241),
button=(148, 204, 183, 253), button=(147, 214, 179, 254),
), ),
) )
MAIN_GO_TO_SCHEDULE = ButtonWrapper( MAIN_GO_TO_SCHEDULE = ButtonWrapper(
@@ -273,17 +273,17 @@ MAIN_GO_TO_WORK = ButtonWrapper(
name='MAIN_GO_TO_WORK', name='MAIN_GO_TO_WORK',
jp=Button( jp=Button(
file='./assets/jp/base/page/MAIN_GO_TO_WORK.png', file='./assets/jp/base/page/MAIN_GO_TO_WORK.png',
area=(1167, 605, 1241, 632), area=(1169, 588, 1239, 612),
search=(1147, 585, 1261, 652), search=(1149, 568, 1259, 632),
color=(135, 149, 169), color=(150, 162, 180),
button=(1167, 605, 1241, 632), button=(1169, 588, 1239, 612),
), ),
en=Button( en=Button(
file='./assets/en/base/page/MAIN_GO_TO_WORK.png', file='./assets/en/base/page/MAIN_GO_TO_WORK.png',
area=(1127, 605, 1250, 637), area=(1143, 591, 1241, 613),
search=(1107, 585, 1270, 657), search=(1123, 571, 1261, 633),
color=(90, 112, 141), color=(110, 129, 154),
button=(1127, 605, 1250, 637), button=(1143, 591, 1241, 613),
), ),
) )
MISSION_CHECK = ButtonWrapper( MISSION_CHECK = ButtonWrapper(
@@ -446,101 +446,101 @@ WORK_GO_TO_BOUNTY = ButtonWrapper(
name='WORK_GO_TO_BOUNTY', name='WORK_GO_TO_BOUNTY',
jp=Button( jp=Button(
file='./assets/jp/base/page/WORK_GO_TO_BOUNTY.png', file='./assets/jp/base/page/WORK_GO_TO_BOUNTY.png',
area=(669, 412, 765, 436), area=(667, 383, 764, 409),
search=(649, 392, 785, 456), search=(647, 363, 784, 429),
color=(165, 181, 208), color=(171, 187, 212),
button=(669, 412, 765, 436), button=(667, 383, 764, 409),
), ),
en=Button( en=Button(
file='./assets/en/base/page/WORK_GO_TO_BOUNTY.png', file='./assets/en/base/page/WORK_GO_TO_BOUNTY.png',
area=(671, 409, 760, 440), area=(668, 385, 756, 412),
search=(651, 389, 780, 460), search=(648, 365, 776, 432),
color=(183, 202, 227), color=(180, 198, 223),
button=(671, 409, 760, 440), button=(668, 385, 756, 412),
), ),
) )
WORK_GO_TO_COMMISSIONS = ButtonWrapper( WORK_GO_TO_COMMISSIONS = ButtonWrapper(
name='WORK_GO_TO_COMMISSIONS', name='WORK_GO_TO_COMMISSIONS',
jp=Button( jp=Button(
file='./assets/jp/base/page/WORK_GO_TO_COMMISSIONS.png', file='./assets/jp/base/page/WORK_GO_TO_COMMISSIONS.png',
area=(655, 494, 751, 518), area=(653, 475, 749, 501),
search=(635, 474, 771, 538), search=(633, 455, 769, 521),
color=(165, 179, 204), color=(171, 185, 208),
button=(655, 494, 751, 518), button=(653, 475, 749, 501),
), ),
en=Button( en=Button(
file='./assets/en/base/page/WORK_GO_TO_COMMISSIONS.png', file='./assets/en/base/page/WORK_GO_TO_COMMISSIONS.png',
area=(656, 494, 803, 517), area=(653, 477, 787, 496),
search=(636, 474, 823, 537), search=(633, 457, 807, 516),
color=(192, 204, 221), color=(187, 199, 218),
button=(656, 494, 803, 517), button=(653, 477, 787, 496),
), ),
) )
WORK_GO_TO_MISSION = ButtonWrapper( WORK_GO_TO_MISSION = ButtonWrapper(
name='WORK_GO_TO_MISSION', name='WORK_GO_TO_MISSION',
jp=Button( jp=Button(
file='./assets/jp/base/page/WORK_GO_TO_MISSION.png', file='./assets/jp/base/page/WORK_GO_TO_MISSION.png',
area=(720, 160, 803, 199), area=(722, 155, 807, 199),
search=(700, 140, 823, 219), search=(702, 135, 827, 219),
color=(165, 178, 204), color=(173, 188, 211),
button=(720, 160, 803, 199), button=(722, 155, 807, 199),
), ),
en=Button( en=Button(
file='./assets/en/base/page/WORK_GO_TO_MISSION.png', file='./assets/en/base/page/WORK_GO_TO_MISSION.png',
area=(720, 160, 871, 206), area=(721, 158, 873, 197),
search=(700, 140, 891, 226), search=(701, 138, 893, 217),
color=(192, 204, 221), color=(180, 195, 215),
button=(720, 160, 871, 206), button=(721, 158, 873, 197),
), ),
) )
WORK_GO_TO_SCHOOL_EXCHANGE = ButtonWrapper( WORK_GO_TO_SCHOOL_EXCHANGE = ButtonWrapper(
name='WORK_GO_TO_SCHOOL_EXCHANGE', name='WORK_GO_TO_SCHOOL_EXCHANGE',
jp=Button( jp=Button(
file='./assets/jp/base/page/WORK_GO_TO_SCHOOL_EXCHANGE.png', file='./assets/jp/base/page/WORK_GO_TO_SCHOOL_EXCHANGE.png',
area=(641, 575, 758, 599), area=(636, 566, 753, 592),
search=(621, 555, 778, 619), search=(616, 546, 773, 612),
color=(165, 179, 204), color=(176, 187, 207),
button=(641, 575, 758, 599), button=(636, 566, 753, 592),
), ),
en=Button( en=Button(
file='./assets/en/base/page/WORK_GO_TO_SCHOOL_EXCHANGE.png', file='./assets/en/base/page/WORK_GO_TO_SCHOOL_EXCHANGE.png',
area=(643, 572, 778, 602), area=(635, 569, 769, 597),
search=(623, 552, 798, 622), search=(615, 549, 789, 617),
color=(190, 203, 221), color=(198, 204, 216),
button=(643, 572, 778, 602), button=(635, 569, 769, 597),
), ),
) )
WORK_GO_TO_STORY = ButtonWrapper( WORK_GO_TO_STORY = ButtonWrapper(
name='WORK_GO_TO_STORY', name='WORK_GO_TO_STORY',
jp=Button( jp=Button(
file='./assets/jp/base/page/WORK_GO_TO_STORY.png', file='./assets/jp/base/page/WORK_GO_TO_STORY.png',
area=(995, 163, 1032, 197), area=(998, 155, 1078, 199),
search=(975, 143, 1052, 217), search=(978, 135, 1098, 219),
color=(191, 201, 219), color=(215, 221, 232),
button=(995, 163, 1032, 197), button=(998, 155, 1078, 199),
), ),
en=Button( en=Button(
file='./assets/en/base/page/WORK_GO_TO_STORY.png', file='./assets/en/base/page/WORK_GO_TO_STORY.png',
area=(994, 159, 1109, 211), area=(996, 159, 1112, 205),
search=(974, 139, 1129, 231), search=(976, 139, 1132, 225),
color=(208, 215, 228), color=(200, 209, 225),
button=(994, 159, 1109, 211), button=(996, 159, 1112, 205),
), ),
) )
WORK_GO_TO_TACTICAL_CHALLENGE = ButtonWrapper( WORK_GO_TO_TACTICAL_CHALLENGE = ButtonWrapper(
name='WORK_GO_TO_TACTICAL_CHALLENGE', name='WORK_GO_TO_TACTICAL_CHALLENGE',
jp=Button( jp=Button(
file='./assets/jp/base/page/WORK_GO_TO_TACTICAL_CHALLENGE.png', file='./assets/jp/base/page/WORK_GO_TO_TACTICAL_CHALLENGE.png',
area=(1012, 535, 1151, 562), area=(801, 565, 920, 593),
search=(992, 515, 1171, 582), search=(781, 545, 940, 613),
color=(159, 174, 200), color=(172, 186, 209),
button=(1012, 535, 1151, 562), button=(801, 565, 920, 593),
), ),
en=Button( en=Button(
file='./assets/en/base/page/WORK_GO_TO_TACTICAL_CHALLENGE.png', file='./assets/en/base/page/WORK_GO_TO_TACTICAL_CHALLENGE.png',
area=(1034, 435, 1162, 466), area=(803, 566, 922, 623),
search=(1014, 415, 1182, 486), search=(783, 546, 942, 643),
color=(179, 199, 221), color=(186, 201, 220),
button=(1034, 435, 1162, 466), button=(803, 566, 922, 623),
), ),
) )
+8 -8
View File
@@ -75,17 +75,17 @@ OCR_TICKET = ButtonWrapper(
name='OCR_TICKET', name='OCR_TICKET',
jp=Button( jp=Button(
file='./assets/jp/bounty/OCR_TICKET.png', file='./assets/jp/bounty/OCR_TICKET.png',
area=(195, 85, 237, 113), area=(196, 87, 258, 113),
search=(175, 65, 257, 133), search=(176, 67, 278, 133),
color=(197, 206, 213), color=(173, 197, 212),
button=(195, 85, 237, 113), button=(196, 87, 258, 113),
), ),
en=Button( en=Button(
file='./assets/en/bounty/OCR_TICKET.png', file='./assets/en/bounty/OCR_TICKET.png',
area=(225, 85, 267, 114), area=(229, 89, 285, 112),
search=(205, 65, 287, 134), search=(209, 69, 305, 132),
color=(197, 206, 213), color=(177, 194, 207),
button=(225, 85, 267, 114), button=(229, 89, 285, 112),
), ),
) )
SELECT_DESERT_RAILROAD = ButtonWrapper( SELECT_DESERT_RAILROAD = ButtonWrapper(
+3 -2
View File
@@ -41,8 +41,9 @@ class Bounty(BountyUI):
if action == 'stop': if action == 'stop':
raise RequestHumanTakeover raise RequestHumanTakeover
elif action == 'skip': elif action == 'skip':
self.config.task_delay(server_update=True) with self.config.multi_set():
self.config.task_stop() self.config.task_delay(server_update=True)
self.config.task_stop()
@property @property
def is_ticket_enough(self) -> bool: def is_ticket_enough(self) -> bool:
+2
View File
@@ -22,6 +22,8 @@ class BountyUI(UI):
return False return False
def enter_stage(self, index: int) -> bool: def enter_stage(self, index: int) -> bool:
if not index:
index = BOUNTY_LIST.insight_max_sweepable_index(self)
if BOUNTY_LIST.select_index_enter(self, index): if BOUNTY_LIST.select_index_enter(self, index):
return True return True
return False return False
+226 -73
View File
@@ -27,85 +27,102 @@ CAFE_FIRST = ButtonWrapper(
name='CAFE_FIRST', name='CAFE_FIRST',
jp=Button( jp=Button(
file='./assets/jp/cafe/CAFE_FIRST.png', file='./assets/jp/cafe/CAFE_FIRST.png',
area=(82, 152, 136, 175), area=(96, 92, 111, 110),
search=(62, 132, 156, 195), search=(76, 72, 131, 130),
color=(111, 127, 147), color=(185, 192, 200),
button=(82, 152, 136, 175), button=(96, 92, 111, 110),
), ),
en=Button( en=Button(
file='./assets/en/cafe/CAFE_FIRST.png', file='./assets/en/cafe/CAFE_FIRST.png',
area=(82, 152, 136, 175), area=(205, 96, 215, 107),
search=(62, 132, 156, 195), search=(185, 76, 235, 127),
color=(111, 127, 147), color=(176, 184, 194),
button=(82, 152, 136, 175), button=(205, 96, 215, 107),
),
)
CAFE_INVITE = ButtonWrapper(
name='CAFE_INVITE',
jp=Button(
file='./assets/jp/cafe/CAFE_INVITE.png',
area=(870, 637, 903, 663),
search=(850, 617, 923, 683),
color=(253, 217, 235),
button=(870, 637, 903, 663),
),
en=Button(
file='./assets/en/cafe/CAFE_INVITE.png',
area=(870, 637, 903, 663),
search=(850, 617, 923, 683),
color=(253, 217, 235),
button=(870, 637, 903, 663),
),
)
CAFE_INVITED = ButtonWrapper(
name='CAFE_INVITED',
jp=Button(
file='./assets/jp/cafe/CAFE_INVITED.png',
area=(870, 637, 903, 663),
search=(850, 617, 923, 683),
color=(111, 109, 109),
button=(870, 637, 903, 663),
),
en=Button(
file='./assets/en/cafe/CAFE_INVITED.png',
area=(870, 637, 903, 663),
search=(850, 617, 923, 683),
color=(111, 109, 109),
button=(870, 637, 903, 663),
), ),
) )
CAFE_SECOND = ButtonWrapper( CAFE_SECOND = ButtonWrapper(
name='CAFE_SECOND', name='CAFE_SECOND',
jp=Button( jp=Button(
file='./assets/jp/cafe/CAFE_SECOND.png', file='./assets/jp/cafe/CAFE_SECOND.png',
area=(219, 152, 279, 175), area=(99, 92, 108, 110),
search=(199, 132, 299, 195), search=(79, 72, 128, 130),
color=(110, 126, 146), color=(193, 200, 209),
button=(219, 152, 279, 175), button=(99, 92, 108, 110),
), ),
en=Button( en=Button(
file='./assets/en/cafe/CAFE_SECOND.png', file='./assets/en/cafe/CAFE_SECOND.png',
area=(219, 152, 279, 175), area=(207, 96, 214, 107),
search=(199, 132, 299, 195), search=(187, 76, 234, 127),
color=(110, 126, 146), color=(174, 182, 192),
button=(219, 152, 279, 175), button=(207, 96, 214, 107),
), ),
) )
CHANGE_CAFE_NOT_SELECTED = ButtonWrapper( CHECK_MOMOTALK = ButtonWrapper(
name='CHANGE_CAFE_NOT_SELECTED', name='CHECK_MOMOTALK',
jp=Button( jp=Button(
file='./assets/jp/cafe/CHANGE_CAFE_NOT_SELECTED.png', file='./assets/jp/cafe/CHECK_MOMOTALK.png',
area=(84, 89, 178, 109), area=(421, 83, 447, 108),
search=(64, 69, 198, 129), search=(401, 63, 467, 128),
color=(185, 193, 203), color=(253, 203, 212),
button=(84, 89, 178, 109), button=(421, 83, 447, 108),
), ),
en=Button( en=Button(
file='./assets/en/cafe/CHANGE_CAFE_NOT_SELECTED.png', file='./assets/en/cafe/CHECK_MOMOTALK.png',
area=(84, 89, 178, 109), area=(421, 83, 447, 108),
search=(64, 69, 198, 129), search=(401, 63, 467, 128),
color=(185, 193, 203), color=(253, 203, 212),
button=(84, 89, 178, 109), button=(421, 83, 447, 108),
),
)
CHANGE_CAFE_SELECTED = ButtonWrapper(
name='CHANGE_CAFE_SELECTED',
jp=Button(
file='./assets/jp/cafe/CHANGE_CAFE_SELECTED.png',
area=(40, 87, 191, 112),
search=(20, 67, 211, 132),
color=(82, 105, 130),
button=(40, 87, 191, 112),
),
en=Button(
file='./assets/en/cafe/CHANGE_CAFE_SELECTED.png',
area=(40, 87, 191, 112),
search=(20, 67, 211, 132),
color=(82, 105, 130),
button=(40, 87, 191, 112),
), ),
) )
CHECK_REWARD = ButtonWrapper( CHECK_REWARD = ButtonWrapper(
name='CHECK_REWARD', name='CHECK_REWARD',
jp=Button( jp=Button(
file='./assets/jp/cafe/CHECK_REWARD.png', file='./assets/jp/cafe/CHECK_REWARD.png',
area=(1095, 621, 1146, 637), area=(1120, 635, 1166, 651),
search=(1075, 601, 1166, 657), search=(1100, 615, 1186, 671),
color=(82, 105, 129), color=(79, 102, 127),
button=(1086, 607, 1225, 685), button=(1109, 627, 1239, 691),
), ),
en=Button( en=Button(
file='./assets/en/cafe/CHECK_REWARD.png', file='./assets/en/cafe/CHECK_REWARD.png',
area=(1090, 613, 1229, 644), area=(1116, 636, 1218, 654),
search=(1070, 593, 1249, 664), search=(1096, 616, 1238, 674),
color=(64, 88, 115), color=(77, 100, 125),
button=(1086, 611, 1229, 685), button=(1113, 625, 1239, 692),
), ),
) )
CLICKABLE_TEMPLATE = ButtonWrapper( CLICKABLE_TEMPLATE = ButtonWrapper(
@@ -129,10 +146,10 @@ GET_REWARD = ButtonWrapper(
), ),
en=Button( en=Button(
file='./assets/en/cafe/GET_REWARD.png', file='./assets/en/cafe/GET_REWARD.png',
area=(581, 503, 692, 536), area=(593, 506, 687, 548),
search=(561, 483, 712, 556), search=(573, 486, 707, 568),
color=(208, 190, 63), color=(211, 193, 64),
button=(539, 491, 741, 555), button=(543, 492, 736, 564),
), ),
) )
GET_REWARD_CLOSE = ButtonWrapper( GET_REWARD_CLOSE = ButtonWrapper(
@@ -146,10 +163,10 @@ GET_REWARD_CLOSE = ButtonWrapper(
), ),
en=Button( en=Button(
file='./assets/en/cafe/GET_REWARD_CLOSE.png', file='./assets/en/cafe/GET_REWARD_CLOSE.png',
area=(883, 134, 926, 178), area=(968, 132, 997, 162),
search=(863, 114, 946, 198), search=(948, 112, 1017, 182),
color=(215, 220, 224), color=(187, 193, 201),
button=(883, 134, 926, 178), button=(968, 132, 997, 162),
), ),
) )
GOT_REWARD = ButtonWrapper( GOT_REWARD = ButtonWrapper(
@@ -163,10 +180,10 @@ GOT_REWARD = ButtonWrapper(
), ),
en=Button( en=Button(
file='./assets/en/cafe/GOT_REWARD.png', file='./assets/en/cafe/GOT_REWARD.png',
area=(543, 489, 741, 558), area=(544, 493, 735, 563),
search=(523, 469, 761, 578), search=(524, 473, 755, 583),
color=(211, 212, 212), color=(213, 213, 212),
button=(543, 489, 741, 558), button=(544, 493, 735, 563),
), ),
) )
INVENTORY = ButtonWrapper( INVENTORY = ButtonWrapper(
@@ -186,6 +203,91 @@ INVENTORY = ButtonWrapper(
button=(1123, 90, 1165, 130), button=(1123, 90, 1165, 130),
), ),
) )
INVITE_CONFIRM = ButtonWrapper(
name='INVITE_CONFIRM',
jp=Button(
file='./assets/jp/cafe/INVITE_CONFIRM.png',
area=(609, 147, 671, 178),
search=(589, 127, 691, 198),
color=(152, 164, 177),
button=(665, 471, 870, 533),
),
en=Button(
file='./assets/en/cafe/INVITE_CONFIRM.png',
area=(592, 149, 689, 176),
search=(572, 129, 709, 196),
color=(169, 179, 191),
button=(664, 470, 872, 534),
),
)
INVITE_IN_SECOND = ButtonWrapper(
name='INVITE_IN_SECOND',
jp=Button(
file='./assets/jp/cafe/INVITE_IN_SECOND.png',
area=(482, 147, 799, 177),
search=(462, 127, 819, 197),
color=(166, 177, 188),
button=(482, 147, 799, 177),
),
en=Button(
file='./assets/en/cafe/INVITE_IN_SECOND.png',
area=(482, 147, 799, 177),
search=(462, 127, 819, 197),
color=(166, 177, 188),
button=(482, 147, 799, 177),
),
)
INVITE_IN_SECOND_CLOSE = ButtonWrapper(
name='INVITE_IN_SECOND_CLOSE',
jp=Button(
file='./assets/jp/cafe/INVITE_IN_SECOND_CLOSE.png',
area=(874, 150, 900, 176),
search=(854, 130, 920, 196),
color=(180, 189, 198),
button=(874, 150, 900, 176),
),
en=Button(
file='./assets/en/cafe/INVITE_IN_SECOND_CLOSE.png',
area=(874, 150, 900, 176),
search=(854, 130, 920, 196),
color=(180, 189, 198),
button=(874, 150, 900, 176),
),
)
INVITE_SUBSTITUTE = ButtonWrapper(
name='INVITE_SUBSTITUTE',
jp=Button(
file='./assets/jp/cafe/INVITE_SUBSTITUTE.png',
area=(582, 154, 698, 184),
search=(562, 134, 718, 204),
color=(154, 166, 179),
button=(673, 478, 858, 541),
),
en=Button(
file='./assets/en/cafe/INVITE_SUBSTITUTE.png',
area=(506, 157, 775, 186),
search=(486, 137, 795, 206),
color=(176, 186, 196),
button=(673, 477, 857, 542),
),
)
INVITE_SUBSTITUTE_CLOSE = ButtonWrapper(
name='INVITE_SUBSTITUTE_CLOSE',
jp=Button(
file='./assets/jp/cafe/INVITE_SUBSTITUTE_CLOSE.png',
area=(867, 158, 893, 184),
search=(847, 138, 913, 204),
color=(180, 189, 199),
button=(867, 158, 893, 184),
),
en=Button(
file='./assets/en/cafe/INVITE_SUBSTITUTE_CLOSE.png',
area=(867, 158, 893, 184),
search=(847, 138, 913, 204),
color=(180, 189, 199),
button=(867, 158, 893, 184),
),
)
MOMOTALK_CLOSE = ButtonWrapper( MOMOTALK_CLOSE = ButtonWrapper(
name='MOMOTALK_CLOSE', name='MOMOTALK_CLOSE',
jp=Button( jp=Button(
@@ -203,21 +305,72 @@ MOMOTALK_CLOSE = ButtonWrapper(
button=(824, 82, 850, 108), button=(824, 82, 850, 108),
), ),
) )
MOMOTALK_INVITE = ButtonWrapper(
name='MOMOTALK_INVITE',
jp=Button(
file='./assets/jp/cafe/MOMOTALK_INVITE.png',
area=(764, 211, 809, 234),
search=(744, 191, 829, 254),
color=(90, 163, 195),
button=(764, 211, 809, 234),
),
en=Button(
file='./assets/en/cafe/MOMOTALK_INVITE.png',
area=(755, 210, 817, 233),
search=(735, 190, 837, 253),
color=(98, 179, 211),
button=(755, 210, 817, 233),
),
)
MOMOTALK_ITEM = ButtonWrapper(
name='MOMOTALK_ITEM',
jp=Button(
file='./assets/jp/cafe/MOMOTALK_ITEM.png',
area=(489, 193, 864, 259),
search=(469, 173, 884, 279),
color=(203, 230, 240),
button=(489, 193, 864, 259),
),
en=Button(
file='./assets/en/cafe/MOMOTALK_ITEM.png',
area=(489, 193, 864, 259),
search=(469, 173, 884, 279),
color=(203, 230, 240),
button=(489, 193, 864, 259),
),
)
OCR_CAFE = ButtonWrapper( OCR_CAFE = ButtonWrapper(
name='OCR_CAFE', name='OCR_CAFE',
jp=Button( jp=Button(
file='./assets/jp/cafe/OCR_CAFE.png', file='./assets/jp/cafe/OCR_CAFE.png',
area=(1103, 642, 1202, 672), area=(1127, 657, 1219, 682),
search=(1083, 622, 1222, 692), search=(1107, 637, 1239, 702),
color=(87, 107, 129), color=(93, 112, 134),
button=(1103, 642, 1202, 672), button=(1127, 657, 1219, 682),
), ),
en=Button( en=Button(
file='./assets/en/cafe/OCR_CAFE.png', file='./assets/en/cafe/OCR_CAFE.png',
area=(1105, 639, 1195, 674), area=(1127, 657, 1219, 682),
search=(1085, 619, 1215, 694), search=(1107, 637, 1239, 702),
color=(84, 104, 127), color=(93, 112, 134),
button=(1105, 639, 1195, 674), button=(1127, 657, 1219, 682),
),
)
OCR_NAME = ButtonWrapper(
name='OCR_NAME',
jp=Button(
file='./assets/jp/cafe/OCR_NAME.png',
area=(488, 194, 704, 588),
search=(468, 174, 724, 608),
color=(237, 239, 241),
button=(488, 194, 704, 588),
),
en=Button(
file='./assets/en/cafe/OCR_NAME.png',
area=(488, 194, 704, 588),
search=(468, 174, 724, 608),
color=(237, 239, 241),
button=(488, 194, 704, 588),
), ),
) )
STUDENT_LIST = ButtonWrapper( STUDENT_LIST = ButtonWrapper(
+14 -33
View File
@@ -1,17 +1,13 @@
from enum import Enum from enum import Enum
from module.base.decorator import Config
from module.base.timer import Timer from module.base.timer import Timer
from module.logger import logger from module.logger import logger
from module.ui.switch import Switch from module.ui.switch import Switch
from tasks.base.page import page_cafe from tasks.base.page import page_cafe
from tasks.cafe.assets.assets_cafe import * from tasks.cafe.assets.assets_cafe import *
from tasks.cafe.invitation import handle_invitation
from tasks.cafe.ui import CafeUI from tasks.cafe.ui import CafeUI
SWITCH_CAFE = Switch('Cafe_switch')
SWITCH_CAFE.add_state('off', CHANGE_CAFE_NOT_SELECTED)
SWITCH_CAFE.add_state('on', CHANGE_CAFE_SELECTED)
SWITCH_CAFE_SELECT = Switch('Cafe_switch_select') SWITCH_CAFE_SELECT = Switch('Cafe_switch_select')
SWITCH_CAFE_SELECT.add_state('1', CAFE_FIRST) SWITCH_CAFE_SELECT.add_state('1', CAFE_FIRST)
SWITCH_CAFE_SELECT.add_state('2', CAFE_SECOND) SWITCH_CAFE_SELECT.add_state('2', CAFE_SECOND)
@@ -22,22 +18,17 @@ class CafeStatus(Enum):
OCR = 1 OCR = 1
REWARD = 2 REWARD = 2
GOT = 3 GOT = 3
CLICK = 4 INVITATION = 4
CHECK = 5 CLICK = 5
CHECK = 6
FINISHED = -1 FINISHED = -1
class Cafe(CafeUI): class Cafe(CafeUI):
@Config.when(Emulator_GameLanguage='jp') @property
def _is_second_cafe_on(self): def is_second_cafe_on(self):
return self.config.Cafe_SecondCafe return self.config.Cafe_SecondCafe
@Config.when(Emulator_GameLanguage=None)
def _is_second_cafe_on(self):
return False
is_second_cafe_on = property(_is_second_cafe_on)
def _handle_cafe(self, status): def _handle_cafe(self, status):
match status: match status:
case CafeStatus.STUDENT_LIST: case CafeStatus.STUDENT_LIST:
@@ -63,9 +54,12 @@ class Cafe(CafeUI):
logger.info('Cafe reward have been got') logger.info('Cafe reward have been got')
self.appear_then_click(GET_REWARD_CLOSE) self.appear_then_click(GET_REWARD_CLOSE)
if not self.appear(GET_REWARD_CLOSE): if not self.appear(GET_REWARD_CLOSE):
return CafeStatus.INVITATION
case CafeStatus.INVITATION:
if handle_invitation(self):
return CafeStatus.CLICK return CafeStatus.CLICK
case CafeStatus.CLICK: case CafeStatus.CLICK:
buttons = self.get_clickable_buttons(offset=(45, 10)) buttons = self.get_clickable_buttons()
self.click = len(buttons) self.click = len(buttons)
logger.attr('Clickable', self.click) logger.attr('Clickable', self.click)
if not buttons: if not buttons:
@@ -111,7 +105,6 @@ class Cafe(CafeUI):
status = CafeStatus.STUDENT_LIST status = CafeStatus.STUDENT_LIST
loading_timer = Timer(2).start() loading_timer = Timer(2).start()
action_timer = Timer(1, count=1) action_timer = Timer(1, count=1)
is_list = False
is_reset = False is_reset = False
is_second = False is_second = False
is_enable = is_reward_on or is_touch_on is_enable = is_reward_on or is_touch_on
@@ -128,11 +121,6 @@ class Cafe(CafeUI):
if not loading_timer.reached(): if not loading_timer.reached():
continue continue
if not is_list and status == CafeStatus.STUDENT_LIST and self.appear(STUDENT_LIST):
is_list = True
loading_timer = Timer(3).start()
continue
if not is_reward_on and status == CafeStatus.OCR: if not is_reward_on and status == CafeStatus.OCR:
logger.info('Skip reward') logger.info('Skip reward')
status = CafeStatus.CLICK status = CafeStatus.CLICK
@@ -149,26 +137,19 @@ class Cafe(CafeUI):
continue continue
if self.is_second_cafe_on and not is_second and status == CafeStatus.FINISHED: if self.is_second_cafe_on and not is_second and status == CafeStatus.FINISHED:
if not SWITCH_CAFE.appear(main=self):
logger.warning('Cafe switch not found')
continue
if SWITCH_CAFE.get(main=self) == 'off':
SWITCH_CAFE.set('on', main=self)
logger.info('Switching to second cafe')
if not SWITCH_CAFE_SELECT.appear(main=self): if not SWITCH_CAFE_SELECT.appear(main=self):
logger.info('Cafe switch select not found') logger.info('Cafe switch not found')
continue continue
match (SWITCH_CAFE_SELECT.get(main=self)): match SWITCH_CAFE_SELECT.get(main=self):
case '1': case '1':
if self.click_with_interval(CAFE_SECOND): if self.click_with_interval(CAFE_FIRST):
continue continue
case '2': case '2':
logger.info('Cafe second arrived') logger.info('Cafe second arrived')
SWITCH_CAFE.set('off', main=self)
status = CafeStatus.STUDENT_LIST status = CafeStatus.STUDENT_LIST
is_list = False
is_second = True is_second = True
self.check = 0 self.check = 0
loading_timer.reset().start()
if action_timer.reached_and_reset(): if action_timer.reached_and_reset():
logger.attr('Status', status) logger.attr('Status', status)
+314
View File
@@ -0,0 +1,314 @@
import re
from datetime import datetime, timedelta
from enum import Enum
import numpy as np
from module.base.base import ModuleBase
from module.base.timer import Timer
from module.base.utils import area_offset, area_size
from module.config.utils import get_server_next_update
from module.logger import logger
from module.ocr.ocr import Ocr
from tasks.cafe.assets.assets_cafe import *
class InvitationOcr(Ocr):
def after_process(self, result):
result = super().after_process(result)
result = result.replace('モI', 'モエ')
return result
class InvitationStatus(Enum):
MOMOTALK = 0
OCR = 1
SELECT = 2
CONFIRM = 3
SUBSTITUTE = 4
IN_SECOND = 5
INVITED = 6
FAILED = 7
FINISHED = -1
class Invitation:
swipe_vector_range = (0.65, 0.85)
cafe_update = ["04:00", "16:00"]
def __init__(self, name: str):
self.name = name
self.ocr = InvitationOcr(OCR_NAME)
self.list = OCR_NAME
self.item = MOMOTALK_ITEM
self.invite = MOMOTALK_INVITE
self.target_names = []
self.waiting_hour = None
self.substitute = None
self.choice = None
self.invited = []
self.current_names = []
def __str__(self):
return f'Invitation({self.name})'
__repr__ = __str__
def __eq__(self, other):
return str(self) == str(other)
def __hash__(self):
return hash(self.name)
def swipe_page(self, main: ModuleBase, vector_range=None, reverse=False):
"""
Args:
main:
vector_range (tuple[float, float]):
reverse (bool):
"""
if vector_range is None:
vector_range = self.swipe_vector_range
vector = np.random.uniform(*vector_range)
width, height = area_size(self.list.button)
vector = (0, -vector * height)
if reverse:
vector = (-vector[0], -vector[1])
name = f'{self.name}_SWIPE'
main.device.swipe_vector(vector, self.list.button, name=name)
main.device.click_record_remove(name)
def load_names(self, main: ModuleBase):
names = self.ocr.detect_and_ocr(main.device.image)
if not names:
logger.warning(f'No valid names in {self.ocr.name}')
return
self.current_names = []
for name_ in names:
name: str = name_.ocr_text.replace(' ', '')
if name.isdigit():
continue
if name.startswith('('):
if not self.current_names:
continue
n = self.current_names.pop(len(self.current_names) - 1)
self.current_names.append((n[0] + name, n[1]))
continue
self.current_names.append((name, name_.box))
@property
def is_invitation(self) -> bool:
return get_server_next_update(self.cafe_update) - datetime.now() > timedelta(hours=self.waiting_hour)
@property
def names(self):
return list(map(lambda x: x[0], self.current_names))
@property
def target_name(self):
return self.target_names[0] if self.target_names else None
def on_success(self):
logger.info(f'Invited {self.target_name}')
self.invited.append(self.target_name)
self.target_names.pop(0)
def on_failed(self):
logger.warning(f'Failed to invite {self.target_name}')
self.target_names.pop(0)
def insight_name(self, name: str, main: ModuleBase, skip_first_screenshot=True) -> bool:
"""
Args:
name:
main:
skip_first_screenshot:
"""
logger.info(f'Insight name: {name}')
last_names: set[str] = set()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
self.load_names(main)
if name in self.names:
return True
names = self.names
if names and last_names == set(names):
logger.warning(f'Name not found: {name}')
return False
last_names = set(names)
self.swipe_page(main)
main.wait_until_stable(
self.list.button,
timer=Timer(0, 0),
timeout=Timer(1.5, 5)
)
def select_name_invite(
self,
main: ModuleBase,
name: str = None,
insight: bool = True,
skip_first_screenshot: bool = True
) -> bool:
"""
Args:
main:
name:
insight:
skip_first_screenshot:
Returns:
If success
"""
if name is None:
if not self.target_name:
return False
name = self.target_name
if insight and not self.insight_name(name, main, skip_first_screenshot):
return False
logger.info(f'Select name: {name}')
click_interval = Timer(1, 2)
load_names_interval = Timer(1, 5)
timeout = Timer(10, 10).start()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
if load_names_interval.reached_and_reset() and not insight:
self.load_names(main)
name_box = next(filter(lambda x: x[0] == name, self.current_names), None)
if name_box is None:
logger.warning(f'No name {name} in {self.ocr.name}')
continue
search_box = area_offset((0, 0, *area_size(self.item.area)), name_box[1][:2])
self.invite.load_search(search_box)
click_button = self.invite.match_multi_template(main.device.image)
if not click_button:
logger.warning(f'No clickable {self.invite.name}')
continue
if click_interval.reached_and_reset():
main.device.click(click_button[0])
return True
if timeout.reached():
logger.warning(f'No clickable {self.invite.name}')
return False
invitation = Invitation('CafeInvitation')
def handle_invitation_status(status: InvitationStatus, main: ModuleBase) -> InvitationStatus:
match status:
case InvitationStatus.MOMOTALK:
if not invitation.is_invitation:
logger.info('Invitation waiting until next refresh')
return InvitationStatus.FINISHED
if main.match_color(CAFE_INVITED):
logger.info('Invitation in cooldown')
return InvitationStatus.FINISHED
if invitation.choice != 'list_top' and invitation.target_name is None:
logger.warning('No student to be invited or all invitations failed')
return InvitationStatus.FINISHED
if main.appear(CHECK_MOMOTALK):
return InvitationStatus.OCR
main.appear_then_click(CAFE_INVITE)
case InvitationStatus.OCR:
if invitation.choice == 'list_top':
invitation.load_names(main)
invitation.target_names = invitation.names
invitation.choice = 'list'
if invitation.select_name_invite(main):
return InvitationStatus.SELECT
return InvitationStatus.FAILED
case InvitationStatus.SELECT:
if main.appear(INVITE_CONFIRM):
return InvitationStatus.CONFIRM
if main.appear(INVITE_IN_SECOND):
return InvitationStatus.IN_SECOND
if main.appear(INVITE_SUBSTITUTE):
return InvitationStatus.SUBSTITUTE
case InvitationStatus.CONFIRM:
main.appear_then_click(INVITE_CONFIRM)
if not main.appear(INVITE_CONFIRM):
invitation.on_success()
return InvitationStatus.INVITED
case InvitationStatus.IN_SECOND:
main.appear_then_click(INVITE_IN_SECOND_CLOSE)
return InvitationStatus.FAILED
case InvitationStatus.SUBSTITUTE:
if not invitation.substitute:
main.appear_then_click(INVITE_SUBSTITUTE_CLOSE)
return InvitationStatus.FAILED
else:
main.appear_then_click(INVITE_SUBSTITUTE)
if not main.appear(INVITE_SUBSTITUTE):
return InvitationStatus.INVITED
case InvitationStatus.INVITED:
main.appear_then_click(MOMOTALK_CLOSE)
if not main.appear(MOMOTALK_CLOSE):
return InvitationStatus.FINISHED
case InvitationStatus.FAILED:
main.appear_then_click(MOMOTALK_CLOSE)
if not main.appear(CHECK_MOMOTALK):
invitation.on_failed()
return InvitationStatus.MOMOTALK
case InvitationStatus.FINISHED:
pass
case _:
logger.warning(f'Invalid status: {status}')
return status
def handle_invitation(main: ModuleBase):
if not main.config.Invitation_Enable:
logger.info('Invitation disabled')
return True
invitation.waiting_hour = main.config.Invitation_WaitingHour
invitation.substitute = main.config.Invitation_Substitute
if invitation.choice is None:
invitation.choice = main.config.Invitation_Choice
if invitation.choice == 'by_name' and not invitation.target_names:
name = main.config.Invitation_Name
if name is None:
logger.warning('Choose By Name but Inviting Student Name is blank')
return True
name = re.sub(r'[ \t\r\n]', '', name)
name = re.sub(r'[>﹥›˃ᐳ❯]', '>', name)
name = re.sub(r'', '(', name)
name = re.sub(r'', ')', name)
invitation.target_names = name.split('>')
status = InvitationStatus.MOMOTALK
action_timer = Timer(1, 1)
loading_timer = Timer(1, 1)
while 1:
main.device.screenshot()
if not loading_timer.reached():
continue
if action_timer.reached_and_reset():
logger.attr('Status', status)
status = handle_invitation_status(status, main)
if status == InvitationStatus.FINISHED:
return True
+11 -10
View File
@@ -31,7 +31,7 @@ class CafeUI(UI):
# generate result # generate result
return cv2.bitwise_and(image, image, mask=mask) return cv2.bitwise_and(image, image, mask=mask)
def get_clickable_buttons(self, similarity=0.8, offset=(45, 10)): def get_clickable_buttons(self, similarity=0.8, offset=(40, 10)):
image = self.extract_clickable_from_image(self.device.image) image = self.extract_clickable_from_image(self.device.image)
self.template.matched_button._button_offset = offset self.template.matched_button._button_offset = offset
self.template.load_offset(self.template) self.template.load_offset(self.template)
@@ -48,21 +48,22 @@ class CafeUI(UI):
vector_left = (-width * r, 0) vector_left = (-width * r, 0)
vector_right = (width * r, 0) vector_right = (width * r, 0)
random_r = (-5, -5, 5, 5) random_r = (-5, -5, 5, 5)
name = 'CAFE_SWIPE'
match direction: match direction:
case 'init': case 'init':
self.device.pinch() self.device.pinch()
self.device.swipe_vector(vector_down, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_down, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
self.device.swipe_vector(vector_right, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_right, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
self.device.swipe_vector(vector_up, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_up, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
self.device.swipe_vector(vector_up, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_up, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
case 'left': case 'left':
self.device.swipe_vector(vector_left, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_left, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
self.device.swipe_vector(vector_left, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_left, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
case 'right': case 'right':
self.device.swipe_vector(vector_right, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_right, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
self.device.swipe_vector(vector_right, box=BOX_CAFE.area, random_range=random_r, padding=5) self.device.swipe_vector(vector_right, box=BOX_CAFE.area, random_range=random_r, padding=5, name=name)
# solve too much swipe causing restart # solve too much swipe causing restart
self.device.click_record_clear() self.device.click_record_remove(name)
def cafe_additional(self) -> bool: def cafe_additional(self) -> bool:
if self.appear_then_click(INVENTORY): if self.appear_then_click(INVENTORY):
+17
View File
@@ -3,6 +3,23 @@ from module.base.button import Button, ButtonWrapper
# This file was auto-generated, do not modify it manually. To generate: # This file was auto-generated, do not modify it manually. To generate:
# ``` python -m dev_tools.button_extract ``` # ``` python -m dev_tools.button_extract ```
CIRCLE = ButtonWrapper(
name='CIRCLE',
jp=Button(
file='./assets/jp/circle/CIRCLE.png',
area=(191, 314, 233, 356),
search=(171, 294, 253, 376),
color=(191, 224, 240),
button=(188, 299, 435, 456),
),
en=Button(
file='./assets/en/circle/CIRCLE.png',
area=(196, 314, 235, 355),
search=(176, 294, 255, 375),
color=(183, 221, 238),
button=(191, 298, 434, 457),
),
)
GET_REWARD_AP = ButtonWrapper( GET_REWARD_AP = ButtonWrapper(
name='GET_REWARD_AP', name='GET_REWARD_AP',
jp=Button( jp=Button(
+15 -2
View File
@@ -2,7 +2,7 @@ from enum import Enum
from module.base.timer import Timer from module.base.timer import Timer
from module.logger import logger from module.logger import logger
from tasks.base.page import page_circle from tasks.base.page import CIRCLE_CHECK, MAIN_GO_TO_CIRCLE
from tasks.base.ui import UI from tasks.base.ui import UI
from tasks.circle.assets.assets_circle import * from tasks.circle.assets.assets_circle import *
@@ -17,6 +17,19 @@ class CircleStatus(Enum):
class Circle(UI): class Circle(UI):
def _enter_circle(self):
self.ui_goto_main()
action_timer = Timer(1, 8)
while not self.appear(CIRCLE_CHECK):
self.device.screenshot()
if not action_timer.reached_and_reset():
continue
if self.appear(CIRCLE):
self.click_with_interval(CIRCLE, 3)
continue
else:
self.device.click(MAIN_GO_TO_CIRCLE)
def _handle_circle(self, status): def _handle_circle(self, status):
match status: match status:
case CircleStatus.REWARD: case CircleStatus.REWARD:
@@ -31,7 +44,7 @@ class Circle(UI):
return status return status
def run(self): def run(self):
self.ui_ensure(page_circle) self._enter_circle()
status = CircleStatus.REWARD status = CircleStatus.REWARD
action_timer = Timer(0.5) action_timer = Timer(0.5)
+8 -8
View File
@@ -7,19 +7,19 @@ OCR_AP = ButtonWrapper(
name='OCR_AP', name='OCR_AP',
share=Button( share=Button(
file='./assets/share/item/data/OCR_AP.png', file='./assets/share/item/data/OCR_AP.png',
area=(560, 11, 667, 37), area=(535, 13, 660, 36),
search=(540, 0, 687, 57), search=(515, 0, 680, 56),
color=(211, 216, 219), color=(207, 215, 220),
button=(560, 11, 667, 37), button=(535, 13, 660, 36),
), ),
) )
OCR_DATA = ButtonWrapper( OCR_DATA = ButtonWrapper(
name='OCR_DATA', name='OCR_DATA',
share=Button( share=Button(
file='./assets/share/item/data/OCR_DATA.png', file='./assets/share/item/data/OCR_DATA.png',
area=(768, 12, 1072, 37), area=(745, 11, 1069, 39),
search=(748, 0, 1092, 57), search=(725, 0, 1089, 59),
color=(212, 220, 224), color=(216, 223, 227),
button=(768, 12, 1072, 37), button=(745, 11, 1069, 39),
), ),
) )
+11 -7
View File
@@ -12,7 +12,10 @@ class DataUpdate(UI):
Page: Page:
in: page_work in: page_work
""" """
ap = DigitCounter(OCR_AP).ocr_single_line(self.device.image) ap, _, ap_total = DigitCounter(OCR_AP).ocr_single_line(self.device.image)
if ap_total == 0:
logger.warning('Invalid AP')
return False
# Data for Credit and Pyroxene # Data for Credit and Pyroxene
ocr = Digit(OCR_DATA) ocr = Digit(OCR_DATA)
timeout = Timer(2, count=6).start() timeout = Timer(2, count=6).start()
@@ -21,27 +24,28 @@ class DataUpdate(UI):
if len(data) != 2: if len(data) != 2:
data = [data[0], data[-1]] data = [data[0], data[-1]]
logger.attr('Data', data) logger.attr('Data', data)
credit, pyroxene = [int(''.join([v for v in d.ocr_text if v.isdigit()])) for d in data] credit, pyroxene = [int(''.join(filter(lambda x: x.isdigit(), d.ocr_text))) for d in data]
if credit > 0 or pyroxene > 0: if credit > 0 or pyroxene > 0:
break break
logger.warning(f'Invalid credit and pyroxene: {data}') logger.warning(f'Invalid credit and pyroxene: {data}')
if timeout.reached(): if timeout.reached():
logger.warning('Get data timeout') logger.warning('Get data timeout')
break return False
logger.attr('Credit', credit) logger.attr('Credit', credit)
logger.attr('Pyroxene', pyroxene) logger.attr('Pyroxene', pyroxene)
with self.config.multi_set(): with self.config.multi_set():
self.config.stored.AP.set(ap[0], ap[2]) self.config.stored.AP.set(ap, ap_total)
self.config.stored.Credit.value = credit self.config.stored.Credit.value = credit
self.config.stored.Pyroxene.value = pyroxene self.config.stored.Pyroxene.value = pyroxene
return ap, credit, pyroxene return True
def run(self): def run(self):
self.ui_ensure(page_work, acquire_lang_checked=False) self.ui_ensure(page_work, acquire_lang_checked=False)
with self.config.multi_set(): if self._get_data():
self._get_data()
self.config.task_delay(server_update=True) self.config.task_delay(server_update=True)
else:
self.config.task_delay(minute=1)
+8 -8
View File
@@ -75,17 +75,17 @@ OCR_TICKET = ButtonWrapper(
name='OCR_TICKET', name='OCR_TICKET',
jp=Button( jp=Button(
file='./assets/jp/scrimmage/OCR_TICKET.png', file='./assets/jp/scrimmage/OCR_TICKET.png',
area=(195, 85, 235, 113), area=(194, 87, 258, 112),
search=(175, 65, 255, 133), search=(174, 67, 278, 132),
color=(206, 211, 215), color=(207, 213, 218),
button=(195, 85, 235, 113), button=(194, 87, 258, 112),
), ),
en=Button( en=Button(
file='./assets/en/scrimmage/OCR_TICKET.png', file='./assets/en/scrimmage/OCR_TICKET.png',
area=(227, 84, 265, 115), area=(229, 88, 289, 112),
search=(207, 64, 285, 135), search=(209, 68, 309, 132),
color=(207, 212, 216), color=(199, 206, 212),
button=(227, 84, 265, 115), button=(229, 88, 289, 112),
), ),
) )
SELECT_GEHENNA = ButtonWrapper( SELECT_GEHENNA = ButtonWrapper(
+14 -29
View File
@@ -7,6 +7,7 @@ from tasks.base.assets.assets_base_page import BACK
from tasks.base.page import page_school_exchange from tasks.base.page import page_school_exchange
from tasks.scrimmage.assets.assets_scrimmage import * from tasks.scrimmage.assets.assets_scrimmage import *
from tasks.scrimmage.ui import ScrimmageUI from tasks.scrimmage.ui import ScrimmageUI
from tasks.stage.ap import AP
class ScrimmageStatus(Enum): class ScrimmageStatus(Enum):
@@ -18,15 +19,20 @@ class ScrimmageStatus(Enum):
FINISH = 5 FINISH = 5
class Scrimmage(ScrimmageUI): class Scrimmage(ScrimmageUI, AP):
_stage_ap = [10, 15, 15, 15]
@property
def stage_ap(self):
return self._stage_ap
@property @property
def scrimmage_info(self): def scrimmage_info(self):
scrimmage = (SELECT_TRINITY, SELECT_GEHENNA, SELECT_MILLENNIUM) scrimmage = (SELECT_TRINITY, SELECT_GEHENNA, SELECT_MILLENNIUM)
check = (CHECK_TRINITY, CHECK_GEHENNA, CHECK_MILLENNIUM) check = (CHECK_TRINITY, CHECK_GEHENNA, CHECK_MILLENNIUM)
stage = (self.config.Trinity_Stage, self.config.Gehenna_Stage, self.config.Millennium_Stage) stage = (self.config.Trinity_Stage, self.config.Gehenna_Stage, self.config.Millennium_Stage)
count = (self.config.Trinity_Count, self.config.Gehenna_Count, self.config.Millennium_Count) count = (self.config.Trinity_Count, self.config.Gehenna_Count, self.config.Millennium_Count)
ap = (10 if stage == 1 else 15 for stage in stage) info = zip(scrimmage, check, stage, count)
info = zip(scrimmage, check, stage, count, ap)
return filter(lambda x: x[3] > 0, info) return filter(lambda x: x[3] > 0, info)
@property @property
@@ -42,17 +48,14 @@ class Scrimmage(ScrimmageUI):
if action == 'stop': if action == 'stop':
raise RequestHumanTakeover raise RequestHumanTakeover
elif action == 'skip': elif action == 'skip':
self.config.task_delay(server_update=True) with self.config.multi_set():
self.config.task_stop() self.config.task_delay(server_update=True)
self.config.task_stop()
@property @property
def is_ticket_enough(self) -> bool: def is_ticket_enough(self) -> bool:
return self.current_ticket >= self.current_count return self.current_ticket >= self.current_count
@property
def is_ap_enough(self) -> bool:
return self.current_ap >= self.current_task_ap
@property @property
def current_scrimmage(self): def current_scrimmage(self):
return self.task[0][:2] return self.task[0][:2]
@@ -65,25 +68,10 @@ class Scrimmage(ScrimmageUI):
def current_count(self): def current_count(self):
return self.task[0][3] return self.task[0][3]
@property
def current_task_ap(self):
return self.task[0][4] * self.current_count
@property @property
def current_ticket(self): def current_ticket(self):
return self.config.stored.ScrimmageTicket.value return self.config.stored.ScrimmageTicket.value
@property
def current_ap(self):
return self.config.stored.AP.value
def update_ap(self):
ap = self.config.stored.AP
ap_old = ap.value
ap_new = ap_old - self.current_task_ap
ap.set(ap_new, ap.total)
logger.info(f'Set AP: {ap_old} -> {ap_new}')
def handle_scrimmage(self, status): def handle_scrimmage(self, status):
match status: match status:
case ScrimmageStatus.OCR: case ScrimmageStatus.OCR:
@@ -95,19 +83,16 @@ class Scrimmage(ScrimmageUI):
if not self.is_ticket_enough: if not self.is_ticket_enough:
logger.warning('Scrimmage ticket not enough') logger.warning('Scrimmage ticket not enough')
self.error_handler() self.error_handler()
if not self.is_ap_enough:
logger.warning('AP not enough')
self.error_handler()
if self.select_scrimmage(*self.current_scrimmage): if self.select_scrimmage(*self.current_scrimmage):
return ScrimmageStatus.ENTER return ScrimmageStatus.ENTER
case ScrimmageStatus.ENTER: case ScrimmageStatus.ENTER:
if self.enter_stage(self.current_stage): if self.enter_stage(self.current_stage) and self.is_ap_enough(self.current_count, self.current_stage):
return ScrimmageStatus.SWEEP return ScrimmageStatus.SWEEP
else: else:
self.error_handler() self.error_handler()
case ScrimmageStatus.SWEEP: case ScrimmageStatus.SWEEP:
if self.do_sweep(self.current_count): if self.do_sweep(self.current_count):
self.update_ap() self.update_ap(self.current_count, self.current_stage)
self.task.pop(0) self.task.pop(0)
return ScrimmageStatus.END return ScrimmageStatus.END
return ScrimmageStatus.ENTER return ScrimmageStatus.ENTER
+6 -1
View File
@@ -3,6 +3,7 @@ from module.logger import logger
from module.ocr.ocr import DigitCounter from module.ocr.ocr import DigitCounter
from tasks.base.ui import UI from tasks.base.ui import UI
from tasks.scrimmage.assets.assets_scrimmage import * from tasks.scrimmage.assets.assets_scrimmage import *
from tasks.stage.ap import AP
from tasks.stage.list import StageList from tasks.stage.list import StageList
from tasks.stage.sweep import StageSweep from tasks.stage.sweep import StageSweep
@@ -10,7 +11,7 @@ SCRIMMAGE_LIST = StageList('ScrimmageList')
SCRIMMAGE_SWEEP = StageSweep('ScrimmageSweep', 6) SCRIMMAGE_SWEEP = StageSweep('ScrimmageSweep', 6)
class ScrimmageUI(UI): class ScrimmageUI(UI, AP):
def select_scrimmage(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper): def select_scrimmage(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper):
timer = Timer(5, 10).start() timer = Timer(5, 10).start()
while 1: while 1:
@@ -22,6 +23,10 @@ class ScrimmageUI(UI):
return False return False
def enter_stage(self, index: int) -> bool: def enter_stage(self, index: int) -> bool:
if not index:
index = SCRIMMAGE_LIST.insight_max_sweepable_index(self)
# set AP stage
self.set_stage(index)
if SCRIMMAGE_LIST.select_index_enter(self, index, insight=False): if SCRIMMAGE_LIST.select_index_enter(self, index, insight=False):
return True return True
return False return False

Some files were not shown because too many files have changed in this diff Show More