lolautoaccept/src/clientapi_json.cpp

231 lines
7.9 KiB
C++

#include "clientapi.h"
#include <iomanip>
#include <QJsonArray>
#include <QJsonObject>
#include <Log.h>
#include "json.h"
// calculate the size of a constant sized array
#define ARRSIZE(ARRNAME) (sizeof(ARRNAME) / sizeof(ARRNAME[0]))
#define ARR(NAME, ...) static const std::string NAME ## Names[] = {__VA_ARGS__}; \
static const uint32_t NAME ## NamesCount = ARRSIZE(NAME ## Names);
ARR(ReadyCheckState, "Invalid", "None", "InProgress", "Accepted", "Declined");
ARR(GameflowPhase, "None", "Lobby", "Matchmaking", "CheckedIntoTournament", "ReadyCheck", "ChampSelect", "GameStart", "FailedToLaunch", "InProgress", "Reconnect", "WaitingForStats", "PreEndOfGame", "EndOfGame", "TerminatedInError");
ARR(ChampSelectPhase, "Invalid", "PLANNING", "BAN_PICK", "FINALIZATION");
ARR(Position, "Invalid", "top", "jungle", "middle", "bottom", "utility");
ARR(ChampSelectActionType, "Invalid", "ban", "pick", "ten_bans_reveal");
template<typename T>
static T mapEnum(const std::string& input, const std::string* names, uint32_t count, T defaul) {
if(input.empty()) return defaul;
for (uint32_t i = 0; i < count; ++i) {
if (names[i] == input) {
return (T) i;
}
}
Log::warn << "no mapping of enum-string: " << std::quoted(input);
return defaul;
}
#define MAPENUM(VAR, ENUM, DEFAULT) \
mapEnum(VAR, ENUM ## Names, ENUM ## NamesCount, ClientAPI:: ENUM :: DEFAULT)
template<typename T>
static std::vector<T> readVector(QJsonArray arr) {
std::vector<T> out;
out.reserve(arr.size());
for(auto it : arr) {
out.push_back(convert<T>((QJsonValue) it));
}
return out;
}
ClientAPI::ReadyCheckState ClientAPI::toReadyCheckState(const QJsonObject& obj) {
std::string searchState = getValue<std::string>(obj, "state", "Invalid");
std::string playerresponse = getValue<std::string>(obj, "playerResponse", "None");
ClientAPI::ReadyCheckState response = MAPENUM(playerresponse, ReadyCheckState, NONE);
if(response == ClientAPI::ReadyCheckState::NONE) {
auto sstate = MAPENUM(searchState, ReadyCheckState, INVALID);
if(sstate == ClientAPI::ReadyCheckState::INPROGRESS) {
return sstate;
}
}
return response;
}
ClientAPI::GameflowPhase ClientAPI::toGameflowPhase(const std::string& str) {
return MAPENUM(str, GameflowPhase, NONE);
}
ClientAPI::ChampSelectPhase ClientAPI::toChampSelectPhase(const std::string& str) {
return MAPENUM(str, ChampSelectPhase, INVALID);
}
Position toPosition(const std::string& str) {
return mapEnum(str, PositionNames, PositionNamesCount, Position::INVALID);
}
std::string toString(Position p) {
return PositionNames[(int) p];
}
ClientAPI::ChampSelectActionType ClientAPI::toChampSelectActionType(const std::string& str) {
return MAPENUM(str, ChampSelectActionType, INVALID);
}
ClientAPI::TimerInfo::TimerInfo() {}
ClientAPI::TimerInfo::TimerInfo(const QJsonObject& obj) {
adjustedTimeLeftInPhase = getValue<int64_t>(obj, "adjustedTimeLeftInPhase", 0);
internalNowInEpochMs = getValue<int64_t>(obj, "internalNowInEpochMs", 0);
isefinite = getValue<bool>(obj, "isefinite", 0);
phase = MAPENUM(getValue<std::string>(obj, "phase", "Invalid"), ChampSelectPhase, INVALID);
totalTimeInPhase = getValue<int64_t>(obj, "totalTimeInPhase", 0);
}
ClientAPI::ChampSelectAction::ChampSelectAction() {}
ClientAPI::ChampSelectAction::ChampSelectAction(const QJsonObject& json) {
actorCellID = getValue<int32_t>(json, "actorCellId");
championID = getValue<int32_t>(json, "championId");
completed = getValue<bool>(json, "completed");
id = getValue<int32_t>(json, "id");
isAllyAction = getValue<bool>(json, "isAllyAction");
isInProgress = getValue<bool>(json, "isInProgress");
const std::string typestr = getValue<std::string>(json, "type", "Invalid");
type = toChampSelectActionType(typestr);
}
ClientAPI::ChampSelectCell::ChampSelectCell() {}
ClientAPI::ChampSelectCell::ChampSelectCell(const QJsonObject& json) {
position = toPosition(getValue<std::string>(json, "assignedPosition"));
cellID = getValue<int32_t>(json, "cellId");
championID = getValue<int32_t>(json, "championId");
championPickIntentID = getValue<int32_t>(json, "championPickIntent");
summonerID = getValue<int32_t>(json, "summonerId");
}
std::vector<ClientAPI::ChampSelectCell> ClientAPI::loadAllInfos(const QJsonArray& arr) {
std::vector<ClientAPI::ChampSelectCell> out;
out.reserve(arr.size()); // should usualy be 5
for(auto it = arr.constBegin(); it != arr.constEnd(); ++it) {
if(it->isObject()) {
out.push_back((ChampSelectCell) it->toObject());
}
}
return out;
}
ClientAPI::ChampSelectSession::ChampSelectSession() {}
ClientAPI::ChampSelectSession::ChampSelectSession(const QJsonObject& json) {
// loading actions
auto actionsref = json["actions"];
// its an array of array id ChampSelectAction
if(actionsref.isArray()) {
QJsonArray jactions = actionsref.toArray();
for(auto jact = jactions.constBegin(); jact != jactions.constEnd(); ++jact) {
if(!jact->isArray()) continue;
QJsonArray jactarr = jact->toArray();
for(auto it = jactarr.constBegin(); it != jactarr.constEnd(); ++it) {
if(it->isObject()) {
actions.push_back((ChampSelectAction) it->toObject());
}
}
}
}
counter = getValue<int32_t>(json, "counter");
gameid = getValue<int64_t>(json, "gameId");
allowDuplicatePick = getValue(json, "allowDuplicatePicks", false);
allowRerolling = getValue(json, "allowRerolling", false);
allowSkinSelection = getValue(json, "allowSkinSelection", true);
hasSimultaneousBans = getValue(json, "hasSimultaneousBans", false);
hasSimultaneousPicks = getValue(json, "hasSimultaneousPicks", true);
isCustomGame = getValue(json, "isCustomGame", false);
isSpectating = getValue(json, "isSpectating", false);
skipChampionSelect = getValue(json, "skipChampionSelect", false);
rerollsRemaining = getValue(json, "rerollsRemaining", 0);
localPlayerCellId = getValue(json, "localPlayerCellId", -1);
auto timerref = json["timer"];
if(timerref.isObject()) {
timer = (TimerInfo) timerref.toObject();
}
// load cellinfo
auto myteamref = json["myTeam"];
if(myteamref.isArray()) {
myTeam = loadAllInfos(myteamref.toArray());
}
auto theirteamref = json["theirTeam"];
if(theirteamref.isArray()) {
theirTeam = loadAllInfos(theirteamref.toArray());
}
}
ClientAPI::ChampSelectSession::operator bool() {
return gameid != 0;
}
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);
name = getValue<std::string>(json, "name");
isDeleteable = getValue<bool>(json, "isDeletable", false);
isEditable = getValue<bool>(json, "isEditable", false);
isActive = getValue<bool>(json, "isActive", false);
isCurrent = getValue<bool>(json, "current", false);
isValid = getValue<bool>(json, "isValid", false);
order = getValue<int32_t>(json, "order", 0);
auto selectedref = json["selectedPerkIds"];
if(selectedref.isArray()) {
selectedPerkIDs = readVector<uint32_t>(selectedref.toArray());
}
}
RuneAspekt::RuneAspekt() {}
RuneAspekt::RuneAspekt(const QJsonObject& json) {
id = getValue<int32_t>(json, "id", 0);
name = getValue<std::string>(json, "name");
shortDesc = getValue<std::string>(json, "shortDesc");
longDesc = getValue<std::string>(json, "longDesc");
tooltip = getValue<std::string>(json, "tooltip");
iconPath = getValue<std::string>(json, "iconPath");
}
#define PRINTENUM(ENUMNAME) \
std::ostream& operator<<(std::ostream& str, const ClientAPI:: ENUMNAME & state) { \
assert(((int) state) < ENUMNAME ## NamesCount); \
return str << ENUMNAME ## Names[(int) state] << " (" << (int) state << ')'; \
}
PRINTENUM(ReadyCheckState)
PRINTENUM(GameflowPhase)
PRINTENUM(ChampSelectPhase)
PRINTENUM(ChampSelectActionType)
std::ostream& operator<<(std::ostream& str, const Position & state) { \
assert(((int) state) < PositionNamesCount); \
return str << PositionNames[(int) state] << " (" << (int) state << ')'; \
}