Skip to content

Commit 734bf40

Browse files
committed
feat: 主播天选时刻抽奖消息
1 parent 8c26a01 commit 734bf40

File tree

5 files changed

+277
-0
lines changed

5 files changed

+277
-0
lines changed

README.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ export interface SuperChatMsg {
452452
| onGuardBuy | 舰长上舰消息 |
453453
| onRedPocketStart | 红包抽奖开始 |
454454
| onRedPocketEnd | 红包抽奖结果 |
455+
| onAnchorLotteryStart | 主播天选时刻抽奖开启 |
456+
| onAnchorLotteryEnd | 主播天选时刻抽奖结果 |
455457

456458
<details>
457459
<summary>Type Definitions</summary>
@@ -617,6 +619,106 @@ interface RedPocketEndAward {
617619
award_price: number
618620
}
619621
```
622+
623+
##### handler.onAnchorLotteryStart
624+
625+
主播天选时刻抽奖开启
626+
627+
```ts
628+
export type Handler = {
629+
/** 主播天选时刻抽奖开启 */
630+
onAnchorLotteryStart: (msg: Message<AnchorLotteryStartMsg>) => void
631+
}
632+
633+
type msgType = 'ANCHOR_LOT_START'
634+
635+
export interface AnchorLotteryStartMsg {
636+
/** 天选抽奖id */
637+
id: number
638+
/** 开始时间,秒级时间戳 */
639+
start_time: number
640+
/** 持续时间,秒 */
641+
duration: number
642+
/** 天选奖品信息 */
643+
award: {
644+
/** 奖品图片 */
645+
image: string
646+
/** 奖品名称 */
647+
name: string
648+
/** 奖品数量 */
649+
num: number
650+
/** 是否为虚拟礼物奖品 */
651+
virtual: boolean
652+
/** 虚拟奖品价值描述,实物奖品为空 */
653+
price_text: string
654+
}
655+
/** 抽奖要求 */
656+
require: {
657+
/** 口令弹幕内容,无需弹幕为空字符串 */
658+
danmu: string
659+
/** 需送主播礼物,无需送礼为空 */
660+
gift: {
661+
/** 礼物id */
662+
id: string
663+
/** 礼物名称 */
664+
name: string
665+
/** 礼物数量 */
666+
num: number
667+
/** 单个礼物价值,除以1000为RMB */
668+
price: number
669+
} | null
670+
/** 抽奖参与人群要求,无要求为空 */
671+
user: {
672+
/** 参与人群限制(关注/粉丝勋章/大航海) */
673+
type: 'follow' | 'medal' | 'guard'
674+
/** 参与人群限制等级,如粉丝勋章等级 */
675+
value: number
676+
/** 参与人群限制描述 */
677+
text: string
678+
} | null
679+
}
680+
}
681+
```
682+
683+
##### handler.onAnchorLotteryEnd
684+
685+
主播天选时刻抽奖结果
686+
687+
```ts
688+
export type Handler = {
689+
/** 主播天选时刻抽奖结果 */
690+
onAnchorLotteryEnd: (msg: Message<AnchorLotteryEndMsg>) => void
691+
}
692+
693+
type msgType = 'ANCHOR_LOT_AWARD'
694+
695+
export interface AnchorLotteryEndMsg {
696+
/** 天选抽奖id */
697+
id: number
698+
/** 天选奖品信息 */
699+
award: {
700+
/** 奖品图片 */
701+
image: string
702+
/** 奖品名称 */
703+
name: string
704+
/** 是否为虚拟礼物奖品 */
705+
virtual: boolean
706+
}
707+
/** 中奖用户列表 */
708+
winner: ({
709+
/** 用户uid */
710+
uid: number
711+
/** 用户昵称 */
712+
uname: string
713+
/** 用户头像 */
714+
face: number
715+
/** 用户粉丝勋章等级 */
716+
level: number
717+
/** 中奖数量 */
718+
num: number
719+
})[]
720+
}
721+
```
620722
</details>
621723

622724
#### 房间管理相关

src/listener/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import {
22
HEARTBEAT, type AttentionChangeMsgHandler,
33
LIVE, type LiveStartMsgHandler,
44
PREPARING, type LiveStopMsgHandler,
5+
ANCHOR_LOT_AWARD, type AnchorLotteryEndMsgHandler,
6+
ANCHOR_LOT_START, type AnchorLotteryStartMsgHandler,
57
DANMU_MSG, type DanmuMsgHandler,
68
GUARD_BUY, type GuardBuyHandler,
79
INTERACT_WORD, ENTRY_EFFECT, LIKE_INFO_V3_CLICK, type UserActionMsgHandler,
@@ -34,6 +36,8 @@ export type MsgHandler = Partial<
3436
& AttentionChangeMsgHandler
3537
& LiveStartMsgHandler
3638
& LiveStopMsgHandler
39+
& AnchorLotteryEndMsgHandler
40+
& AnchorLotteryStartMsgHandler
3741
& DanmuMsgHandler
3842
& GuardBuyHandler
3943
& UserActionMsgHandler
@@ -109,6 +113,26 @@ export const listenAll = (instance: KeepLiveTCP | KeepLiveWS, roomId: number, ha
109113
})
110114
}
111115

116+
// ANCHOR_LOT_AWARD
117+
if (handler[ANCHOR_LOT_AWARD.handlerName] || rawHandlerNames.has(ANCHOR_LOT_AWARD.eventName)) {
118+
rawHandlerNames.delete(ANCHOR_LOT_AWARD.eventName)
119+
instance.on(ANCHOR_LOT_AWARD.eventName as any, (data: WSMessage<any>) => {
120+
isHandleRaw && rawHandler[ANCHOR_LOT_AWARD.eventName]?.(data.data)
121+
const parsedData = ANCHOR_LOT_AWARD.parser(data.data, roomId)
122+
handler[ANCHOR_LOT_AWARD.handlerName]?.(normalizeDanmu(ANCHOR_LOT_AWARD.eventName, parsedData, data.data))
123+
})
124+
}
125+
126+
// ANCHOR_LOT_START
127+
if (handler[ANCHOR_LOT_START.handlerName] || rawHandlerNames.has(ANCHOR_LOT_START.eventName)) {
128+
rawHandlerNames.delete(ANCHOR_LOT_START.eventName)
129+
instance.on(ANCHOR_LOT_START.eventName as any, (data: WSMessage<any>) => {
130+
isHandleRaw && rawHandler[ANCHOR_LOT_START.eventName]?.(data.data)
131+
const parsedData = ANCHOR_LOT_START.parser(data.data, roomId)
132+
handler[ANCHOR_LOT_START.handlerName]?.(normalizeDanmu(ANCHOR_LOT_START.eventName, parsedData, data.data))
133+
})
134+
}
135+
112136
// DANMU_MSG
113137
if (handler[DANMU_MSG.handlerName] || rawHandlerNames.has(DANMU_MSG.eventName)) {
114138
rawHandlerNames.delete(DANMU_MSG.eventName)

src/parser/ANCHOR_LOT_AWARD.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { Message } from '../types/app'
2+
3+
export interface AnchorLotteryEndMsg {
4+
/** 天选抽奖id */
5+
id: number
6+
/** 天选奖品信息 */
7+
award: {
8+
/** 奖品图片 */
9+
image: string
10+
/** 奖品名称 */
11+
name: string
12+
/** 是否为虚拟礼物奖品 */
13+
virtual: boolean
14+
}
15+
/** 中奖用户列表 */
16+
winner: ({
17+
/** 用户uid */
18+
uid: number
19+
/** 用户昵称 */
20+
uname: string
21+
/** 用户头像 */
22+
face: number
23+
/** 用户粉丝勋章等级 */
24+
level: number
25+
/** 中奖数量 */
26+
num: number
27+
})[]
28+
}
29+
30+
const parser = (data: any, roomId: number): AnchorLotteryEndMsg => {
31+
const rawData = data.data
32+
33+
return {
34+
id: rawData.id,
35+
award: {
36+
image: rawData.award_image,
37+
name: rawData.award_name,
38+
virtual: rawData.award_type === 1,
39+
},
40+
winner: rawData.award_users.map((user: any) => ({
41+
uid: user.uid,
42+
uname: user.uname,
43+
face: user.face,
44+
level: user.level,
45+
num: user.num,
46+
})),
47+
}
48+
}
49+
50+
export const ANCHOR_LOT_AWARD = {
51+
parser,
52+
eventName: 'ANCHOR_LOT_AWARD' as const,
53+
handlerName: 'onAnchorLotteryEnd' as const,
54+
}
55+
56+
export type Handler = {
57+
/** 主播天选时刻抽奖结果 */
58+
onAnchorLotteryEnd: (msg: Message<AnchorLotteryEndMsg>) => void
59+
}

src/parser/ANCHOR_LOT_START.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import type { Message } from '../types/app'
2+
3+
export interface AnchorLotteryStartMsg {
4+
/** 天选抽奖id */
5+
id: number
6+
/** 开始时间,秒级时间戳 */
7+
start_time: number
8+
/** 持续时间,秒 */
9+
duration: number
10+
/** 天选奖品信息 */
11+
award: {
12+
/** 奖品图片 */
13+
image: string
14+
/** 奖品名称 */
15+
name: string
16+
/** 奖品数量 */
17+
num: number
18+
/** 是否为虚拟礼物奖品 */
19+
virtual: boolean
20+
/** 虚拟奖品价值描述,实物奖品为空 */
21+
price_text: string
22+
}
23+
/** 抽奖要求 */
24+
require: {
25+
/** 口令弹幕内容,无需弹幕为空字符串 */
26+
danmu: string
27+
/** 需送主播礼物,无需送礼为空 */
28+
gift: {
29+
/** 礼物id */
30+
id: string
31+
/** 礼物名称 */
32+
name: string
33+
/** 礼物数量 */
34+
num: number
35+
/** 单个礼物价值,除以1000为RMB */
36+
price: number
37+
} | null
38+
/** 抽奖参与人群要求,无要求为空 */
39+
user: {
40+
/** 参与人群限制(关注/粉丝勋章/大航海) */
41+
type: 'follow' | 'medal' | 'guard'
42+
/** 参与人群限制等级,如粉丝勋章等级 */
43+
value: number
44+
/** 参与人群限制描述 */
45+
text: string
46+
} | null
47+
}
48+
}
49+
50+
const parser = (data: any, roomId: number): AnchorLotteryStartMsg => {
51+
const rawData = data.data
52+
53+
return {
54+
id: rawData.id,
55+
start_time: rawData.current_time,
56+
duration: rawData.max_time,
57+
award: {
58+
image: rawData.award_image,
59+
name: rawData.award_name,
60+
num: rawData.award_num,
61+
virtual: rawData.award_type === 1,
62+
price_text: rawData.award_price_text || '',
63+
},
64+
require: {
65+
danmu: rawData.danmu || '',
66+
gift: rawData.gift_id ? {
67+
id: rawData.gift_id,
68+
name: rawData.gift_name,
69+
num: rawData.gift_num,
70+
price: rawData.gift_price,
71+
} : null,
72+
user: rawData.require_type ? {
73+
type: (['follow', 'medal', 'guard'] as const)[rawData.require_type - 1],
74+
value: rawData.require_value,
75+
text: rawData.require_text,
76+
} : null,
77+
},
78+
}
79+
}
80+
81+
export const ANCHOR_LOT_START = {
82+
parser,
83+
eventName: 'ANCHOR_LOT_START' as const,
84+
handlerName: 'onAnchorLotteryStart' as const,
85+
}
86+
87+
export type Handler = {
88+
/** 主播天选时刻抽奖开启 */
89+
onAnchorLotteryStart: (msg: Message<AnchorLotteryStartMsg>) => void
90+
}

src/parser/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export { HEARTBEAT, type Handler as AttentionChangeMsgHandler, type AttentionChangeMsg } from './HEARTBEAT'
22
export { LIVE, type Handler as LiveStartMsgHandler, type LiveStartMsg } from './LIVE'
33
export { PREPARING, type Handler as LiveStopMsgHandler, type LiveEndMsg } from './PREPARING'
4+
export { ANCHOR_LOT_AWARD, type Handler as AnchorLotteryEndMsgHandler, type AnchorLotteryEndMsg } from './ANCHOR_LOT_AWARD'
5+
export { ANCHOR_LOT_START, type Handler as AnchorLotteryStartMsgHandler, type AnchorLotteryStartMsg } from './ANCHOR_LOT_START'
46
export { DANMU_MSG, type Handler as DanmuMsgHandler, type DanmuMsg } from './DANMU_MSG'
57
export { GUARD_BUY, type Handler as GuardBuyHandler, type GuardBuyMsg } from './GUARD_BUY'
68
export { INTERACT_WORD, ENTRY_EFFECT, LIKE_INFO_V3_CLICK, type Handler as UserActionMsgHandler, type UserActionMsg } from './INTERACT_WORD_ENTRY_EFFECT'

0 commit comments

Comments
 (0)