diff --git a/Fk/Logic.js b/Fk/Logic.js
index 5e2ad89d..4fef708c 100644
--- a/Fk/Logic.js
+++ b/Fk/Logic.js
@@ -143,14 +143,12 @@ callbacks["UpdateRoomList"] = (jsonData) => {
const current = mainStack.currentItem; // should be lobby
if (mainStack.depth === 2) {
current.roomModel.clear();
- JSON.parse(jsonData).forEach(function (room) {
+ JSON.parse(jsonData).forEach(room => {
+ const [roomId, roomName, gameMode, playerNum, capacity, hasPassword,
+ outdated] = room;
current.roomModel.append({
- roomId: room[0],
- roomName: room[1],
- gameMode: room[2],
- playerNum: room[3],
- capacity: room[4],
- hasPassword: room[5] ? true : false,
+ roomId, roomName, gameMode, playerNum, capacity,
+ hasPassword, outdated,
});
});
}
diff --git a/Fk/Pages/Lobby.qml b/Fk/Pages/Lobby.qml
index 8da9162c..9c5e071a 100644
--- a/Fk/Pages/Lobby.qml
+++ b/Fk/Pages/Lobby.qml
@@ -64,7 +64,13 @@ Item {
Text {
horizontalAlignment: Text.AlignLeft
Layout.fillWidth: true
- text: roomName
+ text: {
+ let ret = roomName;
+ if (outdated) {
+ ret = '' + ret + '';
+ }
+ return ret;
+ }
font.pixelSize: 20
elide: Label.ElideRight
}
@@ -94,7 +100,7 @@ Item {
text: (playerNum < capacity) ? luatr("Enter") :
luatr("Observe")
- enabled: !opTimer.running
+ enabled: !opTimer.running && !outdated
onClicked: {
opTimer.start();
diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts
index 371eae03..f7c58d6d 100644
--- a/lang/zh_CN.ts
+++ b/lang/zh_CN.ts
@@ -318,6 +318,10 @@
房间密码错误
+
+
+ 房间已过时
+
房间不存在
diff --git a/lua/client/i18n/zh_CN.lua b/lua/client/i18n/zh_CN.lua
index b7083b45..c0315d17 100644
--- a/lua/client/i18n/zh_CN.lua
+++ b/lua/client/i18n/zh_CN.lua
@@ -495,6 +495,7 @@ Fk:loadTranslationTable{
["#ChainStateChange"] = "%from %arg 了武将牌",
["#ChainDamage"] = "%from 处于连环状态,将受到传导的伤害",
["#ChangeKingdom"] = "%from 的国籍从 %arg 变成了 %arg2",
+ ["#RoomOutdated"] = "服务器更新完毕!该房间已过期,将无法再次游玩",
}
-- card footnote
diff --git a/lua/server/request.lua b/lua/server/request.lua
index 1b9ff419..66604a3b 100644
--- a/lua/server/request.lua
+++ b/lua/server/request.lua
@@ -181,7 +181,7 @@ request_handlers["newroom"] = function(s, id)
s:registerRoom(id)
end
-request_handlers["reloadpackage"] = function(room, id, reqlist)
+request_handlers["reloadpackage"] = function(_, _, reqlist)
if not IsConsoleStart() then return end
local path = reqlist[3]
Fk:reloadPackage(path)
diff --git a/lua/server/scheduler.lua b/lua/server/scheduler.lua
index e1bf22d3..3df69ece 100644
--- a/lua/server/scheduler.lua
+++ b/lua/server/scheduler.lua
@@ -22,6 +22,8 @@ end)
-- 仿照Room接口编写的request协程处理器
local requestRoom = setmetatable({
+ id = -1,
+ runningRooms = runningRooms,
-- minDelayTime 是当没有任何就绪房间时,可以睡眠的时间。
-- 因为这个时间是所有房间预期就绪用时的最小值,故称为minDelayTime。
@@ -130,6 +132,14 @@ local function mainLoop()
-- 调用RoomThread的trySleep函数开始真正的睡眠。会被wakeUp(c++)唤醒。
requestRoom.thread:trySleep(time)
+ local runningRoomsCount = -1 -- 必有requestRoom,从-1开始算
+ for _ in pairs(runningRooms) do
+ runningRoomsCount = runningRoomsCount + 1
+ if runningRoomsCount > 0 then break end
+ end
+ if runningRoomsCount == 0 and requestRoom.thread:isOutdated() then
+ break
+ end
-- verbose('[!] Waked up after %f ms...', (os.getms() - cur) / 1000)
diff --git a/src/network/router.cpp b/src/network/router.cpp
index 4de18c85..b0e6b412 100644
--- a/src/network/router.cpp
+++ b/src/network/router.cpp
@@ -153,107 +153,6 @@ void Router::abortRequest() {
}
void Router::handlePacket(const QByteArray &rawPacket) {
-#ifndef FK_CLIENT_ONLY
- static QMap lobby_actions;
- if (lobby_actions.size() <= 0) {
- lobby_actions["UpdateAvatar"] = [](ServerPlayer *sender,
- const QString &jsonData) {
- auto arr = String2Json(jsonData).array();
- auto avatar = arr[0].toString();
-
- if (CheckSqlString(avatar)) {
- auto sql = QString("UPDATE userinfo SET avatar='%1' WHERE id=%2;")
- .arg(avatar)
- .arg(sender->getId());
- ExecSQL(ServerInstance->getDatabase(), sql);
- sender->setAvatar(avatar);
- sender->doNotify("UpdateAvatar", avatar);
- }
- };
- lobby_actions["UpdatePassword"] = [](ServerPlayer *sender,
- const QString &jsonData) {
- auto arr = String2Json(jsonData).array();
- auto oldpw = arr[0].toString();
- auto newpw = arr[1].toString();
- auto sql_find =
- QString("SELECT password, salt FROM userinfo WHERE id=%1;")
- .arg(sender->getId());
-
- auto passed = false;
- auto arr2 = SelectFromDatabase(ServerInstance->getDatabase(), sql_find);
- auto result = arr2[0].toObject();
- passed = (result["password"].toString() ==
- QCryptographicHash::hash(
- oldpw.append(result["salt"].toString()).toLatin1(),
- QCryptographicHash::Sha256)
- .toHex());
- if (passed) {
- auto sql_update =
- QString("UPDATE userinfo SET password='%1' WHERE id=%2;")
- .arg(QCryptographicHash::hash(
- newpw.append(result["salt"].toString()).toLatin1(),
- QCryptographicHash::Sha256)
- .toHex())
- .arg(sender->getId());
- ExecSQL(ServerInstance->getDatabase(), sql_update);
- }
-
- sender->doNotify("UpdatePassword", passed ? "1" : "0");
- };
- lobby_actions["CreateRoom"] = [](ServerPlayer *sender,
- const QString &jsonData) {
- auto arr = String2Json(jsonData).array();
- auto name = arr[0].toString();
- auto capacity = arr[1].toInt();
- auto timeout = arr[2].toInt();
- auto settings =
- QJsonDocument(arr[3].toObject()).toJson(QJsonDocument::Compact);
- ServerInstance->createRoom(sender, name, capacity, timeout, settings);
- };
- lobby_actions["EnterRoom"] = [](ServerPlayer *sender,
- const QString &jsonData) {
- auto arr = String2Json(jsonData).array();
- auto roomId = arr[0].toInt();
- auto room = ServerInstance->findRoom(roomId);
- if (room) {
- auto settings = QJsonDocument::fromJson(room->getSettings());
- auto password = settings["password"].toString();
- if (password.isEmpty() || arr[1].toString() == password) {
- room->addPlayer(sender);
- } else {
- sender->doNotify("ErrorMsg", "room password error");
- }
- } else {
- sender->doNotify("ErrorMsg", "no such room");
- }
- };
- lobby_actions["ObserveRoom"] = [](ServerPlayer *sender,
- const QString &jsonData) {
- auto arr = String2Json(jsonData).array();
- auto roomId = arr[0].toInt();
- auto room = ServerInstance->findRoom(roomId);
- if (room) {
- auto settings = QJsonDocument::fromJson(room->getSettings());
- auto password = settings["password"].toString();
- if (password.isEmpty() || arr[1].toString() == password) {
- room->addObserver(sender);
- } else {
- sender->doNotify("ErrorMsg", "room password error");
- }
- } else {
- sender->doNotify("ErrorMsg", "no such room");
- }
- };
- lobby_actions["Chat"] = [](ServerPlayer *sender, const QString &jsonData) {
- sender->getRoom()->chat(sender, jsonData);
- };
- lobby_actions["RefreshRoomList"] = [](ServerPlayer *sender,
- const QString &jsonData) {
- ServerInstance->updateRoomList(sender);
- };
- }
-#endif
-
QJsonDocument packet = QJsonDocument::fromJson(rawPacket);
if (packet.isNull() || !packet.isArray())
return;
@@ -278,35 +177,7 @@ void Router::handlePacket(const QByteArray &rawPacket) {
}
Room *room = player->getRoom();
- if (room->isLobby() && lobby_actions.contains(command))
- lobby_actions[command](player, jsonData);
- else {
- if (command == "QuitRoom") {
- room->removePlayer(player);
- } else if (command == "AddRobot") {
- if (ServerInstance->getConfig("enableBots").toBool()) room->addRobot(player);
- } else if (command == "KickPlayer") {
- int i = jsonData.toInt();
- auto p = room->findPlayer(i);
- if (p && !room->isStarted()) {
- room->removePlayer(p);
- room->addRejectId(i);
- QTimer::singleShot(30000, this, [=]() {
- room->removeRejectId(i);
- });
- }
- } else if (command == "Ready") {
- player->setReady(!player->isReady());
- room->doBroadcastNotify(room->getPlayers(), "ReadyChanged",
- QString("[%1,%2]").arg(player->getId()).arg(player->isReady()));
- } else if (command == "StartGame") {
- room->manuallyStart();
- } else if (command == "Chat") {
- room->chat(player, jsonData);
- } else if (command == "PushRequest") {
- room->pushRequest(QString("%1,").arg(player->getId()) + jsonData);
- }
- }
+ room->handlePacket(player, command, jsonData);
}
#endif
} else if (type & TYPE_REQUEST) {
diff --git a/src/server/room.cpp b/src/server/room.cpp
index 1a811c14..9a27d8f3 100644
--- a/src/server/room.cpp
+++ b/src/server/room.cpp
@@ -22,7 +22,7 @@ Room::Room(RoomThread *m_thread) {
id = server->nextRoomId;
server->nextRoomId++;
this->server = server;
- this->m_thread = m_thread;
+ setThread(m_thread);
if (m_thread) { // In case of lobby
m_thread->addRoom(this);
}
@@ -60,7 +60,12 @@ Server *Room::getServer() const { return server; }
RoomThread *Room::getThread() const { return m_thread; }
-void Room::setThread(RoomThread *t) { m_thread = t; }
+void Room::setThread(RoomThread *t) {
+ m_thread = t;
+ if (t != nullptr) {
+ md5 = t->getMd5();
+ }
+}
int Room::getId() const { return id; }
@@ -366,6 +371,12 @@ int Room::getTimeout() const { return timeout; }
void Room::setTimeout(int timeout) { this->timeout = timeout; }
+bool Room::isOutdated() {
+ bool ret = md5 != server->getMd5();
+ if (ret) md5 = "";
+ return ret;
+}
+
bool Room::isStarted() const { return gameStarted; }
void Room::doBroadcastNotify(const QList targets,
@@ -616,3 +627,186 @@ void Room::addRejectId(int id) {
void Room::removeRejectId(int id) {
rejected_players.removeOne(id);
}
+
+// ------------------------------------------------
+static void updateAvatar(ServerPlayer *sender, const QString &jsonData) {
+ auto arr = String2Json(jsonData).array();
+ auto avatar = arr[0].toString();
+
+ if (CheckSqlString(avatar)) {
+ auto sql = QString("UPDATE userinfo SET avatar='%1' WHERE id=%2;")
+ .arg(avatar)
+ .arg(sender->getId());
+ ExecSQL(ServerInstance->getDatabase(), sql);
+ sender->setAvatar(avatar);
+ sender->doNotify("UpdateAvatar", avatar);
+ }
+}
+
+static void updatePassword(ServerPlayer *sender, const QString &jsonData) {
+ auto arr = String2Json(jsonData).array();
+ auto oldpw = arr[0].toString();
+ auto newpw = arr[1].toString();
+ auto sql_find =
+ QString("SELECT password, salt FROM userinfo WHERE id=%1;")
+ .arg(sender->getId());
+
+ auto passed = false;
+ auto arr2 = SelectFromDatabase(ServerInstance->getDatabase(), sql_find);
+ auto result = arr2[0].toObject();
+ passed = (result["password"].toString() ==
+ QCryptographicHash::hash(
+ oldpw.append(result["salt"].toString()).toLatin1(),
+ QCryptographicHash::Sha256)
+ .toHex());
+ if (passed) {
+ auto sql_update =
+ QString("UPDATE userinfo SET password='%1' WHERE id=%2;")
+ .arg(QCryptographicHash::hash(
+ newpw.append(result["salt"].toString()).toLatin1(),
+ QCryptographicHash::Sha256)
+ .toHex())
+ .arg(sender->getId());
+ ExecSQL(ServerInstance->getDatabase(), sql_update);
+ }
+
+ sender->doNotify("UpdatePassword", passed ? "1" : "0");
+}
+
+static void createRoom(ServerPlayer *sender, const QString &jsonData) {
+ auto arr = String2Json(jsonData).array();
+ auto name = arr[0].toString();
+ auto capacity = arr[1].toInt();
+ auto timeout = arr[2].toInt();
+ auto settings =
+ QJsonDocument(arr[3].toObject()).toJson(QJsonDocument::Compact);
+ ServerInstance->createRoom(sender, name, capacity, timeout, settings);
+}
+
+static void enterRoom(ServerPlayer *sender, const QString &jsonData) {
+ auto arr = String2Json(jsonData).array();
+ auto roomId = arr[0].toInt();
+ auto room = ServerInstance->findRoom(roomId);
+ if (room) {
+ auto settings = QJsonDocument::fromJson(room->getSettings());
+ auto password = settings["password"].toString();
+ if (password.isEmpty() || arr[1].toString() == password) {
+ if (room->isOutdated()) {
+ sender->doNotify("ErrorMsg", "room is outdated");
+ } else {
+ room->addPlayer(sender);
+ }
+ } else {
+ sender->doNotify("ErrorMsg", "room password error");
+ }
+ } else {
+ sender->doNotify("ErrorMsg", "no such room");
+ }
+}
+
+static void observeRoom(ServerPlayer *sender, const QString &jsonData) {
+ auto arr = String2Json(jsonData).array();
+ auto roomId = arr[0].toInt();
+ auto room = ServerInstance->findRoom(roomId);
+ if (room) {
+ auto settings = QJsonDocument::fromJson(room->getSettings());
+ auto password = settings["password"].toString();
+ if (password.isEmpty() || arr[1].toString() == password) {
+ if (room->isOutdated()) {
+ sender->doNotify("ErrorMsg", "room is outdated");
+ } else {
+ room->addObserver(sender);
+ }
+ } else {
+ sender->doNotify("ErrorMsg", "room password error");
+ }
+ } else {
+ sender->doNotify("ErrorMsg", "no such room");
+ }
+}
+
+static void refreshRoomList(ServerPlayer *sender, const QString &) {
+ ServerInstance->updateRoomList(sender);
+};
+
+static void quitRoom(ServerPlayer *player, const QString &) {
+ auto room = player->getRoom();
+ room->removePlayer(player);
+ if (room->isOutdated()) {
+ player->kicked();
+ }
+}
+
+static void addRobot(ServerPlayer *player, const QString &) {
+ auto room = player->getRoom();
+ if (ServerInstance->getConfig("enableBots").toBool())
+ room->addRobot(player);
+}
+
+static void kickPlayer(ServerPlayer *player, const QString &jsonData) {
+ auto room = player->getRoom();
+ int i = jsonData.toInt();
+ auto p = room->findPlayer(i);
+ if (p && !room->isStarted()) {
+ room->removePlayer(p);
+ room->addRejectId(i);
+ QTimer::singleShot(30000, room, [=]() {
+ room->removeRejectId(i);
+ });
+ }
+}
+
+static void ready(ServerPlayer *player, const QString &) {
+ auto room = player->getRoom();
+ player->setReady(!player->isReady());
+ room->doBroadcastNotify(room->getPlayers(), "ReadyChanged",
+ QString("[%1,%2]").arg(player->getId()).arg(player->isReady()));
+}
+
+static void startGame(ServerPlayer *player, const QString &) {
+ auto room = player->getRoom();
+ if (room->isOutdated()) {
+ foreach (auto p, room->getPlayers()) {
+ p->doNotify("ErrorMsg", "room is outdated");
+ p->kicked();
+ }
+ } else {
+ room->manuallyStart();
+ }
+}
+
+typedef void (*room_cb)(ServerPlayer *, const QString &);
+static const QMap lobby_actions = {
+ {"UpdateAvatar", updateAvatar},
+ {"UpdatePassword", updatePassword},
+ {"CreateRoom", createRoom},
+ {"EnterRoom", enterRoom},
+ {"ObserveRoom", observeRoom},
+ {"RefreshRoomList", refreshRoomList},
+};
+
+static const QMap room_actions = {
+ {"QuitRoom", quitRoom},
+ {"AddRobot", addRobot},
+ {"KickPlayer", kickPlayer},
+ {"Ready", ready},
+ {"StartGame", startGame},
+};
+
+void Room::handlePacket(ServerPlayer *sender, const QString &command,
+ const QString &jsonData) {
+ if (command == "Chat") {
+ chat(sender, jsonData);
+ return;
+ } else if (command == "PushRequest") {
+ if (!isLobby())
+ pushRequest(QString("%1,").arg(sender->getId()) + jsonData);
+ }
+
+ auto func_table = lobby_actions;
+ if (!isLobby()) func_table = room_actions;
+ auto func = func_table[command];
+ if (func) {
+ func(sender, jsonData);
+ }
+}
diff --git a/src/server/room.h b/src/server/room.h
index 2cf9a13a..221be5b8 100644
--- a/src/server/room.h
+++ b/src/server/room.h
@@ -50,6 +50,8 @@ class Room : public QObject {
int getTimeout() const;
void setTimeout(int timeout);
+ bool isOutdated();
+
bool isStarted() const;
// ====================================}
@@ -65,6 +67,10 @@ class Room : public QObject {
void addRejectId(int id);
void removeRejectId(int id);
+
+ // router用
+ void handlePacket(ServerPlayer *sender, const QString &command,
+ const QString &jsonData);
signals:
void abandoned();
@@ -90,6 +96,7 @@ class Room : public QObject {
bool m_ready;
int timeout;
+ QString md5;
void addRunRate(int id, const QString &mode);
void updatePlayerGameData(int id, const QString &mode);
diff --git a/src/server/roomthread.cpp b/src/server/roomthread.cpp
index 104d592c..91206caf 100644
--- a/src/server/roomthread.cpp
+++ b/src/server/roomthread.cpp
@@ -3,6 +3,7 @@
#include "roomthread.h"
#include "server.h"
#include "util.h"
+#include
#ifndef FK_SERVER_ONLY
#include "client.h"
@@ -13,6 +14,7 @@ RoomThread::RoomThread(Server *m_server) {
this->m_server = m_server;
m_capacity = 100; // TODO: server cfg
terminated = false;
+ md5 = m_server->getMd5();
L = CreateLuaState();
DoLuaScript(L, "lua/freekill.lua");
@@ -26,6 +28,7 @@ RoomThread::~RoomThread() {
wait();
}
lua_close(L);
+ m_server->removeThread(this);
// foreach (auto room, room_list) {
// room->deleteLater();
// }
@@ -40,6 +43,8 @@ bool RoomThread::isFull() const {
return m_capacity <= 0;
}
+QString RoomThread::getMd5() const { return md5; }
+
Room *RoomThread::getRoom(int id) const {
return m_server->findRoom(id);
}
@@ -52,6 +57,10 @@ void RoomThread::addRoom(Room *room) {
void RoomThread::removeRoom(Room *room) {
room->setThread(nullptr);
m_capacity++;
+ if (m_capacity == 100 // TODO: server cfg
+ && isOutdated()) {
+ deleteLater();
+ }
}
QString RoomThread::fetchRequest() {
@@ -118,3 +127,13 @@ bool RoomThread::isConsoleStart() const {
return false;
#endif
}
+
+bool RoomThread::isOutdated() {
+ bool ret = md5 != m_server->getMd5();
+ if (ret) {
+ // 让以后每次都outdate
+ // 不然反复disable/enable的情况下会出乱子
+ md5 = "";
+ }
+ return ret;
+}
diff --git a/src/server/roomthread.h b/src/server/roomthread.h
index 15cd1964..25d0afe3 100644
--- a/src/server/roomthread.h
+++ b/src/server/roomthread.h
@@ -16,6 +16,7 @@ class RoomThread : public QThread {
Server *getServer() const;
bool isFull() const;
+ QString getMd5() const;
Room *getRoom(int id) const;
void addRoom(Room *room);
void removeRoom(Room *room);
@@ -32,6 +33,9 @@ class RoomThread : public QThread {
bool isTerminated() const;
bool isConsoleStart() const;
+
+ bool isOutdated();
+
protected:
virtual void run();
@@ -39,6 +43,7 @@ class RoomThread : public QThread {
Server *m_server;
// QList room_list;
int m_capacity;
+ QString md5;
lua_State *L;
QMutex request_queue_mutex;
diff --git a/src/server/server.cpp b/src/server/server.cpp
index 9a62d90e..996157b1 100644
--- a/src/server/server.cpp
+++ b/src/server/server.cpp
@@ -112,14 +112,14 @@ void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
RoomThread *thread = nullptr;
foreach (auto t, threads) {
- if (!t->isFull()) {
+ if (!t->isFull() && !t->isOutdated()) {
thread = t;
break;
}
}
+
if (!thread && nextRoomId != 0) {
- thread = new RoomThread(this);
- threads.append(thread);
+ thread = createThread();
}
if (!idle_rooms.isEmpty()) {
@@ -128,6 +128,7 @@ void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
nextRoomId++;
room->setAbandoned(false);
room->setThread(thread);
+ thread->addRoom(room);
rooms.insert(room->getId(), room);
} else {
room = new Room(thread);
@@ -151,6 +152,16 @@ Room *Server::findRoom(int id) const { return rooms.value(id); }
Room *Server::lobby() const { return m_lobby; }
+RoomThread *Server::createThread() {
+ RoomThread *thread = new RoomThread(this);
+ threads.append(thread);
+ return thread;
+}
+
+void Server::removeThread(RoomThread *thread) {
+ threads.removeOne(thread);
+}
+
ServerPlayer *Server::findPlayer(int id) const { return players.value(id); }
void Server::addPlayer(ServerPlayer *player) {
@@ -183,6 +194,7 @@ void Server::updateRoomList(ServerPlayer *teller) {
obj << count;
obj << cap;
obj << !password.isEmpty();
+ obj << room->isOutdated();
if (count == cap)
arr << obj;
@@ -670,6 +682,30 @@ void Server::endTransaction() {
transaction_mutex.unlock();
}
+const QString &Server::getMd5() const {
+ return md5;
+}
+
+void Server::refreshMd5() {
+ md5 = calcFileMD5();
+ foreach (auto room, rooms) {
+ if (room->isOutdated()) {
+ if (!room->isStarted()) {
+ foreach (auto p, room->getPlayers()) {
+ p->doNotify("ErrorMsg", "room is outdated");
+ p->kicked();
+ }
+ } else {
+ room->doBroadcastNotify(room->getPlayers(), "GameLog",
+ "{\"type\":\"#RoomOutdated\",\"toast\":true}");
+ }
+ }
+ }
+ foreach (auto p, lobby()->getPlayers()) {
+ emit p->kicked();
+ }
+}
+
void Server::readPendingDatagrams() {
while (udpSocket->hasPendingDatagrams()) {
QNetworkDatagram datagram = udpSocket->receiveDatagram();
diff --git a/src/server/server.h b/src/server/server.h
index 61b02088..f2baaa53 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -31,6 +31,9 @@ public:
Room *findRoom(int id) const;
Room *lobby() const;
+ RoomThread *createThread();
+ void removeThread(RoomThread *thread);
+
ServerPlayer *findPlayer(int id) const;
void addPlayer(ServerPlayer *player);
void removePlayer(int id);
@@ -50,6 +53,9 @@ public:
void beginTransaction();
void endTransaction();
+ const QString &getMd5() const;
+ void refreshMd5();
+
signals:
void roomCreated(Room *room);
void playerAdded(ServerPlayer *player);
diff --git a/src/server/shell.cpp b/src/server/shell.cpp
index 9b2ee0ca..c286701d 100644
--- a/src/server/shell.cpp
+++ b/src/server/shell.cpp
@@ -117,11 +117,13 @@ void Shell::upgradeCommand(QStringList &list) {
auto obj = a.toObject();
Pacman->upgradePack(obj["name"].toString());
}
+ ServerInstance->refreshMd5();
return;
}
auto pack = list[0];
Pacman->upgradePack(pack);
+ ServerInstance->refreshMd5();
}
void Shell::enableCommand(QStringList &list) {
@@ -132,6 +134,7 @@ void Shell::enableCommand(QStringList &list) {
auto pack = list[0];
Pacman->enablePack(pack);
+ ServerInstance->refreshMd5();
}
void Shell::disableCommand(QStringList &list) {
@@ -142,6 +145,7 @@ void Shell::disableCommand(QStringList &list) {
auto pack = list[0];
Pacman->disablePack(pack);
+ ServerInstance->refreshMd5();
}
void Shell::lspkgCommand(QStringList &) {
@@ -380,33 +384,32 @@ Shell::Shell() {
setObjectName("Shell");
signal(SIGINT, sigintHandler);
- static QHash handlers;
- if (handlers.size() == 0) {
- handlers["help"] = &Shell::helpCommand;
- handlers["?"] = &Shell::helpCommand;
- handlers["lsplayer"] = &Shell::lspCommand;
- handlers["lsroom"] = &Shell::lsrCommand;
- handlers["install"] = &Shell::installCommand;
- handlers["remove"] = &Shell::removeCommand;
- handlers["upgrade"] = &Shell::upgradeCommand;
- handlers["u"] = &Shell::upgradeCommand;
- handlers["lspkg"] = &Shell::lspkgCommand;
- handlers["enable"] = &Shell::enableCommand;
- handlers["disable"] = &Shell::disableCommand;
- handlers["kick"] = &Shell::kickCommand;
- handlers["msg"] = &Shell::msgCommand;
- handlers["m"] = &Shell::msgCommand;
- handlers["ban"] = &Shell::banCommand;
- handlers["unban"] = &Shell::unbanCommand;
- handlers["banip"] = &Shell::banipCommand;
- handlers["unbanip"] = &Shell::unbanipCommand;
- handlers["banuuid"] = &Shell::banUuidCommand;
- handlers["unbanuuid"] = &Shell::unbanUuidCommand;
- handlers["reloadconf"] = &Shell::reloadConfCommand;
- handlers["r"] = &Shell::reloadConfCommand;
- handlers["resetpassword"] = &Shell::resetPasswordCommand;
- handlers["rp"] = &Shell::resetPasswordCommand;
- }
+ static const QHash handlers = {
+ {"help", &Shell::helpCommand},
+ {"?", &Shell::helpCommand},
+ {"lsplayer", &Shell::lspCommand},
+ {"lsroom", &Shell::lsrCommand},
+ {"install", &Shell::installCommand},
+ {"remove", &Shell::removeCommand},
+ {"upgrade", &Shell::upgradeCommand},
+ {"u", &Shell::upgradeCommand},
+ {"lspkg", &Shell::lspkgCommand},
+ {"enable", &Shell::enableCommand},
+ {"disable", &Shell::disableCommand},
+ {"kick", &Shell::kickCommand},
+ {"msg", &Shell::msgCommand},
+ {"m", &Shell::msgCommand},
+ {"ban", &Shell::banCommand},
+ {"unban", &Shell::unbanCommand},
+ {"banip", &Shell::banipCommand},
+ {"unbanip", &Shell::unbanipCommand},
+ {"banuuid", &Shell::banUuidCommand},
+ {"unbanuuid", &Shell::unbanUuidCommand},
+ {"reloadconf", &Shell::reloadConfCommand},
+ {"r", &Shell::reloadConfCommand},
+ {"resetpassword", &Shell::resetPasswordCommand},
+ {"rp", &Shell::resetPasswordCommand},
+ };
handler_map = handlers;
}
diff --git a/src/swig/server.i b/src/swig/server.i
index 82908a2b..ba72a769 100644
--- a/src/swig/server.i
+++ b/src/swig/server.i
@@ -41,6 +41,7 @@ public:
bool isTerminated() const;
bool isConsoleStart() const;
+ bool isOutdated();
};
%{