From 02c5b5353cf5cf2e7501adc7c9c78464770230b1 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Thu, 21 Apr 2022 23:42:53 +0200 Subject: [PATCH] datadragon api --- include/datadragon.h | 39 +++++++++++ lolautoaccept.pro | 4 +- src/datadragon.cpp | 152 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 include/datadragon.h create mode 100644 src/datadragon.cpp diff --git a/include/datadragon.h b/include/datadragon.h new file mode 100644 index 0000000..a1ef353 --- /dev/null +++ b/include/datadragon.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include + +class DataDragon { +public: + DataDragon(); + DataDragon(const DataDragon&) = delete; + DataDragon& operator=(const DataDragon&) = delete; + + struct ChampData { + public: + ChampData(const QJsonObject& source); + + std::string name; + std::string id; + int key; + std::string partype; + std::string title; + }; + + const std::string& getVersion(); + const std::vector& getChamps(); + +protected: + QJsonDocument request(const std::string& url); + + std::string version; + std::vector champs; + +private: + CURL* curl = nullptr; // the curl (does curling) +}; + + +std::ostream& operator<<(std::ostream& str, const DataDragon::ChampData& cd); \ No newline at end of file diff --git a/lolautoaccept.pro b/lolautoaccept.pro index 5eb5ca2..2a7c0ba 100644 --- a/lolautoaccept.pro +++ b/lolautoaccept.pro @@ -3,7 +3,7 @@ QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 -unix:LIBS += thirdparty/XInputSimulator/build/libXInputSimulator.a -lX11 -lXtst -lXext -lxcb -lXau -pthread -lXdmcp -lrt `pkg-config opencv4 --libs` +unix:LIBS += thirdparty/XInputSimulator/build/libXInputSimulator.a -lX11 -lXtst -lXext -lxcb -lXau -lcurl -pthread -lXdmcp -lrt `pkg-config opencv4 --libs` # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings @@ -23,6 +23,7 @@ defineReplace(prependAll) { } SOURCES += \ + src/datadragon.cpp \ src/fakescreen.cpp \ src/lolautoaccept.cpp \ src/main.cpp \ @@ -36,6 +37,7 @@ SOURCES += \ # mainwindow.cpp HEADERS += \ + include/datadragon.h \ include/fakescreen.h \ include/lolautoaccept.h \ include/mainwindow.h \ diff --git a/src/datadragon.cpp b/src/datadragon.cpp new file mode 100644 index 0000000..587fc15 --- /dev/null +++ b/src/datadragon.cpp @@ -0,0 +1,152 @@ +#include "datadragon.h" + +#include +#include +#include + +#include +#include + +#include +#include + + +static const std::string BASEURL = "https://ddragon.leagueoflegends.com/"; + +static size_t write_callback(char* contents, size_t size, size_t nmemb, void* userdata) { + if (userdata) { + std::ostream& os = *static_cast(userdata); + std::streamsize len = size * nmemb; + if (os.write(static_cast(contents), len)) + return len; + } + + return 0; +} + + +template +T convert(const QJsonValue& val); + +template<> +int convert(const QJsonValue& val) { + if(val.isString()) + return val.toString().toInt(); + return val.toInt(); +} + +template<> +std::string convert(const QJsonValue& val) { + return val.toString().toStdString(); +} + +template +static T getValue(const QJsonObject& obj, const char* key, const T& def) { + auto it = obj.constFind(key); + if(it != obj.constEnd()) { + return convert(it.value()); + } + return def; +} + +DataDragon::DataDragon() { + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); +} + +DataDragon::ChampData::ChampData(const QJsonObject& source) { + name = getValue(source, "name", ""); + id = getValue(source, "id", ""); + key = getValue(source, "key", -1); + partype = getValue(source, "partype", ""); + title = getValue(source, "title", ""); +} + +const std::string& DataDragon::getVersion() { + if(!version.empty()) { + return version; + } + + QJsonDocument jversions = request("api/versions.json"); + if(jversions.isArray()) { + QJsonArray jverarr = jversions.array(); + if(!jverarr.empty()) { + version = jverarr.at(0).toString().toStdString(); + Log::info << "got League version: " << version; + return version; + } + } + + Log::error << "error parsing version object"; + // empty version str + return version; +} + +const std::vector& DataDragon::getChamps() { + if(!champs.empty()) { + return champs; + } + if(getVersion().empty()) { + return champs; + } + + QJsonDocument jchamps = request("cdn/" + version + "/data/en_US/champion.json"); + if(jchamps.isObject()) { + QJsonObject obj = jchamps.object(); + auto it = obj.constFind("data"); + if(it != obj.constEnd() && it.value().isObject()) { + QJsonObject jchampsdata = it.value().toObject(); + for(auto champit = jchampsdata.constBegin(); champit != jchampsdata.constEnd(); champit++) { + if(champit.value().isObject()) { + champs.emplace_back(champit.value().toObject()); + Log::info << "loaded champ: " << champs.back(); + } + } + + Log::info << "loaded " << champs.size() << " champs"; + } + } + + return champs; +} + +QJsonDocument DataDragon::request(const std::string& url) { + if(!curl) return {}; + + std::string requrl = BASEURL + url; + std::stringstream ss; //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, &ss); + + // Check for errors + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) { + if(res == CURLE_HTTP_RETURNED_ERROR) { + long responsecode = -1; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responsecode); + Log::warn << "DataDragon request failed: " << url << " -> " << responsecode ; + } else { + Log::warn << "DataDragon request failed: " << url << " " << curl_easy_strerror(res); + } + return {}; + } + + // json parsed = json::parse(ss.str()); + QJsonParseError err; + QJsonDocument parsed = QJsonDocument::fromJson(QByteArray::fromStdString(ss.str()), &err); + if(parsed.isNull() || err.error != QJsonParseError::NoError) { + Log::error << "DataDragon Jsonparse error " << err.errorString().toStdString() << " offset: " << err.offset; + return {}; + } + + return parsed; +} + +std::ostream& operator<<(std::ostream& str, const DataDragon::ChampData& cd) { + return str << "[n: " << cd.name << " " << " k: " << cd.key << " id: " << cd.id << "]"; +}