UNPKG

koishi-plugin-pic-splice-lizard

Version:
162 lines (155 loc) 5.78 kB
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 });