mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-21 17:17:06 +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.description = jsonEntry["description"].String();
|
||||
room.statusID = jsonEntry["status"].String();
|
||||
room.gameVersion = jsonEntry["version"].String();
|
||||
room.modList = ModVerificationInfo::jsonDeserializeList(jsonEntry["mods"]);
|
||||
std::chrono::seconds ageSeconds (jsonEntry["ageSeconds"].Integer());
|
||||
room.startDateFormatted = TextOperations::getCurrentFormattedDateTimeLocal(-ageSeconds);
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../lib/modding/ModVerificationInfo.h"
|
||||
|
||||
struct GlobalLobbyAccount
|
||||
{
|
||||
std::string accountID;
|
||||
@ -22,8 +24,10 @@ struct GlobalLobbyRoom
|
||||
std::string hostAccountID;
|
||||
std::string hostAccountDisplayName;
|
||||
std::string description;
|
||||
std::string gameVersion;
|
||||
std::string statusID;
|
||||
std::string startDateFormatted;
|
||||
ModCompatibilityInfo modList;
|
||||
std::vector<GlobalLobbyAccount> participants;
|
||||
int playerLimit;
|
||||
};
|
||||
|
@ -20,7 +20,7 @@
|
||||
{
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "participants", "playerLimit", "status", "ageSeconds" ],
|
||||
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "participants", "playerLimit", "status", "ageSeconds", "mods", "version" ],
|
||||
"properties" : {
|
||||
"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" :
|
||||
{
|
||||
"type" : "string",
|
||||
@ -78,6 +110,11 @@
|
||||
"maximum" : 8,
|
||||
"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" :
|
||||
{
|
||||
"type" : "number",
|
||||
|
@ -32,6 +32,38 @@
|
||||
{
|
||||
"type" : "string",
|
||||
"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,7 +21,8 @@ JsonNode ModVerificationInfo::jsonSerializeList(const ModCompatibilityInfo & inp
|
||||
JsonNode modWriter;
|
||||
modWriter["modId"].String() = mod.first;
|
||||
modWriter["name"].String() = mod.second.name;
|
||||
modWriter["parent"].String() = mod.second.parent;
|
||||
if (!mod.second.parent.empty())
|
||||
modWriter["parent"].String() = mod.second.parent;
|
||||
modWriter["version"].String() = mod.second.version.toString();
|
||||
output.Vector().push_back(modWriter);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class JsonNode;
|
||||
struct ModVerificationInfo;
|
||||
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
|
||||
|
||||
struct ModVerificationInfo
|
||||
struct DLL_LINKAGE ModVerificationInfo
|
||||
{
|
||||
/// human-readable mod name
|
||||
std::string name;
|
||||
|
@ -33,7 +33,8 @@ void LobbyDatabase::createTables()
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
status INTEGER NOT NULL DEFAULT 0,
|
||||
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();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
static const std::string removeActiveAccounts = R"(
|
||||
@ -122,7 +149,7 @@ void LobbyDatabase::prepareStatements()
|
||||
)");
|
||||
|
||||
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"(
|
||||
@ -233,7 +260,7 @@ void LobbyDatabase::prepareStatements()
|
||||
)");
|
||||
|
||||
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
|
||||
LEFT JOIN accounts a ON gr.hostAccountID = a.accountID
|
||||
WHERE status IN (1, 2, 3)
|
||||
@ -298,6 +325,7 @@ LobbyDatabase::LobbyDatabase(const boost::filesystem::path & databasePath)
|
||||
{
|
||||
database = SQLiteInstance::open(databasePath, true);
|
||||
createTables();
|
||||
upgradeDatabase();
|
||||
clearOldData();
|
||||
prepareStatements();
|
||||
}
|
||||
@ -393,9 +421,9 @@ void LobbyDatabase::insertGameRoomInvite(const std::string & targetAccountID, co
|
||||
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)
|
||||
@ -526,7 +554,7 @@ std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
|
||||
while(getActiveGameRoomsStatement->execute())
|
||||
{
|
||||
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);
|
||||
}
|
||||
getActiveGameRoomsStatement->reset();
|
||||
|
@ -59,6 +59,7 @@ class LobbyDatabase
|
||||
|
||||
void prepareStatements();
|
||||
void createTables();
|
||||
void upgradeDatabase();
|
||||
void clearOldData();
|
||||
|
||||
public:
|
||||
@ -74,7 +75,7 @@ public:
|
||||
void deleteGameRoomInvite(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 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);
|
||||
|
@ -44,6 +44,8 @@ struct LobbyGameRoom
|
||||
std::string hostAccountID;
|
||||
std::string hostAccountDisplayName;
|
||||
std::string description;
|
||||
std::string version;
|
||||
std::string modsJson;
|
||||
std::vector<LobbyAccount> participants;
|
||||
LobbyRoomState roomState;
|
||||
uint32_t playerLimit;
|
||||
|
@ -208,9 +208,11 @@ static JsonNode loadLobbyGameRoomToJson(const LobbyGameRoom & gameRoom)
|
||||
jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID;
|
||||
jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName;
|
||||
jsonEntry["description"].String() = gameRoom.description;
|
||||
jsonEntry["version"].String() = gameRoom.version;
|
||||
jsonEntry["status"].String() = LOBBY_ROOM_STATE_NAMES[vstd::to_underlying(gameRoom.roomState)];
|
||||
jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit;
|
||||
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)
|
||||
jsonEntry["participants"].Vector().push_back(loadLobbyAccountToJson(account));
|
||||
@ -625,7 +627,8 @@ void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, co
|
||||
}
|
||||
else
|
||||
{
|
||||
database->insertGameRoom(gameRoomID, accountID);
|
||||
std::string modListString = json["mods"].isNull() ? "[]" : json["mods"].toCompactString();
|
||||
database->insertGameRoom(gameRoomID, accountID, version, modListString);
|
||||
activeGameRooms[connection] = gameRoomID;
|
||||
sendServerLoginSuccess(connection, accountCookie);
|
||||
broadcastActiveGameRooms();
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "CVCMIServer.h"
|
||||
#include "../lib/CConfigHandler.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)
|
||||
: owner(owner)
|
||||
@ -125,6 +128,7 @@ void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetwor
|
||||
toSend["accountID"].String() = getHostAccountID();
|
||||
toSend["accountCookie"].String() = getHostAccountCookie();
|
||||
toSend["version"].String() = VCMI_VERSION_STRING;
|
||||
toSend["mods"] = getHostModList();
|
||||
|
||||
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()
|
||||
{
|
||||
JsonNode toSend;
|
||||
|
@ -36,6 +36,7 @@ class GlobalLobbyProcessor : public INetworkClientListener
|
||||
void establishNewConnection();
|
||||
void sendMessage(const NetworkConnectionPtr & targetConnection, const JsonNode & payload);
|
||||
|
||||
JsonNode getHostModList() const;
|
||||
const std::string & getHostAccountID() const;
|
||||
const std::string & getHostAccountCookie() const;
|
||||
const std::string & getHostAccountDisplayName() const;
|
||||
|
Loading…
Reference in New Issue
Block a user