完整 AgentSkill:词库外部化 + 全部脚本/Skill 脱敏上传

- 高危词库从 process.py 抽到 config.toml [security] section
- process.py 改为 _get_high_risk_words() 动态加载(配置优先)
- 新增 15 个 QQ 操作脚本(已脱敏:QQ号/IP/Token → 占位符)
- 新增 8 个 SKILL.md(qq-messenger/management/resolver/napcat-extras 等)
- 新增 SKILL.md 入口(完整部署方案文档)
- 保留 SDK 框架(plugin_modules.py, file_store_api.py, package.py 等)
This commit is contained in:
Claw
2026-05-04 16:23:59 +08:00
parent d7d33c39a4
commit e1fbd31c64
35 changed files with 5058 additions and 276 deletions

121
scripts/mc_world.py Normal file
View File

@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""获取Minecraft世界详细信息(JSON输出)"""
import sys, os, subprocess, re
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from mc_config import RCON_HOST, RCON_PORT, RCON_PASSWORD, MC_SERVER_DIR
from mc_rcon import RCONClient
def get_entity_stats():
try:
with RCONClient(RCON_HOST, RCON_PORT, RCON_PASSWORD) as client:
resp = client.send_command("forge entity list")
body = resp.get("body", "") if resp else ""
if not body:
return {}
m = re.search(r'Total:\s*(\d+)', body)
total = int(m.group(1)) if m else 0
entity_map = {}
for line in body.strip().split("\n")[1:]:
line = line.strip()
em = re.match(r'(\d+):\s*(.+)', line)
if em:
entity_map[em.group(2).strip()] = int(em.group(1))
hostile_types = {"zombie", "skeleton", "creeper", "spider", "enderman", "witch", "slime", "phantom", "husk", "stray", "drowned", "pillager", "vindicator", "evoker", "ravager", "vex", "hoglin", "zoglin", "piglin", "piglin_brute", "wither_skeleton", "blaze", "ghast", "magma_cube", "guardian", "elder_guardian", "shulker", "endermite", "silverfish"}
passive_types = {"sheep", "cow", "pig", "chicken", "horse", "donkey", "mule", "rabbit", "fox", "bee", "cat", "wolf", "parrot", "turtle", "panda", "polar_bear", "llama", "mooshroom", "bat", "squid", "dolphin", "cod", "salmon", "tropical_fish", "pufferfish", "villager", "wandering_trader", "iron_golem", "snow_golem", "frog", "axolotl", "goat", "sniffer", "camel"}
hostile, passive, other = 0, 0, 0
for name, count in entity_map.items():
nl = name.replace("minecraft:", "").lower()
if nl in hostile_types:
hostile += count
elif nl in passive_types:
passive += count
else:
other += count
top = sorted(entity_map.items(), key=lambda x: -x[1])[:5]
return {"total": total, "hostile": hostile, "passive": passive, "other": other, "top": top}
except Exception:
return {}
def get_game_time():
try:
with RCONClient(RCON_HOST, RCON_PORT, RCON_PASSWORD) as client:
resp_day = client.send_command("time query day")
resp_daytime = client.send_command("time query daytime")
body_day = resp_day.get("body", "") if resp_day else ""
body_daytime = resp_daytime.get("body", "") if resp_daytime else ""
m_day = re.search(r'The time is (\d+)', body_day)
m_daytime = re.search(r'The time is (\d+)', body_daytime)
day = int(m_day.group(1)) + 1 if m_day else 1
daytime = int(m_daytime.group(1)) if m_daytime else 0
years = day // 365
months = (day % 365) // 30
days = (day % 365) % 30
hours = int(daytime / 1000)
minutes = int((daytime % 1000) * 60 / 1000)
if 0 <= daytime < 1000:
phase = "日出"
elif 1000 <= daytime < 12000:
phase = "白天"
elif 12000 <= daytime < 13000:
phase = "日落"
elif 13000 <= daytime < 23000:
phase = "夜晚"
else:
phase = "黎明"
return {"day": day, "years": years, "months": months, "days": days, "time": f"{hours:02d}:{minutes:02d}", "phase": phase}
except Exception:
return {}
def get_network_stats():
try:
with open("/proc/net/dev", "r") as f:
lines = f.readlines()
total_rx, total_tx = 0, 0
for line in lines[2:]:
parts = line.strip().split()
if len(parts) >= 10 and not parts[0].startswith("lo:"):
total_rx += int(parts[1])
total_tx += int(parts[9])
def fmt(b):
if b >= 1024**3:
return f"{b/1024**3:.1f}GB"
elif b >= 1024**2:
return f"{b/1024**2:.0f}MB"
elif b >= 1024:
return f"{b/1024:.0f}KB"
return f"{b}B"
return {"rx": fmt(total_rx), "tx": fmt(total_tx)}
except Exception:
return {}
def get_active_mods(limit=3):
log_path = os.path.join(MC_SERVER_DIR, "logs", "debug.log")
if not os.path.exists(log_path):
return []
skip = ["net.minecraft", "net.minecraftforge", "Server thread", "RCON", "Thread", "Generic", "mojang", "java", "sun.", "com.google", "org.apache", "io.netty", "org.mtr", "Mixin", "dev.architectury", "libIPN", "MinecraftMappings", "Yggdrasil", "DataFixer"]
counts = {}
try:
with open(log_path, "r", errors="ignore") as f:
lines = f.readlines()
for line in lines[-2000:]:
m = re.search(r'\[([^\/\]]+)/\]', line)
if not m:
continue
mod = m.group(1)
if any(mod.startswith(s) for s in skip) or len(mod) < 3:
continue
counts[mod] = counts.get(mod, 0) + 1
return [m[0] for m in sorted(counts.items(), key=lambda x: -x[1])[:limit]]
except Exception:
return []
if __name__ == "__main__":
import json
result = {
"entity_stats": get_entity_stats(),
"game_time": get_game_time(),
"network": get_network_stats(),
"active_mods": get_active_mods(),
}
print(json.dumps(result, ensure_ascii=False, indent=2))