From d3379ab794a9367edaf2e6fc3a26746bc2013bf8 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Sat, 9 Jul 2022 01:01:51 +0200 Subject: [PATCH] wip blitzapi, load runes, set runes --- include/blitzapi.h | 27 ++++++++++ include/clientapi.h | 27 ++++++++++ include/json.h | 6 +++ include/lolautoaccept.h | 7 +++ include/mainwindow.h | 3 ++ include/restclient.h | 2 + include/runeaspekt.h | 18 +++++++ include/runedisplay.h | 30 +++++++++++ lolautoaccept.pro | 5 ++ src/blitzapi.cpp | 113 ++++++++++++++++++++++++++++++++++++++++ src/clientapi.cpp | 81 ++++++++++++++++++++++++++++ src/clientapi_json.cpp | 41 +++++++++++++++ src/json.cpp | 14 +++++ src/lolautoaccept.cpp | 16 ++++++ src/mainwindow.cpp | 14 +++++ src/restclient.cpp | 25 +++++---- src/runedisplay.cpp | 45 ++++++++++++++++ src/settingstab.cpp | 2 +- ui/mainwindow.ui | 22 ++++++-- ui/runedisplay.ui | 28 ++++++++++ 20 files changed, 513 insertions(+), 13 deletions(-) create mode 100644 include/blitzapi.h create mode 100644 include/runeaspekt.h create mode 100644 include/runedisplay.h create mode 100644 src/blitzapi.cpp create mode 100644 src/runedisplay.cpp create mode 100644 ui/runedisplay.ui diff --git a/include/blitzapi.h b/include/blitzapi.h new file mode 100644 index 0000000..9401242 --- /dev/null +++ b/include/blitzapi.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "restclient.h" +#include "position.h" + +class BlitzAPI : public RestClient { +public: + BlitzAPI(); + + struct ChampionInfo { + std::vector skillorder; + std::vector runes; + uint32_t primaryRune = 0; + + // items? + + ChampionInfo(); + explicit ChampionInfo(const QJsonObject&); + }; + + ChampionInfo getChampionInfo(uint32_t championID, Position p, uint32_t enemyChampionID = 0); // TODO: add more parameters: Queue (Ranked 5x5) +private: +}; + diff --git a/include/clientapi.h b/include/clientapi.h index 8c415a6..44e6ad0 100644 --- a/include/clientapi.h +++ b/include/clientapi.h @@ -3,6 +3,7 @@ #include "clientaccess.h" #include "restclient.h" #include "position.h" +#include "runeaspekt.h" class ClientAPI : public RestClient { public: @@ -128,6 +129,24 @@ public: operator bool(); }; + struct RunePage { + uint64_t id = 0; + uint64_t lastmodified = 0; + uint32_t primaryStyleID = 0; + uint32_t subStyleID = 0; + std::string name; + bool isDeleteable = true; + bool isEditable = true; + bool isActive = false; // what is the difference between active and current???? + bool isCurrent = false; + bool isValid = true; + uint32_t order = 0; // position in the ui + std::vector selectedPerkIDs; + + RunePage(); + explicit RunePage(const QJsonObject& json); + }; + ClientAPI(const ClientAccess& access); ~ClientAPI(); @@ -145,6 +164,14 @@ public: TimerInfo getTimerInfo(); + // rune stuff + RunePage getCurrentRunePage(); + std::vector getAllRunePages(); + bool selectRunePage(uint64_t id); + bool editRunePage(const RunePage& page); + + std::vector getAllRuneAspekts(); + protected: diff --git a/include/json.h b/include/json.h index b5553bd..544d1fd 100644 --- a/include/json.h +++ b/include/json.h @@ -12,9 +12,15 @@ T convert(const QJsonValue& val) { template<> int convert(const QJsonValue& val); +template<> +uint32_t convert(const QJsonValue& val); + template<> int64_t convert(const QJsonValue& val); +template<> +uint64_t convert(const QJsonValue& val); + template<> std::string convert(const QJsonValue& val); diff --git a/include/lolautoaccept.h b/include/lolautoaccept.h index b794a01..f7dbe50 100644 --- a/include/lolautoaccept.h +++ b/include/lolautoaccept.h @@ -4,6 +4,7 @@ #include #include +#include "blitzapi.h" #include "clientapi.h" #include "config.h" #include "datadragon.h" @@ -34,6 +35,9 @@ protected: std::shared_ptr clientapi; + BlitzAPI blitzapi; + std::vector runeaspekts; + public: enum class State { LOBBY = 0, @@ -53,6 +57,9 @@ public: void reload(); // reload the config, when something was changed + const std::vector& getRuneAspekts(); + void applyRunes(); + private: void stopJoinThread(); void innerRun(); diff --git a/include/mainwindow.h b/include/mainwindow.h index d57e39b..59c23e3 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -30,12 +30,15 @@ private slots: void tabtoggled(Position, LolAutoAccept::State, bool); void tabchanged(Position, LolAutoAccept::State); + void applyRunes(); + signals: void requestTabChange(int tabindex); private: // returns empty string on no match void onPosChange(Position newpos); // to trigger the signal from a QObject + void onRuneChanged(const std::vector& runes, uint32_t prim, uint32_t sec); Ui::MainWindow *ui; std::thread lolaathread; diff --git a/include/restclient.h b/include/restclient.h index 6312a82..16efc74 100644 --- a/include/restclient.h +++ b/include/restclient.h @@ -7,6 +7,7 @@ class RestClient { public: RestClient(const std::string& base); + RestClient(const RestClient&) = delete; virtual ~RestClient(); enum class Method { @@ -21,6 +22,7 @@ protected: QByteArray requestRaw(const std::string& url, Method m = Method::GET, const std::string& data = {}); QJsonDocument request(const std::string& url, Method m = Method::GET, const std::string& data = {}); void enableDebugging(bool enabled = true); + std::string escape(const std::string& in) const; std::string baseurl; diff --git a/include/runeaspekt.h b/include/runeaspekt.h new file mode 100644 index 0000000..8afb2a9 --- /dev/null +++ b/include/runeaspekt.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +class QJsonObject; + +struct RuneAspekt { + uint32_t id = 0; + std::string name; + std::string shortDesc; + std::string longDesc; + std::string tooltip; + std::string iconPath; + + RuneAspekt(); + explicit RuneAspekt(const QJsonObject& json); +}; diff --git a/include/runedisplay.h b/include/runedisplay.h new file mode 100644 index 0000000..a879cfe --- /dev/null +++ b/include/runedisplay.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "runeaspekt.h" + +namespace Ui { + class RuneDisplay; +} + +class RuneDisplay : public QWidget { + Q_OBJECT + +public: + explicit RuneDisplay(QWidget *parent = nullptr); + ~RuneDisplay(); + + void setRuneMeta(const std::vector& runeinfo); + void setRunes(std::vector ids, uint32_t primary, uint32_t secondary); +private: + void updateText(); + std::string getRuneText(uint32_t id); + + Ui::RuneDisplay *ui; + + std::vector runes; + uint32_t primary; + uint32_t secondary; + + std::vector runeinfo; +}; diff --git a/lolautoaccept.pro b/lolautoaccept.pro index a22dd79..1b81694 100644 --- a/lolautoaccept.pro +++ b/lolautoaccept.pro @@ -28,6 +28,7 @@ defineReplace(prependAll) { SOURCES += \ src/arg.cpp \ + src/blitzapi.cpp \ src/champcache.cpp \ src/championsearch.cpp \ src/champrow.cpp \ @@ -44,6 +45,7 @@ SOURCES += \ src/mainwindow.cpp \ src/memoryimagecache.cpp \ src/restclient.cpp \ + src/runedisplay.cpp \ src/settingstab.cpp \ src/stagesettings.cpp \ thirdparty/Log/Log.cpp @@ -52,6 +54,7 @@ SOURCES += \ HEADERS += \ include/arg.h \ + include/blitzapi.h \ include/champcache.h \ include/championsearch.h \ include/champrow.h \ @@ -67,6 +70,7 @@ HEADERS += \ include/mainwindow.h \ include/memoryimagecache.h \ include/restclient.h \ + include/runedisplay.h \ include/settingstab.h \ include/stagesettings.h \ thirdparty/Log/Log.h @@ -80,6 +84,7 @@ OBJECTS_DIR = build/ FORMS += \ ui/championsearch.ui \ ui/mainwindow.ui \ + ui/runedisplay.ui \ ui/settingstab.ui \ ui/stagesettings.ui diff --git a/src/blitzapi.cpp b/src/blitzapi.cpp new file mode 100644 index 0000000..4768f2f --- /dev/null +++ b/src/blitzapi.cpp @@ -0,0 +1,113 @@ +#include "blitzapi.h" + +#include +#include + +#include + +#include "json.h" + +// curl 'https://league-champion-aggregate.iesdev.com/graphql?query=query%20ChampionBuilds%28%24championId%3AInt%21%2C%24queue%3AQueue%21%2C%24role%3ARole%2C%24opponentChampionId%3AInt%2C%24key%3AChampionBuildKey%29%7BchampionBuildStats%28championId%3A%24championId%2Cqueue%3A%24queue%2Crole%3A%24role%2CopponentChampionId%3A%24opponentChampionId%2Ckey%3A%24key%29%7BchampionId%20opponentChampionId%20queue%20role%20builds%7BcompletedItems%7Bgames%20index%20averageIndex%20itemId%20wins%7Dgames%20mythicId%20mythicAverageIndex%20primaryRune%20runes%7Bgames%20index%20runeId%20wins%20treeId%7DskillOrders%7Bgames%20skillOrder%20wins%7DstartingItems%7Bgames%20startingItemIds%20wins%7DsummonerSpells%7Bgames%20summonerSpellIds%20wins%7Dwins%7D%7D%7D&variables=%7B%22championId%22%3A25%2C%22role%22%3A%22SUPPORT%22%2C%22queue%22%3A%22RANKED_SOLO_5X5%22%2C%22opponentChampionId%22%3Anull%2C%22key%22%3A%22PUBLIC%22%7D' -H 'Accept: application/json' + +// query=query ChampionBuilds($championId:Int!,$queue:Queue!,$role:Role,$opponentChampionId:Int,$key:ChampionBuildKey){championBuildStats(championId:$championId,queue:$queue,role:$role,opponentChampionId:$opponentChampionId,key:$key){championId opponentChampionId queue role builds{completedItems{games index averageIndex itemId wins}games mythicId mythicAverageIndex primaryRune runes{games index runeId wins treeId}skillOrders{games skillOrder wins}startingItems{games startingItemIds wins}summonerSpells{games summonerSpellIds wins}wins}}} +// &variables={"championId":25,"role":"SUPPORT","queue":"RANKED_SOLO_5X5","opponentChampionId":null,"key":"PUBLIC"} + +static const std::string POSITIONNAMES[] = {"INVALID", "TOP", "JUNGLE", "MIDDLE", "BOTTOM", "SUPPORT"}; + +BlitzAPI::BlitzAPI() : RestClient("https://league-champion-aggregate.iesdev.com/graphql?") {} + +BlitzAPI::ChampionInfo::ChampionInfo() {} +BlitzAPI::ChampionInfo::ChampionInfo(const QJsonObject& json) { + primaryRune = getValue(json, "primaryRune"); + + // kill order stuff + auto skillordersref = json["skillOrders"]; + if(skillordersref.isArray()) { + QJsonArray arr = skillordersref.toArray(); + if(!arr.empty()) { + auto skillorderref = arr.at(0); + if(skillorderref.isObject()) { + QJsonObject skillorder = skillorderref.toObject(); + QJsonValueRef realorderref = skillorder["skillOrder"]; + if(realorderref.isArray()) { + QJsonArray realorder = realorderref.toArray(); + this->skillorder.reserve(realorder.size()); + for(auto it : realorder) { + if(it.isDouble()) { + this->skillorder.push_back(it.toDouble()); + } + } + } + } + } + } + + // runes + QJsonValue runesarrref = json["runes"]; + if(runesarrref.isArray()) { + QJsonArray runesarr = runesarrref.toArray(); + runes.reserve(runesarr.size()); + for(auto it : runesarr) { + if(!it.isObject()) continue; + + QJsonObject rune = it.toObject(); + auto runeid = rune["runeid"]; + if(runeid.isDouble()) { + runes.push_back(runeid.toDouble()); + } + } + } +} + +BlitzAPI::ChampionInfo BlitzAPI::getChampionInfo(uint32_t championID, Position p, uint32_t enemyChampionID) { + QJsonObject vars; + + vars["championId"] = (int) championID; + vars["role"] = QString::fromStdString(POSITIONNAMES[(int) p]); + vars["queue"] = "RANKED_SOLO_5X5"; + + if(enemyChampionID == 0) + vars["opponentChampionId"] = QJsonValue::Null; + else + vars["opponentChampionId"] = (int) enemyChampionID; + vars["key"] = "PUBLIC"; // ? what does this do? + + QJsonDocument jvars(vars); + const std::string variables = jvars.toJson().toStdString(); + const std::string query = "query ChampionBuilds($championId:Int!,$queue:Queue!,$role:Role,$opponentChampionId:Int,$key:ChampionBuildKey){championBuildStats(championId:$championId,queue:$queue,role:$role,opponentChampionId:$opponentChampionId,key:$key){championId opponentChampionId queue role builds{completedItems{games index averageIndex itemId wins}games mythicId mythicAverageIndex primaryRune runes{games index runeId wins treeId}skillOrders{games skillOrder wins}startingItems{games startingItemIds wins}summonerSpells{games summonerSpellIds wins}wins}}}"; + const std::string requeststr = "query=" + escape(query) + "&variables=" + escape(variables); + QJsonDocument doc = request(requeststr); + + if(!doc.isObject()) { + // error + return {}; + } + + // Log::info << "returned: " << doc.toJson().toStdString(); + QJsonObject obj = doc.object(); + QJsonValueRef dataref = obj["data"]; + + if(!dataref.isObject()) return {}; + + QJsonObject data = dataref.toObject(); + QJsonValueRef buildstatsref = data["championBuildStats"]; + + if(!buildstatsref.isObject()) return{}; + + QJsonObject buildstats = buildstatsref.toObject(); + QJsonValueRef buildsref = buildstats["builds"]; + + if(!buildsref.isArray()) return {}; + + QJsonArray builds = buildsref.toArray(); + + if(builds.size() > 0) { + // just take the first + QJsonValue buildval = builds.at(0); + if(buildval.isObject()) { + return (ChampionInfo) buildval.toObject(); + } + } + + return {}; +} diff --git a/src/clientapi.cpp b/src/clientapi.cpp index 1ee96f2..36c8532 100644 --- a/src/clientapi.cpp +++ b/src/clientapi.cpp @@ -94,6 +94,7 @@ ClientAPI::PlayerInfo ClientAPI::getSelf() { info.gameName = getValue(obj, "gameName"); info.name = getValue(obj, "name"); info.statusMessage = getValue(obj, "statusMessage", ""); + info.summonerid = getValue(obj, "summonerId"); auto lolref = obj["lol"]; if(lolref.isObject()) { @@ -165,3 +166,83 @@ ClientAPI::TimerInfo ClientAPI::getTimerInfo() { return (TimerInfo) obj; } + +ClientAPI::RunePage ClientAPI::getCurrentRunePage() { + QJsonDocument doc = request("lol-perks/v1/currentpage"); + + if(!doc.isObject()) return {}; + + return (RunePage) doc.object(); +} + +std::vector ClientAPI::getAllRunePages() { + QJsonDocument doc = request("lol-perks/v1/pages"); + + if(!doc.isArray()) return {}; + + QJsonArray arr = doc.array(); + std::vector out; + out.reserve(arr.size()); + for(auto it : arr) { + if(!it.isObject()) { + out.push_back((RunePage) it.toObject()); + } + } + return out; +} + +bool ClientAPI::selectRunePage(uint64_t id) { + QJsonDocument doc = request("lol-perks/v1/currentpage", Method::PUT, std::to_string(id)); + + if(doc.isEmpty()) return true; // ok + + // error + Log::warn << "error selecting runepage: " << id << " " << doc.toJson().toStdString(); + + return false; +} + +bool ClientAPI::editRunePage(const RunePage& page) { + QJsonObject pagereq; + + pagereq["id"] = (int) page.id; + pagereq["name"] = QString::fromStdString(page.name); + pagereq["primaryStyleId"] = (int) page.primaryStyleID; + pagereq["subStyleId"] = (int) page.subStyleID; + + QJsonArray selected; + for(uint32_t sel : page.selectedPerkIDs) { + selected.push_back((int) sel); + } + + pagereq["selectedPerkIds"] = selected; + + QJsonDocument reqdoc(pagereq); + QJsonDocument doc = request("lol-perks/v1/pages", Method::POST, reqdoc.toJson().toStdString()); + + if(doc.isEmpty()) return true; // ok + + // error + Log::warn << "error editing runepage: " << page.id << " " << doc.toJson().toStdString(); + + return false; +} + +std::vector ClientAPI::getAllRuneAspekts() { + QJsonDocument doc = request("lol-perks/v1/perks"); + + if(!doc.isArray()) { + Log::warn << __PRETTY_FUNCTION__ << " doc is not array"; + return {}; + } + + QJsonArray arr = doc.array(); + std::vector out; + out.reserve(arr.size()); + for(auto it : arr) { + if(it.isObject()) { + out.push_back((RuneAspekt) it.toObject()); + } + } + return out; +} diff --git a/src/clientapi_json.cpp b/src/clientapi_json.cpp index f94dd6e..fe79a31 100644 --- a/src/clientapi_json.cpp +++ b/src/clientapi_json.cpp @@ -36,6 +36,18 @@ static T mapEnum(const std::string& input, const std::string* names, uint32_t co #define MAPENUM(VAR, ENUM, DEFAULT) \ mapEnum(VAR, ENUM ## Names, ENUM ## NamesCount, ClientAPI:: ENUM :: DEFAULT) +template +static std::vector readVector(QJsonArray arr) { + std::vector out; + out.reserve(arr.size()); + + for(auto it : arr) { + out.push_back(convert((QJsonValue) it)); + } + + return out; +} + ClientAPI::ReadyCheckState ClientAPI::toReadyCheckState(const QJsonObject& obj) { std::string searchState = getValue(obj, "state", "Invalid"); std::string playerresponse = getValue(obj, "playerResponse", "None"); @@ -170,6 +182,35 @@ ClientAPI::ChampSelectSession::operator bool() { return gameid != 0; } +ClientAPI::RunePage::RunePage() {} +ClientAPI::RunePage::RunePage(const QJsonObject& json) { + id = getValue(json, "id", 0); + lastmodified = getValue(json, "lastModified", 0); + primaryStyleID = getValue(json, "primaryStyleId", 0); + subStyleID = getValue(json, "subStyleId", 0); + name = getValue(json, "name"); + isDeleteable = getValue(json, "isDeletable", false); + isEditable = getValue(json, "isEditable", false); + isActive = getValue(json, "isActive", false); + isCurrent = getValue(json, "current", false); + isValid = getValue(json, "isValid", false); + order = getValue(json, "order", 0); + + auto selectedref = json["selectedPerkIds"]; + if(selectedref.isArray()) { + selectedPerkIDs = readVector(selectedref.toArray()); + } +} + +RuneAspekt::RuneAspekt() {} +RuneAspekt::RuneAspekt(const QJsonObject& json) { + id = getValue(json, "id", 0); + name = getValue(json, "name"); + shortDesc = getValue(json, "shortDesc"); + longDesc = getValue(json, "longDesc"); + tooltip = getValue(json, "tooltip"); + iconPath = getValue(json, "iconPath"); +} #define PRINTENUM(ENUMNAME) \ std::ostream& operator<<(std::ostream& str, const ClientAPI:: ENUMNAME & state) { \ diff --git a/src/json.cpp b/src/json.cpp index b84c24c..959fda8 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -7,6 +7,13 @@ int convert(const QJsonValue& val) { return val.toInt(); } +template<> +uint32_t convert(const QJsonValue& val) { + if(val.isString()) + return val.toString().toUInt(); + return (uint32_t) val.toDouble(); +} + template<> int64_t convert(const QJsonValue& val) { if(val.isString()) @@ -14,6 +21,13 @@ int64_t convert(const QJsonValue& val) { return (int64_t) val.toDouble(); } +template<> +uint64_t convert(const QJsonValue& val) { + if(val.isString()) + return val.toString().toULongLong(); + return (uint64_t) val.toDouble(); +} + template<> std::string convert(const QJsonValue& val) { return val.toString().toStdString(); diff --git a/src/lolautoaccept.cpp b/src/lolautoaccept.cpp index 3261e4f..4febcf4 100644 --- a/src/lolautoaccept.cpp +++ b/src/lolautoaccept.cpp @@ -70,6 +70,22 @@ void LolAutoAccept::reload() { loadPosition(currentPosition); } +const std::vector& LolAutoAccept::getRuneAspekts() { + if(runeaspekts.empty()) { + if(clientapi) { + runeaspekts = clientapi->getAllRuneAspekts(); + Log::info << "Loaded " << runeaspekts.size() << " rune aspekts"; + } + } + + return runeaspekts; +} + +void LolAutoAccept::applyRunes() { + // TODO + Log::warn << "LolAutoAccept::applyRunes() not implemented"; +} + void LolAutoAccept::stopJoinThread() { stop(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 70cc012..4ff81c4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -52,8 +52,12 @@ void MainWindow::toggleMainswitch(bool state) { return; } + ui->runedisplay->setRuneMeta(lolaa.getRuneAspekts()); + lolaa.run(); + ui->statusbar->showMessage(tr("Auto-Acceptor started!")); + } else { lolaa.stop(); ui->statusbar->showMessage(tr("Auto-Acceptor stoped!")); @@ -83,8 +87,18 @@ void MainWindow::tabchanged(Position p, LolAutoAccept::State s) { lolaa.reload(); } +void MainWindow::applyRunes() { + Log::info << "applyRunes pressed"; + + lolaa.applyRunes(); +} + void MainWindow::onPosChange(Position newpos) { if(newpos != Position::INVALID) { emit requestTabChange((int) newpos -1); } } + +void MainWindow::onRuneChanged(const std::vector& runes, uint32_t prim, uint32_t sec) { + ui->runedisplay->setRunes(runes, prim, sec); +} diff --git a/src/restclient.cpp b/src/restclient.cpp index 823df36..be97127 100644 --- a/src/restclient.cpp +++ b/src/restclient.cpp @@ -77,21 +77,19 @@ QByteArray RestClient::requestRaw(const std::string& url, Method m, const std::s if (!curl) return {}; std::string requrl = baseurl + url; - QByteArray ba; //buffer - // std::cout << "[DEBUG] requrl is: " << requrl << std::endl; curl_easy_setopt(curl, CURLOPT_URL, requrl.c_str()); - // curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //Prevent "longjmp causes uninitialized stack frame" bug - // set callback data - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ba); - curl_easy_setopt(curl, CURLOPT_USERPWD, basicauth.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); if (disableCertCheck) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); } + // restore default HTTP Options + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); // curl header struct curl_slist* headerlist = NULL; @@ -121,9 +119,11 @@ QByteArray RestClient::requestRaw(const std::string& url, Method m, const std::s curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); break; } - if (headerlist) { - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - } + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); + + QByteArray ba; //buffer + // set callback data + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ba); CURLcode res = curl_easy_perform(curl); if (headerlist) { @@ -168,3 +168,10 @@ void RestClient::enableDebugging(bool enabled) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); } } + +std::string RestClient::escape(const std::string& in) const { + char* e = curl_easy_escape(curl, in.c_str(), in.length()); + std::string esc(e); + curl_free(e); + return esc; +} diff --git a/src/runedisplay.cpp b/src/runedisplay.cpp new file mode 100644 index 0000000..2ba66ea --- /dev/null +++ b/src/runedisplay.cpp @@ -0,0 +1,45 @@ +#include "runedisplay.h" +#include "ui_runedisplay.h" + +#include + +RuneDisplay::RuneDisplay(QWidget *parent) : QWidget(parent), ui(new Ui::RuneDisplay) { + ui->setupUi(this); +} + +RuneDisplay::~RuneDisplay() { + delete ui; +} + +void RuneDisplay::setRuneMeta(const std::vector& ri) { + runeinfo = ri; +} + +void RuneDisplay::setRunes(std::vector ids, uint32_t primary, uint32_t secondary) { + runes = ids; + this->primary = primary; + this->secondary = secondary; + + updateText(); +} + +void RuneDisplay::updateText() { + std::ostringstream out; + + out << "primary: " << getRuneText(primary) << " secondary: " << getRuneText(secondary) << " "; + + for(uint32_t rune : runes) { + out << getRuneText(rune); + } + ui->runetext->setText(QString::fromStdString(out.str())); +} + +std::string RuneDisplay::getRuneText(uint32_t id) { + for(const RuneAspekt& ra : runeinfo) { + if(ra.id == id) { + return ra.name; + } + } + + return "(" + std::to_string(id) + ")"; +} \ No newline at end of file diff --git a/src/settingstab.cpp b/src/settingstab.cpp index edd5550..68cc393 100644 --- a/src/settingstab.cpp +++ b/src/settingstab.cpp @@ -83,4 +83,4 @@ StageSettings* SettingsTab::getStage(LolAutoAccept::State s) const { } assert(false); // "invalid" stage (Lobby or Game) return nullptr; -} \ No newline at end of file +} diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index a159ec6..eef0cdb 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 432 - 630 + 433 + 638 @@ -115,6 +115,16 @@ + + + + Apply Runes + + + + + + @@ -123,7 +133,7 @@ 0 0 - 432 + 433 24 @@ -137,6 +147,12 @@
settingstab.h
1 + + RuneDisplay + QWidget +
runedisplay.h
+ 1 +
mainswitch diff --git a/ui/runedisplay.ui b/ui/runedisplay.ui new file mode 100644 index 0000000..86ce6c9 --- /dev/null +++ b/ui/runedisplay.ui @@ -0,0 +1,28 @@ + + + RuneDisplay + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + Runes: + + + + + + + +