From fe043f2b2a23e86d6d96b5fae25816ae4de674ca Mon Sep 17 00:00:00 2001 From: jp9000 Date: Wed, 6 Feb 2019 22:10:08 -0800 Subject: [PATCH] UI: Add per-profile browser panel cookie management Allows the ability to switch cookies between profiles. Allows the ability to, for example, switch streaming service accounts between profiles for proper access to the pages displayed by the browser panels (such as chat windows). --- UI/CMakeLists.txt | 1 + UI/window-basic-main-browser.cpp | 134 ++++++++++++++++++++++++++++++ UI/window-basic-main-profiles.cpp | 18 +++- UI/window-basic-main.cpp | 12 ++- UI/window-basic-main.hpp | 2 +- 5 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 UI/window-basic-main-browser.cpp diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt index bcb9815ad..04f8a973b 100644 --- a/UI/CMakeLists.txt +++ b/UI/CMakeLists.txt @@ -140,6 +140,7 @@ set(obs_SOURCES window-basic-main-transitions.cpp window-basic-main-dropfiles.cpp window-basic-main-profiles.cpp + window-basic-main-browser.cpp window-basic-status-bar.cpp window-basic-adv-audio.cpp window-basic-transform.cpp diff --git a/UI/window-basic-main-browser.cpp b/UI/window-basic-main-browser.cpp new file mode 100644 index 000000000..1478569ee --- /dev/null +++ b/UI/window-basic-main-browser.cpp @@ -0,0 +1,134 @@ +/****************************************************************************** + Copyright (C) 2018 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include +#include +#include +#include "window-basic-main.hpp" +#include "qt-wrappers.hpp" + +#include + +#ifdef BROWSER_AVAILABLE +#include +#endif + +struct QCef; +struct QCefCookieManager; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +static std::string GenId() +{ + std::random_device rd; + std::mt19937_64 e2(rd()); + std::uniform_int_distribution dist(0, 0xFFFFFFFFFFFFFFFF); + + uint64_t id = dist(e2); + + char id_str[20]; + snprintf(id_str, sizeof(id_str), "%16llX", (unsigned long long)id); + return std::string(id_str); +} + +void CheckExistingCookieId() +{ + OBSBasic *main = OBSBasic::Get(); + if (config_has_user_value(main->Config(), "Panels", "CookieId")) + return; + + config_set_string(main->Config(), "Panels", "CookieId", GenId().c_str()); +} + +#ifdef BROWSER_AVAILABLE +static void InitPanelCookieManager() +{ + if (!cef) + return; + if (panel_cookies) + return; + + CheckExistingCookieId(); + + OBSBasic *main = OBSBasic::Get(); + const char *cookie_id = config_get_string(main->Config(), + "Panels", "CookieId"); + + std::string sub_path; + sub_path += "obs_profile_cookies/"; + sub_path += cookie_id; + + panel_cookies = cef->create_cookie_manager(sub_path); +} +#endif + +void DestroyPanelCookieManager() +{ +#ifdef BROWSER_AVAILABLE + if (panel_cookies) { + panel_cookies->FlushStore(); + delete panel_cookies; + panel_cookies = nullptr; + } +#endif +} + +void DuplicateCurrentCookieProfile(ConfigFile &config) +{ +#ifdef BROWSER_AVAILABLE + if (cef) { + OBSBasic *main = OBSBasic::Get(); + const char *cookie_id = config_get_string(main->Config(), + "Panels", "CookieId"); + + std::string src_path; + src_path += "obs_profile_cookies/"; + src_path += cookie_id; + + std::string new_id = GenId(); + + std::string dst_path; + dst_path += "obs_profile_cookies/"; + dst_path += new_id; + + BPtr src_path_full = cef->get_cookie_path(src_path); + BPtr dst_path_full = cef->get_cookie_path(dst_path); + + QDir srcDir(src_path_full.Get()); + QDir dstDir(dst_path_full.Get()); + + if (srcDir.exists()) { + if (!dstDir.exists()) + dstDir.mkdir(dst_path_full.Get()); + + QStringList files = srcDir.entryList(QDir::Files); + for (const QString &file : files) { + QString src = QString(src_path_full); + QString dst = QString(dst_path_full); + src += QDir::separator() + file; + dst += QDir::separator() + file; + QFile::copy(src, dst); + } + } + + config_set_string(config, "Panels", "CookieId", new_id.c_str()); + } +#else + UNUSED_PARAMETER(config); +#endif +} diff --git a/UI/window-basic-main-profiles.cpp b/UI/window-basic-main-profiles.cpp index 82f66d75e..f70e7b46e 100644 --- a/UI/window-basic-main-profiles.cpp +++ b/UI/window-basic-main-profiles.cpp @@ -25,6 +25,10 @@ #include "window-namedialog.hpp" #include "qt-wrappers.hpp" +extern void DestroyPanelCookieManager(); +extern void DuplicateCurrentCookieProfile(ConfigFile &config); +extern void CheckExistingCookieId(); + void EnumProfiles(std::function &&cb) { char path[512]; @@ -182,7 +186,7 @@ static bool CopyProfile(const char *fromPartial, const char *to) } bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, - const char *init_text) + const char *init_text, bool rename) { std::string newName; std::string newDir; @@ -228,6 +232,12 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir.c_str()); + if (create_new) { + DestroyPanelCookieManager(); + } else if (!rename) { + DuplicateCurrentCookieProfile(config); + } + config_set_string(config, "General", "Name", newName.c_str()); config.SaveSafe("tmp"); config.Swap(basicConfig); @@ -380,7 +390,7 @@ void OBSBasic::on_actionRenameProfile_triggered() /* Duplicate and delete in case there are any issues in the process */ bool success = AddProfile(false, Str("RenameProfile.Title"), - Str("AddProfile.Text"), curName.c_str()); + Str("AddProfile.Text"), curName.c_str(), true); if (success) { DeleteProfile(curName.c_str(), curDir.c_str()); RefreshProfiles(); @@ -446,6 +456,8 @@ void OBSBasic::on_actionRemoveProfile_triggered() config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir); + DestroyPanelCookieManager(); + config.Swap(basicConfig); InitBasicConfigDefaults(); ResetProfileData(); @@ -603,6 +615,8 @@ void OBSBasic::ChangeProfile() config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir); + DestroyPanelCookieManager(); + config.Swap(basicConfig); InitBasicConfigDefaults(); ResetProfileData(); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index b2b86542d..d2f106846 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -79,7 +79,12 @@ using namespace std; #endif struct QCef; -QCef *cef = nullptr; +struct QCefCookieManager; + +QCef *cef = nullptr; +QCefCookieManager *panel_cookies = nullptr; + +void DestroyPanelCookieManager(); namespace { @@ -1097,6 +1102,8 @@ static const double scaled_vals[] = 0.0 }; +extern void CheckExistingCookieId(); + bool OBSBasic::InitBasicConfigDefaults() { QList screens = QGuiApplication::screens(); @@ -1302,6 +1309,8 @@ bool OBSBasic::InitBasicConfigDefaults() VOLUME_METER_DECAY_FAST); config_set_default_uint (basicConfig, "Audio", "PeakMeterType", 0); + CheckExistingCookieId(); + return true; } @@ -2247,6 +2256,7 @@ OBSBasic::~OBSBasic() #endif #ifdef BROWSER_AVAILABLE + DestroyPanelCookieManager(); delete cef; cef = nullptr; #endif diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 652877a27..b4b03d998 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -301,7 +301,7 @@ private: void LoadProfile(); void ResetProfileData(); bool AddProfile(bool create_new, const char *title, const char *text, - const char *init_text = nullptr); + const char *init_text = nullptr, bool rename = false); void DeleteProfile(const char *profile_name, const char *profile_dir); void RefreshProfiles(); void ChangeProfile();