Skip to content

Commit

Permalink
修复与服务端稳定性相关的若干bug (#434)
Browse files Browse the repository at this point in the history
- 修复Room析构时没有清理其中玩家导致后续玩家操作崩服的bug
- 修复SWIG中不释放QList的bug
- 将doNotify系列的参数改为`const QByteArray &` 规避中间一次转QString带来的拷贝
  • Loading branch information
Notify-ctrl authored Dec 16, 2024
1 parent 146a0b9 commit c692bb6
Show file tree
Hide file tree
Showing 25 changed files with 82 additions and 92 deletions.
4 changes: 2 additions & 2 deletions src/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,13 @@ void Client::setLoginInfo(const QString &username, const QString &password) {

void Client::replyToServer(const QString &command, const QString &jsonData) {
int type = Router::TYPE_REPLY | Router::SRC_CLIENT | Router::DEST_SERVER;
router->reply(type, command, jsonData);
router->reply(type, command.toUtf8(), jsonData.toUtf8());
}

void Client::notifyServer(const QString &command, const QString &jsonData) {
int type =
Router::TYPE_NOTIFICATION | Router::SRC_CLIENT | Router::DEST_SERVER;
router->notify(type, command, jsonData);
router->notify(type, command.toUtf8(), jsonData.toUtf8());
}

void Client::callLua(const QString& command, const QString& json_data, bool isRequest) {
Expand Down
3 changes: 2 additions & 1 deletion src/core/c-wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class Lua {

class Sqlite3 {
public:
Sqlite3(const QString &filename = "./server/users.db", const QString &initSql = "./server/init.sql");
Sqlite3(const QString &filename = QStringLiteral("./server/users.db"),
const QString &initSql = QStringLiteral("./server/init.sql"));
~Sqlite3();

static bool checkString(const QString &str);
Expand Down
2 changes: 1 addition & 1 deletion src/core/packman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ int PackMan::clone(const QString &u) {
QString fileName = QUrl(url).fileName();
if (fileName.endsWith(".git"))
fileName.chop(4);
fileName = "packages/" + fileName;
fileName = QStringLiteral("packages/") + fileName;

git_clone_options opt = GIT_CLONE_OPTIONS_INIT;
opt.fetch_opts.callbacks.transfer_progress = transfer_progress_cb;
Expand Down
8 changes: 4 additions & 4 deletions src/freekill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,15 +352,15 @@ int freekill_main(int argc, char *argv[]) {

QString system;
#if defined(Q_OS_ANDROID)
system = "Android";
system = QStringLiteral("Android");
#elif defined(Q_OS_WIN32)
qputenv("QT_MEDIA_BACKEND", "windows");
system = "Win";
system = QStringLiteral("Win");
::system("chcp 65001");
#elif defined(Q_OS_LINUX)
system = "Linux";
system = QStringLiteral("Linux");
#else
system = "Other";
system = QStringLiteral("Other");
#endif
root->setContextProperty("OS", system);

Expand Down
2 changes: 1 addition & 1 deletion src/network/client_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void ClientSocket::send(const QByteArray &msg) {
QByteArray _msg;
if (msg.length() >= 1024) {
auto comp = qCompress(msg);
_msg = "Compressed" + comp.toBase64();
_msg = QByteArrayLiteral("Compressed") + comp.toBase64();
_msg = aesEnc(_msg) + "\n";
} else {
_msg = aesEnc(msg) + "\n";
Expand Down
2 changes: 1 addition & 1 deletion src/network/client_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ClientSocket : public QObject {
ClientSocket(QTcpSocket *socket);

/// 客户端使用,用于连接到远程服务器
void connectToHost(const QString &address = "127.0.0.1", ushort port = 9527u);
void connectToHost(const QString &address = QStringLiteral("127.0.0.1"), ushort port = 9527u);
/// 双端都可使用。禁用加密传输并断开TCP连接。
void disconnectFromHost();
/// 设置AES密钥,同时启用加密传输。
Expand Down
20 changes: 10 additions & 10 deletions src/network/router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void Router::setReplyReadySemaphore(QSemaphore *semaphore) {
extraReplyReadySemaphore = semaphore;
}

void Router::request(int type, const QString &command, const QString &jsonData,
void Router::request(int type, const QByteArray &command, const QByteArray &jsonData,
int timeout, qint64 timestamp) {
// In case a request is called without a following waitForReply call
if (replyReadySemaphore.available() > 0)
Expand All @@ -61,36 +61,36 @@ void Router::request(int type, const QString &command, const QString &jsonData,
expectedReplyId = requestId;
replyTimeout = timeout;
requestStartTime = QDateTime::currentDateTime();
m_reply = "__notready";
m_reply = QStringLiteral("__notready");
replyMutex.unlock();

QJsonArray body;
body << requestId;
body << type;
body << command;
body << jsonData;
body << command.constData();
body << jsonData.constData();
body << timeout;
body << (timestamp <= 0 ? requestStartTime.toMSecsSinceEpoch() : timestamp);

emit messageReady(JsonArray2Bytes(body));
}

void Router::reply(int type, const QString &command, const QString &jsonData) {
void Router::reply(int type, const QByteArray &command, const QByteArray &jsonData) {
QJsonArray body;
body << this->requestId;
body << type;
body << command;
body << jsonData;
body << command.constData();
body << jsonData.constData();

emit messageReady(JsonArray2Bytes(body));
}

void Router::notify(int type, const QString &command, const QString &jsonData) {
void Router::notify(int type, const QByteArray &command, const QByteArray &jsonData) {
QJsonArray body;
body << -2; // requestId = -2 mean this is for notification
body << type;
body << command;
body << jsonData;
body << command.constData();
body << jsonData.constData();

emit messageReady(JsonArray2Bytes(body));
}
Expand Down
9 changes: 4 additions & 5 deletions src/network/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class Router : public QObject {

void setReplyReadySemaphore(QSemaphore *semaphore);

void request(int type, const QString &command,
const QString &jsonData, int timeout, qint64 timestamp = -1);
void reply(int type, const QString &command, const QString &jsonData);
void notify(int type, const QString &command, const QString &jsonData);
void request(int type, const QByteArray &command,
const QByteArray &jsonData, int timeout, qint64 timestamp = -1);
void reply(int type, const QByteArray &command, const QByteArray &jsonData);
void notify(int type, const QByteArray &command, const QByteArray &jsonData);

int getTimeout() const;

Expand All @@ -62,7 +62,6 @@ class Router : public QObject {

signals:
void messageReady(const QByteArray &message);
void unknownPacket(const QByteArray &packet);
void replyReady();

void notification_got(const QString &command, const QString &jsonData);
Expand Down
4 changes: 2 additions & 2 deletions src/server/auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bool AuthManager::checkClientVersion(ClientSocket *client, const QString &cver)
.arg(FK_VERSION, "1");
}

server->sendEarlyPacket(client, "ErrorDlg", errmsg);
server->sendEarlyPacket(client, "ErrorDlg", errmsg.toUtf8());
client->disconnectFromHost();
return false;
}
Expand Down Expand Up @@ -107,7 +107,7 @@ QMap<QString, QString> AuthManager::checkPassword(ClientSocket *client, const QS

auto server = qobject_cast<Server *>(parent());
bool passed = false;
QString error_msg;
const char *error_msg = nullptr;
QMap<QString, QString> obj;
int id;
QByteArray salt;
Expand Down
4 changes: 2 additions & 2 deletions src/server/lobby.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void Lobby::updateAvatar(ServerPlayer *sender, const QString &jsonData) {
.arg(sender->getId());
ServerInstance->getDatabase()->exec(sql);
sender->setAvatar(avatar);
sender->doNotify("UpdateAvatar", avatar);
sender->doNotify("UpdateAvatar", avatar.toUtf8());
}
}

Expand Down Expand Up @@ -90,7 +90,7 @@ void Lobby::getRoomConfig(ServerPlayer *sender, const QString &jsonData) {
if (room) {
auto settings = room->getSettings();
// 手搓JSON数组 跳过编码解码
sender->doNotify("GetRoomConfig", QString("[%1,%2]").arg(roomId).arg(settings));
sender->doNotify("GetRoomConfig", QString("[%1,%2]").arg(roomId).arg(settings).toUtf8());
} else {
sender->doNotify("ErrorMsg", "no such room");
}
Expand Down
14 changes: 10 additions & 4 deletions src/server/room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Room::~Room() {
if (gameStarted) {
gameOver();
}
for (auto p : players) {
if (p->getId() > 0) removePlayer(p);
}
for (auto p : observers) {
removeObserver(p);
}
}

int Room::getId() const { return id; }
Expand Down Expand Up @@ -99,7 +105,7 @@ void Room::addPlayer(ServerPlayer *player) {
if (runned_players.contains(player->getId())) {
player->doNotify("ErrorMsg", "Running away is shameful.");
}
// 此时player仍在lobby中,别管就行了
// 此时phttps://github.com/fmanlou/qt6printerslayer仍在lobby中,别管就行了
// emit playerRemoved(player);
return;
}
Expand Down Expand Up @@ -298,7 +304,7 @@ void Room::delay(int ms) {

bool Room::isOutdated() {
bool ret = md5 != server->getMd5();
if (ret) md5 = "";
if (ret) md5 = QStringLiteral("");
return ret;
}

Expand Down Expand Up @@ -542,14 +548,14 @@ void Room::manuallyStart() {
for (auto i = ipList.cbegin(); i != ipList.cend(); i++) {
if (i.value().length() <= 1) continue;
auto warn = QString("*WARN* Same IP address: [%1]").arg(i.value().join(", "));
doBroadcastNotify(getPlayers(), "ServerMessage", warn);
doBroadcastNotify(getPlayers(), "ServerMessage", warn.toUtf8());
qInfo("%s", warn.toUtf8().constData());
}

for (auto i = uuidList.cbegin(); i != uuidList.cend(); i++) {
if (i.value().length() <= 1) continue;
auto warn = QString("*WARN* Same device id: [%1]").arg(i.value().join(", "));
doBroadcastNotify(getPlayers(), "ServerMessage", warn);
doBroadcastNotify(getPlayers(), "ServerMessage", warn.toUtf8());
qInfo("%s", warn.toUtf8().constData());
}

Expand Down
2 changes: 1 addition & 1 deletion src/server/roombase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ ServerPlayer *RoomBase::findPlayer(int id) const {
}

void RoomBase::doBroadcastNotify(const QList<ServerPlayer *> targets,
const QString &command, const QString &jsonData) {
const QByteArray &command, const QByteArray &jsonData) {
for (auto p : targets) {
p->doNotify(command, jsonData);
}
Expand Down
2 changes: 1 addition & 1 deletion src/server/roombase.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RoomBase : public QObject {
ServerPlayer *findPlayer(int id) const;

void doBroadcastNotify(const QList<ServerPlayer *> targets,
const QString &command, const QString &jsonData);
const QByteArray &command, const QByteArray &jsonData);

void chat(ServerPlayer *sender, const QString &jsonData);

Expand Down
2 changes: 1 addition & 1 deletion src/server/roomthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ bool RoomThread::isOutdated() {
if (ret) {
// 让以后每次都outdate
// 不然反复disable/enable的情况下会出乱子
md5 = "";
md5 = QStringLiteral("");
}
return ret;
}
Expand Down
26 changes: 13 additions & 13 deletions src/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,32 +168,32 @@ void Server::updateRoomList(ServerPlayer *teller) {
arr.prepend(v);
}
auto jsonData = JsonArray2Bytes(arr);
teller->doNotify("UpdateRoomList", QString(jsonData));
teller->doNotify("UpdateRoomList", jsonData);
}

void Server::updateOnlineInfo() {
lobby()->doBroadcastNotify(lobby()->getPlayers(), "UpdatePlayerNum",
QString(JsonArray2Bytes(QJsonArray({
JsonArray2Bytes(QJsonArray({
lobby()->getPlayers().length(),
this->players.count(),
}))));
})));
}

Sqlite3 *Server::getDatabase() { return db; }

void Server::broadcast(const QString &command, const QString &jsonData) {
void Server::broadcast(const QByteArray &command, const QByteArray &jsonData) {
for (ServerPlayer *p : players.values()) {
p->doNotify(command, jsonData);
}
}

void Server::sendEarlyPacket(ClientSocket *client, const QString &type, const QString &msg) {
void Server::sendEarlyPacket(ClientSocket *client, const QByteArray &type, const QByteArray &msg) {
QJsonArray body;
body << -2;
body << (Router::TYPE_NOTIFICATION | Router::SRC_SERVER |
Router::DEST_CLIENT);
body << type;
body << msg;
body << type.constData();
body << msg.constData();
client->send(JsonArray2Bytes(body));
}

Expand Down Expand Up @@ -222,7 +222,7 @@ void Server::processNewConnection(ClientSocket *client) {
// check ban ip
auto result = db->select(QString("SELECT * FROM banip WHERE ip='%1';").arg(addr));

auto errmsg = QString();
const char *errmsg = nullptr;

if (!result.isEmpty()) {
errmsg = "you have been banned!";
Expand All @@ -232,7 +232,7 @@ void Server::processNewConnection(ClientSocket *client) {
errmsg = "server is full!";
}

if (!errmsg.isEmpty()) {
if (errmsg) {
sendEarlyPacket(client, "ErrorDlg", errmsg);
qInfo() << "Refused banned IP:" << addr;
client->disconnectFromHost();
Expand All @@ -243,7 +243,7 @@ void Server::processNewConnection(ClientSocket *client) {
[client]() { qInfo() << client->peerAddress() << "disconnected"; });

// network delay test
sendEarlyPacket(client, "NetworkDelayTest", auth->getPublicKey());
sendEarlyPacket(client, "NetworkDelayTest", auth->getPublicKey().toUtf8());
// Note: the client should send a setup string next
connect(client, &ClientSocket::message_got, this, &Server::processRequest);
client->timerSignup.start(30000);
Expand Down Expand Up @@ -295,7 +295,7 @@ void Server::processRequest(const QByteArray &msg) {
auto md5_str = arr[2].toString();
if (md5 != md5_str) {
sendEarlyPacket(client, "ErrorMsg", "MD5 check failed!");
sendEarlyPacket(client, "UpdatePackage", Pacman->getPackSummary());
sendEarlyPacket(client, "UpdatePackage", Pacman->getPackSummary().toUtf8());
client->disconnectFromHost();
return;
}
Expand Down Expand Up @@ -333,7 +333,7 @@ void Server::processRequest(const QByteArray &msg) {
player->setId(id);
player->setUuid(uuid_str);
if (players.count() <= 10) {
broadcast("ServerMessage", tr("%1 logged in").arg(player->getScreenName()));
broadcast("ServerMessage", tr("%1 logged in").arg(player->getScreenName()).toUtf8());
}
players.insert(player->getId(), player);

Expand All @@ -354,7 +354,7 @@ void Server::processRequest(const QByteArray &msg) {

void Server::readConfig() {
QFile file("freekill.server.config.json");
QByteArray json = "{}";
QByteArray json = QByteArrayLiteral("{}");
if (file.open(QIODevice::ReadOnly)) {
json = file.readAll();
}
Expand Down
6 changes: 3 additions & 3 deletions src/server/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Server : public QObject {
@param settings 表示JSON对象的字符串,用作房间配置
*/
void createRoom(ServerPlayer *owner, const QString &name, int capacity,
int timeout = 15, const QByteArray &settings = "{}");
int timeout = 15, const QByteArray &settings = QByteArrayLiteral("{}"));

void removeRoom(int id); /// 单纯从表中删除指针 内存由对应thread管理

Expand All @@ -78,8 +78,8 @@ class Server : public QObject {

Sqlite3 *getDatabase();

void broadcast(const QString &command, const QString &jsonData);
void sendEarlyPacket(ClientSocket *client, const QString &type, const QString &msg);
void broadcast(const QByteArray &command, const QByteArray &jsonData);
void sendEarlyPacket(ClientSocket *client, const QByteArray &type, const QByteArray &msg);
void setupPlayer(ServerPlayer *player, bool all_info = true);
bool isListening;

Expand Down
Loading

0 comments on commit c692bb6

Please sign in to comment.