Skip to content

Commit

Permalink
chore: housekeeping
Browse files Browse the repository at this point in the history
  • Loading branch information
dragon-fish committed Oct 8, 2024
1 parent 3163887 commit b2b9245
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 84 deletions.
82 changes: 37 additions & 45 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import PluginPowerUser from '~/power-user'
import PluginProfile from '~/profile'
import PluginQueue from '~/queue'
import PluginReboot from '~/reboot'
import PluginRepeater, { RepeatState } from '~/repeater'
import PluginSensitiveFilter from '~/sensitive-words-filter'
import PluginSiliName from '~/sili-name'
import PluginSpawn from '~/spawn'
Expand Down Expand Up @@ -84,7 +85,6 @@ import * as PluginNovelAi from 'koishi-plugin-novelai'
import PluginPuppeteer from 'koishi-plugin-puppeteer'
import * as PluginRateLimit from 'koishi-plugin-rate-limit'
import * as PluginRecall from 'koishi-plugin-recall'
import * as PluginRepeater from 'koishi-plugin-repeater'
import * as PluginSchedule from 'koishi-plugin-schedule'
import PluginSilk from 'koishi-plugin-silk'
import * as PluginSwitch from 'koishi-plugin-switch'
Expand Down Expand Up @@ -191,42 +191,6 @@ app.plugin(function PluginCollectionLegacy(ctx) {
ctx.command('echo', { authority: 3 })
ctx.plugin(PluginRateLimit)
ctx.plugin(PluginRecall)
const randomHit = (probability: number) => Math.random() < probability
ctx.plugin(PluginRepeater, {
onRepeat(state: RepeatState, session: Session) {
if (!state.repeated && state.times > 3) {
const hit = randomHit(0.125 * state.times)
logger.info('[尝试参与复读]', hit)
return hit ? state.content : ''
}

const noRepeatText = [
'No,不要再复读了!',
'🤚我说婷婷,你们搞复读,不讲武德。',
'那么就到此为止吧,再复读就不礼貌了。',
'🤚很抱歉打扰大家的复读,水群不要忘记多喝热水哟~',
]
if (
state.repeated &&
state.times > 5 &&
!noRepeatText.includes(state.content)
) {
const hit = randomHit(0.1 * (state.times - 5))
logger.info('[尝试打断复读]', hit)
return hit ? Random.pick(noRepeatText) : ''
}
},
// onInterrupt(state: RepeatState, session: Session) {
// if (!state.repeated) return
// const hit = randomHit(0.1 * (state.times - 5))
// logger.info('[尝试质询打断]', hit)
// return hit
// ? session.send(
// `${segment.at(session.userId as string)}在?为什么打断复读?`
// )
// : false
// },
})
})
// [tools]
ctx.plugin(function PluginCollectionLegacyTools(ctx) {
Expand Down Expand Up @@ -381,6 +345,42 @@ app.plugin(function PluginCollectionInternal(ctx) {
ctx.plugin(PluginDatabaseAdmin)
ctx.plugin(PluginDebug)
ctx.plugin(PluginReboot)
const randomHit = (probability: number) => Math.random() < probability
ctx.plugin(PluginRepeater, {
onRepeat(state: RepeatState, session: Session) {
if (!state.repeated && state.times > 3) {
const hit = randomHit(0.125 * state.times)
logger.info('[尝试参与复读]', hit)
return hit ? state.content : ''
}

const noRepeatText = [
'No,不要再复读了!',
'🤚我说婷婷,你们搞复读,不讲武德。',
'那么就到此为止吧,再复读就不礼貌了。',
'🤚很抱歉打扰大家的复读,水群不要忘记多喝热水哟~',
]
if (
state.repeated &&
state.times > 5 &&
!noRepeatText.includes(state.content)
) {
const hit = randomHit(0.1 * (state.times - 5))
logger.info('[尝试打断复读]', hit)
return hit ? Random.pick(noRepeatText) : ''
}
},
// onInterrupt(state: RepeatState, session: Session) {
// if (!state.repeated) return
// const hit = randomHit(0.1 * (state.times - 5))
// logger.info('[尝试质询打断]', hit)
// return hit
// ? session.send(
// `${segment.at(session.userId as string)}在?为什么打断复读?`
// )
// : false
// },
})
ctx.plugin(PluginSensitiveFilter)
ctx.plugin(PluginSpawn, { shell: 'pwsh' })
ctx.plugin(MinecraftConnect)
Expand All @@ -390,11 +390,3 @@ app.plugin(function PluginCollectionInternal(ctx) {
app.start().then(() => {
logger.info('🌈', 'SILI启动成功~')
})

// Types
interface RepeatState {
content: string
repeated: boolean
times: number
users: Dict<number>
}
25 changes: 17 additions & 8 deletions src/plugins/debug/index.ts → src/plugins/debug/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ export class PluginDebug extends BasePlugin {
constructor(ctx: Context) {
super(ctx, {}, 'plugin-debug')

ctx.command('debug', 'SILI debug commands', { authority: 3, hidden: true })

ctx.inject(['piggyback'], (ctx) => {
ctx
.command(
'debug.piggyback <command:text>',
'Piggyback to another user',
{
authority: 4,
}
)
.command('debug.piggyback <command:text>', 'Run as another user', {
authority: 4,
})
.alias('debug.runas')
.option('user', '-u <user:user>')
.action(({ session, options }, command) => {
if (!command) return 'No command specified.'
if (!command) return session.execute('help debug.piggyback')

const { user } = options
if (!user) return 'No user specified.'
const index = user.indexOf(':')
Expand All @@ -28,5 +28,14 @@ export class PluginDebug extends BasePlugin {
session.executeAsUser(uin, command)
})
})

ctx
.platform('onebot')
.command('debug.face', '<faceId:posint> Send QQ face', {})
.action((_, faceId) => {
const numId = parseInt(faceId)
if (isNaN(numId) || numId < 1) return 'Invalid face ID.'
return <face id={numId} />
})
}
}
34 changes: 27 additions & 7 deletions src/plugins/reboot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,33 @@ export default class PluginReboot extends BasePlugin {
const ctx = this.ctx

ctx
.command('admin/reboot', '重启机器人', { authority: 4 })
.command('admin/reboot', '[tags:text] 重启机器人', { authority: 4 })
.option('sync', '-s 从 Git 同步并处理依赖')
.option('dumpdb', '-d 备份数据库')
.option('yes', '-y 跳过确认', { hidden: true })
.action(async ({ session, options }) => {
.action(async ({ session, options }, tags) => {
tags ||= ''
tags = tags.trim().toLowerCase()
if (tags.includes('s')) {
options.sync = true
}
if (tags.includes('d')) {
options.dumpdb = true
}
if (tags.includes('y')) {
options.yes = true
}
if (tags === 'sodayo' || tags === '硕大友') {
options.sync = true
options.dumpdb = true
options.yes = true
}

if (!options.yes) {
await session.send('请在 10 秒内发送句号以确认重启……')
const ensure = await (session as Session).prompt(10 * 1000)
if (!['.', '。'].includes(ensure)) {
return '重启申请被 SILI 驳回。'
if (!['.', '。', 'y'].includes(ensure)) {
return 'SILI 驳回了重启申请。'
}
}

Expand All @@ -82,7 +99,9 @@ export default class PluginReboot extends BasePlugin {
),
])

await session.send('SILI 正在重启...')
await session.send(
`SILI 即将重新连接到智库...\nGitSync=${!!options.sync}; DumpDB=${!!options.dumpdb}`
)
process.exit(0)
})
}
Expand Down Expand Up @@ -135,9 +154,10 @@ export default class PluginReboot extends BasePlugin {
console.info(session)
bot.sendMessage(
getChannelIdFromSession(session),
`SILI 重启完毕 (SIGNAL-${(+kSignal).toString(2).padStart(6, '0')})
`SILI 已重新连接到智库
SIGNAL: ${(+kSignal).toString(2).padStart(6, '0')}
共耗时: ${((now - lastSession.time) / 1000).toFixed(2)}s
请求者: ${h.at(getUserIdFromSession(session), {
执行人: ${h.at(getUserIdFromSession(session), {
name: getUserNickFromSession(session),
})}
${cmdLogsImg ? h.image(cmdLogsImg, 'image/jpeg') : '(没有详细日志)'}`,
Expand Down
119 changes: 119 additions & 0 deletions src/plugins/repeater.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Context, Dict, Session, h } from 'koishi'

import BasePlugin from './_boilerplate'

// Types
export interface RepeatState {
content: string
repeated: boolean
times: number
users: Dict<number>
}

export interface Config {
onRepeat?: (state: RepeatState, session: Session) => any
onInterrupt?: (state: RepeatState, session: Session) => any
}

export default class PluginRepeater extends BasePlugin {
constructor(ctx: Context, config?: Config) {
super(ctx, config, 'repeater')

// this.onRepeatHandler()
// this.onInterruptHandler()
this.listenQqEmoji()
}

private readonly statusStore = new Map<string, RepeatState>()
private getStatusKey(session: Session) {
return `${session.platform}:${session.channelId}`
}

onRepeatHandler() {
this.ctx.middleware(async (session, next) => {
await next()
const { content, userId } = session
if (!content) return

const key = this.getStatusKey(session)
let state = this.statusStore.get(key)
if (!state) {
state = {
content,
repeated: false,
times: 1,
users: { [userId]: 1 },
}
this.statusStore.set(key, state)
} else {
if (state.content !== content) {
state.content = content
state.times = 0
state.users = {}
}
state.times += 1
state.users[userId] = (state.users[userId] || 0) + 1
}

if (state.times > 2) {
const msg = this.config.onRepeat?.(state, session)
if (msg) {
state.repeated = true
if (
typeof msg === 'string' ||
Array.isArray(msg) ||
h.isElement(msg)
) {
session.send(msg)
} else {
session.send(content)
}
}
}
})
}

onInterruptHandler() {
this.ctx.middleware(async (session, next) => {
await next()
const { userId, channelId, platform } = session
const key = `${platform}:${channelId}`
const state = this.statusStore.get(key)
if (!state) return

if (state.repeated && state.users[userId] === state.times) {
this.config.onInterrupt?.(state, session)
this.statusStore.delete(key)
}
})
}

// 一些能够接龙的QQ表情
listenQqEmoji() {
const DRAGONS = [392, 393, 394]
const TRAINS = [419, 420, 421]

this.ctx.platform('onebot').middleware(async (session, next) => {
await next()

const faces = h.select(session.elements, 'face')

if (faces.length === 1) {
const faceId = parseInt(faces[0].attrs.id)

// 龙 自动接下一个
if (DRAGONS.includes(faceId)) {
session.send(
h('face', { ...faces[0].attrs, id: Math.min(394, faceId + 1) })
)
}
// TODO: 火车头 不确定机制
else if (TRAINS.includes(faceId)) {
session.send(
h('face', { ...faces[0].attrs, /** id: Math.min(421, faceId + 1) */ })
)
}
}
})
}
}
Loading

0 comments on commit b2b9245

Please sign in to comment.