feat: handle image segment

This commit is contained in:
Seijo Cecilia 2024-09-02 15:55:31 +08:00
parent 81daf7ba06
commit 5d145e7f7e
3 changed files with 74 additions and 11 deletions

View File

@ -1,7 +1,14 @@
import { InstanceContext, NapCatCore } from '@/core';
import { NapCatPathWrapper } from '@/common/path';
import { LaanaFileUtils } from '@/laana-v0.1.2/utils/file';
import { LaanaMessageUtils } from '@/laana-v0.1.2/utils/message';
export class NapCatLaanaAdapter {
utils = {
msg: new LaanaMessageUtils(this.core, this),
file: new LaanaFileUtils(this.core, this),
};
constructor(
public core: NapCatCore,
public context: InstanceContext,

View File

@ -0,0 +1,51 @@
import { NapCatCore } from '@/core';
import { NapCatLaanaAdapter } from '..';
import { File as LaanaFile } from '@/laana-v0.1.2/types/entity/file';
import path from 'path';
import fs from 'fs';
import fsPromises from 'fs/promises';
import { httpDownload } from '@/common/file';
import { randomUUID } from 'crypto';
export class LaanaFileUtils {
cacheDir = path.join(this.laana.pathWrapper.cachePath, 'laana');
constructor(
public core: NapCatCore,
public laana: NapCatLaanaAdapter,
) {
}
async resolveCacheIdFromLaanaFile(laanaFile: LaanaFile) {
if (laanaFile.uri.oneofKind === 'cacheId') {
const cacheFilePath = path.join(this.cacheDir, laanaFile.uri.cacheId);
if (!fs.existsSync(cacheFilePath)) {
throw `请求的缓存不存在: ${laanaFile.uri.cacheId}`;
}
return laanaFile.uri.cacheId;
} else if (laanaFile.uri.oneofKind === 'url') {
return this.createCacheFromUrl(laanaFile.uri.url);
} else if (laanaFile.uri.oneofKind === 'raw') {
return this.createCacheFromBytes(laanaFile.uri.raw);
} else {
throw '不支持的缓存类型';
}
}
toLocalPath(cacheId: string) {
return path.join(this.cacheDir, cacheId);
}
async createCacheFromBytes(bytes: Uint8Array) {
let cacheId = randomUUID();
while (fs.existsSync(cacheId)) {
cacheId = randomUUID();
}
await fsPromises.writeFile(path.join(this.cacheDir, cacheId), bytes);
return cacheId;
}
async createCacheFromUrl(url: string) {
return this.createCacheFromBytes(await httpDownload({ url }));
}
}

View File

@ -13,7 +13,7 @@ type Laana2RawConverters = {
params: SendMessagePing,
) => PromiseLike<{
elements: SendMessageElement[],
fileCacheId?: string[],
fileCacheIds: string[],
}>
}
@ -40,7 +40,8 @@ export class LaanaMessageUtils {
};
}
const sendElements: SendMessageElement[] = [];
const elements: SendMessageElement[] = [];
const fileCacheIds: string[] = [];
if (msgContent.repliedMsgId) {
const { msgSeq, msgId, senderUin } = (
@ -49,7 +50,7 @@ export class LaanaMessageUtils {
[msgContent.repliedMsgId]
)
).msgList[0];
sendElements.push({
elements.push({
elementType: ElementType.REPLY,
elementId: '',
replyElement: {
@ -64,7 +65,7 @@ export class LaanaMessageUtils {
for (const seg of msgContent.segments) {
const content = seg.content;
if (content.oneofKind === 'text') {
sendElements.push({
elements.push({
elementType: ElementType.TEXT,
elementId: '',
textElement: {
@ -81,7 +82,7 @@ export class LaanaMessageUtils {
}
if (content.at.uin === '0') {
sendElements.push(at(
elements.push(at(
'0', '0',
AtType.atAll,
'所有人',
@ -91,7 +92,7 @@ export class LaanaMessageUtils {
const atMember = await this.core.apis.GroupApi
.getGroupMember(params.targetPeer.uin, content.at.uin);
if (atMember) {
sendElements.push(at(
elements.push(at(
content.at.uin,
atMember.uid,
AtType.atUser,
@ -103,7 +104,7 @@ export class LaanaMessageUtils {
throw '查询用户 UID 失败';
}
const info = await this.core.apis.UserApi.getUserDetailInfo(uid);
sendElements.push(at(
elements.push(at(
content.at.uin,
uid,
AtType.atUser,
@ -122,7 +123,7 @@ export class LaanaMessageUtils {
const faceType = parsedFaceId >= 222 ?
face.AniStickerType ?
3 : 2 : 1;
sendElements.push({
elements.push({
elementType: ElementType.FACE,
elementId: '',
faceElement: {
@ -136,14 +137,17 @@ export class LaanaMessageUtils {
},
});
} else if (content.oneofKind === 'image') {
// TODO: handle file-like messages
throw 'Unimplemented';
const cacheId = await this.laana.utils.file.resolveCacheIdFromLaanaFile(content.image);
elements.push(await this.core.apis.FileApi.createValidSendPicElement(
this.laana.utils.file.toLocalPath(cacheId)
));
fileCacheIds.push(cacheId);
} else {
throw '未知的消息内容类型';
}
}
return { elements: sendElements };
return { elements, fileCacheIds };
},
file: () => { throw 'Unimplemented'; },
@ -160,6 +164,7 @@ export class LaanaMessageUtils {
faceName: msgContent.displayText ?? '[商城表情]',
},
}],
fileCacheIds: [],
}),
video: () => { throw 'Unimplemented'; },