koishi-plugin-pic-splice-lizard
Version:
162 lines (155 loc) • 5.78 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __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,
usage: () => usage
});
module.exports = __toCommonJS(src_exports);
var import_koishi = require("koishi");
var name = "pic-splice-lizard";
var inject = ["puppeteer"];
var usage = `
## 拼图插件使用方法:
- 输入“拼图 [方向]”(横向/纵向,默认纵向)
- 发送多张图片
- 请输入“完成”或等待10秒自动拼接
### 注意事项
- 发送图片后,请输入“完成”以开始拼接。
- 如果未输入“完成”,插件将在10秒后自动拼接。
- 支持一次性发送多张图片,但建议不要超过10张,以免拼接时间过长。
<details>
<summary><strong><span style="font-size: 1.3em; color: #2a2a2a;">如果要反馈建议或报告问题</span></strong></summary>
<strong>可以[点这里](https://github.com/lizard0126/javbus-lizard/issues)创建议题~</strong>
</details>
<details>
<summary><strong><span style="font-size: 1.3em; color: #2a2a2a;">如果喜欢我的插件</span></strong></summary>
<strong>可以[请我喝可乐](https://ifdian.net/a/lizard0126),没准就有动力更新新功能了~</strong>
</details>
`;
var Config = import_koishi.Schema.object({});
function apply(ctx) {
const tasks = /* @__PURE__ */ new Map();
const timers = /* @__PURE__ */ new Map();
function cleanup(userId) {
tasks.delete(userId);
clearTimeout(timers.get(userId));
timers.delete(userId);
}
__name(cleanup, "cleanup");
ctx.command("拼图 [方向]", "拼接多张图片").action(({ session }, dir = "纵向") => {
if (!["横向", "纵向"].includes(dir)) return '方向只能是 "横向" 或 "纵向"。';
tasks.set(session.userId, { dir, imgs: [], processing: false });
return '请发送图片,输入 "完成" 开始拼接。';
});
ctx.middleware(async (session, next) => {
const task = tasks.get(session.userId);
if (!task) return next();
const images = import_koishi.h.select(session.content, "img").map((img) => img.attrs.src);
task.imgs.push(...images);
if (images.length) await session.send(`已获取 ${task.imgs.length} 张图片。`);
if (session.content.trim() === "完成") return processTask(session);
resetTimeout(session.userId, session);
});
function resetTimeout(userId, session) {
clearTimeout(timers.get(userId));
timers.set(userId, setTimeout(() => processTask(session), 1e4));
}
__name(resetTimeout, "resetTimeout");
async function processTask(session) {
const task = tasks.get(session.userId);
if (!task || task.processing || task.imgs.length < 2) {
return session.send(task?.imgs.length < 2 ? "请提供至少两张图片。" : "任务正在处理中,请稍候。");
}
task.processing = true;
try {
const imgBuffer = await stitchImages(ctx, task.imgs, task.dir);
await session.send(import_koishi.h.image(imgBuffer, "image/png"));
} catch {
await session.send("拼接失败,请稍后重试。");
} finally {
cleanup(session.userId);
}
}
__name(processTask, "processTask");
async function stitchImages(ctx2, imgs, dir) {
const html = `
<html>
<head>
<style>
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: ${dir === "横向" ? "row" : "column"};
align-items: flex-start;
justify-content: flex-start;
}
img {
display: block;
width: ${dir === "纵向" ? "100%" : "auto"};
height: ${dir === "横向" ? "100%" : "auto"};
}
</style>
</head>
<body>
${imgs.map((url) => `<img src="${url}">`).join("")}
</body>
</html>
`;
for (let i = 0; i < 3; i++) {
try {
const page = await ctx2.puppeteer.page();
await page.setViewport({ width: 1920, height: 1080 });
await page.setContent(html, { waitUntil: "networkidle0" });
const { width, height } = await page.evaluate(() => {
const body = document.body;
return {
width: body.scrollWidth,
height: body.scrollHeight
};
});
await page.setViewport({ width, height });
const screenshot = await page.screenshot({
clip: { x: 0, y: 0, width, height }
});
await page.close();
return screenshot;
} catch (e) {
if (e.message.includes("Connection closed")) await new Promise((r) => setTimeout(r, 1e3));
else throw e;
}
}
throw new Error("拼接失败");
}
__name(stitchImages, "stitchImages");
}
__name(apply, "apply");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Config,
apply,
inject,
name,
usage
});