Merge branch 'dev'
|
@ -1 +1 @@
|
|||
{"definitions":{"0949c622-9067-4f0d-bac2-3f938a1d2ed2":{"name":"Shop.ItemLessonNote","displayName":"レッスンノート","type":"template","annotationId":"0949c622-9067-4f0d-bac2-3f938a1d2ed2","useHintRect":false},"b2af59e9-60e3-4d97-8c72-c7ba092113a3":{"name":"Shop.ItemVeteranNote","displayName":"ベテランノート","type":"template","annotationId":"b2af59e9-60e3-4d97-8c72-c7ba092113a3","useHintRect":false},"835489e2-b29b-426c-b4c9-3bb9f8eb6195":{"name":"Shop.ItemSupportEnhancementPt","displayName":"サポート強化Pt 支援强化Pt","type":"template","annotationId":"835489e2-b29b-426c-b4c9-3bb9f8eb6195","useHintRect":false},"c5b7d67e-7260-4f08-a0e9-4d31ce9bbecf":{"name":"Shop.ItemSenseNoteVocal","displayName":"センスノート(ボーカル)感性笔记(声乐)","type":"template","annotationId":"c5b7d67e-7260-4f08-a0e9-4d31ce9bbecf","useHintRect":false},"0f7d581d-cea3-4039-9205-732e4cd29293":{"name":"Shop.ItemSenseNoteDance","displayName":"センスノート(ダンス)感性笔记(舞蹈)","type":"template","annotationId":"0f7d581d-cea3-4039-9205-732e4cd29293","useHintRect":false},"d3cc3323-51af-4882-ae12-49e7384b746d":{"name":"Shop.ItemSenseNoteVisual","displayName":"センスノート(ビジュアル)感性笔记(形象)","type":"template","annotationId":"d3cc3323-51af-4882-ae12-49e7384b746d","useHintRect":false},"a1df3af1-a3e7-4521-a085-e4dc3cd1cc57":{"name":"Shop.ItemLogicNoteVocal","displayName":"ロジックノート(ボーカル)理性笔记(声乐)","type":"template","annotationId":"a1df3af1-a3e7-4521-a085-e4dc3cd1cc57","useHintRect":false},"a9fcaf04-0c1f-4b0f-bb5b-ede9da96180f":{"name":"Shop.ItemLogicNoteDance","displayName":"ロジックノート(ダンス)理性笔记(舞蹈)","type":"template","annotationId":"a9fcaf04-0c1f-4b0f-bb5b-ede9da96180f","useHintRect":false},"c3f536d6-a04a-4651-b3f9-dd2c22593f7f":{"name":"Shop.ItemLogicNoteVisual","displayName":"ロジックノート(ビジュアル)理性笔记(形象)","type":"template","annotationId":"c3f536d6-a04a-4651-b3f9-dd2c22593f7f","useHintRect":false},"eef25cf9-afd0-43b1-b9c5-fbd997bd5fe0":{"name":"Shop.ItemAnomalyNoteVocal","displayName":"アノマリーノート(ボーカル)非凡笔记(声乐)","type":"template","annotationId":"eef25cf9-afd0-43b1-b9c5-fbd997bd5fe0","useHintRect":false},"df991b42-ed8e-4f2c-bf0c-aa7522f147b6":{"name":"Shop.ItemAnomalyNoteDance","displayName":"アノマリーノート(ダンス)非凡笔记(舞蹈)","type":"template","annotationId":"df991b42-ed8e-4f2c-bf0c-aa7522f147b6","useHintRect":false}},"annotations":[{"id":"0949c622-9067-4f0d-bac2-3f938a1d2ed2","type":"rect","data":{"x1":243,"y1":355,"x2":313,"y2":441}},{"id":"b2af59e9-60e3-4d97-8c72-c7ba092113a3","type":"rect","data":{"x1":414,"y1":355,"x2":484,"y2":441}},{"id":"835489e2-b29b-426c-b4c9-3bb9f8eb6195","type":"rect","data":{"x1":574,"y1":363,"x2":662,"y2":438}},{"id":"c5b7d67e-7260-4f08-a0e9-4d31ce9bbecf","type":"rect","data":{"x1":71,"y1":594,"x2":142,"y2":667}},{"id":"0f7d581d-cea3-4039-9205-732e4cd29293","type":"rect","data":{"x1":241,"y1":593,"x2":309,"y2":667}},{"id":"d3cc3323-51af-4882-ae12-49e7384b746d","type":"rect","data":{"x1":417,"y1":586,"x2":481,"y2":668}},{"id":"a1df3af1-a3e7-4521-a085-e4dc3cd1cc57","type":"rect","data":{"x1":585,"y1":591,"x2":651,"y2":669}},{"id":"a9fcaf04-0c1f-4b0f-bb5b-ede9da96180f","type":"rect","data":{"x1":69,"y1":825,"x2":138,"y2":899}},{"id":"c3f536d6-a04a-4651-b3f9-dd2c22593f7f","type":"rect","data":{"x1":242,"y1":820,"x2":310,"y2":898}},{"id":"eef25cf9-afd0-43b1-b9c5-fbd997bd5fe0","type":"rect","data":{"x1":413,"y1":821,"x2":481,"y2":897}},{"id":"df991b42-ed8e-4f2c-bf0c-aa7522f147b6","type":"rect","data":{"x1":583,"y1":823,"x2":649,"y2":900}}]}
|
||||
{"definitions":{"0949c622-9067-4f0d-bac2-3f938a1d2ed2":{"name":"Shop.ItemLessonNote","displayName":"レッスンノート","type":"template","annotationId":"0949c622-9067-4f0d-bac2-3f938a1d2ed2","useHintRect":false},"b2af59e9-60e3-4d97-8c72-c7ba092113a3":{"name":"Shop.ItemVeteranNote","displayName":"ベテランノート","type":"template","annotationId":"b2af59e9-60e3-4d97-8c72-c7ba092113a3","useHintRect":false},"835489e2-b29b-426c-b4c9-3bb9f8eb6195":{"name":"Shop.ItemSupportEnhancementPt","displayName":"サポート強化Pt 支援强化Pt","type":"template","annotationId":"835489e2-b29b-426c-b4c9-3bb9f8eb6195","useHintRect":false},"c5b7d67e-7260-4f08-a0e9-4d31ce9bbecf":{"name":"Shop.ItemSenseNoteVocal","displayName":"センスノート(ボーカル)感性笔记(声乐)","type":"template","annotationId":"c5b7d67e-7260-4f08-a0e9-4d31ce9bbecf","useHintRect":false},"0f7d581d-cea3-4039-9205-732e4cd29293":{"name":"Shop.ItemSenseNoteDance","displayName":"センスノート(ダンス)感性笔记(舞蹈)","type":"template","annotationId":"0f7d581d-cea3-4039-9205-732e4cd29293","useHintRect":false},"d3cc3323-51af-4882-ae12-49e7384b746d":{"name":"Shop.ItemSenseNoteVisual","displayName":"センスノート(ビジュアル)感性笔记(形象)","type":"template","annotationId":"d3cc3323-51af-4882-ae12-49e7384b746d","useHintRect":false},"a1df3af1-a3e7-4521-a085-e4dc3cd1cc57":{"name":"Shop.ItemLogicNoteVocal","displayName":"ロジックノート(ボーカル)理性笔记(声乐)","type":"template","annotationId":"a1df3af1-a3e7-4521-a085-e4dc3cd1cc57","useHintRect":false},"a9fcaf04-0c1f-4b0f-bb5b-ede9da96180f":{"name":"Shop.ItemLogicNoteDance","displayName":"ロジックノート(ダンス)理性笔记(舞蹈)","type":"template","annotationId":"a9fcaf04-0c1f-4b0f-bb5b-ede9da96180f","useHintRect":false},"c3f536d6-a04a-4651-b3f9-dd2c22593f7f":{"name":"Shop.ItemLogicNoteVisual","displayName":"ロジックノート(ビジュアル)理性笔记(形象)","type":"template","annotationId":"c3f536d6-a04a-4651-b3f9-dd2c22593f7f","useHintRect":false},"eef25cf9-afd0-43b1-b9c5-fbd997bd5fe0":{"name":"Shop.ItemAnomalyNoteVocal","displayName":"アノマリーノート(ボーカル)非凡笔记(声乐)","type":"template","annotationId":"eef25cf9-afd0-43b1-b9c5-fbd997bd5fe0","useHintRect":false},"df991b42-ed8e-4f2c-bf0c-aa7522f147b6":{"name":"Shop.ItemAnomalyNoteDance","displayName":"アノマリーノート(ダンス)非凡笔记(舞蹈)","type":"template","annotationId":"df991b42-ed8e-4f2c-bf0c-aa7522f147b6","useHintRect":false},"81c97cd3-df53-44d3-bf3d-1eb4dc67b62a":{"name":"Daily.ButtonRefreshMoneyShop","displayName":"リスト更新:1回無料","type":"template","annotationId":"81c97cd3-df53-44d3-bf3d-1eb4dc67b62a","useHintRect":false}},"annotations":[{"id":"0949c622-9067-4f0d-bac2-3f938a1d2ed2","type":"rect","data":{"x1":243,"y1":355,"x2":313,"y2":441}},{"id":"b2af59e9-60e3-4d97-8c72-c7ba092113a3","type":"rect","data":{"x1":414,"y1":355,"x2":484,"y2":441}},{"id":"835489e2-b29b-426c-b4c9-3bb9f8eb6195","type":"rect","data":{"x1":574,"y1":363,"x2":662,"y2":438}},{"id":"c5b7d67e-7260-4f08-a0e9-4d31ce9bbecf","type":"rect","data":{"x1":71,"y1":594,"x2":142,"y2":667}},{"id":"0f7d581d-cea3-4039-9205-732e4cd29293","type":"rect","data":{"x1":241,"y1":593,"x2":309,"y2":667}},{"id":"d3cc3323-51af-4882-ae12-49e7384b746d","type":"rect","data":{"x1":417,"y1":586,"x2":481,"y2":668}},{"id":"a1df3af1-a3e7-4521-a085-e4dc3cd1cc57","type":"rect","data":{"x1":585,"y1":591,"x2":651,"y2":669}},{"id":"a9fcaf04-0c1f-4b0f-bb5b-ede9da96180f","type":"rect","data":{"x1":69,"y1":825,"x2":138,"y2":899}},{"id":"c3f536d6-a04a-4651-b3f9-dd2c22593f7f","type":"rect","data":{"x1":242,"y1":820,"x2":310,"y2":898}},{"id":"eef25cf9-afd0-43b1-b9c5-fbd997bd5fe0","type":"rect","data":{"x1":413,"y1":821,"x2":481,"y2":897}},{"id":"df991b42-ed8e-4f2c-bf0c-aa7522f147b6","type":"rect","data":{"x1":583,"y1":823,"x2":649,"y2":900}},{"id":"81c97cd3-df53-44d3-bf3d-1eb4dc67b62a","type":"rect","data":{"x1":440,"y1":149,"x2":679,"y2":179}}]}
|
|
@ -1 +1 @@
|
|||
{"definitions":{"9340b854-025c-40da-9387-385d38433bef":{"name":"Shop.ItemAnomalyNoteVisual","displayName":"アノマリーノート(ビジュアル)非凡笔记(形象)","type":"template","annotationId":"9340b854-025c-40da-9387-385d38433bef","useHintRect":false},"ea1ba124-9cb3-4427-969a-bacd47e7d920":{"name":"Shop.ItemRechallengeTicket","displayName":"再挑戦チケット 重新挑战券","type":"template","annotationId":"ea1ba124-9cb3-4427-969a-bacd47e7d920","useHintRect":false},"1926f2f9-4bd7-48eb-9eba-28ec4efb0606":{"name":"Shop.ItemRecordKey","displayName":"記録の鍵 解锁交流的物品","type":"template","annotationId":"1926f2f9-4bd7-48eb-9eba-28ec4efb0606","useHintRect":false},"6720b6e8-ae80-4cc0-a885-518efe12b707":{"name":"Shop.IdolPiece.倉本千奈_WonderScale","displayName":"倉本千奈 WonderScale 碎片","type":"template","annotationId":"6720b6e8-ae80-4cc0-a885-518efe12b707","useHintRect":false},"afa06fdc-a345-4384-b25d-b16540830256":{"name":"Shop.IdolPiece.篠泽广_光景","displayName":"篠泽广 光景 碎片","type":"template","annotationId":"afa06fdc-a345-4384-b25d-b16540830256","useHintRect":false},"278b7d9c-707e-4392-9677-74574b5cdf42":{"name":"Shop.IdolPiece.紫云清夏_TameLieOneStep","displayName":"紫云清夏 Tame-Lie-One-Step 碎片","type":"template","annotationId":"278b7d9c-707e-4392-9677-74574b5cdf42","useHintRect":false},"e9ee330d-dfca-440e-8b8c-0a3b4e8c8730":{"name":"Daily.IconTitleDailyShop","displayName":"日常商店标题图标","type":"template","annotationId":"e9ee330d-dfca-440e-8b8c-0a3b4e8c8730","useHintRect":false}},"annotations":[{"id":"9340b854-025c-40da-9387-385d38433bef","type":"rect","data":{"x1":72,"y1":611,"x2":138,"y2":693}},{"id":"ea1ba124-9cb3-4427-969a-bacd47e7d920","type":"rect","data":{"x1":227,"y1":639,"x2":316,"y2":674}},{"id":"1926f2f9-4bd7-48eb-9eba-28ec4efb0606","type":"rect","data":{"x1":385,"y1":591,"x2":508,"y2":694}},{"id":"6720b6e8-ae80-4cc0-a885-518efe12b707","type":"rect","data":{"x1":589,"y1":633,"x2":638,"y2":678}},{"id":"afa06fdc-a345-4384-b25d-b16540830256","type":"rect","data":{"x1":83,"y1":867,"x2":134,"y2":912}},{"id":"278b7d9c-707e-4392-9677-74574b5cdf42","type":"rect","data":{"x1":247,"y1":864,"x2":301,"y2":907}},{"id":"e9ee330d-dfca-440e-8b8c-0a3b4e8c8730","type":"rect","data":{"x1":17,"y1":35,"x2":59,"y2":76}}]}
|
||||
{"definitions":{"9340b854-025c-40da-9387-385d38433bef":{"name":"Shop.ItemAnomalyNoteVisual","displayName":"アノマリーノート(ビジュアル)非凡笔记(形象)","type":"template","annotationId":"9340b854-025c-40da-9387-385d38433bef","useHintRect":false},"ea1ba124-9cb3-4427-969a-bacd47e7d920":{"name":"Shop.ItemRechallengeTicket","displayName":"再挑戦チケット 重新挑战券","type":"template","annotationId":"ea1ba124-9cb3-4427-969a-bacd47e7d920","useHintRect":false},"1926f2f9-4bd7-48eb-9eba-28ec4efb0606":{"name":"Shop.ItemRecordKey","displayName":"記録の鍵 解锁交流的物品","type":"template","annotationId":"1926f2f9-4bd7-48eb-9eba-28ec4efb0606","useHintRect":false},"e9ee330d-dfca-440e-8b8c-0a3b4e8c8730":{"name":"Daily.IconTitleDailyShop","displayName":"日常商店标题图标","type":"template","annotationId":"e9ee330d-dfca-440e-8b8c-0a3b4e8c8730","useHintRect":false}},"annotations":[{"id":"9340b854-025c-40da-9387-385d38433bef","type":"rect","data":{"x1":72,"y1":611,"x2":138,"y2":693}},{"id":"ea1ba124-9cb3-4427-969a-bacd47e7d920","type":"rect","data":{"x1":227,"y1":639,"x2":316,"y2":674}},{"id":"1926f2f9-4bd7-48eb-9eba-28ec4efb0606","type":"rect","data":{"x1":385,"y1":591,"x2":508,"y2":694}},{"id":"e9ee330d-dfca-440e-8b8c-0a3b4e8c8730","type":"rect","data":{"x1":17,"y1":35,"x2":59,"y2":76}}]}
|
Before Width: | Height: | Size: 300 KiB |
|
@ -1 +0,0 @@
|
|||
{"definitions":{"74ff07b3-d91c-4579-80cd-379ed7020622":{"name":"Shop.IdolPiece.葛城リーリヤ_白線","displayName":"葛城リーリヤ 白線 碎片","type":"template","annotationId":"74ff07b3-d91c-4579-80cd-379ed7020622","useHintRect":false}},"annotations":[{"id":"74ff07b3-d91c-4579-80cd-379ed7020622","type":"rect","data":{"x1":101,"y1":630,"x2":135,"y2":664}}]}
|
Before Width: | Height: | Size: 307 KiB |
|
@ -1 +0,0 @@
|
|||
{"definitions":{"a7f5abf1-982f-4a55-8d41-3ad6f56798e0":{"name":"Shop.IdolPiece.姫崎薪波_cIclumsy_trick ","displayName":"姫崎薪波 cIclumsy trick 碎片","type":"template","annotationId":"a7f5abf1-982f-4a55-8d41-3ad6f56798e0","useHintRect":false}},"annotations":[{"id":"a7f5abf1-982f-4a55-8d41-3ad6f56798e0","type":"rect","data":{"x1":113,"y1":628,"x2":148,"y2":656}}]}
|
Before Width: | Height: | Size: 295 KiB |
|
@ -1 +0,0 @@
|
|||
{"definitions":{"2bc00520-0afe-40e5-8743-d33fc6b2945a":{"name":"Shop.IdolPiece.花海咲季_FightingMyWay","displayName":"花海咲季 FightingMyWay 碎片","type":"template","annotationId":"2bc00520-0afe-40e5-8743-d33fc6b2945a","useHintRect":false}},"annotations":[{"id":"2bc00520-0afe-40e5-8743-d33fc6b2945a","type":"rect","data":{"x1":112,"y1":601,"x2":148,"y2":640}}]}
|
Before Width: | Height: | Size: 297 KiB |
|
@ -1 +0,0 @@
|
|||
{"definitions":{"135ee57a-d30d-4ba8-83f0-9f1681a49ff7":{"name":"Shop.IdolPiece.藤田ことね_世界一可愛い私","displayName":"藤田ことね 世界一可愛い私 碎片","type":"template","annotationId":"135ee57a-d30d-4ba8-83f0-9f1681a49ff7","useHintRect":false}},"annotations":[{"id":"135ee57a-d30d-4ba8-83f0-9f1681a49ff7","type":"rect","data":{"x1":113,"y1":602,"x2":146,"y2":635}}]}
|
Before Width: | Height: | Size: 294 KiB |
|
@ -1 +0,0 @@
|
|||
{"definitions":{"d15959bf-d07b-4f07-948a-c0aeaf17756a":{"name":"Shop.IdolPiece.花海佑芽_TheRollingRiceball","displayName":"花海佑芽 The Rolling Riceball 碎片","type":"template","annotationId":"d15959bf-d07b-4f07-948a-c0aeaf17756a","useHintRect":false}},"annotations":[{"id":"d15959bf-d07b-4f07-948a-c0aeaf17756a","type":"rect","data":{"x1":103,"y1":605,"x2":137,"y2":635}}]}
|
Before Width: | Height: | Size: 291 KiB |
|
@ -1 +0,0 @@
|
|||
{"definitions":{"868b97a9-492e-4712-b47f-82b97495b019":{"name":"Shop.IdolPiece.月村手毬_LunaSayMaybe","displayName":"月村手毬 Luna say maybe 碎片","type":"template","annotationId":"868b97a9-492e-4712-b47f-82b97495b019","useHintRect":false}},"annotations":[{"id":"868b97a9-492e-4712-b47f-82b97495b019","type":"rect","data":{"x1":106,"y1":601,"x2":145,"y2":633}}]}
|
After Width: | Height: | Size: 549 KiB |
|
@ -0,0 +1 @@
|
|||
{"definitions":{"3942ae40-7f22-412c-aebe-4b064f68db9b":{"name":"Shop.IdolPiece.花海咲季_FightingMyWay","displayName":"","type":"template","annotationId":"3942ae40-7f22-412c-aebe-4b064f68db9b","useHintRect":false},"185f7838-92a7-460b-9340-f60858948ce9":{"name":"Shop.IdolPiece.月村手毬_LunaSayMaybe","displayName":"","type":"template","annotationId":"185f7838-92a7-460b-9340-f60858948ce9","useHintRect":false},"cb3d0ca7-8d14-408a-a2f5-2e25f7b86d6c":{"name":"Shop.IdolPiece.藤田ことね_世界一可愛い私 ","displayName":"","type":"template","annotationId":"cb3d0ca7-8d14-408a-a2f5-2e25f7b86d6c","useHintRect":false},"213016c2-c3a2-43d8-86a3-ab4d27666ced":{"name":"Shop.IdolPiece.花海佑芽_TheRollingRiceball","displayName":"","type":"template","annotationId":"213016c2-c3a2-43d8-86a3-ab4d27666ced","useHintRect":false},"cc60b509-2ed5-493d-bb9f-333c6d2a6006":{"name":"Shop.IdolPiece.葛城リーリヤ_白線","displayName":"","type":"template","annotationId":"cc60b509-2ed5-493d-bb9f-333c6d2a6006","useHintRect":false},"5031808b-5525-4118-92b4-317ec8bda985":{"name":"Shop.IdolPiece.紫云清夏_TameLieOneStep","displayName":"","type":"template","annotationId":"5031808b-5525-4118-92b4-317ec8bda985","useHintRect":false},"ae9fe233-9acc-4e96-ba8e-1fb1d9bc2ea5":{"name":"Shop.IdolPiece.篠泽广_光景","displayName":"","type":"template","annotationId":"ae9fe233-9acc-4e96-ba8e-1fb1d9bc2ea5","useHintRect":false},"8f8b7b46-53bb-42ab-907a-4ea87eb09ab4":{"name":"Shop.IdolPiece.倉本千奈_WonderScale","displayName":"","type":"template","annotationId":"8f8b7b46-53bb-42ab-907a-4ea87eb09ab4","useHintRect":false},"0d9ac648-eefa-4869-ac99-1b0c83649681":{"name":"Shop.IdolPiece.有村麻央_Fluorite","displayName":"","type":"template","annotationId":"0d9ac648-eefa-4869-ac99-1b0c83649681","useHintRect":false}},"annotations":[{"id":"3942ae40-7f22-412c-aebe-4b064f68db9b","type":"rect","data":{"x1":409,"y1":342,"x2":477,"y2":413}},{"id":"185f7838-92a7-460b-9340-f60858948ce9","type":"rect","data":{"x1":71,"y1":512,"x2":140,"y2":585}},{"id":"cb3d0ca7-8d14-408a-a2f5-2e25f7b86d6c","type":"rect","data":{"x1":410,"y1":513,"x2":475,"y2":581}},{"id":"213016c2-c3a2-43d8-86a3-ab4d27666ced","type":"rect","data":{"x1":585,"y1":858,"x2":640,"y2":913}},{"id":"cc60b509-2ed5-493d-bb9f-333c6d2a6006","type":"rect","data":{"x1":247,"y1":690,"x2":303,"y2":743}},{"id":"5031808b-5525-4118-92b4-317ec8bda985","type":"rect","data":{"x1":80,"y1":860,"x2":133,"y2":908}},{"id":"ae9fe233-9acc-4e96-ba8e-1fb1d9bc2ea5","type":"rect","data":{"x1":418,"y1":852,"x2":471,"y2":912}},{"id":"8f8b7b46-53bb-42ab-907a-4ea87eb09ab4","type":"rect","data":{"x1":589,"y1":679,"x2":639,"y2":742}},{"id":"0d9ac648-eefa-4869-ac99-1b0c83649681","type":"rect","data":{"x1":83,"y1":690,"x2":136,"y2":744}}]}
|
After Width: | Height: | Size: 539 KiB |
|
@ -0,0 +1 @@
|
|||
{"definitions":{"921eefeb-730e-46fc-9924-d338fb286592":{"name":"Shop.IdolPiece.姬崎莉波_clumsy_trick","displayName":"","type":"template","annotationId":"921eefeb-730e-46fc-9924-d338fb286592","useHintRect":false}},"annotations":[{"id":"921eefeb-730e-46fc-9924-d338fb286592","type":"rect","data":{"x1":88,"y1":914,"x2":141,"y2":963}}]}
|
After Width: | Height: | Size: 506 KiB |
|
@ -0,0 +1 @@
|
|||
{"definitions":{"5d36b880-7b3f-49b1-a018-7de59867d376":{"name":"Daily.TextShopItemPurchased","displayName":"交換しました","type":"template","annotationId":"5d36b880-7b3f-49b1-a018-7de59867d376","useHintRect":false}},"annotations":[{"id":"5d36b880-7b3f-49b1-a018-7de59867d376","type":"rect","data":{"x1":275,"y1":626,"x2":432,"y2":655}}]}
|
After Width: | Height: | Size: 522 KiB |
|
@ -0,0 +1 @@
|
|||
{"definitions":{"24dc7158-036c-4a66-9280-e934f470be53":{"name":"Daily.TextShopItemSoldOut","displayName":"交換済みです","type":"template","annotationId":"24dc7158-036c-4a66-9280-e934f470be53","useHintRect":false}},"annotations":[{"id":"24dc7158-036c-4a66-9280-e934f470be53","type":"rect","data":{"x1":287,"y1":625,"x2":434,"y2":655}}]}
|
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 405 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 973 B |
|
@ -145,6 +145,18 @@ class KotoneBot:
|
|||
"""
|
||||
raise NotImplementedError('Implement `_create_device` before using Kotonebot.')
|
||||
|
||||
def _on_init_context(self) -> None:
|
||||
"""
|
||||
初始化 Context 的钩子方法。子类可以重写此方法来自定义初始化逻辑。
|
||||
默认实现调用 init_context 而不传入 target_screenshot_interval。
|
||||
"""
|
||||
d = self._on_create_device()
|
||||
init_context(
|
||||
config_path=self.config_path,
|
||||
config_type=self.config_type,
|
||||
target_device=d
|
||||
)
|
||||
|
||||
def _on_after_init_context(self):
|
||||
"""
|
||||
抽象方法,在 init_context() 被调用后立即执行。
|
||||
|
@ -155,8 +167,7 @@ class KotoneBot:
|
|||
"""
|
||||
按优先级顺序运行所有任务。
|
||||
"""
|
||||
d = self._on_create_device()
|
||||
init_context(config_path=self.config_path, config_type=self.config_type, target_device=d)
|
||||
self._on_init_context()
|
||||
self._on_after_init_context()
|
||||
vars.flow.clear_interrupt()
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ from cv2.typing import MatLike
|
|||
|
||||
from kotonebot.client.device import Device, AndroidDevice, WindowsDevice
|
||||
from kotonebot.backend.flow_controller import FlowController
|
||||
from kotonebot.util import Interval
|
||||
import kotonebot.backend.image as raw_image
|
||||
from kotonebot.backend.image import (
|
||||
TemplateMatchResult,
|
||||
|
@ -718,8 +719,20 @@ class Forwarded:
|
|||
|
||||
T_Device = TypeVar('T_Device', bound=Device)
|
||||
class ContextDevice(Generic[T_Device], Device):
|
||||
def __init__(self, device: T_Device):
|
||||
def __init__(self, device: T_Device, target_screenshot_interval: float | None = None):
|
||||
"""
|
||||
:param device: 目标设备。
|
||||
:param target_screenshot_interval: 见 `ContextDevice.target_screenshot_interval`。
|
||||
"""
|
||||
self._device = device
|
||||
self.target_screenshot_interval: float | None = target_screenshot_interval
|
||||
"""
|
||||
目标截图间隔,可用于限制截图速度。若两次截图实际间隔小于该值,则会自动等待。
|
||||
为 None 时不限制截图速度。
|
||||
"""
|
||||
self._screenshot_interval: Interval | None = None
|
||||
if self.target_screenshot_interval is not None:
|
||||
self._screenshot_interval = Interval(self.target_screenshot_interval)
|
||||
|
||||
def screenshot(self, *, force: bool = False):
|
||||
"""
|
||||
|
@ -734,6 +747,9 @@ class ContextDevice(Generic[T_Device], Device):
|
|||
img = current._inherit_screenshot
|
||||
current._inherit_screenshot = None
|
||||
else:
|
||||
if self._screenshot_interval is not None:
|
||||
self._screenshot_interval.wait()
|
||||
|
||||
if next_wait == 'screenshot':
|
||||
delta = time.time() - last_screenshot_time
|
||||
if delta < next_wait_time:
|
||||
|
@ -780,7 +796,8 @@ class Context(Generic[T]):
|
|||
self,
|
||||
config_path: str,
|
||||
config_type: Type[T],
|
||||
device: Device
|
||||
device: Device,
|
||||
target_screenshot_interval: float | None = None
|
||||
):
|
||||
self.__ocr = ContextOcr(self)
|
||||
self.__image = ContextImage(self)
|
||||
|
@ -788,7 +805,7 @@ class Context(Generic[T]):
|
|||
self.__vars = ContextGlobalVars()
|
||||
self.__debug = ContextDebug(self)
|
||||
self.__config = ContextConfig[T](self, config_path, config_type)
|
||||
self.__device = ContextDevice(device)
|
||||
self.__device = ContextDevice(device, target_screenshot_interval)
|
||||
|
||||
def inject(
|
||||
self,
|
||||
|
@ -900,6 +917,7 @@ def init_context(
|
|||
config_type: Type[T] = dict[str, Any],
|
||||
force: bool = False,
|
||||
target_device: Device,
|
||||
target_screenshot_interval: float | None = None,
|
||||
):
|
||||
"""
|
||||
初始化 Context 模块。
|
||||
|
@ -911,6 +929,7 @@ def init_context(
|
|||
:param force: 是否强制重新初始化。
|
||||
若为 `True`,则忽略已存在的 Context 实例,并重新创建一个新的实例。
|
||||
:param target_device: 目标设备
|
||||
:param target_screenshot_interval: 见 `ContextDevice.target_screenshot_interval`。
|
||||
"""
|
||||
global _c, device, ocr, image, color, vars, debug, config
|
||||
if _c is not None and not force:
|
||||
|
@ -919,6 +938,7 @@ def init_context(
|
|||
config_path=config_path,
|
||||
config_type=config_type,
|
||||
device=target_device,
|
||||
target_screenshot_interval=target_screenshot_interval,
|
||||
)
|
||||
device._FORWARD_getter = lambda: _c.device # type: ignore
|
||||
ocr._FORWARD_getter = lambda: _c.ocr # type: ignore
|
||||
|
|
|
@ -50,6 +50,8 @@ class BackendConfig(ConfigBaseModel):
|
|||
"""Windows 截图方式的 AutoHotkey 可执行文件路径,为 None 时使用默认路径"""
|
||||
mumu_background_mode: bool = False
|
||||
"""MuMu12 模拟器后台保活模式"""
|
||||
target_screenshot_interval: float | None = None
|
||||
"""最小截图间隔,单位为秒。为 None 时不限制截图速度。"""
|
||||
|
||||
class PushConfig(ConfigBaseModel):
|
||||
"""推送配置。"""
|
||||
|
|
|
@ -80,7 +80,7 @@ class DailyMoneyShopItems(IntEnum):
|
|||
"""紫云清夏 Tame-Lie-One-Step 碎片"""
|
||||
IdolPiece_葛城リーリヤ_白線 = 17
|
||||
"""葛城リーリヤ 白線 碎片"""
|
||||
IdolPiece_姫崎薪波_cIclumsy_trick = 18
|
||||
IdolPiece_姬崎莉波_clumsy_trick = 18
|
||||
"""姫崎薪波 cIclumsy trick 碎片"""
|
||||
IdolPiece_花海咲季_FightingMyWay = 19
|
||||
"""花海咲季 FightingMyWay 碎片"""
|
||||
|
@ -90,6 +90,8 @@ class DailyMoneyShopItems(IntEnum):
|
|||
"""花海佑芽 The Rolling Riceball 碎片"""
|
||||
IdolPiece_月村手毬_LunaSayMaybe = 22
|
||||
"""月村手毬 Luna say maybe 碎片"""
|
||||
IdolPiece_有村麻央_Fluorite = 23
|
||||
"""有村麻央 Fluorite 碎片"""
|
||||
|
||||
@classmethod
|
||||
def to_ui_text(cls, item: "DailyMoneyShopItems") -> str:
|
||||
|
@ -126,23 +128,25 @@ class DailyMoneyShopItems(IntEnum):
|
|||
case cls.RecordKey:
|
||||
return "记录钥匙"
|
||||
case cls.IdolPiece_倉本千奈_WonderScale:
|
||||
return "倉本千奈 WonderScale 碎片"
|
||||
return "倉本千奈 WonderScale 碎片"
|
||||
case cls.IdolPiece_篠泽广_光景:
|
||||
return "篠泽广 光景 碎片"
|
||||
return "篠泽广 光景 碎片"
|
||||
case cls.IdolPiece_紫云清夏_TameLieOneStep:
|
||||
return "紫云清夏 Tame-Lie-One-Step 碎片"
|
||||
return "紫云清夏 Tame-Lie-One-Step 碎片"
|
||||
case cls.IdolPiece_葛城リーリヤ_白線:
|
||||
return "葛城リーリヤ 白線 碎片"
|
||||
case cls.IdolPiece_姫崎薪波_cIclumsy_trick:
|
||||
return "姫崎薪波 cIclumsy trick 碎片"
|
||||
return "葛城リーリヤ 白線 碎片"
|
||||
case cls.IdolPiece_姬崎莉波_clumsy_trick:
|
||||
return "姫崎薪波 clumsy trick 碎片"
|
||||
case cls.IdolPiece_花海咲季_FightingMyWay:
|
||||
return "花海咲季 FightingMyWay 碎片"
|
||||
return "花海咲季 FightingMyWay 碎片"
|
||||
case cls.IdolPiece_藤田ことね_世界一可愛い私:
|
||||
return "藤田ことね 世界一可愛い私 碎片"
|
||||
return "藤田ことね 世界一可愛い私 碎片"
|
||||
case cls.IdolPiece_花海佑芽_TheRollingRiceball:
|
||||
return "花海佑芽 The Rolling Riceball 碎片"
|
||||
return "花海佑芽 The Rolling Riceball 碎片"
|
||||
case cls.IdolPiece_月村手毬_LunaSayMaybe:
|
||||
return "月村手毬 Luna say maybe 碎片"
|
||||
return "月村手毬 Luna say maybe 碎片"
|
||||
case cls.IdolPiece_有村麻央_Fluorite:
|
||||
return "有村麻央 Fluorite 碎片"
|
||||
case _:
|
||||
assert_never(item)
|
||||
|
||||
|
@ -202,8 +206,8 @@ class DailyMoneyShopItems(IntEnum):
|
|||
return R.Shop.IdolPiece.紫云清夏_TameLieOneStep
|
||||
case DailyMoneyShopItems.IdolPiece_葛城リーリヤ_白線:
|
||||
return R.Shop.IdolPiece.葛城リーリヤ_白線
|
||||
case DailyMoneyShopItems.IdolPiece_姫崎薪波_cIclumsy_trick:
|
||||
return R.Shop.IdolPiece.姫崎薪波_cIclumsy_trick
|
||||
case DailyMoneyShopItems.IdolPiece_姬崎莉波_clumsy_trick:
|
||||
return R.Shop.IdolPiece.姬崎莉波_clumsy_trick
|
||||
case DailyMoneyShopItems.IdolPiece_花海咲季_FightingMyWay:
|
||||
return R.Shop.IdolPiece.花海咲季_FightingMyWay
|
||||
case DailyMoneyShopItems.IdolPiece_藤田ことね_世界一可愛い私:
|
||||
|
@ -212,6 +216,8 @@ class DailyMoneyShopItems(IntEnum):
|
|||
return R.Shop.IdolPiece.花海佑芽_TheRollingRiceball
|
||||
case DailyMoneyShopItems.IdolPiece_月村手毬_LunaSayMaybe:
|
||||
return R.Shop.IdolPiece.月村手毬_LunaSayMaybe
|
||||
case DailyMoneyShopItems.IdolPiece_有村麻央_Fluorite:
|
||||
return R.Shop.IdolPiece.有村麻央_Fluorite
|
||||
case _:
|
||||
assert_never(self)
|
||||
|
||||
|
@ -225,13 +231,9 @@ class PurchaseConfig(ConfigBaseModel):
|
|||
"""是否启用金币购买"""
|
||||
money_items: list[DailyMoneyShopItems] = []
|
||||
"""金币商店要购买的物品"""
|
||||
money_refresh_on: Literal['never', 'not_found', 'always'] = 'never'
|
||||
money_refresh: bool = True
|
||||
"""
|
||||
金币商店刷新逻辑。
|
||||
|
||||
* never: 从不刷新。
|
||||
* not_found: 仅当要购买的物品不存在时刷新。
|
||||
* always: 总是刷新。
|
||||
是否使用每日一次免费刷新金币商店。
|
||||
"""
|
||||
ap_enabled: bool = False
|
||||
"""是否启用AP购买"""
|
||||
|
@ -465,16 +467,22 @@ class MiscConfig(ConfigBaseModel):
|
|||
check_update: Literal['never', 'startup'] = 'startup'
|
||||
"""
|
||||
检查更新时机。
|
||||
|
||||
|
||||
* never: 从不检查更新。
|
||||
* startup: 启动时检查更新。
|
||||
"""
|
||||
auto_install_update: bool = True
|
||||
"""
|
||||
是否自动安装更新。
|
||||
|
||||
|
||||
若启用,则每次自动检查更新时若有新版本会自动安装,否则只是会提示。
|
||||
"""
|
||||
expose_to_lan: bool = False
|
||||
"""
|
||||
是否允许局域网访问 Web 界面。
|
||||
|
||||
启用后,局域网内的其他设备可以通过本机 IP 地址访问 Web 界面。
|
||||
"""
|
||||
|
||||
class BaseConfig(ConfigBaseModel):
|
||||
purchase: PurchaseConfig = PurchaseConfig()
|
||||
|
|
|
@ -37,12 +37,12 @@ ConfigKey = Literal[
|
|||
'check_emulator', 'emulator_path',
|
||||
'adb_emulator_name', 'emulator_args',
|
||||
'_mumu_index', '_leidian_index',
|
||||
'mumu_background_mode',
|
||||
'mumu_background_mode', 'target_screenshot_interval',
|
||||
|
||||
# purchase
|
||||
'purchase_enabled',
|
||||
'money_enabled', 'ap_enabled',
|
||||
'ap_items', 'money_items',
|
||||
'ap_items', 'money_items', 'money_refresh',
|
||||
|
||||
# assignment
|
||||
'assignment_enabled',
|
||||
|
@ -92,8 +92,8 @@ ConfigKey = Literal[
|
|||
'trace_recommend_card_detection',
|
||||
|
||||
# misc
|
||||
'check_update', 'auto_install_update',
|
||||
|
||||
'check_update', 'auto_install_update', 'expose_to_lan',
|
||||
|
||||
'_selected_backend_index'
|
||||
|
||||
]
|
||||
|
@ -761,6 +761,15 @@ class KotoneBotUI:
|
|||
interactive=True
|
||||
)
|
||||
|
||||
target_screenshot_interval = gr.Number(
|
||||
label="最小截图间隔(秒)",
|
||||
value=self.current_config.backend.target_screenshot_interval,
|
||||
info=BackendConfig.model_fields['target_screenshot_interval'].description,
|
||||
minimum=0,
|
||||
step=0.1,
|
||||
interactive=True
|
||||
)
|
||||
|
||||
tab_mumu12.select(fn=partial(_update_emulator_tab_options, selected_index=0), inputs=[screenshot_impl], outputs=[screenshot_impl])
|
||||
tab_leidian.select(fn=partial(_update_emulator_tab_options, selected_index=1), inputs=[screenshot_impl], outputs=[screenshot_impl])
|
||||
tab_custom.select(fn=partial(_update_emulator_tab_options, selected_index=2), inputs=[screenshot_impl], outputs=[screenshot_impl])
|
||||
|
@ -814,12 +823,14 @@ class KotoneBotUI:
|
|||
|
||||
# Common settings for all backend types
|
||||
self.current_config.backend.screenshot_impl = data['screenshot_method']
|
||||
self.current_config.backend.target_screenshot_interval = data['target_screenshot_interval']
|
||||
self.current_config.keep_screenshots = data['keep_screenshots'] # This is a UserConfig field
|
||||
|
||||
return set_config, {
|
||||
'adb_ip': adb_ip,
|
||||
'adb_port': adb_port,
|
||||
'screenshot_method': screenshot_impl, # screenshot_impl is the component
|
||||
'target_screenshot_interval': target_screenshot_interval,
|
||||
'keep_screenshots': keep_screenshots,
|
||||
'check_emulator': check_emulator,
|
||||
'emulator_path': emulator_path,
|
||||
|
@ -854,6 +865,12 @@ class KotoneBotUI:
|
|||
info=PurchaseConfig.model_fields['money_items'].description
|
||||
)
|
||||
|
||||
money_refresh = gr.Checkbox(
|
||||
label="每日一次免费刷新金币商店",
|
||||
value=self.current_config.options.purchase.money_refresh,
|
||||
info=PurchaseConfig.model_fields['money_refresh'].description
|
||||
)
|
||||
|
||||
ap_enabled = gr.Checkbox(
|
||||
label="启用AP购买",
|
||||
value=self.current_config.options.purchase.ap_enabled,
|
||||
|
@ -891,6 +908,7 @@ class KotoneBotUI:
|
|||
config.purchase.enabled = data['purchase_enabled']
|
||||
config.purchase.money_enabled = data['money_enabled']
|
||||
config.purchase.money_items = [DailyMoneyShopItems(x) for x in data['money_items']]
|
||||
config.purchase.money_refresh = data['money_refresh']
|
||||
config.purchase.ap_enabled = data['ap_enabled']
|
||||
ap_items_enum: List[Literal[0, 1, 2, 3]] = []
|
||||
ap_items_map: Dict[str, APShopItems] = {
|
||||
|
@ -909,7 +927,8 @@ class KotoneBotUI:
|
|||
'money_enabled': money_enabled,
|
||||
'ap_enabled': ap_enabled,
|
||||
'ap_items': ap_items,
|
||||
'money_items': money_items
|
||||
'money_items': money_items,
|
||||
'money_refresh': money_refresh
|
||||
}
|
||||
|
||||
def _create_work_settings(self) -> ConfigBuilderReturnValue:
|
||||
|
@ -1494,14 +1513,22 @@ class KotoneBotUI:
|
|||
info=MiscConfig.model_fields['auto_install_update'].description,
|
||||
interactive=True
|
||||
)
|
||||
|
||||
expose_to_lan = gr.Checkbox(
|
||||
label="允许局域网访问",
|
||||
value=self.current_config.options.misc.expose_to_lan,
|
||||
info=MiscConfig.model_fields['expose_to_lan'].description,
|
||||
interactive=True
|
||||
)
|
||||
|
||||
def set_config(config: BaseConfig, data: dict[ConfigKey, Any]) -> None:
|
||||
config.misc.check_update = data['check_update']
|
||||
config.misc.auto_install_update = data['auto_install_update']
|
||||
config.misc.expose_to_lan = data['expose_to_lan']
|
||||
|
||||
return set_config, {
|
||||
'check_update': check_update,
|
||||
'auto_install_update': auto_install_update
|
||||
'auto_install_update': auto_install_update,
|
||||
'expose_to_lan': expose_to_lan
|
||||
}
|
||||
|
||||
def _create_settings_tab(self) -> None:
|
||||
|
@ -1888,7 +1915,9 @@ def main(kaa: Kaa | None = None) -> None:
|
|||
kaa = kaa or Kaa('./config.json')
|
||||
ui = KotoneBotUI(kaa)
|
||||
app = ui.create_ui()
|
||||
app.launch(inbrowser=True, show_error=True)
|
||||
|
||||
server_name = "0.0.0.0" if ui.current_config.options.misc.expose_to_lan else "127.0.0.1"
|
||||
app.launch(inbrowser=True, show_error=True, server_name=server_name)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -110,6 +110,27 @@ class Kaa(KotoneBot):
|
|||
logger.exception('Failed to save error report:')
|
||||
return ''
|
||||
|
||||
@override
|
||||
def _on_init_context(self) -> None:
|
||||
"""
|
||||
初始化 Context,从配置中读取 target_screenshot_interval。
|
||||
"""
|
||||
from kotonebot.config.manager import load_config
|
||||
from kotonebot.backend.context import init_context
|
||||
|
||||
# 加载配置以获取 target_screenshot_interval
|
||||
config = load_config(self.config_path, type=self.config_type)
|
||||
user_config = config.user_configs[0] # HACK: 硬编码
|
||||
target_screenshot_interval = user_config.backend.target_screenshot_interval
|
||||
|
||||
d = self._on_create_device()
|
||||
init_context(
|
||||
config_path=self.config_path,
|
||||
config_type=self.config_type,
|
||||
target_device=d,
|
||||
target_screenshot_interval=target_screenshot_interval
|
||||
)
|
||||
|
||||
@override
|
||||
def _on_after_init_context(self):
|
||||
if self.backend_instance is None:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""收取活动费"""
|
||||
import logging
|
||||
|
||||
from kotonebot.backend.loop import Loop
|
||||
from kotonebot.kaa.tasks import R
|
||||
from kotonebot.kaa.common import conf
|
||||
from ..actions.scenes import at_home, goto_home
|
||||
|
@ -16,17 +17,18 @@ def acquire_activity_funds():
|
|||
|
||||
if not at_home():
|
||||
goto_home()
|
||||
device.screenshot()
|
||||
if color.find('#ff1249', rect=R.Daily.BoxHomeActivelyFunds):
|
||||
logger.info('Claiming activity funds.')
|
||||
device.click(R.Daily.BoxHomeActivelyFunds)
|
||||
device.click(image.expect_wait(R.Common.ButtonClose))
|
||||
logger.info('Activity funds claimed.')
|
||||
else:
|
||||
logger.info('No activity funds to claim.')
|
||||
|
||||
while not at_home():
|
||||
pass
|
||||
for _ in Loop():
|
||||
if (
|
||||
not color.find('#ff1249', rect=R.Daily.BoxHomeActivelyFunds)
|
||||
and at_home()
|
||||
):
|
||||
break
|
||||
elif image.find(R.Common.ButtonClose):
|
||||
logger.info('Closing popup dialog.')
|
||||
device.click()
|
||||
else:
|
||||
device.click(R.Daily.BoxHomeActivelyFunds)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import logging
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from kotonebot.backend.loop import Loop
|
||||
from kotonebot.kaa.tasks import R
|
||||
from kotonebot.kaa.common import conf, DailyMoneyShopItems
|
||||
from kotonebot.util import cropped
|
||||
from kotonebot.primitives.geometry import Point
|
||||
from kotonebot.util import Countdown, cropped
|
||||
from kotonebot import task, device, image, action, sleep
|
||||
from kotonebot.backend.dispatch import SimpleDispatcher
|
||||
from ..actions.scenes import goto_home, goto_shop, at_daily_shop
|
||||
|
@ -37,10 +39,10 @@ def money_items2(items: Optional[list[DailyMoneyShopItems]] = None):
|
|||
scroll = 0
|
||||
while items:
|
||||
for item in items:
|
||||
if image.find(item.to_resource(), colored=True):
|
||||
if ret := image.find(item.to_resource(), colored=True):
|
||||
logger.info(f'Purchasing {item.to_ui_text(item)}...')
|
||||
device.click()
|
||||
handle_purchase_dialog()
|
||||
confirm_purchase(ret.position)
|
||||
finished.append(item)
|
||||
items = [item for item in items if item not in finished]
|
||||
# 全都买完了
|
||||
|
@ -71,16 +73,17 @@ def dispatch_recommended_items():
|
|||
|
||||
while True:
|
||||
device.screenshot()
|
||||
if image.find(R.Daily.TextShopRecommended):
|
||||
if rec := image.find(R.Daily.TextShopRecommended):
|
||||
logger.info(f'Clicking on recommended item.') # TODO: 计数
|
||||
device.click()
|
||||
handle_purchase_dialog()
|
||||
confirm_purchase(rec.position)
|
||||
sleep(2.5) #
|
||||
elif image.find(R.Daily.IconTitleDailyShop) and not image.find(R.Daily.TextShopRecommended):
|
||||
logger.info(f'No recommended item found. Finished.')
|
||||
break
|
||||
|
||||
@action('确认购买', screenshot_mode='manual-inherit')
|
||||
def handle_purchase_dialog():
|
||||
def confirm_purchase(target_item_pos: Point | None = None):
|
||||
"""
|
||||
确认购买
|
||||
|
||||
|
@ -89,11 +92,27 @@ def handle_purchase_dialog():
|
|||
"""
|
||||
# 前置条件:[screenshots\shop\dialog.png]
|
||||
# TODO: 需要有个更好的方式检测是否已购买
|
||||
purchased = (SimpleDispatcher('dispatch_purchase_dialog')
|
||||
.until(R.Common.ButtonConfirm, result=False)
|
||||
.until(R.Daily.TextShopPurchased, result=True)
|
||||
.timeout(timeout=3, result=True)
|
||||
).run()
|
||||
purchased = False
|
||||
cd = Countdown(sec=3)
|
||||
for _ in Loop():
|
||||
if cd.expired():
|
||||
purchased = True
|
||||
break
|
||||
if image.find(R.Daily.TextShopItemSoldOut):
|
||||
logger.info('Item sold out.')
|
||||
purchased = True
|
||||
break
|
||||
elif image.find(R.Daily.TextShopItemPurchased):
|
||||
logger.info('Item already purchased.')
|
||||
purchased = True
|
||||
break
|
||||
elif image.find(R.Common.ButtonConfirm):
|
||||
logger.info('Confirming purchase...')
|
||||
device.click()
|
||||
sleep(0.5)
|
||||
else:
|
||||
if target_item_pos:
|
||||
device.click(target_item_pos)
|
||||
|
||||
if purchased:
|
||||
logger.info('Item sold out.')
|
||||
|
@ -132,20 +151,19 @@ def ap_items():
|
|||
logger.info(f'Purchasing #{index} AP item.')
|
||||
device.click(results[index])
|
||||
sleep(0.5)
|
||||
with cropped(device, y1=0.3):
|
||||
purchased = image.wait_for(R.Daily.TextShopPurchased, timeout=1)
|
||||
if purchased is not None:
|
||||
logger.info(f'AP item #{index} already purchased.')
|
||||
continue
|
||||
comfirm = image.expect_wait(R.Common.ButtonConfirm, timeout=2)
|
||||
# 如果数量不是最大,调到最大
|
||||
while image.find(R.Daily.ButtonShopCountAdd, colored=True):
|
||||
logger.debug('Adjusting quantity(+1)...')
|
||||
device.click()
|
||||
sleep(0.3)
|
||||
logger.debug(f'Confirming purchase...')
|
||||
device.click(comfirm)
|
||||
sleep(1.5)
|
||||
purchased = image.wait_for(R.Daily.TextShopItemSoldOut, timeout=1)
|
||||
if purchased is not None:
|
||||
logger.info(f'AP item #{index} already purchased.')
|
||||
continue
|
||||
comfirm = image.expect_wait(R.Common.ButtonConfirm, timeout=2)
|
||||
# 如果数量不是最大,调到最大
|
||||
while image.find(R.Daily.ButtonShopCountAdd, colored=True):
|
||||
logger.debug('Adjusting quantity(+1)...')
|
||||
device.click()
|
||||
sleep(0.3)
|
||||
logger.debug(f'Confirming purchase...')
|
||||
device.click(comfirm)
|
||||
sleep(1.5)
|
||||
else:
|
||||
logger.warning(f'AP item #{index} not found')
|
||||
logger.info(f'Purchasing AP items completed. {len(item_indices)} items purchased.')
|
||||
|
@ -158,8 +176,8 @@ def purchase():
|
|||
if not conf().purchase.enabled:
|
||||
logger.info('Purchase is disabled.')
|
||||
return
|
||||
if not at_daily_shop():
|
||||
goto_shop()
|
||||
|
||||
goto_shop()
|
||||
# 进入每日商店 [screenshots\shop\shop.png]
|
||||
device.click(image.expect(R.Daily.ButtonDailyShop)) # TODO: memoable
|
||||
# 等待载入
|
||||
|
@ -170,6 +188,12 @@ def purchase():
|
|||
image.expect_wait(R.Daily.IconShopMoney)
|
||||
money_items2()
|
||||
sleep(0.5)
|
||||
if image.find(R.Daily.ButtonRefreshMoneyShop):
|
||||
logger.info('Refreshing money shop.')
|
||||
device.click()
|
||||
sleep(0.5)
|
||||
money_items2()
|
||||
sleep(0.5)
|
||||
else:
|
||||
logger.info('Money purchase is disabled.')
|
||||
|
||||
|
@ -178,7 +202,7 @@ def purchase():
|
|||
# 点击 AP 选项卡
|
||||
device.click(ap_tab)
|
||||
# 等待 AP 选项卡加载完成
|
||||
image.expect_wait(R.Daily.IconShopAp)
|
||||
image.expect_wait(R.Daily.IconShopAp, threshold=0.7)
|
||||
ap_items()
|
||||
sleep(0.5)
|
||||
else:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit bca78ea35b0883c24814c523cec1856615205199
|
||||
Subproject commit 4328e2b53dc6e3efa4fef691064f40ceb998c97a
|