diff --git a/packages/plugin-chess/src/index.ts b/packages/plugin-chess/src/index.ts index 2e6eaba638..195926724d 100644 --- a/packages/plugin-chess/src/index.ts +++ b/packages/plugin-chess/src/index.ts @@ -50,14 +50,9 @@ export function apply(ctx: Context) { states[id].update = rules[chess.rule].update } } - - if (!ctx.app.browser) { - chess.removeOption('imageMode') - chess.removeOption('textMode') - } }) - const chess = ctx.command('chess [position]', '棋类游戏') + ctx.command('chess [position]', '棋类游戏') .userFields(['name']) .channelFields(['chess']) .shortcut('落子', { fuzzy: true }) @@ -69,8 +64,6 @@ export function apply(ctx: Context) { .shortcut('停止下棋', { options: { stop: true } }) .shortcut('跳过回合', { options: { skip: true } }) .shortcut('查看棋盘', { options: { show: true } }) - .option('imageMode', '-i 使用图片模式') - .option('textMode', '-t 使用文本模式') .option('rule', ' 设置规则,支持的规则有 go, gomoku, othello') .option('size', ' 设置大小') .option('skip', '跳过回合') @@ -100,8 +93,6 @@ export function apply(ctx: Context) { const state = new State(ctx.app, options.rule, options.size, rule.placement || 'cross') state.p1 = userId - if (options.textMode) state.imageMode = false - if (rule.create) { const result = rule.create.call(state) if (result) return result @@ -121,16 +112,6 @@ export function apply(ctx: Context) { const state = states[cid] - if (ctx.app.browser) { - if (options.textMode) { - state.imageMode = false - return state.draw(session, '已切换到文本模式。') - } else if (options.imageMode) { - state.imageMode = true - return state.draw(session, '已切换到图片模式。') - } - } - if (options.show) return state.draw(session) if (state.p2 && state.p1 !== userId && state.p2 !== userId) { @@ -231,4 +212,24 @@ export function apply(ctx: Context) { channel.chess = state.serial() return state.draw(session, message, x, y) }) + + ctx.with(['koishi-plugin-puppeteer'], (ctx) => { + ctx.command('chess', { patch: true }) + .option('imageMode', '-i 使用图片模式') + .option('textMode', '-t 使用文本模式') + .action(({ session, options }) => { + const state = states[session.cid] + if (!state) return + + if (ctx.app.puppeteer) { + if (options.textMode) { + state.imageMode = false + return state.draw(session, '已切换到文本模式。') + } else if (options.imageMode) { + state.imageMode = true + return state.draw(session, '已切换到图片模式。') + } + } + }) + }) } diff --git a/packages/plugin-chess/src/state.ts b/packages/plugin-chess/src/state.ts index d893479ade..cf9cec9aec 100644 --- a/packages/plugin-chess/src/state.ts +++ b/packages/plugin-chess/src/state.ts @@ -1,6 +1,6 @@ /* global BigInt */ -import * as puppeteer from 'koishi-plugin-puppeteer' +import type * as puppeteer from 'koishi-plugin-puppeteer' import { Session, App } from 'koishi-core' const numbers = '①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳' @@ -29,7 +29,7 @@ export class State { constructor(public app: App, public readonly rule: string, public readonly size: number, public readonly placement: 'cross' | 'grid') { this.area = BigInt(size * size) this.full = (1n << this.area) - 1n - this.imageMode = !!app.browser + this.imageMode = !!app.puppeteer } get pBoard() { diff --git a/packages/plugin-github/src/server.ts b/packages/plugin-github/src/server.ts index 1c9d342bd3..d1b8243f7f 100644 --- a/packages/plugin-github/src/server.ts +++ b/packages/plugin-github/src/server.ts @@ -222,8 +222,8 @@ export class ReplyHandler { } async shot(url: string, selector: string, padding: number[] = []) { - const page = await this.session.app.browser.newPage() - let base64: string + const page = await this.session.app.puppeteer.page() + let buffer: Buffer try { await page.goto(url) const el = await page.$(selector) @@ -233,13 +233,13 @@ export class ReplyHandler { clip.y -= top clip.width += left + right clip.height += top + bottom - base64 = await page.screenshot({ clip, encoding: 'base64' }) + buffer = await page.screenshot({ clip }) } catch (error) { new Logger('puppeteer').warn(error) return this.session.send('截图失败。') } finally { await page.close() } - return this.session.send(segment.image('base64://' + base64)) + return this.session.send(segment.image(buffer)) } } diff --git a/packages/plugin-puppeteer/src/index.ts b/packages/plugin-puppeteer/src/index.ts index a071d6704e..a1b3c3a40d 100644 --- a/packages/plugin-puppeteer/src/index.ts +++ b/packages/plugin-puppeteer/src/index.ts @@ -4,6 +4,7 @@ import { escape } from 'querystring' import { PNG } from 'pngjs' import { resolve } from 'path' import {} from 'koishi-plugin-eval' +import { SVG, SVGOptions } from './svg' export * from './svg' @@ -38,6 +39,12 @@ declare module 'koishi-core' { puppeteer: Puppeteer } + namespace Plugin { + interface Packages { + 'koishi-plugin-puppeteer': typeof import('.'), + } + } + interface EventMap { 'puppeteer/start'(): void 'puppeteer/validate'(url: string): string @@ -85,7 +92,9 @@ class Puppeteer { this.status = Status.close } - newPage = () => this.browser.newPage() + page = () => this.browser.newPage() + + svg = (options?: SVGOptions) => new SVG(options) render = async (content: string, callback?: RenderCallback) => { if (this.status === Status.opening) { @@ -94,7 +103,7 @@ class Puppeteer { throw new Error('browser instance is not running') } - const page = await this.newPage() + const page = await this.page() await page.setViewport({ ...this.config.browser.defaultViewport, ...this.config.renderViewport, @@ -167,7 +176,7 @@ export function apply(ctx: Context, config: Config = {}) { if (typeof result === 'string') return result let loaded = false - const page = await ctx.puppeteer.newPage() + const page = await ctx.puppeteer.page() page.on('load', () => loaded = true) try { diff --git a/packages/plugin-puppeteer/src/svg.ts b/packages/plugin-puppeteer/src/svg.ts index 85027b5ae9..5bdab23a53 100644 --- a/packages/plugin-puppeteer/src/svg.ts +++ b/packages/plugin-puppeteer/src/svg.ts @@ -131,7 +131,7 @@ export class SVG extends Tag { } async render(ctx: Context) { - const page = await ctx.puppeteer.newPage() + const page = await ctx.puppeteer.page() await page.setContent(this.outer) const buffer = await page.screenshot({ clip: {