forked from MrBesen/lolautoaccept
190 lines
4.3 KiB
C++
190 lines
4.3 KiB
C++
#include "lolautoaccept.h"
|
|
|
|
#include <thread>
|
|
#include <Log.h>
|
|
|
|
#include "util.h"
|
|
#include "fakescreen.h"
|
|
|
|
// set to 1 to use the test screenshot feature
|
|
#define TESTSCREEN 0
|
|
|
|
void debugImage(cv::Mat img, const std::string& name) {
|
|
if(img.channels() > 3) {
|
|
std::vector<cv::Mat> channels(4);
|
|
cv::split(img, channels);
|
|
channels.resize(3); // drop alpha channel
|
|
cv::merge(channels, img);
|
|
}
|
|
|
|
time_t t = time(0);
|
|
cv::imwrite("debugimages/" + name + std::to_string(t) + ".png", img);
|
|
}
|
|
|
|
LolAutoAccept::Stage::Stage(const std::string& matchertmpl) : matcher(matchertmpl) {}
|
|
LolAutoAccept::Stage::~Stage() {}
|
|
|
|
bool LolAutoAccept::Stage::process(LolAutoAccept& lolaa, cv::Mat& img) {
|
|
if(enabled) {
|
|
auto match = matcher.match(img);
|
|
if(match.doesMatch) {
|
|
action(lolaa);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void LolAutoAccept::performClick(uint32_t nr, bool movemouseaway) {
|
|
inputs.setOffset(screen->getXOffset(), screen->getYOffset());
|
|
inputs.setScale(screen->getXScale(), screen->getYScale());
|
|
|
|
auto p = inputs.get(nr);
|
|
Log::info << "click " << nr << " @ " << p.x << " " << p.y;
|
|
|
|
sim.mouseMoveTo(p.x, p.y);
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(170));
|
|
sim.mouseClick(XIS::LEFT_MOUSE_BUTTON);
|
|
|
|
// move mouse away
|
|
if(movemouseaway) {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(170));
|
|
p = inputs.get(0);
|
|
sim.mouseMoveTo(p.x, p.y);
|
|
}
|
|
}
|
|
|
|
void LolAutoAccept::enterSearch(const std::string& text) {
|
|
performClick(2, false); // click searchbox
|
|
|
|
Log::debug << "enter text: " << text;
|
|
|
|
sim.keySequence(text);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(750));
|
|
}
|
|
|
|
void LolAutoAccept::pickFirst(const std::string& search) {
|
|
enterSearch(search);
|
|
|
|
performClick(3, false); // first champion
|
|
}
|
|
|
|
LolAutoAccept::LolAutoAccept() : sim(XInputSimulator::getInstance()) {
|
|
// click positions in 1280x720 scale
|
|
inputs.addPoint({0, 0}); // zero zero
|
|
inputs.addPoint({645, 560}); // accept game
|
|
inputs.addPoint({775, 105}); // search box
|
|
inputs.addPoint({380, 160}); // first champ
|
|
inputs.addPoint({638, 608}); // pick/ban champ
|
|
|
|
stages.reserve(4);
|
|
stages.push_back(new AcceptStage());
|
|
stages.push_back(new PrePickStage());
|
|
stages.push_back(new BanStage());
|
|
stages.push_back(new PickStage());
|
|
}
|
|
|
|
LolAutoAccept::~LolAutoAccept() {
|
|
stopJoinThread();
|
|
|
|
for(auto s : stages) {
|
|
delete s;
|
|
}
|
|
|
|
delete screen;
|
|
screen = nullptr;
|
|
}
|
|
|
|
void LolAutoAccept::setChamp(const std::string& champ, State s) {
|
|
if(s == State::LOBBY || s >= State::GAME) {
|
|
Log::warn << "setChamp() called on invalid State";
|
|
}
|
|
|
|
stages.at((int) s)->champ = champ;
|
|
}
|
|
|
|
void LolAutoAccept::setEnabled(bool b, State s) {
|
|
if(s >= State::GAME) {
|
|
Log::warn << "setEnabled() called on invalid State";
|
|
}
|
|
|
|
stages.at((int) s)->enabled = b;
|
|
}
|
|
|
|
bool LolAutoAccept::init() {
|
|
if(screen)
|
|
return true;
|
|
|
|
// get window
|
|
#if TESTSCREEN == 0
|
|
auto wins = ScreenShot::getWindows("League of Legends");
|
|
if(wins.size() != 1) {
|
|
Log::fatal << "invalid count of windows found: " << wins.size();
|
|
for(auto w : wins) {
|
|
delete w;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
screen = (wins.at(0)); // just take the first
|
|
#else
|
|
|
|
// testing whole screen, but take a part of it, so it behaves like a focused screenshot
|
|
screen = new FakeScreen(1, 683, 1280, 720);
|
|
#endif
|
|
|
|
// testing: whole screen:
|
|
// screen = new ScreenShot();
|
|
return true;
|
|
}
|
|
|
|
void LolAutoAccept::run() {
|
|
// make sure its not running
|
|
stopJoinThread();
|
|
|
|
if(!screen) return;
|
|
|
|
lolaathread = std::thread(&LolAutoAccept::innerRun, this);
|
|
}
|
|
|
|
void LolAutoAccept::stop() {
|
|
shouldrun = false;
|
|
}
|
|
|
|
void LolAutoAccept::stopJoinThread() {
|
|
stop();
|
|
|
|
if(lolaathread.joinable()) {
|
|
lolaathread.join();
|
|
}
|
|
}
|
|
|
|
void LolAutoAccept::innerRun() {
|
|
shouldrun = true;
|
|
|
|
while(shouldrun) {
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
cv::Mat img;
|
|
screen->take(img);
|
|
cv::resize(img, img, cv::Size(ScreenShot::DEFAULTWIDTH, ScreenShot::DEFAULTHEIGHT));
|
|
|
|
for(size_t i = 0; i < stages.size(); ++i) {
|
|
Log::trace << "processing stage" << i;
|
|
Stage* stage = stages.at(i);
|
|
if(stage->process(*this, img)) {
|
|
Log::debug << "stage successful: " << i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
std::chrono::duration<double> dur = (end-start);
|
|
if(dur.count() > 1e-5)
|
|
Log::info << "iteration took: " << (dur.count() * 1000) << " ms";
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(800));
|
|
}
|
|
}
|