From e80b51740e145441df8d940a62f3eef265475615 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 16 Aug 2026 16:43:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dweb=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=88=BF=E9=97=B4=E4=B8=8D=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=A4=BC=E7=89=A9=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 3 +- frontend/src/api/chat/ChatClientDirectWeb.js | 36 ++++++++++++++++++ frontend/src/api/chat/pb.js | 39 ++++++++++++++++++++ pyproject.toml | 2 +- uv.lock | 6 +-- 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 frontend/src/api/chat/pb.js diff --git a/frontend/package.json b/frontend/package.json index a973de8..72a6bbd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "blivechat", - "version": "1.10.3", + "version": "1.10.4-dev", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -17,6 +17,7 @@ "lodash": "^4.17.21", "opossum": "^8.3.0", "pako": "^2.1.0", + "protobufjs": "^8.7.2", "vue": "^2.7.14", "vue-i18n": "^8.28.2", "vue-router": "^3.6.5" diff --git a/frontend/src/api/chat/ChatClientDirectWeb.js b/frontend/src/api/chat/ChatClientDirectWeb.js index 7c82138..582e25a 100644 --- a/frontend/src/api/chat/ChatClientDirectWeb.js +++ b/frontend/src/api/chat/ChatClientDirectWeb.js @@ -3,6 +3,7 @@ import * as chat from '.' import * as chatModels from './models' import * as base from './ChatClientOfficialBase' import ChatClientOfficialBase from './ChatClientOfficialBase' +import { longToNumber, SendGiftBroadcast } from './pb' export default class ChatClientDirectWeb extends ChatClientOfficialBase { constructor(roomId) { @@ -177,6 +178,40 @@ export default class ChatClientDirectWeb extends ChatClientOfficialBase { this.msgHandler.onAddGift(data) } + sendGiftV2Callback(command) { + let data = command.data + // let bytes = Uint8Array.fromBase64(data.pb) + let bytes = Uint8Array.from(atob(data.pb), c => c.charCodeAt(0)) + let proto = SendGiftBroadcast.decode(bytes) + + let uid = longToNumber(proto.uid) + uid = uid ? uid.toString() : proto.uname + let medalRuid = longToNumber(proto.medal_info.target_id) + let medalLevel = medalRuid === this.roomOwnerUid ? longToNumber(proto.medal_info.medal_level) : 0 + let medalName = medalRuid === this.roomOwnerUid ? proto.medal_info.medal_name : '' + + for (let gift of proto.gift_list) { + let isPaidGift = gift.coin_type === 'gold' + let giftMsg = new chatModels.AddGiftMsg({ + avatarUrl: chat.processAvatarUrl(proto.face), + timestamp: longToNumber(gift.timestamp), + authorName: proto.uname, + totalCoin: isPaidGift ? longToNumber(gift.total_coin) : 0, + totalFreeCoin: !isPaidGift ? longToNumber(gift.total_coin) : 0, + giftName: gift.gift_name, + num: longToNumber(gift.num), + // 给模板用的字段 + giftId: longToNumber(gift.gift_id), + giftIconUrl: gift.gift_info.img_basic, + uid: uid, + privilegeType: longToNumber(proto.guard_level), + medalLevel: medalLevel, + medalName: medalName, + }) + this.msgHandler.onAddGift(giftMsg) + } + } + async userToastV2Callback(command) { let data = command.data // 官方的评论栏不会显示2的消息 @@ -260,6 +295,7 @@ const CMD_CALLBACK_MAP = { DANMU_MSG: ChatClientDirectWeb.prototype.danmuMsgCallback, DANMU_MSG_MIRROR: ChatClientDirectWeb.prototype.danmuMsgMirrorCallback, SEND_GIFT: ChatClientDirectWeb.prototype.sendGiftCallback, + SEND_GIFT_V2: ChatClientDirectWeb.prototype.sendGiftV2Callback, USER_TOAST_MSG_V2: ChatClientDirectWeb.prototype.userToastV2Callback, SUPER_CHAT_MESSAGE: ChatClientDirectWeb.prototype.superChatMessageCallback, SUPER_CHAT_MESSAGE_DELETE: ChatClientDirectWeb.prototype.superChatMessageDeleteCallback diff --git a/frontend/src/api/chat/pb.js b/frontend/src/api/chat/pb.js new file mode 100644 index 0000000..1b24e59 --- /dev/null +++ b/frontend/src/api/chat/pb.js @@ -0,0 +1,39 @@ +import protobuf, { Field, Root, Type } from 'protobufjs' + +const Long = protobuf.util.Long + +export function longToNumber(value) { + return Long && value instanceof Long ? value.toNumber() : value +} + +const SendGiftV2MedalInfo = new Type('SendGiftV2MedalInfo') + .add(new Field('target_id', 1, 'int64')) + .add(new Field('medal_level', 5, 'int64')) + .add(new Field('medal_name', 6, 'string')) + +const SendGiftV2GiftMaterialSnapShot = new Type('SendGiftV2GiftMaterialSnapShot') + .add(new Field('img_basic', 1, 'string')) + +const SendGiftV2GiftItem = new Type('SendGiftV2GiftItem') + .add(new Field('gift_id', 1, 'int64')) + .add(new Field('gift_name', 2, 'string')) + .add(new Field('num', 3, 'int64')) + .add(new Field('total_coin', 7, 'int64')) + .add(new Field('coin_type', 8, 'string')) + .add(new Field('timestamp', 10, 'int64')) + .add(new Field('gift_info', 35, 'SendGiftV2GiftMaterialSnapShot')) + +export const SendGiftBroadcast = new Type('SendGiftBroadcast') + .add(new Field('uid', 1, 'int64')) + .add(new Field('uname', 2, 'string')) + .add(new Field('face', 3, 'string')) + .add(new Field('guard_level', 5, 'int64')) + .add(new Field('medal_info', 8, 'SendGiftV2MedalInfo')) + .add(new Field('gift_list', 10, 'SendGiftV2GiftItem', 'repeated')) + +export const root = new Root() + .define('bilibili.live.gift.v1') + .add(SendGiftV2MedalInfo) + .add(SendGiftV2GiftMaterialSnapShot) + .add(SendGiftV2GiftItem) + .add(SendGiftBroadcast) diff --git a/pyproject.toml b/pyproject.toml index 323b558..53d0bc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,8 +38,8 @@ version = {source = "file", path = "update.py"} distribution = false [tool.uv.sources] -blivedm = {git = "https://github.com/xfgryujk/blivedm.git", rev = "8727ca9f8340e9c1e20e473eb1757bffb56c66f6"} blcsdk = {workspace = true, editable = true} +blivedm = { git = "https://github.com/xfgryujk/blivedm.git", rev = "3bf17fe862b8c2fc6bc04c81c3f0c5db95de93d6" } [tool.uv.workspace] members = ["blcsdk"] diff --git a/uv.lock b/uv.lock index 9bfde1e..571e6e8 100644 --- a/uv.lock +++ b/uv.lock @@ -103,7 +103,7 @@ dev = [ requires-dist = [ { name = "aiohttp", specifier = "==3.9.5" }, { name = "blcsdk", editable = "blcsdk" }, - { name = "blivedm", git = "https://github.com/xfgryujk/blivedm.git?rev=8727ca9f8340e9c1e20e473eb1757bffb56c66f6" }, + { name = "blivedm", git = "https://github.com/xfgryujk/blivedm.git?rev=3bf17fe862b8c2fc6bc04c81c3f0c5db95de93d6" }, { name = "cachetools", specifier = "==5.3.1" }, { name = "circuitbreaker", specifier = "==2.0.0" }, { name = "pycryptodome", specifier = "==3.19.1" }, @@ -117,8 +117,8 @@ dev = [{ name = "pyinstaller", specifier = "~=6.20.0" }] [[package]] name = "blivedm" -version = "1.1.6" -source = { git = "https://github.com/xfgryujk/blivedm.git?rev=8727ca9f8340e9c1e20e473eb1757bffb56c66f6#8727ca9f8340e9c1e20e473eb1757bffb56c66f6" } +version = "1.1.7" +source = { git = "https://github.com/xfgryujk/blivedm.git?rev=3bf17fe862b8c2fc6bc04c81c3f0c5db95de93d6#3bf17fe862b8c2fc6bc04c81c3f0c5db95de93d6" } dependencies = [ { name = "aiohttp" }, { name = "brotli" },