parent
e9a81cd185
commit
6097f0b389
|
@ -36,7 +36,7 @@ local function tellRoomToObserver(self, player)
|
|||
player:doNotify("UpdateDrawPile", #self.draw_pile)
|
||||
player:doNotify("UpdateRoundNum", self:getTag("RoundCount") or 0)
|
||||
|
||||
table.insert(self.observers, {observee.id, player})
|
||||
table.insert(self.observers, {observee.id, player, player:getId()})
|
||||
end
|
||||
|
||||
local function addObserver(self, id)
|
||||
|
@ -56,12 +56,10 @@ end
|
|||
|
||||
local function removeObserver(self, id)
|
||||
for _, t in ipairs(self.observers) do
|
||||
local __, p = table.unpack(t)
|
||||
if p:getId() == id then
|
||||
local pid = t[3]
|
||||
if pid == id then
|
||||
table.removeOne(self.observers, t)
|
||||
self:doBroadcastNotify("RemoveObserver", json.encode{
|
||||
p:getId(),
|
||||
})
|
||||
self:doBroadcastNotify("RemoveObserver", json.encode{ pid })
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,7 +47,7 @@ function ServerPlayer:doNotify(command, jsonData)
|
|||
local room = self.room
|
||||
for _, t in ipairs(room.observers) do
|
||||
local id, p = table.unpack(t)
|
||||
if id == self.id then
|
||||
if id == self.id and room.room:hasObserver(p) then
|
||||
p:doNotify(command, jsonData)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,15 @@ CREATE TABLE IF NOT EXISTS banip (
|
|||
ip VARCHAR(64)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS uuidinfo (
|
||||
id INTEGER PRIMARY KEY,
|
||||
uuid VARCHAR(32)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS banuuid (
|
||||
uuid VARCHAR(32)
|
||||
);
|
||||
|
||||
-- 胜率相关
|
||||
|
||||
CREATE TABLE IF NOT EXISTS winRate (
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <qcryptographichash.h>
|
||||
#include <qnamespace.h>
|
||||
#include <qregularexpression.h>
|
||||
#include <QSysInfo>
|
||||
|
||||
extern "C" {
|
||||
int luaopen_fk(lua_State *);
|
||||
|
@ -203,6 +204,10 @@ QJsonDocument String2Json(const QString &str) {
|
|||
return QJsonDocument::fromJson(bytes);
|
||||
}
|
||||
|
||||
QString GetDeviceUuid() {
|
||||
return QSysInfo::machineUniqueId();
|
||||
}
|
||||
|
||||
QString Color(const QString &raw, fkShell::TextColor color,
|
||||
fkShell::TextType type) {
|
||||
#ifdef Q_OS_LINUX
|
||||
|
|
|
@ -20,6 +20,8 @@ QString calcFileMD5();
|
|||
QByteArray JsonArray2Bytes(const QJsonArray &arr);
|
||||
QJsonDocument String2Json(const QString &str);
|
||||
|
||||
QString GetDeviceUuid();
|
||||
|
||||
namespace fkShell {
|
||||
enum TextColor {
|
||||
Black,
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
#include <qjsonarray.h>
|
||||
#include <qjsondocument.h>
|
||||
|
||||
#ifdef FK_SERVER_ONLY
|
||||
static void *ClientInstance = nullptr;
|
||||
#else
|
||||
#include "client.h"
|
||||
#endif
|
||||
|
||||
#include "client_socket.h"
|
||||
#include "roomthread.h"
|
||||
#include "server.h"
|
||||
|
@ -268,15 +273,15 @@ void Room::removePlayer(ServerPlayer *player) {
|
|||
// 原先的跑路机器人会在游戏结束后自动销毁掉
|
||||
server->addPlayer(runner);
|
||||
|
||||
// 如果走小道的人不是单机启动玩家 那么直接ban
|
||||
if (!ClientInstance && !player->isDied()) {
|
||||
server->temporarilyBan(runner->getId());
|
||||
}
|
||||
|
||||
m_thread->wakeUp();
|
||||
|
||||
// 发出信号,让大厅添加这个人
|
||||
emit playerRemoved(runner);
|
||||
|
||||
// 如果走小道的人不是单机启动玩家 那么直接ban
|
||||
if (!ClientInstance && !player->isDied()) {
|
||||
server->temporarilyBan(runner->getId());
|
||||
}
|
||||
}
|
||||
|
||||
// 如果房间空了,就把房间标为废弃,Server有信号处理函数的
|
||||
|
@ -341,6 +346,8 @@ void Room::removeObserver(ServerPlayer *player) {
|
|||
|
||||
QList<ServerPlayer *> Room::getObservers() const { return observers; }
|
||||
|
||||
bool Room::hasObserver(ServerPlayer *player) const { return observers.contains(player); }
|
||||
|
||||
int Room::getTimeout() const { return timeout; }
|
||||
|
||||
void Room::setTimeout(int timeout) { this->timeout = timeout; }
|
||||
|
|
|
@ -45,6 +45,7 @@ class Room : public QObject {
|
|||
void addObserver(ServerPlayer *player);
|
||||
void removeObserver(ServerPlayer *player);
|
||||
QList<ServerPlayer *> getObservers() const;
|
||||
bool hasObserver(ServerPlayer *player) const;
|
||||
|
||||
int getTimeout() const;
|
||||
void setTimeout(int timeout);
|
||||
|
|
|
@ -273,7 +273,7 @@ void Server::processRequest(const QByteArray &msg) {
|
|||
doc[2] != "Setup")
|
||||
valid = false;
|
||||
else
|
||||
valid = (String2Json(doc[3].toString()).array().size() == 4);
|
||||
valid = (String2Json(doc[3].toString()).array().size() == 5);
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
|
@ -313,13 +313,34 @@ void Server::processRequest(const QByteArray &msg) {
|
|||
return;
|
||||
}
|
||||
|
||||
auto uuid = arr[4].toString();
|
||||
auto result2 = QJsonArray({1});
|
||||
if (CheckSqlString(uuid)) {
|
||||
result2 = SelectFromDatabase(
|
||||
db, QString("SELECT * FROM banuuid WHERE uuid='%1';").arg(uuid));
|
||||
}
|
||||
|
||||
if (!result2.isEmpty()) {
|
||||
QJsonArray body;
|
||||
body << -2;
|
||||
body << (Router::TYPE_NOTIFICATION | Router::SRC_SERVER |
|
||||
Router::DEST_CLIENT);
|
||||
body << "ErrorMsg";
|
||||
body << "you have been banned!";
|
||||
client->send(JsonArray2Bytes(body));
|
||||
qInfo() << "Refused banned UUID:" << uuid;
|
||||
client->disconnectFromHost();
|
||||
return;
|
||||
}
|
||||
|
||||
handleNameAndPassword(client, arr[0].toString(), arr[1].toString(),
|
||||
arr[2].toString());
|
||||
arr[2].toString(), uuid);
|
||||
}
|
||||
|
||||
void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
|
||||
const QString &password,
|
||||
const QString &md5_str) {
|
||||
const QString &md5_str,
|
||||
const QString &uuid_str) {
|
||||
auto encryted_pw = QByteArray::fromBase64(password.toLatin1());
|
||||
unsigned char buf[4096] = {0};
|
||||
RSA_private_decrypt(RSA_size(rsa), (const unsigned char *)encryted_pw.data(),
|
||||
|
@ -462,6 +483,9 @@ void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
|
|||
.arg(obj["id"].toString().toInt());
|
||||
ExecSQL(db, sql_update);
|
||||
|
||||
auto uuid_update = QString("REPLACE INTO uuidinfo (id, uuid) VALUES (%1, '%2');").arg(obj["id"].toString().toInt()).arg(uuid_str);
|
||||
ExecSQL(db, uuid_update);
|
||||
|
||||
// create new ServerPlayer and setup
|
||||
ServerPlayer *player = new ServerPlayer(lobby());
|
||||
player->setSocket(client);
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
void readConfig();
|
||||
|
||||
void handleNameAndPassword(ClientSocket *client, const QString &name,
|
||||
const QString &password, const QString &md5_str);
|
||||
const QString &password, const QString &md5_str, const QString &uuid_str);
|
||||
void processDatagram(const QByteArray &msg, const QHostAddress &addr, uint port);
|
||||
};
|
||||
|
||||
|
|
|
@ -29,16 +29,24 @@ void Shell::helpCommand(QStringList &) {
|
|||
HELP_MSG("%s: List all running rooms.", "lsroom");
|
||||
HELP_MSG("%s: Kick a player by his <id>.", "kick");
|
||||
HELP_MSG("%s: Broadcast message.", "msg");
|
||||
HELP_MSG("%s: Ban 1 or more accounts by their <name>.", "ban");
|
||||
HELP_MSG("%s: Ban 1 or more accounts, IP, UUID by their <name>.", "ban");
|
||||
HELP_MSG("%s: Unban 1 or more accounts by their <name>.", "unban");
|
||||
HELP_MSG(
|
||||
"%s: Ban 1 or more IP address according to somebody's 'lastLoginIp'. "
|
||||
"%s: Ban 1 or more IP address. "
|
||||
"At least 1 <name> required.",
|
||||
"banip");
|
||||
HELP_MSG(
|
||||
"%s: Unban 1 or more IP address according to somebody's 'lastLoginIp'. "
|
||||
"%s: Unban 1 or more IP address. "
|
||||
"At least 1 <name> required.",
|
||||
"unbanip");
|
||||
HELP_MSG(
|
||||
"%s: Ban 1 or more UUID. "
|
||||
"At least 1 <name> required.",
|
||||
"banuuid");
|
||||
HELP_MSG(
|
||||
"%s: Unban 1 or more UUID. "
|
||||
"At least 1 <name> required.",
|
||||
"unbanuuid");
|
||||
qInfo();
|
||||
qInfo("===== Package commands =====");
|
||||
HELP_MSG("%s: Install a new package from <url>.", "install");
|
||||
|
@ -207,6 +215,9 @@ void Shell::banCommand(QStringList &list) {
|
|||
foreach (auto name, list) {
|
||||
banAccount(db, name, true);
|
||||
}
|
||||
|
||||
banipCommand(list);
|
||||
banUuidCommand(list);
|
||||
}
|
||||
|
||||
void Shell::unbanCommand(QStringList &list) {
|
||||
|
@ -220,7 +231,11 @@ void Shell::unbanCommand(QStringList &list) {
|
|||
foreach (auto name, list) {
|
||||
banAccount(db, name, false);
|
||||
}
|
||||
|
||||
unbanipCommand(list);
|
||||
unbanUuidCommand(list);
|
||||
}
|
||||
|
||||
static void banIPByName(sqlite3 *db, const QString &name, bool banned) {
|
||||
if (!CheckSqlString(name))
|
||||
return;
|
||||
|
@ -275,6 +290,65 @@ void Shell::unbanipCommand(QStringList &list) {
|
|||
}
|
||||
}
|
||||
|
||||
static void banUuidByName(sqlite3 *db, const QString &name, bool banned) {
|
||||
if (!CheckSqlString(name))
|
||||
return;
|
||||
|
||||
QString sql_find = QString("SELECT * FROM userinfo \
|
||||
WHERE name='%1';")
|
||||
.arg(name);
|
||||
auto result = SelectFromDatabase(db, sql_find);
|
||||
if (result.isEmpty())
|
||||
return;
|
||||
auto obj = result[0].toObject();
|
||||
int id = obj["id"].toString().toInt();
|
||||
|
||||
auto result2 = SelectFromDatabase(db, QString("SELECT * FROM uuidinfo WHERE id=%1;").arg(id));
|
||||
if (result2.isEmpty())
|
||||
return;
|
||||
|
||||
auto uuid = result2[0].toObject()["uuid"].toString();
|
||||
|
||||
if (banned) {
|
||||
ExecSQL(db, QString("INSERT INTO banuuid VALUES('%1');").arg(uuid));
|
||||
|
||||
auto p = ServerInstance->findPlayer(id);
|
||||
if (p) {
|
||||
p->kicked();
|
||||
}
|
||||
qInfo("Banned UUID %s.", uuid.toUtf8().constData());
|
||||
} else {
|
||||
ExecSQL(db, QString("DELETE FROM banuuid WHERE uuid='%1';").arg(uuid));
|
||||
qInfo("Unbanned UUID %s.", uuid.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void Shell::banUuidCommand(QStringList &list) {
|
||||
if (list.isEmpty()) {
|
||||
qWarning("The 'banuuid' command needs at least 1 <name>.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto db = ServerInstance->getDatabase();
|
||||
|
||||
foreach (auto name, list) {
|
||||
banUuidByName(db, name, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Shell::unbanUuidCommand(QStringList &list) {
|
||||
if (list.isEmpty()) {
|
||||
qWarning("The 'unbanuuid' command needs at least 1 <name>.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto db = ServerInstance->getDatabase();
|
||||
|
||||
foreach (auto name, list) {
|
||||
banUuidByName(db, name, false);
|
||||
}
|
||||
}
|
||||
|
||||
Shell::Shell() {
|
||||
setObjectName("Shell");
|
||||
signal(SIGINT, sigintHandler);
|
||||
|
@ -297,6 +371,8 @@ Shell::Shell() {
|
|||
handlers["unban"] = &Shell::unbanCommand;
|
||||
handlers["banip"] = &Shell::banipCommand;
|
||||
handlers["unbanip"] = &Shell::unbanipCommand;
|
||||
handlers["banuuid"] = &Shell::banUuidCommand;
|
||||
handlers["unbanuuid"] = &Shell::unbanUuidCommand;
|
||||
}
|
||||
handler_map = handlers;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,10 @@ private:
|
|||
void msgCommand(QStringList &);
|
||||
void banCommand(QStringList &);
|
||||
void banipCommand(QStringList &);
|
||||
void banUuidCommand(QStringList &);
|
||||
void unbanCommand(QStringList &);
|
||||
void unbanipCommand(QStringList &);
|
||||
void unbanUuidCommand(QStringList &);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@ public:
|
|||
QList<ServerPlayer *> getPlayers() const;
|
||||
|
||||
QList<ServerPlayer *> getObservers() const;
|
||||
bool hasObserver(ServerPlayer *player) const;
|
||||
int getTimeout() const;
|
||||
void checkAbandoned();
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ void QmlBackend::replyDelayTest(const QString &screenName,
|
|||
auto md5 = calcFileMD5();
|
||||
|
||||
QJsonArray arr;
|
||||
arr << screenName << cipher << md5 << FK_VERSION;
|
||||
arr << screenName << cipher << md5 << FK_VERSION << GetDeviceUuid();
|
||||
ClientInstance->notifyServer("Setup", JsonArray2Bytes(arr));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue