2022-08-24 16:12:03 +02:00
|
|
|
#include "clientaccess.h"
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
# include <sys/mman.h>
|
|
|
|
# include <dirent.h>
|
|
|
|
# include <fcntl.h>
|
|
|
|
# include <sys/types.h>
|
|
|
|
# include <sys/stat.h>
|
|
|
|
# include <unistd.h>
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <Log.h>
|
|
|
|
|
|
|
|
#include "defer.h"
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
static const QString CLIENTNAME = "LeagueClientUx.exe"; // returns the name and value of a argument or empty string if it could not be parsed
|
2022-08-24 16:12:03 +02:00
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
static std::shared_ptr<ClientAccess> findUsingLockfile(const std::vector<QString>& cmdline, pid_t pid);
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
// reads a procfile into a vector (strings are \0 seperated)
|
2023-05-31 22:22:23 +02:00
|
|
|
static std::vector<QString> readProcFile(const QString& path) {
|
|
|
|
std::ifstream in(path.toStdString());
|
|
|
|
std::vector<QString> out;
|
2022-08-24 16:12:03 +02:00
|
|
|
std::string line;
|
|
|
|
while(std::getline(in, line, '\0')) {
|
|
|
|
if(!line.empty()) {
|
2023-05-31 22:22:23 +02:00
|
|
|
out.push_back(QString::fromStdString(line));
|
2022-08-24 16:12:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2023-06-13 22:40:55 +02:00
|
|
|
// test server
|
|
|
|
#if 0
|
|
|
|
std::shared_ptr<ClientAccess> ClientAccess::find() {
|
|
|
|
return std::make_shared<ClientAccess>("password", 4443);
|
|
|
|
}
|
|
|
|
#else
|
2022-08-24 19:24:18 +02:00
|
|
|
std::shared_ptr<ClientAccess> ClientAccess::find() {
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
DIR* procdir = opendir("/proc");
|
|
|
|
if(!procdir) return nullptr;
|
|
|
|
|
|
|
|
defer( closedir(procdir) );
|
|
|
|
|
|
|
|
dirent* entry = nullptr;
|
|
|
|
while ((entry = readdir(procdir)) != NULL) {
|
|
|
|
if (entry->d_type != DT_DIR) continue;
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
QString name(entry->d_name);
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
pid_t pid = -1;
|
2023-05-31 22:22:23 +02:00
|
|
|
bool success = false;
|
|
|
|
pid = name.toULong(&success);
|
|
|
|
if(!success) {
|
2022-08-24 16:12:03 +02:00
|
|
|
// could not parse -> not a pid
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get info on the exe
|
2023-05-31 22:22:23 +02:00
|
|
|
QString cmdfile = "/proc/" + QString::number(pid) + "/cmdline";
|
|
|
|
std::vector<QString> args = readProcFile(cmdfile);
|
2022-08-24 16:12:03 +02:00
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
// qDebug() << "process: " << pid << " has " << args.size() << " args";
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
if(args.empty()) continue;
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
QString& exename = args.at(0);
|
|
|
|
if(exename.endsWith(CLIENTNAME)) {
|
|
|
|
qInfo() << CLIENTNAME << " found: " << exename;
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
std::shared_ptr<ClientAccess> out;
|
|
|
|
|
2022-08-24 19:24:18 +02:00
|
|
|
out = findUsingLockfile(args, pid);
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
if(out) {
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2023-06-13 22:40:55 +02:00
|
|
|
#endif
|
2022-08-24 16:12:03 +02:00
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
std::shared_ptr<ClientAccess> findUsingLockfile(const std::vector<QString>& cmdline, pid_t pid) {
|
2022-08-24 16:12:03 +02:00
|
|
|
// get WINEPREFIX env
|
2023-05-31 22:22:23 +02:00
|
|
|
std::vector<QString> envs = readProcFile("/proc/" + QString::number(pid) + "/environ");
|
2022-08-24 16:12:03 +02:00
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
const static QString WINEPREFIX = "WINEPREFIX=";
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
// find WINEPREFIX
|
2023-05-31 22:22:23 +02:00
|
|
|
auto found = std::find_if(envs.begin(), envs.end(), [](const QString& s) {
|
|
|
|
return s.startsWith(WINEPREFIX);
|
2022-08-24 16:12:03 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
// WINEPREFIX env not present
|
|
|
|
if(found == envs.end()) {
|
2023-05-31 22:22:23 +02:00
|
|
|
qDebug() << "WINEPREFIX environment variable not set";
|
2022-08-24 16:12:03 +02:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
const QString wineprefix = found->remove(0, WINEPREFIX.size());
|
|
|
|
const QString binarypath = cmdline.at(0);
|
|
|
|
QString gamefolder = binarypath.mid(2, binarypath.lastIndexOf('/')-1); // remove the "C:" and the name of the binary
|
2022-08-24 16:12:03 +02:00
|
|
|
// TODO: gamefoldre could contain '\' so replacing every occurance with '/' would be a good idea
|
2023-05-31 22:22:23 +02:00
|
|
|
const QString lockfilepath = wineprefix + "/drive_c/" + gamefolder + "/lockfile";
|
2022-08-24 16:12:03 +02:00
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
qDebug() << "lockfilepath: " << lockfilepath;
|
2022-08-24 16:12:03 +02:00
|
|
|
|
|
|
|
// read lockfile
|
2023-05-31 22:22:23 +02:00
|
|
|
std::ifstream lockfile(lockfilepath.toStdString());
|
2022-08-24 16:12:03 +02:00
|
|
|
return createFromLockfile(lockfile);
|
|
|
|
}
|