koishi-plugin-chat-patch 5.3.0 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/web/dist/assets/Chat-Bo5JdcNg.js +28 -0
- package/client/web/dist/assets/{Chat-CTdyeaX2.css → Chat-C-rmzMIw.css} +1 -1
- package/client/web/dist/assets/{MsgBody-DDacjWJ9.js → MsgBody-h4C1nnBQ.js} +1 -1
- package/client/web/dist/assets/{MsgBody.vue_vue_type_script_setup_true_lang-B1dWyCB0.js → MsgBody.vue_vue_type_script_setup_true_lang-a902ps2r.js} +2 -2
- package/client/web/dist/assets/{index-BlLut5xn.js → index-CdTmWcO4.js} +46 -46
- package/client/web/dist/assets/{index-fW_zcub3.css → index-wjp_A4n1.css} +1 -1
- package/client/web/dist/index.html +2 -2
- package/client/web/src/components/AboutPan.vue +2 -1
- package/client/web/src/components/BulletinBody.vue +1 -1
- package/client/web/src/components/FriendBody.vue +1 -0
- package/client/web/src/components/MsgBody.vue +1 -0
- package/client/web/src/components/TinySessionBody.vue +1 -0
- package/client/web/src/components/UpdatePan.vue +2 -2
- package/client/web/src/components/tooltip/UserInfoTooltip.vue +1 -1
- package/client/web/src/function/connect.ts +47 -14
- package/client/web/src/function/satori-model.ts +8 -0
- package/client/web/src/function/satori.ts +31 -1
- package/client/web/src/function/utils/avatarUtil.ts +18 -3
- package/client/web/src/main.ts +5 -0
- package/client/web/src/pages/Chat.vue +3 -4
- package/client/web/src/pages/Friends.vue +23 -17
- package/client/web/src/pages/Info.vue +3 -3
- package/client/web/src/pages/Messages.vue +20 -14
- package/client/web/src/pages/Qzone.vue +2 -2
- package/client/web/src/pages/chat-view/SystemNotice.vue +3 -3
- package/client/web/src/pages/options/OptAccount.vue +6 -4
- package/lib/index.js +14 -14
- package/lib/types.d.ts +115 -0
- package/package.json +1 -1
- package/src/bootstrap.ts +1 -0
- package/src/config.ts +1 -1
- package/src/recorder.ts +7 -7
- package/src/types.ts +4 -0
- package/src/web.ts +8 -9
- package/client/web/dist/assets/Chat-B448YOeN.js +0 -28
|
@@ -38,17 +38,17 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
<div id="message-list-body" class="robot-accordion-list">
|
|
41
|
-
<div v-for="bot in satoriLogins" :key="'bot-' + bot.selfId"
|
|
42
|
-
:class="['robot-accordion', { expanded: bot.selfId === activeBotId }]">
|
|
41
|
+
<div v-for="bot in satoriLogins" :key="'bot-' + botKey(bot.platform, bot.selfId)"
|
|
42
|
+
:class="['robot-accordion', { expanded: botKey(bot.platform, bot.selfId) === activeBotId }]">
|
|
43
43
|
<div class="robot-accordion-header" @click="toggleRobot(bot)">
|
|
44
|
-
<img :src="bot.avatar || '/img/icons/icon.svg'" :alt="bot.name" @error="avatarError">
|
|
44
|
+
<img data-avatar :src="bot.avatar || '/img/icons/icon.svg'" :alt="bot.name" @error="avatarError">
|
|
45
45
|
<div>
|
|
46
46
|
<span :title="bot.name">{{ bot.name }}</span>
|
|
47
47
|
<small>{{ bot.platform }}</small>
|
|
48
48
|
</div>
|
|
49
|
-
<font-awesome-icon :icon="['fas', bot.selfId === activeBotId ? 'angle-up' : 'angle-down']" />
|
|
49
|
+
<font-awesome-icon :icon="['fas', botKey(bot.platform, bot.selfId) === activeBotId ? 'angle-up' : 'angle-down']" />
|
|
50
50
|
</div>
|
|
51
|
-
<div v-if="bot.selfId === activeBotId" class="robot-accordion-content">
|
|
51
|
+
<div v-if="botKey(bot.platform, bot.selfId) === activeBotId" class="robot-accordion-content">
|
|
52
52
|
<div v-if="!showGroupAssist &&
|
|
53
53
|
!contactStore.systemNoticesList &&
|
|
54
54
|
(!contactStore.groupAssistList || contactStore.groupAssistList.length === 0) &&
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
219
219
|
import { login as loginInfo } from '../function/connect'
|
|
220
220
|
import { Connector, flushPendingBotEvents, loadContactsFromCache, restoreBotStateFromMessageCache } from '../function/connect'
|
|
221
|
-
import { getActiveBot, getLogins, setActiveBot } from '../function/satori'
|
|
221
|
+
import { botKey, getActiveBot, getLogins, setActiveBot } from '../function/satori'
|
|
222
222
|
import { getShowName, updateBaseOnMsgList } from '../function/utils/msgUtil'
|
|
223
223
|
|
|
224
224
|
import {
|
|
@@ -249,7 +249,12 @@
|
|
|
249
249
|
const chatStore = useChatStore()
|
|
250
250
|
const settingsStore = useSettingsStore()
|
|
251
251
|
const satoriLogins = ref<Array<{ platform: string; selfId: string; name: string; avatar?: string; status?: number; features?: string[] }>>(getLogins())
|
|
252
|
-
const
|
|
252
|
+
const active = getActiveBot()
|
|
253
|
+
const activeBotId = ref(
|
|
254
|
+
active?.platform && active.selfId
|
|
255
|
+
? botKey(active.platform, active.selfId)
|
|
256
|
+
: loginInfo.selectedSatoriBot ?? '',
|
|
257
|
+
)
|
|
253
258
|
|
|
254
259
|
watch(() => loginInfo.satoriLogins, (list) => {
|
|
255
260
|
satoriLogins.value = list ?? []
|
|
@@ -259,7 +264,7 @@
|
|
|
259
264
|
}, { immediate: true })
|
|
260
265
|
|
|
261
266
|
const currentBotName = computed(() => {
|
|
262
|
-
return satoriLogins.value.find((item) => item.selfId === activeBotId.value)?.name ?? ''
|
|
267
|
+
return satoriLogins.value.find((item) => botKey(item.platform, item.selfId) === activeBotId.value)?.name ?? ''
|
|
263
268
|
})
|
|
264
269
|
|
|
265
270
|
function backToRobots() {
|
|
@@ -280,7 +285,7 @@
|
|
|
280
285
|
}
|
|
281
286
|
|
|
282
287
|
function restoreBotStateUi(bot: { platform: string; selfId: string }) {
|
|
283
|
-
const restored = contactStore.botStates.get(bot.selfId)
|
|
288
|
+
const restored = contactStore.botStates.get(botKey(bot.platform, bot.selfId))
|
|
284
289
|
if (!restored) return
|
|
285
290
|
contactStore.baseOnMsgList.clear()
|
|
286
291
|
for (const [, value] of restored.baseList) {
|
|
@@ -309,9 +314,10 @@
|
|
|
309
314
|
}
|
|
310
315
|
|
|
311
316
|
function selectRobot(bot: { platform: string; selfId: string; name: string; avatar?: string; features?: string[] }) {
|
|
312
|
-
|
|
317
|
+
const key = botKey(bot.platform, bot.selfId)
|
|
318
|
+
if (key === activeBotId.value) return
|
|
313
319
|
snapshotCurrentBot()
|
|
314
|
-
activeBotId.value =
|
|
320
|
+
activeBotId.value = key
|
|
315
321
|
setActiveBot(bot.platform, bot.selfId)
|
|
316
322
|
loginInfo.uin = bot.selfId
|
|
317
323
|
loginInfo.nickname = bot.name
|
|
@@ -324,9 +330,9 @@
|
|
|
324
330
|
platform: bot.platform,
|
|
325
331
|
avatar: bot.avatar,
|
|
326
332
|
satoriLogins: satoriLogins.value,
|
|
327
|
-
selectedSatoriBot:
|
|
333
|
+
selectedSatoriBot: key,
|
|
328
334
|
}
|
|
329
|
-
const saved = contactStore.botStates.get(
|
|
335
|
+
const saved = contactStore.botStates.get(key)
|
|
330
336
|
if (saved) {
|
|
331
337
|
contactStore.userList = saved.userList
|
|
332
338
|
contactStore.baseOnMsgList.clear()
|
|
@@ -354,7 +360,7 @@
|
|
|
354
360
|
}
|
|
355
361
|
|
|
356
362
|
function toggleRobot(bot: { platform: string; selfId: string; name: string; avatar?: string; features?: string[] }) {
|
|
357
|
-
if (activeBotId.value === bot.selfId) {
|
|
363
|
+
if (activeBotId.value === botKey(bot.platform, bot.selfId)) {
|
|
358
364
|
backToRobots()
|
|
359
365
|
} else {
|
|
360
366
|
selectRobot(bot)
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
class="qzone-feed-card ss-card">
|
|
66
66
|
<article>
|
|
67
67
|
<header class="qzone-feed-card-header">
|
|
68
|
-
<img :src="item.avatar" :alt="item.nickname">
|
|
68
|
+
<img data-avatar :src="item.avatar" :alt="item.nickname">
|
|
69
69
|
<div class="qzone-feed-meta">
|
|
70
70
|
<a>{{ item.nickname }}</a>
|
|
71
71
|
<span>{{ item.timeText }}</span>
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
</template>
|
|
150
150
|
</div>
|
|
151
151
|
<div class="qzone-feed-reply">
|
|
152
|
-
<img :src="authStore.loginInfo.avatar || '/img/icons/icon.svg'">
|
|
152
|
+
<img data-avatar :src="authStore.loginInfo.avatar || '/img/icons/icon.svg'">
|
|
153
153
|
<label :for="`qzone-reply-input-${item.id}`" class="sr-only">{{ $t('评论输入框') }}</label>
|
|
154
154
|
<input :id="`qzone-reply-input-${item.id}`"
|
|
155
155
|
v-model="getReplyDraft(item.id).content"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
:key="'sysNot-' + index">
|
|
21
21
|
<div v-if="notice.request_type == 'friend'">
|
|
22
22
|
<div>
|
|
23
|
-
<img :src="notice.avatar || '/img/icons/icon.svg'">
|
|
23
|
+
<img data-avatar :src="notice.avatar || '/img/icons/icon.svg'">
|
|
24
24
|
<div>
|
|
25
25
|
<span>{{ notice.user_id }}
|
|
26
26
|
{{ $t('请求加为好友') }}</span>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
<div v-else-if="notice.request_type == 'group'">
|
|
51
51
|
<div v-if="notice.sub_type == 'add'">
|
|
52
|
-
<img :src="notice.avatar || '/img/icons/icon.svg'">
|
|
52
|
+
<img data-avatar :src="notice.avatar || '/img/icons/icon.svg'">
|
|
53
53
|
<div>
|
|
54
54
|
<span>{{ getName(notice.user_id) }}
|
|
55
55
|
{{ $t('申请加入群聊') }}
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
</div>
|
|
69
69
|
<div v-else>
|
|
70
70
|
<!-- TODO:这情况会出现在 notice 里?记不太清了,先放着吧 😭 -->
|
|
71
|
-
<img :src="notice.group_avatar || '/img/icons/icon.svg'">
|
|
71
|
+
<img data-avatar :src="notice.group_avatar || '/img/icons/icon.svg'">
|
|
72
72
|
<div>
|
|
73
73
|
<span>{{ getName(notice.user_id) }}
|
|
74
74
|
{{ $t('邀请你加入群聊') }}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<div v-for="account in accounts"
|
|
14
14
|
:key="account.platform + ':' + account.selfId"
|
|
15
15
|
:class="['ss-card', 'account-info', { active: isActive(account) }]">
|
|
16
|
-
<img :src="account.avatar || '/img/icons/icon.svg'">
|
|
16
|
+
<img data-avatar :src="account.avatar || '/img/icons/icon.svg'">
|
|
17
17
|
<div>
|
|
18
18
|
<div>
|
|
19
19
|
<span>{{ account.name || account.selfId }}</span>
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
<script setup lang="ts">
|
|
39
39
|
import { computed } from 'vue'
|
|
40
40
|
import { login as loginInfo } from '../../function/connect'
|
|
41
|
-
import { getActiveBot } from '../../function/satori'
|
|
41
|
+
import { botKey, getActiveBot, getLogins } from '../../function/satori'
|
|
42
42
|
import { useAuthStore } from '../../state/auth'
|
|
43
43
|
import { i18n } from '../../main'
|
|
44
44
|
|
|
@@ -63,9 +63,11 @@ const accounts = computed<SatoriAccount[]>(() => {
|
|
|
63
63
|
const activeBot = computed(() => {
|
|
64
64
|
const current = getActiveBot()
|
|
65
65
|
if (current?.platform && current.selfId) return current
|
|
66
|
+
const selectedKey = String(authStore.loginInfo.selectedSatoriBot ?? '')
|
|
67
|
+
const selected = getLogins().find((item) => botKey(item.platform, item.selfId) === selectedKey)
|
|
66
68
|
return {
|
|
67
|
-
platform: String(authStore.loginInfo.platform ?? ''),
|
|
68
|
-
selfId: String(
|
|
69
|
+
platform: String(selected?.platform ?? authStore.loginInfo.platform ?? ''),
|
|
70
|
+
selfId: String(selected?.selfId ?? authStore.loginInfo.uin ?? ''),
|
|
69
71
|
}
|
|
70
72
|
})
|
|
71
73
|
|
package/lib/index.js
CHANGED
|
@@ -844,8 +844,8 @@ var _Recorder = class _Recorder {
|
|
|
844
844
|
}
|
|
845
845
|
async handleSession(session) {
|
|
846
846
|
const platform = session.platform || "unknown";
|
|
847
|
-
if (this.isBlocked(platform)) return;
|
|
848
847
|
if (!MESSAGE_TYPES.has(session.type)) return;
|
|
848
|
+
if (this.isBlocked(platform)) return;
|
|
849
849
|
const event = session.toJSON();
|
|
850
850
|
const message = event.message;
|
|
851
851
|
const record = {
|
|
@@ -866,15 +866,15 @@ var _Recorder = class _Recorder {
|
|
|
866
866
|
};
|
|
867
867
|
try {
|
|
868
868
|
await this.database.appendMessage(record);
|
|
869
|
-
void this.cacheMessageContacts(event).catch((error) => {
|
|
870
|
-
this.logger.warn("缓存消息联系人失败:", error);
|
|
871
|
-
});
|
|
872
|
-
void this.cacheMessageMedia(event).catch((error) => {
|
|
873
|
-
this.logger.warn("异步缓存消息媒体失败:", error);
|
|
874
|
-
});
|
|
875
869
|
} catch (error) {
|
|
876
870
|
this.logger.warn("写入历史消息失败:", error);
|
|
877
871
|
}
|
|
872
|
+
void this.cacheMessageContacts(event).catch((error) => {
|
|
873
|
+
this.logger.warn("缓存消息联系人失败:", error);
|
|
874
|
+
});
|
|
875
|
+
void this.cacheMessageMedia(event).catch((error) => {
|
|
876
|
+
this.logger.warn("异步缓存消息媒体失败:", error);
|
|
877
|
+
});
|
|
878
878
|
}
|
|
879
879
|
async cacheMessageContacts(event) {
|
|
880
880
|
const platform = event.platform || "";
|
|
@@ -1622,7 +1622,8 @@ function registerBootstrap(ctx, config, database, logger) {
|
|
|
1622
1622
|
return {
|
|
1623
1623
|
endpoint: resolveEndpoint(ctx, config),
|
|
1624
1624
|
token: ctx.satori?.server?.config?.token ?? "",
|
|
1625
|
-
basePath: config.basePath
|
|
1625
|
+
basePath: config.basePath,
|
|
1626
|
+
blockedPlatforms: config.blockedPlatforms ?? []
|
|
1626
1627
|
};
|
|
1627
1628
|
}, { authority: 4 });
|
|
1628
1629
|
ctx.console.addListener("chat-patch/history", async (query) => {
|
|
@@ -1706,13 +1707,12 @@ function registerWeb(ctx, config, database, contactCache, logger) {
|
|
|
1706
1707
|
koa.status = 404;
|
|
1707
1708
|
koa.body = "";
|
|
1708
1709
|
}, "servePublicFile");
|
|
1709
|
-
const
|
|
1710
|
-
ctx.server.get(pattern, async (koa
|
|
1711
|
-
if (!getVite()) return next();
|
|
1710
|
+
const registerPublic = /* @__PURE__ */ __name((pattern, prefix) => {
|
|
1711
|
+
ctx.server.get(pattern, async (koa) => {
|
|
1712
1712
|
await servePublicFile(koa, prefix);
|
|
1713
1713
|
});
|
|
1714
|
-
}, "
|
|
1715
|
-
|
|
1714
|
+
}, "registerPublic");
|
|
1715
|
+
registerPublic("/img(.*)", "img");
|
|
1716
1716
|
const toExtension2 = /* @__PURE__ */ __name((value) => {
|
|
1717
1717
|
const ext = value.startsWith(".") ? value : `.${value}`;
|
|
1718
1718
|
return ext.toLowerCase();
|
|
@@ -2283,7 +2283,7 @@ var Config = import_koishi2.Schema.intersect([
|
|
|
2283
2283
|
blockedPlatforms: import_koishi2.Schema.array(import_koishi2.Schema.object({
|
|
2284
2284
|
platformName: import_koishi2.Schema.string(),
|
|
2285
2285
|
exactMatch: import_koishi2.Schema.boolean().default(true)
|
|
2286
|
-
})).role("table").description("
|
|
2286
|
+
})).role("table").description("屏蔽消息接收的平台").default([
|
|
2287
2287
|
{ platformName: "qq", exactMatch: true },
|
|
2288
2288
|
{ platformName: "qqguild", exactMatch: true },
|
|
2289
2289
|
{ platformName: "sandbox", exactMatch: false }
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { Awaitable } from 'koishi';
|
|
2
|
+
export interface SatoriBootstrap {
|
|
3
|
+
endpoint: string;
|
|
4
|
+
token: string;
|
|
5
|
+
basePath: string;
|
|
6
|
+
blockedPlatforms: Array<{
|
|
7
|
+
platformName: string;
|
|
8
|
+
exactMatch: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export interface MessageRecord {
|
|
12
|
+
id?: string;
|
|
13
|
+
sequence?: number;
|
|
14
|
+
type: string;
|
|
15
|
+
platform: string;
|
|
16
|
+
selfId: string;
|
|
17
|
+
channelId?: string;
|
|
18
|
+
guildId?: string;
|
|
19
|
+
userId?: string;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
timestampMs?: number;
|
|
22
|
+
receivedAt?: number;
|
|
23
|
+
content?: string;
|
|
24
|
+
elements?: unknown[];
|
|
25
|
+
raw?: unknown;
|
|
26
|
+
}
|
|
27
|
+
export type SelfMessageChannelType = 'group' | 'user';
|
|
28
|
+
export type SelfMessageSource = 'webui' | 'bot' | 'plugin';
|
|
29
|
+
export interface SelfMessageRecord {
|
|
30
|
+
id: string;
|
|
31
|
+
platform: string;
|
|
32
|
+
selfId: string;
|
|
33
|
+
channelId: string;
|
|
34
|
+
guildId?: string;
|
|
35
|
+
channelType?: SelfMessageChannelType;
|
|
36
|
+
messageId?: string;
|
|
37
|
+
content?: string;
|
|
38
|
+
elements?: unknown[];
|
|
39
|
+
message?: unknown[];
|
|
40
|
+
forwardId?: string;
|
|
41
|
+
forwardContent?: unknown[];
|
|
42
|
+
sentAt: number;
|
|
43
|
+
sequence: number;
|
|
44
|
+
source: SelfMessageSource;
|
|
45
|
+
kind: string;
|
|
46
|
+
fingerprint?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface SelfMessagePayload {
|
|
49
|
+
id?: string;
|
|
50
|
+
platform: string;
|
|
51
|
+
selfId: string;
|
|
52
|
+
channelId: string;
|
|
53
|
+
guildId?: string;
|
|
54
|
+
channelType?: SelfMessageChannelType;
|
|
55
|
+
messageId?: string;
|
|
56
|
+
content?: string;
|
|
57
|
+
elements?: unknown[];
|
|
58
|
+
message?: unknown[];
|
|
59
|
+
forwardId?: string;
|
|
60
|
+
forwardContent?: unknown[];
|
|
61
|
+
sentAt?: number;
|
|
62
|
+
sequence?: number;
|
|
63
|
+
source?: SelfMessageSource;
|
|
64
|
+
kind?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface HistoryQuery {
|
|
67
|
+
platform: string;
|
|
68
|
+
selfId: string;
|
|
69
|
+
channelId: string;
|
|
70
|
+
limit?: number;
|
|
71
|
+
}
|
|
72
|
+
export interface HistoryResult {
|
|
73
|
+
messages: MessageRecord[];
|
|
74
|
+
}
|
|
75
|
+
export interface PinnedState {
|
|
76
|
+
bots: string[];
|
|
77
|
+
channels: string[];
|
|
78
|
+
}
|
|
79
|
+
export interface PluginConfigPayload {
|
|
80
|
+
basePath: string;
|
|
81
|
+
maxMessagesPerChannel: number;
|
|
82
|
+
historyPageSize: number;
|
|
83
|
+
maxMediaFiles: number;
|
|
84
|
+
blockedPlatforms: Array<{
|
|
85
|
+
platformName: string;
|
|
86
|
+
exactMatch: boolean;
|
|
87
|
+
}>;
|
|
88
|
+
loggerinfo: boolean;
|
|
89
|
+
}
|
|
90
|
+
export interface ContactCacheItem {
|
|
91
|
+
id: string;
|
|
92
|
+
name: string;
|
|
93
|
+
avatar?: string;
|
|
94
|
+
channelId?: string;
|
|
95
|
+
guildId?: string;
|
|
96
|
+
raw?: unknown;
|
|
97
|
+
}
|
|
98
|
+
export interface ContactCacheQuery {
|
|
99
|
+
platform: string;
|
|
100
|
+
selfId: string;
|
|
101
|
+
type: string;
|
|
102
|
+
contacts?: ContactCacheItem[];
|
|
103
|
+
append?: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface ContactCacheResult {
|
|
106
|
+
contacts?: ContactCacheItem[];
|
|
107
|
+
}
|
|
108
|
+
declare module '@koishijs/console' {
|
|
109
|
+
interface Events {
|
|
110
|
+
'chat-patch/bootstrap'(): SatoriBootstrap;
|
|
111
|
+
'chat-patch/history'(query: HistoryQuery): Awaitable<HistoryResult>;
|
|
112
|
+
'chat-patch/config'(): PluginConfigPayload;
|
|
113
|
+
'chat-patch/contact-cache'(query: ContactCacheQuery): Awaitable<ContactCacheResult>;
|
|
114
|
+
}
|
|
115
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-chat-patch",
|
|
3
3
|
"description": "[<ruby>chat-patch<rp>(</rp><rt>点我预览效果</rt><rp>)</rp></ruby>](https://i0.hdslb.com/bfs/openplatform/71074dfc9e5256fc3333d8bd8478bec1af874046.png) 视奸小插件((bushi( (低性能警告)。手机端适配。灵感来自 chat 插件。",
|
|
4
|
-
"version": "5.3.
|
|
4
|
+
"version": "5.3.1",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:web": "npm --prefix client/web run build",
|
|
7
7
|
"prepack": "npm run build:web",
|
package/src/bootstrap.ts
CHANGED
package/src/config.ts
CHANGED
|
@@ -25,7 +25,7 @@ export const Config: Schema<Config> = Schema.intersect([
|
|
|
25
25
|
blockedPlatforms: Schema.array(Schema.object({
|
|
26
26
|
platformName: Schema.string(),
|
|
27
27
|
exactMatch: Schema.boolean().default(true),
|
|
28
|
-
})).role('table').description('
|
|
28
|
+
})).role('table').description('屏蔽消息接收的平台').default([
|
|
29
29
|
{ platformName: 'qq', exactMatch: true },
|
|
30
30
|
{ platformName: 'qqguild', exactMatch: true },
|
|
31
31
|
{ platformName: 'sandbox', exactMatch: false },
|
package/src/recorder.ts
CHANGED
|
@@ -41,8 +41,8 @@ export class Recorder {
|
|
|
41
41
|
|
|
42
42
|
private async handleSession(session: Session) {
|
|
43
43
|
const platform = session.platform || 'unknown'
|
|
44
|
-
if (this.isBlocked(platform)) return
|
|
45
44
|
if (!MESSAGE_TYPES.has(session.type)) return
|
|
45
|
+
if (this.isBlocked(platform)) return
|
|
46
46
|
|
|
47
47
|
const event = session.toJSON()
|
|
48
48
|
const message = event.message
|
|
@@ -65,15 +65,15 @@ export class Recorder {
|
|
|
65
65
|
|
|
66
66
|
try {
|
|
67
67
|
await this.database.appendMessage(record)
|
|
68
|
-
void this.cacheMessageContacts(event).catch((error) => {
|
|
69
|
-
this.logger.warn('缓存消息联系人失败:', error)
|
|
70
|
-
})
|
|
71
|
-
void this.cacheMessageMedia(event).catch((error) => {
|
|
72
|
-
this.logger.warn('异步缓存消息媒体失败:', error)
|
|
73
|
-
})
|
|
74
68
|
} catch (error) {
|
|
75
69
|
this.logger.warn('写入历史消息失败:', error)
|
|
76
70
|
}
|
|
71
|
+
void this.cacheMessageContacts(event).catch((error) => {
|
|
72
|
+
this.logger.warn('缓存消息联系人失败:', error)
|
|
73
|
+
})
|
|
74
|
+
void this.cacheMessageMedia(event).catch((error) => {
|
|
75
|
+
this.logger.warn('异步缓存消息媒体失败:', error)
|
|
76
|
+
})
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
private async cacheMessageContacts(event: ReturnType<Session['toJSON']>) {
|
package/src/types.ts
CHANGED
package/src/web.ts
CHANGED
|
@@ -82,15 +82,14 @@ export function registerWeb(
|
|
|
82
82
|
koa.body = ''
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// web 应用里仍有 /img
|
|
86
|
-
const
|
|
87
|
-
ctx.server.get(pattern, async (koa: WebContext
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
registerDevPublic('/img(.*)', 'img')
|
|
85
|
+
// web 应用里仍有 /img 这类运行时绝对路径,生产/开发模式都要由 Koishi 服务托管
|
|
86
|
+
const registerPublic = (pattern: string, prefix: string) => {
|
|
87
|
+
ctx.server.get(pattern, async (koa: WebContext) => {
|
|
88
|
+
await servePublicFile(koa, prefix)
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
registerPublic('/img(.*)', 'img')
|
|
94
93
|
|
|
95
94
|
const toExtension = (value: string): string => {
|
|
96
95
|
const ext = value.startsWith('.') ? value : `.${value}`
|