mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-10 16:24:45 -07:00
Merge branch 'devel' into servernetwork
This commit is contained in:
commit
6bbc76af2b
39 changed files with 658 additions and 147 deletions
|
|
@ -30,6 +30,7 @@
|
|||
#include "main.h"
|
||||
#include "passwordhasher.h"
|
||||
#include "pb/game_replay.pb.h"
|
||||
#include "pb/event_replay_added.pb.h"
|
||||
#include "pb/event_server_message.pb.h"
|
||||
#include "pb/event_server_shutdown.pb.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
|
|
@ -203,6 +204,15 @@ bool Servatrice::openDatabase()
|
|||
nextGameId = query.value(0).toInt() + 1;
|
||||
qDebug() << "set nextGameId to " << nextGameId;
|
||||
}
|
||||
if (!nextReplayId) {
|
||||
QSqlQuery query;
|
||||
if (!query.exec("select max(id) from " + dbPrefix + "_replays"))
|
||||
return false;
|
||||
if (!query.next())
|
||||
return false;
|
||||
nextReplayId = query.value(0).toInt() + 1;
|
||||
qDebug() << "set nextReplayId to " << nextReplayId;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -582,43 +592,32 @@ void Servatrice::statusUpdate()
|
|||
execSqlQuery(query);
|
||||
}
|
||||
|
||||
void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const GameReplay &replay)
|
||||
void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replayList)
|
||||
{
|
||||
Server_Room *room = rooms.value(replay.game_info().room_id());
|
||||
const ServerInfo_Game &gameInfo = replayList.first()->game_info();
|
||||
|
||||
Server_Room *room = rooms.value(gameInfo.room_id());
|
||||
|
||||
Event_ReplayAdded replayEvent;
|
||||
ServerInfo_ReplayMatch *replayMatchInfo = replayEvent.mutable_match_info();
|
||||
replayMatchInfo->set_game_id(gameInfo.game_id());
|
||||
replayMatchInfo->set_room_name(room->getName().toStdString());
|
||||
replayMatchInfo->set_time_started(QDateTime::currentDateTime().addSecs(-secondsElapsed).toTime_t());
|
||||
replayMatchInfo->set_length(secondsElapsed);
|
||||
replayMatchInfo->set_game_name(gameInfo.description());
|
||||
|
||||
const QStringList &allGameTypes = room->getGameTypes();
|
||||
QStringList gameTypes;
|
||||
for (int i = replay.game_info().game_types_size() - 1; i >= 0; --i)
|
||||
gameTypes.append(allGameTypes[replay.game_info().game_types(i)]);
|
||||
|
||||
QByteArray replayBlob;
|
||||
const unsigned int size = replay.ByteSize();
|
||||
replayBlob.resize(size);
|
||||
replay.SerializeToArray(replayBlob.data(), size);
|
||||
|
||||
QMutexLocker locker(&dbMutex);
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("insert into " + dbPrefix + "_games (room_name, id, descr, creator_name, password, game_types, player_count, time_started, time_finished, replay) values (:id_room, :id_game, :descr, :creator_name, :password, :game_types, :player_count, date_sub(now(), interval :seconds second), now(), :replay)");
|
||||
query1.bindValue(":room_name", room->getName());
|
||||
query1.bindValue(":id_game", replay.game_info().game_id());
|
||||
query1.bindValue(":descr", QString::fromStdString(replay.game_info().description()));
|
||||
query1.bindValue(":creator_name", QString::fromStdString(replay.game_info().creator_info().name()));
|
||||
query1.bindValue(":password", replay.game_info().with_password() ? 1 : 0);
|
||||
query1.bindValue(":game_types", gameTypes.isEmpty() ? QString("") : gameTypes.join(", "));
|
||||
query1.bindValue(":player_count", replay.game_info().max_players());
|
||||
query1.bindValue(":seconds", secondsElapsed);
|
||||
query1.bindValue(":replay", replayBlob);
|
||||
if (!execSqlQuery(query1))
|
||||
return;
|
||||
for (int i = gameInfo.game_types_size() - 1; i >= 0; --i)
|
||||
gameTypes.append(allGameTypes[gameInfo.game_types(i)]);
|
||||
|
||||
QVariantList gameIds1, playerNames, gameIds2, userIds, replayNames;
|
||||
QSetIterator<QString> playerIterator(allPlayersEver);
|
||||
while (playerIterator.hasNext()) {
|
||||
gameIds1.append(replay.game_info().game_id());
|
||||
playerNames.append(playerIterator.next());
|
||||
gameIds1.append(gameInfo.game_id());
|
||||
const QString &playerName = playerIterator.next();
|
||||
playerNames.append(playerName);
|
||||
replayMatchInfo->add_player_names(playerName.toStdString());
|
||||
}
|
||||
QSet<QString> allUsersInGame = allPlayersEver + allSpectatorsEver;
|
||||
QSetIterator<QString> allUsersIterator(allUsersInGame);
|
||||
|
|
@ -626,17 +625,71 @@ void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &a
|
|||
int id = getUserIdInDB(allUsersIterator.next());
|
||||
if (id == -1)
|
||||
continue;
|
||||
gameIds2.append(replay.game_info().game_id());
|
||||
gameIds2.append(gameInfo.game_id());
|
||||
userIds.append(id);
|
||||
replayNames.append(QString::fromStdString(replay.game_info().description()));
|
||||
replayNames.append(QString::fromStdString(gameInfo.description()));
|
||||
}
|
||||
|
||||
QVariantList replayIds, replayGameIds, replayDurations, replayBlobs;
|
||||
for (int i = 0; i < replayList.size(); ++i) {
|
||||
QByteArray blob;
|
||||
const unsigned int size = replayList[i]->ByteSize();
|
||||
blob.resize(size);
|
||||
replayList[i]->SerializeToArray(blob.data(), size);
|
||||
|
||||
replayIds.append(QVariant((qulonglong) replayList[i]->replay_id()));
|
||||
replayGameIds.append(gameInfo.game_id());
|
||||
replayDurations.append(replayList[i]->duration_seconds());
|
||||
replayBlobs.append(blob);
|
||||
|
||||
ServerInfo_Replay *replayInfo = replayMatchInfo->add_replay_list();
|
||||
replayInfo->set_replay_id(replayList[i]->replay_id());
|
||||
replayInfo->set_replay_name(gameInfo.description());
|
||||
replayInfo->set_duration(replayList[i]->duration_seconds());
|
||||
}
|
||||
|
||||
SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent);
|
||||
allUsersIterator.toFront();
|
||||
serverMutex.lock();
|
||||
while (allUsersIterator.hasNext()) {
|
||||
Server_ProtocolHandler *userHandler = users.value(allUsersIterator.next());
|
||||
if (userHandler)
|
||||
userHandler->sendProtocolItem(*sessionEvent);
|
||||
}
|
||||
serverMutex.unlock();
|
||||
delete sessionEvent;
|
||||
|
||||
QMutexLocker locker(&dbMutex);
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("insert into " + dbPrefix + "_games (room_name, id, descr, creator_name, password, game_types, player_count, time_started, time_finished) values (:id_room, :id_game, :descr, :creator_name, :password, :game_types, :player_count, date_sub(now(), interval :seconds second), now())");
|
||||
query1.bindValue(":room_name", room->getName());
|
||||
query1.bindValue(":id_game", gameInfo.game_id());
|
||||
query1.bindValue(":descr", QString::fromStdString(gameInfo.description()));
|
||||
query1.bindValue(":creator_name", QString::fromStdString(gameInfo.creator_info().name()));
|
||||
query1.bindValue(":password", gameInfo.with_password() ? 1 : 0);
|
||||
query1.bindValue(":game_types", gameTypes.isEmpty() ? QString("") : gameTypes.join(", "));
|
||||
query1.bindValue(":player_count", gameInfo.max_players());
|
||||
query1.bindValue(":seconds", secondsElapsed);
|
||||
if (!execSqlQuery(query1))
|
||||
return;
|
||||
|
||||
QSqlQuery query2;
|
||||
query2.prepare("insert into " + dbPrefix + "_games_players (id_game, player_name) values (:id_game, :player_name)");
|
||||
query2.bindValue(":id_game", gameIds1);
|
||||
query2.bindValue(":player_name", playerNames);
|
||||
query2.execBatch();
|
||||
|
||||
QSqlQuery replayQuery1;
|
||||
replayQuery1.prepare("insert into " + dbPrefix + "_replays (id, id_game, duration, replay) values (:id_replay, :id_game, :duration, :replay)");
|
||||
replayQuery1.bindValue(":id_replay", replayIds);
|
||||
replayQuery1.bindValue(":id_game", replayGameIds);
|
||||
replayQuery1.bindValue(":duration", replayDurations);
|
||||
replayQuery1.bindValue(":replay", replayBlobs);
|
||||
replayQuery1.execBatch();
|
||||
|
||||
QSqlQuery query3;
|
||||
query3.prepare("insert into " + dbPrefix + "_replays_access (id_game, id_player, replay_name) values (:id_game, :id_player, :replay_name)");
|
||||
query3.bindValue(":id_game", gameIds2);
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public:
|
|||
void incTxBytes(quint64 num);
|
||||
void incRxBytes(quint64 num);
|
||||
int getUserIdInDB(const QString &name);
|
||||
void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const GameReplay &replay);
|
||||
void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays);
|
||||
protected:
|
||||
int startSession(const QString &userName, const QString &address);
|
||||
void endSession(int sessionId);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "pb/command_deck_del.pb.h"
|
||||
#include "pb/command_replay_list.pb.h"
|
||||
#include "pb/command_replay_download.pb.h"
|
||||
#include "pb/command_replay_modify_match.pb.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
#include "pb/event_server_message.pb.h"
|
||||
#include "pb/event_server_identification.pb.h"
|
||||
|
|
@ -499,27 +500,40 @@ Response::ResponseCode ServerSocketInterface::cmdReplayList(const Command_Replay
|
|||
|
||||
servatrice->dbMutex.lock();
|
||||
QSqlQuery query1;
|
||||
query1.prepare("select a.id_game, a.replay_name, b.room_name, b.time_started, b.time_finished, b.descr from cockatrice_replays_access a left join cockatrice_games b on b.id = a.id_game where a.id_player = :id_player");
|
||||
query1.prepare("select a.id_game, a.replay_name, b.room_name, b.time_started, b.time_finished, b.descr, a.do_not_hide from cockatrice_replays_access a left join cockatrice_games b on b.id = a.id_game where a.id_player = :id_player and (a.do_not_hide = 1 or date_add(b.time_started, interval 14 day) > now())");
|
||||
query1.bindValue(":id_player", userInfo->id());
|
||||
servatrice->execSqlQuery(query1);
|
||||
while (query1.next()) {
|
||||
ServerInfo_Replay *replayInfo = re->add_replay_list();
|
||||
ServerInfo_ReplayMatch *matchInfo = re->add_match_list();
|
||||
|
||||
const int gameId = query1.value(0).toInt();
|
||||
replayInfo->set_game_id(gameId);
|
||||
replayInfo->set_room_name(query1.value(2).toString().toStdString());
|
||||
matchInfo->set_game_id(gameId);
|
||||
matchInfo->set_room_name(query1.value(2).toString().toStdString());
|
||||
const int timeStarted = query1.value(3).toDateTime().toTime_t();
|
||||
const int timeFinished = query1.value(4).toDateTime().toTime_t();
|
||||
replayInfo->set_time_started(timeStarted);
|
||||
replayInfo->set_length(timeFinished - timeStarted);
|
||||
replayInfo->set_game_name(query1.value(5).toString().toStdString());
|
||||
replayInfo->set_replay_name(query1.value(1).toString().toStdString());
|
||||
matchInfo->set_time_started(timeStarted);
|
||||
matchInfo->set_length(timeFinished - timeStarted);
|
||||
matchInfo->set_game_name(query1.value(5).toString().toStdString());
|
||||
const QString replayName = query1.value(1).toString();
|
||||
matchInfo->set_do_not_hide(query1.value(6).toBool());
|
||||
|
||||
QSqlQuery query2;
|
||||
query2.prepare("select player_name from cockatrice_games_players where id_game = :id_game");
|
||||
query2.bindValue(":id_game", gameId);
|
||||
servatrice->execSqlQuery(query2);
|
||||
while (query2.next())
|
||||
replayInfo->add_player_names(query2.value(0).toString().toStdString());
|
||||
matchInfo->add_player_names(query2.value(0).toString().toStdString());
|
||||
|
||||
QSqlQuery query3;
|
||||
query3.prepare("select id, duration from " + servatrice->getDbPrefix() + "_replays where id_game = :id_game");
|
||||
query3.bindValue(":id_game", gameId);
|
||||
servatrice->execSqlQuery(query3);
|
||||
while (query3.next()) {
|
||||
ServerInfo_Replay *replayInfo = matchInfo->add_replay_list();
|
||||
replayInfo->set_replay_id(query3.value(0).toInt());
|
||||
replayInfo->set_replay_name(replayName.toStdString());
|
||||
replayInfo->set_duration(query3.value(1).toInt());
|
||||
}
|
||||
}
|
||||
servatrice->dbMutex.unlock();
|
||||
|
||||
|
|
@ -535,8 +549,8 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re
|
|||
QMutexLocker dbLocker(&servatrice->dbMutex);
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("select 1 from " + servatrice->getDbPrefix() + "_replays_access where id_game = :id_game and id_player = :id_player");
|
||||
query1.bindValue(":id_game", cmd.game_id());
|
||||
query1.prepare("select 1 from " + servatrice->getDbPrefix() + "_replays_access a left join " + servatrice->getDbPrefix() + "_replays b on a.id_game = b.id_game where b.id = :id_replay and a.id_player = :id_player");
|
||||
query1.bindValue(":id_replay", cmd.replay_id());
|
||||
query1.bindValue(":id_player", userInfo->id());
|
||||
if (!servatrice->execSqlQuery(query1))
|
||||
return Response::RespInternalError;
|
||||
|
|
@ -544,8 +558,8 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re
|
|||
return Response::RespAccessDenied;
|
||||
|
||||
QSqlQuery query2;
|
||||
query2.prepare("select replay from " + servatrice->getDbPrefix() + "_games where id = :id_game");
|
||||
query2.bindValue(":id_game", cmd.game_id());
|
||||
query2.prepare("select replay from " + servatrice->getDbPrefix() + "_replays where id = :id_replay");
|
||||
query2.bindValue(":id_replay", cmd.replay_id());
|
||||
if (!servatrice->execSqlQuery(query2))
|
||||
return Response::RespInternalError;
|
||||
if (!query2.next())
|
||||
|
|
@ -560,6 +574,22 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re
|
|||
return Response::RespOk;
|
||||
}
|
||||
|
||||
Response::ResponseCode ServerSocketInterface::cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer & /*rc*/)
|
||||
{
|
||||
if (authState != PasswordRight)
|
||||
return Response::RespFunctionNotAllowed;
|
||||
|
||||
QMutexLocker dbLocker(&servatrice->dbMutex);
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("update " + servatrice->getDbPrefix() + "_replays_access set do_not_hide=:do_not_hide where id_player = :id_player and id_game = :id_game");
|
||||
query1.bindValue(":id_player", userInfo->id());
|
||||
query1.bindValue(":id_game", cmd.game_id());
|
||||
query1.bindValue(":do_not_hide", cmd.do_not_hide());
|
||||
|
||||
return servatrice->execSqlQuery(query1) ? Response::RespOk : Response::RespNameNotFound;
|
||||
}
|
||||
|
||||
|
||||
// MODERATOR FUNCTIONS.
|
||||
// May be called by admins and moderators. Permission is checked by the calling function.
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ private:
|
|||
Response::ResponseCode cmdDeckDownload(const Command_DeckDownload &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayList(const Command_ReplayList &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayDownload(const Command_ReplayDownload &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue