feat(tobypasstrackers): Add new trackers and refine IP exclusion logic

This commit is contained in:
wumode
2025-12-10 22:42:55 +08:00
parent 4a0c700e6b
commit 5ccbb412eb
6 changed files with 50 additions and 48 deletions

View File

@@ -443,11 +443,12 @@
"name": "绕过Trackers",
"description": "提供tracker服务器IP地址列表帮助IPv6连接绕过OpenClash。",
"labels": "工具",
"version": "1.5.0",
"version": "1.5.1",
"icon": "Clash_A.png",
"author": "wumode",
"level": 2,
"history": {
"v1.5.1": "新增 Tracker",
"v1.5.0": "新增 Page 界面; 支持通过`/check_ip` 命令检查IP; 改进 UI",
"v1.4.3": "修复 bug",
"v1.4.2": "修复插件动作",

View File

@@ -6,9 +6,9 @@ ___
## 主要功能
![](https://images2.imgbox.com/d6/b6/kZu6EH2a_o.png)
![](https://images2.imgbox.com/c8/3a/rEJBWu5v_o.png)
![](https://images2.imgbox.com/56/c0/FBhJMvRD_o.jpg)
![](https://images2.imgbox.com/e8/8c/B1EJwst7_o.jpg)
![](https://images2.imgbox.com/8a/d4/AtgOe265_o.jpg)
- 识别视频的原始语言和字幕语言

View File

@@ -1275,7 +1275,7 @@ class LexiAnnot(_PluginBase):
f"{media_info.title_year} {context.meta_info.season_episode}"
)
else:
media_name = f"{media_info.title_year}.{video_path.suffix}"
media_name = f"{media_info.title_year}"
message = f"标题: {media_name}"
if phase == "start":
self.post_message(
@@ -1803,7 +1803,7 @@ class LexiAnnot(_PluginBase):
usage_style = zh_style.copy()
usage_style.name = "Annotation USAGE"
usage_style.fontsize = fs * 0.5
usage_style.fontsize = fs * 0.75
usage_style.italic = True
usage_style.primarycolor = Color(224, 224, 224, self._color_alpha)
ass.styles["Annotation USAGE"] = usage_style
@@ -2060,12 +2060,10 @@ class LexiAnnot(_PluginBase):
exams = [exam for exam in word.exams if exam in self._exam_tags]
new_text = f"{{\\c{abgr_str}}}{word.text}{{\\r}}"
if self._in_place:
part_of_speech = f"{{\\fnTimes New Roman\\fs{int(main_style_fs * 0.75)}\\i1}}{UNIVERSAL_POS_MAP[word.pos] or ''}{{\\r}}"
new_text = (
new_text + f" ({word.llm_translation} {part_of_speech})"
if word.llm_translation
else ""
)
part_of_speech = (f"{{\\fnTimes New Roman\\fs{int(main_style_fs * 0.75)}\\i1}}"
f"{UNIVERSAL_POS_MAP[word.pos] or ''}{{\\r}}")
new_text = new_text + f" ({word.llm_translation} {part_of_speech})" \
if word.llm_translation else ""
else:
dialogue = SSAEvent()
dialogue.start = main_processor[seg.index].start
@@ -2086,7 +2084,10 @@ class LexiAnnot(_PluginBase):
if word.phonetics and self._show_phonetics
else ""
)
annot_text = f"{word.lemma} {style_text('Annotation POS', UNIVERSAL_POS_MAP[word.pos] or '')} {style_text('Annotation ZH', word.llm_translation or '')}{cefr_text}{exam_text}{phone_text}"
annot_text = (f"{word.lemma} "
f"{style_text('Annotation POS', UNIVERSAL_POS_MAP[word.pos] or '')} "
f"{style_text('Annotation ZH', word.llm_translation or '')}"
f"{cefr_text}{exam_text}{phone_text}")
dialogue.text = annot_text
ass_file.append(dialogue)
if word.llm_usage_context:
@@ -2094,9 +2095,7 @@ class LexiAnnot(_PluginBase):
start=main_processor[seg.index].start,
style="DETAIL CN",
end=main_processor[seg.index].end,
text=style_text(
"Annotation USAGE", word.llm_usage_context
),
text=style_text("Annotation USAGE", f"{{\\q1}}{word.llm_usage_context}"),
)
ass_file.append(dialogue)
if self._show_vocabulary_detail and word.pos_defs:

View File

@@ -460,6 +460,8 @@ def _context_process_chain(
continue
if any(w.text == new_word.text for w in seg.candidate_words):
continue
if new_word.lemma in lexi.swear_words:
continue
new_meta = WordMetadata(
start_pos=start_pos,
end_pos=start_pos + len(new_word.text),
@@ -471,6 +473,7 @@ def _context_process_chain(
pos=new_word.pos,
meta=new_meta
)
built_word = _update_word_via_lexicon(built_word, lexi)
if built_word.cefr and built_word.cefr < leaner_level:
continue
@@ -504,7 +507,7 @@ Your goal is to identify **only** content that helps them reach native-level pro
* Avoid repeating words already listed in `candidate_words`.
* Must exist in the exact form in `context_text`.
* Provide lemma and POS.
* **Do NOT include** simple high-frequency words, common fillers ('gonna', 'gotta'), or basic swear words unless necessary for context.
* **Do NOT include** simple high-frequency words, common fillers ('gonna', 'gotta'), or basic swear words.
-------------------------
You MUST return output strictly matching the provided Pydantic schema.
@@ -711,16 +714,12 @@ def llm_process_chain(
if media_context and media_context.media_info and media_context.meta_info:
media_info = media_context.media_info
if media_info.type == MediaType.TV:
media_name = (
f"{media_info.title_year} {media_context.meta_info.season_episode}"
)
media_name = f"{media_info.title_year} {media_context.meta_info.season_episode}"
else:
media_name = f"{media_info.title_year}"
segments_list = []
for context, (start, end) in segments.context_generator(
context_window=context_window, extra_len=2
):
for context, (start, end) in segments.context_generator(context_window=context_window, extra_len=2):
if shutdown_event.is_set():
break
logger.info(

View File

@@ -51,11 +51,11 @@ class ToBypassTrackers(_PluginBase):
# 插件名称
plugin_name = "绕过Trackers"
# 插件描述
plugin_desc = "提供tracker服务器IP地址列表帮助IPv6连接绕过OpenClash。"
plugin_desc = "提供 Tracker 服务器 IP 地址列表,帮助 IPv6 连接绕过 OpenClash。"
# 插件图标
plugin_icon = "Clash_A.png"
# 插件版本
plugin_version = "1.5.0"
plugin_version = "1.5.1"
# 插件作者
plugin_author = "wumode"
# 作者主页
@@ -558,7 +558,6 @@ class ToBypassTrackers(_PluginBase):
'title': '绕过的 Tracker 服务器 IP 列表',
'subtitle': '以下是已解析并添加到绕过列表中的 Tracker 服务器 IP 地址,'
'请在 OpenClash 中配置「绕过中国大陆 IP」并订阅本列表以实现绕过效果。',
'variant': 'elevated',
},
'content': [
{
@@ -589,7 +588,7 @@ class ToBypassTrackers(_PluginBase):
{
'component': 'VCard',
'props': {
'class': 'mb-4',
'class': 'pa-0',
'title': '排除的 IP 列表',
'variant': 'elevated',
},
@@ -696,14 +695,18 @@ class ToBypassTrackers(_PluginBase):
for ip in ip_list:
detail = bypassed.get(ip)
excluded_detail = excluded.get(ip)
if ip in excluded and excluded_detail is not None:
sub_message = f"{ip}"
if excluded_detail is not None:
detail_msg = '\n'.join(f"{k}: {v}" for k,v in excluded_detail.to_dict().items())
message += f"\nIP 地址 {ip} 在排除列表中,不会被绕过\n{detail_msg}\n"
elif ip in bypassed and detail is not None:
sub_message += f" 在排除列表中:\n{detail_msg}\n"
if detail is not None:
detail_msg = '\n'.join(f"{k}: {v}" for k,v in detail.to_dict().items())
message += f"\nIP 地址 {ip} 会被绕过\n{detail_msg}\n"
sub_message += f" 在绕过列表中\n{detail_msg}\n"
if detail and not excluded_detail:
sub_message += f"✈️ 会被绕过。\n"
else:
message += f"\nIP 地址 {ip} 不在绕过列表中\n"
sub_message += f"🛑 不会被绕过\n"
message += sub_message + "\n"
self.post_message(channel=channel, user=userid, text=message, title=f"{host}")
@overload
@@ -892,26 +895,26 @@ class ToBypassTrackers(_PluginBase):
timestamp=int(time.time())))
except ValueError:
exempted_domains.append(exempted_domain)
cidr_details_dict = {detail.ip_cidr: detail for detail in cidr_details}
asyncio.run(resolve_all(exempted_domains, exempted_ipv6, exempted_ip, exempted_cidr_details))
for ip in exempted_ip:
index = ToBypassTrackers._search_subnet(ip, ip_list)
if index == -1:
continue
subnet = ip_list[index]
ip_list.pop(index)
if subnet.prefixlen < 12:
new_subnet = IPv4Network((ip.network_address, subnet.prefixlen + 8), strict=False)
ip_list.extend(subnet.address_exclude(new_subnet))
while (index:= ToBypassTrackers._search_subnet(ip, ip_list)) != -1:
subnet = ip_list[index]
ip_list.pop(index)
source = cidr_details_dict[str(subnet)].domain if str(subnet) in cidr_details_dict else "CN"
logger.warn(f"Excluding subnet {subnet} ({source}) for exempted IP {ip}")
if subnet.prefixlen < 12:
new_subnet = IPv4Network((ip.network_address, subnet.prefixlen + 8), strict=False)
ip_list.extend(subnet.address_exclude(new_subnet))
for ip in exempted_ipv6:
index = ToBypassTrackers._search_subnet(ip, ipv6_list)
if index == -1:
continue
subnet = ipv6_list[index]
ipv6_list.pop(index)
if subnet.prefixlen < 32:
new_subnet = IPv6Network((ip.network_address, min(32, subnet.prefixlen + 8)), strict=False)
ipv6_list.extend(subnet.address_exclude(new_subnet))
while (index:=ToBypassTrackers._search_subnet(ip, ipv6_list)) != -1:
subnet = ipv6_list[index]
ipv6_list.pop(index)
source = cidr_details_dict[str(subnet)].domain if str(subnet) in cidr_details_dict else "CN"
logger.warn(f"Excluding subnet {subnet} ({source}) for exempted IP {ip}")
if subnet.prefixlen < 32:
new_subnet = IPv6Network((ip.network_address, min(32, subnet.prefixlen + 8)), strict=False)
ipv6_list.extend(subnet.address_exclude(new_subnet))
ipv4_txt = "\n".join(str(net) for net in ip_list)
ipv6_txt = "\n".join(str(net) for net in ipv6_list)
self.save_data("ipv4_txt", ipv4_txt)

View File

@@ -1 +1 @@
eyI1MnB0LnNpdGUiOiBbIjUycHQuc2l0ZSJdLCAiYXVkaWVuY2VzLm1lIjogWyJ0LmF1ZGllbmNlcy5tZSIsICJ0cmFja2VyLmNpbmVmaWxlcy5pbmZvIl0sICJidHNjaG9vbC5jbHViIjogWyJwdC5idHNjaG9vbC5jbHViIl0sICJieXIucHQiOiBbInRyYWNrZXIuYnlyLnB0Il0sICJjYXJwdC5uZXQiOiBbInRyYWNrZXIuY2FycHQubmV0Il0sICJjcmFicHQudmlwIjogWyJjcmFicHQudmlwIl0sICJjc3B0LnRvcCI6IFsidHJhY2tlci5jc3B0LnRvcCIsICJ0cmFja2VyLmNzcHQuY2MiLCAidHJhY2tlci5jc3B0LmRhdGUiXSwgImRpc2NmYW4ubmV0IjogWyJkaXNjZmFuLnh5eiJdLCAiZWFzdGdhbWUub3JnIjogWyJwdC5lYXN0Z2FtZS5vcmciXSwgImV0OC5vcmciOiBbImV0OC5vcmciLCAidC5ldDgub3JnIl0sICJnYW1lZ2FtZXB0LmNvbSI6IFsid3d3LmdhbWVnYW1lcHQuY29tIl0sICJoZGFyZWEuY2x1YiI6IFsidHJhY2tlci5oZGFyZWEuY2x1YiJdLCAiaGRkb2xieS5jb20iOiBbInQuaGRkb2xieS5jb20iXSwgImhkZmFucy5vcmciOiBbImhkZmFucy5vcmciXSwgImhka3lsLmluIjogWyJ0cmFja2VyLmhka3lsLmluIiwgInd3dy5oZGt5bGluLnRvcCJdLCAiaGR0aW1lLm9yZyI6IFsiaGR0aW1lLm9yZyJdLCAiaGl0cHQuY29tIjogWyJoaXRwdC5jb20iXSwgImh1ZGJ0Lmh1c3QuZWR1LmNuIjogWyJodWRidC5odXN0LmVkdS5jbiJdLCAiaWNjMjAyMi5jb20iOiBbInRyYWNrZXIuaWNjMjAyMi54eXoiXSwgImlsb2xpY29uLmNvbSI6IFsidHJhY2tlci5pbG9saWNvbi5jYyJdLCAia2VlcGZyZHMuY29tIjogWyJ0cmFja2VyLmtlZXBmcmRzLmNvbSJdLCAibS10ZWFtLmNjIjogWyJ0cmFja2VyLm0tdGVhbS5jYyIsICJ0cmFja2VyLm0tdGVhbS5pbyJdLCAibW9uaWthZGVzaWduLnVrIjogWyJ0cmFja2VyLm1vbmlrYWRlc2lnbi51ayIsICJkYWlraXJhaS5tb25pa2FkZXNpZ24udWsiLCAiYW5pbWUtbm8taW5kZXguY29tIl0sICJuaWNlcHQubmV0IjogWyJ3d3cubmljZXB0Lm5ldCJdLCAib2twdC5uZXQiOiBbInd3dy5va3B0Lm5ldCJdLCAicHRob21lLm5ldCI6IFsicHRob21lLm5ldCJdLCAicHRsZ3Mub3JnIjogWyJwdGwuZ3MiLCAicmVsYXkwMS5wdGwuZ3MiXSwgInB0c2Jhby5jbHViIjogWyJwdHNiYW8uY2x1YiJdLCAicHR0aW1lLm9yZyI6IFsid3d3LnB0dGltZS5vcmciXSwgInB0em9uZS54eXoiOiBbInB0em9uZS54eXoiXSwgInFpbmd3YXB0LmNvbSI6IFsidHJhY2tlci5xaW5nd2EucHJvIiwgInRyYWNrZXIucWluZ3dhcHQuY29tIiwgInRyYWNrZXIucWluZ3dhcHQub3JnIl0sICJyYWluZ2ZoLnRvcCI6IFsicmFpbmdmaC50b3AiXSwgInJvdXNpLnppcCI6IFsiaGl0cHQuY29tIl0sICJzcHJpbmdzdW5kYXkubmV0IjogWyJvbjYuc3ByaW5nc3VuZGF5Lm5ldCIsICJvbi5zcHJpbmdzdW5kYXkubmV0Il0sICJ0anVwdC5vcmciOiBbInRyYWNrZXItcHVibGljLnRqdXB0Lm9yZyJdLCAidG90aGVnbG9yeS5pbSI6IFsidHJhY2tlci50b3RoZWdsb3J5LmltIl0sICJ1Mi5kbWh5Lm9yZyI6IFsiZGF5ZHJlYW0uZG1oeS5iZXN0Il0sICJ4aW5neXVuZ2UudG9wIjogWyJ0cmFja2VyLnhpbmd5dW5nZS50b3AiLCAidHJhY2tlci54aW5neXVuZ2Uuc2JzIl0sICJ6bXB0LmNjIjogWyJ6bXB0LmNjIl0sICJoaGFuY2x1Yi50b3AiOiBbInRyYWNrZXIuaGhhbmNsdWIudG9wIl0sICJoZGNpdHkuY2l0eSI6IFsic3luYy5sZW5pdGVyLm9yZyJdfQ==
eyI1MnB0LnNpdGUiOiBbIjUycHQuc2l0ZSJdLCAiYXVkaWVuY2VzLm1lIjogWyJ0LmF1ZGllbmNlcy5tZSIsICJ0cmFja2VyLmNpbmVmaWxlcy5pbmZvIl0sICJidHNjaG9vbC5jbHViIjogWyJwdC5idHNjaG9vbC5jbHViIl0sICJieXIucHQiOiBbInRyYWNrZXIuYnlyLnB0Il0sICJjYXJwdC5uZXQiOiBbInRyYWNrZXIuY2FycHQubmV0Il0sICJjcmFicHQudmlwIjogWyJjcmFicHQudmlwIl0sICJjc3B0LnRvcCI6IFsidHJhY2tlci5jc3B0LnRvcCIsICJ0cmFja2VyLmNzcHQuY2MiLCAidHJhY2tlci5jc3B0LmRhdGUiXSwgImRpc2NmYW4ubmV0IjogWyJkaXNjZmFuLnh5eiJdLCAiZWFzdGdhbWUub3JnIjogWyJwdC5lYXN0Z2FtZS5vcmciXSwgImV0OC5vcmciOiBbImV0OC5vcmciLCAidC5ldDgub3JnIl0sICJnYW1lZ2FtZXB0LmNvbSI6IFsid3d3LmdhbWVnYW1lcHQuY29tIl0sICJoZGFyZWEuY2x1YiI6IFsidHJhY2tlci5oZGFyZWEuY2x1YiJdLCAiaGRkb2xieS5jb20iOiBbInQuaGRkb2xieS5jb20iXSwgImhkZmFucy5vcmciOiBbImhkZmFucy5vcmciXSwgImhka3lsLmluIjogWyJ0cmFja2VyLmhka3lsLmluIiwgInd3dy5oZGt5bGluLnRvcCJdLCAiaGR0aW1lLm9yZyI6IFsiaGR0aW1lLm9yZyJdLCAiaGl0cHQuY29tIjogWyJoaXRwdC5jb20iXSwgImh1ZGJ0Lmh1c3QuZWR1LmNuIjogWyJodWRidC5odXN0LmVkdS5jbiJdLCAiaWNjMjAyMi5jb20iOiBbInRyYWNrZXIuaWNjMjAyMi54eXoiXSwgImlsb2xpY29uLmNvbSI6IFsidHJhY2tlci5pbG9saWNvbi5jYyJdLCAia2VlcGZyZHMuY29tIjogWyJ0cmFja2VyLmtlZXBmcmRzLmNvbSJdLCAibS10ZWFtLmNjIjogWyJ0cmFja2VyLm0tdGVhbS5jYyIsICJ0cmFja2VyLm0tdGVhbS5pbyJdLCAibW9uaWthZGVzaWduLnVrIjogWyJ0cmFja2VyLm1vbmlrYWRlc2lnbi51ayIsICJkYWlraXJhaS5tb25pa2FkZXNpZ24udWsiLCAiYW5pbWUtbm8taW5kZXguY29tIl0sICJuaWNlcHQubmV0IjogWyJ3d3cubmljZXB0Lm5ldCJdLCAib2twdC5uZXQiOiBbInd3dy5va3B0Lm5ldCJdLCAicHRob21lLm5ldCI6IFsicHRob21lLm5ldCJdLCAicHRsZ3Mub3JnIjogWyJwdGwuZ3MiLCAicmVsYXkwMS5wdGwuZ3MiXSwgInB0c2Jhby5jbHViIjogWyJwdHNiYW8uY2x1YiJdLCAicHR0aW1lLm9yZyI6IFsid3d3LnB0dGltZS5vcmciXSwgInB0em9uZS54eXoiOiBbInB0em9uZS54eXoiXSwgInFpbmd3YXB0LmNvbSI6IFsidHJhY2tlci5xaW5nd2EucHJvIiwgInRyYWNrZXIucWluZ3dhcHQuY29tIiwgInRyYWNrZXIucWluZ3dhcHQub3JnIl0sICJyYWluZ2ZoLnRvcCI6IFsicmFpbmdmaC50b3AiXSwgInJvdXNpLnppcCI6IFsiaGl0cHQuY29tIl0sICJzcHJpbmdzdW5kYXkubmV0IjogWyJvbjYuc3ByaW5nc3VuZGF5Lm5ldCIsICJvbi5zcHJpbmdzdW5kYXkubmV0Il0sICJ0anVwdC5vcmciOiBbInRyYWNrZXItcHVibGljLnRqdXB0Lm9yZyJdLCAidG90aGVnbG9yeS5pbSI6IFsidHJhY2tlci50b3RoZWdsb3J5LmltIl0sICJ1Mi5kbWh5Lm9yZyI6IFsiZGF5ZHJlYW0uZG1oeS5iZXN0Il0sICJ4aW5neXVuZ2UudG9wIjogWyJ0cmFja2VyLnhpbmd5dW5nZS50b3AiLCAidHJhY2tlci54aW5neXVuZ2Uuc2JzIl0sICJ6bXB0LmNjIjogWyJ6bXB0LmNjIl0sICJoaGFuY2x1Yi50b3AiOiBbInRyYWNrZXIuaGhhbmNsdWIudG9wIl0sICJoZGNpdHkuY2l0eSI6IFsic3luYy5sZW5pdGVyLm9yZyJdLCAib3VyYml0cy5jbHViIjogWyJvdXJiaXRzLmNsdWIiXX0=