Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified assets/cn/island_daily_interact/ROUTE_PORT_BUSINESS_COMPLETE.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/jp/combat/GET_ITEMS_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/jp/combat/GET_ITEMS_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/jp/combat/GET_ITEMS_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tw/handler/AIR_STRIKE_CANCEL.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tw/handler/AIR_STRIKE_CONFIRM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion campaign/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,4 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
| 20260528 | event 20220818 cn | Operation Convergence | - | - | - | 復刻遠匯點作戰 |
| 20260605 | event 20260520 cn | Alliance Before the Hagiobull | - | - | - | 聖印前的同盟 |
| 20260618 | event 20240521 cn | Light of the Martyrium Rerun | 复刻绽放于辉光之城 | Light of the Martyrium Rerun | 赫輝のマルティリウム(復刻) | - |
| 20260625 | event 20260625 cn | - | 美梦巡演:奇妙夜 | - | - | - |
| 20260625 | event 20260625 cn | Miracle by Midnight | 美梦巡演:奇妙夜 | - | 幻夢のカヴァルカード | - |
2 changes: 1 addition & 1 deletion campaign/event_20260625_cn/sp.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Config:
MAP_HAS_MYSTERY = False
MAP_CHAPTER_SWITCH_20260326 = True
STAGE_ENTRANCE = ['half', '20240725']
MAP_HAS_MODE_SWITCH = True
MAP_HAS_MODE_SWITCH = False
STAGE_INCREASE_AB = True
MAP_WALK_USE_CURRENT_FLEET = True
STAR_REQUIRE_1 = 0
Expand Down
6 changes: 3 additions & 3 deletions module/combat/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
EXP_INFO_C = Button(area={'cn': (332, 56, 345, 107), 'en': (332, 56, 345, 107), 'jp': (332, 56, 345, 107), 'tw': (332, 56, 345, 107)}, color={'cn': (198, 208, 198), 'en': (198, 208, 198), 'jp': (198, 208, 198), 'tw': (198, 208, 198)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_C.png', 'en': './assets/en/combat/EXP_INFO_C.png', 'jp': './assets/jp/combat/EXP_INFO_C.png', 'tw': './assets/tw/combat/EXP_INFO_C.png'})
EXP_INFO_D = Button(area={'cn': (328, 45, 341, 119), 'en': (328, 45, 341, 119), 'jp': (328, 45, 341, 119), 'tw': (328, 45, 341, 119)}, color={'cn': (199, 208, 199), 'en': (199, 208, 199), 'jp': (199, 208, 199), 'tw': (199, 208, 199)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_D.png', 'en': './assets/en/combat/EXP_INFO_D.png', 'jp': './assets/jp/combat/EXP_INFO_D.png', 'tw': './assets/tw/combat/EXP_INFO_D.png'})
EXP_INFO_S = Button(area={'cn': (342, 107, 389, 119), 'en': (342, 107, 389, 119), 'jp': (342, 107, 389, 119), 'tw': (342, 107, 389, 119)}, color={'cn': (233, 242, 127), 'en': (233, 242, 127), 'jp': (233, 242, 127), 'tw': (233, 242, 127)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_S.png', 'en': './assets/en/combat/EXP_INFO_S.png', 'jp': './assets/jp/combat/EXP_INFO_S.png', 'tw': './assets/tw/combat/EXP_INFO_S.png'})
GET_ITEMS_1 = Button(area={'cn': (538, 217, 741, 253), 'en': (551, 223, 736, 250), 'jp': (548, 217, 741, 253), 'tw': (539, 217, 742, 253)}, color={'cn': (160, 192, 248), 'en': (166, 194, 235), 'jp': (144, 183, 250), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1.png', 'en': './assets/en/combat/GET_ITEMS_1.png', 'jp': './assets/jp/combat/GET_ITEMS_1.png', 'tw': './assets/tw/combat/GET_ITEMS_1.png'})
GET_ITEMS_1 = Button(area={'cn': (538, 217, 741, 253), 'en': (551, 223, 736, 250), 'jp': (539, 220, 741, 252), 'tw': (539, 217, 742, 253)}, color={'cn': (160, 192, 248), 'en': (166, 194, 235), 'jp': (146, 184, 249), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1.png', 'en': './assets/en/combat/GET_ITEMS_1.png', 'jp': './assets/jp/combat/GET_ITEMS_1.png', 'tw': './assets/tw/combat/GET_ITEMS_1.png'})
GET_ITEMS_1_RYZA = Button(area={'cn': (564, 217, 721, 245), 'en': (577, 211, 704, 239), 'jp': (566, 217, 719, 244), 'tw': (564, 218, 723, 246)}, color={'cn': (176, 199, 243), 'en': (172, 199, 246), 'jp': (179, 201, 243), 'tw': (173, 197, 242)}, button={'cn': (1000, 631, 1055, 689), 'en': (1000, 631, 1055, 689), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1_RYZA.png', 'en': './assets/en/combat/GET_ITEMS_1_RYZA.png', 'jp': './assets/jp/combat/GET_ITEMS_1_RYZA.png', 'tw': './assets/tw/combat/GET_ITEMS_1_RYZA.png'})
GET_ITEMS_2 = Button(area={'cn': (538, 146, 742, 182), 'en': (551, 149, 735, 175), 'jp': (547, 143, 742, 179), 'tw': (538, 148, 741, 182)}, color={'cn': (160, 192, 248), 'en': (167, 195, 235), 'jp': (145, 183, 250), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_2.png', 'en': './assets/en/combat/GET_ITEMS_2.png', 'jp': './assets/jp/combat/GET_ITEMS_2.png', 'tw': './assets/tw/combat/GET_ITEMS_2.png'})
GET_ITEMS_3 = Button(area={'cn': (539, 143, 742, 179), 'en': (548, 136, 740, 172), 'jp': (547, 143, 742, 179), 'tw': (546, 145, 742, 178)}, color={'cn': (161, 193, 248), 'en': (152, 185, 237), 'jp': (145, 183, 250), 'tw': (156, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_3.png', 'en': './assets/en/combat/GET_ITEMS_3.png', 'jp': './assets/jp/combat/GET_ITEMS_3.png', 'tw': './assets/tw/combat/GET_ITEMS_3.png'})
GET_ITEMS_2 = Button(area={'cn': (538, 146, 742, 182), 'en': (551, 149, 735, 175), 'jp': (536, 146, 741, 182), 'tw': (538, 148, 741, 182)}, color={'cn': (160, 192, 248), 'en': (167, 195, 235), 'jp': (145, 182, 249), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_2.png', 'en': './assets/en/combat/GET_ITEMS_2.png', 'jp': './assets/jp/combat/GET_ITEMS_2.png', 'tw': './assets/tw/combat/GET_ITEMS_2.png'})
GET_ITEMS_3 = Button(area={'cn': (539, 143, 742, 179), 'en': (548, 136, 740, 172), 'jp': (540, 143, 742, 179), 'tw': (546, 145, 742, 178)}, color={'cn': (161, 193, 248), 'en': (152, 185, 237), 'jp': (145, 182, 248), 'tw': (156, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_3.png', 'en': './assets/en/combat/GET_ITEMS_3.png', 'jp': './assets/jp/combat/GET_ITEMS_3.png', 'tw': './assets/tw/combat/GET_ITEMS_3.png'})
GET_ITEMS_3_CHECK = Button(area={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, color={'cn': (84, 95, 109), 'en': (84, 95, 109), 'jp': (84, 95, 109), 'tw': (84, 95, 109)}, button={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, file={'cn': './assets/cn/combat/GET_ITEMS_3_CHECK.png', 'en': './assets/en/combat/GET_ITEMS_3_CHECK.png', 'jp': './assets/jp/combat/GET_ITEMS_3_CHECK.png', 'tw': './assets/tw/combat/GET_ITEMS_3_CHECK.png'})
GET_SHIP = Button(area={'cn': (1104, 610, 1110, 630), 'en': (1104, 610, 1110, 630), 'jp': (1104, 610, 1110, 630), 'tw': (1104, 610, 1110, 630)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_SHIP.png', 'en': './assets/en/combat/GET_SHIP.png', 'jp': './assets/jp/combat/GET_SHIP.png', 'tw': './assets/tw/combat/GET_SHIP.png'})
LOADING_BAR = Button(area={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, color={'cn': (172, 205, 232), 'en': (172, 205, 232), 'jp': (172, 205, 232), 'tw': (172, 205, 232)}, button={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, file={'cn': './assets/cn/combat/LOADING_BAR.png', 'en': './assets/en/combat/LOADING_BAR.png', 'jp': './assets/jp/combat/LOADING_BAR.png', 'tw': './assets/tw/combat/LOADING_BAR.png'})
Expand Down
143 changes: 97 additions & 46 deletions module/commission/project.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import datetime, timedelta

import module.config.server as server
from module.base.decorator import Config
from module.base.filter import Filter
from module.base.utils import *
Expand All @@ -23,36 +22,56 @@
)


class SuffixOcr(Ocr):
"""后缀 OCR 识别器,用于识别委托名称末尾的罗马数字后缀
def crop_suffix_image(image, area):
"""裁剪委托名称右侧的罗马数字后缀图像

预处理时裁剪掉图像右侧空白区域,只保留后缀部分以提高识别准确率。
"""

def pre_process(self, image):
"""预处理图像,裁剪右侧空白区域以聚焦后缀字符。

通过检测每列像素最小值定位文本右边界,再向左回退若干像素
以确保完整保留后缀字符。日服字符较宽,需要更大的回退量。

Args:
image: 输入的灰度图像。

Returns:
裁剪后的图像。
"""
image = super().pre_process(image)
Args:
image: 游戏截图。
area: 委托名称区域。

left = np.where(np.min(image[5:-5, :], axis=0) < 85)[0]
# 日服字符较宽,需要回退更多像素
if server.server in ['jp']:
look_back = 21
else:
look_back = 18
if len(left):
image = image[:, left[-1] - look_back:]
Returns:
后缀裁剪图,黑字白底;未检测到文字时返回 None。
"""
name_image = crop(image, area)
name_image = extract_letters(name_image, letter=(255, 255, 255), threshold=128).astype(np.uint8)

line = cv2.reduce(name_image[5:-5, :], 0, cv2.REDUCE_AVG).flatten()
Comment on lines +35 to +38

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 在进行切片和归约之前,需要防范 name_image 过小或为空的情况。

如果裁剪区域非常小(例如高度 ≤ 10 或宽度 == 0),name_image[5:-5, :] 可能为空,而此时调用 cv2.reduce 会报错。建议先检查 name_image.shape,在区域太小不适合做 5 像素裁剪时直接返回 None,或采用其他回退处理方式。

Original comment in English

issue (bug_risk): Guard against very small or empty name_image before slicing and reducing.

If the cropped region is very small (e.g., height ≤ 10 or width == 0), name_image[5:-5, :] may be empty and cv2.reduce will error. Consider checking name_image.shape first and returning None or using a fallback when the region is too small for the 5‑pixel trim.

columns = np.where(line < 250)[0]
if not len(columns):
return None

# 从最右侧文字向左回看,尽量完整包含罗马数字后缀。
threshold = 250
look_back = 10
for i in range(columns[-1], 0, -1):
if line[i] > threshold:
if columns[-1] - i > look_back:
look_back = columns[-1] - i
break

left = columns[-1] - look_back
right = columns[-1] + 1
Comment on lines +38 to +53

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If name_image has a height of 10 or less, slicing name_image[5:-5, :] will result in an empty array, causing cv2.reduce to crash. Additionally, if columns[-1] is less than look_back (10), left will become negative, which can lead to out-of-bounds cropping or unexpected behavior.

We should add a guard for the image height and ensure that left and right are clamped within the valid boundaries of name_image.

Suggested change
line = cv2.reduce(name_image[5:-5, :], 0, cv2.REDUCE_AVG).flatten()
columns = np.where(line < 250)[0]
if not len(columns):
return None
# 从最右侧文字向左回看,尽量完整包含罗马数字后缀。
threshold = 250
look_back = 10
for i in range(columns[-1], 0, -1):
if line[i] > threshold:
if columns[-1] - i > look_back:
look_back = columns[-1] - i
break
left = columns[-1] - look_back
right = columns[-1] + 1
h, w = name_image.shape[:2]
if h > 10:
line = cv2.reduce(name_image[5:-5, :], 0, cv2.REDUCE_AVG).flatten()
else:
line = cv2.reduce(name_image, 0, cv2.REDUCE_AVG).flatten()
columns = np.where(line < 250)[0]
if not len(columns):
return None
# 从最右侧文字向左回看,尽量完整包含罗马数字后缀。
threshold = 250
look_back = 10
for i in range(columns[-1], 0, -1):
if line[i] > threshold:
if columns[-1] - i > look_back:
look_back = columns[-1] - i
break
left = max(0, columns[-1] - look_back)
right = min(w, columns[-1] + 1)

x1, y1 = area[0:2]
suffix_area = area_offset((left - 3, -3, right + 3, name_image.shape[0] + 3), (x1, y1))
image = crop(image, suffix_area)
image = extract_letters(image, letter=(255, 255, 255), threshold=128).astype(np.uint8)
return image


def image_hash(image):
"""计算图像哈希,用于日志输出。

Args:
image: 输入图像。

Returns:
图像 MD5;图像为空时返回空字符串。
"""
if image is None:
return ''

return image
import hashlib
return hashlib.md5(image.tobytes()).hexdigest()


class Commission:
Expand All @@ -68,9 +87,10 @@ class Commission:
name: str
# 委托名称是否解析成功
valid: bool
# 罗马数字后缀,委托无后缀时可能识别错误
# 值: ⅠⅡⅢⅤⅣⅥ
suffix: str
# 裁剪出的后缀图像,黑字白底;无后缀时为 None
suffix_image: np.ndarray
# 后缀图像哈希,仅用于日志;无后缀时为空字符串
suffix_hash: str
# 委托类型名称,定义在 project_data.py 中
# 值: major_comm, daily_resource, urgent_cube, ...
genre: str
Expand Down Expand Up @@ -146,9 +166,9 @@ def commission_parse(self):
self.name = result
self.genre = self.commission_name_parse(self.name)

# 后缀识别
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
self.suffix = self.beautify_name(ocr.ocr(self.image))
# 后缀图像识别
self.suffix_image = crop_suffix_image(self.image, self.button.area)
self.suffix_hash = image_hash(self.suffix_image)

# 执行时长
area = area_offset((290, 68, 390, 95), self.area[0:2])
Expand Down Expand Up @@ -198,9 +218,9 @@ def commission_parse(self):
self.name = result
self.genre = self.commission_name_parse(self.name)

# 后缀识别
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
self.suffix = self.beautify_name(ocr.ocr(self.image))
# 后缀图像识别
self.suffix_image = crop_suffix_image(self.image, self.button.area)
self.suffix_hash = image_hash(self.suffix_image)

# 执行时长
area = area_offset((290, 68, 390, 95), self.area[0:2])
Expand Down Expand Up @@ -254,9 +274,9 @@ def commission_parse(self):
self.name = result
self.genre = self.commission_name_parse(self.name)

# 后缀识别
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
self.suffix = self.beautify_name(ocr.ocr(self.image))
# 后缀图像识别
self.suffix_image = crop_suffix_image(self.image, self.button.area)
self.suffix_hash = image_hash(self.suffix_image)

# 执行时长
area = area_offset((290, 68, 390, 95), self.area[0:2])
Expand Down Expand Up @@ -292,7 +312,7 @@ def commission_parse(self):
def commission_parse(self):
"""解析委托信息(CN 服务器,默认回退)。

CN 服后缀直接从名称末尾提取罗马数字,不使用独立 OCR
CN 服同样裁剪名称右侧后缀图像,用于后续相似度匹配
解析内容:名称、后缀、时长、过期时间、状态。
"""
# 名称识别
Expand All @@ -306,8 +326,9 @@ def commission_parse(self):
self.name = result
self.genre = self.commission_name_parse(self.name)

# 后缀——直接从名称末尾提取罗马数字
self.suffix = self.beautify_name(''.join(c for c in result[-4:] if c in 'IV'))
# 后缀图像识别
self.suffix_image = crop_suffix_image(self.image, self.button.area)
self.suffix_hash = image_hash(self.suffix_image)

# 执行时长
area = area_offset((290, 68, 390, 95), self.area[0:2])
Expand Down Expand Up @@ -341,7 +362,7 @@ def commission_parse(self):

def __str__(self):
"""返回委托的可读字符串表示,包含名称、类型、状态和时长。"""
name = f'{self.name} | {self.suffix}'
name = f'{self.name} | {self.suffix_hash}' if self.suffix_hash else self.name
if not self.valid:
return f'{name} (Invalid)'
info = {'Genre': self.genre, 'Status': self.status, 'Duration': self.duration}
Expand Down Expand Up @@ -372,7 +393,7 @@ def __eq__(self, other):
if self.genre != other.genre or self.status != other.status:
return False
if self.category_str == 'daily':
if self.suffix != other.suffix:
if not self.suffix_match(other):
return False
if self.genre == 'urgent_box':
for tag in ['NYB', 'BIW']:
Expand All @@ -389,7 +410,7 @@ def __eq__(self, other):
return False
if self.repeat_count != other.repeat_count:
return False
if self.genre in ['extra_oil', 'night_oil'] and self.suffix != other.suffix:
if self.genre in ['extra_oil', 'night_oil'] and not self.suffix_match(other):
return False

return True
Expand All @@ -398,6 +419,36 @@ def __hash__(self):
"""返回委托的哈希值,基于类型和名称。"""
return hash(f'{self.genre}_{self.name}')

def suffix_match(self, other, similarity=0.75):
"""判断两个委托的后缀图像是否匹配。

Args:
other: 要比较的委托对象。
similarity: 相似度阈值,范围 0-1。

Returns:
后缀是否匹配。
"""
if self.suffix_image is None and other.suffix_image is None:
return True
if self.suffix_image is None or other.suffix_image is None:
return False

def match(image, template):
template = crop(template, (3, 3, template.shape[1] - 3, template.shape[0] - 3), copy=False)
if image.shape[0] < template.shape[0] or image.shape[1] < template.shape[1]:
return 0.0

res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
_, sim, _, _ = cv2.minMaxLoc(res)
return sim
Comment on lines +437 to +444

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If the template width or height is 6 or less (which can happen for narrow characters like "I" or due to tight cropping), template.shape[1] - 3 will be 3 or less, resulting in an invalid crop area where x1 >= x2 or y1 >= y2. This causes crop to return an empty image, which will crash cv2.matchTemplate with an assertion error.

We should check if the template dimensions are too small and return 0.0 early to prevent crashes.

        def match(image, template):
            h, w = template.shape[:2]
            if h <= 6 or w <= 6:
                return 0.0
            template = crop(template, (3, 3, w - 3, h - 3), copy=False)
            if image.shape[0] < template.shape[0] or image.shape[1] < template.shape[1]:
                return 0.0

            res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
            _, sim, _, _ = cv2.minMaxLoc(res)
            return sim


sim = max(
match(self.suffix_image, other.suffix_image),
match(other.suffix_image, self.suffix_image)
)
return sim >= similarity

def parse_time(self, string):
"""解析时间字符串为 timedelta 对象。

Expand Down
20 changes: 10 additions & 10 deletions module/config/argument/args.json
Original file line number Diff line number Diff line change
Expand Up @@ -2291,7 +2291,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -2800,7 +2800,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -3738,7 +3738,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -4179,7 +4179,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -4620,7 +4620,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -7163,7 +7163,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -7621,7 +7621,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -8079,7 +8079,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -8537,7 +8537,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down Expand Up @@ -8985,7 +8985,7 @@
"event_20240521_cn"
],
"option_jp": [
"event_20240521_cn"
"event_20260625_cn"
],
"option_tw": [
"event_20260520_cn"
Expand Down
2 changes: 1 addition & 1 deletion module/config/i18n/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@
"event_20260326_cn": "ワンダラー募集計画",
"event_20260417_cn": "バケーションレーン・きらめく砂浜",
"event_20260520_cn": "聖印前の同盟",
"event_20260625_cn": "美梦巡演:奇妙夜",
"event_20260625_cn": "幻夢のカヴァルカード",
"raid_20200624": "特別演習超空強襲波(復刻)",
"raid_20210708": "交錯する新たな波 (復刻)",
"raid_20220127": "秘密事件調査",
Expand Down
Loading
Loading