koishi-plugin-bangbangcai
Version:
[<ruby>邦多利卡面猜猜看<rp>(</rp><rt>点我查看效果预览</rt><rp>)</rp></ruby>](https://i0.hdslb.com/bfs/article/198ba51e2b3ffce9b1275a003c87c9dc312276085.png) 角色立绘切分、猜测人物名称 ...
232 lines (218 loc) • 10 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,
reusable: () => reusable,
usage: () => usage
});
module.exports = __toCommonJS(src_exports);
var import_koishi = require("koishi");
var import_node_fs = __toESM(require("node:fs"));
var import_node_path = __toESM(require("node:path"));
var import_jimp = require("jimp");
var reusable = true;
var name = "bangbangcai";
var inject = {
required: ["database"]
};
var usage = `
<h1>邦多利猜猜看(邦邦猜)</h1>
<p>卡面图片来源于 <a href="https://bestdori.com" target="_blank">bestdori.com</a></p>
<div class="notice">
<h3>Notice</h3>
<p>在 Onebot 适配器下,偶尔发不出来图,Koishi 报错日志为 <code>retcode:1200</code> 时,
请查看协议端日志自行解决!</p>
<p>在 QQ 适配器下,偶尔发不出来图,Koishi 报错日志为 <code>bad request</code> 时,建议参见 论坛10257帖!
-> https://forum.koishi.xyz/t/topic/10257 </p>
</div>
<hr>
<div class="version">
<h3>Version</h3>
<p>1.6.0</p>
<ul>
<li>现在答案对大小写不敏感了</li>
</ul>
<p>1.5.0</p>
<ul>
<li>题库中加入特训后卡面</li>
<li>@的后面加了个空格</li>
</ul>
<p>1.4.0</p>
<ul>
<li>完全重构了代码</li>
<li>修复了已知的所有bug</li>
<li>删除了不必要的指令:bbc重开、bbcdrop等</li>
</ul>
</div>
<hr>
<div class="thanks">
<h3>Thanks</h3>
<p>灵感参考: <a href="/market?keyword=koishi-plugin-cck">koishi-plugin-cck</a></p>
<hr>
<h4>如果想继续开发优化本插件,<a href="https://github.com/xsjh/koishi-plugin-bangbangcai/pulls" target="_blank">欢迎 PR</a></h4>
</body>
`;
var Config = import_koishi.Schema.intersect([
import_koishi.Schema.object({
bbc_command: import_koishi.Schema.string().default("bbc").description("`游戏开始`的指令名称"),
bbc_recrop_command: import_koishi.Schema.string().default("bbc重切").description("`重新切片`的指令名称")
}).description("基础设置"),
import_koishi.Schema.object({
textMessage: import_koishi.Schema.string().description("`猜谜`提示语1").default("时间60秒~\n猜猜我是谁:"),
phrase_timeout: import_koishi.Schema.array(String).role("table").description("`超时结束`时 提示:").default(["60秒到了~\n答案是:"]),
phrase_answered: import_koishi.Schema.array(String).role("table").description("`回答正确`时 提示:").default(["不赖,你还懂"]),
phrase_bzd: import_koishi.Schema.array(String).role("table").description("触发`不知道`时 提示:").default(["游戏结束,这是:"])
}).description("进阶设置"),
import_koishi.Schema.object({
bbctimeout: import_koishi.Schema.number().default(60).description("游戏持续(计时)的 时长(秒)"),
recrop: import_koishi.Schema.boolean().default(false).description("玩家是否可以重新裁剪图片"),
max_recrop_times: import_koishi.Schema.number().default(3).min(0).max(15).step(1).description("允许`重新切片`的最大次数").role("slider")
}).description("交互设置"),
import_koishi.Schema.object({
cutWidth: import_koishi.Schema.number().default(200).description("卡片剪裁 宽度"),
cutLength: import_koishi.Schema.number().default(150).description("卡片剪裁 高度")
}).description("高级设置")
]);
async function apply(ctx, config) {
let games = {};
ctx.command(config.bbc_command).action(async ({ session }) => {
if (games[session.channelId]) {
return "当前已有正在进行的游戏";
}
games[session.channelId] = true;
await session.send("图片加载中请稍等...");
const { resourceSetName, characterId } = randomCharacter();
const nicknames = getNicknames(characterId);
let imageArrayBuffer;
let imageUrl;
try {
if (import_koishi.Random.bool(0.5)) {
imageUrl = `https://bestdori.com/assets/jp/characters/resourceset/${resourceSetName}_rip/card_after_training.png`;
if ((await ctx.http.get(imageUrl, { responseType: "text" })).includes("We're sorry but Bestdori!")) {
imageUrl = `https://bestdori.com/assets/jp/characters/resourceset/${resourceSetName}_rip/card_normal.png`;
imageArrayBuffer = await ctx.http.get(imageUrl, { responseType: "arraybuffer" });
} else {
imageArrayBuffer = await ctx.http.get(imageUrl, { responseType: "arraybuffer" });
}
} else {
imageUrl = `https://bestdori.com/assets/jp/characters/resourceset/${resourceSetName}_rip/card_normal.png`;
imageArrayBuffer = await ctx.http.get(imageUrl, { responseType: "arraybuffer" });
}
} catch {
games[session.channelId] = false;
return "下载图片时遇到网络错误";
}
const image = Buffer.from(imageArrayBuffer);
const cropedImages = await randomCropImage(image, config.cutWidth, config.cutLength);
const message = `时间${config.bbctimeout}秒~
猜猜我是谁:
${import_koishi.h.image(cropedImages[0], "image/jpeg")}
${import_koishi.h.image(cropedImages[1], "image/jpeg")}
${import_koishi.h.image(cropedImages[2], "image/jpeg")}
${config.recrop ? `(输入 重切 可以重新随机裁剪图片,至多${config.max_recrop_times}次)` : ""}
(如果猜不出来输入 bzd 可以查看答案)`;
await session.send(message);
let cropTimes = 0;
const dispose = ctx.channel(session.channelId).middleware(async (session2, next) => {
if (nicknames.includes(session2.content.toLowerCase())) {
dispose();
disposeTimer();
games[session2.channelId] = false;
await session2.send(`正确,${nicknames[7]}:${imageUrl}`);
await session2.send(`${import_koishi.h.at(session2.userId)} ${config.phrase_answered}${session2.content.toLowerCase()}
${import_koishi.h.image(image, "image/jpeg")}`);
} else if (session2.content === "bzd") {
dispose();
disposeTimer();
games[session2.channelId] = false;
await session2.send(`${import_koishi.h.at(session2.userId)} ${config.phrase_bzd}${nicknames[7]}
${import_koishi.h.image(image, "image/jpeg")}`);
} else if (session2.content === "重切") {
if (!config.recrop) {
return next();
} else if (cropTimes >= config.max_recrop_times) {
await session2.send(`已经重切了${config.max_recrop_times}次了哦~`);
} else {
cropTimes++;
await session2.send("正在重新裁剪请稍等...");
const recropedImages = await randomCropImage(image, config.cutWidth, config.cutLength);
await session2.send(`${import_koishi.h.at(session2.userId)}</br>${import_koishi.h.image(recropedImages[0], "image/jpeg")}
${import_koishi.h.image(recropedImages[1], "image/jpeg")}
${import_koishi.h.image(recropedImages[2], "image/jpeg")}`);
}
} else {
return next();
}
}, true);
const disposeTimer = ctx.setTimeout(async () => {
if (games[session.channelId]) {
dispose();
games[session.channelId] = false;
await session.send(`${config.phrase_timeout}${nicknames[7]}
${import_koishi.h.image(image, "image/jpeg")}`);
}
}, config.bbctimeout * 1e3);
});
function randomCharacter() {
const characters = JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(__dirname, "./../resource/all5_2.json"), "utf-8"));
return characters[import_koishi.Random.pick(Object.keys(characters))];
}
__name(randomCharacter, "randomCharacter");
function getNicknames(characterId) {
const allNicknames = JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(__dirname, "./../resource/nickname.json"), "utf-8"));
return allNicknames[characterId];
}
__name(getNicknames, "getNicknames");
async function randomCropImage(imageBuffer, cutWidth, cutLength) {
const image = await import_jimp.Jimp.read(imageBuffer);
let images = [];
for (let i = 1; i <= 3; i++) {
const x = Math.floor(Math.random() * (image.bitmap.width - cutWidth));
const y = Math.floor(Math.random() * (image.bitmap.height - cutLength));
images.push(await image.clone().crop({ x, y, w: cutWidth, h: cutLength }).getBuffer("image/jpeg"));
}
return images;
}
__name(randomCropImage, "randomCropImage");
}
__name(apply, "apply");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Config,
apply,
inject,
name,
reusable,
usage
});