2022-07-02 12:36:38 +02:00
|
|
|
#include "clientapi.h"
|
|
|
|
|
|
|
|
#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]))
|
2023-05-31 22:22:23 +02:00
|
|
|
#define ARR(NAME, ...) static const QString NAME ## Names[] = {__VA_ARGS__}; \
|
2022-07-02 12:36:38 +02:00
|
|
|
static const uint32_t NAME ## NamesCount = ARRSIZE(NAME ## Names);
|
|
|
|
|
2023-09-02 12:01:41 +02:00
|
|
|
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", "GAME_STARTING", "PLANNING", "BAN_PICK", "FINALIZATION")
|
|
|
|
ARR(Position, "Invalid", "top", "jungle", "middle", "bottom", "utility")
|
|
|
|
ARR(ShortPosition, "", "Top", "Jgl", "Mid", "Bot", "Sup")
|
|
|
|
ARR(ChampSelectActionType, "Invalid", "ban", "pick", "ten_bans_reveal")
|
2022-07-02 12:36:38 +02:00
|
|
|
|
|
|
|
template<typename T>
|
2023-05-31 22:22:23 +02:00
|
|
|
static T mapEnum(const QString& input, const QString* names, uint32_t count, T defaul) {
|
|
|
|
if(input.isEmpty()) return defaul;
|
2022-07-02 12:36:38 +02:00
|
|
|
|
|
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
|
|
if (names[i] == input) {
|
|
|
|
return (T) i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
qWarning() << "no mapping of enum-string: " << input << " using default: " << defaul << " type: " << typeid(T).name();
|
2022-07-02 12:36:38 +02:00
|
|
|
return defaul;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAPENUM(VAR, ENUM, DEFAULT) \
|
|
|
|
mapEnum(VAR, ENUM ## Names, ENUM ## NamesCount, ClientAPI:: ENUM :: DEFAULT)
|
|
|
|
|
2022-07-09 01:01:51 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-07-02 12:36:38 +02:00
|
|
|
ClientAPI::ReadyCheckState ClientAPI::toReadyCheckState(const QJsonObject& obj) {
|
2023-05-31 22:22:23 +02:00
|
|
|
QString searchState = getValue<QString>(obj, "state", "Invalid");
|
|
|
|
QString playerresponse = getValue<QString>(obj, "playerResponse", "None");
|
2022-07-02 12:36:38 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
ClientAPI::GameflowPhase ClientAPI::toGameflowPhase(const QString& str) {
|
2022-07-02 12:36:38 +02:00
|
|
|
return MAPENUM(str, GameflowPhase, NONE);
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
ClientAPI::ChampSelectPhase ClientAPI::toChampSelectPhase(const QString& str) {
|
2022-07-02 12:36:38 +02:00
|
|
|
return MAPENUM(str, ChampSelectPhase, INVALID);
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
Position toPosition(const QString& str) {
|
2022-07-04 00:30:00 +02:00
|
|
|
return mapEnum(str, PositionNames, PositionNamesCount, Position::INVALID);
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
QString toString(Position p) {
|
2022-07-04 00:30:00 +02:00
|
|
|
return PositionNames[(int) p];
|
2022-07-02 12:36:38 +02:00
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
QString toShortString(Position p) {
|
2022-07-10 15:19:25 +02:00
|
|
|
return ShortPositionNames[(int) p];
|
|
|
|
}
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
ClientAPI::ChampSelectActionType ClientAPI::toChampSelectActionType(const QString& str) {
|
2022-07-02 12:36:38 +02:00
|
|
|
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);
|
|
|
|
|
2023-05-31 22:22:23 +02:00
|
|
|
phase = MAPENUM(getValue<QString>(obj, "phase", "Invalid"), ChampSelectPhase, INVALID);
|
2022-07-02 12:36:38 +02:00
|
|
|
|
|
|
|
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");
|
2023-05-31 22:22:23 +02:00
|
|
|
const QString typestr = getValue<QString>(json, "type", "Invalid");
|
2022-07-02 12:36:38 +02:00
|
|
|
type = toChampSelectActionType(typestr);
|
|
|
|
}
|
|
|
|
|
|
|
|
ClientAPI::ChampSelectCell::ChampSelectCell() {}
|
|
|
|
ClientAPI::ChampSelectCell::ChampSelectCell(const QJsonObject& json) {
|
2023-05-31 22:22:23 +02:00
|
|
|
position = toPosition(getValue<QString>(json, "assignedPosition"));
|
2022-07-02 12:36:38 +02:00
|
|
|
cellID = getValue<int32_t>(json, "cellId");
|
|
|
|
championID = getValue<int32_t>(json, "championId");
|
|
|
|
championPickIntentID = getValue<int32_t>(json, "championPickIntent");
|
|
|
|
summonerID = getValue<int32_t>(json, "summonerId");
|
2022-08-26 02:12:25 +02:00
|
|
|
spell1Id = getValue<int64_t>(json, "spell1Id", 0);
|
|
|
|
spell2Id = getValue<int64_t>(json, "spell2Id", 0);
|
2022-07-02 12:36:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-07-09 01:01:51 +02:00
|
|
|
ClientAPI::RunePage::RunePage() {}
|
|
|
|
ClientAPI::RunePage::RunePage(const QJsonObject& json) {
|
|
|
|
id = getValue<int32_t>(json, "id", 0);
|
|
|
|
lastmodified = getValue<int64_t>(json, "lastModified", 0);
|
2022-07-10 14:32:44 +02:00
|
|
|
runepage.primaryStyle = getValue<int32_t>(json, "primaryStyleId", 0);
|
|
|
|
runepage.secondaryStyle = getValue<int32_t>(json, "subStyleId", 0);
|
2023-05-31 22:22:23 +02:00
|
|
|
name = getValue<QString>(json, "name");
|
2022-07-09 01:01:51 +02:00
|
|
|
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()) {
|
2022-07-10 14:32:44 +02:00
|
|
|
runepage.selectedAspects = readVector<uint32_t>(selectedref.toArray());
|
2022-07-09 01:01:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:36:11 +02:00
|
|
|
RuneStyleSlot::RuneStyleSlot() {}
|
|
|
|
RuneStyleSlot::RuneStyleSlot(const QJsonObject& json) {
|
|
|
|
type = getValue<QString>(json, "type");
|
|
|
|
|
|
|
|
auto perksj = json["perks"];
|
|
|
|
if(perksj.isArray()) {
|
|
|
|
perks = readVector<int>(perksj.toArray());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-10 15:56:09 +02:00
|
|
|
RuneStyle::RuneStyle() {}
|
|
|
|
RuneStyle::RuneStyle(const QJsonObject& json) {
|
|
|
|
id = getValue<int32_t>(json, "id", 0);
|
2023-05-31 22:22:23 +02:00
|
|
|
name = getValue<QString>(json, "name");
|
|
|
|
iconPath = getValue<QString>(json, "iconPath");
|
|
|
|
tooltip = getValue<QString>(json, "tooltip");
|
2023-05-01 22:36:11 +02:00
|
|
|
idName = getValue<QString>(json, "idName");
|
|
|
|
|
|
|
|
auto subStylesRef = json["allowedSubStyles"];
|
|
|
|
if(subStylesRef.isArray()) {
|
|
|
|
allowedSubStyles = readVector<int>(subStylesRef.toArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
auto runeSlotsRef = json["slots"];
|
|
|
|
if(runeSlotsRef.isArray()) {
|
|
|
|
runeSlots = readVector<RuneStyleSlot>(runeSlotsRef.toArray());
|
|
|
|
}
|
2022-07-10 15:56:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-07-09 01:01:51 +02:00
|
|
|
RuneAspekt::RuneAspekt() {}
|
|
|
|
RuneAspekt::RuneAspekt(const QJsonObject& json) {
|
|
|
|
id = getValue<int32_t>(json, "id", 0);
|
2023-05-31 22:22:23 +02:00
|
|
|
name = getValue<QString>(json, "name");
|
|
|
|
shortDesc = getValue<QString>(json, "shortDesc");
|
|
|
|
longDesc = getValue<QString>(json, "longDesc");
|
|
|
|
tooltip = getValue<QString>(json, "tooltip");
|
|
|
|
iconPath = getValue<QString>(json, "iconPath");
|
2022-07-09 01:01:51 +02:00
|
|
|
}
|
2022-07-02 12:36:38 +02:00
|
|
|
|
2022-08-26 02:12:25 +02:00
|
|
|
ClientAPI::Message::Message() {}
|
|
|
|
ClientAPI::Message::Message(const QJsonObject& json) {
|
2023-05-31 22:22:23 +02:00
|
|
|
body = getValue<QString>(json, "body");
|
|
|
|
fromId = getValue<QString>(json, "fromId");
|
|
|
|
fromPid = getValue<QString>(json, "fromPid");
|
2022-08-26 02:12:25 +02:00
|
|
|
fromSummonerId = getValue<int64_t>(json, "fromSummonerId");
|
2023-05-31 22:22:23 +02:00
|
|
|
id = getValue<QString>(json, "id");
|
2022-08-26 02:12:25 +02:00
|
|
|
isHistorical = getValue<bool>(json, "isHistorical", true);
|
2023-05-31 22:22:23 +02:00
|
|
|
timestamp = getValue<QString>(json, "timestamp");
|
|
|
|
type = getValue<QString>(json, "type");
|
2022-08-26 02:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ClientAPI::Conversation::Conversation() {}
|
|
|
|
ClientAPI::Conversation::Conversation(const QJsonObject& json) : lastMessage(nullptr) {
|
2023-05-31 22:22:23 +02:00
|
|
|
gameName = getValue<QString>(json, "gameName");
|
|
|
|
gameTag = getValue<QString>(json, "gameTag");
|
|
|
|
id = getValue<QString>(json, "id");
|
2022-08-26 02:12:25 +02:00
|
|
|
isMuted = getValue<bool>(json, "isMuted");
|
2023-05-31 22:22:23 +02:00
|
|
|
name = getValue<QString>(json, "name");
|
|
|
|
password = getValue<QString>(json, "password");
|
|
|
|
pid = getValue<QString>(json, "pid");
|
|
|
|
targetRegion = getValue<QString>(json, "targetRegion");
|
|
|
|
type = getValue<QString>(json, "type");
|
2022-08-26 02:12:25 +02:00
|
|
|
unreadMessageCount = getValue<int64_t>(json, "unreadMessageCount");
|
|
|
|
|
|
|
|
auto msgref = json["lastMessage"];
|
|
|
|
if(msgref.isObject()) {
|
|
|
|
lastMessage = std::make_shared<Message>(msgref.toObject());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-07-02 12:36:38 +02:00
|
|
|
#define PRINTENUM(ENUMNAME) \
|
|
|
|
std::ostream& operator<<(std::ostream& str, const ClientAPI:: ENUMNAME & state) { \
|
2023-05-31 22:22:23 +02:00
|
|
|
assert(((uint32_t) state) < ENUMNAME ## NamesCount); \
|
|
|
|
return str << ENUMNAME ## Names[(uint32_t) state].toStdString() << " (" << (uint32_t) state << ')'; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
QDebug operator<<(QDebug str, const ClientAPI:: ENUMNAME & state) { \
|
2022-08-26 02:12:25 +02:00
|
|
|
assert(((uint32_t) state) < ENUMNAME ## NamesCount); \
|
|
|
|
return str << ENUMNAME ## Names[(uint32_t) state] << " (" << (uint32_t) state << ')'; \
|
2022-07-02 12:36:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRINTENUM(ReadyCheckState)
|
|
|
|
PRINTENUM(GameflowPhase)
|
|
|
|
PRINTENUM(ChampSelectPhase)
|
|
|
|
PRINTENUM(ChampSelectActionType)
|
2022-07-04 00:30:00 +02:00
|
|
|
|
2022-08-26 02:12:25 +02:00
|
|
|
// not using macro because its not in ClientAPI
|
|
|
|
std::ostream& operator<<(std::ostream& str, const Position & state) {
|
2023-05-31 22:22:23 +02:00
|
|
|
assert(((uint32_t) state) < PositionNamesCount);
|
|
|
|
return str << PositionNames[(uint32_t) state].toStdString() << " (" << (uint32_t) state << ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
QDebug operator<<(QDebug str, const Position & state) {
|
2022-08-26 02:12:25 +02:00
|
|
|
assert(((uint32_t) state) < PositionNamesCount);
|
|
|
|
return str << PositionNames[(uint32_t) state] << " (" << (uint32_t) state << ')';
|
2022-07-04 00:30:00 +02:00
|
|
|
}
|