231 lines
7.9 KiB
C++
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 << ')'; \
|
|
}
|