parent
873d68363c
commit
1a4da186d2
12
Fk/Logic.js
12
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,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -64,7 +64,13 @@ Item {
|
|||
Text {
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
text: roomName
|
||||
text: {
|
||||
let ret = roomName;
|
||||
if (outdated) {
|
||||
ret = '<font color="grey"><del>' + ret + '</del></font>';
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -318,6 +318,10 @@
|
|||
<source>room password error</source>
|
||||
<translation>房间密码错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>room is outdated</source>
|
||||
<translation>房间已过时</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>no such room</source>
|
||||
<translation>房间不存在</translation>
|
||||
|
|
|
@ -495,6 +495,7 @@ Fk:loadTranslationTable{
|
|||
["#ChainStateChange"] = "%from %arg 了武将牌",
|
||||
["#ChainDamage"] = "%from 处于连环状态,将受到传导的伤害",
|
||||
["#ChangeKingdom"] = "%from 的国籍从 %arg 变成了 %arg2",
|
||||
["#RoomOutdated"] = "服务器更新完毕!该房间已过期,将无法再次游玩",
|
||||
}
|
||||
|
||||
-- card footnote
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -153,107 +153,6 @@ void Router::abortRequest() {
|
|||
}
|
||||
|
||||
void Router::handlePacket(const QByteArray &rawPacket) {
|
||||
#ifndef FK_CLIENT_ONLY
|
||||
static QMap<QString, void (*)(ServerPlayer *, const QString &)> 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) {
|
||||
|
|
|
@ -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<ServerPlayer *> 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<QString, room_cb> lobby_actions = {
|
||||
{"UpdateAvatar", updateAvatar},
|
||||
{"UpdatePassword", updatePassword},
|
||||
{"CreateRoom", createRoom},
|
||||
{"EnterRoom", enterRoom},
|
||||
{"ObserveRoom", observeRoom},
|
||||
{"RefreshRoomList", refreshRoomList},
|
||||
};
|
||||
|
||||
static const QMap<QString, room_cb> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "roomthread.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
#include <lua.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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 *> room_list;
|
||||
int m_capacity;
|
||||
QString md5;
|
||||
|
||||
lua_State *L;
|
||||
QMutex request_queue_mutex;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<QString, void (Shell::*)(QStringList &)> 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<QString, void (Shell::*)(QStringList &)> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
bool isTerminated() const;
|
||||
|
||||
bool isConsoleStart() const;
|
||||
bool isOutdated();
|
||||
};
|
||||
|
||||
%{
|
||||
|
|
Loading…
Reference in New Issue