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
|
const current = mainStack.currentItem; // should be lobby
|
||||||
if (mainStack.depth === 2) {
|
if (mainStack.depth === 2) {
|
||||||
current.roomModel.clear();
|
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({
|
current.roomModel.append({
|
||||||
roomId: room[0],
|
roomId, roomName, gameMode, playerNum, capacity,
|
||||||
roomName: room[1],
|
hasPassword, outdated,
|
||||||
gameMode: room[2],
|
|
||||||
playerNum: room[3],
|
|
||||||
capacity: room[4],
|
|
||||||
hasPassword: room[5] ? true : false,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,13 @@ Item {
|
||||||
Text {
|
Text {
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: roomName
|
text: {
|
||||||
|
let ret = roomName;
|
||||||
|
if (outdated) {
|
||||||
|
ret = '<font color="grey"><del>' + ret + '</del></font>';
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
font.pixelSize: 20
|
font.pixelSize: 20
|
||||||
elide: Label.ElideRight
|
elide: Label.ElideRight
|
||||||
}
|
}
|
||||||
|
@ -94,7 +100,7 @@ Item {
|
||||||
text: (playerNum < capacity) ? luatr("Enter") :
|
text: (playerNum < capacity) ? luatr("Enter") :
|
||||||
luatr("Observe")
|
luatr("Observe")
|
||||||
|
|
||||||
enabled: !opTimer.running
|
enabled: !opTimer.running && !outdated
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
opTimer.start();
|
opTimer.start();
|
||||||
|
|
|
@ -318,6 +318,10 @@
|
||||||
<source>room password error</source>
|
<source>room password error</source>
|
||||||
<translation>房间密码错误</translation>
|
<translation>房间密码错误</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>room is outdated</source>
|
||||||
|
<translation>房间已过时</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>no such room</source>
|
<source>no such room</source>
|
||||||
<translation>房间不存在</translation>
|
<translation>房间不存在</translation>
|
||||||
|
|
|
@ -495,6 +495,7 @@ Fk:loadTranslationTable{
|
||||||
["#ChainStateChange"] = "%from %arg 了武将牌",
|
["#ChainStateChange"] = "%from %arg 了武将牌",
|
||||||
["#ChainDamage"] = "%from 处于连环状态,将受到传导的伤害",
|
["#ChainDamage"] = "%from 处于连环状态,将受到传导的伤害",
|
||||||
["#ChangeKingdom"] = "%from 的国籍从 %arg 变成了 %arg2",
|
["#ChangeKingdom"] = "%from 的国籍从 %arg 变成了 %arg2",
|
||||||
|
["#RoomOutdated"] = "服务器更新完毕!该房间已过期,将无法再次游玩",
|
||||||
}
|
}
|
||||||
|
|
||||||
-- card footnote
|
-- card footnote
|
||||||
|
|
|
@ -181,7 +181,7 @@ request_handlers["newroom"] = function(s, id)
|
||||||
s:registerRoom(id)
|
s:registerRoom(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
request_handlers["reloadpackage"] = function(room, id, reqlist)
|
request_handlers["reloadpackage"] = function(_, _, reqlist)
|
||||||
if not IsConsoleStart() then return end
|
if not IsConsoleStart() then return end
|
||||||
local path = reqlist[3]
|
local path = reqlist[3]
|
||||||
Fk:reloadPackage(path)
|
Fk:reloadPackage(path)
|
||||||
|
|
|
@ -22,6 +22,8 @@ end)
|
||||||
|
|
||||||
-- 仿照Room接口编写的request协程处理器
|
-- 仿照Room接口编写的request协程处理器
|
||||||
local requestRoom = setmetatable({
|
local requestRoom = setmetatable({
|
||||||
|
id = -1,
|
||||||
|
runningRooms = runningRooms,
|
||||||
|
|
||||||
-- minDelayTime 是当没有任何就绪房间时,可以睡眠的时间。
|
-- minDelayTime 是当没有任何就绪房间时,可以睡眠的时间。
|
||||||
-- 因为这个时间是所有房间预期就绪用时的最小值,故称为minDelayTime。
|
-- 因为这个时间是所有房间预期就绪用时的最小值,故称为minDelayTime。
|
||||||
|
@ -130,6 +132,14 @@ local function mainLoop()
|
||||||
|
|
||||||
-- 调用RoomThread的trySleep函数开始真正的睡眠。会被wakeUp(c++)唤醒。
|
-- 调用RoomThread的trySleep函数开始真正的睡眠。会被wakeUp(c++)唤醒。
|
||||||
requestRoom.thread:trySleep(time)
|
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)
|
-- verbose('[!] Waked up after %f ms...', (os.getms() - cur) / 1000)
|
||||||
|
|
||||||
|
|
|
@ -153,107 +153,6 @@ void Router::abortRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Router::handlePacket(const QByteArray &rawPacket) {
|
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);
|
QJsonDocument packet = QJsonDocument::fromJson(rawPacket);
|
||||||
if (packet.isNull() || !packet.isArray())
|
if (packet.isNull() || !packet.isArray())
|
||||||
return;
|
return;
|
||||||
|
@ -278,35 +177,7 @@ void Router::handlePacket(const QByteArray &rawPacket) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Room *room = player->getRoom();
|
Room *room = player->getRoom();
|
||||||
if (room->isLobby() && lobby_actions.contains(command))
|
room->handlePacket(player, command, jsonData);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (type & TYPE_REQUEST) {
|
} else if (type & TYPE_REQUEST) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ Room::Room(RoomThread *m_thread) {
|
||||||
id = server->nextRoomId;
|
id = server->nextRoomId;
|
||||||
server->nextRoomId++;
|
server->nextRoomId++;
|
||||||
this->server = server;
|
this->server = server;
|
||||||
this->m_thread = m_thread;
|
setThread(m_thread);
|
||||||
if (m_thread) { // In case of lobby
|
if (m_thread) { // In case of lobby
|
||||||
m_thread->addRoom(this);
|
m_thread->addRoom(this);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,12 @@ Server *Room::getServer() const { return server; }
|
||||||
|
|
||||||
RoomThread *Room::getThread() const { return m_thread; }
|
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; }
|
int Room::getId() const { return id; }
|
||||||
|
|
||||||
|
@ -366,6 +371,12 @@ int Room::getTimeout() const { return timeout; }
|
||||||
|
|
||||||
void Room::setTimeout(int timeout) { this->timeout = 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; }
|
bool Room::isStarted() const { return gameStarted; }
|
||||||
|
|
||||||
void Room::doBroadcastNotify(const QList<ServerPlayer *> targets,
|
void Room::doBroadcastNotify(const QList<ServerPlayer *> targets,
|
||||||
|
@ -616,3 +627,186 @@ void Room::addRejectId(int id) {
|
||||||
void Room::removeRejectId(int id) {
|
void Room::removeRejectId(int id) {
|
||||||
rejected_players.removeOne(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;
|
int getTimeout() const;
|
||||||
void setTimeout(int timeout);
|
void setTimeout(int timeout);
|
||||||
|
|
||||||
|
bool isOutdated();
|
||||||
|
|
||||||
bool isStarted() const;
|
bool isStarted() const;
|
||||||
// ====================================}
|
// ====================================}
|
||||||
|
|
||||||
|
@ -65,6 +67,10 @@ class Room : public QObject {
|
||||||
|
|
||||||
void addRejectId(int id);
|
void addRejectId(int id);
|
||||||
void removeRejectId(int id);
|
void removeRejectId(int id);
|
||||||
|
|
||||||
|
// router用
|
||||||
|
void handlePacket(ServerPlayer *sender, const QString &command,
|
||||||
|
const QString &jsonData);
|
||||||
signals:
|
signals:
|
||||||
void abandoned();
|
void abandoned();
|
||||||
|
|
||||||
|
@ -90,6 +96,7 @@ class Room : public QObject {
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
|
||||||
int timeout;
|
int timeout;
|
||||||
|
QString md5;
|
||||||
|
|
||||||
void addRunRate(int id, const QString &mode);
|
void addRunRate(int id, const QString &mode);
|
||||||
void updatePlayerGameData(int id, const QString &mode);
|
void updatePlayerGameData(int id, const QString &mode);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "roomthread.h"
|
#include "roomthread.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include <lua.h>
|
||||||
|
|
||||||
#ifndef FK_SERVER_ONLY
|
#ifndef FK_SERVER_ONLY
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
@ -13,6 +14,7 @@ RoomThread::RoomThread(Server *m_server) {
|
||||||
this->m_server = m_server;
|
this->m_server = m_server;
|
||||||
m_capacity = 100; // TODO: server cfg
|
m_capacity = 100; // TODO: server cfg
|
||||||
terminated = false;
|
terminated = false;
|
||||||
|
md5 = m_server->getMd5();
|
||||||
|
|
||||||
L = CreateLuaState();
|
L = CreateLuaState();
|
||||||
DoLuaScript(L, "lua/freekill.lua");
|
DoLuaScript(L, "lua/freekill.lua");
|
||||||
|
@ -26,6 +28,7 @@ RoomThread::~RoomThread() {
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
|
m_server->removeThread(this);
|
||||||
// foreach (auto room, room_list) {
|
// foreach (auto room, room_list) {
|
||||||
// room->deleteLater();
|
// room->deleteLater();
|
||||||
// }
|
// }
|
||||||
|
@ -40,6 +43,8 @@ bool RoomThread::isFull() const {
|
||||||
return m_capacity <= 0;
|
return m_capacity <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString RoomThread::getMd5() const { return md5; }
|
||||||
|
|
||||||
Room *RoomThread::getRoom(int id) const {
|
Room *RoomThread::getRoom(int id) const {
|
||||||
return m_server->findRoom(id);
|
return m_server->findRoom(id);
|
||||||
}
|
}
|
||||||
|
@ -52,6 +57,10 @@ void RoomThread::addRoom(Room *room) {
|
||||||
void RoomThread::removeRoom(Room *room) {
|
void RoomThread::removeRoom(Room *room) {
|
||||||
room->setThread(nullptr);
|
room->setThread(nullptr);
|
||||||
m_capacity++;
|
m_capacity++;
|
||||||
|
if (m_capacity == 100 // TODO: server cfg
|
||||||
|
&& isOutdated()) {
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString RoomThread::fetchRequest() {
|
QString RoomThread::fetchRequest() {
|
||||||
|
@ -118,3 +127,13 @@ bool RoomThread::isConsoleStart() const {
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#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;
|
Server *getServer() const;
|
||||||
bool isFull() const;
|
bool isFull() const;
|
||||||
|
|
||||||
|
QString getMd5() const;
|
||||||
Room *getRoom(int id) const;
|
Room *getRoom(int id) const;
|
||||||
void addRoom(Room *room);
|
void addRoom(Room *room);
|
||||||
void removeRoom(Room *room);
|
void removeRoom(Room *room);
|
||||||
|
@ -32,6 +33,9 @@ class RoomThread : public QThread {
|
||||||
bool isTerminated() const;
|
bool isTerminated() const;
|
||||||
|
|
||||||
bool isConsoleStart() const;
|
bool isConsoleStart() const;
|
||||||
|
|
||||||
|
bool isOutdated();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
|
@ -39,6 +43,7 @@ class RoomThread : public QThread {
|
||||||
Server *m_server;
|
Server *m_server;
|
||||||
// QList<Room *> room_list;
|
// QList<Room *> room_list;
|
||||||
int m_capacity;
|
int m_capacity;
|
||||||
|
QString md5;
|
||||||
|
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
QMutex request_queue_mutex;
|
QMutex request_queue_mutex;
|
||||||
|
|
|
@ -112,14 +112,14 @@ void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
||||||
RoomThread *thread = nullptr;
|
RoomThread *thread = nullptr;
|
||||||
|
|
||||||
foreach (auto t, threads) {
|
foreach (auto t, threads) {
|
||||||
if (!t->isFull()) {
|
if (!t->isFull() && !t->isOutdated()) {
|
||||||
thread = t;
|
thread = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thread && nextRoomId != 0) {
|
if (!thread && nextRoomId != 0) {
|
||||||
thread = new RoomThread(this);
|
thread = createThread();
|
||||||
threads.append(thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!idle_rooms.isEmpty()) {
|
if (!idle_rooms.isEmpty()) {
|
||||||
|
@ -128,6 +128,7 @@ void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
||||||
nextRoomId++;
|
nextRoomId++;
|
||||||
room->setAbandoned(false);
|
room->setAbandoned(false);
|
||||||
room->setThread(thread);
|
room->setThread(thread);
|
||||||
|
thread->addRoom(room);
|
||||||
rooms.insert(room->getId(), room);
|
rooms.insert(room->getId(), room);
|
||||||
} else {
|
} else {
|
||||||
room = new Room(thread);
|
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; }
|
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); }
|
ServerPlayer *Server::findPlayer(int id) const { return players.value(id); }
|
||||||
|
|
||||||
void Server::addPlayer(ServerPlayer *player) {
|
void Server::addPlayer(ServerPlayer *player) {
|
||||||
|
@ -183,6 +194,7 @@ void Server::updateRoomList(ServerPlayer *teller) {
|
||||||
obj << count;
|
obj << count;
|
||||||
obj << cap;
|
obj << cap;
|
||||||
obj << !password.isEmpty();
|
obj << !password.isEmpty();
|
||||||
|
obj << room->isOutdated();
|
||||||
|
|
||||||
if (count == cap)
|
if (count == cap)
|
||||||
arr << obj;
|
arr << obj;
|
||||||
|
@ -670,6 +682,30 @@ void Server::endTransaction() {
|
||||||
transaction_mutex.unlock();
|
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() {
|
void Server::readPendingDatagrams() {
|
||||||
while (udpSocket->hasPendingDatagrams()) {
|
while (udpSocket->hasPendingDatagrams()) {
|
||||||
QNetworkDatagram datagram = udpSocket->receiveDatagram();
|
QNetworkDatagram datagram = udpSocket->receiveDatagram();
|
||||||
|
|
|
@ -31,6 +31,9 @@ public:
|
||||||
Room *findRoom(int id) const;
|
Room *findRoom(int id) const;
|
||||||
Room *lobby() const;
|
Room *lobby() const;
|
||||||
|
|
||||||
|
RoomThread *createThread();
|
||||||
|
void removeThread(RoomThread *thread);
|
||||||
|
|
||||||
ServerPlayer *findPlayer(int id) const;
|
ServerPlayer *findPlayer(int id) const;
|
||||||
void addPlayer(ServerPlayer *player);
|
void addPlayer(ServerPlayer *player);
|
||||||
void removePlayer(int id);
|
void removePlayer(int id);
|
||||||
|
@ -50,6 +53,9 @@ public:
|
||||||
void beginTransaction();
|
void beginTransaction();
|
||||||
void endTransaction();
|
void endTransaction();
|
||||||
|
|
||||||
|
const QString &getMd5() const;
|
||||||
|
void refreshMd5();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void roomCreated(Room *room);
|
void roomCreated(Room *room);
|
||||||
void playerAdded(ServerPlayer *player);
|
void playerAdded(ServerPlayer *player);
|
||||||
|
|
|
@ -117,11 +117,13 @@ void Shell::upgradeCommand(QStringList &list) {
|
||||||
auto obj = a.toObject();
|
auto obj = a.toObject();
|
||||||
Pacman->upgradePack(obj["name"].toString());
|
Pacman->upgradePack(obj["name"].toString());
|
||||||
}
|
}
|
||||||
|
ServerInstance->refreshMd5();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pack = list[0];
|
auto pack = list[0];
|
||||||
Pacman->upgradePack(pack);
|
Pacman->upgradePack(pack);
|
||||||
|
ServerInstance->refreshMd5();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::enableCommand(QStringList &list) {
|
void Shell::enableCommand(QStringList &list) {
|
||||||
|
@ -132,6 +134,7 @@ void Shell::enableCommand(QStringList &list) {
|
||||||
|
|
||||||
auto pack = list[0];
|
auto pack = list[0];
|
||||||
Pacman->enablePack(pack);
|
Pacman->enablePack(pack);
|
||||||
|
ServerInstance->refreshMd5();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::disableCommand(QStringList &list) {
|
void Shell::disableCommand(QStringList &list) {
|
||||||
|
@ -142,6 +145,7 @@ void Shell::disableCommand(QStringList &list) {
|
||||||
|
|
||||||
auto pack = list[0];
|
auto pack = list[0];
|
||||||
Pacman->disablePack(pack);
|
Pacman->disablePack(pack);
|
||||||
|
ServerInstance->refreshMd5();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::lspkgCommand(QStringList &) {
|
void Shell::lspkgCommand(QStringList &) {
|
||||||
|
@ -380,33 +384,32 @@ Shell::Shell() {
|
||||||
setObjectName("Shell");
|
setObjectName("Shell");
|
||||||
signal(SIGINT, sigintHandler);
|
signal(SIGINT, sigintHandler);
|
||||||
|
|
||||||
static QHash<QString, void (Shell::*)(QStringList &)> handlers;
|
static const QHash<QString, void (Shell::*)(QStringList &)> handlers = {
|
||||||
if (handlers.size() == 0) {
|
{"help", &Shell::helpCommand},
|
||||||
handlers["help"] = &Shell::helpCommand;
|
{"?", &Shell::helpCommand},
|
||||||
handlers["?"] = &Shell::helpCommand;
|
{"lsplayer", &Shell::lspCommand},
|
||||||
handlers["lsplayer"] = &Shell::lspCommand;
|
{"lsroom", &Shell::lsrCommand},
|
||||||
handlers["lsroom"] = &Shell::lsrCommand;
|
{"install", &Shell::installCommand},
|
||||||
handlers["install"] = &Shell::installCommand;
|
{"remove", &Shell::removeCommand},
|
||||||
handlers["remove"] = &Shell::removeCommand;
|
{"upgrade", &Shell::upgradeCommand},
|
||||||
handlers["upgrade"] = &Shell::upgradeCommand;
|
{"u", &Shell::upgradeCommand},
|
||||||
handlers["u"] = &Shell::upgradeCommand;
|
{"lspkg", &Shell::lspkgCommand},
|
||||||
handlers["lspkg"] = &Shell::lspkgCommand;
|
{"enable", &Shell::enableCommand},
|
||||||
handlers["enable"] = &Shell::enableCommand;
|
{"disable", &Shell::disableCommand},
|
||||||
handlers["disable"] = &Shell::disableCommand;
|
{"kick", &Shell::kickCommand},
|
||||||
handlers["kick"] = &Shell::kickCommand;
|
{"msg", &Shell::msgCommand},
|
||||||
handlers["msg"] = &Shell::msgCommand;
|
{"m", &Shell::msgCommand},
|
||||||
handlers["m"] = &Shell::msgCommand;
|
{"ban", &Shell::banCommand},
|
||||||
handlers["ban"] = &Shell::banCommand;
|
{"unban", &Shell::unbanCommand},
|
||||||
handlers["unban"] = &Shell::unbanCommand;
|
{"banip", &Shell::banipCommand},
|
||||||
handlers["banip"] = &Shell::banipCommand;
|
{"unbanip", &Shell::unbanipCommand},
|
||||||
handlers["unbanip"] = &Shell::unbanipCommand;
|
{"banuuid", &Shell::banUuidCommand},
|
||||||
handlers["banuuid"] = &Shell::banUuidCommand;
|
{"unbanuuid", &Shell::unbanUuidCommand},
|
||||||
handlers["unbanuuid"] = &Shell::unbanUuidCommand;
|
{"reloadconf", &Shell::reloadConfCommand},
|
||||||
handlers["reloadconf"] = &Shell::reloadConfCommand;
|
{"r", &Shell::reloadConfCommand},
|
||||||
handlers["r"] = &Shell::reloadConfCommand;
|
{"resetpassword", &Shell::resetPasswordCommand},
|
||||||
handlers["resetpassword"] = &Shell::resetPasswordCommand;
|
{"rp", &Shell::resetPasswordCommand},
|
||||||
handlers["rp"] = &Shell::resetPasswordCommand;
|
};
|
||||||
}
|
|
||||||
handler_map = handlers;
|
handler_map = handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
bool isTerminated() const;
|
bool isTerminated() const;
|
||||||
|
|
||||||
bool isConsoleStart() const;
|
bool isConsoleStart() const;
|
||||||
|
bool isOutdated();
|
||||||
};
|
};
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
Loading…
Reference in New Issue