Dev (#233)
- 以不存在的游戏模式开房时,自动替换成身份局 - 烧条满3管直接踢 - 游戏结束时掉线玩家(可能故意杀后台逃跑的)会受到逃跑惩罚 - 修git闪退的bug - 关于页面补全作者信息 - 增加重载配置文件的shell命令 - 禁将方案切换
This commit is contained in:
parent
8bfe087374
commit
cc0228dc03
|
@ -24,6 +24,8 @@ QtObject {
|
||||||
property bool disableMsgAudio
|
property bool disableMsgAudio
|
||||||
property bool hideUseless
|
property bool hideUseless
|
||||||
property var disabledGenerals: []
|
property var disabledGenerals: []
|
||||||
|
property var disableGeneralSchemes: []
|
||||||
|
property int disableSchemeIdx: 0
|
||||||
|
|
||||||
property int preferredTimeout
|
property int preferredTimeout
|
||||||
property int preferredLuckTime
|
property int preferredLuckTime
|
||||||
|
@ -43,6 +45,10 @@ QtObject {
|
||||||
property bool replaying: false
|
property bool replaying: false
|
||||||
property var blockedUsers: []
|
property var blockedUsers: []
|
||||||
|
|
||||||
|
onDisabledGeneralsChanged: {
|
||||||
|
disableGeneralSchemes[disableSchemeIdx] = disabledGenerals;
|
||||||
|
}
|
||||||
|
|
||||||
function loadConf() {
|
function loadConf() {
|
||||||
conf = JSON.parse(Backend.loadConf());
|
conf = JSON.parse(Backend.loadConf());
|
||||||
winX = conf.winX ?? 100;
|
winX = conf.winX ?? 100;
|
||||||
|
@ -67,6 +73,8 @@ QtObject {
|
||||||
preferredTimeout = conf.preferredTimeout ?? 15;
|
preferredTimeout = conf.preferredTimeout ?? 15;
|
||||||
preferredLuckTime = conf.preferredLuckTime ?? 0;
|
preferredLuckTime = conf.preferredLuckTime ?? 0;
|
||||||
disabledGenerals = conf.disabledGenerals ?? [];
|
disabledGenerals = conf.disabledGenerals ?? [];
|
||||||
|
disableGeneralSchemes = conf.disableGeneralSchemes ?? [ disabledGenerals ];
|
||||||
|
disableSchemeIdx = conf.disableSchemeIdx ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveConf() {
|
function saveConf() {
|
||||||
|
@ -92,6 +100,8 @@ QtObject {
|
||||||
conf.preferredTimeout = preferredTimeout;
|
conf.preferredTimeout = preferredTimeout;
|
||||||
conf.preferredLuckTime = preferredLuckTime;
|
conf.preferredLuckTime = preferredLuckTime;
|
||||||
conf.disabledGenerals = disabledGenerals;
|
conf.disabledGenerals = disabledGenerals;
|
||||||
|
conf.disableGeneralSchemes = disableGeneralSchemes;
|
||||||
|
conf.disableSchemeIdx = disableSchemeIdx;
|
||||||
|
|
||||||
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: "禁将方案"
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: banCombo
|
||||||
|
textRole: "name"
|
||||||
|
model: ListModel {
|
||||||
|
id: banComboList
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
config.disableSchemeIdx = currentIndex;
|
||||||
|
config.disabledGenerals = config.disableGeneralSchemes[currentIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "新建"
|
||||||
|
onClicked: {
|
||||||
|
const i = config.disableGeneralSchemes.length;
|
||||||
|
banComboList.append({
|
||||||
|
name: "方案" + (i + 1),
|
||||||
|
});
|
||||||
|
config.disableGeneralSchemes.push([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "清空"
|
||||||
|
onClicked: {
|
||||||
|
config.disabledGenerals = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.margins: 8
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
text: "导出键会将这个方案的内容复制到剪贴板中;" +
|
||||||
|
"导入键会自动读取剪贴板,若可以导入则导入,不能导入则报错。"
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
text: "导出"
|
||||||
|
onClicked: {
|
||||||
|
Backend.copyToClipboard(JSON.stringify(config.disabledGenerals));
|
||||||
|
toast.show("该禁将方案已经复制到剪贴板。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "导入"
|
||||||
|
onClicked: {
|
||||||
|
const str = Backend.readClipboard();
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
data = JSON.parse(str);
|
||||||
|
} catch (e) {
|
||||||
|
toast.show("导入失败:不是合法的JSON字符串。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!data instanceof Array) {
|
||||||
|
toast.show("导入失败:数据格式不对。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let e of data) {
|
||||||
|
if (!(typeof e === "string" && Backend.translate(e) !== e)) {
|
||||||
|
toast.show("导入失败:含有未知的武将。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config.disabledGenerals = data;
|
||||||
|
toast.show("导入禁将方案成功。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: listView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
clip: true
|
||||||
|
cellWidth: width / 2
|
||||||
|
cellHeight: 24
|
||||||
|
model: config.disabledGenerals
|
||||||
|
delegate: Text {
|
||||||
|
width: listView.width
|
||||||
|
text: {
|
||||||
|
const prefix = modelData.split("__")[0];
|
||||||
|
let name = Backend.translate(modelData);
|
||||||
|
if (prefix !== modelData) {
|
||||||
|
name += (" (" + Backend.translate(prefix) + ")");
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
font.pixelSize: 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (let i = 0; i < config.disableGeneralSchemes.length; i++) {
|
||||||
|
banComboList.append({
|
||||||
|
name: "方案" + (i + 1),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
banCombo.currentIndex = config.disableSchemeIdx;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,9 @@ Item {
|
||||||
TabButton {
|
TabButton {
|
||||||
text: Backend.translate("Audio Settings")
|
text: Backend.translate("Audio Settings")
|
||||||
}
|
}
|
||||||
|
TabButton {
|
||||||
|
text: Backend.translate("Ban General Settings")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SwipeView {
|
SwipeView {
|
||||||
|
@ -36,5 +39,6 @@ Item {
|
||||||
UserInfo {}
|
UserInfo {}
|
||||||
BGSetting {}
|
BGSetting {}
|
||||||
AudioSetting {}
|
AudioSetting {}
|
||||||
|
BanGeneralSetting {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,10 +106,12 @@ Item {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (pkgEnabled === "0") {
|
if (pkgEnabled === "0") {
|
||||||
Pacman.enablePack(pkgName);
|
Pacman.enablePack(pkgName);
|
||||||
|
pkgEnabled = "1";
|
||||||
} else {
|
} else {
|
||||||
Pacman.disablePack(pkgName);
|
Pacman.disablePack(pkgName);
|
||||||
|
pkgEnabled = "0";
|
||||||
}
|
}
|
||||||
updatePackageList();
|
// updatePackageList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +122,15 @@ Item {
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: 8
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Pacman.upgradePack(pkgName);
|
Pacman.upgradePack(pkgName);
|
||||||
updatePackageList();
|
// updatePackageList();
|
||||||
|
const data = JSON.parse(Pacman.listPackages());
|
||||||
|
const e = data[index];
|
||||||
|
packageModel.set(index, {
|
||||||
|
pkgName: e.name,
|
||||||
|
pkgURL: e.url,
|
||||||
|
pkgVersion: e.hash.substring(0, 8),
|
||||||
|
pkgEnabled: e.enabled
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +141,8 @@ Item {
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: 8
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Pacman.removePack(pkgName);
|
Pacman.removePack(pkgName);
|
||||||
updatePackageList();
|
// updatePackageList();
|
||||||
|
packageModel.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,7 @@ Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - bar.height
|
height: parent.height - bar.height
|
||||||
anchors.top: bar.bottom
|
anchors.top: bar.bottom
|
||||||
color: "snow"
|
color: "#A0EFEFEF"
|
||||||
opacity: 0.75
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
|
|
|
@ -24,6 +24,7 @@ Fk:loadTranslationTable{
|
||||||
["Audio Settings"] = "音频",
|
["Audio Settings"] = "音频",
|
||||||
["Disable message audio"] = "禁用聊天语音",
|
["Disable message audio"] = "禁用聊天语音",
|
||||||
["Hide unselectable cards"] = "下移不可选卡牌",
|
["Hide unselectable cards"] = "下移不可选卡牌",
|
||||||
|
["Ban General Settings"] = "禁将",
|
||||||
["Back"] = "返回",
|
["Back"] = "返回",
|
||||||
|
|
||||||
["Refresh Room List"] = "刷新房间列表",
|
["Refresh Room List"] = "刷新房间列表",
|
||||||
|
@ -84,13 +85,24 @@ Fk:loadTranslationTable{
|
||||||
以便于DIY为首要目的的开源三国杀游戏。
|
以便于DIY为首要目的的开源三国杀游戏。
|
||||||
|
|
||||||
项目链接: https://github.com/Notify-ctrl/FreeKill
|
项目链接: https://github.com/Notify-ctrl/FreeKill
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
作者: Notify Ho-spair
|
||||||
|
|
||||||
|
开发者: RalphR Nyutanislavsky xxyheaven 妖梦厨
|
||||||
|
|
||||||
|
贡献者: 假象 deepskybird 板蓝根
|
||||||
|
|
||||||
|
鸣谢: Mogara
|
||||||
|
|
||||||
]],
|
]],
|
||||||
["about_qt_description"] = [[
|
["about_qt_description"] = [[
|
||||||
# 关于Qt
|
# 关于Qt
|
||||||
|
|
||||||
Qt是一个C++图形界面应用程序开发框架,拥有强大的跨平台能力以及易于使用的API。
|
Qt是一个C++图形界面应用程序开发框架,拥有强大的跨平台能力以及易于使用的API。
|
||||||
|
|
||||||
本程序使用Qt 6.2+,主要利用QtQuick开发UI,同时也使用Qt的网络库开发服务端程序。
|
本程序使用Qt 6.4,主要利用QtQuick开发UI,同时也使用Qt的网络库开发服务端程序。
|
||||||
|
|
||||||
官网: https://www.qt.io
|
官网: https://www.qt.io
|
||||||
]],
|
]],
|
||||||
|
|
|
@ -94,6 +94,10 @@ function Room:initialize(_room)
|
||||||
|
|
||||||
self.settings = json.decode(self.room:settings())
|
self.settings = json.decode(self.room:settings())
|
||||||
self.disabled_packs = self.settings.disabledPack
|
self.disabled_packs = self.settings.disabledPack
|
||||||
|
if not Fk.game_modes[self.settings.gameMode] then
|
||||||
|
self.settings.gameMode = "aaa_role_mode"
|
||||||
|
end
|
||||||
|
|
||||||
table.insertTable(self.disabled_packs, Fk.game_mode_disabled[self.settings.gameMode])
|
table.insertTable(self.disabled_packs, Fk.game_mode_disabled[self.settings.gameMode])
|
||||||
self.disabled_generals = self.settings.disabledGenerals
|
self.disabled_generals = self.settings.disabledGenerals
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
---@field public phase_state table[]
|
---@field public phase_state table[]
|
||||||
---@field public phase_index integer
|
---@field public phase_index integer
|
||||||
---@field public role_shown boolean
|
---@field public role_shown boolean
|
||||||
|
---@field private _timewaste_count integer
|
||||||
---@field public ai AI
|
---@field public ai AI
|
||||||
---@field public ai_data any
|
---@field public ai_data any
|
||||||
local ServerPlayer = Player:subclass("ServerPlayer")
|
local ServerPlayer = Player:subclass("ServerPlayer")
|
||||||
|
@ -34,6 +35,7 @@ function ServerPlayer:initialize(_self)
|
||||||
self.reply_cancel = false
|
self.reply_cancel = false
|
||||||
self.phases = {}
|
self.phases = {}
|
||||||
self.skipped_phases = {}
|
self.skipped_phases = {}
|
||||||
|
self._timewaste_count = 0
|
||||||
self.ai = RandomAI:new(self)
|
self.ai = RandomAI:new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -113,12 +115,19 @@ local function _waitForReply(player, timeout)
|
||||||
player.serverplayer:setThinking(true)
|
player.serverplayer:setThinking(true)
|
||||||
result = player.serverplayer:waitForReply(0)
|
result = player.serverplayer:waitForReply(0)
|
||||||
if result ~= "__notready" then
|
if result ~= "__notready" then
|
||||||
|
player._timewaste_count = 0
|
||||||
player.serverplayer:setThinking(false)
|
player.serverplayer:setThinking(false)
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
local rest = timeout * 1000 - (os.getms() - start) / 1000
|
local rest = timeout * 1000 - (os.getms() - start) / 1000
|
||||||
if timeout and rest <= 0 then
|
if timeout and rest <= 0 then
|
||||||
|
player._timewaste_count = player._timewaste_count + 1
|
||||||
player.serverplayer:setThinking(false)
|
player.serverplayer:setThinking(false)
|
||||||
|
|
||||||
|
if player._timewaste_count >= 3 then
|
||||||
|
player.serverplayer:emitKick()
|
||||||
|
end
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,20 @@ PackMan *Pacman;
|
||||||
PackMan::PackMan(QObject *parent) : QObject(parent) {
|
PackMan::PackMan(QObject *parent) : QObject(parent) {
|
||||||
git_libgit2_init();
|
git_libgit2_init();
|
||||||
db = OpenDatabase("./packages/packages.db", "./packages/init.sql");
|
db = OpenDatabase("./packages/packages.db", "./packages/init.sql");
|
||||||
|
|
||||||
|
QDir d("packages");
|
||||||
|
foreach (auto e, SelectFromDatabase(db, "SELECT name, enabled FROM packages;")) {
|
||||||
|
auto obj = e.toObject();
|
||||||
|
auto pack = obj["name"].toString();
|
||||||
|
auto enabled = obj["enabled"].toString().toInt() == 1;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
d.rename(pack + ".disabled", pack);
|
||||||
|
} else {
|
||||||
|
d.rename(pack, pack + ".disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, "./certs");
|
git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, "./certs");
|
||||||
#endif
|
#endif
|
||||||
|
@ -128,16 +142,24 @@ void PackMan::enablePack(const QString &pack) {
|
||||||
ExecSQL(
|
ExecSQL(
|
||||||
db,
|
db,
|
||||||
QString("UPDATE packages SET enabled = 1 WHERE name = '%1';").arg(pack));
|
QString("UPDATE packages SET enabled = 1 WHERE name = '%1';").arg(pack));
|
||||||
QDir d(QString("packages"));
|
QDir d("packages");
|
||||||
d.rename(pack + ".disabled", pack);
|
int i = 0;
|
||||||
|
while (!d.rename(pack + ".disabled", pack) && i < 3) {
|
||||||
|
QThread::currentThread()->msleep(1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackMan::disablePack(const QString &pack) {
|
void PackMan::disablePack(const QString &pack) {
|
||||||
ExecSQL(
|
ExecSQL(
|
||||||
db,
|
db,
|
||||||
QString("UPDATE packages SET enabled = 0 WHERE name = '%1';").arg(pack));
|
QString("UPDATE packages SET enabled = 0 WHERE name = '%1';").arg(pack));
|
||||||
QDir d(QString("packages"));
|
QDir d("packages");
|
||||||
d.rename(pack, pack + ".disabled");
|
int i = 0;
|
||||||
|
while (!d.rename(pack, pack + ".disabled") && i < 3) {
|
||||||
|
QThread::currentThread()->msleep(1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackMan::updatePack(const QString &pack) {
|
void PackMan::updatePack(const QString &pack) {
|
||||||
|
|
|
@ -535,6 +535,9 @@ void Room::gameOver() {
|
||||||
// 清理所有状态不是“在线”的玩家
|
// 清理所有状态不是“在线”的玩家
|
||||||
foreach (ServerPlayer *p, players) {
|
foreach (ServerPlayer *p, players) {
|
||||||
if (p->getState() != Player::Online) {
|
if (p->getState() != Player::Online) {
|
||||||
|
if (p->getState() == Player::Offline) {
|
||||||
|
server->temporarilyBan(p->getId());
|
||||||
|
}
|
||||||
p->deleteLater();
|
p->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -636,9 +636,19 @@ void Server::temporarilyBan(int playerId) {
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
|
|
||||||
auto socket = player->getSocket();
|
auto socket = player->getSocket();
|
||||||
if (!socket) return;
|
QString addr;
|
||||||
|
if (!socket) {
|
||||||
|
QString sql_find = QString("SELECT * FROM userinfo \
|
||||||
|
WHERE id=%1;").arg(playerId);
|
||||||
|
auto result = SelectFromDatabase(db, sql_find);
|
||||||
|
if (result.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
auto addr = socket->peerAddress();
|
auto obj = result[0].toObject();
|
||||||
|
addr = obj["lastLoginIp"].toString();
|
||||||
|
} else {
|
||||||
|
addr = socket->peerAddress();
|
||||||
|
}
|
||||||
temp_banlist.append(addr);
|
temp_banlist.append(addr);
|
||||||
|
|
||||||
auto time = getConfig("tempBanTime").toInt();
|
auto time = getConfig("tempBanTime").toInt();
|
||||||
|
|
|
@ -25,8 +25,10 @@ void Shell::helpCommand(QStringList &) {
|
||||||
|
|
||||||
HELP_MSG("%s: Display this help message.", "help");
|
HELP_MSG("%s: Display this help message.", "help");
|
||||||
HELP_MSG("%s: Shut down the server.", "quit");
|
HELP_MSG("%s: Shut down the server.", "quit");
|
||||||
|
HELP_MSG("%s: Crash the server. Useful when encounter dead loop.", "crash");
|
||||||
HELP_MSG("%s: List all online players.", "lsplayer");
|
HELP_MSG("%s: List all online players.", "lsplayer");
|
||||||
HELP_MSG("%s: List all running rooms.", "lsroom");
|
HELP_MSG("%s: List all running rooms.", "lsroom");
|
||||||
|
HELP_MSG("%s: Reload server config file.", "reloadconf");
|
||||||
HELP_MSG("%s: Kick a player by his <id>.", "kick");
|
HELP_MSG("%s: Kick a player by his <id>.", "kick");
|
||||||
HELP_MSG("%s: Broadcast message.", "msg");
|
HELP_MSG("%s: Broadcast message.", "msg");
|
||||||
HELP_MSG("%s: Ban 1 or more accounts, IP, UUID by their <name>.", "ban");
|
HELP_MSG("%s: Ban 1 or more accounts, IP, UUID by their <name>.", "ban");
|
||||||
|
@ -349,6 +351,11 @@ void Shell::unbanUuidCommand(QStringList &list) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shell::reloadConfCommand(QStringList &) {
|
||||||
|
ServerInstance->readConfig();
|
||||||
|
qInfo("Reloaded server config file.");
|
||||||
|
}
|
||||||
|
|
||||||
Shell::Shell() {
|
Shell::Shell() {
|
||||||
setObjectName("Shell");
|
setObjectName("Shell");
|
||||||
signal(SIGINT, sigintHandler);
|
signal(SIGINT, sigintHandler);
|
||||||
|
@ -373,6 +380,7 @@ Shell::Shell() {
|
||||||
handlers["unbanip"] = &Shell::unbanipCommand;
|
handlers["unbanip"] = &Shell::unbanipCommand;
|
||||||
handlers["banuuid"] = &Shell::banUuidCommand;
|
handlers["banuuid"] = &Shell::banUuidCommand;
|
||||||
handlers["unbanuuid"] = &Shell::unbanUuidCommand;
|
handlers["unbanuuid"] = &Shell::unbanUuidCommand;
|
||||||
|
handlers["reloadconf"] = &Shell::reloadConfCommand;
|
||||||
}
|
}
|
||||||
handler_map = handlers;
|
handler_map = handlers;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +392,8 @@ void Shell::run() {
|
||||||
"This is free software, and you are welcome to redistribute it under\n");
|
"This is free software, and you are welcome to redistribute it under\n");
|
||||||
printf("certain conditions; For more information visit "
|
printf("certain conditions; For more information visit "
|
||||||
"http://www.gnu.org/licenses.\n\n");
|
"http://www.gnu.org/licenses.\n\n");
|
||||||
printf("This is server cli. Enter \"help\" for usage hints.\n");
|
|
||||||
|
printf("[v%s] This is server cli. Enter \"help\" for usage hints.\n", FK_VERSION);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
char *bytes = readline("fk> ");
|
char *bytes = readline("fk> ");
|
||||||
|
@ -394,6 +403,8 @@ void Shell::run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qInfo("Running command: \"%s\"", bytes);
|
||||||
|
|
||||||
if (!strcmp(bytes, "crash")) {
|
if (!strcmp(bytes, "crash")) {
|
||||||
qFatal("Crashing."); // should dump core
|
qFatal("Crashing."); // should dump core
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,6 +31,7 @@ private:
|
||||||
void unbanCommand(QStringList &);
|
void unbanCommand(QStringList &);
|
||||||
void unbanipCommand(QStringList &);
|
void unbanipCommand(QStringList &);
|
||||||
void unbanUuidCommand(QStringList &);
|
void unbanUuidCommand(QStringList &);
|
||||||
|
void reloadConfCommand(QStringList &);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -72,3 +72,9 @@ public:
|
||||||
bool thinking();
|
bool thinking();
|
||||||
void setThinking(bool t);
|
void setThinking(bool t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
%extend ServerPlayer {
|
||||||
|
void emitKick() {
|
||||||
|
emit $self->kicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -321,6 +321,10 @@ void QmlBackend::copyToClipboard(const QString &s) {
|
||||||
QGuiApplication::clipboard()->setText(s);
|
QGuiApplication::clipboard()->setText(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QmlBackend::readClipboard() {
|
||||||
|
return QGuiApplication::clipboard()->text();
|
||||||
|
}
|
||||||
|
|
||||||
void QmlBackend::setAESKey(const QString &key) { aes_key = key; }
|
void QmlBackend::setAESKey(const QString &key) { aes_key = key; }
|
||||||
|
|
||||||
QString QmlBackend::getAESKey() const { return aes_key; }
|
QString QmlBackend::getAESKey() const { return aes_key; }
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
Q_INVOKABLE void playSound(const QString &name, int index = 0);
|
Q_INVOKABLE void playSound(const QString &name, int index = 0);
|
||||||
|
|
||||||
Q_INVOKABLE void copyToClipboard(const QString &s);
|
Q_INVOKABLE void copyToClipboard(const QString &s);
|
||||||
|
Q_INVOKABLE QString readClipboard();
|
||||||
|
|
||||||
Q_INVOKABLE void setAESKey(const QString &key);
|
Q_INVOKABLE void setAESKey(const QString &key);
|
||||||
Q_INVOKABLE QString getAESKey() const;
|
Q_INVOKABLE QString getAESKey() const;
|
||||||
|
|
Loading…
Reference in New Issue