mirror of
https://github.com/chrononeko/chronocat.git
synced 2024-11-25 09:37:35 +00:00
feat: support marketface
This commit is contained in:
parent
60fa49ae01
commit
72cdae235e
@ -1,31 +1,63 @@
|
|||||||
import type { Media } from '@chronocat/red'
|
import type { AssetRequest } from '@chronocat/red'
|
||||||
import { ChatType } from '@chronocat/red'
|
import { ChatType } from '@chronocat/red'
|
||||||
import type { ChronocatContext } from '@chronocat/shell'
|
import type { ChronocatContext } from '@chronocat/shell'
|
||||||
import { downloadRichMedia } from '../../../definitions/msgService'
|
import {
|
||||||
import { richMediaDownloadMap } from '../../../globalVars'
|
downloadRichMedia,
|
||||||
|
fetchMarketEmoticonAioImage,
|
||||||
|
} from '../../../definitions/msgService'
|
||||||
|
import { emojiDownloadMap, richMediaDownloadMap } from '../../../globalVars'
|
||||||
|
|
||||||
export const buildAssetsGet =
|
export const buildAssetsGet =
|
||||||
(ctx: ChronocatContext) => async (raw: string) => {
|
(ctx: ChronocatContext) => async (raw: string) => {
|
||||||
const data = JSON.parse(
|
const data = JSON.parse(
|
||||||
Buffer.from(raw, 'base64url').toString('utf-8'),
|
Buffer.from(raw, 'base64url').toString('utf-8'),
|
||||||
) as Media
|
) as AssetRequest
|
||||||
|
|
||||||
const downloadId = data.msgId + '::' + data.elementId
|
if ('type' in data) {
|
||||||
|
switch (data.type) {
|
||||||
|
case 'marketface': {
|
||||||
|
const downloadId = data.tabId + '::' + data.faceId
|
||||||
|
|
||||||
const downloadCompletePromise = new Promise<string>((res, rej) => {
|
const downloadCompletePromise = new Promise<string>((res, rej) => {
|
||||||
richMediaDownloadMap[downloadId] = res
|
emojiDownloadMap[downloadId] = res
|
||||||
void ctx.chronocat.sleep(1000).then(rej)
|
void ctx.chronocat.sleep(5000).then(rej)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (data.chatType === ChatType.Private && !data.peerUid.startsWith('u_'))
|
await fetchMarketEmoticonAioImage({
|
||||||
data.peerUid = ctx.chronocat.uix.getUid(data.peerUid)!
|
marketEmoticonAioImageReq: {
|
||||||
|
eId: data.faceId,
|
||||||
|
epId: data.tabId,
|
||||||
|
name: data.name,
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
jobType: 0,
|
||||||
|
encryptKey: data.key,
|
||||||
|
filePath: data.filePath,
|
||||||
|
downloadType: 3,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
await downloadRichMedia({
|
return await downloadCompletePromise
|
||||||
getReq: {
|
}
|
||||||
...data,
|
}
|
||||||
downloadType: 1,
|
} else {
|
||||||
},
|
const downloadId = data.msgId + '::' + data.elementId
|
||||||
})
|
|
||||||
|
|
||||||
return await downloadCompletePromise
|
const downloadCompletePromise = new Promise<string>((res, rej) => {
|
||||||
|
richMediaDownloadMap[downloadId] = res
|
||||||
|
void ctx.chronocat.sleep(1000).then(rej)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (data.chatType === ChatType.Private && !data.peerUid.startsWith('u_'))
|
||||||
|
data.peerUid = ctx.chronocat.uix.getUid(data.peerUid)!
|
||||||
|
|
||||||
|
await downloadRichMedia({
|
||||||
|
getReq: {
|
||||||
|
...data,
|
||||||
|
downloadType: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return await downloadCompletePromise
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,6 +277,19 @@ export class Messager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case `${this.ctx.chronocat.platform}:marketface`: {
|
||||||
|
this.children.push(
|
||||||
|
r.marketFace(
|
||||||
|
Number(attrs['tabId']),
|
||||||
|
attrs['faceId'] as string,
|
||||||
|
attrs['key'] as string,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
this.isEndLine = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
case 'quote': {
|
case 'quote': {
|
||||||
const [author] = this.ctx.chronocat.h.select(children, 'author')
|
const [author] = this.ctx.chronocat.h.select(children, 'author')
|
||||||
|
|
||||||
|
@ -114,6 +114,28 @@ const b = () => {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
marketFace: (
|
||||||
|
tabId: number,
|
||||||
|
faceId: string,
|
||||||
|
key: string,
|
||||||
|
): O.Partial<Element, 'deep'> => ({
|
||||||
|
elementType: 11,
|
||||||
|
elementId: '',
|
||||||
|
marketFaceElement: {
|
||||||
|
itemType: 6,
|
||||||
|
faceInfo: 1,
|
||||||
|
emojiPackageId: tabId,
|
||||||
|
subType: 3,
|
||||||
|
mediaType: 0,
|
||||||
|
imageWidth: 200,
|
||||||
|
imageHeight: 200,
|
||||||
|
faceName: '[动画表情]',
|
||||||
|
emojiId: faceId,
|
||||||
|
key: key,
|
||||||
|
emojiType: 1,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
pcPoke: (pokeType: number): O.Partial<Element, 'deep'> => ({
|
pcPoke: (pokeType: number): O.Partial<Element, 'deep'> => ({
|
||||||
elementId: '0',
|
elementId: '0',
|
||||||
elementType: 6,
|
elementType: 6,
|
||||||
|
@ -151,3 +151,22 @@ export const deleteActiveChatByUid = define<Record<string, never>, [string]>(
|
|||||||
'ns-ntApi-2',
|
'ns-ntApi-2',
|
||||||
'nodeIKernelMsgService/deleteActiveChatByUid',
|
'nodeIKernelMsgService/deleteActiveChatByUid',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const fetchMarketEmoticonAioImage = define<
|
||||||
|
never,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
marketEmoticonAioImageReq: {
|
||||||
|
eId: string // '94c8ffa6977fd17e8b180b312cdddc28'
|
||||||
|
epId: number // 235125
|
||||||
|
name: string // '[抱抱]'
|
||||||
|
width: 200
|
||||||
|
height: 200
|
||||||
|
jobType: 0
|
||||||
|
encryptKey: string // 'ea4dc6c26b6f9c31'
|
||||||
|
filePath: string
|
||||||
|
downloadType: 3 | 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
>('ns-ntApi-2', 'nodeIKernelMsgService/fetchMarketEmoticonAioImage')
|
||||||
|
@ -11,6 +11,7 @@ export const groupMap: Record<string, Group> = {}
|
|||||||
export const roleMap: Record<string, Record<string, number>> = {}
|
export const roleMap: Record<string, Record<string, number>> = {}
|
||||||
export const friendMap: Record<string, Profile> = {}
|
export const friendMap: Record<string, Profile> = {}
|
||||||
export const richMediaDownloadMap: Record<string, (path: string) => void> = {}
|
export const richMediaDownloadMap: Record<string, (path: string) => void> = {}
|
||||||
|
export const emojiDownloadMap: Record<string, (path: string) => void> = {}
|
||||||
|
|
||||||
export const sendQueue: ((msg: RedMessage) => void)[] = []
|
export const sendQueue: ((msg: RedMessage) => void)[] = []
|
||||||
export const sendCallbackMap: Record<string, (msg: RedMessage) => void> = {}
|
export const sendCallbackMap: Record<string, (msg: RedMessage) => void> = {}
|
||||||
|
@ -3,6 +3,7 @@ import type {
|
|||||||
MsgsIncludeSelf,
|
MsgsIncludeSelf,
|
||||||
OnAddSendMsg,
|
OnAddSendMsg,
|
||||||
OnBuddyListChange,
|
OnBuddyListChange,
|
||||||
|
OnEmojiDownloadComplete,
|
||||||
OnGroupListUpdate,
|
OnGroupListUpdate,
|
||||||
OnMemberInfoChange,
|
OnMemberInfoChange,
|
||||||
OnMemberListChange,
|
OnMemberListChange,
|
||||||
@ -20,6 +21,7 @@ import type { ChronocatContext } from '@chronocat/shell'
|
|||||||
import type { IpcManData } from 'ipcman'
|
import type { IpcManData } from 'ipcman'
|
||||||
import {
|
import {
|
||||||
chronoEventEmitter,
|
chronoEventEmitter,
|
||||||
|
emojiDownloadMap,
|
||||||
friendMap,
|
friendMap,
|
||||||
groupMap,
|
groupMap,
|
||||||
requestCallbackMap,
|
requestCallbackMap,
|
||||||
@ -131,6 +133,19 @@ const responseDispatcher = async (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'nodeIKernelMsgListener/onEmojiDownloadComplete': {
|
||||||
|
const { notifyInfo } = payload as OnEmojiDownloadComplete
|
||||||
|
|
||||||
|
const downloadId = `${notifyInfo.emojiPackageId}::${notifyInfo.emojiId}`
|
||||||
|
|
||||||
|
if (notifyInfo.downloadType === 0 && emojiDownloadMap[downloadId]) {
|
||||||
|
emojiDownloadMap[downloadId]!(notifyInfo.path)
|
||||||
|
delete emojiDownloadMap[downloadId]
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
case 'nodeIKernelProfileListener/onProfileSimpleChanged':
|
case 'nodeIKernelProfileListener/onProfileSimpleChanged':
|
||||||
case 'nodeIKernelProfileListener/onProfileDetailInfoChanged':
|
case 'nodeIKernelProfileListener/onProfileDetailInfoChanged':
|
||||||
case 'nodeIKernelGroupListener/onSearchMemberChange':
|
case 'nodeIKernelGroupListener/onSearchMemberChange':
|
||||||
|
@ -552,6 +552,34 @@ async function parseElements(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 11: {
|
||||||
|
elements.push(
|
||||||
|
ctx.chronocat.h(
|
||||||
|
`${ctx.chronocat.platform}:marketface`,
|
||||||
|
{
|
||||||
|
tabId: m.marketFaceElement!.emojiPackageId,
|
||||||
|
faceId: m.marketFaceElement!.emojiId,
|
||||||
|
key: m.marketFaceElement!.key,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
ctx.chronocat.h('img', {
|
||||||
|
src: `${config.self_url}/v1/assets/${Buffer.from(
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'marketface',
|
||||||
|
tabId: m.marketFaceElement!.emojiPackageId,
|
||||||
|
faceId: m.marketFaceElement!.emojiId,
|
||||||
|
key: m.marketFaceElement!.key,
|
||||||
|
name: m.marketFaceElement!.faceName,
|
||||||
|
filePath: m.marketFaceElement!.staticFacePath,
|
||||||
|
}),
|
||||||
|
).toString('base64url')}`,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ export interface Element {
|
|||||||
inlineKeyboardElement?: InlineKeyboardElement
|
inlineKeyboardElement?: InlineKeyboardElement
|
||||||
liveGiftElement?: unknown
|
liveGiftElement?: unknown
|
||||||
markdownElement?: MarkdownElement
|
markdownElement?: MarkdownElement
|
||||||
marketFaceElement?: unknown
|
marketFaceElement?: MarketFaceElement
|
||||||
multiForwardMsgElement?: unknown
|
multiForwardMsgElement?: unknown
|
||||||
pttElement?: PttElement
|
pttElement?: PttElement
|
||||||
replyElement?: ReplyElement
|
replyElement?: ReplyElement
|
||||||
@ -653,6 +653,17 @@ export interface Media {
|
|||||||
downloadType: number
|
downloadType: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MarketFaceAssetRequest {
|
||||||
|
type: 'marketface'
|
||||||
|
tabId: number
|
||||||
|
faceId: string
|
||||||
|
key: string
|
||||||
|
name: string
|
||||||
|
filePath: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AssetRequest = MarketFaceAssetRequest | Media
|
||||||
|
|
||||||
export interface InlineKeyboardElement {
|
export interface InlineKeyboardElement {
|
||||||
rows: InlineKeyboardRow[]
|
rows: InlineKeyboardRow[]
|
||||||
}
|
}
|
||||||
@ -762,6 +773,41 @@ export interface MarkdownElement {
|
|||||||
content: string
|
content: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MarketFaceElement {
|
||||||
|
itemType: 6
|
||||||
|
faceInfo: 1
|
||||||
|
emojiPackageId: number // 235125
|
||||||
|
subType: 3
|
||||||
|
mediaType: 0
|
||||||
|
imageWidth: number // 200
|
||||||
|
imageHeight: number // 200
|
||||||
|
faceName: string // '[好耶]'
|
||||||
|
emojiId: string // 'e6e7817c449efdea0be5ceeef3a40c06'
|
||||||
|
key: string // 'ea4dc6c26b6f9c31'
|
||||||
|
param: unknown
|
||||||
|
mobileParam: unknown
|
||||||
|
sourceType: 0
|
||||||
|
startTime: 0
|
||||||
|
endTime: 0
|
||||||
|
emojiType: 1
|
||||||
|
hasIpProduct: 0
|
||||||
|
voiceItemHeightArr: unknown
|
||||||
|
sourceName: unknown
|
||||||
|
sourceJumpUrl: unknown
|
||||||
|
sourceTypeName: string // ''
|
||||||
|
backColor: unknown
|
||||||
|
volumeColor: unknown
|
||||||
|
staticFacePath: string
|
||||||
|
dynamicFacePath: string
|
||||||
|
supportSize: MarketFaceElementSupportSize[]
|
||||||
|
apngSupportSize: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFaceElementSupportSize {
|
||||||
|
width: number // 300
|
||||||
|
height: number // 300
|
||||||
|
}
|
||||||
|
|
||||||
export interface ArkElement {
|
export interface ArkElement {
|
||||||
bytesData: string
|
bytesData: string
|
||||||
linkInfo: never
|
linkInfo: never
|
||||||
|
@ -75,6 +75,27 @@ export interface OnRichMediaDownloadComplete {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OnEmojiDownloadComplete {
|
||||||
|
notifyInfo: {
|
||||||
|
result: 0
|
||||||
|
errMsg: string // ''
|
||||||
|
emojiType: 0
|
||||||
|
md5: string // ''
|
||||||
|
resId: string // ''
|
||||||
|
path: string
|
||||||
|
extraData: Record<string, never>
|
||||||
|
emojiId: string // '94c8ffa6977fd17e8b180b312cdddc28'
|
||||||
|
emojiPackageId: string // '235125'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载富媒体的类型。发送时 3 为 PNG,4 为动图;接收时 0 为 PNG,4 为动图。
|
||||||
|
*/
|
||||||
|
downloadType: 0 | 4
|
||||||
|
|
||||||
|
dynamicFacePath: string // ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface OnGroupListUpdate {
|
export interface OnGroupListUpdate {
|
||||||
updateType: 1
|
updateType: 1
|
||||||
groupList: Group[]
|
groupList: Group[]
|
||||||
|
Loading…
Reference in New Issue
Block a user