mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-04-30 06:50:58 +08:00
添加显示礼物名、只合并同类礼物
This commit is contained in:
parent
2d237af6fd
commit
102746d0b0
11
api/chat.py
11
api/chat.py
@ -63,7 +63,7 @@ class Room(blivedm.BLiveClient):
|
||||
def __parse_gift(self, command):
|
||||
data = command['data']
|
||||
return self._on_receive_gift(blivedm.GiftMessage(
|
||||
None, None, data['uname'], data['face'], None,
|
||||
data['giftName'], data['num'], data['uname'], data['face'], None,
|
||||
data['uid'], data['timestamp'], None, None,
|
||||
None, None, None, data['coin_type'], data['total_coin']
|
||||
))
|
||||
@ -192,7 +192,9 @@ class Room(blivedm.BLiveClient):
|
||||
'avatarUrl': avatar_url,
|
||||
'timestamp': gift.timestamp,
|
||||
'authorName': gift.uname,
|
||||
'totalCoin': gift.total_coin
|
||||
'totalCoin': gift.total_coin,
|
||||
'giftName': gift.gift_name,
|
||||
'num': gift.num
|
||||
})
|
||||
|
||||
async def _on_buy_guard(self, message: blivedm.GuardBuyMessage):
|
||||
@ -419,7 +421,9 @@ class ChatHandler(tornado.websocket.WebSocketHandler):
|
||||
gift_data = {
|
||||
**base_data,
|
||||
'id': uuid.uuid4().hex,
|
||||
'totalCoin': 450000
|
||||
'totalCoin': 450000,
|
||||
'giftName': '摩天大楼',
|
||||
'num': 1
|
||||
}
|
||||
sc_data = {
|
||||
**base_data,
|
||||
@ -444,6 +448,7 @@ class ChatHandler(tornado.websocket.WebSocketHandler):
|
||||
self.send_message(Command.ADD_GIFT, gift_data)
|
||||
gift_data['id'] = uuid.uuid4().hex
|
||||
gift_data['totalCoin'] = 1245000
|
||||
gift_data['giftName'] = '小电视飞船'
|
||||
self.send_message(Command.ADD_GIFT, gift_data)
|
||||
|
||||
@property
|
||||
|
@ -2,9 +2,11 @@ import {mergeConfig} from '@/utils'
|
||||
|
||||
export const DEFAULT_CONFIG = {
|
||||
minGiftPrice: 7, // $1
|
||||
mergeSimilarDanmaku: true,
|
||||
showDanmaku: true,
|
||||
showGift: true,
|
||||
showGiftName: false,
|
||||
mergeSimilarDanmaku: true,
|
||||
mergeGift: true,
|
||||
maxNumber: 60,
|
||||
|
||||
blockGiftDanmaku: true,
|
||||
|
@ -34,18 +34,19 @@
|
||||
<paid-message :key="pinnedMessage.id" v-else
|
||||
class="style-scope yt-live-chat-ticker-renderer"
|
||||
:price="pinnedMessage.price" :avatarUrl="pinnedMessage.avatarUrl" :authorName="pinnedMessage.authorName"
|
||||
:time="pinnedMessage.time" :content="pinnedMessage.content"
|
||||
:time="pinnedMessage.time" :content="showContent"
|
||||
></paid-message>
|
||||
</template>
|
||||
</yt-live-chat-ticker-renderer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as config from '@/api/config'
|
||||
import {formatCurrency} from '@/utils'
|
||||
import ImgShadow from './ImgShadow.vue'
|
||||
import LegacyPaidMessage from './LegacyPaidMessage.vue'
|
||||
import PaidMessage from './PaidMessage.vue'
|
||||
import * as constants from './constants'
|
||||
import {formatCurrency} from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'Ticker',
|
||||
@ -55,7 +56,11 @@ export default {
|
||||
PaidMessage
|
||||
},
|
||||
props: {
|
||||
messages: Array
|
||||
messages: Array,
|
||||
showGiftName: {
|
||||
type: Boolean,
|
||||
default: config.DEFAULT_CONFIG.showGiftName
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -65,6 +70,18 @@ export default {
|
||||
pinnedMessage: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showContent() {
|
||||
if (!this.pinnedMessage) {
|
||||
return ''
|
||||
}
|
||||
if (this.pinnedMessage.type === constants.MESSAGE_TYPE_GIFT) {
|
||||
return constants.getGiftShowContent(this.pinnedMessage, this.showGiftName)
|
||||
} else {
|
||||
return constants.getShowContent(this.pinnedMessage)
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearInterval(this.updateTimerId)
|
||||
},
|
||||
|
@ -18,10 +18,11 @@ export const GUARD_LEVEL_TO_TEXT = [
|
||||
]
|
||||
|
||||
export const MESSAGE_TYPE_TEXT = 0
|
||||
export const MESSAGE_TYPE_MEMBER = 1
|
||||
export const MESSAGE_TYPE_SUPER_CHAT = 2
|
||||
export const MESSAGE_TYPE_DEL = 3
|
||||
export const MESSAGE_TYPE_UPDATE = 4
|
||||
export const MESSAGE_TYPE_GIFT = 1
|
||||
export const MESSAGE_TYPE_MEMBER = 2
|
||||
export const MESSAGE_TYPE_SUPER_CHAT = 3
|
||||
export const MESSAGE_TYPE_DEL = 4
|
||||
export const MESSAGE_TYPE_UPDATE = 5
|
||||
|
||||
// 美元 -> 人民币 汇率
|
||||
const EXCHANGE_RATE = 7
|
||||
@ -120,3 +121,17 @@ export function getPriceConfig (price) {
|
||||
}
|
||||
return PRICE_CONFIGS[PRICE_CONFIGS.length - 1]
|
||||
}
|
||||
|
||||
export function getShowContent(message) {
|
||||
if (message.translation) {
|
||||
return `${message.content}(${message.translation})`
|
||||
}
|
||||
return message.content
|
||||
}
|
||||
|
||||
export function getGiftShowContent(message, showGiftName) {
|
||||
if (!showGiftName) {
|
||||
return ''
|
||||
}
|
||||
return `Sent ${message.giftName}x${message.num}`
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
<yt-live-chat-renderer class="style-scope yt-live-chat-app" style="--scrollbar-width:11px;" hide-timestamps
|
||||
@mousemove="refreshCantScrollStartTime"
|
||||
>
|
||||
<ticker class="style-scope yt-live-chat-renderer" :messages="paidMessages" :hidden="paidMessages.length === 0"></ticker>
|
||||
<ticker class="style-scope yt-live-chat-renderer" :messages="paidMessages" :showGiftName="showGiftName"
|
||||
:hidden="paidMessages.length === 0"
|
||||
></ticker>
|
||||
<yt-live-chat-item-list-renderer class="style-scope yt-live-chat-renderer" allow-scroll>
|
||||
<div ref="scroller" id="item-scroller" class="style-scope yt-live-chat-item-list-renderer animated" @scroll="onScroll">
|
||||
<div ref="itemOffset" id="item-offset" class="style-scope yt-live-chat-item-list-renderer" style="height: 0px;">
|
||||
@ -16,6 +18,11 @@
|
||||
:authorType="message.authorType" :content="getShowContent(message)" :privilegeType="message.privilegeType"
|
||||
:repeated="message.repeated"
|
||||
></text-message>
|
||||
<paid-message :key="message.id" v-else-if="message.type === MESSAGE_TYPE_GIFT"
|
||||
class="style-scope yt-live-chat-item-list-renderer"
|
||||
:price="message.price" :avatarUrl="message.avatarUrl" :authorName="message.authorName"
|
||||
:time="message.time" :content="getGiftShowContent(message)"
|
||||
></paid-message>
|
||||
<legacy-paid-message :key="message.id" v-else-if="message.type === MESSAGE_TYPE_MEMBER"
|
||||
class="style-scope yt-live-chat-item-list-renderer"
|
||||
:avatarUrl="message.avatarUrl" :title="message.title" :content="message.content"
|
||||
@ -58,6 +65,10 @@ export default {
|
||||
maxNumber: {
|
||||
type: Number,
|
||||
default: config.DEFAULT_CONFIG.maxNumber
|
||||
},
|
||||
showGiftName: {
|
||||
type: Boolean,
|
||||
default: config.DEFAULT_CONFIG.showGiftName
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -65,6 +76,7 @@ export default {
|
||||
document.head.appendChild(styleElement)
|
||||
return {
|
||||
MESSAGE_TYPE_TEXT: constants.MESSAGE_TYPE_TEXT,
|
||||
MESSAGE_TYPE_GIFT: constants.MESSAGE_TYPE_GIFT,
|
||||
MESSAGE_TYPE_MEMBER: constants.MESSAGE_TYPE_MEMBER,
|
||||
MESSAGE_TYPE_SUPER_CHAT: constants.MESSAGE_TYPE_SUPER_CHAT,
|
||||
|
||||
@ -118,12 +130,10 @@ export default {
|
||||
this.clearMessages()
|
||||
},
|
||||
methods: {
|
||||
getShowContent(message) {
|
||||
if (message.translation) {
|
||||
return `${message.content}(${message.translation})`
|
||||
}
|
||||
return message.content
|
||||
getGiftShowContent(message) {
|
||||
return constants.getGiftShowContent(message, this.showGiftName)
|
||||
},
|
||||
getShowContent: constants.getShowContent,
|
||||
|
||||
addMessage(message) {
|
||||
this.addMessages([message])
|
||||
@ -159,14 +169,15 @@ export default {
|
||||
})
|
||||
return res
|
||||
},
|
||||
mergeSimilarGift(authorName, price) {
|
||||
mergeSimilarGift(authorName, price, giftName, num) {
|
||||
let res = false
|
||||
this.forEachRecentMessage(5, message => {
|
||||
if (message.type === constants.MESSAGE_TYPE_SUPER_CHAT
|
||||
&& message.content === ''
|
||||
if (message.type === constants.MESSAGE_TYPE_GIFT
|
||||
&& message.authorName === authorName
|
||||
&& message.giftName === giftName
|
||||
) {
|
||||
message.price += price
|
||||
message.num += num
|
||||
res = true
|
||||
return false
|
||||
}
|
||||
@ -317,6 +328,7 @@ export default {
|
||||
for (let message of messageGroup) {
|
||||
switch (message.type) {
|
||||
case constants.MESSAGE_TYPE_TEXT:
|
||||
case constants.MESSAGE_TYPE_GIFT:
|
||||
case constants.MESSAGE_TYPE_MEMBER:
|
||||
case constants.MESSAGE_TYPE_SUPER_CHAT:
|
||||
this.handleAddMessage(message)
|
||||
|
@ -14,7 +14,9 @@ export default {
|
||||
roomId: 'Room ID',
|
||||
showDanmaku: 'Show messages',
|
||||
showGift: 'Show Super Chats',
|
||||
showGiftName: 'Show gift name',
|
||||
mergeSimilarDanmaku: 'Merge similar messages',
|
||||
mergeGift: 'Merge gifts',
|
||||
minGiftPrice: 'Min price of Super Chats to show (CNY)',
|
||||
maxNumber: 'Max number of messages',
|
||||
|
||||
|
@ -14,7 +14,9 @@ export default {
|
||||
roomId: 'ルームID',
|
||||
showDanmaku: 'コメントを表示する',
|
||||
showGift: 'スーパーチャットと新メンバーを表示する',
|
||||
showGiftName: 'ギフト名を表示する',
|
||||
mergeSimilarDanmaku: '同じコメントを合併する',
|
||||
mergeGift: 'ギフトを合併する',
|
||||
minGiftPrice: '最低表示スーパーチャット価格(CNY)',
|
||||
maxNumber: '最大コメント数',
|
||||
|
||||
|
@ -14,7 +14,9 @@ export default {
|
||||
roomId: '房间ID',
|
||||
showDanmaku: '显示弹幕',
|
||||
showGift: '显示打赏和新舰长',
|
||||
showGiftName: '显示礼物名',
|
||||
mergeSimilarDanmaku: '合并相似弹幕',
|
||||
mergeGift: '合并礼物',
|
||||
minGiftPrice: '最低显示打赏价格(元)',
|
||||
maxNumber: '最大弹幕数',
|
||||
|
||||
|
@ -16,9 +16,15 @@
|
||||
<el-form-item :label="$t('home.showGift')">
|
||||
<el-switch v-model="form.showGift"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('home.showGiftName')">
|
||||
<el-switch v-model="form.showGiftName"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('home.mergeSimilarDanmaku')">
|
||||
<el-switch v-model="form.mergeSimilarDanmaku"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('home.mergeGift')">
|
||||
<el-switch v-model="form.mergeGift"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('home.minGiftPrice')">
|
||||
<el-input v-model.number="form.minGiftPrice" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<chat-renderer ref="renderer" :maxNumber="config.maxNumber"></chat-renderer>
|
||||
<chat-renderer ref="renderer" :maxNumber="config.maxNumber" :showGiftName="config.showGiftName"></chat-renderer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -65,9 +65,11 @@ export default {
|
||||
cfg = mergeConfig(cfg, config.DEFAULT_CONFIG)
|
||||
|
||||
cfg.minGiftPrice = toInt(cfg.minGiftPrice, config.DEFAULT_CONFIG.minGiftPrice)
|
||||
cfg.mergeSimilarDanmaku = toBool(cfg.mergeSimilarDanmaku)
|
||||
cfg.showDanmaku = toBool(cfg.showDanmaku)
|
||||
cfg.showGift = toBool(cfg.showGift)
|
||||
cfg.showGiftName = toBool(cfg.showGiftName)
|
||||
cfg.mergeSimilarDanmaku = toBool(cfg.mergeSimilarDanmaku)
|
||||
cfg.mergeGift = toBool(cfg.mergeGift)
|
||||
cfg.maxNumber = toInt(cfg.maxNumber, config.DEFAULT_CONFIG.maxNumber)
|
||||
cfg.blockGiftDanmaku = toBool(cfg.blockGiftDanmaku)
|
||||
cfg.blockLevel = toInt(cfg.blockLevel, config.DEFAULT_CONFIG.blockLevel)
|
||||
@ -158,20 +160,21 @@ export default {
|
||||
break
|
||||
}
|
||||
let price = data.totalCoin / 1000
|
||||
if (price < this.config.minGiftPrice) { // 丢人
|
||||
if (this.mergeSimilarGift(data.authorName, price, data.giftName, data.num)) {
|
||||
break
|
||||
}
|
||||
if (this.mergeSimilarGift(data.authorName, price)) {
|
||||
if (price < this.config.minGiftPrice) { // 丢人
|
||||
break
|
||||
}
|
||||
message = {
|
||||
id: data.id,
|
||||
type: constants.MESSAGE_TYPE_SUPER_CHAT,
|
||||
type: constants.MESSAGE_TYPE_GIFT,
|
||||
avatarUrl: data.avatarUrl,
|
||||
time: new Date(data.timestamp * 1000),
|
||||
authorName: data.authorName,
|
||||
price: price,
|
||||
time: new Date(data.timestamp * 1000),
|
||||
content: '' // 有了SC,礼物不需要内容了
|
||||
giftName: data.giftName,
|
||||
num: data.num
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -262,11 +265,11 @@ export default {
|
||||
}
|
||||
return this.$refs.renderer.mergeSimilarText(content)
|
||||
},
|
||||
mergeSimilarGift(authorName, price) {
|
||||
if (!this.config.mergeSimilarDanmaku) {
|
||||
mergeSimilarGift(authorName, price, giftName, num) {
|
||||
if (!this.config.mergeGift) {
|
||||
return false
|
||||
}
|
||||
return this.$refs.renderer.mergeSimilarGift(authorName, price)
|
||||
return this.$refs.renderer.mergeSimilarGift(authorName, price, giftName, num)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,8 +268,8 @@ const EXAMPLE_MESSAGES = [
|
||||
{
|
||||
...legacyPaidMessageTemplate,
|
||||
id: (nextId++).toString(),
|
||||
authorName: '少年Pi',
|
||||
content: 'Welcome 少年Pi!'
|
||||
authorName: '进击的冰糖',
|
||||
content: 'Welcome 进击的冰糖!'
|
||||
},
|
||||
{
|
||||
...paidMessageTemplate,
|
||||
|
Loading…
Reference in New Issue
Block a user