mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Store and send mod list and game version for game rooms
This commit is contained in:
parent
6ba6e0d55b
commit
e5f8cefa7f
@ -201,6 +201,8 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
|
|||||||
room.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String();
|
room.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String();
|
||||||
room.description = jsonEntry["description"].String();
|
room.description = jsonEntry["description"].String();
|
||||||
room.statusID = jsonEntry["status"].String();
|
room.statusID = jsonEntry["status"].String();
|
||||||
|
room.gameVersion = jsonEntry["version"].String();
|
||||||
|
room.modList = ModVerificationInfo::jsonDeserializeList(jsonEntry["mods"]);
|
||||||
std::chrono::seconds ageSeconds (jsonEntry["ageSeconds"].Integer());
|
std::chrono::seconds ageSeconds (jsonEntry["ageSeconds"].Integer());
|
||||||
room.startDateFormatted = TextOperations::getCurrentFormattedDateTimeLocal(-ageSeconds);
|
room.startDateFormatted = TextOperations::getCurrentFormattedDateTimeLocal(-ageSeconds);
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../lib/modding/ModVerificationInfo.h"
|
||||||
|
|
||||||
struct GlobalLobbyAccount
|
struct GlobalLobbyAccount
|
||||||
{
|
{
|
||||||
std::string accountID;
|
std::string accountID;
|
||||||
@ -22,8 +24,10 @@ struct GlobalLobbyRoom
|
|||||||
std::string hostAccountID;
|
std::string hostAccountID;
|
||||||
std::string hostAccountDisplayName;
|
std::string hostAccountDisplayName;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
std::string gameVersion;
|
||||||
std::string statusID;
|
std::string statusID;
|
||||||
std::string startDateFormatted;
|
std::string startDateFormatted;
|
||||||
|
ModCompatibilityInfo modList;
|
||||||
std::vector<GlobalLobbyAccount> participants;
|
std::vector<GlobalLobbyAccount> participants;
|
||||||
int playerLimit;
|
int playerLimit;
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"additionalProperties" : false,
|
"additionalProperties" : false,
|
||||||
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "participants", "playerLimit", "status", "ageSeconds" ],
|
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "participants", "playerLimit", "status", "ageSeconds", "mods", "version" ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"gameRoomID" :
|
"gameRoomID" :
|
||||||
{
|
{
|
||||||
@ -65,6 +65,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mods" :
|
||||||
|
{
|
||||||
|
"type" : "array",
|
||||||
|
"description" : "List of gameplay-affecting mods active on server",
|
||||||
|
"items" : {
|
||||||
|
"type" : "object",
|
||||||
|
"additionalProperties" : false,
|
||||||
|
"required" : [ "modId", "name", "version" ],
|
||||||
|
"properties" : {
|
||||||
|
"modId" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Unique identifier of the mod"
|
||||||
|
},
|
||||||
|
"name" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Human-readable name of the mod"
|
||||||
|
},
|
||||||
|
"parent" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Unique ID of parent mod, only for submods"
|
||||||
|
},
|
||||||
|
"version" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Version of mod, as specified in mod config"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
"status" :
|
"status" :
|
||||||
{
|
{
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
@ -78,6 +110,11 @@
|
|||||||
"maximum" : 8,
|
"maximum" : 8,
|
||||||
"description" : "Maximum number of players that can join this room, including host"
|
"description" : "Maximum number of players that can join this room, including host"
|
||||||
},
|
},
|
||||||
|
"version" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Version of match server, e.g. 1.5.0"
|
||||||
|
},
|
||||||
"ageSeconds" :
|
"ageSeconds" :
|
||||||
{
|
{
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
|
@ -32,6 +32,38 @@
|
|||||||
{
|
{
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "Version of match server, e.g. 1.5.0"
|
"description" : "Version of match server, e.g. 1.5.0"
|
||||||
|
},
|
||||||
|
"mods" :
|
||||||
|
{
|
||||||
|
"type" : "array",
|
||||||
|
"description" : "List of gameplay-affecting mods active on server",
|
||||||
|
"items" : {
|
||||||
|
"type" : "object",
|
||||||
|
"additionalProperties" : false,
|
||||||
|
"required" : [ "modId", "name", "version" ],
|
||||||
|
"properties" : {
|
||||||
|
"modId" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Unique identifier of the mod"
|
||||||
|
},
|
||||||
|
"name" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Human-readable name of the mod"
|
||||||
|
},
|
||||||
|
"parent" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Unique ID of parent mod, only for submods"
|
||||||
|
},
|
||||||
|
"version" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"description" : "Version of mod, as specified in mod config"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ JsonNode ModVerificationInfo::jsonSerializeList(const ModCompatibilityInfo & inp
|
|||||||
JsonNode modWriter;
|
JsonNode modWriter;
|
||||||
modWriter["modId"].String() = mod.first;
|
modWriter["modId"].String() = mod.first;
|
||||||
modWriter["name"].String() = mod.second.name;
|
modWriter["name"].String() = mod.second.name;
|
||||||
|
if (!mod.second.parent.empty())
|
||||||
modWriter["parent"].String() = mod.second.parent;
|
modWriter["parent"].String() = mod.second.parent;
|
||||||
modWriter["version"].String() = mod.second.version.toString();
|
modWriter["version"].String() = mod.second.version.toString();
|
||||||
output.Vector().push_back(modWriter);
|
output.Vector().push_back(modWriter);
|
||||||
|
@ -17,7 +17,7 @@ class JsonNode;
|
|||||||
struct ModVerificationInfo;
|
struct ModVerificationInfo;
|
||||||
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
|
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
|
||||||
|
|
||||||
struct ModVerificationInfo
|
struct DLL_LINKAGE ModVerificationInfo
|
||||||
{
|
{
|
||||||
/// human-readable mod name
|
/// human-readable mod name
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -33,7 +33,8 @@ void LobbyDatabase::createTables()
|
|||||||
description TEXT NOT NULL DEFAULT '',
|
description TEXT NOT NULL DEFAULT '',
|
||||||
status INTEGER NOT NULL DEFAULT 0,
|
status INTEGER NOT NULL DEFAULT 0,
|
||||||
playerLimit INTEGER NOT NULL,
|
playerLimit INTEGER NOT NULL,
|
||||||
creationTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
creationTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
mods TEXT NOT NULL DEFAULT '[]'
|
||||||
);
|
);
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@ -81,6 +82,32 @@ void LobbyDatabase::createTables()
|
|||||||
database->prepare(createTableGameRoomInvites)->execute();
|
database->prepare(createTableGameRoomInvites)->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LobbyDatabase::upgradeDatabase()
|
||||||
|
{
|
||||||
|
auto getDatabaseVersionStatement = database->prepare(R"(
|
||||||
|
PRAGMA schema.user_version
|
||||||
|
)");
|
||||||
|
|
||||||
|
auto setDatabaseVersionStatement = database->prepare(R"(
|
||||||
|
PRAGMA schema.user_version = ?
|
||||||
|
)");
|
||||||
|
|
||||||
|
int databaseVersion;
|
||||||
|
getDatabaseVersionStatement->execute();
|
||||||
|
getDatabaseVersionStatement->getColumns(databaseVersion);
|
||||||
|
|
||||||
|
if (databaseVersion < 10501)
|
||||||
|
{
|
||||||
|
database->prepare(R"(
|
||||||
|
ALTER TABLE gameRooms
|
||||||
|
ADD COLUMN version TEXT NOT NULL DEFAULT ''
|
||||||
|
ADD COLUMN mods TEXT NOT NULL DEFAULT '{}'
|
||||||
|
)")->execute();
|
||||||
|
|
||||||
|
setDatabaseVersionStatement->executeOnce(10501);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LobbyDatabase::clearOldData()
|
void LobbyDatabase::clearOldData()
|
||||||
{
|
{
|
||||||
static const std::string removeActiveAccounts = R"(
|
static const std::string removeActiveAccounts = R"(
|
||||||
@ -122,7 +149,7 @@ void LobbyDatabase::prepareStatements()
|
|||||||
)");
|
)");
|
||||||
|
|
||||||
insertGameRoomStatement = database->prepare(R"(
|
insertGameRoomStatement = database->prepare(R"(
|
||||||
INSERT INTO gameRooms(roomID, hostAccountID, status, playerLimit) VALUES(?, ?, 0, 8);
|
INSERT INTO gameRooms(roomID, hostAccountID, status, playerLimit, version, mods) VALUES(?, ?, 0, 8, ?, ?);
|
||||||
)");
|
)");
|
||||||
|
|
||||||
insertGameRoomPlayersStatement = database->prepare(R"(
|
insertGameRoomPlayersStatement = database->prepare(R"(
|
||||||
@ -233,7 +260,7 @@ void LobbyDatabase::prepareStatements()
|
|||||||
)");
|
)");
|
||||||
|
|
||||||
getActiveGameRoomsStatement = database->prepare(R"(
|
getActiveGameRoomsStatement = database->prepare(R"(
|
||||||
SELECT roomID, hostAccountID, displayName, description, status, playerLimit, strftime('%s',CURRENT_TIMESTAMP)- strftime('%s',gr.creationTime) AS secondsElapsed
|
SELECT roomID, hostAccountID, displayName, description, status, playerLimit, mods, strftime('%s',CURRENT_TIMESTAMP)- strftime('%s',gr.creationTime) AS secondsElapsed
|
||||||
FROM gameRooms gr
|
FROM gameRooms gr
|
||||||
LEFT JOIN accounts a ON gr.hostAccountID = a.accountID
|
LEFT JOIN accounts a ON gr.hostAccountID = a.accountID
|
||||||
WHERE status IN (1, 2, 3)
|
WHERE status IN (1, 2, 3)
|
||||||
@ -298,6 +325,7 @@ LobbyDatabase::LobbyDatabase(const boost::filesystem::path & databasePath)
|
|||||||
{
|
{
|
||||||
database = SQLiteInstance::open(databasePath, true);
|
database = SQLiteInstance::open(databasePath, true);
|
||||||
createTables();
|
createTables();
|
||||||
|
upgradeDatabase();
|
||||||
clearOldData();
|
clearOldData();
|
||||||
prepareStatements();
|
prepareStatements();
|
||||||
}
|
}
|
||||||
@ -393,9 +421,9 @@ void LobbyDatabase::insertGameRoomInvite(const std::string & targetAccountID, co
|
|||||||
insertGameRoomInvitesStatement->executeOnce(roomID, targetAccountID);
|
insertGameRoomInvitesStatement->executeOnce(roomID, targetAccountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LobbyDatabase::insertGameRoom(const std::string & roomID, const std::string & hostAccountID)
|
void LobbyDatabase::insertGameRoom(const std::string & roomID, const std::string & hostAccountID, const std::string & serverVersion, const std::string & modListJson)
|
||||||
{
|
{
|
||||||
insertGameRoomStatement->executeOnce(roomID, hostAccountID);
|
insertGameRoomStatement->executeOnce(roomID, hostAccountID, serverVersion, modListJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LobbyDatabase::insertAccount(const std::string & accountID, const std::string & displayName)
|
void LobbyDatabase::insertAccount(const std::string & accountID, const std::string & displayName)
|
||||||
@ -526,7 +554,7 @@ std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
|
|||||||
while(getActiveGameRoomsStatement->execute())
|
while(getActiveGameRoomsStatement->execute())
|
||||||
{
|
{
|
||||||
LobbyGameRoom entry;
|
LobbyGameRoom entry;
|
||||||
getActiveGameRoomsStatement->getColumns(entry.roomID, entry.hostAccountID, entry.hostAccountDisplayName, entry.description, entry.roomState, entry.playerLimit, entry.age);
|
getActiveGameRoomsStatement->getColumns(entry.roomID, entry.hostAccountID, entry.hostAccountDisplayName, entry.description, entry.roomState, entry.playerLimit, entry.version, entry.modsJson, entry.age);
|
||||||
result.push_back(entry);
|
result.push_back(entry);
|
||||||
}
|
}
|
||||||
getActiveGameRoomsStatement->reset();
|
getActiveGameRoomsStatement->reset();
|
||||||
|
@ -59,6 +59,7 @@ class LobbyDatabase
|
|||||||
|
|
||||||
void prepareStatements();
|
void prepareStatements();
|
||||||
void createTables();
|
void createTables();
|
||||||
|
void upgradeDatabase();
|
||||||
void clearOldData();
|
void clearOldData();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -74,7 +75,7 @@ public:
|
|||||||
void deleteGameRoomInvite(const std::string & targetAccountID, const std::string & roomID);
|
void deleteGameRoomInvite(const std::string & targetAccountID, const std::string & roomID);
|
||||||
void insertGameRoomInvite(const std::string & targetAccountID, const std::string & roomID);
|
void insertGameRoomInvite(const std::string & targetAccountID, const std::string & roomID);
|
||||||
|
|
||||||
void insertGameRoom(const std::string & roomID, const std::string & hostAccountID);
|
void insertGameRoom(const std::string & roomID, const std::string & hostAccountID, const std::string & serverVersion, const std::string & modListJson);
|
||||||
void insertAccount(const std::string & accountID, const std::string & displayName);
|
void insertAccount(const std::string & accountID, const std::string & displayName);
|
||||||
void insertAccessCookie(const std::string & accountID, const std::string & accessCookieUUID);
|
void insertAccessCookie(const std::string & accountID, const std::string & accessCookieUUID);
|
||||||
void insertChatMessage(const std::string & sender, const std::string & channelType, const std::string & roomID, const std::string & messageText);
|
void insertChatMessage(const std::string & sender, const std::string & channelType, const std::string & roomID, const std::string & messageText);
|
||||||
|
@ -44,6 +44,8 @@ struct LobbyGameRoom
|
|||||||
std::string hostAccountID;
|
std::string hostAccountID;
|
||||||
std::string hostAccountDisplayName;
|
std::string hostAccountDisplayName;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
std::string version;
|
||||||
|
std::string modsJson;
|
||||||
std::vector<LobbyAccount> participants;
|
std::vector<LobbyAccount> participants;
|
||||||
LobbyRoomState roomState;
|
LobbyRoomState roomState;
|
||||||
uint32_t playerLimit;
|
uint32_t playerLimit;
|
||||||
|
@ -208,9 +208,11 @@ static JsonNode loadLobbyGameRoomToJson(const LobbyGameRoom & gameRoom)
|
|||||||
jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID;
|
jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID;
|
||||||
jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName;
|
jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName;
|
||||||
jsonEntry["description"].String() = gameRoom.description;
|
jsonEntry["description"].String() = gameRoom.description;
|
||||||
|
jsonEntry["version"].String() = gameRoom.version;
|
||||||
jsonEntry["status"].String() = LOBBY_ROOM_STATE_NAMES[vstd::to_underlying(gameRoom.roomState)];
|
jsonEntry["status"].String() = LOBBY_ROOM_STATE_NAMES[vstd::to_underlying(gameRoom.roomState)];
|
||||||
jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit;
|
jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit;
|
||||||
jsonEntry["ageSeconds"].Integer() = gameRoom.age.count();
|
jsonEntry["ageSeconds"].Integer() = gameRoom.age.count();
|
||||||
|
jsonEntry["mods"] = JsonNode(reinterpret_cast<const std::byte *>(gameRoom.modsJson.data()), gameRoom.modsJson.size());
|
||||||
|
|
||||||
for(const auto & account : gameRoom.participants)
|
for(const auto & account : gameRoom.participants)
|
||||||
jsonEntry["participants"].Vector().push_back(loadLobbyAccountToJson(account));
|
jsonEntry["participants"].Vector().push_back(loadLobbyAccountToJson(account));
|
||||||
@ -625,7 +627,8 @@ void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, co
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
database->insertGameRoom(gameRoomID, accountID);
|
std::string modListString = json["mods"].isNull() ? "[]" : json["mods"].toCompactString();
|
||||||
|
database->insertGameRoom(gameRoomID, accountID, version, modListString);
|
||||||
activeGameRooms[connection] = gameRoomID;
|
activeGameRooms[connection] = gameRoomID;
|
||||||
sendServerLoginSuccess(connection, accountCookie);
|
sendServerLoginSuccess(connection, accountCookie);
|
||||||
broadcastActiveGameRooms();
|
broadcastActiveGameRooms();
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include "CVCMIServer.h"
|
#include "CVCMIServer.h"
|
||||||
#include "../lib/CConfigHandler.h"
|
#include "../lib/CConfigHandler.h"
|
||||||
#include "../lib/json/JsonUtils.h"
|
#include "../lib/json/JsonUtils.h"
|
||||||
|
#include "../lib/VCMI_Lib.h"
|
||||||
|
#include "../lib/modding/CModHandler.h"
|
||||||
|
#include "../lib/modding/CModInfo.h"
|
||||||
|
|
||||||
GlobalLobbyProcessor::GlobalLobbyProcessor(CVCMIServer & owner)
|
GlobalLobbyProcessor::GlobalLobbyProcessor(CVCMIServer & owner)
|
||||||
: owner(owner)
|
: owner(owner)
|
||||||
@ -125,6 +128,7 @@ void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetwor
|
|||||||
toSend["accountID"].String() = getHostAccountID();
|
toSend["accountID"].String() = getHostAccountID();
|
||||||
toSend["accountCookie"].String() = getHostAccountCookie();
|
toSend["accountCookie"].String() = getHostAccountCookie();
|
||||||
toSend["version"].String() = VCMI_VERSION_STRING;
|
toSend["version"].String() = VCMI_VERSION_STRING;
|
||||||
|
toSend["mods"] = getHostModList();
|
||||||
|
|
||||||
sendMessage(connection, toSend);
|
sendMessage(connection, toSend);
|
||||||
}
|
}
|
||||||
@ -149,6 +153,19 @@ void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetwor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonNode GlobalLobbyProcessor::getHostModList() const
|
||||||
|
{
|
||||||
|
ModCompatibilityInfo info;
|
||||||
|
|
||||||
|
for (auto const & modName : VLC->modh->getActiveMods())
|
||||||
|
{
|
||||||
|
if(VLC->modh->getModInfo(modName).checkModGameplayAffecting())
|
||||||
|
info[modName] = VLC->modh->getModInfo(modName).getVerificationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ModVerificationInfo::jsonSerializeList(info);
|
||||||
|
}
|
||||||
|
|
||||||
void GlobalLobbyProcessor::sendGameStarted()
|
void GlobalLobbyProcessor::sendGameStarted()
|
||||||
{
|
{
|
||||||
JsonNode toSend;
|
JsonNode toSend;
|
||||||
|
@ -36,6 +36,7 @@ class GlobalLobbyProcessor : public INetworkClientListener
|
|||||||
void establishNewConnection();
|
void establishNewConnection();
|
||||||
void sendMessage(const NetworkConnectionPtr & targetConnection, const JsonNode & payload);
|
void sendMessage(const NetworkConnectionPtr & targetConnection, const JsonNode & payload);
|
||||||
|
|
||||||
|
JsonNode getHostModList() const;
|
||||||
const std::string & getHostAccountID() const;
|
const std::string & getHostAccountID() const;
|
||||||
const std::string & getHostAccountCookie() const;
|
const std::string & getHostAccountCookie() const;
|
||||||
const std::string & getHostAccountDisplayName() const;
|
const std::string & getHostAccountDisplayName() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user