From 86ccf4bbf5aaa9626a194444e18fe532e1e6c5f9 Mon Sep 17 00:00:00 2001 From: maye174 <96584640+maye174@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:18:36 +0800 Subject: [PATCH 1/3] Improve the process of handling live danmuku --- wiliwili/include/api/live/danmaku_live.hpp | 13 +- wiliwili/include/api/live/dl_emoticon.hpp | 14 ++ wiliwili/include/view/danmaku_core.hpp | 4 +- .../source/activity/live_player_activity.cpp | 22 +-- wiliwili/source/api/danmaku_live.cpp | 100 +++++------- wiliwili/source/api/util/dl_emoticon.cpp | 84 ++++++++++ wiliwili/source/api/util/extract_messages.cpp | 154 +++++++++--------- wiliwili/source/view/danmaku_core.cpp | 22 +-- 8 files changed, 239 insertions(+), 174 deletions(-) create mode 100644 wiliwili/include/api/live/dl_emoticon.hpp create mode 100644 wiliwili/source/api/util/dl_emoticon.cpp diff --git a/wiliwili/include/api/live/danmaku_live.hpp b/wiliwili/include/api/live/danmaku_live.hpp index f7932007..c4933ce9 100644 --- a/wiliwili/include/api/live/danmaku_live.hpp +++ b/wiliwili/include/api/live/danmaku_live.hpp @@ -4,18 +4,15 @@ #pragma once -#include -#include - #include #include -#include #include #include #include -#include -#include "mongoose.h" // Include Mongoose header file +#include +#include +#include "mongoose.h" class LiveDanmaku : public brls::Singleton { public: @@ -28,8 +25,8 @@ class LiveDanmaku : public brls::Singleton { void send_heartbeat(); void send_text_message(const std::string &message); - void setonMessage(std::function func); - std::function onMessage; + void setonMessage(std::function func); + std::function onMessage; void set_wait_time(int time); int wait_time = 800; diff --git a/wiliwili/include/api/live/dl_emoticon.hpp b/wiliwili/include/api/live/dl_emoticon.hpp new file mode 100644 index 00000000..c168c470 --- /dev/null +++ b/wiliwili/include/api/live/dl_emoticon.hpp @@ -0,0 +1,14 @@ +// +//Created by Maye174 on 2023/8/7. +// + +#pragma once + +#include +#include +#include +#include + +using lmp = std::unordered_map>; + +lmp dl_emoticon(int room_id); \ No newline at end of file diff --git a/wiliwili/include/view/danmaku_core.hpp b/wiliwili/include/view/danmaku_core.hpp index 23463a89..81d2184b 100644 --- a/wiliwili/include/view/danmaku_core.hpp +++ b/wiliwili/include/view/danmaku_core.hpp @@ -4,6 +4,8 @@ #pragma once +#include "api/live/extract_messages.hpp" + #include #include #include @@ -12,7 +14,7 @@ class DanmakuItem { public: DanmakuItem(std::string content, const char *attributes); - DanmakuItem(std::string &&content, const std::string &attributes); + DanmakuItem(const float _time, danmaku_t *dan); std::string msg; // 弹幕内容 float time; // 弹幕出现的时间 diff --git a/wiliwili/source/activity/live_player_activity.cpp b/wiliwili/source/activity/live_player_activity.cpp index 9031d893..8c8b80c9 100644 --- a/wiliwili/source/activity/live_player_activity.cpp +++ b/wiliwili/source/activity/live_player_activity.cpp @@ -16,19 +16,13 @@ using namespace brls::literals; -#define tostr(x) std::to_string(x) -static void process_danmaku(danmaku_t *dan){ - char comma = ','; - std::string tem = "0,0,0,0,"; +static void process_danmaku(danmaku_t* dan) { //做其他处理 //... //弹幕加载到视频中去 - double time = MPVCore::instance().getPlaybackTime() + 0.3; - std::string combined_attr = tostr(time) + comma + tostr(dan->dan_type) + comma - + tostr(dan->dan_size) + comma + tostr(dan->dan_color) + comma - + tem + tostr(dan->user_level); - DanmakuCore::instance().addSingleDanmaku(DanmakuItem(dan->dan, combined_attr)); + float time = MPVCore::instance().getPlaybackTime() + 0.1; + DanmakuCore::instance().addSingleDanmaku(DanmakuItem(time, dan)); danmaku_t_free(dan); } @@ -38,14 +32,14 @@ static void onDanmakuReceived(std::string&& message) { std::vector payload(msg.begin(), msg.end()); std::vector messages = parse_packet(payload); - if(messages.size() == 0){ + if (messages.size() == 0) { return; } - for(auto &&live_msg : extract_messages(messages)){ - if(live_msg.type == danmaku){ - if(!live_msg.ptr) continue; - process_danmaku((danmaku_t *)live_msg.ptr); + for (const auto& live_msg : extract_messages(messages)) { + if (live_msg.type == danmaku) { + if (!live_msg.ptr) continue; + process_danmaku((danmaku_t*)live_msg.ptr); free(live_msg.ptr); } else if (live_msg.type == watched_change) { //todo diff --git a/wiliwili/source/api/danmaku_live.cpp b/wiliwili/source/api/danmaku_live.cpp index 33b09166..a3d23bf0 100644 --- a/wiliwili/source/api/danmaku_live.cpp +++ b/wiliwili/source/api/danmaku_live.cpp @@ -2,23 +2,18 @@ // Created by maye174 on 2023/4/6. // -#include +#include "live/danmaku_live.hpp" +#include "live/ws_utils.hpp" -#include -#include -#include #include -#include #include #include - -#include "live/danmaku_live.hpp" -#include "live/ws_utils.hpp" - #ifdef _WIN32 #include #endif +#include + using json = nlohmann::json; const std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub"; @@ -52,18 +47,19 @@ static void heartbeat_timer(void *param) { typedef struct task { // 函数 - std::function onMessage; + std::function onMessage; // 参数 std::string arg; // 优先级,暂时都设置0 int priority; -}task; +} task; static std::queue task_q; static std::condition_variable cv; static std::mutex task_mutex; -static void add_task(std::function &func, std::string &&a){ +static void add_task(std::function &func, + std::string &&a) { std::lock_guard lock(task_mutex); task_q.emplace(task{func, a, 0}); cv.notify_one(); @@ -77,7 +73,7 @@ void LiveDanmaku::connect(int room_id, int uid) { // Create and configure Mongoose connection this->mgr = new mg_mgr; - if(this->mgr == nullptr){ + if (this->mgr == nullptr) { disconnect(); return; } @@ -85,9 +81,10 @@ void LiveDanmaku::connect(int room_id, int uid) { mg_log_set(MG_LL_NONE); mg_mgr_init(this->mgr); - this->nc = mg_ws_connect(this->mgr, url.c_str(), mongoose_event_handler, this, nullptr); + this->nc = mg_ws_connect(this->mgr, url.c_str(), mongoose_event_handler, + this, nullptr); - if(this->nc == nullptr) { + if (this->nc == nullptr) { std::cout << "nc is null" << std::endl; disconnect(); mg_mgr_free(this->mgr); @@ -95,16 +92,15 @@ void LiveDanmaku::connect(int room_id, int uid) { return; } - this->room_id = room_id; - this->uid = uid; + this->uid = uid; //mg_mgr_poll(this->mgr, 10); // Start Mongoose event loop and heartbeat thread mongoose_thread = std::thread([this]() { while (this->is_connected()) { this->mongoose_mutex.lock(); - if(this->nc == nullptr) { + if (this->nc == nullptr) { break; } this->mongoose_mutex.unlock(); @@ -114,12 +110,13 @@ void LiveDanmaku::connect(int room_id, int uid) { delete this->mgr; }); - task_thread = std::thread([this](){ + task_thread = std::thread([this]() { while (true) { std::unique_lock lock(task_mutex); - cv.wait(lock, [this]{return !task_q.empty() or !this->is_connected();}); - if (!this->is_connected()) - break; + cv.wait(lock, [this] { + return !task_q.empty() or !this->is_connected(); + }); + if (!this->is_connected()) break; auto task = task_q.front(); task_q.pop(); lock.unlock(); @@ -129,8 +126,6 @@ void LiveDanmaku::connect(int room_id, int uid) { }); } - - void LiveDanmaku::disconnect() { if (!connected.load(std::memory_order_acquire)) { return; @@ -140,45 +135,36 @@ void LiveDanmaku::disconnect() { connected.store(false, std::memory_order_release); // Stop Mongoose event loop thread - if(mongoose_thread.joinable()) { + if (mongoose_thread.joinable()) { mongoose_thread.join(); } cv.notify_one(); - if(task_thread.joinable()){ + if (task_thread.joinable()) { task_thread.join(); } - } -void LiveDanmaku::set_wait_time(int time){ - wait_time = time; -} +void LiveDanmaku::set_wait_time(int time) { wait_time = time; } bool LiveDanmaku::is_connected() { return connected.load(std::memory_order_acquire); } -bool LiveDanmaku::is_evOK(){ - return ms_ev_ok.load(std::memory_order_acquire); -} +bool LiveDanmaku::is_evOK() { return ms_ev_ok.load(std::memory_order_acquire); } void LiveDanmaku::send_join_request(int room_id, int uid) { - json join_request = { - {"clientver", "1.6.3"}, - {"platform", "web"}, - {"protover", 2}, - {"roomid", room_id}, - {"uid", uid}, - {"type", 2} - }; + json join_request = {{"clientver", "1.6.3"}, {"platform", "web"}, + {"protover", 2}, {"roomid", room_id}, + {"uid", uid}, {"type", 2}}; std::string join_request_str = join_request.dump(); - std::vector packet = encode_packet(0, 7, join_request_str); + std::vector packet = encode_packet(0, 7, join_request_str); std::string packet_str(packet.begin(), packet.end()); mongoose_mutex.lock(); - if(this->nc == nullptr) return; - mg_ws_send(this->nc, packet_str.data(), packet_str.size(), WEBSOCKET_OP_BINARY); + if (this->nc == nullptr) return; + mg_ws_send(this->nc, packet_str.data(), packet_str.size(), + WEBSOCKET_OP_BINARY); mongoose_mutex.unlock(); } @@ -186,19 +172,18 @@ void LiveDanmaku::send_heartbeat() { std::vector packet = encode_packet(0, 2, ""); std::string packet_str(packet.begin(), packet.end()); mongoose_mutex.lock(); - if(this->nc == nullptr) return; - mg_ws_send(this->nc, packet_str.data(), packet_str.size(), WEBSOCKET_OP_BINARY); + if (this->nc == nullptr) return; + mg_ws_send(this->nc, packet_str.data(), packet_str.size(), + WEBSOCKET_OP_BINARY); mongoose_mutex.unlock(); } void LiveDanmaku::send_text_message(const std::string &message) { -//暂时不用 + //暂时不用 } - - - -static void mongoose_event_handler(struct mg_connection *nc, int ev, void *ev_data, void *user_data) { +static void mongoose_event_handler(struct mg_connection *nc, int ev, + void *ev_data, void *user_data) { LiveDanmaku *liveDanmaku = static_cast(user_data); liveDanmaku->ms_ev_ok.store(true, std::memory_order_release); if (ev == MG_EV_OPEN) { @@ -209,18 +194,19 @@ static void mongoose_event_handler(struct mg_connection *nc, int ev, void *ev_da liveDanmaku->ms_ev_ok.store(false, std::memory_order_release); } else if (ev == MG_EV_WS_OPEN) { liveDanmaku->send_join_request(liveDanmaku->room_id, liveDanmaku->uid); - mg_timer_add(liveDanmaku->mgr, 30000, MG_TIMER_REPEAT, - heartbeat_timer, user_data); + mg_timer_add(liveDanmaku->mgr, 30000, MG_TIMER_REPEAT, heartbeat_timer, + user_data); } else if (ev == MG_EV_WS_MSG) { - struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; + struct mg_ws_message *wm = (struct mg_ws_message *)ev_data; //liveDanmaku->onMessage(std::string(wm->data.ptr, wm->data.len)); - add_task(liveDanmaku->onMessage, std::string(wm->data.ptr, wm->data.len)); - } else if(ev == MG_EV_CLOSE) { + add_task(liveDanmaku->onMessage, + std::string(wm->data.ptr, wm->data.len)); + } else if (ev == MG_EV_CLOSE) { //liveDanmaku->disconnect(); liveDanmaku->ms_ev_ok.store(false, std::memory_order_release); } } -void LiveDanmaku::setonMessage(std::function func) { +void LiveDanmaku::setonMessage(std::function func) { onMessage = func; } \ No newline at end of file diff --git a/wiliwili/source/api/util/dl_emoticon.cpp b/wiliwili/source/api/util/dl_emoticon.cpp new file mode 100644 index 00000000..debad058 --- /dev/null +++ b/wiliwili/source/api/util/dl_emoticon.cpp @@ -0,0 +1,84 @@ +// +//Created by Maye174 on 2023/8/7. +// + +#include +#include + +#include +#include +#include + +#include "live/dl_emoticon.hpp" + +static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) { + ((std::vector*)userp)->insert(((std::vector*)userp)->end(), + (char*)contents, (char*)contents + size * nmemb); + return size * nmemb; +} + +static void download(const std::string &url, std::vector &data) { + CURL *curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); + curl_easy_perform(curl); + + curl_easy_cleanup(curl); +} + +static void to_url(int room_id, std::vector &names, + std::vector &urls) { + std::string u = "https://api.live.bilibili.com/xlive/web-ucenter/v2/emoticon/GetEmoticons?platform=pc&room_id="; + std::vector data; + download(u + std::to_string(room_id), data); + + nlohmann::json _json = nlohmann::json::parse(data); + + auto it = _json["data"]["data"]; + + if (it.is_array()) { + int n = it.size(); + + for (int i = 0; i < n; ++i) { + if(!it.is_array()) break; + + int e_n = it[i].size(); + auto e_it = it[i]["emoticons"]; + + if(!e_it.is_array()) break; + + for (int j = 0; j < e_n; ++j) { + auto em_name = e_it[i]["emoji"]; + + if(!em_name.is_string()) break; + + auto em_url = e_it[j]["url"]; + + if(!em_url.is_string()) break; + + names.emplace_back(em_name.get_ref()); + urls.emplace_back(em_url.get_ref()); + } + } + } +} + + +lmp dl_emoticon(int room_id){ + lmp ret; + + std::vector names; + std::vector urls; + + to_url(room_id,names, urls); + + int n = names.size(); + for (int i = 0; i < n; ++i) { + std::vector data; + download(urls[i], data); + ret[names[i]] = std::move(data); + } + + return ret; +} diff --git a/wiliwili/source/api/util/extract_messages.cpp b/wiliwili/source/api/util/extract_messages.cpp index c18299d0..8d2accb2 100644 --- a/wiliwili/source/api/util/extract_messages.cpp +++ b/wiliwili/source/api/util/extract_messages.cpp @@ -4,35 +4,34 @@ #include #include - -danmaku_t* danmaku_t_init(){ - danmaku_t *ret = (danmaku_t *) malloc(sizeof(danmaku_t)); - ret->user_name = nullptr; - ret->user_name_color = nullptr; - ret->dan = nullptr; - ret->fan_medal_name = nullptr; +danmaku_t *danmaku_t_init() { + danmaku_t *ret = (danmaku_t *)malloc(sizeof(danmaku_t)); + ret->user_name = nullptr; + ret->user_name_color = nullptr; + ret->dan = nullptr; + ret->fan_medal_name = nullptr; ret->fan_medal_liveuser_name = nullptr; - ret->user_uid = 0; - ret->dan_color = 16777215; - ret->fan_medal_roomid = 0; - ret->fan_medal_font_color = 0; - ret->fan_medal_border_color = 0; - ret->fan_medal_start_color = 0; - ret->fan_medal_end_color = 0; - ret->fan_medal_liveuser_uid = 0; - ret->is_emoticon = 0; - ret->dan_type = 1; - ret->dan_size = 25; - ret->user_level = 1; - ret->user_vip_level = 0; - ret->fan_medal_level = 0; - ret->fan_medal_vip_level = 0; - ret->is_guard = 0; - ret->glory_v = 0; + ret->user_uid = 0; + ret->dan_color = 16777215; + ret->fan_medal_roomid = 0; + ret->fan_medal_font_color = 0; + ret->fan_medal_border_color = 0; + ret->fan_medal_start_color = 0; + ret->fan_medal_end_color = 0; + ret->fan_medal_liveuser_uid = 0; + ret->is_emoticon = 0; + ret->dan_type = 1; + ret->dan_size = 25; + ret->user_level = 1; + ret->user_vip_level = 0; + ret->fan_medal_level = 0; + ret->fan_medal_vip_level = 0; + ret->is_guard = 0; + ret->glory_v = 0; return ret; } -void danmaku_t_free(danmaku_t *p){ +void danmaku_t_free(danmaku_t *p) { free(p->user_name); free(p->user_name_color); free(p->dan); @@ -40,34 +39,30 @@ void danmaku_t_free(danmaku_t *p){ free(p->fan_medal_liveuser_name); } - -static char *to_cstr(const std::string& s){ +static char *to_cstr(const std::string &s) { char *ret = (char *)malloc(s.size() + 1); memcpy(ret, s.c_str(), s.size() + 1); return ret; } -std::vector extract_messages(const std::vector& messages) { - +std::vector extract_messages(const std::vector &messages) { std::vector live_messages; - live_messages.reserve(messages.size()); + live_messages.reserve(messages.size() / 5); - for (auto& message : messages) { - - - nlohmann::json json_message = nlohmann::json::parse(message); + for (auto &message : messages) { + nlohmann::json json_message = nlohmann::json::parse(message); auto it = json_message.find("cmd"); if (it == json_message.end()) continue; if (it->get() == "WATCHED_CHANGE") { - - if(json_message["data"]["num"].is_number()) continue; + if (json_message["data"]["num"].is_number()) continue; auto num = json_message["data"]["num"].get(); - watched_change_t *wc = (watched_change_t *)malloc(sizeof(watched_change_t)); + watched_change_t *wc = + (watched_change_t *)malloc(sizeof(watched_change_t)); if (!wc) { continue; @@ -77,96 +72,95 @@ std::vector extract_messages(const std::vector& messages) { live_messages.emplace_back(live_t{watched_change, wc}); } else if (it->get() == "DANMU_MSG") { - auto& info = json_message["info"]; + auto &info = json_message["info"]; - if(!info.is_array() || info.size() != 17) continue; + if (!info.is_array() || info.size() != 17) continue; danmaku_t *dan = danmaku_t_init(); - if(!dan) { + if (!dan) { continue; } if (info[0].is_array() && info[0].size() > 12) { - auto& attribute = info[0]; - if(attribute[1].is_number()) + auto &attribute = info[0]; + if (attribute[1].is_number()) dan->dan_type = attribute[1].get(); - if(attribute[2].is_number()) + if (attribute[2].is_number()) dan->dan_size = attribute[2].get(); - if(attribute[3].is_number()) + if (attribute[3].is_number()) dan->dan_color = attribute[3].get(); - if(attribute[12].is_number()) + if (attribute[12].is_number()) dan->is_emoticon = attribute[12].get(); } - - if(info[1].is_string()){ - dan->dan = to_cstr(info[1].get_ref()); + + if (info[1].is_string()) { + dan->dan = to_cstr(info[1].get_ref()); } - if(info[2].is_array() && info[2].size() == 8) { - auto& user = info[2]; - if(user[0].is_number()) - dan->user_uid = user[0].get(); + if (info[2].is_array() && info[2].size() == 8) { + auto &user = info[2]; + if (user[0].is_number()) dan->user_uid = user[0].get(); - if(user[1].is_string()) - dan->user_name = to_cstr(user[1].get_ref()); + if (user[1].is_string()) + dan->user_name = + to_cstr(user[1].get_ref()); - if(user[2].is_number()) - dan->is_guard = user[2].get(); + if (user[2].is_number()) dan->is_guard = user[2].get(); - if(user[7].is_string()) - dan->user_name_color = to_cstr(user[7].get_ref()); + if (user[7].is_string()) + dan->user_name_color = + to_cstr(user[7].get_ref()); } - if(info[3].is_array() && info[3].size() == 13) { - - auto& fan = info[3]; - if(fan[0].is_number()) + if (info[3].is_array() && info[3].size() == 13) { + auto &fan = info[3]; + if (fan[0].is_number()) dan->fan_medal_level = fan[0].get(); - if(fan[1].is_string()) - dan->fan_medal_name = to_cstr(fan[1].get_ref()); + if (fan[1].is_string()) + dan->fan_medal_name = + to_cstr(fan[1].get_ref()); - if(fan[2].is_string()) - dan->fan_medal_liveuser_name = to_cstr(fan[2].get_ref()); + if (fan[2].is_string()) + dan->fan_medal_liveuser_name = + to_cstr(fan[2].get_ref()); - if(fan[3].is_number()) + if (fan[3].is_number()) dan->fan_medal_roomid = fan[3].get(); - if(fan[6].is_number()) + if (fan[6].is_number()) dan->fan_medal_font_color = fan[6].get(); - if(fan[7].is_number()) + if (fan[7].is_number()) dan->fan_medal_border_color = fan[7].get(); - if(fan[8].is_number()) + if (fan[8].is_number()) dan->fan_medal_end_color = fan[8].get(); - if(fan[9].is_number()) + if (fan[9].is_number()) dan->fan_medal_start_color = fan[9].get(); - if(fan[10].is_number()) + if (fan[10].is_number()) dan->fan_medal_vip_level = fan[10].get(); - if(fan[12].is_number()) + if (fan[12].is_number()) dan->fan_medal_liveuser_uid = fan[12].get(); - } - if(info[4].is_array() && info[4].size() > 0){ - if(info[4][0].is_number()) + if (info[4].is_array() && info[4].size() > 0) { + if (info[4][0].is_number()) dan->user_level = info[4][0].get(); } - - if(info[7].is_number()){ + + if (info[7].is_number()) { dan->user_vip_level = info[7].get(); } - + live_messages.emplace_back(live_t{danmaku, dan}); } - } return live_messages; } \ No newline at end of file diff --git a/wiliwili/source/view/danmaku_core.cpp b/wiliwili/source/view/danmaku_core.cpp index 51d31e83..e6a6e908 100644 --- a/wiliwili/source/view/danmaku_core.cpp +++ b/wiliwili/source/view/danmaku_core.cpp @@ -44,26 +44,20 @@ DanmakuItem::DanmakuItem(std::string content, const char *attributes) } } -DanmakuItem::DanmakuItem(std::string &&content, const std::string &attributes){ - msg = std::move(content); +DanmakuItem::DanmakuItem(const float _time, danmaku_t *dan) { + msg = std::string(dan->dan); #ifdef OPENCC static bool ZH_T = brls::Application::getLocale() == brls::LOCALE_ZH_HANT || brls::Application::getLocale() == brls::LOCALE_ZH_TW; if (ZH_T && brls::Label::OPENCC_ON) msg = brls::Label::STConverter(msg); #endif - std::vector attrs; - pystring::split(attributes.c_str(), attrs, ","); - if (attrs.size() < 9) { - brls::Logger::error("error decode danmaku: {} {}", msg, attributes); - type = -1; - return; - } - time = atof(attrs[0].c_str()); - type = atoi(attrs[1].c_str()); - fontSize = atoi(attrs[2].c_str()); - fontColor = atoi(attrs[3].c_str()); - level = atoi(attrs[8].c_str()); + + time = _time; + type = dan->dan_type; + fontSize = dan->dan_size; + fontColor = dan->dan_color; + level = dan->user_level; int r = (fontColor >> 16) & 0xff; int g = (fontColor >> 8) & 0xff; From 8ab309375d1e04144ebcc2f1a35c1bdc82f74fd2 Mon Sep 17 00:00:00 2001 From: maye174 <96584640+maye174@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:28:50 +0800 Subject: [PATCH 2/3] fix live danmaku --- wiliwili/include/view/danmaku_core.hpp | 5 +- .../source/activity/live_player_activity.cpp | 16 ++--- wiliwili/source/api/danmaku_live.cpp | 60 +++++++++++++++---- wiliwili/source/view/danmaku_core.cpp | 7 ++- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/wiliwili/include/view/danmaku_core.hpp b/wiliwili/include/view/danmaku_core.hpp index 81d2184b..3d2c165a 100644 --- a/wiliwili/include/view/danmaku_core.hpp +++ b/wiliwili/include/view/danmaku_core.hpp @@ -32,7 +32,8 @@ class DanmakuItem { int64_t startTime = 0; NVGcolor color = nvgRGBA(255, 255, 255, 160); NVGcolor borderColor = nvgRGBA(0, 0, 0, 160); - int level; // 弹幕等级 1-10 + int level; // 弹幕等级 1-10 直播弹幕等级0-60 + int is_live; // 是否为直播弹幕 // 暂时用不到的信息,先不使用 // int pubDate; // 弹幕发送时间 // int pool; // 弹幕池类型 @@ -102,6 +103,8 @@ class DanmakuCore : public brls::Singleton { /// range: [1 - 10], 1: show all danmaku, 10: the most strong filter static inline int DANMAKU_FILTER_LEVEL = 1; + //0-60 + static inline int DANMAKU_FILTER_LEVEL_LIVE = 0; static inline bool DANMAKU_FILTER_SHOW_TOP = true; static inline bool DANMAKU_FILTER_SHOW_BOTTOM = true; diff --git a/wiliwili/source/activity/live_player_activity.cpp b/wiliwili/source/activity/live_player_activity.cpp index 8c8b80c9..4acaf3fd 100644 --- a/wiliwili/source/activity/live_player_activity.cpp +++ b/wiliwili/source/activity/live_player_activity.cpp @@ -16,13 +16,13 @@ using namespace brls::literals; -static void process_danmaku(danmaku_t* dan) { - //做其他处理 +static void process_danmaku(const float time, danmaku_t* dan) { + //TODO:做其他处理 //... //弹幕加载到视频中去 - float time = MPVCore::instance().getPlaybackTime() + 0.1; - DanmakuCore::instance().addSingleDanmaku(DanmakuItem(time, dan)); + float _time = MPVCore::instance().getPlaybackTime() + time; + DanmakuCore::instance().addSingleDanmaku(DanmakuItem(_time, dan)); danmaku_t_free(dan); } @@ -36,13 +36,15 @@ static void onDanmakuReceived(std::string&& message) { return; } + float time = 0.1f; for (const auto& live_msg : extract_messages(messages)) { if (live_msg.type == danmaku) { if (!live_msg.ptr) continue; - process_danmaku((danmaku_t*)live_msg.ptr); + process_danmaku(time, (danmaku_t*)live_msg.ptr); free(live_msg.ptr); + time += 0.2f; } else if (live_msg.type == watched_change) { - //todo + //TODO: 更新在线人数 free(live_msg.ptr); } } @@ -71,7 +73,7 @@ LiveActivity::LiveActivity(int roomid, const std::string& name, void LiveActivity::setCommonData() { DanmakuCore::instance().reset(); - LiveDanmaku::instance().connect(liveData.roomid, 0 /*liveData.uid*/); + LiveDanmaku::instance().connect(liveData.roomid, liveData.uid); // 清空字幕 SubtitleCore::instance().reset(); diff --git a/wiliwili/source/api/danmaku_live.cpp b/wiliwili/source/api/danmaku_live.cpp index a3d23bf0..f5460cf9 100644 --- a/wiliwili/source/api/danmaku_live.cpp +++ b/wiliwili/source/api/danmaku_live.cpp @@ -3,11 +3,13 @@ // #include "live/danmaku_live.hpp" +#include "bilibili/util/http.hpp" #include "live/ws_utils.hpp" #include #include #include +#include #ifdef _WIN32 #include #endif @@ -16,7 +18,46 @@ using json = nlohmann::json; -const std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub"; +static std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub"; +static std::string buvid = ""; +static std::string key = ""; + +void get_live_s(int room_id) { + for (const auto &i : bilibili::HTTP::COOKIES) { + if (i.GetName() == "buvid3") { + buvid = i.GetValue(); + break; + } + } + + auto res = bilibili::HTTP::get( + "https://api.live.bilibili.com/xlive/web-room/v1/index/" + "getDanmuInfo?type=0&id=" + + std::to_string(room_id)); + + if (res.status_code != 200) { + std::cout << "getDanmuInfo error" << std::endl; + } else { + std::cout << "getDanmuInfo success" << std::endl; + json _json; + try { + _json = json::parse(res.text); + } catch (const std::exception &e) { + std::cout << "getDanmuInfo json parse error" << std::endl; + } + if (_json["code"].get() == 0) { + url = "ws://" + + _json["data"]["host_list"][0]["host"] + .get_ref() + + ":" + + std::to_string( + _json["data"]["host_list"][0]["ws_port"].get()) + + "/sub"; + std::cout << url << std::endl; + key = _json["data"]["token"].get_ref(); + } + } +} LiveDanmaku::LiveDanmaku() { #ifdef _WIN32 @@ -78,6 +119,8 @@ void LiveDanmaku::connect(int room_id, int uid) { return; } + get_live_s(room_id); + mg_log_set(MG_LL_NONE); mg_mgr_init(this->mgr); @@ -154,10 +197,10 @@ bool LiveDanmaku::is_connected() { bool LiveDanmaku::is_evOK() { return ms_ev_ok.load(std::memory_order_acquire); } -void LiveDanmaku::send_join_request(int room_id, int uid) { - json join_request = {{"clientver", "1.6.3"}, {"platform", "web"}, - {"protover", 2}, {"roomid", room_id}, - {"uid", uid}, {"type", 2}}; +void LiveDanmaku::send_join_request(const int room_id, const int uid) { + json join_request = {{"uid", uid}, {"roomid", room_id}, {"protover", 2}, + {"buvid", buvid}, {"platform", "web"}, {"type", 2}, + {"key", key}}; std::string join_request_str = join_request.dump(); std::vector packet = encode_packet(0, 7, join_request_str); std::string packet_str(packet.begin(), packet.end()); @@ -187,10 +230,9 @@ static void mongoose_event_handler(struct mg_connection *nc, int ev, LiveDanmaku *liveDanmaku = static_cast(user_data); liveDanmaku->ms_ev_ok.store(true, std::memory_order_release); if (ev == MG_EV_OPEN) { - nc->is_hexdumping = 1; + nc->is_hexdumping = 0; } else if (ev == MG_EV_ERROR) { - //MG_ERROR(("%p %s", nc->fd, (char *) ev_data)); - //liveDanmaku->disconnect(); + MG_ERROR(("%p %s", nc->fd, (char *)ev_data)); liveDanmaku->ms_ev_ok.store(false, std::memory_order_release); } else if (ev == MG_EV_WS_OPEN) { liveDanmaku->send_join_request(liveDanmaku->room_id, liveDanmaku->uid); @@ -198,11 +240,9 @@ static void mongoose_event_handler(struct mg_connection *nc, int ev, user_data); } else if (ev == MG_EV_WS_MSG) { struct mg_ws_message *wm = (struct mg_ws_message *)ev_data; - //liveDanmaku->onMessage(std::string(wm->data.ptr, wm->data.len)); add_task(liveDanmaku->onMessage, std::string(wm->data.ptr, wm->data.len)); } else if (ev == MG_EV_CLOSE) { - //liveDanmaku->disconnect(); liveDanmaku->ms_ev_ok.store(false, std::memory_order_release); } } diff --git a/wiliwili/source/view/danmaku_core.cpp b/wiliwili/source/view/danmaku_core.cpp index e6a6e908..bbfe84a3 100644 --- a/wiliwili/source/view/danmaku_core.cpp +++ b/wiliwili/source/view/danmaku_core.cpp @@ -28,6 +28,7 @@ DanmakuItem::DanmakuItem(std::string content, const char *attributes) fontSize = atoi(attrs[2].c_str()); fontColor = atoi(attrs[3].c_str()); level = atoi(attrs[8].c_str()); + is_live = 0; int r = (fontColor >> 16) & 0xff; int g = (fontColor >> 8) & 0xff; @@ -58,6 +59,7 @@ DanmakuItem::DanmakuItem(const float _time, danmaku_t *dan) { fontSize = dan->dan_size; fontColor = dan->dan_color; level = dan->user_level; + is_live = 1; int r = (fontColor >> 16) & 0xff; int g = (fontColor >> 8) & 0xff; @@ -270,7 +272,7 @@ void DanmakuCore::drawDanmaku(NVGcontext *vg, float x, float y, float width, } //滑动弹幕 float position = 0; - if (MPVCore::instance().isPaused()) { + if (!i.is_live && MPVCore::instance().isPaused()) { // 暂停状态弹幕也要暂停 position = i.speed * (playbackTime - i.time); i.startTime = @@ -316,7 +318,8 @@ void DanmakuCore::drawDanmaku(NVGcontext *vg, float x, float y, float width, /// 过滤弹幕 i.canShow = false; // 1. 过滤显示的弹幕级别 - if (i.level < DANMAKU_FILTER_LEVEL) continue; + if (!i.is_live && i.level < DANMAKU_FILTER_LEVEL) continue; + if (i.is_live && i.level < DANMAKU_FILTER_LEVEL_LIVE) continue; if (i.type == 4) { // 2. 过滤底部弹幕 From 119a6bdba9518ce2f054b47561dc47a15ec00dde Mon Sep 17 00:00:00 2001 From: maye174 <96584640+maye174@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:01:21 +0800 Subject: [PATCH 3/3] Add buvid into cookie --- .../include/api/live/extract_messages.hpp | 94 +++++++++---------- wiliwili/include/utils/config_helper.hpp | 4 +- wiliwili/include/view/danmaku_core.hpp | 2 +- .../source/activity/live_player_activity.cpp | 6 +- wiliwili/source/api/danmaku_live.cpp | 80 ++++++++-------- wiliwili/source/api/mine_api.cpp | 11 ++- wiliwili/source/api/util/extract_messages.cpp | 2 +- wiliwili/source/utils/config_helper.cpp | 11 ++- wiliwili/source/view/danmaku_core.cpp | 2 +- 9 files changed, 114 insertions(+), 98 deletions(-) diff --git a/wiliwili/include/api/live/extract_messages.hpp b/wiliwili/include/api/live/extract_messages.hpp index ea1d3a51..b05eb5eb 100644 --- a/wiliwili/include/api/live/extract_messages.hpp +++ b/wiliwili/include/api/live/extract_messages.hpp @@ -10,53 +10,52 @@ #include typedef enum { - watched_change,//在线人数更新,xx人看过 - online_cnt,//当前在线人数 - online_v2,//待确定,似乎是当前在线高能用户 - danmaku,//弹幕 - super_chat,//sc,醒目留言 - initeract_word,//普通用户的进场消息 - entry_effect,//舰长进场消息 - send_gift,//发送的礼物 - combo_send,//连击礼物 - like_info_update,//人气值(助力值) - like_info_click,//给主播点赞 -}message_t; //还有上舰长,续费信息什么的,暂时不加 - - -typedef struct{ + watched_change, //在线人数更新,xx人看过 + online_cnt, //当前在线人数 + online_v2, //待确定,似乎是当前在线高能用户 + danmaku, //弹幕 + super_chat, //sc,醒目留言 + initeract_word, //普通用户的进场消息 + entry_effect, //舰长进场消息 + send_gift, //发送的礼物 + combo_send, //连击礼物 + like_info_update, //人气值(助力值) + like_info_click, //给主播点赞 +} message_t; //还有上舰长,续费信息什么的,暂时不加 + +typedef struct { //b站会直接传3个值{"num":23592,"text_large":"2.3万人看过","text_small":"2.3万"} //真的浪费 int num; -}watched_change_t; +} watched_change_t; -typedef struct{ +typedef struct { //代表在线人数 int count; -}online_cnt_t; +} online_cnt_t; -typedef struct{ +typedef struct { //头像 - void *face_photo[10]; + void* face_photo[10]; //名字 - char * user_name[10]; + char* user_name[10]; //暂时先写这俩 -}online_v2_t; +} online_v2_t; //弹幕类型,内容太多,暂时写这么多 // //很多重复内容,感觉不是同一批人写的,或者可能b站想换协议, -typedef struct{ +typedef struct { //用户名字 - char * user_name; + char* user_name; //用户名字颜色,一般为舰长以上有,即vip等级1以上 - char * user_name_color; + char* user_name_color; //弹幕内容 - char * dan; + char* dan; //粉丝牌子名字 - char * fan_medal_name; + char* fan_medal_name; //粉丝牌子对应主播名字 - char * fan_medal_liveuser_name; + char* fan_medal_liveuser_name; //用户uid int user_uid; //弹幕颜色 @@ -92,20 +91,19 @@ typedef struct{ uint8_t is_guard; //荣耀值,就是用户名和牌子前面那个带蓝色框子的数字 暂时不用 uint8_t glory_v; -}danmaku_t; //Maye174: 为了对齐内存,乱序排 +} danmaku_t; //Maye174: 为了对齐内存,乱序排 danmaku_t* danmaku_t_init(); -void danmaku_t_free(danmaku_t* p); +void danmaku_t_free(const danmaku_t* p); -typedef struct{ +typedef struct { //todo -}super_chat_t; - +} super_chat_t; //这里b站的接口命名更混乱,感觉b站后面会逐步换掉 -typedef struct{ +typedef struct { //用户名字 - char * user_name; + char* user_name; //牌子字体颜色 目前应该都是白色 int fan_medal_font_color; //牌子边框颜色 @@ -118,30 +116,30 @@ typedef struct{ int fan_medal_uid; //牌子等级 uint8_t fan_medal_level; -}initeract_word_t; +} initeract_word_t; -initeract_word_t *initeract_word_t_init(); +initeract_word_t* initeract_word_t_init(); -typedef struct{ +typedef struct { //todo -}send_gift_t; +} send_gift_t; -typedef struct{ +typedef struct { //todo -}combo_send_t; +} combo_send_t; -typedef struct{ +typedef struct { //人气值,但是这个值叫click_count,我有点搞不清 int count; -}like_info_update_t; +} like_info_update_t; -typedef struct{ +typedef struct { //todo -}like_info_click_t; +} like_info_click_t; -typedef struct{ +typedef struct { message_t type; - void *ptr; -}live_t; + void* ptr; +} live_t; std::vector extract_messages(const std::vector& messages); \ No newline at end of file diff --git a/wiliwili/include/utils/config_helper.hpp b/wiliwili/include/utils/config_helper.hpp index fb6de1d9..1d515763 100644 --- a/wiliwili/include/utils/config_helper.hpp +++ b/wiliwili/include/utils/config_helper.hpp @@ -27,11 +27,10 @@ namespace fs = std::experimental::filesystem; #endif #ifdef PS4 -const std::string primaryDNSStr = "223.5.5.5"; +const std::string primaryDNSStr = "223.5.5.5"; const std::string secondaryDNSStr = "1.1.1.1"; #endif - typedef std::map Cookie; constexpr uint32_t MINIMUM_WINDOW_WIDTH = 640; constexpr uint32_t MINIMUM_WINDOW_HEIGHT = 360; @@ -157,6 +156,7 @@ class ProgramConfig : public brls::Singleton { std::string getRefreshToken() const; std::string getCSRF(); std::string getUserID(); + std::string getBuvid3(); bool hasLoginInfo(); // Google Analytics ID diff --git a/wiliwili/include/view/danmaku_core.hpp b/wiliwili/include/view/danmaku_core.hpp index 3d2c165a..ea4662ed 100644 --- a/wiliwili/include/view/danmaku_core.hpp +++ b/wiliwili/include/view/danmaku_core.hpp @@ -14,7 +14,7 @@ class DanmakuItem { public: DanmakuItem(std::string content, const char *attributes); - DanmakuItem(const float _time, danmaku_t *dan); + DanmakuItem(const float _time, const danmaku_t *dan); std::string msg; // 弹幕内容 float time; // 弹幕出现的时间 diff --git a/wiliwili/source/activity/live_player_activity.cpp b/wiliwili/source/activity/live_player_activity.cpp index 4acaf3fd..7b718c0a 100644 --- a/wiliwili/source/activity/live_player_activity.cpp +++ b/wiliwili/source/activity/live_player_activity.cpp @@ -9,6 +9,7 @@ #include "view/subtitle_core.hpp" #include "view/grid_dropdown.hpp" #include "utils/shader_helper.hpp" +#include "utils/config_helper.hpp" #include "live/danmaku_live.hpp" #include "live/extract_messages.hpp" #include "live/ws_utils.hpp" @@ -16,7 +17,7 @@ using namespace brls::literals; -static void process_danmaku(const float time, danmaku_t* dan) { +static void process_danmaku(const float time, const danmaku_t* dan) { //TODO:做其他处理 //... @@ -73,7 +74,8 @@ LiveActivity::LiveActivity(int roomid, const std::string& name, void LiveActivity::setCommonData() { DanmakuCore::instance().reset(); - LiveDanmaku::instance().connect(liveData.roomid, liveData.uid); + LiveDanmaku::instance().connect( + liveData.roomid, std::stoi(ProgramConfig::instance().getUserID())); // 清空字幕 SubtitleCore::instance().reset(); diff --git a/wiliwili/source/api/danmaku_live.cpp b/wiliwili/source/api/danmaku_live.cpp index f5460cf9..4805c4a2 100644 --- a/wiliwili/source/api/danmaku_live.cpp +++ b/wiliwili/source/api/danmaku_live.cpp @@ -5,6 +5,7 @@ #include "live/danmaku_live.hpp" #include "bilibili/util/http.hpp" #include "live/ws_utils.hpp" +#include "utils/config_helper.hpp" #include #include @@ -18,27 +19,18 @@ using json = nlohmann::json; -static std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub"; -static std::string buvid = ""; -static std::string key = ""; - -void get_live_s(int room_id) { - for (const auto &i : bilibili::HTTP::COOKIES) { - if (i.GetName() == "buvid3") { - buvid = i.GetValue(); - break; - } - } +static std::string url = "ws://broadcastlv.chat.bilibili.com:2244/sub"; +static std::string key = ""; +static void get_live_s(int room_id) { auto res = bilibili::HTTP::get( "https://api.live.bilibili.com/xlive/web-room/v1/index/" "getDanmuInfo?type=0&id=" + std::to_string(room_id)); if (res.status_code != 200) { - std::cout << "getDanmuInfo error" << std::endl; + brls::Logger::error("getDanmuInfo error:{}", res.status_code); } else { - std::cout << "getDanmuInfo success" << std::endl; json _json; try { _json = json::parse(res.text); @@ -53,29 +45,11 @@ void get_live_s(int room_id) { std::to_string( _json["data"]["host_list"][0]["ws_port"].get()) + "/sub"; - std::cout << url << std::endl; key = _json["data"]["token"].get_ref(); } } } -LiveDanmaku::LiveDanmaku() { -#ifdef _WIN32 - WSADATA wsaData; - int result = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (result != 0) { - printf("WSAStartup failed with error: %d\n", result); - } -#endif -} - -LiveDanmaku::~LiveDanmaku() { - disconnect(); -#ifdef _WIN32 - WSACleanup(); -#endif -} - static void mongoose_event_handler(struct mg_connection *nc, int ev, void *ev_data, void *user_data); @@ -88,7 +62,7 @@ static void heartbeat_timer(void *param) { typedef struct task { // 函数 - std::function onMessage; + const std::function onMessage; // 参数 std::string arg; // 优先级,暂时都设置0 @@ -99,13 +73,30 @@ static std::queue task_q; static std::condition_variable cv; static std::mutex task_mutex; -static void add_task(std::function &func, +static void add_task(const std::function &func, std::string &&a) { std::lock_guard lock(task_mutex); task_q.emplace(task{func, a, 0}); cv.notify_one(); } +LiveDanmaku::LiveDanmaku() { +#ifdef _WIN32 + WSADATA wsaData; + int result = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (result != 0) { + printf("WSAStartup failed with error: %d\n", result); + } +#endif +} + +LiveDanmaku::~LiveDanmaku() { + disconnect(); +#ifdef _WIN32 + WSACleanup(); +#endif +} + void LiveDanmaku::connect(int room_id, int uid) { if (connected.load(std::memory_order_acquire)) { return; @@ -167,6 +158,8 @@ void LiveDanmaku::connect(int room_id, int uid) { task.onMessage(std::move(task.arg)); } }); + + brls::Logger::info("(LiveDanmaku) connect step finish"); } void LiveDanmaku::disconnect() { @@ -187,6 +180,7 @@ void LiveDanmaku::disconnect() { if (task_thread.joinable()) { task_thread.join(); } + brls::Logger::info("(LiveDanmaku) close step finish"); } void LiveDanmaku::set_wait_time(int time) { wait_time = time; } @@ -198,11 +192,14 @@ bool LiveDanmaku::is_connected() { bool LiveDanmaku::is_evOK() { return ms_ev_ok.load(std::memory_order_acquire); } void LiveDanmaku::send_join_request(const int room_id, const int uid) { - json join_request = {{"uid", uid}, {"roomid", room_id}, {"protover", 2}, - {"buvid", buvid}, {"platform", "web"}, {"type", 2}, - {"key", key}}; + json join_request = { + {"uid", uid}, {"roomid", room_id}, + {"protover", 2}, {"buvid", ProgramConfig::instance().getBuvid3()}, + {"platform", "web"}, {"type", 2}, + {"key", key}}; std::string join_request_str = join_request.dump(); - std::vector packet = encode_packet(0, 7, join_request_str); + brls::Logger::info("(LiveDanmaku) join_request:{}", join_request_str); + std::vector packet = encode_packet(0, 7, join_request_str); std::string packet_str(packet.begin(), packet.end()); mongoose_mutex.lock(); if (this->nc == nullptr) return; @@ -212,6 +209,7 @@ void LiveDanmaku::send_join_request(const int room_id, const int uid) { } void LiveDanmaku::send_heartbeat() { + brls::Logger::debug("(LiveDanmaku) send_heartbeat"); std::vector packet = encode_packet(0, 2, ""); std::string packet_str(packet.begin(), packet.end()); mongoose_mutex.lock(); @@ -230,19 +228,27 @@ static void mongoose_event_handler(struct mg_connection *nc, int ev, LiveDanmaku *liveDanmaku = static_cast(user_data); liveDanmaku->ms_ev_ok.store(true, std::memory_order_release); if (ev == MG_EV_OPEN) { + MG_DEBUG(("%p %s", nc->fd, (char *)ev_data)); +#ifdef MONGOOSE_HEX_DUMPS + nc->is_hexdumping = 1; +#else nc->is_hexdumping = 0; +#endif } else if (ev == MG_EV_ERROR) { MG_ERROR(("%p %s", nc->fd, (char *)ev_data)); liveDanmaku->ms_ev_ok.store(false, std::memory_order_release); } else if (ev == MG_EV_WS_OPEN) { + MG_DEBUG(("%p %s", nc->fd, (char *)ev_data)); liveDanmaku->send_join_request(liveDanmaku->room_id, liveDanmaku->uid); mg_timer_add(liveDanmaku->mgr, 30000, MG_TIMER_REPEAT, heartbeat_timer, user_data); } else if (ev == MG_EV_WS_MSG) { + MG_DEBUG(("%p %s", nc->fd, (char *)ev_data)); struct mg_ws_message *wm = (struct mg_ws_message *)ev_data; add_task(liveDanmaku->onMessage, std::string(wm->data.ptr, wm->data.len)); } else if (ev == MG_EV_CLOSE) { + MG_DEBUG(("%p %s", nc->fd, (char *)ev_data)); liveDanmaku->ms_ev_ok.store(false, std::memory_order_release); } } diff --git a/wiliwili/source/api/mine_api.cpp b/wiliwili/source/api/mine_api.cpp index d5e2f9f0..d71b9fc1 100644 --- a/wiliwili/source/api/mine_api.cpp +++ b/wiliwili/source/api/mine_api.cpp @@ -77,11 +77,12 @@ void BilibiliClient::get_login_info_v2( const std::string& deviceID, const std::function& callback, const ErrorCallback& error) { + auto buvid3 = BilibiliClient::genRandomBuvid3(); HTTP::COOKIES = {{{"appkey", BILIBILI_APP_KEY}, {"mobi_app", "pc_electron"}, {"device", "mac"}, {"innersign", "0"}, - {"buvid3", BilibiliClient::genRandomBuvid3()}, + {"buvid3", buvid3}, {"device_id", deviceID}, {"device_name", deviceName}}, false}; @@ -89,13 +90,14 @@ void BilibiliClient::get_login_info_v2( HTTP::__cpr_get( Api::QrLoginInfoV2, {{"qrcode_key", qrcodeKey}, {"source", "main_electron_pc"}}, - [callback, error](const cpr::Response& r) { + [callback, error, buvid3](const cpr::Response& r) { try { HTTP::COOKIES = {false}; nlohmann::json res = nlohmann::json::parse(r.text); auto data = res.at("data").get(); if (data.status) { std::map cookies; + cookies["buvid3"] = buvid3; for (const auto& cookie : r.cookies) { cookies[cookie.GetName()] = cookie.GetValue(); HTTP::COOKIES.emplace_back( @@ -162,9 +164,8 @@ void BilibiliClient::get_my_history( void BilibiliClient::getWatchLater( const std::function& callback, const bilibili::ErrorCallback& error) { - HTTP::getResultAsync( - Api::WatchLater, {}, - callback, error); + HTTP::getResultAsync(Api::WatchLater, {}, callback, + error); } // diff --git a/wiliwili/source/api/util/extract_messages.cpp b/wiliwili/source/api/util/extract_messages.cpp index 8d2accb2..97355c2e 100644 --- a/wiliwili/source/api/util/extract_messages.cpp +++ b/wiliwili/source/api/util/extract_messages.cpp @@ -31,7 +31,7 @@ danmaku_t *danmaku_t_init() { return ret; } -void danmaku_t_free(danmaku_t *p) { +void danmaku_t_free(const danmaku_t *p) { free(p->user_name); free(p->user_name_color); free(p->dan); diff --git a/wiliwili/source/utils/config_helper.cpp b/wiliwili/source/utils/config_helper.cpp index 7c915ca8..1a1a4b59 100644 --- a/wiliwili/source/utils/config_helper.cpp +++ b/wiliwili/source/utils/config_helper.cpp @@ -71,7 +71,9 @@ std::unordered_map ProgramConfig::SETTING_MAP = { {SettingItem::APP_THEME, {"app_theme", {"auto", "light", "dark"}, {}, 0}}, {SettingItem::APP_RESOURCES, {"app_resources", {}, {}, 0}}, {SettingItem::APP_UI_SCALE, - {"app_ui_scale", {"544p", "720p", "900p", "1080p"}, {}, + {"app_ui_scale", + {"544p", "720p", "900p", "1080p"}, + {}, #ifdef __PSV__ 0}}, #else @@ -298,6 +300,13 @@ std::string ProgramConfig::getUserID() { return this->cookie["DedeUserID"]; } +std::string ProgramConfig::getBuvid3() { + if (this->cookie.count("buvid3") == 0) { + return ""; + } + return this->cookie["buvid3"]; +} + bool ProgramConfig::hasLoginInfo() { return !getUserID().empty() && (getUserID() != "0") && !getCSRF().empty(); } diff --git a/wiliwili/source/view/danmaku_core.cpp b/wiliwili/source/view/danmaku_core.cpp index bbfe84a3..abee7199 100644 --- a/wiliwili/source/view/danmaku_core.cpp +++ b/wiliwili/source/view/danmaku_core.cpp @@ -45,7 +45,7 @@ DanmakuItem::DanmakuItem(std::string content, const char *attributes) } } -DanmakuItem::DanmakuItem(const float _time, danmaku_t *dan) { +DanmakuItem::DanmakuItem(const float _time, const danmaku_t *dan) { msg = std::string(dan->dan); #ifdef OPENCC