koishi-plugin-toram
Version:
1,024 lines (1,005 loc) • 37.7 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name2 in all)
__defProp(target, name2, { get: all[name2], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
Config: () => Config,
apply: () => apply,
inject: () => inject,
name: () => name
});
module.exports = __toCommonJS(src_exports);
var import_koishi = require("koishi");
// src/script/TalkMgr.ts
var _TalkMgr = class _TalkMgr {
constructor() {
this.bot = null;
this._talks = /* @__PURE__ */ new Map();
}
static Inst() {
if (!_TalkMgr.instance) {
_TalkMgr.instance = new _TalkMgr();
}
return _TalkMgr.instance;
}
setBot(bot) {
this.bot = bot;
}
setTalks() {
const data = JsonMgr.Inst().getJson("talks.json");
Object.keys(data).forEach((key) => {
this._talks.set(key, data[key]);
});
}
genTalk(talkType, args) {
const talkList = this._talks.get(talkType);
let talk = talkList[Math.floor(Math.random() * talkList.length)];
if (args) Object.keys(args).forEach((key) => talk = talk.replace(`${key}_@`, args[key]));
return talk;
}
reply(event, talkType, args) {
const talk = this.genTalk(talkType, args);
event.session.send(talk);
}
send(targetId, talkType, args) {
const talk = this.genTalk(talkType, args);
this.bot?.sendMessage(targetId, talk);
}
};
__name(_TalkMgr, "TalkMgr");
_TalkMgr.instance = null;
var TalkMgr = _TalkMgr;
// src/script/ResultClass.ts
var _Result = class _Result {
constructor(code, result) {
this.code = 1001 /* 通过 */;
this.code = code;
if (result !== void 0) this.result = result;
}
};
__name(_Result, "Result");
var Result = _Result;
// src/script/JsonMgr.ts
var import_promises = __toESM(require("fs/promises"));
var import_path = __toESM(require("path"));
var _JsonMgr = class _JsonMgr {
constructor() {
this._json = /* @__PURE__ */ new Map();
this._logger = null;
}
static Inst() {
if (!_JsonMgr.instance) {
_JsonMgr.instance = new _JsonMgr();
}
return _JsonMgr.instance;
}
/**
* 异步获取 ./external/toram/src/json 目录下的所有JSON文件,并将其内容解析后存储到内部的Map对象中。
* 该方法会遍历指定目录下的所有文件,筛选出扩展名为.json的文件,然后读取每个文件的内容,
* 将其解析为JavaScript对象,并以文件名作为键,解析后的对象作为值存储在内部的Map对象中。
* 如果在读取文件或解析JSON时发生错误,将在控制台输出错误信息。
*/
async loadJson() {
const arr = __dirname.split("\\");
if (arr[arr.length - 1] !== "lib") arr.pop();
arr.push("json");
const pathWay = arr.join("\\");
this._logger.info(pathWay);
try {
const files = await import_promises.default.readdir(pathWay);
const jsonFiles = files.filter((file) => import_path.default.extname(file).toLowerCase() === ".json");
for (const file of jsonFiles) {
const filePath = import_path.default.join(pathWay, file);
try {
const data = await import_promises.default.readFile(filePath, "utf-8");
this._json.set(file, JSON.parse(data));
} catch (readErr) {
console.error(`Error reading file ${filePath}:`, readErr);
}
}
} catch (err) {
console.error(`Error reading directory ${pathWay}:`, err);
}
}
/**
* 根据指定的名称从内部的Map对象中获取对应的JSON数据。
* 该方法会在内部的Map对象中查找与给定名称匹配的键,并返回对应的值。
* 如果找不到匹配的键,则返回undefined。
* @param name - 要获取的JSON数据的名称,通常是文件名(不包括扩展名)。
* @returns 返回与指定名称对应的JSON数据,如果找不到则打印log并返回null。
*/
getJson(name2) {
const result = this._json.get(name2);
if (result) {
return result;
} else {
this._logger.error(`未找到${name2}`);
return null;
}
}
/**
* 设置日志记录器实例,用于记录JsonMgr类的操作日志。
* 该方法允许外部传入一个Logger实例,以便在JsonMgr类的各个方法中使用该实例进行日志记录。
* @param logger - 一个Logger实例,用于记录日志。
*/
setLogger(logger) {
this._logger = logger;
}
/** 保存json */
async saveJson(name2, data) {
if (!data) data = this._json.get(name2);
const arr = __dirname.split("\\");
if (arr[arr.length - 1] !== "lib") arr.pop();
arr.push("json");
const pathWay = arr.join("\\");
const filePath = import_path.default.join(pathWay, "", name2);
const jsonString = JSON.stringify(data, null, 2);
try {
await import_promises.default.writeFile(filePath, jsonString, "utf8");
this._logger.info("JSON 文件已保存!");
} catch (err) {
this._logger.error("保存文件时出错:", err);
}
}
};
__name(_JsonMgr, "JsonMgr");
_JsonMgr.instance = null;
var JsonMgr = _JsonMgr;
// src/script/botFunction/monthlyCardReminder.ts
var MONTHLY_CARD_REMINDER_TYPE = "monthly-card-reminder";
async function scheduleMonthlyCardReminders(groupId, hours) {
const now = /* @__PURE__ */ new Date();
for (let i = 0; i < hours.length; i++) {
const hour = hours[i];
const next = new Date(now);
next.setHours(hour, 10, 0, 0);
if (next.getTime() <= now.getTime()) next.setDate(next.getDate() + 1);
const ts = next.getTime();
const exists = (BotTodoMgr.Inst().getTodosAt(ts) || []).some(
(x) => x.type === MONTHLY_CARD_REMINDER_TYPE && x.payload?.groupId === groupId && x.payload?.timeIndex === i
);
if (!exists) {
await BotTodoMgr.Inst().addTodo(ts, MONTHLY_CARD_REMINDER_TYPE, { groupId, timeIndex: i });
}
}
}
__name(scheduleMonthlyCardReminders, "scheduleMonthlyCardReminders");
function executeMonthlyCardReminder(item) {
const payload = item.payload || {};
const groupId = payload.groupId;
const timeIndex = payload.timeIndex;
if (!groupId || typeof timeIndex !== "number") return;
const atUsers = genMonthlyCardReminderUsers(timeIndex);
if (atUsers) {
TalkMgr.Inst().send(groupId, "月卡提醒", { atUsers });
}
const next = new Date(item.ts + 24 * 60 * 60 * 1e3);
const hour = new Date(item.ts).getHours();
next.setHours(hour, 10, 0, 0);
const nextTs = next.getTime();
const exists = (BotTodoMgr.Inst().getTodosAt(nextTs) || []).some(
(x) => x.type === MONTHLY_CARD_REMINDER_TYPE && x.payload?.groupId === groupId && x.payload?.timeIndex === timeIndex
);
if (!exists) {
BotTodoMgr.Inst().addTodo(nextTs, MONTHLY_CARD_REMINDER_TYPE, { groupId, timeIndex });
}
}
__name(executeMonthlyCardReminder, "executeMonthlyCardReminder");
function genMonthlyCardReminderUsers(timeIndex) {
const users = UserMgr.Inst().getUsersWithMonthlyCardRemindTimeIndex(timeIndex);
if (users.length === 0) return;
const atUsers = users.map((user) => `<at id="${user.qq}"/>`).join(" ");
return atUsers;
}
__name(genMonthlyCardReminderUsers, "genMonthlyCardReminderUsers");
// src/script/botFunction/allMemberReminder.ts
var ALL_MEMBER_REMINDER_TYPE = "all-member-reminder";
function genAtAllMessage(content) {
const atAll = `<at id="all"/>`;
return content ? `${atAll} ${content}` : atAll;
}
__name(genAtAllMessage, "genAtAllMessage");
function executeAllMemberReminder(item) {
const payload = item.payload || {};
const groupId = payload.groupId;
const content = payload.content;
if (!groupId) return;
const message = genAtAllMessage(content || "");
TalkMgr.Inst().send(groupId, "简易回复", { result: message });
}
__name(executeAllMemberReminder, "executeAllMemberReminder");
// src/script/botFunction/monthlyCardFinalReminder.ts
var MONTHLY_CARD_FINAL_REMINDER_TYPE = "monthly-card-final-reminder";
async function scheduleMonthlyCardFinalReminder(groupId) {
const now = /* @__PURE__ */ new Date();
const next = new Date(now);
next.setHours(23, 30, 0, 0);
if (next.getTime() <= now.getTime()) next.setDate(next.getDate() + 1);
const ts = next.getTime();
const exists = (BotTodoMgr.Inst().getTodosAt(ts) || []).some(
(x) => x.type === MONTHLY_CARD_FINAL_REMINDER_TYPE && x.payload?.groupId === groupId
);
if (!exists) {
await BotTodoMgr.Inst().addTodo(ts, MONTHLY_CARD_FINAL_REMINDER_TYPE, { groupId });
}
}
__name(scheduleMonthlyCardFinalReminder, "scheduleMonthlyCardFinalReminder");
function executeMonthlyCardFinalReminder(item) {
const payload = item.payload || {};
const groupId = payload.groupId;
if (!groupId) return;
const atUsers = genMonthlyCardFinalReminderUsers();
if (atUsers) {
TalkMgr.Inst().send(groupId, "月卡最后提醒", { atUsers });
}
const next = new Date(item.ts + 24 * 60 * 60 * 1e3);
next.setHours(23, 30, 0, 0);
const nextTs = next.getTime();
const exists = (BotTodoMgr.Inst().getTodosAt(nextTs) || []).some(
(x) => x.type === MONTHLY_CARD_FINAL_REMINDER_TYPE && x.payload?.groupId === groupId
);
if (!exists) {
BotTodoMgr.Inst().addTodo(nextTs, MONTHLY_CARD_FINAL_REMINDER_TYPE, { groupId });
}
}
__name(executeMonthlyCardFinalReminder, "executeMonthlyCardFinalReminder");
function genMonthlyCardFinalReminderUsers() {
const users = UserMgr.Inst().getAllMonthlyCardRemindUsers();
if (users.length === 0) return;
const now = /* @__PURE__ */ new Date();
const todayStr = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
const notConfirmed = users.filter((user) => user.lastGetMonthlyCardDate !== todayStr);
if (notConfirmed.length === 0) return;
const atUsers = notConfirmed.map((user) => `<at id="${user.qq}"/>`).join(" ");
return atUsers;
}
__name(genMonthlyCardFinalReminderUsers, "genMonthlyCardFinalReminderUsers");
// src/script/command/allMemberRemindCommand.ts
function allMemberRemind(event, args) {
const qq = event.session.event.user.id;
const authResult = isAdmin(qq, event);
if (authResult?.code === 2002 /* 无权限 */) {
TalkMgr.Inst().reply(event, "无权限");
return;
}
const checkResult = checkArgs(args, event.config);
switch (checkResult.code) {
case 2001 /* 参数缺失 */:
TalkMgr.Inst().reply(event, "简易回复", { result: "参数缺失:需要 时间段 时间点 内容" });
return;
case 3002 /* 时间不正确 */:
TalkMgr.Inst().reply(event, "简易回复", { result: "时间不正确:请输入 (yy.)mm.dd(-yy.mm.dd) 和 hh:mm" });
return;
}
const { timeList, content } = checkResult.result;
const groupId = event.config.groupId;
if (!Array.isArray(timeList) || timeList.length === 0) {
TalkMgr.Inst().reply(event, "简易回复", { result: "没有可用的时间点。" });
return;
}
let created = 0;
for (const ts of timeList) {
BotTodoMgr.Inst().addTodo(ts, ALL_MEMBER_REMINDER_TYPE, { groupId, content });
created++;
}
TalkMgr.Inst().reply(event, "简易回复", { result: `咕` });
}
__name(allMemberRemind, "allMemberRemind");
function isAdmin(qq, event) {
const adminQQList = event.config.adminQQList;
if (!adminQQList.includes(qq)) {
return new Result(2002 /* 无权限 */, false);
}
}
__name(isAdmin, "isAdmin");
function checkArgs(args, config) {
const timePeriod = args[0];
const timePointStr = args[1];
const content = args[2];
if (timePeriod === void 0 || timePointStr === void 0 || content === void 0) {
return new Result(2001 /* 参数缺失 */);
}
const now = /* @__PURE__ */ new Date();
const currentYear = now.getFullYear();
const parseSingleDay = /* @__PURE__ */ __name((str, defaultYear) => {
if (!str) return null;
let yearProvided = false;
let y = defaultYear;
let mStr = "";
let dStr = "";
const parts = str.split(".");
if (parts.length === 2) {
mStr = parts[0];
dStr = parts[1];
} else if (parts.length === 3) {
yearProvided = true;
const yy = parts[0];
mStr = parts[1];
dStr = parts[2];
const yNum = Number(yy);
if (!Number.isInteger(yNum)) return null;
if (yy.length <= 2) y = 2e3 + yNum;
else if (yy.length === 4) y = yNum;
else return null;
} else {
return null;
}
const m = Number(mStr);
const d = Number(dStr);
if (!Number.isInteger(m) || !Number.isInteger(d)) return null;
if (m < 1 || m > 12 || d < 1 || d > 31) return null;
const date = new Date(y, m - 1, d);
if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d) return null;
return { date, yearProvided };
}, "parseSingleDay");
const timeStr = timePointStr.trim().replace(/:/g, ":");
const tm = timeStr.match(/^(\d{1,2}):(\d{1,2})$/);
if (!tm) return new Result(3002 /* 时间不正确 */);
const hour = Number(tm[1]);
const minute = Number(tm[2]);
if (!Number.isInteger(hour) || !Number.isInteger(minute) || hour < 0 || hour > 23 || minute < 0 || minute > 59) {
return new Result(3002 /* 时间不正确 */);
}
const periodParts = timePeriod.split("-").map((s) => s.trim()).filter((s) => s.length > 0);
if (periodParts.length < 1 || periodParts.length > 2) {
return new Result(3002 /* 时间不正确 */);
}
const startParsed = parseSingleDay(periodParts[0], currentYear);
if (!startParsed) return new Result(3002 /* 时间不正确 */);
let { date: startDate } = startParsed;
let endDate = startDate;
if (periodParts.length === 2) {
const endParsed = parseSingleDay(periodParts[1], startDate.getFullYear());
if (!endParsed) return new Result(3002 /* 时间不正确 */);
endDate = endParsed.date;
if (!endParsed.yearProvided && endDate.getTime() < startDate.getTime()) {
endDate = new Date(endDate.getFullYear() + 1, endDate.getMonth(), endDate.getDate());
}
}
if (periodParts.length === 1 && !startParsed.yearProvided) {
const firstDt = new Date(startDate);
firstDt.setHours(hour, minute, 0, 0);
if (firstDt.getTime() <= now.getTime()) {
startDate = new Date(startDate.getFullYear() + 1, startDate.getMonth(), startDate.getDate());
endDate = startDate;
}
}
if (endDate.getTime() < startDate.getTime()) return new Result(3002 /* 时间不正确 */);
const timeList = [];
const cursor = new Date(startDate);
const maxDays = 366 * 2;
let guard = 0;
while (cursor.getTime() <= endDate.getTime()) {
const dt = new Date(cursor);
dt.setHours(hour, minute, 0, 0);
if (dt.getTime() > now.getTime()) {
timeList.push(dt.getTime());
}
cursor.setDate(cursor.getDate() + 1);
guard++;
if (guard > maxDays) return new Result(3002 /* 时间不正确 */);
}
return new Result(1001 /* 通过 */, { timeList, content });
}
__name(checkArgs, "checkArgs");
// src/script/command/levelUpCommand.ts
function command_levelUP(event, args) {
const checkResult = checkArgs2(args, event.config.maxLevel);
switch (checkResult.code) {
case 2001 /* 参数缺失 */:
TalkMgr.Inst().reply(event, "升级命令_参数缺失");
return;
case 3001 /* 等级不正确 */:
TalkMgr.Inst().reply(event, `升级命令_等级不正确`, { maxLevel: event.config.maxLevel.toString() });
return;
}
let title = "";
let result = "";
let tips = "";
const { level } = checkResult.result;
title = getUpgradeExp(level, event.config.maxLevel);
switch (true) {
case level < 38:
result = "\n亲亲,建议去尼塞尔山刷布兰达哦?";
break;
case level < 55:
result = "\n去上古女帝陵墓打机骨龙吧~";
break;
case level < event.config.maxLevel:
let fixBossList = [];
const fixBossDataList = MonsterMgr.Inst().getMonsters().filter((data) => data.type === 2 /* 定点王 */ && data.baseLevel >= level - 50 && data.baseLevel <= level + 20);
fixBossDataList.forEach((data) => {
for (let i = 0; i <= 4; i++) {
fixBossList.push(new Monster(data, i));
}
});
fixBossList = fixBossList.sort((a, b) => b.getPlayerExp(level) * (100 + b.recommend * 30) - a.getPlayerExp(level) * (100 + a.recommend * 30)).slice(0, event.config.levelUP_player_fixedBossReturn);
let wildBossList = [];
const wildBossDataList = MonsterMgr.Inst().getMonsters().filter((data) => data.type === 1 /* 野王 */ && data.baseLevel >= level - 10 && data.baseLevel <= level + 10);
wildBossDataList.forEach((data) => {
wildBossList.push(new Monster(data));
});
wildBossList = wildBossList.sort((a, b) => b.getPlayerExp(level) * (100 + b.recommend * 30) - a.getPlayerExp(level) * (100 + a.recommend * 30)).slice(0, event.config.levelUP_player_wildBossReturn);
const fixBossResult = fixBossList.map((monster, i) => {
return `${i + 1}.${monster.cmdPlayerLevelUP(level)}`;
});
result += `
定点王:
${fixBossResult.join("\n")}`;
const wildBossResult = wildBossList.map((monster, i) => {
return `${i + 1}.${monster.cmdPlayerLevelUP(level)}`;
});
result += `
野王:
${wildBossResult.join("\n")}`;
const rand = Math.floor(Math.random() * (fixBossList.length + wildBossList.length));
let suggestion = rand < fixBossList.length ? fixBossList[rand] : wildBossList[rand - fixBossList.length];
tips = `
去打${suggestion.name}怎么样?`;
break;
case level === event.config.maxLevel:
result = `
你已经升到满级啦!`;
break;
}
TalkMgr.Inst().reply(event, "正常回复", { title, result, tips });
}
__name(command_levelUP, "command_levelUP");
function checkArgs2(args, maxLevel) {
let levelCN = args[0];
if (levelCN === void 0) return new Result(2001 /* 参数缺失 */);
if (/级$/.test(levelCN)) levelCN = levelCN.replace(/级/g, "");
const level = Number(levelCN);
if (isNaN(level) || level < 1 || level > maxLevel || Math.floor(level) !== level) return new Result(3001 /* 等级不正确 */);
return new Result(1001 /* 通过 */, { level });
}
__name(checkArgs2, "checkArgs");
function getUpgradeExp(level, maxLevel) {
const exp = Math.floor(level ** 4 / 40) + level * 2;
return level !== maxLevel ? `${level}级升级所需经验为${exp}` : "";
}
__name(getUpgradeExp, "getUpgradeExp");
// src/script/command/monthlyCardRemindCommand.ts
function command_monthlyCardRemind(event, args) {
const checkResult = checkArgs3(args);
switch (checkResult.code) {
case 2001 /* 参数缺失 */:
TalkMgr.Inst().reply(event, "月卡提醒_参数缺失");
return;
case 3002 /* 时间不正确 */:
TalkMgr.Inst().reply(event, `月卡提醒_时间不正确`);
return;
}
const { timeIndex } = checkResult.result;
const qq = event.session.event.user.id;
UserMgr.Inst().setUserMonthlyCardRemindTimeIndex(qq, timeIndex);
const hours = [
event.config.monthlyCardReminder_midnightTime,
event.config.monthlyCardReminder_morningTime,
event.config.monthlyCardReminder_noonTime,
event.config.monthlyCardReminder_afternoonTime,
event.config.monthlyCardReminder_eveningTime,
event.config.monthlyCardReminder_latenightTime
];
TalkMgr.Inst().reply(event, "正常回复", {
title: "月卡提醒设置成功!\n",
result: `你已将月卡提醒时间设置为${args[0]}(${hours[timeIndex]}点10分)
`,
tips: "魔导书会在每天对应的时间点提醒你领取月卡哦~"
});
}
__name(command_monthlyCardRemind, "command_monthlyCardRemind");
function checkArgs3(args) {
const time = args[0];
if (time === void 0) return new Result(2001 /* 参数缺失 */);
const allowTimesCN = ["凌晨", "早上", "中午", "下午", "晚上", "深夜"];
const index = allowTimesCN.indexOf(time);
if (index === -1) return new Result(3002 /* 时间不正确 */);
return new Result(1001 /* 通过 */, { timeIndex: index });
}
__name(checkArgs3, "checkArgs");
function command_cancelMonthlyCardRemind(event, args) {
const qq = event.session.event.user.id;
UserMgr.Inst().setUserMonthlyCardRemindTimeIndex(qq, -1);
TalkMgr.Inst().reply(event, "简易回复", {
result: "月卡提醒取消成功!"
});
}
__name(command_cancelMonthlyCardRemind, "command_cancelMonthlyCardRemind");
function confirmMonthlyCardGet(event) {
const qq = event.session.event.user.id;
const user = UserMgr.Inst().getAllMonthlyCardRemindUsers().find((u) => u.qq === qq);
let result;
if (user) {
result = UserMgr.Inst().updateUserLastGetMonthlyCardDate(qq);
} else {
result = new Result(1002 /* 无需处理 */);
}
return result;
}
__name(confirmMonthlyCardGet, "confirmMonthlyCardGet");
// src/script/monster/monsterClass.ts
var ElementType = /* @__PURE__ */ ((ElementType2) => {
ElementType2[ElementType2["无"] = 0] = "无";
ElementType2[ElementType2["风"] = 1] = "风";
ElementType2[ElementType2["地"] = 2] = "地";
ElementType2[ElementType2["水"] = 3] = "水";
ElementType2[ElementType2["火"] = 4] = "火";
ElementType2[ElementType2["光"] = 5] = "光";
ElementType2[ElementType2["暗"] = 6] = "暗";
return ElementType2;
})(ElementType || {});
var _Monster = class _Monster {
// 推荐系数
constructor(monsterData, star) {
this.type = monsterData.type;
this.name = monsterData.name;
this.level = monsterData.baseLevel;
this.baseExp = monsterData.baseExp;
this.map = monsterData.map;
this.element = monsterData.element;
const starLevel = [-10, 0, 10, 20, 40];
const starExp = [0.1, 1, 2, 5, 10];
if (star !== void 0) {
this.name = `${star}星${this.name}`;
this.star = star;
this.level = Math.max(1, this.level + starLevel[star]);
this.baseExp *= starExp[star];
}
if (monsterData.recommend) this.recommend = monsterData.recommend;
}
getPlayerExp(level) {
const playerExpRate = [11, 11, 11, 11, 11, 11, 10, 9, 7, 3, 1];
return this.baseExp * playerExpRate[Math.abs(level - this.level)] || 0;
}
cmdPlayerLevelUP(level) {
return `${this.name} 等级${this.level} 经验值${this.getPlayerExp(level)} ${this.map} ${ElementType[this.element]}属性`;
}
};
__name(_Monster, "Monster");
var Monster = _Monster;
// src/script/monster/MonsterMgr.ts
var _MonsterMgr = class _MonsterMgr {
constructor() {
this._monsters = /* @__PURE__ */ new Map();
}
static Inst() {
if (!_MonsterMgr.instance) {
_MonsterMgr.instance = new _MonsterMgr();
}
return _MonsterMgr.instance;
}
setMonsters() {
const data = JsonMgr.Inst().getJson("monsters.json");
data.forEach((monster) => {
this._monsters.set(monster.id, monster);
});
}
getMonsters() {
return Array.from(this._monsters.values());
}
};
__name(_MonsterMgr, "MonsterMgr");
_MonsterMgr.instance = null;
var MonsterMgr = _MonsterMgr;
// src/script/user/UserMgr.ts
var _UserMgr = class _UserMgr {
constructor() {
this._users = /* @__PURE__ */ new Map();
}
static Inst() {
if (!_UserMgr.instance) {
_UserMgr.instance = new _UserMgr();
}
return _UserMgr.instance;
}
async setUsers(ctx) {
this.ctx = ctx;
const data = await ctx.database.get("toram_user", {});
if (!data) return;
data.forEach((user) => {
this._users.set(user.qq, user);
});
}
saveUser(user) {
this.ctx.database.upsert("toram_user", () => [user]);
}
addUser(qq, saveNow = true) {
const user = {
qq,
nickname: "",
otherNames: [],
monthlyCardRemindTimeIndex: -1,
lastGetMonthlyCardDate: ""
};
this._users.set(user.qq, user);
if (saveNow) {
this.saveUser(user);
}
}
setUserMonthlyCardRemindTimeIndex(qq, timeIndex) {
let user = this._users.get(qq);
if (!user) {
this.addUser(qq, false);
user = this._users.get(qq);
}
user.monthlyCardRemindTimeIndex = timeIndex;
this.saveUser(user);
}
getUsersWithMonthlyCardRemindTimeIndex(timeIndex) {
const result = [];
const now = /* @__PURE__ */ new Date();
this._users.forEach((user) => {
if (user.monthlyCardRemindTimeIndex !== timeIndex) return;
if (user.lastGetMonthlyCardDate === `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`) return;
result.push(user);
});
return result;
}
getAllMonthlyCardRemindUsers() {
const result = [];
this._users.forEach((user) => {
if (user.monthlyCardRemindTimeIndex === -1) return;
result.push(user);
});
return result;
}
updateUserLastGetMonthlyCardDate(qq) {
let user = this._users.get(qq);
if (!user) {
this.addUser(qq, false);
user = this._users.get(qq);
}
const now = /* @__PURE__ */ new Date();
const dateStr = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
if (user.lastGetMonthlyCardDate === dateStr) {
return new Result(1002 /* 无需处理 */);
}
user.lastGetMonthlyCardDate = dateStr;
this.saveUser(user);
return new Result(1001 /* 通过 */);
}
};
__name(_UserMgr, "UserMgr");
_UserMgr.instance = null;
var UserMgr = _UserMgr;
// src/script/BotTodoMgr.ts
var _BotTodoMgr = class _BotTodoMgr {
constructor() {
this.ctx = null;
this._todos = /* @__PURE__ */ new Map();
this._handlers = /* @__PURE__ */ new Map();
this._timer = null;
this._started = false;
}
static Inst() {
if (!_BotTodoMgr.instance) {
_BotTodoMgr.instance = new _BotTodoMgr();
}
return _BotTodoMgr.instance;
}
// 读取 json 到内存
async setTodos(ctx) {
this.ctx = ctx;
const data = await ctx.database.get("toram_todo", {});
if (!data) return;
this._todos.clear();
data.forEach((item) => {
const list = this._todos.get(item.ts) || [];
list.push(item);
this._todos.set(item.ts, list);
});
}
// 持久化内存中的 todo
async saveTodos() {
const data = Array.from(this._todos.values()).flat();
await this.ctx.database.upsert("toram_todo", data);
}
// 新增一条 todo,返回 id
async addTodo(ts, type, payload) {
const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
const todo = { id, ts, type, payload };
const list = this._todos.get(ts) || [];
list.push(todo);
this._todos.set(ts, list);
await this.saveTodos();
if (this._started) {
if (this._nextTs === void 0 || ts < this._nextTs) {
this.scheduleNext();
}
}
return id;
}
// 获取某个时间戳下的 todo 列表(拷贝)
getTodosAt(ts) {
const list = this._todos.get(ts) || [];
return list.map((x) => ({ ...x }));
}
// 删除某个时间戳下的指定 todo
async removeTodo(ts, id) {
const list = this._todos.get(ts);
if (!list) return;
const next = list.filter((x) => x.id !== id);
if (next.length > 0) this._todos.set(ts, next);
else this._todos.delete(ts);
await this.saveTodos();
}
// 删除某个时间戳下的所有 todo
async removeTodosAt(ts) {
if (!this._todos.has(ts)) return;
this._todos.delete(ts);
await this.saveTodos();
}
// 取出并删除“到期”的 todo 列表(ts <= now)
async popDueTodos(now) {
const result = [];
const keys = Array.from(this._todos.keys()).filter((ts) => ts <= now).sort((a, b) => a - b);
keys.forEach((ts) => {
const list = this._todos.get(ts);
if (list && list.length) result.push(...list);
this._todos.delete(ts);
});
if (keys.length > 0) await this.saveTodos();
return result;
}
// 下一个最近的时间戳(若不存在返回 undefined)
getNextTimestamp() {
const keys = Array.from(this._todos.keys());
if (keys.length === 0) return void 0;
return keys.sort((a, b) => a - b)[0];
}
// 注册任务处理器
on(type, handler) {
this._handlers.set(type, handler);
}
// 启动调度(基于 setTimeout)
start() {
this._started = true;
this.scheduleNext();
}
// 停止调度
stop() {
this._started = false;
if (this._timer) {
clearTimeout(this._timer);
this._timer = null;
}
this._nextTs = void 0;
}
// 立即重新计算下一个调度点
async scheduleNext() {
if (!this._started) return;
try {
const dropped = await this.popDueTodos(Date.now());
if (dropped.length) {
console.warn("BotTodoMgr 清理过期任务数量: ", dropped.length);
}
} catch (e) {
console.error("BotTodoMgr 清理过期任务异常: ", e);
}
if (this._timer) {
clearTimeout(this._timer);
this._timer = null;
}
this.internalPlanNext();
}
internalPlanNext() {
if (!this._started) return;
const now = Date.now();
const keys = Array.from(this._todos.keys()).filter((ts) => ts > now);
if (keys.length === 0) {
this._nextTs = void 0;
return;
}
const next = keys.sort((a, b) => a - b)[0];
this._nextTs = next;
const delay = Math.max(0, next - now);
const scheduledTs = next;
this._timer = setTimeout(async () => {
try {
const list = this._todos.get(scheduledTs) || [];
if (list.length) {
this._todos.delete(scheduledTs);
await this.saveTodos();
await this.executeBatch(list);
}
} catch (e) {
console.error("BotTodoMgr 执行任务异常: ", e);
} finally {
this.scheduleNext();
}
}, delay);
}
async executeBatch(list) {
for (const item of list) {
const handler = this._handlers.get(item.type);
if (!handler) {
console.warn("BotTodoMgr 未找到处理器:", item.type, item);
continue;
}
try {
await handler(item);
} catch (e) {
console.error("BotTodoMgr 执行单个任务异常:", e, item);
}
}
}
};
__name(_BotTodoMgr, "BotTodoMgr");
_BotTodoMgr.instance = null;
var BotTodoMgr = _BotTodoMgr;
// src/index.ts
var name = "toram";
var inject = ["database"];
var Config = import_koishi.Schema.intersect([
import_koishi.Schema.object({
qq: import_koishi.Schema.string().description("机器人QQ号").default("机器人qq号").required(),
groupId: import_koishi.Schema.string().description("机器人运行的群号").default("机器人运行的群号").required()
}).description("机器人信息"),
import_koishi.Schema.object({
adminQQList: import_koishi.Schema.array(String).description("管理员QQ列表").default([])
}).description("管理员信息"),
import_koishi.Schema.object({
maxLevel: import_koishi.Schema.number().description("当前版本的最大等级").step(5).default(290)
}).description("游戏信息"),
import_koishi.Schema.object({
levelUP_player_recommend: import_koishi.Schema.number().description("使用升级指令时推荐系数的影响幅度").min(0).step(5).default(30),
levelUP_player_fixedBossReturn: import_koishi.Schema.number().description("使用升级指令时返回的定点王数量").min(1).step(1).default(6),
levelUP_player_wildBossReturn: import_koishi.Schema.number().description("使用升级指令时返回的野王数量").min(1).step(1).default(4)
}).description("升级指令管理"),
import_koishi.Schema.object({
monthlyCardReminder_midnightTime: import_koishi.Schema.number().description("月卡提醒的凌晨时间").default(0),
monthlyCardReminder_morningTime: import_koishi.Schema.number().description("月卡提醒的早上时间").default(9),
monthlyCardReminder_noonTime: import_koishi.Schema.number().description("月卡提醒的中午时间").default(12),
monthlyCardReminder_afternoonTime: import_koishi.Schema.number().description("月卡提醒的下午时间").default(16),
monthlyCardReminder_eveningTime: import_koishi.Schema.number().description("月卡提醒的晚上时间").default(20),
monthlyCardReminder_latenightTime: import_koishi.Schema.number().description("月卡提醒的深夜时间").default(23)
}).description("月卡提醒管理"),
import_koishi.Schema.object({
sendDialog: import_koishi.Schema.boolean().description("是否发送日志以调试").default(false)
}).description("调试相关")
]);
async function apply(ctx, config) {
const logger = ctx.logger("toram");
ctx.model.extend(
"toram_user",
{
// 各字段的类型声明
qq: "string",
nickname: "string",
otherNames: "list",
monthlyCardRemindTimeIndex: "integer",
lastGetMonthlyCardDate: "string"
},
{
primary: "qq"
}
);
ctx.model.extend("toram_todo", {
// 各字段的类型声明
id: "string",
ts: "double",
type: "string",
payload: "json"
}, {
primary: "id"
});
JsonMgr.Inst().setLogger(logger);
await JsonMgr.Inst().loadJson();
const bot = ctx.bots.find((bot2) => bot2.selfId === config.qq);
TalkMgr.Inst().setBot(bot);
TalkMgr.Inst().setTalks();
await UserMgr.Inst().setUsers(ctx);
MonsterMgr.Inst().setMonsters();
await BotTodoMgr.Inst().setTodos(ctx);
registerBotTodoHandlers();
BotTodoMgr.Inst().start();
scheduleMonthlyCardReminders(config.groupId, [
config.monthlyCardReminder_midnightTime,
config.monthlyCardReminder_morningTime,
config.monthlyCardReminder_noonTime,
config.monthlyCardReminder_afternoonTime,
config.monthlyCardReminder_eveningTime,
config.monthlyCardReminder_latenightTime
]);
scheduleMonthlyCardFinalReminder(config.groupId);
ctx.on("notice", (session) => {
if (config.sendDialog) logger.info(session);
if (session.event._data.target_id != config.qq) return;
const event = newEvent(ctx, session, config, logger);
const result = confirmMonthlyCardGet(event);
if (result.code === 1001 /* 通过 */) {
TalkMgr.Inst().reply(event, "月卡确认领取");
} else {
TalkMgr.Inst().reply(event, "戳一戳");
}
});
ctx.middleware(async (session, next) => {
if (config.sendDialog) logger.info(session);
if (session.event.message.elements.some((e) => e.type === "at" && e.attrs.id === config.qq)) {
const event = newEvent(ctx, session, config, logger);
TalkMgr.Inst().reply(event, "被@", {
MCRMidnight: config.monthlyCardReminder_midnightTime.toString(),
MCRMorning: config.monthlyCardReminder_morningTime.toString(),
MCRNoon: config.monthlyCardReminder_noonTime.toString(),
MCRAfternoon: config.monthlyCardReminder_afternoonTime.toString(),
MCREvening: config.monthlyCardReminder_eveningTime.toString(),
MCRLatenight: config.monthlyCardReminder_latenightTime.toString()
});
}
return next();
});
ctx.command("升级 <等级数>").action(async ({ session }, ...args) => {
const event = newEvent(ctx, session, config, logger);
command_levelUP(event, args);
});
ctx.command("月卡提醒 <时间段>").action(async ({ session }, ...args) => {
const event = newEvent(ctx, session, config, logger);
command_monthlyCardRemind(event, args);
});
ctx.command("取消月卡提醒").action(async ({ session }, ...args) => {
const event = newEvent(ctx, session, config, logger);
command_cancelMonthlyCardRemind(event, args);
});
ctx.command("魔导书,全员提醒 <时间段> <时间点> <内容>").action(async ({ session }, ...args) => {
const event = newEvent(ctx, session, config, logger);
allMemberRemind(event, args);
});
ctx.command("我领月卡啦").action(async ({ session }, ...args) => {
const event = newEvent(ctx, session, config, logger);
const result = confirmMonthlyCardGet(event);
if (result.code === 1001 /* 通过 */) {
TalkMgr.Inst().reply(event, "月卡确认领取");
}
});
}
__name(apply, "apply");
function registerBotTodoHandlers() {
BotTodoMgr.Inst().on(ALL_MEMBER_REMINDER_TYPE, executeAllMemberReminder);
BotTodoMgr.Inst().on(MONTHLY_CARD_REMINDER_TYPE, executeMonthlyCardReminder);
BotTodoMgr.Inst().on(MONTHLY_CARD_FINAL_REMINDER_TYPE, executeMonthlyCardFinalReminder);
}
__name(registerBotTodoHandlers, "registerBotTodoHandlers");
function newEvent(ctx, session, config, logger) {
const event = {
ctx,
session,
config,
logger
};
return event;
}
__name(newEvent, "newEvent");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Config,
apply,
inject,
name
});