From 94d2869c512e34da23d1ce4937a26e1f0da88a51 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Mon, 4 Jul 2022 22:59:48 +0200 Subject: [PATCH] multiple tabs working --- include/datadragon.h | 4 +- include/lolautoaccept.h | 20 ++++++-- include/mainwindow.h | 9 ++-- src/datadragon.cpp | 12 +++++ src/lolautoaccept.cpp | 110 +++++++++++++++++++++++++++------------- src/main.cpp | 4 +- src/mainwindow.cpp | 28 +++++----- ui/mainwindow.ui | 17 +++++++ 8 files changed, 144 insertions(+), 60 deletions(-) diff --git a/include/datadragon.h b/include/datadragon.h index 0b01504..69321c6 100644 --- a/include/datadragon.h +++ b/include/datadragon.h @@ -29,7 +29,7 @@ public: std::string name; std::string id; - int key; + int key = 0; std::string partype; std::string title; }; @@ -51,6 +51,8 @@ public: const ChampData& getBestMatchingChamp(const std::string& name, int* count = nullptr); std::vector getMatchingChamp(const std::string& name, uint32_t limit = 25); + std::vector resolveChampIDs(const std::vector& champnames); + static const ChampData EMPTYCHAMP; protected: std::string getImageUrl(const std::string& champid, ImageType type); diff --git a/include/lolautoaccept.h b/include/lolautoaccept.h index df288fe..b794a01 100644 --- a/include/lolautoaccept.h +++ b/include/lolautoaccept.h @@ -5,8 +5,12 @@ #include #include "clientapi.h" +#include "config.h" +#include "datadragon.h" class LolAutoAccept { +public: + using onposchange_func = std::function; protected: struct Stage { Stage(); @@ -18,15 +22,18 @@ protected: }; std::mutex stagesMutex; // protects stagesvector - std::vector stages; + std::vector stages; + Position currentPosition = Position::INVALID; + + Config::RootConfig& config; + DataDragon& dd; + onposchange_func onPoschange; bool shouldrun = false; std::thread lolaathread; std::shared_ptr clientapi; - int64_t summonerid = -1; - public: enum class State { LOBBY = 0, @@ -34,7 +41,7 @@ public: PICK = 2, }; - LolAutoAccept(); + LolAutoAccept(Config::RootConfig& config, DataDragon& dd, onposchange_func = {}); ~LolAutoAccept(); void setChamps(const std::vector& champs, State s); @@ -44,15 +51,20 @@ public: void run(); void stop(); + void reload(); // reload the config, when something was changed + private: void stopJoinThread(); void innerRun(); void resetAllOffsets(); + void applyConfigToStage(Stage& stage, const Config::StageConfig& stageconf); + void loadPosition(Position pos); uint32_t getChampOfState(State s); void nextChampOfState(State s); static bool isChampIntentofTeammate(uint32_t champid, const ClientAPI::ChampSelectSession& session); + static bool isChampBanned(uint32_t champid, const ClientAPI::ChampSelectSession& session); using ownactions_t = std::vector; ownactions_t getOwnActions(int32_t cellid, const std::vector actions); diff --git a/include/mainwindow.h b/include/mainwindow.h index 57afc16..d57e39b 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -16,7 +16,7 @@ class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(LolAutoAccept& lolaa, QWidget *parent = nullptr); + MainWindow(QWidget *parent = nullptr); ~MainWindow(); protected: @@ -30,15 +30,18 @@ private slots: void tabtoggled(Position, LolAutoAccept::State, bool); void tabchanged(Position, LolAutoAccept::State); +signals: + void requestTabChange(int tabindex); + private: // returns empty string on no match - const DataDragon::ChampData& getBestMatchingChamp(const std::string& name); + void onPosChange(Position newpos); // to trigger the signal from a QObject Ui::MainWindow *ui; - LolAutoAccept& lolaa; std::thread lolaathread; DataDragon dd; Config conf; + LolAutoAccept lolaa; }; #endif // MAINWINDOW_H diff --git a/src/datadragon.cpp b/src/datadragon.cpp index 36c1f5a..040b6b9 100644 --- a/src/datadragon.cpp +++ b/src/datadragon.cpp @@ -192,6 +192,18 @@ std::vector DataDragon::getMatchingChamp(const std return out; } +std::vector DataDragon::resolveChampIDs(const std::vector& champnames) { + std::vector out; + out.reserve(champnames.size()); + + std::transform(champnames.begin(), champnames.end(), std::insert_iterator(out, out.begin()), [this](const std::string& champname) { + auto cd = getBestMatchingChamp(champname); + return cd.key; // might be 0 (invalid) + }); + + return out; +} + std::string DataDragon::getImageUrl(const std::string& champid, ImageType type) { switch(type) { case ImageType::SQUARE: { diff --git a/src/lolautoaccept.cpp b/src/lolautoaccept.cpp index 317c990..3261e4f 100644 --- a/src/lolautoaccept.cpp +++ b/src/lolautoaccept.cpp @@ -1,27 +1,19 @@ #include "lolautoaccept.h" +#include #include #include - LolAutoAccept::Stage::Stage() {} LolAutoAccept::Stage::~Stage() {} -LolAutoAccept::LolAutoAccept() { +LolAutoAccept::LolAutoAccept(Config::RootConfig& config, DataDragon& dd, onposchange_func onposch) : config(config), dd(dd), onPoschange(onposch) { std::lock_guard lock(stagesMutex); - stages.reserve(3); - stages.push_back(new Stage()); // accept - stages.push_back(new Stage()); // ban - stages.push_back(new Stage()); // pick + stages.resize(3); // accept, ban, pick } LolAutoAccept::~LolAutoAccept() { stopJoinThread(); - - std::lock_guard lock(stagesMutex); - for(auto s : stages) { - delete s; - } } void LolAutoAccept::setChamps(const std::vector& champs, State s) { @@ -31,8 +23,8 @@ void LolAutoAccept::setChamps(const std::vector& champs, State s) { } { std::lock_guard lock(stagesMutex); - stages.at((int) s)->champids = champs; - stages.at((int) s)->currentOffset = 0; + stages.at((int) s).champids = champs; + stages.at((int) s).currentOffset = 0; } Log::info << "set champs on state: " << (int) s << " count: " << champs.size(); } @@ -44,7 +36,7 @@ void LolAutoAccept::setEnabled(bool b, State s) { } std::lock_guard lock(stagesMutex); - stages.at((int) s)->enabled = b; + stages.at((int) s).enabled = b; } bool LolAutoAccept::init() { @@ -54,7 +46,6 @@ bool LolAutoAccept::init() { if(ca) { clientapi = std::make_shared(*ca.get()); auto selfinfo = clientapi->getSelf(); - summonerid = selfinfo.summonerid; Log::info << "selfinfo: gameName: " << selfinfo.gameName << " name: " << selfinfo.name << " summonerid: " << selfinfo.summonerid << " statusMessage: " << selfinfo.statusMessage << " puuid: " << selfinfo.puuid << " level: " << selfinfo.level; } @@ -74,6 +65,11 @@ void LolAutoAccept::stop() { shouldrun = false; } +void LolAutoAccept::reload() { + Log::note << "reload LolAutoAccept"; + loadPosition(currentPosition); +} + void LolAutoAccept::stopJoinThread() { stop(); @@ -94,8 +90,10 @@ void LolAutoAccept::innerRun() { Log::info << "current Gameflowphase: " << phase; // do processing - if(phase == ClientAPI::GameflowPhase::READYCHECK) { - if(stages.at(0)->enabled) { // auto accept enabled + if(phase == ClientAPI::GameflowPhase::MATCHMAKING) { + extrasleep = 200; + } else if(phase == ClientAPI::GameflowPhase::READYCHECK) { + if(stages.at(0).enabled) { // auto accept enabled auto state = clientapi->getReadyCheckState(); Log::info << "readychack state: " << state; @@ -118,53 +116,76 @@ void LolAutoAccept::innerRun() { } else if(phase == ClientAPI::GameflowPhase::WAITINGFORSTATS) { extrasleep = 4000; // 4 s bonus sleep } else if(phase == ClientAPI::GameflowPhase::NONE) { - extrasleep = 30000; // 30 s bonus sleep - no lobby + extrasleep = 10000; // 10 s bonus sleep - no lobby } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration dur = (end-start); //if(dur.count() > 1e-5) - Log::note << "iteration took: " << (dur.count() * 1000) << " ms"; + Log::note << "iteration took: " << (dur.count() * 1000) << " ms extrasleep: " << extrasleep; std::this_thread::sleep_for(std::chrono::milliseconds(400 + extrasleep)); } } void LolAutoAccept::resetAllOffsets() { - for(Stage* stage : stages) { - stage->currentOffset = 0; + for(Stage& stage : stages) { + stage.currentOffset = 0; } + currentPosition = Position::INVALID; +} + +void LolAutoAccept::applyConfigToStage(Stage& stage, const Config::StageConfig& stageconf) { + stage.champids = dd.resolveChampIDs(stageconf.champs); + stage.enabled = stage.enabled; + stage.currentOffset = 0; +} + +void LolAutoAccept::loadPosition(Position pos) { + Log::trace << __PRETTY_FUNCTION__ << " pos: " << pos; + + // reinit the stages + std::lock_guard lock(stagesMutex); + stages.resize(1); // first stage does not change + stages.resize(3); + + const Config::PositionConfig& posconf = config.getPositionConfig(pos); + + applyConfigToStage(stages.at((int) State::BAN), posconf.ban); + applyConfigToStage(stages.at((int) State::PICK), posconf.pick); + + currentPosition = pos; } uint32_t LolAutoAccept::getChampOfState(State s) { assert(((int) s) >= 0 && s <= State::PICK); - auto stage = stages[(int) s]; - uint32_t size = stage->champids.size(); - if(stage->currentOffset >= size) { + Stage& stage = stages[(int) s]; + uint32_t size = stage.champids.size(); + if(stage.currentOffset >= size) { // no champ to try left Log::warn << "no champ left at stage: " << (int) s; - Log::warn << "stage size: " << stage->champids.size(); + Log::warn << "stage size: " << stage.champids.size(); return 0; } - return stage->champids[stage->currentOffset]; + return stage.champids[stage.currentOffset]; } void LolAutoAccept::nextChampOfState(State s) { - assert(((int) s) >= 0 && s <= State::PICK); + assert(s > State::LOBBY && s <= State::PICK); auto stage = stages[(int) s]; - uint32_t size = stage->champids.size(); + uint32_t size = stage.champids.size(); - stage->currentOffset++; + stage.currentOffset++; - if(stage->currentOffset >= size) { + if(stage.currentOffset >= size) { // no champ to try left Log::warn << "no champ left at stage: " << (int) s; - Log::warn << "stage size: " << stage->champids.size(); + Log::warn << "stage size: " << stage.champids.size(); - stage->currentOffset = 0; + stage.currentOffset = 0; return; } } @@ -179,6 +200,15 @@ bool LolAutoAccept::isChampIntentofTeammate(uint32_t champid, const ClientAPI::C return false; } +bool LolAutoAccept::isChampBanned(uint32_t champid, const ClientAPI::ChampSelectSession& session) { + for(const ClientAPI::ChampSelectAction& act : session.actions) { + if(act.type == ClientAPI::ChampSelectActionType::BAN && act.championID == (int32_t) champid && act.completed) { + return true; + } + } + return false; +} + LolAutoAccept::ownactions_t LolAutoAccept::getOwnActions(int32_t cellid, const std::vector actions) { ownactions_t out; for(const auto& it : actions) { @@ -198,7 +228,7 @@ void LolAutoAccept::prepickPhase(const ownactions_t& ownactions) { void LolAutoAccept::banPhase(const ownactions_t& ownactions, const ClientAPI::ChampSelectSession& session) { phase(ownactions, ClientAPI::ChampSelectActionType::BAN, State::BAN, true, [session](uint32_t champid) { - return !isChampIntentofTeammate(champid, session); + return !isChampIntentofTeammate(champid, session) && !isChampBanned(champid, session); }); } @@ -215,6 +245,7 @@ void LolAutoAccept::phase(const ownactions_t& ownactions, ClientAPI::ChampSelect if(filter) { // filter says no if(!filter(champid)) { + Log::trace << "champid: " << champid << " filter says no - next champ"; nextChampOfState(s); return; } @@ -247,9 +278,20 @@ void LolAutoAccept::champSelect() { } Position pos = me ? me->position : Position::INVALID; + if(pos == Position::INVALID) { + pos = Position::UTILITY; // default: support TODO: make the default changeable? extra tab? + } + + // reload config based on position if changed + if(pos != currentPosition) { + Log::note << "LolAutoAccept reloading config for position: " << pos << " because it was: " << currentPosition; + loadPosition(pos); + if(onPoschange) { + onPoschange(pos); + } + } Log::debug << "cellid: " << cellid << " position: " << pos << " counter: " << session.counter << " timer: timeleftip: " << session.timer.adjustedTimeLeftInPhase << " totaltimephase: " << session.timer.totalTimeInPhase; - // find actions for own cell auto ownactions = getOwnActions(cellid, session.actions); Log::debug << "ownactions: " << ownactions.size(); diff --git a/src/main.cpp b/src/main.cpp index cb96d61..d261190 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,6 @@ #include "arg.h" #include "mainwindow.h" -#include "lolautoaccept.h" #include "clientaccess.h" #include "clientapi.h" @@ -54,7 +53,6 @@ int main(int argc, char** argv) { std::string base = getBaseString(argv); Log::info << "appbase: " << base; - LolAutoAccept lolaa; QApplication app(argc, argv); QTranslator translator; if(translator.load(QLocale().name(), QString::fromStdString(base + "ts"))) { @@ -62,7 +60,7 @@ int main(int argc, char** argv) { } else { Log::warn << "translation not found"; } - MainWindow win(lolaa); + MainWindow win; QIcon icon(QString::fromStdString(base + "lolautoaccept.png")); win.setWindowIcon(icon); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f2d4888..70cc012 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3,7 +3,7 @@ #include -MainWindow::MainWindow(LolAutoAccept& lolaa, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), lolaa(lolaa), dd(QLocale().name().toStdString()) { +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), dd(QLocale().name().toStdString()), lolaa(conf.getConfig(), dd, std::bind(&MainWindow::onPosChange, this, std::placeholders::_1)) { ui->setupUi(this); conf.load(); @@ -67,26 +67,24 @@ void MainWindow::aatoggled(bool state) { conf.getConfig().enabledAutoAccept = state; } -static std::vector toChampionIDList(const std::vector& scs) { - std::vector out; - - for(const StageSettings::SelectedChamp& sc : scs) { - out.push_back(sc.id); - } - - return out; -} - void MainWindow::tabtoggled(Position p, LolAutoAccept::State s, bool state) { Log::info << "checkbox toggled " << state << " position: " << p << " state: " << (int) s; - lolaa.setEnabled(state, s); + if(s == LolAutoAccept::State::LOBBY) { + lolaa.setEnabled(state, s); + } + + lolaa.reload(); } void MainWindow::tabchanged(Position p, LolAutoAccept::State s) { Log::info << "edited position: " << p << " state: " << (int) s; - SettingsTab* tab = (SettingsTab*) ui->tabWidget->widget((int) p -1); - auto champs = tab->getChamps(s); - lolaa.setChamps(toChampionIDList(champs), s); + lolaa.reload(); +} + +void MainWindow::onPosChange(Position newpos) { + if(newpos != Position::INVALID) { + emit requestTabChange((int) newpos -1); + } } diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 9615d68..a159ec6 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -176,8 +176,25 @@ + + MainWindow + requestTabChange(int) + tabWidget + setCurrentIndex(int) + + + 417 + 86 + + + 407 + 145 + + + + requestTabChange(int) aatoggled(bool) tabtoggled(Position, LolAutoAccept::State, bool) tabchanged(Position, LolAutoAccept::State)