码桶
发现社区成员的开源项目
index.js8.9 KB
/**
* 插件:三角洲每日密码(delta-password)
* --------------------------------------------------
* 三角洲行动(Delta Force)各地图每日密码房密码查询。
*
* 命令:
* - 「三角洲」/「三角洲密码」/「今日密码」 → 返回全部地图今日密码汇总(含位置描述)
* - 「三角洲图 <地图名>」 → 发送该地图的位置图片(模糊匹配地图名)
*
* 数据源:https://tmini.net/api/sjzmm (返回纯文本,每天更新一次,缓存 30 分钟)
*/
const axios = require('axios');
const path = require('path');
const fs = require('fs');
const API_URL = 'https://tmini.net/api/sjzmm';
const CACHE_TTL = 30 * 60 * 1000; // 30 分钟缓存
const TMP_DIR = path.join(__dirname, '..', '..', 'data', 'tmp');
let cache = null; // { data: { updateDate, maps }, time: timestamp }
// 解析接口返回的纯文本为结构化数据
function parsePasswords(text) {
const lines = String(text).split(/\r?\n/);
let updateDate = '';
const maps = [];
let cur = null;
let imgMode = false;
for (const raw of lines) {
const line = raw.trim();
if (!line) continue;
if (line.startsWith('更新日期')) { updateDate = line.replace(/^更新日期[::]?/, '').replace(/每日密码已更新$/, '').trim(); continue; }
if (line.startsWith('密码总数')) { imgMode = false; continue; }
if (line.startsWith('---')) { imgMode = false; continue; }
if (line.startsWith('地图名称')) {
cur = { name: line.replace(/^地图名称[::]?/, '').trim(), pwd: '', desc: '', images: [] };
maps.push(cur);
imgMode = false;
continue;
}
if (!cur) continue;
if (line.startsWith('密码')) { cur.pwd = line.replace(/^密码[::]?/, '').trim(); continue; }
if (line.startsWith('位置描述')) { cur.desc = line.replace(/^位置描述[::]?/, '').trim(); continue; }
if (line.startsWith('位置图片')) { imgMode = true; continue; }
if (imgMode) {
const m = line.match(/https?:\/\/\S+/);
if (m) cur.images.push(m[0]);
continue;
}
}
return { updateDate, maps };
}
async function fetchData() {
if (cache && Date.now() - cache.time < CACHE_TTL) return cache.data;
const { data } = await axios.get(API_URL, {
timeout: 12000,
responseType: 'text',
headers: { 'User-Agent': 'Mozilla/5.0 (compatible; DeltaBot/1.0)' },
});
const parsed = parsePasswords(data);
if (!parsed.maps.length) throw new Error('接口无数据');
cache = { data: parsed, time: Date.now() };
return parsed;
}
// 拼装密码汇总文本
function buildText({ updateDate, maps }) {
const lines = [];
lines.push('🎯 三角洲行动 · 今日密码');
if (updateDate) lines.push('📅 ' + updateDate);
lines.push('');
for (const m of maps) {
lines.push(`【${m.name}】密码:${m.pwd}`);
if (m.desc) lines.push(' ' + m.desc);
lines.push('');
}
lines.push('———');
lines.push('发送「三角洲图 地图名」查看位置图(如:三角洲图 零号大坝)');
return lines.join('\n').trim();
}
// 地图别名,用于自然语言里按关键词匹配具体地图
const MAP_ALIASES = [
{ keys: ['航天基地', '航天'], name: '航天基地' },
{ keys: ['零号大坝', '零号', '大坝'], name: '零号大坝' },
{ keys: ['长弓溪谷', '长弓', '溪谷'], name: '长弓溪谷' },
{ keys: ['AZ3', 'az3', '核电站'], name: 'AZ3核电站' },
{ keys: ['巴克什'], name: '巴克什' },
{ keys: ['彩六', '联动房'], name: '彩六联动房' },
{ keys: ['潮汐', '监狱'], name: '潮汐监狱' },
];
function findMap(text, maps) {
// 先按别名关键词匹配
for (const a of MAP_ALIASES) {
if (a.keys.some((k) => text.includes(k))) {
const hit = maps.find((m) => m.name === a.name)
|| maps.find((m) => m.name.includes(a.name) || a.name.includes(m.name));
if (hit) return hit;
}
}
// 再按地图全名匹配
return maps.find((m) => text.includes(m.name)) || null;
}
// 下载图片到临时目录并发送,发送后清理
async function sendImages(ctx, urls) {
if (!fs.existsSync(TMP_DIR)) fs.mkdirSync(TMP_DIR, { recursive: true });
for (let i = 0; i < urls.length; i++) {
const url = urls[i];
let tmpPath = '';
try {
const ext = (url.split('?')[0].split('.').pop() || 'jpg').toLowerCase();
const safeExt = /^(jpg|jpeg|png|gif|webp)$/.test(ext) ? ext : 'jpg';
tmpPath = path.join(TMP_DIR, 'delta_' + Date.now() + '_' + i + '.' + safeExt);
const resp = await axios.get(url, {
timeout: 15000,
responseType: 'arraybuffer',
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' },
});
const buf = Buffer.from(resp.data);
if (buf.length < 100) continue;
fs.writeFileSync(tmpPath, buf);
await ctx.sendMedia(tmpPath, 'image');
} catch (e) {
console.warn('[delta-password] 图片发送失败:', url, e.message);
} finally {
if (tmpPath) { try { fs.unlinkSync(tmpPath); } catch (_) {} }
}
}
}
module.exports = {
meta: {
id: 'delta-password',
name: '三角洲每日密码',
version: '1.0.0',
author: '奶狗',
category: '信息获取',
description: '发送「三角洲」查询三角洲行动各地图今日密码房密码;「三角洲图 地图名」查看位置图。也支持自然语言,如「看一下航天基地密码」。',
entry: 'delta-password/index.js',
configurable: false,
commandPrefix: ['三角洲', '今日密码'],
// 柔性匹配:含「密码」的自然语言(如「看一下航天基地密码」)也让位给本插件,不走 AI
commandMatch: '三角洲|今日密码|密码',
},
async onMessage(msg, ctx) {
const text = (msg.content || '').trim();
// 1) 查看位置图:三角洲图 <地图名> / 图 <地图名> / <地图名>图
let imgQ = null;
const m1 = text.match(/^三角洲图\s*(.+)$/);
if (m1) imgQ = m1[1].trim();
else if (text.startsWith('图 ')) imgQ = text.slice(2).trim();
else {
const m3 = text.match(/^(.+?)图$/);
if (m3) imgQ = m3[1].trim();
}
if (imgQ) {
if (!imgQ) { await ctx.sendText('用法:三角洲图 地图名(如:三角洲图 零号大坝)'); return true; }
try {
const data = await fetchData();
const hit = data.maps.find((m) => m.name === imgQ)
|| data.maps.find((m) => m.name.includes(imgQ) || imgQ.includes(m.name));
if (!hit) {
await ctx.sendText('未找到地图「' + imgQ + '」。可选:' + data.maps.map((m) => m.name).join('、'));
return true;
}
if (!hit.images.length) {
await ctx.sendText('【' + hit.name + '】密码:' + hit.pwd + '\n暂无位置图片。' + (hit.desc ? '\n' + hit.desc : ''));
return true;
}
await ctx.sendText('【' + hit.name + '】密码:' + hit.pwd + (hit.desc ? '\n' + hit.desc : ''));
await sendImages(ctx, hit.images);
} catch (e) {
console.error('[delta-password] 出错:', e.message);
await ctx.sendText('三角洲密码获取失败,请稍后再试。');
}
return true;
}
// 2) 查询全部密码汇总
if (text === '三角洲' || text === '三角洲密码' || text === '今日密码' || text === '三角洲行动') {
try {
const data = await fetchData();
await ctx.sendText(buildText(data));
} catch (e) {
console.error('[delta-password] 出错:', e.message);
await ctx.sendText('三角洲密码获取失败,请稍后再试。');
}
return true;
}
// 3) 自然语言密码查询:含「密码」二字(如「看一下航天基地密码」「航天基地的密码是多少」)
if (text.includes('密码')) {
try {
const data = await fetchData();
const hit = findMap(text, data.maps);
const wantsImg = text.includes('图');
if (hit) {
let out = `【${hit.name}】密码:${hit.pwd}`;
if (hit.desc) out += '\n' + hit.desc;
if (wantsImg && hit.images.length) {
await ctx.sendText(out);
await sendImages(ctx, hit.images);
return true;
}
if (hit.images.length) out += '\n(发送「三角洲图 ' + hit.name + '」可查看位置图)';
await ctx.sendText(out);
} else {
await ctx.sendText(buildText(data));
}
} catch (e) {
console.error('[delta-password] 出错:', e.message);
await ctx.sendText('三角洲密码获取失败,请稍后再试。');
}
return true;
}
return false;
},
// 导出解析函数(便于单测/调试;插件系统只读 meta/onMessage)
parsePasswords,
};