From ef362808947d88d9892778b87a19af3af895c755 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Sun, 23 Apr 2023 19:13:49 +0200 Subject: [PATCH] rune manager preperations --- include/config.h | 11 + include/mainwindow.h | 7 +- include/runemanager.h | 29 +++ include/runepage.h | 5 + include/runepagelist.h | 37 +++ lolautoaccept.pro | 7 +- src/config.cpp | 31 ++- src/main.cpp | 2 +- src/mainwindow.cpp | 6 - src/runemanager.cpp | 68 ++++++ src/runepage.cpp | 37 +++ src/runepagelist.cpp | 48 ++++ ui/mainwindow.ui | 513 ++++++++++++++++++++--------------------- ui/runemanager.ui | 110 +++++++++ ui/runepagelist.ui | 16 ++ 15 files changed, 658 insertions(+), 269 deletions(-) create mode 100644 include/runemanager.h create mode 100644 include/runepagelist.h create mode 100644 src/runemanager.cpp create mode 100644 src/runepagelist.cpp create mode 100644 ui/runemanager.ui create mode 100644 ui/runepagelist.ui diff --git a/include/config.h b/include/config.h index 5bf9628..3a9bbdd 100644 --- a/include/config.h +++ b/include/config.h @@ -4,6 +4,7 @@ #include #include "position.h" +#include "runepage.h" class Config { public: @@ -27,6 +28,15 @@ public: StageConfig pick; }; + struct RunePageConfig { + RunePageConfig(); + RunePageConfig(const QJsonObject&); + operator QJsonObject() const; + + QString name; + RunePage runepage; + }; + struct RootConfig { RootConfig(); RootConfig(const QJsonObject&); @@ -35,6 +45,7 @@ public: std::shared_ptr getPositionConfig(Position position); std::vector> positionConfigs; + std::vector<::RunePage*> runePages; bool enabledAutoAccept; bool enabledSmiteWarn; diff --git a/include/mainwindow.h b/include/mainwindow.h index d712a50..b351654 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -25,6 +25,9 @@ public: protected: virtual void closeEvent(QCloseEvent* event) override; +signals: + void requestTabChange(int tabindex); + public slots: void resetSaveTimer(); @@ -41,14 +44,12 @@ private slots: void saveConfig(); void initDone(); -signals: - void requestTabChange(int tabindex); -private: // returns empty string on no match void onPosChange(Position newpos); // to trigger the signal from a QObject void lolaaStatusChanged(LolAutoAccept::Status); // get triggerd, when the autoacceptor fails (lost connection) +private: bool loading; Ui::MainWindow *ui; QTimer* saveTimer; diff --git a/include/runemanager.h b/include/runemanager.h new file mode 100644 index 0000000..08233f8 --- /dev/null +++ b/include/runemanager.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include + +namespace Ui { + class RuneManager; +} + +class ClientAPI; +class QListWidgetItem; + +class RuneManager : public QWidget { + Q_OBJECT + +public: + explicit RuneManager(QWidget* parent = nullptr); + ~RuneManager(); + +private slots: + void loadRunes(); + void setRunesEnabled(bool enabled); + + void clientRunePageRenamed(QListWidgetItem* item); +private: + Ui::RuneManager* ui; + std::shared_ptr client; +}; diff --git a/include/runepage.h b/include/runepage.h index b678cb8..e3af151 100644 --- a/include/runepage.h +++ b/include/runepage.h @@ -4,6 +4,7 @@ #include #include +#include // represents a runepage struct RunePage { public: @@ -11,9 +12,13 @@ public: uint32_t secondaryStyle = 0; std::vector selectedAspects; // all selected aspekts (should be exactly 9) + RunePage(); bool operator==(const RunePage& rp) const; operator bool() const; // check if this runepage is valid (this does not check semantic validity, only if the values are set as they supposed to be) + + operator QJsonObject() const; + RunePage(const QJsonObject& obj); }; std::ostream& operator<<(std::ostream&, const RunePage&); diff --git a/include/runepagelist.h b/include/runepagelist.h new file mode 100644 index 0000000..d53f346 --- /dev/null +++ b/include/runepagelist.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include + +#include "clientapi.h" + +namespace Ui { + class RunePageList; +} + +class DropEvent; + +class RunePageList : public QListWidget { + Q_OBJECT + +public: + static const uint32_t RoleId = Qt::UserRole; + static const uint32_t RolePointer = Qt::UserRole + 1; + + explicit RunePageList(QWidget* parent = nullptr); + ~RunePageList(); + + constexpr void setClient(bool b) { isClient = b; } + constexpr void setOther(QListWidget* other) { this->other = other; } + + void loadRunePages(const std::vector& pages); + +protected: + virtual void dropEvent(QDropEvent* event) override; + +private: + Ui::RunePageList* ui; + QListWidget* other = nullptr; + bool isClient; +}; diff --git a/lolautoaccept.pro b/lolautoaccept.pro index b107b78..7ccd57e 100644 --- a/lolautoaccept.pro +++ b/lolautoaccept.pro @@ -54,7 +54,9 @@ SOURCES += \ src/memoryimagecache.cpp \ src/restclient.cpp \ src/runedisplay.cpp \ + src/runemanager.cpp \ src/runepage.cpp \ + src/runepagelist.cpp \ src/settingstab.cpp \ src/stagesettings.cpp \ thirdparty/Log/Log.cpp @@ -82,7 +84,9 @@ HEADERS += \ include/memoryimagecache.h \ include/restclient.h \ include/runedisplay.h \ + include/runemanager.h \ include/runepage.h \ + include/runepagelist.h \ include/settingstab.h \ include/stagesettings.h \ thirdparty/Log/Log.h @@ -91,6 +95,8 @@ FORMS += \ ui/championsearch.ui \ ui/mainwindow.ui \ ui/runedisplay.ui \ + ui/runemanager.ui \ + ui/runepagelist.ui \ ui/settingstab.ui \ ui/stagesettings.ui @@ -116,7 +122,6 @@ unix { appimg.depends = linuxdeploy-x86_64.AppImage $${TARGET} resources/lolautoaccept.png appimg.commands = rm -rf AppDir ; \ mkdir -p AppDir/ts ; \ - cp ./resources/ts/*.qm ./AppDir/ts ; \ ./linuxdeploy-x86_64.AppImage --appdir=AppDir -e lolautoaccept -i resources/lolautoaccept.png -d resources/lolautoaccept.desktop --output appimage QMAKE_EXTRA_TARGETS += appimg linuxdeploy-x86_64.AppImage resources/lolautoaccept.png diff --git a/src/config.cpp b/src/config.cpp index 22918c5..dd4dc56 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -19,7 +19,7 @@ Config::StageConfig::StageConfig() : enabled(false) {} Config::StageConfig::StageConfig(const QJsonObject& j) { if(j["champ"].isString()) { - champs.push_back(getValue(j, "champ", "")); + champs.push_back(getValue(j, "champ")); } if(j["champs"].isArray()) { QJsonArray jchamps = j["champs"].toArray(); @@ -71,9 +71,35 @@ Config::PositionConfig::operator QJsonObject() const { return out; } +Config::RunePageConfig::RunePageConfig() {} +Config::RunePageConfig::RunePageConfig(const QJsonObject& j) { + name = getValue(j, "name"); + runepage = getValue<::RunePage>(j, "runepage"); +} +Config::RunePageConfig::operator QJsonObject() const { + QJsonObject out; + + out["name"] = name; + out["runepage"] = static_cast(runepage); + + return out; +} + Config::RootConfig::RootConfig() {} Config::RootConfig::RootConfig(const QJsonObject& j) { + if(j.contains("version")) { + int version = j["version"].toInt(); + if(version > 1) { + // error + qCritical() << "config version is not known: " << version << " using the config might corrupt it."; + + // TODO: make backup of config or something + } + + // add migrations here if required + } + auto jposref = j["positions"]; if(jposref.isArray()) { QJsonArray jpos = jposref.toArray(); @@ -105,6 +131,7 @@ Config::RootConfig::operator QJsonObject() const { out.insert("enabledSmiteWarn", enabledSmiteWarn); out.insert("enabledAutoWrite", enabledAutoWrite); out.insert("autoWriteText", QString::fromStdString(autoWriteText)); + out.insert("version", 1); return out; } @@ -146,7 +173,9 @@ bool Config::load() { return false; } if(doc.isObject()) { + // implicit cast root = doc.object(); + Log::info << "config loaded"; return true; } diff --git a/src/main.cpp b/src/main.cpp index 100f8ff..eb4e082 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,7 +30,7 @@ int main(int argc, char** argv) { } qInfo() << "Hello, World!"; - qInfo() << "Using Locale: " << QLocale().name().toStdString(); + qInfo() << "Using Locale: " << QLocale().name(); QApplication app(argc, argv); QTranslator translator; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 82b1085..cc7ff2a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -8,7 +8,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), loading(true), ui(new Ui::MainWindow), saveTimer(new QTimer(this)), dd(QLocale().name().toStdString()), lolaa(conf.getConfig(), dd) { ui->setupUi(this); - this->ui->runesPage->setLolAA(&lolaa); QObject::connect(&lolaa, &LolAutoAccept::statusChanged, this, &MainWindow::lolaaStatusChanged); QObject::connect(&lolaa, &LolAutoAccept::positionChanged, this, &MainWindow::onPosChange); @@ -19,8 +18,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), loading(true), ui ui->copyrightlabel->setText(ui->copyrightlabel->text().arg(LOLAA_VERSION)); - lolaa.setOnRuneChangeFunc(std::bind(&RuneDisplay::setRunes, ui->runedisplay, std::placeholders::_1)); - conf.load(); // for all tabs - set their config and datadragon @@ -89,9 +86,6 @@ void MainWindow::toggleMainswitch(bool state) { return; } - ui->runedisplay->setRuneMeta(lolaa.getRuneAspekts()); - ui->runedisplay->setStyles(lolaa.getRuneStyles()); - lolaa.run(); } else { lolaa.stop(); diff --git a/src/runemanager.cpp b/src/runemanager.cpp new file mode 100644 index 0000000..0c53e71 --- /dev/null +++ b/src/runemanager.cpp @@ -0,0 +1,68 @@ +#include "runemanager.h" +#include "ui_runemanager.h" + +#include +#include + +#include "clientapi.h" + +RuneManager::RuneManager(QWidget* parent) : QWidget(parent), ui(new Ui::RuneManager) { + ui->setupUi(this); + + ui->listClientRunes->setClient(true); + ui->listaaRunes->setClient(false); + ui->listClientRunes->setOther(ui->listaaRunes); + ui->listaaRunes->setOther(ui->listClientRunes); + + loadRunes(); +} + +RuneManager::~RuneManager() { + delete this->ui; +} + +void RuneManager::loadRunes() { + if(!client) { + auto ca = ClientAccess::find(); + + if(ca) { + client = std::make_shared(*ca.get()); + } + } + + if(client) { + // load runepages + const std::vector runePages = client->getAllRunePages(); + ui->listClientRunes->loadRunePages(runePages); + } + + setRunesEnabled(!!client); // cast to bool +} + + +void RuneManager::setRunesEnabled(bool enabled) { + this->ui->lblClientRunes->setEnabled(enabled); + this->ui->lblaaRunes->setEnabled(enabled); + this->ui->listClientRunes->setEnabled(enabled); + this->ui->listaaRunes->setEnabled(enabled); + this->ui->btnDelete->setEnabled(enabled); + + this->ui->btnRetry->setEnabled(!enabled); +} + +void RuneManager::clientRunePageRenamed(QListWidgetItem* item) { + uint32_t pageId = item->data(RunePageList::RoleId).toUInt(); + const ::RunePage* page = (::RunePage*) item->data(RunePageList::RolePointer).toULongLong(); + qDebug() << "edit page: " << pageId << "setname:" << item->text(); + + if(client) { + ClientAPI::RunePage newPage; + newPage.id = pageId; + newPage.name = item->text().toStdString(); + newPage.runepage = *page; + + if(!client->editRunePage(newPage)) { + // TODO: some error occured + } + } +} diff --git a/src/runepage.cpp b/src/runepage.cpp index 20eb416..56d22ab 100644 --- a/src/runepage.cpp +++ b/src/runepage.cpp @@ -1,7 +1,13 @@ #include "runepage.h" +#include + #include +#include "json.h" + +RunePage::RunePage() {} + bool RunePage::operator==(const RunePage& rp) const { if(primaryStyle == rp.primaryStyle && secondaryStyle == rp.secondaryStyle && selectedAspects.size() == rp.selectedAspects.size()) { return std::is_permutation(selectedAspects.begin(), selectedAspects.end(), rp.selectedAspects.begin()); @@ -13,6 +19,37 @@ RunePage::operator bool() const { return primaryStyle != 0 && secondaryStyle != 0 && selectedAspects.size() == 9; } +RunePage::operator QJsonObject() const { + QJsonObject obj; + + obj.insert("primary", (int) primaryStyle); + obj.insert("secondary", (int) secondaryStyle); + + QJsonArray aspects; + for(uint32_t aspect : selectedAspects) { + aspects.push_back((int) aspect); + } + obj.insert("aspects", aspects); + + return obj; +} + +RunePage::RunePage(const QJsonObject& obj) : + primaryStyle(getValue(obj, "primary", 0)), + secondaryStyle(getValue(obj, "secondary", 0)) +{ + if(obj.contains("aspects") && obj["aspects"].isArray() && obj["aspects"].toArray().size() == 9) { + selectedAspects.clear(); + selectedAspects.reserve(9); + QJsonArray arr = obj["aspects"].toArray(); + for(QJsonValueRef aspect : arr) { + if(aspect.isDouble()) { + selectedAspects.push_back(aspect.toDouble()); + } + } + } +} + std::ostream& operator<<(std::ostream& str, const RunePage& rp) { return str << "Primary: " << rp.primaryStyle << " Secondary: " << rp.secondaryStyle << " aspects: " << rp.selectedAspects.size(); } diff --git a/src/runepagelist.cpp b/src/runepagelist.cpp new file mode 100644 index 0000000..697db94 --- /dev/null +++ b/src/runepagelist.cpp @@ -0,0 +1,48 @@ +#include "runepagelist.h" +#include "ui_runepagelist.h" + +#include +#include +#include + +RunePageList::RunePageList(QWidget* parent) : QListWidget(parent), ui(new Ui::RunePageList) { + ui->setupUi(this); +} + +RunePageList::~RunePageList() { + delete this->ui; +} + +void RunePageList::loadRunePages(const std::vector& pages) { + clear(); + for(const ClientAPI::RunePage& rp : pages) { + QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(rp.name)); + item->setData(RoleId, (uint) rp.id); + item->setData(RolePointer, (qulonglong) new ::RunePage(rp.runepage)); + item->setToolTip(QString("id: %0").arg(rp.id)); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addItem(item); + if(rp.isCurrent) { + item->setSelected(true); + } + } +} + +void RunePageList::dropEvent(QDropEvent* event) { + qDebug() << "drop event"; + if(event->source() == nullptr || event->source() != other) { + event->ignore(); + return; + } + + auto selected = other->selectedItems(); + if(selected.size() != 1) { + event->ignore(); + return; + } + qDebug() << "data: " << selected.at(0)->data(RoleId); + + // compare rune pages for duplicates? + + QListWidget::dropEvent(event); +} diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 813a667..aa4b32d 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -20,237 +20,254 @@ LoL-Auto-Accept - - - 0 - 0 - - - - - - 0 - 0 - 575 - 809 - + + + QLayout::SetDefaultConstraint - - - QLayout::SetDefaultConstraint - - - 6 - - - 6 - - - 6 - - - 6 - - - 9 - - - - - Spam "smite" in the chat when there is not exactly 1 player with smite equiped in champ select - - - Enable Smite Warning - - - true - - - - - - - QTabWidget::North - - - QTabWidget::Rounded - - - 4 - - - Qt::ElideNone - - - false - - - false - - - - This Tab is used, when you are in a gamemode with no fixed roles + + + + + 0 + 0 + + + + 0 + + + + Auto Accept + + + + QLayout::SetDefaultConstraint - - 0 + + 6 - - Default - - - - - 1 + + 6 - - - :/icons/top.svg:/icons/top.svg - - - Top - - - - - 2 + + 6 - - - :/icons/jgl.svg:/icons/jgl.svg - - - Jungle - - - - - 3 + + 6 - - - :/icons/mid.svg:/icons/mid.svg - - - Middle - - - - - 4 + + 9 - - - :/icons/bot.svg:/icons/bot.svg - - - Bottom - - - - - 5 - - - - :/icons/sup.svg:/icons/sup.svg - - - Support - - + + + + Write a Text as soon as you are in a champ select lobby. + + + Auto Write + + + + + + + Qt::NoContextMenu + + + <html><head/><body><p>Developed by + MrBesen</p><p><a + href="https://git.mrbesen.de/MrBesen/lolautoaccept/releases"><span + style=" text-decoration: underline; + color:#007af4;">Webseite</span></a></p><p>Version: + %1</p></body></html> + + + Qt::RichText + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + true + + + Qt::TextBrowserInteraction + + + + + + + This controls the connection to the LoL client. As long as this is off, no interactions with the LoL client take place. + + + Mainswitch + + + + + + + Spam "smite" in the chat when there is not exactly 1 player with smite equiped in champ select + + + Enable Smite Warning + + + true + + + + + + + Enable LoL-Auto-Accept + + + + + + + + 0 + 0 + + + + + 16777215 + 80 + + + + + 0 + 0 + + + + Qt::WheelFocus + + + QFrame::Sunken + + + QTextEdit::NoWrap + + + false + + + Qt::NoTextInteraction + + + autowriteText + + + + + + + QTabWidget::North + + + QTabWidget::Rounded + + + 4 + + + Qt::ElideNone + + + false + + + false + + + + This Tab is used, when you are in a gamemode with no fixed roles + + + 0 + + + Default + + + + + 1 + + + + :/icons/top.svg:/icons/top.svg + + + Top + + + + + 2 + + + + :/icons/jgl.svg:/icons/jgl.svg + + + Jungle + + + + + 3 + + + + :/icons/mid.svg:/icons/mid.svg + + + Middle + + + + + 4 + + + + :/icons/bot.svg:/icons/bot.svg + + + Bottom + + + + + 5 + + + + :/icons/sup.svg:/icons/sup.svg + + + Support + + + + + - - - - - - 0 - 0 - - - - - 16777215 - 80 - - - - - 0 - 0 - - - - Qt::WheelFocus - - - QFrame::Sunken - - - QTextEdit::NoWrap - - - false - - - Qt::LinksAccessibleByMouse|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - autowriteText - + + + Runes + - - - - - Write a Text as soon as you are in a champ select lobby. - - - Auto Write - - - - - - - Enable LoL-Auto-Accept - - - - - - - Mainswitch - - - - - - - Qt::NoContextMenu - - - <html><head/><body><p>Developed by MrBesen</p><p><a href="https://git.mrbesen.de/MrBesen/lolautoaccept/releases"><span style=" text-decoration: underline; color:#007af4;">Webseite</span></a></p><p>Version: %1</p></body></html> - - - Qt::RichText - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - true - - - Qt::TextBrowserInteraction - - - - - - - - + + + @@ -272,16 +289,14 @@ 1 - RuneDisplay + RuneManager QWidget -
runedisplay.h
+
runemanager.h
1 - - applyRunes() -
+ centralTabWidget mainswitch enableAll enableSmiteWarning @@ -300,8 +315,8 @@ aatoggled(bool) - 25 - 88 + 36 + 128 393 @@ -316,8 +331,8 @@ toggleMainswitch(bool) - 88 - 38 + 99 + 94 1 @@ -341,22 +356,6 @@ - - runedisplay - applyRunes() - MainWindow - applyRunes() - - - 232 - 598 - - - 452 - 576 - - - enableSmiteWarning clicked(bool) @@ -364,8 +363,8 @@ smitewarntoggled(bool) - 191 - 111 + 202 + 162 201 @@ -380,8 +379,8 @@ autoWriteChanged() - 188 - 156 + 199 + 196 441 @@ -396,8 +395,8 @@ autoWriteChanged() - 315 - 169 + 326 + 285 347 @@ -412,12 +411,12 @@ setEnabled(bool) - 94 - 156 + 105 + 196 - 86 - 168 + 97 + 285 diff --git a/ui/runemanager.ui b/ui/runemanager.ui new file mode 100644 index 0000000..6743d38 --- /dev/null +++ b/ui/runemanager.ui @@ -0,0 +1,110 @@ + + + RuneManager + + + + 0 + 0 + 498 + 654 + + + + + + + true + + + QAbstractItemView::DragDrop + + + + + + + Runes in the Client + + + + + + + Delete + + + + + + + Runes in the Autoacceptor + + + + + + + true + + + QAbstractItemView::DragDrop + + + + + + + Retry + + + + + + + + RunePageList + QListWidget +
runepagelist.h
+
+
+ + + + btnRetry + clicked() + RuneManager + loadRunes() + + + 223 + 28 + + + 544 + 55 + + + + + listClientRunes + itemChanged(QListWidgetItem*) + RuneManager + clientRunePageRenamed(QListWidgetItem*) + + + 266 + 229 + + + 644 + 240 + + + + + + loadRunes() + clientRunePageRenamed(QListWidgetItem*) + +
diff --git a/ui/runepagelist.ui b/ui/runepagelist.ui new file mode 100644 index 0000000..71832e9 --- /dev/null +++ b/ui/runepagelist.ui @@ -0,0 +1,16 @@ + + + RunePageList + + + + 0 + 0 + 400 + 300 + + + + + +