mirror of
https://github.com/wess09/AzurLaneAutoScript.git
synced 2026-05-14 06:38:38 +08:00
TW Server 活动适配
This commit is contained in:
parent
6f3de587b0
commit
38e8a09454
@ -288,6 +288,6 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
|
||||
| 20260402 | event 20260326 cn | The Vagabond’s Recruitment Plan | - | - | - | 漫遊者招募計劃 |
|
||||
| 20260416 | event 20220915 cn | Violet Tempest Blooming Lycoris | - | - | - | 復刻紫絳槿嵐 |
|
||||
| 20260417 | event 20260417 cn | Vacation Lane – Beachside Brilliance | 假日航线闪耀海滨 | Vacation Lane – Beachside Brilliance | バケーションレーン・きらめく砂浜 | - |
|
||||
| 20260417 | event 20201126 cn | Vacation Lane Rerun | 复刻假日航线 | Vacation Lane Rerun | バケーションレーン(復刻) | - |
|
||||
| 20260417 | event 20201126 cn | Vacation Lane Rerun | 复刻假日航线 | Vacation Lane Rerun | バケーションレーン(復刻) | 復刻假日航線 |
|
||||
| 20260417 | event 20250424 cn | Toward Tulipa’s Seas Rerun | 复刻扬起郁金之旗 | Toward Tulipa’s Seas Rerun | チュリッパの海へ(復刻) | - |
|
||||
| 20260417 | event 20260417 cn | Vacation Lane – Beachside Brilliance | - | - | - | 假日航線閃耀海濱 |
|
||||
|
||||
@ -2148,6 +2148,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -2642,6 +2643,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -3540,6 +3542,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -3974,6 +3977,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -4408,6 +4412,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -6760,6 +6765,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -7211,6 +7217,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -7662,6 +7669,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -8113,6 +8121,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
@ -8554,6 +8563,7 @@
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20260417_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20260326_cn",
|
||||
"event_20220728_cn"
|
||||
|
||||
@ -895,7 +895,7 @@
|
||||
"event_20201002_en": "Counterattack Within the Fjord",
|
||||
"event_20201012_cn": "復刻劃破海空之翼",
|
||||
"event_20201029_cn": "激唱的UNIVERSE",
|
||||
"event_20201126_cn": "假日航線",
|
||||
"event_20201126_cn": "復刻假日航線",
|
||||
"event_20201229_cn": "復刻-負象限作戰",
|
||||
"event_20210121_cn": "復刻神聖的悲喜劇",
|
||||
"event_20210225_cn": "復刻破曉冰華",
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import os
|
||||
import queue
|
||||
import threading
|
||||
import numpy as np
|
||||
import cv2
|
||||
from PIL import Image
|
||||
@ -30,6 +32,68 @@ config_name = os.environ.get("ALAS_CONFIG_NAME") or "alas"
|
||||
config = AzurLaneConfig(config_name)
|
||||
|
||||
|
||||
class _OcrJob:
|
||||
def __init__(self, func, args, kwargs):
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.done = threading.Event()
|
||||
self.result = None
|
||||
self.exc_info = None
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.result = self.func(*self.args, **self.kwargs)
|
||||
except BaseException as e:
|
||||
self.exc_info = (e, e.__traceback__)
|
||||
finally:
|
||||
self.done.set()
|
||||
|
||||
|
||||
_ocr_queue = queue.Queue()
|
||||
_ocr_worker = None
|
||||
_ocr_worker_lock = threading.Lock()
|
||||
_ocr_worker_ident = None
|
||||
|
||||
|
||||
def _ocr_worker_loop():
|
||||
global _ocr_worker_ident
|
||||
_ocr_worker_ident = threading.get_ident()
|
||||
while True:
|
||||
job = _ocr_queue.get()
|
||||
try:
|
||||
job.run()
|
||||
finally:
|
||||
_ocr_queue.task_done()
|
||||
|
||||
|
||||
def _ensure_ocr_worker():
|
||||
global _ocr_worker
|
||||
with _ocr_worker_lock:
|
||||
if _ocr_worker is None or not _ocr_worker.is_alive():
|
||||
_ocr_worker = threading.Thread(
|
||||
target=_ocr_worker_loop,
|
||||
name='AlOcrQueue',
|
||||
daemon=True,
|
||||
)
|
||||
_ocr_worker.start()
|
||||
|
||||
|
||||
def _run_ocr_queued(func, *args, **kwargs):
|
||||
if threading.get_ident() == _ocr_worker_ident:
|
||||
return func(*args, **kwargs)
|
||||
|
||||
_ensure_ocr_worker()
|
||||
job = _OcrJob(func, args, kwargs)
|
||||
_ocr_queue.put(job)
|
||||
job.done.wait()
|
||||
|
||||
if job.exc_info is not None:
|
||||
exc, traceback = job.exc_info
|
||||
raise exc.with_traceback(traceback)
|
||||
return job.result
|
||||
|
||||
|
||||
class RecOnlyOCR(RapidOCR):
|
||||
"""只加载识别模型,跳过 det 和 cls 的 ONNX 模型加载。"""
|
||||
|
||||
@ -118,12 +182,15 @@ def _get_model(name):
|
||||
|
||||
|
||||
def reset_ocr_model():
|
||||
global _cn_model, _en_model, _jp_model, _tw_model
|
||||
logger.info("Resetting OCR models")
|
||||
_cn_model = None
|
||||
_en_model = None
|
||||
_jp_model = None
|
||||
_tw_model = None
|
||||
def _reset():
|
||||
global _cn_model, _en_model, _jp_model, _tw_model
|
||||
logger.info("Resetting OCR models")
|
||||
_cn_model = None
|
||||
_en_model = None
|
||||
_jp_model = None
|
||||
_tw_model = None
|
||||
|
||||
return _run_ocr_queued(_reset)
|
||||
|
||||
|
||||
class AlOcr:
|
||||
@ -193,7 +260,7 @@ class AlOcr:
|
||||
# We don't want to crash the main process due to debug saving failure
|
||||
logger.warning(f"Failed to save OCR debug image: {e}")
|
||||
|
||||
def ocr(self, img_fp):
|
||||
def _ocr_direct(self, img_fp):
|
||||
logger.debug(f"[VERBOSE] AlOcr.ocr: Ensure loaded...")
|
||||
self._ensure_loaded()
|
||||
|
||||
@ -209,10 +276,13 @@ class AlOcr:
|
||||
logger.error(f"AlOcr.ocr exception: {e}")
|
||||
raise
|
||||
|
||||
def ocr(self, img_fp):
|
||||
return _run_ocr_queued(self._ocr_direct, img_fp)
|
||||
|
||||
def ocr_for_single_line(self, img_fp):
|
||||
return self.ocr(img_fp)
|
||||
|
||||
def ocr_for_single_lines(self, img_list):
|
||||
def _ocr_for_single_lines_direct(self, img_list):
|
||||
self._ensure_loaded()
|
||||
results = []
|
||||
for i, img in enumerate(img_list):
|
||||
@ -229,6 +299,9 @@ class AlOcr:
|
||||
raise
|
||||
return results
|
||||
|
||||
def ocr_for_single_lines(self, img_list):
|
||||
return _run_ocr_queued(self._ocr_for_single_lines_direct, img_list)
|
||||
|
||||
def set_cand_alphabet(self, cand_alphabet):
|
||||
pass
|
||||
|
||||
|
||||
@ -86,6 +86,7 @@ class AzurStats:
|
||||
LOCAL_MEOW_CSV = './log/azurstat_meowofficer_farming.csv'
|
||||
LOCAL_GENRES = {'opsi_meowfficer_farming'}
|
||||
_local_lock = threading.Lock()
|
||||
_record_lock = threading.Lock()
|
||||
|
||||
def __init__(self, config):
|
||||
"""
|
||||
@ -348,9 +349,9 @@ class AzurStats:
|
||||
save_thread.start()
|
||||
|
||||
if local:
|
||||
local_thread = threading.Thread(
|
||||
target=self._record_local, args=(image, genre, filename, combat_count))
|
||||
local_thread.start()
|
||||
logger.info(f'Local AzurStats parse start, genre={genre}')
|
||||
with self._record_lock:
|
||||
self._record_local(image, genre, filename, combat_count)
|
||||
|
||||
return True
|
||||
|
||||
@ -366,12 +367,16 @@ class AzurStats:
|
||||
Returns:
|
||||
DropImage:
|
||||
"""
|
||||
method_value = None
|
||||
if isinstance(method, bool):
|
||||
save = save or method
|
||||
method = None
|
||||
if method is not None:
|
||||
method = str(method)
|
||||
save = save or 'save' in method
|
||||
method_value = str(method)
|
||||
save = save or 'save' in method_value
|
||||
if local is None:
|
||||
local = genre in self.LOCAL_GENRES
|
||||
if method_value is None:
|
||||
local = genre in self.LOCAL_GENRES
|
||||
else:
|
||||
local = 'upload' in method_value and genre in self.LOCAL_GENRES
|
||||
return DropImage(stat=self, genre=genre, save=save, local=local, info=info)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user