diff --git a/README.md b/README.md
index 32b041f..4f0d3ee 100644
--- a/README.md
+++ b/README.md
@@ -452,6 +452,8 @@ export interface SuperChatMsg {
| onGuardBuy | 舰长上舰消息 |
| onRedPocketStart | 红包抽奖开始 |
| onRedPocketEnd | 红包抽奖结果 |
+| onAnchorLotteryStart | 主播天选时刻抽奖开启 |
+| onAnchorLotteryEnd | 主播天选时刻抽奖结果 |
Type Definitions
@@ -617,6 +619,106 @@ interface RedPocketEndAward {
award_price: number
}
```
+
+##### handler.onAnchorLotteryStart
+
+主播天选时刻抽奖开启
+
+```ts
+export type Handler = {
+ /** 主播天选时刻抽奖开启 */
+ onAnchorLotteryStart: (msg: Message) => void
+}
+
+type msgType = 'ANCHOR_LOT_START'
+
+export interface AnchorLotteryStartMsg {
+ /** 天选抽奖id */
+ id: number
+ /** 开始时间,秒级时间戳 */
+ start_time: number
+ /** 持续时间,秒 */
+ duration: number
+ /** 天选奖品信息 */
+ award: {
+ /** 奖品图片 */
+ image: string
+ /** 奖品名称 */
+ name: string
+ /** 奖品数量 */
+ num: number
+ /** 是否为虚拟礼物奖品 */
+ virtual: boolean
+ /** 虚拟奖品价值描述,实物奖品为空 */
+ price_text: string
+ }
+ /** 抽奖要求 */
+ require: {
+ /** 口令弹幕内容,无需弹幕为空字符串 */
+ danmu: string
+ /** 需送主播礼物,无需送礼为空 */
+ gift: {
+ /** 礼物id */
+ id: string
+ /** 礼物名称 */
+ name: string
+ /** 礼物数量 */
+ num: number
+ /** 单个礼物价值,除以1000为RMB */
+ price: number
+ } | null
+ /** 抽奖参与人群要求,无要求为空 */
+ user: {
+ /** 参与人群限制(关注/粉丝勋章/大航海) */
+ type: 'follow' | 'medal' | 'guard'
+ /** 参与人群限制等级,如粉丝勋章等级 */
+ value: number
+ /** 参与人群限制描述 */
+ text: string
+ } | null
+ }
+}
+```
+
+##### handler.onAnchorLotteryEnd
+
+主播天选时刻抽奖结果
+
+```ts
+export type Handler = {
+ /** 主播天选时刻抽奖结果 */
+ onAnchorLotteryEnd: (msg: Message) => void
+}
+
+type msgType = 'ANCHOR_LOT_AWARD'
+
+export interface AnchorLotteryEndMsg {
+ /** 天选抽奖id */
+ id: number
+ /** 天选奖品信息 */
+ award: {
+ /** 奖品图片 */
+ image: string
+ /** 奖品名称 */
+ name: string
+ /** 是否为虚拟礼物奖品 */
+ virtual: boolean
+ }
+ /** 中奖用户列表 */
+ winner: ({
+ /** 用户uid */
+ uid: number
+ /** 用户昵称 */
+ uname: string
+ /** 用户头像 */
+ face: number
+ /** 用户粉丝勋章等级 */
+ level: number
+ /** 中奖数量 */
+ num: number
+ })[]
+}
+```
#### 房间管理相关
diff --git a/src/listener/index.ts b/src/listener/index.ts
index 7bb5ebf..910a3ee 100644
--- a/src/listener/index.ts
+++ b/src/listener/index.ts
@@ -2,6 +2,8 @@ import {
HEARTBEAT, type AttentionChangeMsgHandler,
LIVE, type LiveStartMsgHandler,
PREPARING, type LiveStopMsgHandler,
+ ANCHOR_LOT_AWARD, type AnchorLotteryEndMsgHandler,
+ ANCHOR_LOT_START, type AnchorLotteryStartMsgHandler,
DANMU_MSG, type DanmuMsgHandler,
GUARD_BUY, type GuardBuyHandler,
INTERACT_WORD, ENTRY_EFFECT, LIKE_INFO_V3_CLICK, type UserActionMsgHandler,
@@ -34,6 +36,8 @@ export type MsgHandler = Partial<
& AttentionChangeMsgHandler
& LiveStartMsgHandler
& LiveStopMsgHandler
+ & AnchorLotteryEndMsgHandler
+ & AnchorLotteryStartMsgHandler
& DanmuMsgHandler
& GuardBuyHandler
& UserActionMsgHandler
@@ -109,6 +113,26 @@ export const listenAll = (instance: KeepLiveTCP | KeepLiveWS, roomId: number, ha
})
}
+ // ANCHOR_LOT_AWARD
+ if (handler[ANCHOR_LOT_AWARD.handlerName] || rawHandlerNames.has(ANCHOR_LOT_AWARD.eventName)) {
+ rawHandlerNames.delete(ANCHOR_LOT_AWARD.eventName)
+ instance.on(ANCHOR_LOT_AWARD.eventName as any, (data: WSMessage) => {
+ isHandleRaw && rawHandler[ANCHOR_LOT_AWARD.eventName]?.(data.data)
+ const parsedData = ANCHOR_LOT_AWARD.parser(data.data, roomId)
+ handler[ANCHOR_LOT_AWARD.handlerName]?.(normalizeDanmu(ANCHOR_LOT_AWARD.eventName, parsedData, data.data))
+ })
+ }
+
+ // ANCHOR_LOT_START
+ if (handler[ANCHOR_LOT_START.handlerName] || rawHandlerNames.has(ANCHOR_LOT_START.eventName)) {
+ rawHandlerNames.delete(ANCHOR_LOT_START.eventName)
+ instance.on(ANCHOR_LOT_START.eventName as any, (data: WSMessage) => {
+ isHandleRaw && rawHandler[ANCHOR_LOT_START.eventName]?.(data.data)
+ const parsedData = ANCHOR_LOT_START.parser(data.data, roomId)
+ handler[ANCHOR_LOT_START.handlerName]?.(normalizeDanmu(ANCHOR_LOT_START.eventName, parsedData, data.data))
+ })
+ }
+
// DANMU_MSG
if (handler[DANMU_MSG.handlerName] || rawHandlerNames.has(DANMU_MSG.eventName)) {
rawHandlerNames.delete(DANMU_MSG.eventName)
diff --git a/src/parser/ANCHOR_LOT_AWARD.ts b/src/parser/ANCHOR_LOT_AWARD.ts
new file mode 100644
index 0000000..0c655ce
--- /dev/null
+++ b/src/parser/ANCHOR_LOT_AWARD.ts
@@ -0,0 +1,59 @@
+import type { Message } from '../types/app'
+
+export interface AnchorLotteryEndMsg {
+ /** 天选抽奖id */
+ id: number
+ /** 天选奖品信息 */
+ award: {
+ /** 奖品图片 */
+ image: string
+ /** 奖品名称 */
+ name: string
+ /** 是否为虚拟礼物奖品 */
+ virtual: boolean
+ }
+ /** 中奖用户列表 */
+ winner: ({
+ /** 用户uid */
+ uid: number
+ /** 用户昵称 */
+ uname: string
+ /** 用户头像 */
+ face: number
+ /** 用户粉丝勋章等级 */
+ level: number
+ /** 中奖数量 */
+ num: number
+ })[]
+}
+
+const parser = (data: any, roomId: number): AnchorLotteryEndMsg => {
+ const rawData = data.data
+
+ return {
+ id: rawData.id,
+ award: {
+ image: rawData.award_image,
+ name: rawData.award_name,
+ virtual: rawData.award_type === 1,
+ },
+ winner: rawData.award_users.map((user: any) => ({
+ uid: user.uid,
+ uname: user.uname,
+ face: user.face,
+ level: user.level,
+ num: user.num,
+ })),
+ }
+}
+
+export const ANCHOR_LOT_AWARD = {
+ parser,
+ eventName: 'ANCHOR_LOT_AWARD' as const,
+ handlerName: 'onAnchorLotteryEnd' as const,
+}
+
+export type Handler = {
+ /** 主播天选时刻抽奖结果 */
+ onAnchorLotteryEnd: (msg: Message) => void
+}
diff --git a/src/parser/ANCHOR_LOT_START.ts b/src/parser/ANCHOR_LOT_START.ts
new file mode 100644
index 0000000..165665b
--- /dev/null
+++ b/src/parser/ANCHOR_LOT_START.ts
@@ -0,0 +1,90 @@
+import type { Message } from '../types/app'
+
+export interface AnchorLotteryStartMsg {
+ /** 天选抽奖id */
+ id: number
+ /** 开始时间,秒级时间戳 */
+ start_time: number
+ /** 持续时间,秒 */
+ duration: number
+ /** 天选奖品信息 */
+ award: {
+ /** 奖品图片 */
+ image: string
+ /** 奖品名称 */
+ name: string
+ /** 奖品数量 */
+ num: number
+ /** 是否为虚拟礼物奖品 */
+ virtual: boolean
+ /** 虚拟奖品价值描述,实物奖品为空 */
+ price_text: string
+ }
+ /** 抽奖要求 */
+ require: {
+ /** 口令弹幕内容,无需弹幕为空字符串 */
+ danmu: string
+ /** 需送主播礼物,无需送礼为空 */
+ gift: {
+ /** 礼物id */
+ id: string
+ /** 礼物名称 */
+ name: string
+ /** 礼物数量 */
+ num: number
+ /** 单个礼物价值,除以1000为RMB */
+ price: number
+ } | null
+ /** 抽奖参与人群要求,无要求为空 */
+ user: {
+ /** 参与人群限制(关注/粉丝勋章/大航海) */
+ type: 'follow' | 'medal' | 'guard'
+ /** 参与人群限制等级,如粉丝勋章等级 */
+ value: number
+ /** 参与人群限制描述 */
+ text: string
+ } | null
+ }
+}
+
+const parser = (data: any, roomId: number): AnchorLotteryStartMsg => {
+ const rawData = data.data
+
+ return {
+ id: rawData.id,
+ start_time: rawData.current_time,
+ duration: rawData.max_time,
+ award: {
+ image: rawData.award_image,
+ name: rawData.award_name,
+ num: rawData.award_num,
+ virtual: rawData.award_type === 1,
+ price_text: rawData.award_price_text || '',
+ },
+ require: {
+ danmu: rawData.danmu || '',
+ gift: rawData.gift_id ? {
+ id: rawData.gift_id,
+ name: rawData.gift_name,
+ num: rawData.gift_num,
+ price: rawData.gift_price,
+ } : null,
+ user: rawData.require_type ? {
+ type: (['follow', 'medal', 'guard'] as const)[rawData.require_type - 1],
+ value: rawData.require_value,
+ text: rawData.require_text,
+ } : null,
+ },
+ }
+}
+
+export const ANCHOR_LOT_START = {
+ parser,
+ eventName: 'ANCHOR_LOT_START' as const,
+ handlerName: 'onAnchorLotteryStart' as const,
+}
+
+export type Handler = {
+ /** 主播天选时刻抽奖开启 */
+ onAnchorLotteryStart: (msg: Message) => void
+}
diff --git a/src/parser/index.ts b/src/parser/index.ts
index e34ae8c..0d4379a 100644
--- a/src/parser/index.ts
+++ b/src/parser/index.ts
@@ -1,6 +1,8 @@
export { HEARTBEAT, type Handler as AttentionChangeMsgHandler, type AttentionChangeMsg } from './HEARTBEAT'
export { LIVE, type Handler as LiveStartMsgHandler, type LiveStartMsg } from './LIVE'
export { PREPARING, type Handler as LiveStopMsgHandler, type LiveEndMsg } from './PREPARING'
+export { ANCHOR_LOT_AWARD, type Handler as AnchorLotteryEndMsgHandler, type AnchorLotteryEndMsg } from './ANCHOR_LOT_AWARD'
+export { ANCHOR_LOT_START, type Handler as AnchorLotteryStartMsgHandler, type AnchorLotteryStartMsg } from './ANCHOR_LOT_START'
export { DANMU_MSG, type Handler as DanmuMsgHandler, type DanmuMsg } from './DANMU_MSG'
export { GUARD_BUY, type Handler as GuardBuyHandler, type GuardBuyMsg } from './GUARD_BUY'
export { INTERACT_WORD, ENTRY_EFFECT, LIKE_INFO_V3_CLICK, type Handler as UserActionMsgHandler, type UserActionMsg } from './INTERACT_WORD_ENTRY_EFFECT'