mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
feat: handle image segment
This commit is contained in:
parent
81daf7ba06
commit
5d145e7f7e
@ -1,7 +1,14 @@
|
|||||||
import { InstanceContext, NapCatCore } from '@/core';
|
import { InstanceContext, NapCatCore } from '@/core';
|
||||||
import { NapCatPathWrapper } from '@/common/path';
|
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 {
|
export class NapCatLaanaAdapter {
|
||||||
|
utils = {
|
||||||
|
msg: new LaanaMessageUtils(this.core, this),
|
||||||
|
file: new LaanaFileUtils(this.core, this),
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public core: NapCatCore,
|
public core: NapCatCore,
|
||||||
public context: InstanceContext,
|
public context: InstanceContext,
|
||||||
|
51
src/laana-v0.1.2/utils/file.ts
Normal file
51
src/laana-v0.1.2/utils/file.ts
Normal 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 }));
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ type Laana2RawConverters = {
|
|||||||
params: SendMessagePing,
|
params: SendMessagePing,
|
||||||
) => PromiseLike<{
|
) => PromiseLike<{
|
||||||
elements: SendMessageElement[],
|
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) {
|
if (msgContent.repliedMsgId) {
|
||||||
const { msgSeq, msgId, senderUin } = (
|
const { msgSeq, msgId, senderUin } = (
|
||||||
@ -49,7 +50,7 @@ export class LaanaMessageUtils {
|
|||||||
[msgContent.repliedMsgId]
|
[msgContent.repliedMsgId]
|
||||||
)
|
)
|
||||||
).msgList[0];
|
).msgList[0];
|
||||||
sendElements.push({
|
elements.push({
|
||||||
elementType: ElementType.REPLY,
|
elementType: ElementType.REPLY,
|
||||||
elementId: '',
|
elementId: '',
|
||||||
replyElement: {
|
replyElement: {
|
||||||
@ -64,7 +65,7 @@ export class LaanaMessageUtils {
|
|||||||
for (const seg of msgContent.segments) {
|
for (const seg of msgContent.segments) {
|
||||||
const content = seg.content;
|
const content = seg.content;
|
||||||
if (content.oneofKind === 'text') {
|
if (content.oneofKind === 'text') {
|
||||||
sendElements.push({
|
elements.push({
|
||||||
elementType: ElementType.TEXT,
|
elementType: ElementType.TEXT,
|
||||||
elementId: '',
|
elementId: '',
|
||||||
textElement: {
|
textElement: {
|
||||||
@ -81,7 +82,7 @@ export class LaanaMessageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (content.at.uin === '0') {
|
if (content.at.uin === '0') {
|
||||||
sendElements.push(at(
|
elements.push(at(
|
||||||
'0', '0',
|
'0', '0',
|
||||||
AtType.atAll,
|
AtType.atAll,
|
||||||
'所有人',
|
'所有人',
|
||||||
@ -91,7 +92,7 @@ export class LaanaMessageUtils {
|
|||||||
const atMember = await this.core.apis.GroupApi
|
const atMember = await this.core.apis.GroupApi
|
||||||
.getGroupMember(params.targetPeer.uin, content.at.uin);
|
.getGroupMember(params.targetPeer.uin, content.at.uin);
|
||||||
if (atMember) {
|
if (atMember) {
|
||||||
sendElements.push(at(
|
elements.push(at(
|
||||||
content.at.uin,
|
content.at.uin,
|
||||||
atMember.uid,
|
atMember.uid,
|
||||||
AtType.atUser,
|
AtType.atUser,
|
||||||
@ -103,7 +104,7 @@ export class LaanaMessageUtils {
|
|||||||
throw '查询用户 UID 失败';
|
throw '查询用户 UID 失败';
|
||||||
}
|
}
|
||||||
const info = await this.core.apis.UserApi.getUserDetailInfo(uid);
|
const info = await this.core.apis.UserApi.getUserDetailInfo(uid);
|
||||||
sendElements.push(at(
|
elements.push(at(
|
||||||
content.at.uin,
|
content.at.uin,
|
||||||
uid,
|
uid,
|
||||||
AtType.atUser,
|
AtType.atUser,
|
||||||
@ -122,7 +123,7 @@ export class LaanaMessageUtils {
|
|||||||
const faceType = parsedFaceId >= 222 ?
|
const faceType = parsedFaceId >= 222 ?
|
||||||
face.AniStickerType ?
|
face.AniStickerType ?
|
||||||
3 : 2 : 1;
|
3 : 2 : 1;
|
||||||
sendElements.push({
|
elements.push({
|
||||||
elementType: ElementType.FACE,
|
elementType: ElementType.FACE,
|
||||||
elementId: '',
|
elementId: '',
|
||||||
faceElement: {
|
faceElement: {
|
||||||
@ -136,14 +137,17 @@ export class LaanaMessageUtils {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (content.oneofKind === 'image') {
|
} else if (content.oneofKind === 'image') {
|
||||||
// TODO: handle file-like messages
|
const cacheId = await this.laana.utils.file.resolveCacheIdFromLaanaFile(content.image);
|
||||||
throw 'Unimplemented';
|
elements.push(await this.core.apis.FileApi.createValidSendPicElement(
|
||||||
|
this.laana.utils.file.toLocalPath(cacheId)
|
||||||
|
));
|
||||||
|
fileCacheIds.push(cacheId);
|
||||||
} else {
|
} else {
|
||||||
throw '未知的消息内容类型';
|
throw '未知的消息内容类型';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { elements: sendElements };
|
return { elements, fileCacheIds };
|
||||||
},
|
},
|
||||||
|
|
||||||
file: () => { throw 'Unimplemented'; },
|
file: () => { throw 'Unimplemented'; },
|
||||||
@ -160,6 +164,7 @@ export class LaanaMessageUtils {
|
|||||||
faceName: msgContent.displayText ?? '[商城表情]',
|
faceName: msgContent.displayText ?? '[商城表情]',
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
|
fileCacheIds: [],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
video: () => { throw 'Unimplemented'; },
|
video: () => { throw 'Unimplemented'; },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user