forked from MrBesen/lolautoaccept
RunePage class added and refactored; find matching runepages
This commit is contained in:
parent
c03b123af0
commit
4716e48cbf
|
@ -4,6 +4,7 @@
|
|||
#include <QJsonObject>
|
||||
|
||||
#include "restclient.h"
|
||||
#include "runepage.h"
|
||||
#include "position.h"
|
||||
|
||||
class BlitzAPI : public RestClient {
|
||||
|
@ -12,9 +13,8 @@ public:
|
|||
|
||||
struct ChampionInfo {
|
||||
std::vector<uint32_t> skillorder;
|
||||
std::vector<uint32_t> runes;
|
||||
uint32_t primaryRuneStyle = 0;
|
||||
uint32_t secondaryRuneStyle = 0;
|
||||
|
||||
RunePage runepage;
|
||||
|
||||
// items?
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "restclient.h"
|
||||
#include "position.h"
|
||||
#include "runeaspekt.h"
|
||||
#include "runepage.h"
|
||||
|
||||
class ClientAPI : public RestClient {
|
||||
public:
|
||||
|
@ -132,8 +133,6 @@ public:
|
|||
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;
|
||||
|
@ -141,7 +140,7 @@ public:
|
|||
bool isCurrent = false;
|
||||
bool isValid = true;
|
||||
uint32_t order = 0; // position in the ui
|
||||
std::vector<uint32_t> selectedPerkIDs;
|
||||
::RunePage runepage;
|
||||
|
||||
RunePage();
|
||||
explicit RunePage(const QJsonObject& json);
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
#include "clientapi.h"
|
||||
#include "config.h"
|
||||
#include "datadragon.h"
|
||||
#include "runepage.h"
|
||||
|
||||
class LolAutoAccept {
|
||||
public:
|
||||
using onposchange_func = std::function<void(Position)>;
|
||||
using onruneschange_func = std::function<void(const std::vector<uint32_t>, uint32_t, uint32_t)>;
|
||||
using onruneschange_func = std::function<void(const RunePage&)>;
|
||||
protected:
|
||||
struct Stage {
|
||||
Stage();
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
|
||||
const std::vector<RuneAspekt>& getRuneAspekts();
|
||||
void applyRunes();
|
||||
void setOnRuneChangeFunc(onruneschange_func on);
|
||||
|
||||
private:
|
||||
void stopJoinThread();
|
||||
|
@ -84,5 +86,7 @@ private:
|
|||
void pickPhase(const ownactions_t& ownactions);
|
||||
void phase(const ownactions_t& ownactions, ClientAPI::ChampSelectActionType type, State s, bool complete, std::function<bool(uint32_t)> filter = {});
|
||||
static int32_t getBestRunePage(const std::vector<ClientAPI::RunePage>& allpages);
|
||||
static int32_t getMatchingRunePage(const RunePage& rp, const std::vector<ClientAPI::RunePage>& allpages);
|
||||
void champSelect();
|
||||
void applyRunes_internal(uint32_t champid, Position pos);
|
||||
};
|
|
@ -38,7 +38,6 @@ signals:
|
|||
private:
|
||||
// returns empty string on no match
|
||||
void onPosChange(Position newpos); // to trigger the signal from a QObject
|
||||
void onRuneChanged(const std::vector<uint32_t>& runes, uint32_t prim, uint32_t sec);
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
std::thread lolaathread;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "runeaspekt.h"
|
||||
#include "runepage.h"
|
||||
|
||||
namespace Ui {
|
||||
class RuneDisplay;
|
||||
|
@ -15,16 +17,14 @@ public:
|
|||
~RuneDisplay();
|
||||
|
||||
void setRuneMeta(const std::vector<RuneAspekt>& runeinfo);
|
||||
void setRunes(const std::vector<uint32_t>& ids, uint32_t primary, uint32_t secondary);
|
||||
void setRunes(const RunePage& rp);
|
||||
private:
|
||||
void updateText();
|
||||
std::string getRuneText(uint32_t id);
|
||||
|
||||
Ui::RuneDisplay *ui;
|
||||
|
||||
std::vector<uint32_t> runes;
|
||||
uint32_t primary;
|
||||
uint32_t secondary;
|
||||
RunePage runepage;
|
||||
|
||||
std::vector<RuneAspekt> runeinfo;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
// represents a runepage
|
||||
struct RunePage {
|
||||
public:
|
||||
uint32_t primaryStyle = 0;
|
||||
uint32_t secondaryStyle = 0;
|
||||
std::vector<uint32_t> selectedAspects; // all selected aspekts (should be exactly 9)
|
||||
|
||||
bool operator==(const RunePage& rp) const;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, const RunePage&);
|
|
@ -46,6 +46,7 @@ SOURCES += \
|
|||
src/memoryimagecache.cpp \
|
||||
src/restclient.cpp \
|
||||
src/runedisplay.cpp \
|
||||
src/runepage.cpp \
|
||||
src/settingstab.cpp \
|
||||
src/stagesettings.cpp \
|
||||
thirdparty/Log/Log.cpp
|
||||
|
@ -71,6 +72,7 @@ HEADERS += \
|
|||
include/memoryimagecache.h \
|
||||
include/restclient.h \
|
||||
include/runedisplay.h \
|
||||
include/runepage.h \
|
||||
include/settingstab.h \
|
||||
include/stagesettings.h \
|
||||
thirdparty/Log/Log.h
|
||||
|
|
|
@ -43,8 +43,10 @@ BlitzAPI::ChampionInfo::ChampionInfo(const QJsonObject& json) {
|
|||
// runes
|
||||
// TODO: create a diffrent algorithm to choose wich runes should be picked, insted of just the first one
|
||||
QJsonValue runesarrref = json["runes"];
|
||||
std::vector<uint32_t>& runes = runepage.selectedAspects;
|
||||
if(runesarrref.isArray()) {
|
||||
QJsonArray runesarr = runesarrref.toArray();
|
||||
runes.clear();
|
||||
runes.resize(9, 0);// a list of runes, that are taken (the first one is a speare for the primary one)
|
||||
for(auto it : runesarr) {
|
||||
if(!it.isObject()) continue;
|
||||
|
@ -59,9 +61,9 @@ BlitzAPI::ChampionInfo::ChampionInfo(const QJsonObject& json) {
|
|||
Log::debug << "found rune: index: " << index << " +1 set to: " << runes.at(index+1);
|
||||
|
||||
if(index == 0) {
|
||||
primaryRuneStyle = rune["treeId"].toInt();
|
||||
runepage.primaryStyle = rune["treeId"].toInt();
|
||||
} else if(index == 3) {
|
||||
secondaryRuneStyle = rune["treeId"].toInt();
|
||||
runepage.secondaryStyle = rune["treeId"].toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,11 +206,11 @@ bool ClientAPI::editRunePage(const RunePage& page) {
|
|||
QJsonObject pagereq;
|
||||
|
||||
pagereq["name"] = QString::fromStdString(page.name);
|
||||
pagereq["primaryStyleId"] = (int) page.primaryStyleID;
|
||||
pagereq["subStyleId"] = (int) page.subStyleID;
|
||||
pagereq["primaryStyleId"] = (int) page.runepage.primaryStyle;
|
||||
pagereq["subStyleId"] = (int) page.runepage.secondaryStyle;
|
||||
|
||||
QJsonArray selected;
|
||||
for(uint32_t sel : page.selectedPerkIDs) {
|
||||
for(uint32_t sel : page.runepage.selectedAspects) {
|
||||
selected.push_back((int) sel);
|
||||
}
|
||||
|
||||
|
|
|
@ -186,8 +186,8 @@ ClientAPI::RunePage::RunePage() {}
|
|||
ClientAPI::RunePage::RunePage(const QJsonObject& json) {
|
||||
id = getValue<int32_t>(json, "id", 0);
|
||||
lastmodified = getValue<int64_t>(json, "lastModified", 0);
|
||||
primaryStyleID = getValue<int32_t>(json, "primaryStyleId", 0);
|
||||
subStyleID = getValue<int32_t>(json, "subStyleId", 0);
|
||||
runepage.primaryStyle = getValue<int32_t>(json, "primaryStyleId", 0);
|
||||
runepage.secondaryStyle = getValue<int32_t>(json, "subStyleId", 0);
|
||||
name = getValue<std::string>(json, "name");
|
||||
isDeleteable = getValue<bool>(json, "isDeletable", false);
|
||||
isEditable = getValue<bool>(json, "isEditable", false);
|
||||
|
@ -198,7 +198,7 @@ ClientAPI::RunePage::RunePage(const QJsonObject& json) {
|
|||
|
||||
auto selectedref = json["selectedPerkIds"];
|
||||
if(selectedref.isArray()) {
|
||||
selectedPerkIDs = readVector<uint32_t>(selectedref.toArray());
|
||||
runepage.selectedAspects = readVector<uint32_t>(selectedref.toArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,10 @@ void LolAutoAccept::applyRunes() {
|
|||
nextApplyRunes = true;
|
||||
}
|
||||
|
||||
void LolAutoAccept::setOnRuneChangeFunc(onruneschange_func on) {
|
||||
onRuneschange = on;
|
||||
}
|
||||
|
||||
void LolAutoAccept::stopJoinThread() {
|
||||
stop();
|
||||
|
||||
|
@ -290,7 +294,7 @@ int32_t LolAutoAccept::getBestRunePage(const std::vector<ClientAPI::RunePage>& p
|
|||
// search for a rune page with a name that starts with "AA: "
|
||||
for(uint32_t i = 0; i < pages.size(); ++i) {
|
||||
const ClientAPI::RunePage& rp = pages.at(i);
|
||||
if(rp.name.size() >= 4 && rp.name.substr(4) == "AA: ") {
|
||||
if(rp.name.size() >= 4 && rp.name.substr(0, 4) == "AA: ") {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +309,12 @@ int32_t LolAutoAccept::getBestRunePage(const std::vector<ClientAPI::RunePage>& p
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t LolAutoAccept::getMatchingRunePage(const RunePage& rp, const std::vector<ClientAPI::RunePage>& allpages) {
|
||||
auto it = std::find_if(allpages.begin(), allpages.end(), [rp](const ClientAPI::RunePage& r){ return r.runepage == rp; });
|
||||
|
||||
return (it == allpages.end()) ? -1 : it - allpages.begin();
|
||||
}
|
||||
|
||||
void LolAutoAccept::champSelect() {
|
||||
auto session = clientapi->getChampSelectSession();
|
||||
int32_t cellid = session.localPlayerCellId;
|
||||
|
@ -335,8 +345,9 @@ void LolAutoAccept::champSelect() {
|
|||
// update runes
|
||||
if(onRuneschange) {
|
||||
auto champinfo = blitzapi.getChampionInfo(pickedChamp, pos); // TODO: add detection for enemy champ
|
||||
Log::info << "champinfo aquired: " << champinfo.runes.size() << " runes primary style: " << champinfo.primaryRuneStyle;
|
||||
onRuneschange(champinfo.runes, champinfo.primaryRuneStyle, champinfo.secondaryRuneStyle); //
|
||||
Log::info << "champinfo aquired: " << champinfo.runepage;
|
||||
|
||||
onRuneschange(champinfo.runepage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,38 +379,53 @@ void LolAutoAccept::champSelect() {
|
|||
}
|
||||
|
||||
if(nextApplyRunes) {
|
||||
nextApplyRunes = false;
|
||||
Log::note << "apply runes";
|
||||
|
||||
// choose page
|
||||
auto pages = clientapi->getAllRunePages();
|
||||
int32_t pageoffset = getBestRunePage(pages);
|
||||
|
||||
if(pageoffset < 0) {
|
||||
Log::warn << "no rune page found!";
|
||||
return;
|
||||
}
|
||||
ClientAPI::RunePage& rp = pages.at(pageoffset);
|
||||
Log::info << "replace runepage id: " << rp.id << " old-name: " << rp.name;
|
||||
|
||||
auto champinfo = blitzapi.getChampionInfo(pickedChamp, pos);
|
||||
|
||||
Log::info << "fetched champion info runes: " << champinfo.runes.size();
|
||||
|
||||
ClientAPI::RunePage newpage;
|
||||
newpage.id = rp.id;
|
||||
newpage.name = "AA: " + std::to_string(pickedChamp) + " " + toString(pos); // TODO: resolve champname? add role?
|
||||
newpage.selectedPerkIDs = champinfo.runes;
|
||||
newpage.primaryStyleID = champinfo.primaryRuneStyle;
|
||||
newpage.subStyleID = champinfo.secondaryRuneStyle;
|
||||
clientapi->editRunePage(newpage);
|
||||
|
||||
//select runepage
|
||||
if(!rp.isCurrent) {
|
||||
Log::info << "page is not selected, selecting now (id: " << newpage.id << ')';
|
||||
clientapi->selectRunePage(newpage.id);
|
||||
}
|
||||
|
||||
Log::info << "runepage done";
|
||||
applyRunes_internal(pickedChamp, pos);
|
||||
}
|
||||
}
|
||||
|
||||
void LolAutoAccept::applyRunes_internal(uint32_t champid, Position pos) {
|
||||
nextApplyRunes = false;
|
||||
Log::note << "apply runes";
|
||||
|
||||
// get recommended runes and stuff
|
||||
auto champinfo = blitzapi.getChampionInfo(champid, pos);
|
||||
Log::info << "fetched champion info runes: " << champinfo.runepage;
|
||||
|
||||
// choose page
|
||||
auto pages = clientapi->getAllRunePages();
|
||||
|
||||
// check for page that allready contains the settings
|
||||
int32_t choosepage = getMatchingRunePage(champinfo.runepage, pages);
|
||||
if(choosepage != -1) {
|
||||
ClientAPI::RunePage& page = pages.at(choosepage);
|
||||
Log::info << "matching runepage found, selecting: " << page.id << " " << page.name;
|
||||
if(clientapi->selectRunePage(page.id)) {
|
||||
return;
|
||||
}
|
||||
Log::warn << "selecting runepage failed";
|
||||
}
|
||||
|
||||
// find page to replace
|
||||
int32_t pageoffset = getBestRunePage(pages);
|
||||
|
||||
if(pageoffset < 0) {
|
||||
Log::warn << "no rune page found!";
|
||||
return;
|
||||
}
|
||||
ClientAPI::RunePage& rp = pages.at(pageoffset);
|
||||
Log::info << "replace runepage id: " << rp.id << " old-name: " << rp.name;
|
||||
|
||||
ClientAPI::RunePage newpage;
|
||||
newpage.id = rp.id;
|
||||
newpage.name = "AA: " + std::to_string(champid) + " " + toString(pos); // TODO: resolve champname? add role?
|
||||
newpage.runepage = champinfo.runepage;
|
||||
clientapi->editRunePage(newpage);
|
||||
|
||||
//select runepage
|
||||
if(!rp.isCurrent) {
|
||||
Log::info << "page is not selected, selecting now (id: " << newpage.id << ')';
|
||||
clientapi->selectRunePage(newpage.id);
|
||||
}
|
||||
|
||||
Log::info << "runepage done";
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
#include <Log.h>
|
||||
|
||||
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), std::bind(&MainWindow::onRuneChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {
|
||||
lolaa(conf.getConfig(), dd, std::bind(&MainWindow::onPosChange, this, std::placeholders::_1)) {
|
||||
ui->setupUi(this);
|
||||
|
||||
lolaa.setOnRuneChangeFunc(std::bind(&RuneDisplay::setRunes, ui->runedisplay, std::placeholders::_1));
|
||||
|
||||
conf.load();
|
||||
|
||||
// for all tabs - set their config and datadragon
|
||||
|
@ -100,6 +102,3 @@ void MainWindow::onPosChange(Position newpos) {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::onRuneChanged(const std::vector<uint32_t>& runes, uint32_t prim, uint32_t sec) {
|
||||
ui->runedisplay->setRunes(runes, prim, sec);
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@ void RuneDisplay::setRuneMeta(const std::vector<RuneAspekt>& ri) {
|
|||
runeinfo = ri;
|
||||
}
|
||||
|
||||
void RuneDisplay::setRunes(const std::vector<uint32_t>& ids, uint32_t primary, uint32_t secondary) {
|
||||
runes = ids;
|
||||
this->primary = primary;
|
||||
this->secondary = secondary;
|
||||
void RuneDisplay::setRunes(const RunePage& rp) {
|
||||
runepage = rp;
|
||||
|
||||
updateText();
|
||||
}
|
||||
|
@ -26,9 +24,9 @@ void RuneDisplay::setRunes(const std::vector<uint32_t>& ids, uint32_t primary, u
|
|||
void RuneDisplay::updateText() {
|
||||
std::ostringstream out;
|
||||
|
||||
out << "primary: " << getRuneText(primary) << " secondary: " << getRuneText(secondary) << '\n';
|
||||
out << "primary: " << getRuneText(runepage.primaryStyle) << " secondary: " << getRuneText(runepage.secondaryStyle) << '\n';
|
||||
|
||||
for(uint32_t rune : runes) {
|
||||
for(uint32_t rune : runepage.selectedAspects) {
|
||||
out << getRuneText(rune) << '\n';
|
||||
}
|
||||
ui->runetext->setText(QString::fromStdString(out.str()));
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#include "runepage.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
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());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& str, const RunePage& rp) {
|
||||
return str << "Primary: " << rp.primaryStyle << " Secondary: " << rp.secondaryStyle << " aspects: " << rp.selectedAspects.size();
|
||||
}
|
|
@ -117,6 +117,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="applyRunesBtn">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select a Runepage and modify it to this runes.<br/>The page used is the first that:</p><ol style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">matches this Runes</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">has a name starting with &quot;AA:&quot;</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">is currently selected</li></ol></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply Runes</string>
|
||||
</property>
|
||||
|
|
Loading…
Reference in New Issue