refactor: restructure plugins per MTSS standard, consolidate assets to res/
Per docs/plugin-audit-report.md (plugins normalized to Trigger(handlers) → Service(services) → Model(repository/models) + utils): - Split monolithic __init__.py into handlers/services/utils across dailywife, deer_pipe, dice, galgame_card, helldivers_tools, huoziyinshua, learning_chat, makeaquote, mc_server_status, ncm_saying, picfinder_take, picstatus, random_jm_code, regif, steam_info, video_analysis, group_tools - Move static assets under res/: deer_pipe font/img, makeaquote font, helldivers img/templates, huoziyinshua HuoZiYinShua - Add config.py + register_config_items to ncm_saying, random_jm_code, group_tools; learning_chat unified config bridge - Remove deprecated: voice_trans plugin, bf_bot/test.py, dead code in dailywife/deer_pipe, empty dirs, debug scripts under helldivers temp - Disable brash_general_supercredits_tools (stub comment only) - bot.py: optional stdout/stderr redirect to log file for Web log viewer, force ANSI colorize on non-TTY sinks - Move runtime data (jm_code.json) out of plugin dir into hexi/data - Docs: plugin-audit-report.md; README reflects removed plugins Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,22 +1,9 @@
|
||||
import json
|
||||
import random
|
||||
import json
|
||||
import random
|
||||
import asyncio
|
||||
import os
|
||||
from typing import List
|
||||
"""随机 JM 码 —— 入口(元数据 + 配置注册)。"""
|
||||
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, PokeNotifyEvent, Message
|
||||
from nonebot.plugin.on import on_notice, on_command
|
||||
from nonebot import on_type, on_message, logger
|
||||
from nonebot.adapters import Event
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_alconna import UniMessage, get_target
|
||||
from nonebot import require
|
||||
from nonebot.plugin import PluginMetadata
|
||||
|
||||
from hexi.plugins.nonebot_plugin_hexi_core.message_utils import send_poke
|
||||
require("nonebot_plugin_alconna")
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="随机JM码",
|
||||
@@ -25,127 +12,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
type="application",
|
||||
)
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
FILE_PATH = os.path.join(BASE_DIR, "jm_code.json")
|
||||
from . import config as _config # noqa: E402
|
||||
from . import handlers as _handlers # noqa: E402
|
||||
|
||||
TEXT_TEMPLATES = [
|
||||
"给你{code},拿去吧",
|
||||
"给你{code},记得谢谢我",
|
||||
"给你{code},注意保养弹簧"
|
||||
]
|
||||
BLOCK_CODE = ["350235", "350234"]
|
||||
|
||||
WHITE_LIST = ["1019165018"]
|
||||
|
||||
jm_handler = on_notice(priority=10, block=False, rule=to_me())
|
||||
|
||||
add_jm_code = on_command("jm", rule=to_me())
|
||||
|
||||
|
||||
@add_jm_code.handle()
|
||||
async def add_more_jm_code(event: Event, matcher: Matcher):
|
||||
input_code = event.get_message().extract_plain_text().strip()
|
||||
cmd = matcher.state["_prefix"]["command"][0]
|
||||
input_code = input_code.replace(cmd, "")
|
||||
if input_code in BLOCK_CODE:
|
||||
await UniMessage.at(event.get_user_id()).text(" 不准发石!!").send()
|
||||
return
|
||||
await add_new_jm_code(input_code)
|
||||
await UniMessage.reply(event.get_user_id()).text(" 添加成功").send()
|
||||
return
|
||||
|
||||
|
||||
@jm_handler.handle()
|
||||
async def random_jm_code(event: Event, poke_event: PokeNotifyEvent):
|
||||
user_id = event.get_user_id()
|
||||
logger.info(f"{user_id}触发了戳一戳")
|
||||
target = get_target(event)
|
||||
group_id = target.parent_id or target.id or poke_event.group_id
|
||||
logger.info(f"触发戳一戳的群聊:{group_id}")
|
||||
if group_id in WHITE_LIST:
|
||||
logger.info(f"白名单:{group_id}")
|
||||
choice = random.randint(0, 100)
|
||||
logger.info(f"触发概率:{choice}")
|
||||
if choice >= 50:
|
||||
await poke_reply(event)
|
||||
else:
|
||||
logger.info("不做操作")
|
||||
|
||||
else:
|
||||
logger.info(f"不在白名单:{group_id}")
|
||||
if target.private:
|
||||
group_id = None
|
||||
result = await send_poke(group_id=group_id, user_id=user_id)
|
||||
logger.info(result)
|
||||
return
|
||||
|
||||
|
||||
async def poke_reply(event: Event):
|
||||
user_id = event.get_user_id()
|
||||
jm_message = await get_random_jm_code()
|
||||
await UniMessage.at(user_id).text(" " + jm_message).send()
|
||||
|
||||
|
||||
JM_CODES: List[int] = []
|
||||
_LOADED = False
|
||||
LOCK = asyncio.Lock()
|
||||
|
||||
|
||||
def _safe_write_json(data, file_path: str):
|
||||
tmp_path = file_path + ".tmp"
|
||||
|
||||
with open(tmp_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 原子替换(防止写一半崩溃)
|
||||
os.replace(tmp_path, file_path)
|
||||
|
||||
|
||||
async def load_codes(file_path: str = FILE_PATH):
|
||||
global JM_CODES, _LOADED
|
||||
|
||||
if _LOADED:
|
||||
return
|
||||
|
||||
async with LOCK:
|
||||
if _LOADED:
|
||||
return
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
JM_CODES = []
|
||||
_safe_write_json(JM_CODES, file_path)
|
||||
else:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
try:
|
||||
JM_CODES = json.load(f)
|
||||
except json.JSONDecodeError:
|
||||
# 文件损坏时兜底
|
||||
JM_CODES = []
|
||||
|
||||
_LOADED = True
|
||||
|
||||
|
||||
async def get_random_jm_code() -> str:
|
||||
await load_codes()
|
||||
|
||||
if not JM_CODES:
|
||||
return "暂无可用代码"
|
||||
|
||||
code = random.choice(JM_CODES)
|
||||
logger.info(f"随机JM:{code}")
|
||||
template = random.choice(TEXT_TEMPLATES)
|
||||
|
||||
return template.format(code=code)
|
||||
|
||||
|
||||
async def add_new_jm_code(new_code: int) -> bool:
|
||||
await load_codes()
|
||||
|
||||
async with LOCK:
|
||||
if new_code in JM_CODES:
|
||||
return False # 已存在
|
||||
|
||||
JM_CODES.append(new_code)
|
||||
_safe_write_json(JM_CODES, FILE_PATH)
|
||||
|
||||
return True
|
||||
_config.register_config()
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
"""随机 JM 码 —— 配置注册(按《插件配置文件标准》)。
|
||||
|
||||
把原本硬编码在 __init__.py 里的文案模板 / 屏蔽码 / 白名单群号
|
||||
注册为 Web 可读可改的配置项(来源无关,store=本模块)。运行期插件读本模块常量,
|
||||
Web 保存后经 apply 热更新本模块属性,重启也不丢。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys as _sys
|
||||
|
||||
from hexi.config_standard import register_config_items
|
||||
|
||||
# plugin_id = NoneBot 插件模块名
|
||||
_PLUGIN_ID = __package__
|
||||
|
||||
# —— 可配置常量(来源为本模块) ——
|
||||
TEXT_TEMPLATES = [
|
||||
"给你{code},拿去吧",
|
||||
"给你{code},记得谢谢我",
|
||||
"给你{code},注意保养弹簧",
|
||||
]
|
||||
BLOCK_CODE = ["350235", "350234"]
|
||||
WHITE_LIST = ["1019165018"]
|
||||
|
||||
|
||||
def register_config() -> None:
|
||||
register_config_items(
|
||||
_PLUGIN_ID,
|
||||
[
|
||||
{
|
||||
"key": "TEXT_TEMPLATES",
|
||||
"label": "随机文案模板",
|
||||
"type": "text",
|
||||
"item_type": "str",
|
||||
"default": TEXT_TEMPLATES,
|
||||
},
|
||||
{
|
||||
"key": "BLOCK_CODE",
|
||||
"label": "屏蔽码",
|
||||
"type": "text",
|
||||
"item_type": "str",
|
||||
"default": BLOCK_CODE,
|
||||
},
|
||||
{
|
||||
"key": "WHITE_LIST",
|
||||
"label": "白名单群号",
|
||||
"type": "text",
|
||||
"item_type": "str",
|
||||
"default": WHITE_LIST,
|
||||
},
|
||||
],
|
||||
store=_sys.modules[__name__],
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
"""随机 JM 码 —— Trigger 层。"""
|
||||
|
||||
from .jm import add_jm_code, jm_handler # noqa: F401
|
||||
@@ -0,0 +1,72 @@
|
||||
"""随机 JM 码 —— 触发器(Trigger)层。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
|
||||
from nonebot import logger
|
||||
from nonebot.adapters import Event
|
||||
from nonebot.adapters.onebot.v11 import PokeNotifyEvent
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.plugin.on import on_notice, on_command
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_alconna import UniMessage, get_target
|
||||
|
||||
from hexi.plugins.nonebot_plugin_hexi_core.message_utils import send_poke
|
||||
|
||||
from .. import config as _cfg
|
||||
from ..services.store import add_new_jm_code, get_random_jm_code
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="随机JM码",
|
||||
description="随机发送JM码,支持添加与屏蔽",
|
||||
usage="@bot 触发随机JM码;jm 添加JM码",
|
||||
type="application",
|
||||
)
|
||||
|
||||
jm_handler = on_notice(priority=10, block=False, rule=to_me())
|
||||
add_jm_code = on_command("jm", rule=to_me())
|
||||
|
||||
|
||||
@add_jm_code.handle()
|
||||
async def add_more_jm_code(event: Event, matcher: Matcher):
|
||||
input_code = event.get_message().extract_plain_text().strip()
|
||||
cmd = matcher.state["_prefix"]["command"][0]
|
||||
input_code = input_code.replace(cmd, "")
|
||||
if input_code in _cfg.BLOCK_CODE:
|
||||
await UniMessage.at(event.get_user_id()).text(" 不准发石!!").send()
|
||||
return
|
||||
await add_new_jm_code(input_code)
|
||||
await UniMessage.reply(event.get_user_id()).text(" 添加成功").send()
|
||||
return
|
||||
|
||||
|
||||
@jm_handler.handle()
|
||||
async def random_jm_code(event: Event, poke_event: PokeNotifyEvent):
|
||||
user_id = event.get_user_id()
|
||||
logger.info(f"{user_id}触发了戳一戳")
|
||||
target = get_target(event)
|
||||
group_id = target.parent_id or target.id or poke_event.group_id
|
||||
logger.info(f"触发戳一戳的群聊:{group_id}")
|
||||
if group_id in _cfg.WHITE_LIST:
|
||||
logger.info(f"白名单:{group_id}")
|
||||
choice = random.randint(0, 100)
|
||||
logger.info(f"触发概率:{choice}")
|
||||
if choice >= 50:
|
||||
await poke_reply(event)
|
||||
else:
|
||||
logger.info("不做操作")
|
||||
else:
|
||||
logger.info(f"不在白名单:{group_id}")
|
||||
if target.private:
|
||||
group_id = None
|
||||
result = await send_poke(group_id=group_id, user_id=user_id)
|
||||
logger.info(result)
|
||||
return
|
||||
|
||||
|
||||
async def poke_reply(event: Event):
|
||||
user_id = event.get_user_id()
|
||||
jm_message = await get_random_jm_code()
|
||||
await UniMessage.at(user_id).text(" " + jm_message).send()
|
||||
@@ -1,286 +0,0 @@
|
||||
[
|
||||
"219",
|
||||
"224",
|
||||
"759",
|
||||
"877",
|
||||
"878",
|
||||
"2057",
|
||||
"2388",
|
||||
"2868",
|
||||
"4333",
|
||||
"6102",
|
||||
"6411",
|
||||
"18212",
|
||||
"20106",
|
||||
"20348",
|
||||
"20902",
|
||||
"21274",
|
||||
"21407",
|
||||
"21994",
|
||||
"22392",
|
||||
"27512",
|
||||
"27701",
|
||||
"28650",
|
||||
"33775",
|
||||
"39509",
|
||||
"46555",
|
||||
"47729",
|
||||
"50514",
|
||||
"54747",
|
||||
"55427",
|
||||
"58267",
|
||||
"61257",
|
||||
"62268",
|
||||
"69354",
|
||||
"73451",
|
||||
"74891",
|
||||
"77778",
|
||||
"78665",
|
||||
"80358",
|
||||
"85055",
|
||||
"86779",
|
||||
"89218",
|
||||
"98509",
|
||||
"98669",
|
||||
"101792",
|
||||
"104738",
|
||||
"105854",
|
||||
"107184",
|
||||
"114445",
|
||||
"116157",
|
||||
"122333",
|
||||
"122427",
|
||||
"124116",
|
||||
"124561",
|
||||
"125237",
|
||||
"127282",
|
||||
"135697",
|
||||
"138809",
|
||||
"140620",
|
||||
"142464",
|
||||
"142568",
|
||||
"145289",
|
||||
"148486",
|
||||
"148624",
|
||||
"149578",
|
||||
"149906",
|
||||
"151607",
|
||||
"151696",
|
||||
"181107",
|
||||
"181611",
|
||||
"190447",
|
||||
"192957",
|
||||
"203446",
|
||||
"207063",
|
||||
"209232",
|
||||
"218796",
|
||||
"220455",
|
||||
"220995",
|
||||
"220996",
|
||||
"221659",
|
||||
"223153",
|
||||
"224879",
|
||||
"225764",
|
||||
"230702",
|
||||
"230806",
|
||||
"231692",
|
||||
"235366",
|
||||
"239642",
|
||||
"239797",
|
||||
"241726",
|
||||
"245189",
|
||||
"247044",
|
||||
"248646",
|
||||
"249121",
|
||||
"251050",
|
||||
"255015",
|
||||
"258778",
|
||||
"263104",
|
||||
"265236",
|
||||
"266615",
|
||||
"268453",
|
||||
"269417",
|
||||
"271249",
|
||||
"273943",
|
||||
"278032",
|
||||
"281142",
|
||||
"284185",
|
||||
"285994",
|
||||
"290391",
|
||||
"291407",
|
||||
"293593",
|
||||
"293867",
|
||||
"303683",
|
||||
"305291",
|
||||
"305428",
|
||||
"306326",
|
||||
"306848",
|
||||
"308472",
|
||||
"308595",
|
||||
"310176",
|
||||
"318730",
|
||||
"318731",
|
||||
"322028",
|
||||
"326357",
|
||||
"329995",
|
||||
"333722",
|
||||
"334554",
|
||||
"343898",
|
||||
"346346",
|
||||
"346862",
|
||||
"352727",
|
||||
"355019",
|
||||
"355659",
|
||||
"362197",
|
||||
"362460",
|
||||
"368639",
|
||||
"368837",
|
||||
"369504",
|
||||
"370634",
|
||||
"371570",
|
||||
"371631",
|
||||
"371875",
|
||||
"373099",
|
||||
"374495",
|
||||
"377532",
|
||||
"380052",
|
||||
"382336",
|
||||
"384297",
|
||||
"385372",
|
||||
"389479",
|
||||
"390353",
|
||||
"392326",
|
||||
"394523",
|
||||
"395280",
|
||||
"395281",
|
||||
"397150",
|
||||
"397478",
|
||||
"398569",
|
||||
"401496",
|
||||
"401574",
|
||||
"409658",
|
||||
"409896",
|
||||
"410841",
|
||||
"411613",
|
||||
"412004",
|
||||
"415513",
|
||||
"417463",
|
||||
"427706",
|
||||
"429322",
|
||||
"433023",
|
||||
"434797",
|
||||
"434801",
|
||||
"435777",
|
||||
"441189",
|
||||
"441594",
|
||||
"442137",
|
||||
"443170",
|
||||
"445794",
|
||||
"448098",
|
||||
"451603",
|
||||
"451610",
|
||||
"452501",
|
||||
"452699",
|
||||
"453931",
|
||||
"454803",
|
||||
"465335",
|
||||
"467110",
|
||||
"467180",
|
||||
"468624",
|
||||
"469738",
|
||||
"471872",
|
||||
"472952",
|
||||
"475378",
|
||||
"476677",
|
||||
"477029",
|
||||
"477990",
|
||||
"478437",
|
||||
"479907",
|
||||
"480142",
|
||||
"480841",
|
||||
"481536",
|
||||
"481979",
|
||||
"482542",
|
||||
"484683",
|
||||
"485647",
|
||||
"485870",
|
||||
"486253",
|
||||
"487798",
|
||||
"488125",
|
||||
"495051",
|
||||
"495256",
|
||||
"498750",
|
||||
"501638",
|
||||
"501838",
|
||||
"502132",
|
||||
"505048",
|
||||
"505241",
|
||||
"505253",
|
||||
"505484",
|
||||
"507975",
|
||||
"508253",
|
||||
"509489",
|
||||
"509834",
|
||||
"511010",
|
||||
"513984",
|
||||
"515569",
|
||||
"517500",
|
||||
"523276",
|
||||
"524360",
|
||||
"527354",
|
||||
"529468",
|
||||
"533458",
|
||||
"533552",
|
||||
"537119",
|
||||
"541285",
|
||||
"541762",
|
||||
"542252",
|
||||
"543247",
|
||||
"543525",
|
||||
"543749",
|
||||
"544360",
|
||||
"544401",
|
||||
"545733",
|
||||
"547590",
|
||||
"549168",
|
||||
"550176",
|
||||
"552312",
|
||||
"554413",
|
||||
"563746",
|
||||
"608258",
|
||||
"1020570",
|
||||
"1060990",
|
||||
"1071423",
|
||||
"1176067",
|
||||
"1190464",
|
||||
"1193587",
|
||||
"1196804",
|
||||
"1202415",
|
||||
"1206636",
|
||||
"1212262",
|
||||
"1212643",
|
||||
"1215962",
|
||||
"1216628",
|
||||
"1217450",
|
||||
"1222299",
|
||||
"1222320",
|
||||
"1222393",
|
||||
"1223363",
|
||||
"1224091",
|
||||
"1224493",
|
||||
"2904551",
|
||||
"3037141",
|
||||
"3157283",
|
||||
"3300062",
|
||||
"3481682",
|
||||
"3918941",
|
||||
"3921012",
|
||||
"4214502",
|
||||
"4283473",
|
||||
"4283484",
|
||||
"4366352",
|
||||
"4380002",
|
||||
"5430811",
|
||||
"1434077",
|
||||
"1423811"
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
"""随机 JM 码 —— Service 层。"""
|
||||
|
||||
from .store import add_new_jm_code, get_random_jm_code # noqa: F401
|
||||
@@ -0,0 +1,74 @@
|
||||
"""随机 JM 码 —— 数据访问(Service 层)。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from .. import config as _cfg
|
||||
|
||||
# 运行时数据统一放 hexi/data
|
||||
_DATA_DIR = Path(__file__).resolve().parents[3] / "data" / "random_jm_code"
|
||||
FILE_PATH = _DATA_DIR / "jm_code.json"
|
||||
_LEGACY_FILE = Path(__file__).resolve().parents[1] / "jm_code.json"
|
||||
|
||||
JM_CODES: List[int] = []
|
||||
_LOADED = False
|
||||
LOCK = asyncio.Lock()
|
||||
|
||||
|
||||
def _migrate_legacy() -> None:
|
||||
if not FILE_PATH.exists() and _LEGACY_FILE.exists():
|
||||
_DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
os.replace(_LEGACY_FILE, FILE_PATH)
|
||||
|
||||
|
||||
def _safe_write_json(data, file_path: Path):
|
||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
tmp_path = file_path.with_suffix(".tmp")
|
||||
with open(tmp_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
os.replace(tmp_path, file_path)
|
||||
|
||||
|
||||
async def load_codes(file_path: Path = FILE_PATH):
|
||||
global JM_CODES, _LOADED
|
||||
if _LOADED:
|
||||
return
|
||||
async with LOCK:
|
||||
if _LOADED:
|
||||
return
|
||||
_migrate_legacy()
|
||||
if not file_path.exists():
|
||||
JM_CODES = []
|
||||
_safe_write_json(JM_CODES, file_path)
|
||||
else:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
try:
|
||||
JM_CODES = json.load(f)
|
||||
except json.JSONDecodeError:
|
||||
JM_CODES = []
|
||||
_LOADED = True
|
||||
|
||||
|
||||
async def get_random_jm_code() -> str:
|
||||
await load_codes()
|
||||
if not JM_CODES:
|
||||
return "暂无可用代码"
|
||||
code = random.choice(JM_CODES)
|
||||
template = random.choice(_cfg.TEXT_TEMPLATES)
|
||||
return template.format(code=code)
|
||||
|
||||
|
||||
async def add_new_jm_code(new_code: int) -> bool:
|
||||
await load_codes()
|
||||
async with LOCK:
|
||||
if new_code in JM_CODES:
|
||||
return False
|
||||
JM_CODES.append(new_code)
|
||||
_safe_write_json(JM_CODES, FILE_PATH)
|
||||
return True
|
||||
Reference in New Issue
Block a user