diff --git a/config/world_patrol/P02_YLL6/R05_CXHL_R05_GZCQX.yml b/config/world_patrol/P02_YLL6/R05_CXHL_R05_GZCQX.yml index 28e78bc7..e93f0664 100644 --- a/config/world_patrol/P02_YLL6/R05_CXHL_R05_GZCQX.yml +++ b/config/world_patrol/P02_YLL6/R05_CXHL_R05_GZCQX.yml @@ -20,6 +20,7 @@ route: data: [265, 1190] - op: 'move' data: [265, 1320] + - op: 'patrol' - op: 'move' - data: [295, 1324] + data: [303, 1320] - op: 'patrol' diff --git a/config/world_patrol/P03_XZLF/R06_TBS_R02_JHZ_2.yml b/config/world_patrol/P03_XZLF/R06_TBS_R02_JHZ_2.yml index e897d6cb..5a1d790b 100644 --- a/config/world_patrol/P03_XZLF/R06_TBS_R02_JHZ_2.yml +++ b/config/world_patrol/P03_XZLF/R06_TBS_R02_JHZ_2.yml @@ -17,25 +17,32 @@ route: data: [286, 420] - op: 'patrol' - op: 'move' - data: [212, 417] + data: [230, 420] + - op: 'move' + data: [231, 407] + - op: 'patrol' + - op: 'move' + data: [229, 389] - op: 'patrol' - op: 'move' - data: [212, 391] + data: [192, 389] + - op: 'move' + data: [192, 420] - op: 'patrol' - op: 'move' - data: [235, 420] + data: [230, 420] - op: 'move' - data: [289, 420] + data: [288, 420] - op: 'move' - data: [289, 520] + data: [285, 520] - op: 'move' - data: [327, 559] + data: [330, 563] - op: 'move' - data: [377, 580] + data: [378, 580] - op: 'move' - data: [404, 635] + data: [403, 635] - op: 'move' data: [436, 666] - op: 'move' - data: [522, 668] + data: [522, 670] - op: 'patrol' diff --git a/config/world_patrol/P03_XZLF/R07_GZS_R01_RJFTD.yml b/config/world_patrol/P03_XZLF/R07_GZS_R01_RJFTD.yml index 26180f60..0fd2c9c2 100644 --- a/config/world_patrol/P03_XZLF/R07_GZS_R01_RJFTD.yml +++ b/config/world_patrol/P03_XZLF/R07_GZS_R01_RJFTD.yml @@ -5,47 +5,32 @@ floor: 0 tp: '镕金坊通道' route: - op: 'move' - data: [793, 589] + data: [793, 601] - op: 'move' - data: [793, 500] + data: [796, 502] - op: 'move' - data: [831, 500] - - op: 'move' - data: [896, 502] - - op: 'move' - data: [915, 501] + data: [911, 502] - op: 'patrol' - op: 'move' - data: [896, 502] - - op: 'move' - data: [831, 500] - - op: 'move' - data: [798, 500] - - op: 'move' - data: [798, 474] - - op: 'move' - data: [799, 439] - - op: 'move' - data: [779, 430] - - op: 'move' - data: [779, 450] + data: [943, 502] - op: 'patrol' - op: 'move' - data: [779, 407] + data: [796, 502] - op: 'move' - data: [821, 407] + data: [798, 431] - op: 'move' - data: [869, 407] + data: [779, 431] - op: 'move' - data: [867, 357] + data: [779, 444] + - op: 'patrol' - op: 'move' - data: [855, 353] + data: [779, 405] - op: 'move' - data: [858, 305] + data: [864, 405] - op: 'move' - data: [880, 305] + data: [855, 312] - op: 'move' - data: [880, 320] + data: [884, 311] - op: 'patrol' - op: 'move' data: [880, 258] @@ -56,29 +41,22 @@ route: - op: 'interact' data: '入画' - op: 'wait' - data: ['in_world', '20'] + data: ['i', 'n'] - op: 'update_pos' - data: [573, 319] - - op: 'move' - data: [462, 335] + data: [558, 321] - op: 'move' - data: [415, 337] + data: [444, 333] - op: 'patrol' - op: 'move' - data: [413, 370] + data: [407, 346] - op: 'patrol' - op: 'move' - data: [408, 406] + data: [370, 410] - op: 'move' - data: [369, 403] - - op: 'move' - data: [368, 324] - - op: 'move' - data: [348, 329] - - op: 'patrol' + data: [368, 321] - op: 'move' - data: [343, 392] + data: [344, 334] - op: 'patrol' - op: 'move' - data: [346, 427] + data: [343, 414] - op: 'patrol' diff --git a/config/world_patrol/P03_XZLF/R08_DDS_R03_GYT_2.yml b/config/world_patrol/P03_XZLF/R08_DDS_R03_GYT_2.yml index a5f23965..372fa4d8 100644 --- a/config/world_patrol/P03_XZLF/R08_DDS_R03_GYT_2.yml +++ b/config/world_patrol/P03_XZLF/R08_DDS_R03_GYT_2.yml @@ -1,4 +1,4 @@ -author: ['DoctorReid'] +author: ['DoctorReid', '龙女姬'] planet: '仙舟罗浮' region: '丹鼎司' floor: 1 @@ -15,38 +15,27 @@ route: - op: 'move' data: [498, 924] - op: 'move' - data: [502, 913] + data: [507, 838] - op: 'move' - data: [504, 844] - - op: 'move' - data: [531, 846] - - op: 'move' - data: [531, 866] + data: [531, 852] - op: 'patrol' - op: 'move' - data: [531, 846] - - op: 'move' - data: [504, 844] - - op: 'move' - data: [502, 913] - - op: 'move' - data: [498, 924] - - op: 'move' - data: [500, 1015] + data: [531, 885] + - op: 'patrol' - op: 'move' - data: [502, 1080] + data: [532, 836] - op: 'move' - data: [515, 1115] + data: [506, 838] - op: 'move' - data: [540, 1117] + data: [502, 1019] - op: 'move' - data: [611, 1119] + data: [500, 1113] - op: 'move' - data: [611, 1221] + data: [613, 1115] - op: 'move' - data: [604, 1244] + data: [607, 1245] - op: 'move' - data: [632, 1265] + data: [634, 1266] - op: 'move' - data: [645, 1242] + data: [650, 1254] - op: 'patrol' diff --git a/config/world_patrol/P03_XZLF/R08_DDS_R04_YSZJ.yml b/config/world_patrol/P03_XZLF/R08_DDS_R04_YSZJ.yml index 66397c2b..9518f298 100644 --- a/config/world_patrol/P03_XZLF/R08_DDS_R04_YSZJ.yml +++ b/config/world_patrol/P03_XZLF/R08_DDS_R04_YSZJ.yml @@ -1,4 +1,4 @@ -author: ['DoctorReid'] +author: ['DoctorReid', '龙女姬'] planet: '仙舟罗浮' region: '丹鼎司' floor: 2 @@ -43,5 +43,8 @@ route: - op: 'move' data: [708, 1016] - op: 'move' - data: [573, 1016] + data: [556, 1017] + - op: 'patrol' + - op: 'move' + data: [559, 975] - op: 'patrol' diff --git a/config/world_patrol/P03_XZLF/R09_LYJ_R01_NSZX.yml b/config/world_patrol/P03_XZLF/R09_LYJ_R01_NSZX.yml index 74f7444a..acdc5579 100644 --- a/config/world_patrol/P03_XZLF/R09_LYJ_R01_NSZX.yml +++ b/config/world_patrol/P03_XZLF/R09_LYJ_R01_NSZX.yml @@ -1,4 +1,4 @@ -author: ['DoctorReid'] +author: ['DoctorReid', '龙女姬'] planet: '仙舟罗浮' region: '鳞渊境' floor: 0 @@ -15,3 +15,6 @@ route: - op: 'move' data: [799, 175] - op: 'patrol' + - op: 'move' + data: [789, 200] + - op: 'patrol' diff --git a/data/locales/cn/LC_MESSAGES/ocr.mo b/data/locales/cn/LC_MESSAGES/ocr.mo index 96f25930..2030e4da 100644 Binary files a/data/locales/cn/LC_MESSAGES/ocr.mo and b/data/locales/cn/LC_MESSAGES/ocr.mo differ diff --git a/data/locales/cn/LC_MESSAGES/ui.mo b/data/locales/cn/LC_MESSAGES/ui.mo index 2030e4da..1c2c5c85 100644 Binary files a/data/locales/cn/LC_MESSAGES/ui.mo and b/data/locales/cn/LC_MESSAGES/ui.mo differ diff --git a/data/locales/en/LC_MESSAGES/ocr.mo b/data/locales/en/LC_MESSAGES/ocr.mo index af54ff4b..bc81240b 100644 Binary files a/data/locales/en/LC_MESSAGES/ocr.mo and b/data/locales/en/LC_MESSAGES/ocr.mo differ diff --git a/data/locales/en/LC_MESSAGES/ui.mo b/data/locales/en/LC_MESSAGES/ui.mo index ac1be3da..97daac3d 100644 Binary files a/data/locales/en/LC_MESSAGES/ui.mo and b/data/locales/en/LC_MESSAGES/ui.mo differ diff --git a/data/locales/ocr/cn.po b/data/locales/ocr/cn.po index d45680d9..3d773648 100644 --- a/data/locales/ocr/cn.po +++ b/data/locales/ocr/cn.po @@ -3,117 +3,3 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -# 星球 -msgid "空间站黑塔" -msgstr "空间站" - -msgid "仙舟罗浮" -msgstr "仙舟" - -# 区域 - 雅利洛 -msgid "残响回廊" -msgstr "回廊" - -msgid "铆钉镇" -msgstr "钉镇" - -# 区域 - 仙舟罗浮 -msgid "廻星港" -msgstr "星港" - -# 特殊点 - 空间站黑塔 - 主控舱段 -msgid "黑塔的办公室" -msgstr "办公室" - -# 特殊点 - 空间站黑塔 - 收容舱段 -msgid "中庭" -msgstr "一楼" - -msgid "毁灭之蕾" -msgstr "毁灭" - -# 特殊点 - 空间站黑塔 - 支援舱段 -msgid "存护之蕾" -msgstr "存护" - -# 特殊点 - 雅利洛 - 行政区 -msgid "售货机1" -msgstr "售货机" - -msgid "售货机2" -msgstr "售货机" - -msgid "售货机3" -msgstr "售货机" - -msgid "花店" -msgstr "" - -msgid "克里珀堡1" -msgstr "克里珀堡" - -msgid "克里珀堡2" -msgstr "克里珀堡" - -msgid "歌德宾馆入口" -msgstr "歌德宾馆" - -# 特殊点 - 雅利洛 - 城郊雪原 -msgid "回忆之蕾" -msgstr "回忆" - -# 特殊点 -雅利洛 - 边缘通路 -msgid "歌德旧宅" -msgstr "歌德" - -# 特殊点 - 雅利洛 - 残响回廊 -msgid "筑城领域" -msgstr "筑城" - -msgid "作战指挥室" -msgstr "作战" - -# 特殊点 - 雅利洛 - 永冬岭 -msgid "睿治之径" -msgstr "治之径" - -# 特殊点 - 雅利洛 - 大矿区 -msgid "俯瞰点" -msgstr "点" - -# 特殊点 - 雅利洛 - 铆钉镇 -msgid "巽风之形" -msgstr "风之形" - -# 特殊点 - 雅利洛 - 机械聚落 -msgid "同谐之蕾" -msgstr "同谐" - -# 特殊点 - 仙舟罗浮 - 廻星港 -msgid "植船区萌甲" -msgstr "萌甲" - -msgid "植船区繁生" -msgstr "繁生" - -# 特殊点 - 仙舟罗浮 - 工造司 -msgid "镕金坊通道" -msgstr "金坊" - -# 特殊点 - 仙舟罗浮 - 丹鼎司 -msgid "观颐台" -msgstr "观" - -# 特殊点 - 仙舟罗浮 - 鳞渊境 -msgid "宫墟深处" -msgstr "深处" - -msgid "古海宫墟" -msgstr "古海" - -msgid "显龙大雩殿" -msgstr "显龙" - -msgid "孽兽之形" -msgstr "兽之形" - diff --git a/data/locales/ocr/en.po b/data/locales/ocr/en.po index 09d669c6..77968778 100644 --- a/data/locales/ocr/en.po +++ b/data/locales/ocr/en.po @@ -3,31 +3,111 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +# Honkai: Star Rail Auto Proxy UI +msgid "设置" +msgstr "Settings" + +msgid "锄大地" +msgstr "Patrol" + +msgid "校准" +msgstr "Calibrate" + +msgid "锄地路线绘制" +msgstr "Patrol Route" + +msgid "锄地路线白名单" +msgstr "Patrol Whitelist" + +# Patrol Part +msgid "锄地路线绘制" +msgstr "Patrol Route" + +msgid "路线白名单" +msgstr "Whitelist" + +msgid "无" +msgstr "None" + +msgid "开始" +msgstr "Start" + +msgid "F9 暂停" +msgstr "F9 Pause" + +msgid "F9 继续" +msgstr "F9 Resume" + +msgid "F10 结束" +msgstr "F10 Stop" + +msgid "结束后关机" +msgstr "Shutdown after Stop" + +msgid "未开始" +msgstr "Waiting" + +msgid "运行中" +msgstr "Running" + +msgid "暂停" +msgstr "Pause" + +msgid "请先结束其他运行中的功能 再启动" +msgstr "Stop the running function before another" + +# Settings Part +msgid "区服" +msgstr "Game Server" + +msgid "疾跑设置" +msgstr "Sprint" + +msgid "语言" +msgstr "Language" + +msgid "保存" +msgstr "Save" + +msgid "不启用" +msgstr "Off" + +msgid "通过按钮切换" +msgstr "Click to Switch" + +msgid "长按进入疾跑状态" +msgstr "Hold to Sprint" + + +# Game Part +msgid "崩坏:星穹铁道" +msgstr "Honkai: Star Rail" + # Planet msgid "空间站黑塔" -msgstr "Herta" +msgstr "Herta Space Station" msgid "雅利洛" -msgstr "Jarilo" +msgstr "Jarilo-VI" msgid "仙舟罗浮" -msgstr "Xianzhou" +msgstr "The Xianzhou Luofu" # Region msgid "观景车厢" msgstr "Parlor Car" msgid "主控舱段" -msgstr "Master Control Zone" +msgstr "Master Control" msgid "基座舱段" -msgstr "Base Zone" +msgstr "Base" msgid "收容舱段" -msgstr "Storage Zone" +msgstr "Storage" msgid "支援舱段" -msgstr "Supply Zone" +msgstr "Supply" msgid "行政区" msgstr "Administrative District" @@ -44,6 +124,9 @@ msgstr "Silvermane Guard Restricted Zone" msgid "残响回廊" msgstr "Corridor of Fading Echoes" +msgid "永冬岭" +msgstr "Everwinter Hill" + msgid "造物之柱" msgstr "Pillars of Creation" @@ -78,13 +161,13 @@ msgid "金人巷" msgstr "Aurum Alley" msgid "太卜司" -msgstr "Divination Commission" +msgstr "Divination" msgid "工造司" -msgstr "Artisanship Commission" +msgstr "Artisanship" msgid "丹鼎司" -msgstr "Alchemy Commission" +msgstr "Alchemy" msgid "鳞渊境" msgstr "Scalegorge Waterscape" @@ -148,17 +231,460 @@ msgid "月台" msgstr "Railway Platform" msgid "电力室" -msgstr "ectrical" +msgstr "Electrical Room" msgid "存护之蕾" -msgstr "Bud" +msgstr "Bud of Preservation" msgid "毁灭的开端" -msgstr "Beginning" +msgstr "Destruction's Beginning" + +# Interact +msgid "配控装置" +msgstr "Control Device" + +# Special Point - Jarilo-VI - Administrative District +msgid "黄金歌剧院" +msgstr "Golden Theater" + +msgid "中央广场" +msgstr "Central Plaza" + +msgid "歌德宾馆" +msgstr "Goethe Hotel" + +msgid "历史文化博物馆" +msgstr "History and Culture Museum" + +msgid "售货机1" +msgstr "Vending Machine" + +msgid "书商" +msgstr "Book Merchant" + +msgid "卖报人" +msgstr "Newspaper Seller" + +msgid "行政区商店" +msgstr "Administrative District Shop" + +msgid "售货机2" +msgstr "Vending Machine" + +msgid "花店长夏" +msgstr "Eversummer Florist" + +msgid "克里珀堡1" +msgstr "Qlipoth Fort" + +msgid "克里珀堡2" +msgstr "Qlipoth Fort" + +msgid "机械屋永动" +msgstr "Neverwinter Workshop" + +msgid "歌德宾馆入口" +msgstr "Goethe Hotel" + +msgid "售货机3" +msgstr "Vending Machine" + +# Special Point - Jarilo-VI - Outlying Snow Plains +msgid "长坡" +msgstr "Long Slope" + +msgid "着陆点" +msgstr "Landing Point" + +msgid "巡猎之蕾" +msgstr "Bud of The Hunt" + +msgid "回忆之蕾" +msgstr "Bud of Memories" + +msgid "玲可" +msgstr "Lynx" + +# Special Point - Jarilo-VI - Backwater Pass +msgid "候车广场" +msgstr "Transport Hub" + +msgid "休闲广场" +msgstr "Leisure Plaza" + +msgid "歌德旧宅" +msgstr "Goethe Mansion" + +msgid "幻光之形" +msgstr "Shape of Mirage" + +msgid "丰饶之蕾" +msgstr "Bud of Abundance" + +msgid "以太之蕾" +msgstr "Bud of Aether" + +# Special Point - Jarilo-VI - Silvermane Guard Restricted Zone +msgid "禁区岗哨" +msgstr "Outpost" + +msgid "禁区前线" +msgstr "Frontline" + +msgid "能源枢纽" +msgstr "Energy Hub" + +msgid "炎华之形" +msgstr "Shape of Blaze" + +msgid "迅拳之径" +msgstr "Path of Jabbing Punch" + +msgid "以眼还眼" +msgstr "An Eye for an Eye" + +msgid "冬兵进行曲" +msgstr "Winter Soldiers' March" + +# Special Point - Jarilo-VI - Corridor of Fading Echoes +msgid "筑城领域" +msgstr "Fortified Zone" + +msgid "污染广场" +msgstr "Contaminated Plaza" + +msgid "作战指挥室" +msgstr "Command Center" + +msgid "古战场前线" +msgstr "Ancient Battlefield: Frontline" + +msgid "鸣雷之形" +msgstr "Shape of Fulmination" + +msgid "霜晶之形" +msgstr "Shape of Rime" + +msgid "漂泊之径" +msgstr "Path of Drifting" + +# Special Point - Jarilo-VI - Everwinter Hill +msgid "古战场" +msgstr "Ancient Battlefield" + +msgid "造物平台" +msgstr "Deck of Creation" + +msgid "睿治之径" +msgstr "Path of Providence" + +msgid "寒潮的落幕" +msgstr "End of the Eternal Freeze" + +# Special Point - Jarilo-VI - Pillars of Creation +msgid "造物之柱入口" +msgstr "Pillars of Creation: Entrance" + +msgid "造物之柱施工场" +msgstr "Pillars of Creation: Construction Site" + +# Special Point - Jarilo-VI - Old Weapon Testing Ground +msgid "决胜庆典中心" +msgstr "Victory Celebration Center" + +msgid "以太战线终端" +msgstr "Aetherium Wars Terminal" + +# Special Point - Jarilo-VI - Boulder Town +msgid "歌德大饭店" +msgstr "Goethe Grand Hotel" + +msgid "搏击俱乐部" +msgstr "Fight Club" + +msgid "娜塔莎的诊所" +msgstr "Natasha's Clinic" + +msgid "磐岩镇超级联赛" +msgstr "Boulder Town Super League" + +msgid "地底商店" +msgstr "Underground Shop" + +msgid "小吃摊" +msgstr "Food Stall" + +msgid "娜塔莎的诊所入口" +msgstr "Natasha's Clinic" + +# Special Point - Jarilo-VI - Great Mine +msgid "入口" +msgstr "Entrance" + +msgid "流浪者避难所" +msgstr "Vagrant Shelter" + +msgid "俯瞰点" +msgstr "Overlook" + +msgid "主矿道" +msgstr "Main Mine Shaft" + +msgid "锋芒之形" +msgstr "Shape of Spike" + +msgid "燔灼之形" +msgstr "Shape of Scorch" + +msgid "虚无之蕾" +msgstr "Bud of Nihility" + +msgid "藏珍之蕾" +msgstr "Bud of Treasures" + +# Special Point - Jarilo-VI - Rivet Town +msgid "孤儿院" +msgstr "Orphanage" + +msgid "废弃市集" +msgstr "Abandoned Market" + +msgid "巽风之形" +msgstr "Shape of Gust" + +msgid "智识之蕾" +msgstr "Bud of Erudition" + +# Special Point - Jarilo-VI - Robot Settlement +msgid "流浪者营地" +msgstr "Vagrant Camp" + +msgid "史瓦罗驻地" +msgstr "Svarog's Base" + +msgid "能源转换设施" +msgstr "Energy Conversion Station" + +msgid "同谐之蕾" +msgstr "Bud of Harmony" + +# Special Point - The Xianzhou Luofu - Central Starskiff Haven +msgid "星槎码头" +msgstr "Starskiff Jetty" + +msgid "坤舆台" +msgstr "Earthrise Agora" + +msgid "宣夜大道" +msgstr "Starwatcher Avenue" + +msgid "天空之眼" +msgstr "Eye of the Cosmos" + +msgid "杂货铺老板" +msgstr "Grocery Store Owner" + +msgid "不夜侯" +msgstr "The Sleepless Earl" + +msgid "赎珠阁" +msgstr "Jeweler's Pagoda" + +msgid "售货机4" +msgstr "Vending Machine" + +msgid "司辰宫" +msgstr "Palace of Astrum" + +# Special Point - The Xianzhou Luofu - Central Starskiff Haven +msgid "流云渡货道" +msgstr "Cloudford: Cargo Lane" + +msgid "积玉坊" +msgstr "Trove of Verdure" + +msgid "积玉坊南侧" +msgstr "Trove of Verdure: South Wing" + +msgid "流云渡乘槎处" +msgstr "Cloudford: Skiff Boarding Area" + +msgid "冰棱之形" +msgstr "Shape of Icicle" + +msgid "圣颂之径" +msgstr "Path of Holy Hymn" + +msgid "过期邮包收购处" +msgstr "Procurement Point for Expired Parcels" + +# Special Point - The Xianzhou Luofu - Stargazer Navalia +msgid "飞星小筑" +msgstr "Astral Cottage" + +msgid "植船区萌甲" +msgstr "Ship Nursery - The Budding" + +msgid "植船区繁生" +msgstr "Ship Nursery - The Burgeoning" + +msgid "泊航区" +msgstr "The Mooring" + +msgid "震厄之形" +msgstr "Shape of Doom" + +msgid "野焰之径" +msgstr "Path of Conflagration" + +# Special Point - The Xianzhou Luofu - Exalting Sanctum +msgid "若木亭" +msgstr "Synwood Pavilion" + +msgid "悠暇庭" +msgstr "Court of Tranquility" + +msgid "神策府" +msgstr "Seat of Divine Foresight" + +msgid "金人巷1" +msgstr "Aurum Alley" + +msgid "金人巷2" +msgstr "Aurum Alley" + +msgid "杂货小摊" +msgstr "Grocery Stand" + +msgid "宝饵堂" +msgstr "NutriTreasures" + +msgid "三余书肆" +msgstr "Spare Time Book Shop" + +msgid "地衡司公廨" +msgstr "Realm-Keeping Commission Chancery" + +# Special Point - The Xianzhou Luofu - Aurum Alley +msgid "乾坤街" +msgstr "Cosmos Street" + +msgid "金人巷夜市" +msgstr "Aurum Alley Night Market" + +msgid "金人巷码头" +msgstr "Aurum Alley Dock" + +msgid "长乐天1" +msgstr "Exalting Sanctum" + +msgid "长乐天2" +msgstr "Exalting Sanctum" + +msgid "寿考堂" +msgstr "Longevity Hall" + +msgid "尚滋味" +msgstr "Spices Supreme" + +msgid "高阿姨的小吃摊" +msgstr "Tall Auntie's Food Stall" + +msgid "陈机铺" +msgstr "Oldies Depot" + +msgid "杜氏茶庄" +msgstr "Du's Teahouse" + +msgid "美馔阁" +msgstr "Delicacy Pavilion" + +msgid "霍三哥的大衣内侧" +msgstr "The Insides of Mr.Huo's Coat" + +# Special Point - The Xianzhou Luofu - Aurum Alley +msgid "界寰阵" +msgstr "Spatial Terminal" + +msgid "太衍穷观阵" +msgstr "Matrix of Prescience Ultima" + +msgid "授事厅" +msgstr "Conclave Hall" + +msgid "祥台" +msgstr "Fortuna Augurstead" + +# Special Point - The Xianzhou Luofu - Artisanship Commission +msgid "格物院通道" +msgstr "Passage to the Sapientia Academe" + +msgid "镕金坊通道" +msgstr "Passage to the Finery Foundry" + +msgid "玄机坪" +msgstr "Arcane Moorage" + +msgid "造化洪炉" +msgstr "Creation Furnace" + +msgid "偃偶之形" +msgstr "Shape of Puppetry" + +# Interact +msgid "入画" +msgstr "Teleport" + +# Special Point - The Xianzhou Luofu - Alchemy Commission +msgid "太真丹室" +msgstr "Aureate Elixir Furance" + +msgid "观颐台" +msgstr "Elixir Research Terrace" + +msgid "行医市集" +msgstr "Healer's Market" + +msgid "岐黄署" +msgstr "Medicine Bureau" + +msgid "天人之形" +msgstr "Shape of Celestial" + +msgid "药使之径" +msgstr "Path of Elixir Seekers" + +msgid "祈龙坛" +msgstr "Dragonprayer Terrace" + +msgid "蜃楼遁影" +msgstr "Wraiths of Mirage" + +msgid "永仁的小药摊" +msgstr "Yongren's Medicine Stand" + +msgid "汵汵的药材摊" +msgstr "Lingling's Medicine Stand" + +# Special Point - The Xianzhou Luofu - Scalegorge Waterscape +msgid "宫墟深处" +msgstr "Palace Ruin Depths" + +msgid "古海宫墟" +msgstr "Ancient Sea Palace Ruins" + +msgid "显龙大雩殿" +msgstr "Draggonvista Rain Hall" + +msgid "孽兽之形" +msgstr "Shape of Abomination" + +msgid "不死的神实" +msgstr "Divine Seed" # Large Map Btn msgid "星轨航图" -msgstr "Rail Map" +msgstr "Star Rail Map" msgid "传送" msgstr "Teleport" @@ -170,5 +696,4 @@ msgid "1层" msgstr "F1" msgid "2层" -msgstr "F2" - +msgstr "F2" \ No newline at end of file diff --git a/data/locales/ui/cn.po b/data/locales/ui/cn.po index d72e4c48..8cd3855b 100644 --- a/data/locales/ui/cn.po +++ b/data/locales/ui/cn.po @@ -2,3 +2,9 @@ msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" + +msgid "设置" +msgstr "设置/Settings" + +msgid "语言" +msgstr "语言/Language" diff --git a/data/locales/ui/en.po b/data/locales/ui/en.po index bd4a3ab3..7c67aecb 100644 --- a/data/locales/ui/en.po +++ b/data/locales/ui/en.po @@ -3,6 +3,83 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +# Honkai: Star Rail Auto Proxy UI +msgid "设置" +msgstr "Settings" + +msgid "锄大地" +msgstr "Patrol" + +msgid "校准" +msgstr "Calibrate" + +msgid "锄地路线绘制" +msgstr "Patrol Route" + +msgid "锄地路线白名单" +msgstr "Patrol Whitelist" + +# Patrol Part +msgid "锄地路线绘制" +msgstr "Patrol Route" + +msgid "路线白名单" +msgstr "Whitelist" + +msgid "无" +msgstr "None" + +msgid "开始" +msgstr "Start" + +msgid "F9 暂停" +msgstr "F9 Pause" + +msgid "F9 继续" +msgstr "Resume" + +msgid "F10 结束" +msgstr "Stop" + +msgid "结束后关机" +msgstr "Shutdown after Stop" + +msgid "未开始" +msgstr "Waiting" + +msgid "运行中" +msgstr "Running" + +msgid "暂停" +msgstr "Pause" + +msgid "请先结束其他运行中的功能 再启动" +msgstr "Stop the running function before another" + +# Settings Part +msgid "区服" +msgstr "Game Server" + +msgid "疾跑设置" +msgstr "Sprint" + +msgid "语言" +msgstr "Language" + +msgid "保存" +msgstr "Save" + +msgid "不启用" +msgstr "Off" + +msgid "通过按钮切换" +msgstr "Click to Switch" + +msgid "长按进入疾跑状态" +msgstr "Hold to Sprint" + + +# Game Part msgid "崩坏:星穹铁道" msgstr "Honkai: Star Rail" @@ -47,6 +124,9 @@ msgstr "Silvermane Guard Restricted Zone" msgid "残响回廊" msgstr "Corridor of Fading Echoes" +msgid "永冬岭" +msgstr "Everwinter Hill" + msgid "造物之柱" msgstr "Pillars of Creation" @@ -157,4 +237,463 @@ msgid "存护之蕾" msgstr "Bud of Preservation" msgid "毁灭的开端" -msgstr "Destruction's Beginning" \ No newline at end of file +msgstr "Destruction's Beginning" + +# Interact +msgid "配控装置" +msgstr "Control Device" + +# Special Point - Jarilo-VI - Administrative District +msgid "黄金歌剧院" +msgstr "Golden Theater" + +msgid "中央广场" +msgstr "Central Plaza" + +msgid "歌德宾馆" +msgstr "Goethe Hotel" + +msgid "历史文化博物馆" +msgstr "History and Culture Museum" + +msgid "售货机1" +msgstr "Vending Machine" + +msgid "书商" +msgstr "Book Merchant" + +msgid "卖报人" +msgstr "Newspaper Seller" + +msgid "行政区商店" +msgstr "Administrative District Shop" + +msgid "售货机2" +msgstr "Vending Machine" + +msgid "花店长夏" +msgstr "Eversummer Florist" + +msgid "克里珀堡1" +msgstr "Qlipoth Fort" + +msgid "克里珀堡2" +msgstr "Qlipoth Fort" + +msgid "机械屋永动" +msgstr "Neverwinter Workshop" + +msgid "歌德宾馆入口" +msgstr "Goethe Hotel" + +msgid "售货机3" +msgstr "Vending Machine" + +# Special Point - Jarilo-VI - Outlying Snow Plains +msgid "长坡" +msgstr "Long Slope" + +msgid "着陆点" +msgstr "Landing Point" + +msgid "巡猎之蕾" +msgstr "Bud of The Hunt" + +msgid "回忆之蕾" +msgstr "Bud of Memories" + +msgid "玲可" +msgstr "Lynx" + +# Special Point - Jarilo-VI - Backwater Pass +msgid "候车广场" +msgstr "Transport Hub" + +msgid "休闲广场" +msgstr "Leisure Plaza" + +msgid "歌德旧宅" +msgstr "Goethe Mansion" + +msgid "幻光之形" +msgstr "Shape of Mirage" + +msgid "丰饶之蕾" +msgstr "Bud of Abundance" + +msgid "以太之蕾" +msgstr "Bud of Aether" + +# Special Point - Jarilo-VI - Silvermane Guard Restricted Zone +msgid "禁区岗哨" +msgstr "Outpost" + +msgid "禁区前线" +msgstr "Frontline" + +msgid "能源枢纽" +msgstr "Energy Hub" + +msgid "炎华之形" +msgstr "Shape of Blaze" + +msgid "迅拳之径" +msgstr "Path of Jabbing Punch" + +msgid "以眼还眼" +msgstr "An Eye for an Eye" + +msgid "冬兵进行曲" +msgstr "Winter Soldiers' March" + +# Special Point - Jarilo-VI - Corridor of Fading Echoes +msgid "筑城领域" +msgstr "Fortified Zone" + +msgid "污染广场" +msgstr "Contaminated Plaza" + +msgid "作战指挥室" +msgstr "Command Center" + +msgid "古战场前线" +msgstr "Ancient Battlefield: Frontline" + +msgid "鸣雷之形" +msgstr "Shape of Fulmination" + +msgid "霜晶之形" +msgstr "Shape of Rime" + +msgid "漂泊之径" +msgstr "Path of Drifting" + +# Special Point - Jarilo-VI - Everwinter Hill +msgid "古战场" +msgstr "Ancient Battlefield" + +msgid "造物平台" +msgstr "Deck of Creation" + +msgid "睿治之径" +msgstr "Path of Providence" + +msgid "寒潮的落幕" +msgstr "End of the Eternal Freeze" + +# Special Point - Jarilo-VI - Pillars of Creation +msgid "造物之柱入口" +msgstr "Pillars of Creation: Entrance" + +msgid "造物之柱施工场" +msgstr "Pillars of Creation: Construction Site" + +# Special Point - Jarilo-VI - Old Weapon Testing Ground +msgid "决胜庆典中心" +msgstr "Victory Celebration Center" + +msgid "以太战线终端" +msgstr "Aetherium Wars Terminal" + +# Special Point - Jarilo-VI - Boulder Town +msgid "歌德大饭店" +msgstr "Goethe Grand Hotel" + +msgid "搏击俱乐部" +msgstr "Fight Club" + +msgid "娜塔莎的诊所" +msgstr "Natasha's Clinic" + +msgid "磐岩镇超级联赛" +msgstr "Boulder Town Super League" + +msgid "地底商店" +msgstr "Underground Shop" + +msgid "小吃摊" +msgstr "Food Stall" + +msgid "娜塔莎的诊所入口" +msgstr "Natasha's Clinic" + +# Special Point - Jarilo-VI - Great Mine +msgid "入口" +msgstr "Entrance" + +msgid "流浪者避难所" +msgstr "Vagrant Shelter" + +msgid "俯瞰点" +msgstr "Overlook" + +msgid "主矿道" +msgstr "Main Mine Shaft" + +msgid "锋芒之形" +msgstr "Shape of Spike" + +msgid "燔灼之形" +msgstr "Shape of Scorch" + +msgid "虚无之蕾" +msgstr "Bud of Nihility" + +msgid "藏珍之蕾" +msgstr "Bud of Treasures" + +# Special Point - Jarilo-VI - Rivet Town +msgid "孤儿院" +msgstr "Orphanage" + +msgid "废弃市集" +msgstr "Abandoned Market" + +msgid "巽风之形" +msgstr "Shape of Gust" + +msgid "智识之蕾" +msgstr "Bud of Erudition" + +# Special Point - Jarilo-VI - Robot Settlement +msgid "流浪者营地" +msgstr "Vagrant Camp" + +msgid "史瓦罗驻地" +msgstr "Svarog's Base" + +msgid "能源转换设施" +msgstr "Energy Conversion Station" + +msgid "同谐之蕾" +msgstr "Bud of Harmony" + +# Special Point - The Xianzhou Luofu - Central Starskiff Haven +msgid "星槎码头" +msgstr "Starskiff Jetty" + +msgid "坤舆台" +msgstr "Earthrise Agora" + +msgid "宣夜大道" +msgstr "Starwatcher Avenue" + +msgid "天空之眼" +msgstr "Eye of the Cosmos" + +msgid "杂货铺老板" +msgstr "Grocery Store Owner" + +msgid "不夜侯" +msgstr "The Sleepless Earl" + +msgid "赎珠阁" +msgstr "Jeweler's Pagoda" + +msgid "售货机4" +msgstr "Vending Machine" + +msgid "司辰宫" +msgstr "Palace of Astrum" + +# Special Point - The Xianzhou Luofu - Central Starskiff Haven +msgid "流云渡货道" +msgstr "Cloudford: Cargo Lane" + +msgid "积玉坊" +msgstr "Trove of Verdure" + +msgid "积玉坊南侧" +msgstr "Trove of Verdure: South Wing" + +msgid "流云渡乘槎处" +msgstr "Cloudford: Skiff Boarding Area" + +msgid "冰棱之形" +msgstr "Shape of Icicle" + +msgid "圣颂之径" +msgstr "Path of Holy Hymn" + +msgid "过期邮包收购处" +msgstr "Procurement Point for Expired Parcels" + +# Special Point - The Xianzhou Luofu - Stargazer Navalia +msgid "飞星小筑" +msgstr "Astral Cottage" + +msgid "植船区萌甲" +msgstr "Ship Nursery - The Budding" + +msgid "植船区繁生" +msgstr "Ship Nursery - The Burgeoning" + +msgid "泊航区" +msgstr "The Mooring" + +msgid "震厄之形" +msgstr "Shape of Doom" + +msgid "野焰之径" +msgstr "Path of Conflagration" + +# Special Point - The Xianzhou Luofu - Exalting Sanctum +msgid "若木亭" +msgstr "Synwood Pavilion" + +msgid "悠暇庭" +msgstr "Court of Tranquility" + +msgid "神策府" +msgstr "Seat of Divine Foresight" + +msgid "金人巷1" +msgstr "Aurum Alley" + +msgid "金人巷2" +msgstr "Aurum Alley" + +msgid "杂货小摊" +msgstr "Grocery Stand" + +msgid "宝饵堂" +msgstr "NutriTreasures" + +msgid "三余书肆" +msgstr "Spare Time Book Shop" + +msgid "地衡司公廨" +msgstr "Realm-Keeping Commission Chancery" + +# Special Point - The Xianzhou Luofu - Aurum Alley +msgid "乾坤街" +msgstr "Cosmos Street" + +msgid "金人巷夜市" +msgstr "Aurum Alley Night Market" + +msgid "金人巷码头" +msgstr "Aurum Alley Dock" + +msgid "长乐天1" +msgstr "Exalting Sanctum" + +msgid "长乐天2" +msgstr "Exalting Sanctum" + +msgid "寿考堂" +msgstr "Longevity Hall" + +msgid "尚滋味" +msgstr "Spices Supreme" + +msgid "高阿姨的小吃摊" +msgstr "Tall Auntie's Food Stall" + +msgid "陈机铺" +msgstr "Oldies Depot" + +msgid "杜氏茶庄" +msgstr "Du's Teahouse" + +msgid "美馔阁" +msgstr "Delicacy Pavilion" + +msgid "霍三哥的大衣内侧" +msgstr "The Insides of Mr.Huo's Coat" + +# Special Point - The Xianzhou Luofu - Aurum Alley +msgid "界寰阵" +msgstr "Spatial Terminal" + +msgid "太衍穷观阵" +msgstr "Matrix of Prescience Ultima" + +msgid "授事厅" +msgstr "Conclave Hall" + +msgid "祥台" +msgstr "Fortuna Augurstead" + +# Special Point - The Xianzhou Luofu - Artisanship Commission +msgid "格物院通道" +msgstr "Passage to the Sapientia Academe" + +msgid "镕金坊通道" +msgstr "Passage to the Finery Foundry" + +msgid "玄机坪" +msgstr "Arcane Moorage" + +msgid "造化洪炉" +msgstr "Creation Furnace" + +msgid "偃偶之形" +msgstr "Shape of Puppetry" + +# Interact +msgid "入画" +msgstr "Teleport" + +# Special Point - The Xianzhou Luofu - Alchemy Commission +msgid "太真丹室" +msgstr "Aureate Elixir Furance" + +msgid "观颐台" +msgstr "Elixir Research Terrace" + +msgid "行医市集" +msgstr "Healer's Market" + +msgid "岐黄署" +msgstr "Medicine Bureau" + +msgid "天人之形" +msgstr "Shape of Celestial" + +msgid "药使之径" +msgstr "Path of Elixir Seekers" + +msgid "祈龙坛" +msgstr "Dragonprayer Terrace" + +msgid "蜃楼遁影" +msgstr "Wraiths of Mirage" + +msgid "永仁的小药摊" +msgstr "Yongren's Medicine Stand" + +msgid "汵汵的药材摊" +msgstr "Lingling's Medicine Stand" + +# Special Point - The Xianzhou Luofu - Scalegorge Waterscape +msgid "宫墟深处" +msgstr "Palace Ruin Depths" + +msgid "古海宫墟" +msgstr "Ancient Sea Palace Ruins" + +msgid "显龙大雩殿" +msgstr "Draggonvista Rain Hall" + +msgid "孽兽之形" +msgstr "Shape of Abomination" + +msgid "不死的神实" +msgstr "Divine Seed" + +# Large Map Btn +msgid "星轨航图" +msgstr "Star Rail Map" + +msgid "传送" +msgstr "Teleport" + +msgid "-1层" +msgstr "B1" + +msgid "1层" +msgstr "F1" + +msgid "2层" +msgstr "F2" \ No newline at end of file diff --git a/src/basic/img/__init__.py b/src/basic/img/__init__.py index 2d3e595b..de6e07e3 100644 --- a/src/basic/img/__init__.py +++ b/src/basic/img/__init__.py @@ -3,7 +3,7 @@ class MatchResult: - def __init__(self, c, x, y, w, h, template_scale: float = 1): + def __init__(self, c, x, y, w, h, template_scale: float = 1, data: str = None): self.confidence = c self.x = int(x) self.y = int(y) @@ -12,6 +12,7 @@ def __init__(self, c, x, y, w, h, template_scale: float = 1): self.cx = int(self.x + self.w // 2) self.cy = int(self.y + self.h // 2) self.template_scale = template_scale + self.data: str = data def __str__(self): return '(%.2f, %d, %d, %d, %d, %.2f)' % (self.confidence, self.x, self.y, self.w, self.h, self.template_scale) diff --git a/src/basic/log_utils.py b/src/basic/log_utils.py index 377155b4..ce7ffb0b 100644 --- a/src/basic/log_utils.py +++ b/src/basic/log_utils.py @@ -8,20 +8,20 @@ def get_logger(): logger = logging.getLogger('StarRailAutoProxy') logger.handlers.clear() - logger.setLevel(logging.DEBUG) + logger.setLevel(logging.DEBUG if os_utils.is_debug() else logging.INFO) formatter = logging.Formatter('[%(asctime)s] [%(funcName)s %(lineno)d] [%(levelname)s]: %(message)s', '%H:%M:%S') log_file_path = os.path.join(os_utils.get_path_under_work_dir('.log'), 'log.txt') archive_handler = TimedRotatingFileHandler(log_file_path, when='midnight', interval=1, backupCount=3) - archive_handler.setLevel(logging.DEBUG) # 文件输出默认debug + archive_handler.setLevel(logging.DEBUG if os_utils.is_debug() else logging.INFO) # 文件输出默认debug archive_handler.setFormatter(formatter) logger.addHandler(archive_handler) - console_handler = logging.StreamHandler() - console_handler.setLevel(logging.DEBUG if os_utils.is_debug() else logging.INFO) # 前台日志默认info - console_handler.setFormatter(formatter) - logger.addHandler(console_handler) + # console_handler = logging.StreamHandler() + # console_handler.setLevel(logging.DEBUG if os_utils.is_debug() else logging.INFO) # 前台日志默认info + # console_handler.setFormatter(formatter) + # logger.addHandler(console_handler) return logger diff --git a/src/basic/str_utils.py b/src/basic/str_utils.py new file mode 100644 index 00000000..82806300 --- /dev/null +++ b/src/basic/str_utils.py @@ -0,0 +1,59 @@ +def find(source: str, target: str, ignore_case: bool = False) -> int: + """ + 字符串find的封装 在原目标串中招目标字符串 + :param source: 原字符串 + :param target: 目标字符串 + :param ignore_case: 是否忽略大小写 + :return: + """ + if source is None or target is None: + return -1 + if ignore_case: + return source.lower().find(target.lower()) + else: + return source.find(target) + + +def find_by_lcs(source: str, target: str, percent: float = 0.3, + ignore_case: bool = False) -> bool: + """ + 根据最长公共子序列长度和一定阈值 判断字符串是否有包含关系。 + 用于OCR结果和目标的匹配 + :param source: OCR目标 + :param target: OCR结果 + :param percent: 最长公共子序列长度 需要占 source长度 的百分比 + :param ignore_case: 是否忽略大小写 + :return: 是否包含 + """ + if source is None or target is None: + return False + source_usage = source.lower() if ignore_case else source + target_usage = target.lower() if ignore_case else target + + common_length = longest_common_subsequence_length(source_usage, target_usage) + + return common_length >= len(source) * percent + + +def longest_common_subsequence_length(str1: str, str2: str): + """ + 找两个字符串的最长公共子序列长度 + :param str1: + :param str2: + :return: 长度 + """ + m = len(str1) + n = len(str2) + + # 创建一个二维数组用于存储中间结果 + dp = [[0] * (n + 1) for _ in range(m + 1)] + + # 动态规划求解 + for i in range(1, m + 1): + for j in range(1, n + 1): + if str1[i - 1] == str2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + + return dp[m][n] diff --git a/src/gui/settings_view.py b/src/gui/settings_view.py index c9752ba2..e3b80862 100644 --- a/src/gui/settings_view.py +++ b/src/gui/settings_view.py @@ -26,7 +26,7 @@ def __init__(self, page: ft.Page, ctx: Context): self.run_mode_dropdown = ft.Dropdown( label=gt("疾跑设置", model='ui'), width=200, options=[ - ft.dropdown.Option(text=k, key=v) for k, v in game_config_const.RUN_MODE.items() + ft.dropdown.Option(text=gt(k, 'ui'), key=v) for k, v in game_config_const.RUN_MODE.items() ], on_change=self.on_run_mode_changed ) diff --git a/src/gui/sr_app_view.py b/src/gui/sr_app_view.py index d996fa29..f04c0dd9 100644 --- a/src/gui/sr_app_view.py +++ b/src/gui/sr_app_view.py @@ -17,7 +17,7 @@ def __init__(self, page: ft.Page, ctx: Context): self.page = page self.ctx = ctx - self.start_btn = ft.ElevatedButton(text=gt("F9 开始", model='ui'), on_click=self.start) + self.start_btn = ft.ElevatedButton(text=gt("开始", model='ui'), on_click=self.start) self.pause_btn = ft.ElevatedButton(text=gt("F9 暂停", model='ui'), on_click=self.pause, visible=False) self.resume_btn = ft.ElevatedButton(text=gt("F9 继续", model='ui'), on_click=self.resume, visible=False) self.stop_btn = ft.ElevatedButton(text=gt("F10 结束", model='ui'), on_click=self.stop, disabled=True) @@ -50,7 +50,7 @@ def __init__(self, page: ft.Page, ctx: Context): def start(self, e): if self.ctx.running != 0: - snack_bar.show_message('请先结束其他运行中的功能 再启动', self.page) + snack_bar.show_message(gt('请先结束其他运行中的功能 再启动', 'ui'), self.page) return self.running_status.value = gt('运行中', model='ui') diff --git a/src/gui/world_patrol_view.py b/src/gui/world_patrol_view.py index bcff8a15..692e53dd 100644 --- a/src/gui/world_patrol_view.py +++ b/src/gui/world_patrol_view.py @@ -2,6 +2,7 @@ import flet as ft +from basic.i18_utils import gt from gui.sr_app_view import SrAppView from sr.app import world_patrol from sr.app.world_patrol import WorldPatrolWhitelist @@ -13,9 +14,9 @@ class WorldPatrolView(SrAppView): def __init__(self, page: ft.Page, ctx: Context): super().__init__(page, ctx) - settings_text = ft.Text(value='设置') + settings_text = ft.Text(value=gt('设置', 'ui')) - self.whitelist_dropdown = ft.Dropdown(label='路线白名单', width=200, height=70) + self.whitelist_dropdown = ft.Dropdown(label=gt('路线白名单', 'ui'), width=200, height=70) self.existed_whitelist_id_list: List[str] = [] self.load_whitelist_id_list() @@ -27,7 +28,7 @@ def __init__(self, page: ft.Page, ctx: Context): def load_whitelist_id_list(self): self.existed_whitelist_id_list = world_patrol.load_all_whitelist_id() options = [] - options.append(ft.dropdown.Option(text='无', key='none')) + options.append(ft.dropdown.Option(text=gt('无', 'ui'), key='none')) for i in range(len(self.existed_whitelist_id_list)): opt = ft.dropdown.Option(text=self.existed_whitelist_id_list[i], key=self.existed_whitelist_id_list[i]) options.append(opt) diff --git a/src/sr/app/world_patrol.py b/src/sr/app/world_patrol.py index 2ad01f11..0be1c614 100644 --- a/src/sr/app/world_patrol.py +++ b/src/sr/app/world_patrol.py @@ -212,7 +212,7 @@ def run_one_route(self, route_id: WorldPatrolRouteId) -> bool: :return: 是否执行成功当前线路 """ route: WorldPatrolRoute = WorldPatrolRoute(route_id) - log.info('准备执行线路 %s %s %s %s', route_id, route.tp.planet.cn, route.tp.region.cn, route.tp.cn) + log.info('准备执行线路 %s', route_id.display_name) if self.record is not None and route_id.unique_id in self.record.finished: log.info('线路 %s 之前已执行 跳过', route_id.display_name) diff --git a/src/sr/config/game_config.py b/src/sr/config/game_config.py index f7ba8a15..ce8a7d42 100644 --- a/src/sr/config/game_config.py +++ b/src/sr/config/game_config.py @@ -1,5 +1,5 @@ from sr.config import ConfigHolder -from sr.const import game_config_const +from sr.const import game_config_const, ocr_const class MiniMapPos: @@ -54,6 +54,18 @@ def set_lang(self, value: str): self.lang = value self.update('lang', value) + @property + def planet_lcs_percent(self): + return ocr_const.PLANET_LCS_PERCENT[self.lang] + + @property + def region_lcs_percent(self): + return ocr_const.REGION_LCS_PERCENT[self.lang] + + @property + def special_point_lcs_percent(self): + return ocr_const.SPECIAL_POINT_LCS_PERCENT[self.lang] + _gc = None diff --git a/src/sr/const/ocr_const.py b/src/sr/const/ocr_const.py new file mode 100644 index 00000000..55eec42f --- /dev/null +++ b/src/sr/const/ocr_const.py @@ -0,0 +1,16 @@ +from sr.const import game_config_const + +PLANET_LCS_PERCENT = { + game_config_const.LANG_CN: 0.55, + game_config_const.LANG_EN: 0.55 +} + +REGION_LCS_PERCENT = { + game_config_const.LANG_CN: 0.55, + game_config_const.LANG_EN: 0.7 +} + +SPECIAL_POINT_LCS_PERCENT = { + game_config_const.LANG_CN: 0.55, + game_config_const.LANG_EN: 0.55 +} \ No newline at end of file diff --git a/src/sr/context.py b/src/sr/context.py index de9831a0..1b93df53 100644 --- a/src/sr/context.py +++ b/src/sr/context.py @@ -13,7 +13,7 @@ from sr.image import ImageMatcher from sr.image.en_ocr_matcher import EnOcrMatcher from sr.image.ocr_matcher import OcrMatcher -from sr.image.cnocr_matcher import CnOcrMatcher +from sr.image.cn_ocr_matcher import CnOcrMatcher from sr.image.cv2_matcher import CvImageMatcher from sr.image.image_holder import ImageHolder from sr.image.sceenshot import fill_uid_black diff --git a/src/sr/control/__init__.py b/src/sr/control/__init__.py index b1946a21..3f7cf302 100644 --- a/src/sr/control/__init__.py +++ b/src/sr/control/__init__.py @@ -1,6 +1,7 @@ from cv2.typing import MatLike import basic.cal_utils +from basic.i18_utils import gt from basic.img import cv2_utils from basic.log_utils import log from sr.image.ocr_matcher import OcrMatcher @@ -25,7 +26,8 @@ def open_map(self) -> bool: pass def click_ocr(self, screen: MatLike, word: str, threshold: float = 0.5, rect: tuple = None, click_offset: tuple = None, - press_time: float = 0, same_word: bool = False, + press_time: float = 0, same_word: bool = False, ignore_case: bool = True, lcs_percent: float = -1, + merge_line_distance: float = -1 ) -> bool: """ 在屏幕中点击关键词所在位置 多个关键词时随机点击一个 @@ -36,13 +38,18 @@ def click_ocr(self, screen: MatLike, word: str, threshold: float = 0.5, rect: tu :param click_offset: 在匹配结果后 偏移多少进行点击 :param press_time: 持续按的时间 :param same_word: 要求整个词一样 + :param ignore_case: 忽略大小写 + :param lcs_percent: 最长公共子序列长度百分比 -1代表不使用 + :param merge_line_distance: 多少行距内合并OCR结果 -1为不合并 :return: """ if rect is not None: x1, y1, x2, y2 = rect # cv2_utils.show_image(screen[y1:y2, x1:x2], win_name='ocr_part') km = self.ocr.match_words(screen if rect is None else screen[y1:y2, x1:x2], - words=[word], threshold=threshold, same_word=same_word) + words=[word], threshold=threshold, same_word=same_word, + ignore_case=ignore_case, lcs_percent=lcs_percent, + merge_line_distance=merge_line_distance) if len(km) == 0: return False for v in km.values(): @@ -53,7 +60,7 @@ def click_ocr(self, screen: MatLike, word: str, threshold: float = 0.5, rect: tu if click_offset is not None: x += click_offset[0] y += click_offset[1] - log.debug('OCR识别 %s 成功 准备点击 (%d, %d)', word, x, y) + log.debug('OCR识别 %s 成功 准备点击 (%d, %d)', gt(word, 'ui'), x, y) return self.click((x, y), press_time=press_time) def click(self, pos: tuple = None, press_time: float = 0) -> bool: diff --git a/src/sr/image/cnocr_matcher.py b/src/sr/image/cn_ocr_matcher.py similarity index 58% rename from src/sr/image/cnocr_matcher.py rename to src/sr/image/cn_ocr_matcher.py index f56de6ae..f862508d 100644 --- a/src/sr/image/cnocr_matcher.py +++ b/src/sr/image/cn_ocr_matcher.py @@ -5,7 +5,7 @@ from basic.i18_utils import gt from basic.img import MatchResultList, MatchResult from basic.log_utils import log -from sr.image.ocr_matcher import OcrMatcher +from sr.image.ocr_matcher import OcrMatcher, merge_ocr_result_to_single_line class CnOcrMatcher(OcrMatcher): @@ -22,16 +22,30 @@ def __init__(self): except Exception: log.error(gt('OCR模型加载出错'), exc_info=True) - def ocr_for_single_line(self, image: MatLike, threshold: float = None, lang: str = None) -> str: - result = self.ocr.ocr_for_single_line(image) - log.debug('OCR结果 %s', result.keys()) - return result['text'] if threshold is None or result['score'] >= threshold else None + def ocr_for_single_line(self, image: MatLike, threshold: float = None, strict_one_line: bool = True) -> str: + """ + 单行文本识别 手动合成一行 按匹配结果从左到右 从上到下 + 理论中文情况不会出现过长分行的 这里只是为了兼容英语的情况 + :param image: 图片 + :param threshold: 阈值 + :param strict_one_line: 严格判断只有单行文本 False时合并成一行 + :return: + """ + if strict_one_line: + result = self.ocr.ocr_for_single_line(image) + log.debug('OCR结果 %s', result.keys()) + return result['text'] if threshold is None or result['score'] >= threshold else None + else: + ocr_map: dict = self.run_ocr(image, threshold) + return merge_ocr_result_to_single_line(ocr_map, join_space=False) - def run_ocr(self, image: MatLike, threshold: float = None, lang: str = None) -> dict: + def run_ocr(self, image: MatLike, threshold: float = None, + merge_line_distance: float = -1) -> dict: """ 对图片进行OCR 返回所有匹配结果 :param image: 图片 :param threshold: 匹配阈值 + :param merge_line_distance: 多少行距内合并结果 -1为不合并 理论中文情况不会出现过长分行的 这里只是为了兼容英语的情况 :return: {key_word: []} """ scan_result: list = self.ocr.ocr(image) @@ -45,6 +59,7 @@ def run_ocr(self, image: MatLike, threshold: float = None, lang: str = None) -> r['position'][0][0], r['position'][0][1], r['position'][2][0] - r['position'][0][0], - r['position'][2][1] - r['position'][0][1])) + r['position'][2][1] - r['position'][0][1], + data=r['text'])) log.debug('OCR结果 %s', result_map.keys()) return result_map diff --git a/src/sr/image/en_ocr_matcher.py b/src/sr/image/en_ocr_matcher.py index b662650b..5833a0a9 100644 --- a/src/sr/image/en_ocr_matcher.py +++ b/src/sr/image/en_ocr_matcher.py @@ -4,7 +4,7 @@ from basic import os_utils from basic.img import MatchResultList, MatchResult from basic.log_utils import log -from sr.image.ocr_matcher import OcrMatcher +from sr.image.ocr_matcher import OcrMatcher, merge_ocr_result_to_single_line, merge_ocr_result_to_multiple_line class EnOcrMatcher(OcrMatcher): @@ -22,24 +22,29 @@ def __init__(self): except Exception: log.error('OCR模型加载出错', exc_info=True) - def ocr_for_single_line(self, image: MatLike, threshold: float = None, lang: str = None, - strict_one_line: bool = True) -> str: + def ocr_for_single_line(self, image: MatLike, threshold: float = None, strict_one_line: bool = True) -> str: """ - Some - :param image: - :param threshold: - :param lang: + 单行文本识别 部分英语很长 会分成两行 手动合成一行 按匹配结果从左到右 从上到下 + :param image: 图片 + :param threshold: 阈值 + :param strict_one_line: 严格判断只有单行文本 False时合并成一行 :return: """ - result = self.ocr.ocr_for_single_line(image) - log.debug('OCR结果 %s', result.keys()) - return result['text'] if threshold is None or result['score'] >= threshold else None + if strict_one_line: + result = self.ocr.ocr_for_single_line(image) + log.debug('OCR结果 %s', result.keys()) + return result['text'] if threshold is None or result['score'] >= threshold else None + else: + ocr_map: dict = self.run_ocr(image, threshold) + return merge_ocr_result_to_single_line(ocr_map, join_space=True) - def run_ocr(self, image: MatLike, threshold: float = None, lang: str = None) -> dict: + def run_ocr(self, image: MatLike, threshold: float = None, + merge_line_distance: float = -1) -> dict: """ 对图片进行OCR 返回所有匹配结果 :param image: 图片 :param threshold: 匹配阈值 + :param merge_line_distance: 多少行距内合并结果 -1为不合并 :return: {key_word: []} """ scan_result: list = self.ocr.ocr(image) @@ -53,6 +58,9 @@ def run_ocr(self, image: MatLike, threshold: float = None, lang: str = None) -> r['position'][0][0], r['position'][0][1], r['position'][2][0] - r['position'][0][0], - r['position'][2][1] - r['position'][0][1])) + r['position'][2][1] - r['position'][0][1], + data=r['text'])) + if merge_line_distance != -1: + result_map = merge_ocr_result_to_multiple_line(result_map, join_space=True, merge_line_distance=merge_line_distance) log.debug('OCR结果 %s', result_map.keys()) return result_map \ No newline at end of file diff --git a/src/sr/image/ocr_matcher.py b/src/sr/image/ocr_matcher.py index 20059158..a8a2a89f 100644 --- a/src/sr/image/ocr_matcher.py +++ b/src/sr/image/ocr_matcher.py @@ -2,7 +2,9 @@ from cv2.typing import MatLike +from basic import str_utils from basic.i18_utils import gt +from basic.img import MatchResult, MatchResultList class OcrMatcher: @@ -17,35 +19,138 @@ def ocr_for_single_line(self, image: MatLike, threshold: float = None, strict_on """ pass - def run_ocr(self, image: MatLike, threshold: float = None) -> dict: + def run_ocr(self, image: MatLike, threshold: float = None, merge_line_distance: float = -1) -> dict: """ 对图片进行OCR 返回所有匹配结果 :param image: 图片 :param threshold: 匹配阈值 + :param merge_line_distance: 多少行距内合并结果 -1为不合并 :return: {key_word: []} """ pass - def match_words(self, image: MatLike, words: List[str], threshold: float = None, same_word: bool = False) -> dict: + def match_words(self, image: MatLike, words: List[str], threshold: float = None, + same_word: bool = False, + ignore_case: bool = True, lcs_percent: float = -1, merge_line_distance: float = -1) -> dict: """ 在图片中查找关键词 返回所有词对应的位置 :param image: 图片 :param words: 关键词 :param threshold: 匹配阈值 :param same_word: 要求整个词一样 + :param ignore_case: 忽略大小写 + :param lcs_percent: 最长公共子序列长度百分比 -1代表不使用 same_word=True时不生效 + :param merge_line_distance: 多少行距内合并结果 -1为不合并 :return: {key_word: []} """ - all_match_result: dict = self.run_ocr(image, threshold) + all_match_result: dict = self.run_ocr(image, threshold, merge_line_distance=merge_line_distance) match_key = set() for k in all_match_result.keys(): for w in words: - ocr_world = gt(w, 'ocr') - if same_word and k == ocr_world: - match_key.add(k) - elif not same_word and k.find(ocr_world) != -1: - match_key.add(k) - break + ocr_result: str = k + ocr_target = gt(w, 'ocr') + if ignore_case: + ocr_result = ocr_result.lower() + ocr_target = ocr_target.lower() + + if same_word: + if ocr_result == ocr_target: + match_key.add(k) + else: + if lcs_percent == -1: + if ocr_result.find(ocr_target) != -1: + match_key.add(k) + else: + if str_utils.find_by_lcs(ocr_target, ocr_result, percent=lcs_percent): + match_key.add(k) return {key: all_match_result[key] for key in match_key if key in all_match_result} +def merge_ocr_result_to_single_line(ocr_map, join_space: bool = True) -> str: + """ + 将OCR结果合并成一行 用于过长的文体产生换行 + :param ocr_map: run_ocr的结果 + :param join_space: 连接时是否加入空格 + :return: + """ + lines = [] + for text, result_list in ocr_map.items(): + for result in result_list: + in_line: int = -1 + for line_idx in range(len(lines)): + for line_item in lines[line_idx]: + if abs(line_item.cy - result.cy) <= 5: + in_line = line_idx + break + if in_line != -1: + break + + if in_line == -1: + lines.append([result]) + else: + lines[in_line].append(result) + + result_str: str = None + for line in lines: + sorted_line = sorted(line, key=lambda x: x.cx) + for result_item in sorted_line: + if result_str is None: + result_str = result_item.data + else: + result_str += (' ' if join_space else '') + result_item.data + + return result_str + + +def merge_ocr_result_to_multiple_line(ocr_map, join_space: bool = True, merge_line_distance: float = 40) -> dict[str, MatchResultList]: + """ + 将OCR结果合并成多行 用于过长的文体产生换行 + :param ocr_map: run_ocr的结果 + :param join_space: 连接时是否加入空格 + :param merge_line_distance: 多少行距内合并结果 + :return: + """ + lines = [] + for text, result_list in ocr_map.items(): + for result in result_list: + in_line: int = -1 + for line_idx in range(len(lines)): + for line_item in lines[line_idx]: + if abs(line_item.cy - result.cy) <= merge_line_distance: + in_line = line_idx + break + if in_line != -1: + break + + if in_line == -1: + lines.append([result]) + else: + lines[in_line].append(result) + + merge_ocr_result_map: dict[str, MatchResultList] = {} + for line in lines: + line_ocr_map = {} + merge_result: MatchResult = MatchResult(1, 9999, 9999, 0, 0) + for ocr_result in line: + if ocr_result.data not in line_ocr_map: + line_ocr_map[ocr_result.data] = MatchResultList() + line_ocr_map[ocr_result.data].append(ocr_result) + + if ocr_result.x < merge_result.x: + merge_result.x = ocr_result.x + if ocr_result.y < merge_result.y: + merge_result.y = ocr_result.y + if ocr_result.x + ocr_result.w > merge_result.x + merge_result.w: + merge_result.w = ocr_result.x + ocr_result.w - merge_result.x + if ocr_result.y + ocr_result.h > merge_result.y + merge_result.h: + merge_result.h = ocr_result.y + ocr_result.h - merge_result.y + + merge_result.data = merge_ocr_result_to_single_line(line_ocr_map, join_space=join_space) + merge_result.cx = merge_result.x + merge_result.w // 2 + merge_result.cy = merge_result.y + merge_result.h // 2 + if merge_result.data not in merge_ocr_result_map: + merge_ocr_result_map[merge_result.data] = MatchResultList() + merge_ocr_result_map[merge_result.data].append(merge_result) + + return merge_ocr_result_map diff --git a/src/sr/image/sceenshot/large_map.py b/src/sr/image/sceenshot/large_map.py index 2da8624a..f91840b0 100644 --- a/src/sr/image/sceenshot/large_map.py +++ b/src/sr/image/sceenshot/large_map.py @@ -5,7 +5,7 @@ import numpy as np from cv2.typing import MatLike -from basic import os_utils +from basic import os_utils, str_utils from basic.i18_utils import gt from basic.img import cv2_utils from basic.log_utils import log @@ -44,7 +44,7 @@ def get_planet(screen: MatLike, ocr: OcrMatcher) -> Planet: log.debug('屏幕左上方获取星球结果 %s', planet_name_str) if planet_name_str is not None: for p in PLANET_LIST: - if planet_name_str.find(gt(p.cn, 'ocr')) != -1: + if str_utils.find_by_lcs(gt(p.cn, 'ocr'), planet_name_str, percent=game_config.get().planet_lcs_percent): return p return None @@ -173,12 +173,13 @@ def get_active_region_name(screen: MatLike, ocr: OcrMatcher) -> str: upper = 255 part, _ = cv2_utils.crop_image(screen, REGION_LIST_RECT) bw = cv2.inRange(part, (lower, lower, lower), (upper, upper, upper)) - # cv2_utils.show_image(bw, win_name='get_active_region_name') - km = ocr.run_ocr(bw) - if len(km) > 0: - return km.popitem()[0] - else: - return None + left, right, top, bottom = cv2_utils.get_four_corner(bw) + rect = (left[0] - 10, top[1] - 10, right[0] + 10, bottom[1] + 10) + to_ocr: MatLike = cv2_utils.crop_image(bw, rect)[0] + cv2_utils.show_image(to_ocr, win_name='get_active_region_name') + lang = game_config.get().lang + strict_one_line: bool = lang in [game_config_const.LANG_CN] + return ocr.ocr_for_single_line(to_ocr, strict_one_line=strict_one_line) def get_active_floor(screen: MatLike, ocr: OcrMatcher) -> str: diff --git a/src/sr/operation/__init__.py b/src/sr/operation/__init__.py index e1c60b73..782ee690 100644 --- a/src/sr/operation/__init__.py +++ b/src/sr/operation/__init__.py @@ -4,6 +4,8 @@ from basic.img.os import save_debug_image from basic.log_utils import log +from sr.config import game_config +from sr.config.game_config import GameConfig from sr.context import Context from sr.image.sceenshot import fill_uid_black @@ -25,6 +27,7 @@ def __init__(self, ctx: Context, try_times: int = 2): self.ctx: Context = ctx ctx.register_pause(self, self.on_pause, self.on_resume) self.last_screenshot: MatLike = None + self.gc: GameConfig = game_config.get() def execute(self) -> bool: """ diff --git a/src/sr/operation/unit/choose_planet.py b/src/sr/operation/unit/choose_planet.py index 9bb4e784..6e6ed092 100644 --- a/src/sr/operation/unit/choose_planet.py +++ b/src/sr/operation/unit/choose_planet.py @@ -49,7 +49,8 @@ def open_choose_planet(self, screen) -> bool: :param screen: 屏幕截图 :return: 找到 星轨航图 """ - return self.ctx.controller.click_ocr(screen, word=gt('星轨航图', 'ocr'), rect=ChoosePlanet.xght_rect) + return self.ctx.controller.click_ocr(screen, word=gt('星轨航图', 'ocr'), rect=ChoosePlanet.xght_rect, + lcs_percent=self.gc.planet_lcs_percent) def choose_planet(self, screen) -> bool: """ @@ -60,7 +61,7 @@ def choose_planet(self, screen) -> bool: # 二值化后更方便识别字体 gray = cv2.cvtColor(screen, cv2.COLOR_RGB2GRAY) _, mask = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY) - km = self.ctx.ocr.match_words(mask, words=[self.planet.cn]) + km = self.ctx.ocr.match_words(mask, words=[self.planet.cn], lcs_percent=self.gc.planet_lcs_percent) if len(km) == 0: return False for v in km.values(): diff --git a/src/sr/operation/unit/choose_region.py b/src/sr/operation/unit/choose_region.py index 68ef0479..cfecdc7f 100644 --- a/src/sr/operation/unit/choose_region.py +++ b/src/sr/operation/unit/choose_region.py @@ -1,5 +1,6 @@ import time +from basic import str_utils from basic.i18_utils import gt from basic.img import cv2_utils from basic.log_utils import log @@ -36,14 +37,15 @@ def run(self) -> int: current_region_name = large_map.get_active_region_name(screen, self.ctx.ocr) target_region_name = gt(self.region.cn, 'ocr') log.info('当前选择区域 %s', current_region_name) - if current_region_name is None or current_region_name.find(target_region_name) == -1: + is_current: bool = str_utils.find_by_lcs(target_region_name, current_region_name, ignore_case=True, + percent=self.gc.region_lcs_percent) + if not is_current: find = self.click_target_region(screen) - if not find: self.scroll_when_no_target_region(current_region_name) return Operation.RETRY else: - time.sleep(0.2) + time.sleep(0.5) return Operation.RETRY # 需要选择层数 @@ -72,7 +74,8 @@ def click_target_region(self, screen) -> bool: :param screen: :return: """ - return self.ctx.controller.click_ocr(screen, self.region.cn, rect=large_map.REGION_LIST_RECT, threshold=0.4) + return self.ctx.controller.click_ocr(screen, self.region.cn, rect=large_map.REGION_LIST_RECT, + lcs_percent=self.gc.region_lcs_percent, merge_line_distance=40) def scroll_when_no_target_region(self, current_region_name): """ @@ -80,7 +83,7 @@ def scroll_when_no_target_region(self, current_region_name): :param current_region_name: 当前选择的区域 :return: """ - log.info('当前界面未发现 %s 准备滚动', self.region.cn) + log.info('当前界面未发现 %s 准备滚动', gt(self.region.cn, 'ui')) if current_region_name is None and self.scroll_direction is None: # 判断不了当前选择区域的情况 就先向下滚动5次 再向上滚动5次 if self.op_round < 5: self.scroll_region_area() @@ -98,7 +101,8 @@ def scroll_when_no_target_region(self, current_region_name): for r in region_list: if r == self.region: break - if current_region_name.find(gt(r.cn, 'ocr')) != -1: + if str_utils.find_by_lcs(gt(r.cn, 'ocr'), current_region_name, ignore_case=True, + percent=self.gc.region_lcs_percent): find_current = True # 在找到目标区域前 当前区域已经出现 说明目标区域在下面 向下滚动 @@ -136,7 +140,7 @@ def check_tp_and_cancel(self, screen) -> bool: """ tp_btn_part, _ = cv2_utils.crop_image(screen, large_map.TP_BTN_RECT) # cv2_utils.show_image(tp_btn_part, win_name='tp_btn_part') - tp_btn_ocr = self.ctx.ocr.match_words(tp_btn_part, ['传送'], threshold=0.4) + tp_btn_ocr = self.ctx.ocr.match_words(tp_btn_part, ['传送']) if len(tp_btn_ocr) > 0: return self.ctx.controller.click(large_map.EMPTY_MAP_POS) return False \ No newline at end of file diff --git a/src/sr/operation/unit/choose_transport_point.py b/src/sr/operation/unit/choose_transport_point.py index d7915cfc..52856ad3 100644 --- a/src/sr/operation/unit/choose_transport_point.py +++ b/src/sr/operation/unit/choose_transport_point.py @@ -5,6 +5,7 @@ import numpy as np from cv2.typing import MatLike +from basic import str_utils from basic.i18_utils import gt from basic.img import MatchResultList, MatchResult, cv2_utils from basic.log_utils import log @@ -19,7 +20,7 @@ class ChooseTransportPoint(Operation): - tp_name_rect = (1485, 120, 1850, 170) # 右侧显示传送点名称的区域 + tp_name_rect = (1485, 120, 1870, 170) # 右侧显示传送点名称的区域 drag_distance = -200 def __init__(self, ctx: Context, tp: TransportPoint): @@ -82,7 +83,7 @@ def check_and_click_transport(self, screen: MatLike): """ tp_btn_part, _ = cv2_utils.crop_image(screen, large_map.TP_BTN_RECT) # cv2_utils.show_image(tp_btn_part, win_name='tp_btn_part') - tp_btn_ocr = self.ctx.ocr.match_words(tp_btn_part, ['传送'], threshold=0.4) + tp_btn_ocr = self.ctx.ocr.match_words(tp_btn_part, ['传送']) if len(tp_btn_ocr) > 0: # 看看是否目标传送点 tp_name_part, _ = cv2_utils.crop_image(screen, ChooseTransportPoint.tp_name_rect) @@ -106,7 +107,8 @@ def check_and_click_transport(self, screen: MatLike): log.info('当前选择传送点名称 %s', tp_name_str) # cv2_utils.show_image(gold_part, win_name='gold_part') - if tp_name_str is not None and tp_name_str.lower().find(gt(self.tp.cn, 'ocr').lower()) != -1: + if (tp_name_str is not None and + str_utils.find_by_lcs(gt(self.tp.cn, 'ocr'), tp_name_str, ignore_case=True, percent=self.gc.special_point_lcs_percent)): # 点击传送 tx = large_map.TP_BTN_RECT[0] ty = large_map.TP_BTN_RECT[1] @@ -204,7 +206,8 @@ def check_and_click_sp_cn(self, screen) -> bool: white_part = cv2.inRange(screen_map, lower_color, upper_color) # 提取白色部分方便匹配 # cv2_utils.show_image(white_part, win_name='check_and_click_sp_cn') - ocr_result = self.ctx.ocr.match_words(white_part, words=[self.tp.cn], threshold=0.3) + ocr_result = self.ctx.ocr.match_words(white_part, words=[self.tp.cn], + lcs_percent=self.gc.special_point_lcs_percent) for r in ocr_result.values(): tx = r.max.cx + large_map.CUT_MAP_RECT[0] diff --git a/src/sr/operation/unit/wait_in_world.py b/src/sr/operation/unit/wait_in_world.py index f3b103ea..3f180c11 100644 --- a/src/sr/operation/unit/wait_in_world.py +++ b/src/sr/operation/unit/wait_in_world.py @@ -11,7 +11,7 @@ class WaitInWorld(Operation): 等待加载 直到进入游戏主界面 右上角有角色图标 """ - def __init__(self, ctx: Context, wait: float = 10): + def __init__(self, ctx: Context, wait: float = 20): """ :param ctx: :param wait: 最多等待多少秒 diff --git a/test/src/basic/str_utils_test.py b/test/src/basic/str_utils_test.py new file mode 100644 index 00000000..9472b4e7 --- /dev/null +++ b/test/src/basic/str_utils_test.py @@ -0,0 +1,9 @@ +from basic import str_utils + + +def _test_find_by_lcs(): + print(str_utils.find_by_lcs('Artisanship Commission', 'Artisanship Commi55Ion', 0.7)) + + +if __name__ == '__main__': + _test_find_by_lcs() \ No newline at end of file diff --git a/test/src/sr/image/screenshot/large_map_test.py b/test/src/sr/image/screenshot/large_map_test.py index d9df31a5..c0e112c3 100644 --- a/test/src/sr/image/screenshot/large_map_test.py +++ b/test/src/sr/image/screenshot/large_map_test.py @@ -5,7 +5,7 @@ from sr.const import map_const from sr.const.map_const import Region from sr.image import ImageMatcher -from sr.image.cnocr_matcher import CnOcrMatcher +from sr.image.cn_ocr_matcher import CnOcrMatcher from sr.image.cv2_matcher import CvImageMatcher from sr.image.image_holder import ImageHolder from sr.image.sceenshot import large_map, LargeMapInfo