diff --git a/Fk/Pages/Replay.qml b/Fk/Pages/Replay.qml index 6f2742bf..c9e86ce5 100644 --- a/Fk/Pages/Replay.qml +++ b/Fk/Pages/Replay.qml @@ -3,6 +3,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import QtQuick.Dialogs import Fk Item { @@ -29,6 +30,12 @@ Item { Menu { id: menu y: bar.height + MenuItem { + text: qsTr("Replay from file") + onTriggered: { + fdialog.open(); + } + } } } } @@ -104,7 +111,7 @@ Item { onClicked: { config.observing = true; config.replaying = true; - Backend.playRecord(fileName); + Backend.playRecord("recording/" + fileName); } } @@ -122,6 +129,17 @@ Item { } } + FileDialog { + id: fdialog + nameFilters: ["FK Rep Files (*.fk.rep)"]; + onAccepted: { + config.observing = true; + config.replaying = true; + let str = selectedFile.toString(); // QUrl -> string + Backend.playRecord(str); + } + } + function updateList() { model.clear(); const data = Backend.ls("recording"); diff --git a/Fk/Pages/Room.qml b/Fk/Pages/Room.qml index 7e6d5993..c1eae3ea 100644 --- a/Fk/Pages/Room.qml +++ b/Fk/Pages/Room.qml @@ -210,22 +210,55 @@ Item { } } Rectangle { - x: parent.width / 2 + 80 - y: parent.height / 2 + x: parent.width / 2 + 60 + y: parent.height / 2 - 30 color: "snow" opacity: 0.8 radius: 6 - height: childrenRect.height + 16 - width: childrenRect.width + 16 visible: !isStarted + width: 280 + height: 280 - Text { - x: 8; y: 8 - Component.onCompleted: { - const data = JSON.parse(Backend.callLuaFunction("GetRoomConfig", [])); - text = Backend.translate("LuckCardNum") + data.luckTime + "
" + Backend.translate("ResponseTime") + config.roomTimeout - + "
" + Backend.translate("GeneralBoxNum") + data.generalNum + (data.enableFreeAssign ? "
" + Backend.translate("IncludeFreeAssign") : "") - + (data.enableDeputy ? "
" + Backend.translate("IncludeDeputy") : "") + Flickable { + id: flickableContainer + ScrollBar.vertical: ScrollBar {} + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 10 + flickableDirection: Flickable.VerticalFlick + width: parent.width - 10 + height: parent.height - 10 + contentHeight: roominfo.height + clip: true + + Text { + id: roominfo + font.pixelSize: 16 + width: parent.width + wrapMode: TextEdit.WordWrap + Component.onCompleted: { + const data = JSON.parse(Backend.callLuaFunction("GetRoomConfig", [])); + let cardpack = JSON.parse(Backend.callLuaFunction("GetAllCardPack", [])); + cardpack = cardpack.filter(p => !data.disabledPack.includes(p)); + + text = "游戏模式:" + Backend.translate(data.gameMode) + "
" + + Backend.translate("LuckCardNum") + "" + data.luckTime + "
" + + Backend.translate("ResponseTime") + "" + config.roomTimeout + "
" + + Backend.translate("GeneralBoxNum") + "" + data.generalNum + "" + + (data.enableFreeAssign ? "
" + Backend.translate("IncludeFreeAssign") : "") + + (data.enableDeputy ? " " + Backend.translate("IncludeDeputy") : "") + + '
使用牌堆:' + cardpack.map(e => { + let ret = Backend.translate(e); + if (ret.search(/特殊牌|衍生牌/) === -1) { // TODO: 这种东西最好还是变量名规范化= = + ret = "" + ret + ""; + } else { + ret = '' + ret + ""; + } + return ret; + }).join(',') + //+ '
禁包:' + data.disabledPack.map(e => Backend.translate(e)).join(',') + //+ '
禁将:' + data.disabledGenerals.map(e => Backend.translate(e)).join(',') + } } } } diff --git a/Fk/PhotoElement/LimitSkillArea.qml b/Fk/PhotoElement/LimitSkillArea.qml index 4632fbdf..00061eff 100644 --- a/Fk/PhotoElement/LimitSkillArea.qml +++ b/Fk/PhotoElement/LimitSkillArea.qml @@ -22,6 +22,9 @@ ColumnLayout { const data = skills.get(i); if (data.skillname_ === skill) { data.times = times; + if (times == -1) { + skills.remove(i); + } return; } } diff --git a/Fk/PhotoElement/RoleComboBox.qml b/Fk/PhotoElement/RoleComboBox.qml index 2b326f00..d146461e 100644 --- a/Fk/PhotoElement/RoleComboBox.qml +++ b/Fk/PhotoElement/RoleComboBox.qml @@ -8,7 +8,7 @@ Image { property var options: ["unknown", "loyalist", "rebel", "renegade"] id: root - source: visible ? SkinBank.ROLE_DIR + value : "" + source: visible ? SkinBank.getRolePic(value) : "" visible: value != "hidden" Image { diff --git a/Fk/skin-bank.js b/Fk/skin-bank.js index d45e2fc4..ab56bc06 100644 --- a/Fk/skin-bank.js +++ b/Fk/skin-bank.js @@ -55,6 +55,7 @@ function getCardPicture(cidOrName) { return path; } else { for (let dir of Backend.ls(AppPath + "/packages/")) { + if (dir.endsWith(".disabled")) continue; path = AppPath + "/packages/" + dir + "/image/card/" + name + ".png"; if (Backend.exists(path)) return path; } @@ -70,6 +71,7 @@ function getDelayedTrickPicture(name) { return path; } else { for (let dir of Backend.ls(AppPath + "/packages/")) { + if (dir.endsWith(".disabled")) continue; path = AppPath + "/packages/" + dir + "/image/card/delayedTrick/" + name + ".png"; if (Backend.exists(path)) return path; } @@ -87,6 +89,7 @@ function getEquipIcon(cid, icon) { return path; } else { for (let dir of Backend.ls(AppPath + "/packages/")) { + if (dir.endsWith(".disabled")) continue; path = AppPath + "/packages/" + dir + "/image/card/equipIcon/" + name + ".png"; if (Backend.exists(path)) return path; } @@ -98,6 +101,7 @@ function getPhotoBack(kingdom) { let path = PHOTO_BACK_DIR + kingdom + ".png"; if (!Backend.exists(path)) { for (let dir of Backend.ls(AppPath + "/packages/")) { + if (dir.endsWith(".disabled")) continue; path = AppPath + "/packages/" + dir + "/image/kingdom/" + kingdom + "-back.png"; if (Backend.exists(path)) return path; } @@ -111,6 +115,7 @@ function getGeneralCardDir(kingdom) { let path = GENERALCARD_DIR + kingdom + ".png"; if (!Backend.exists(path)) { for (let dir of Backend.ls(AppPath + "/packages/")) { + if (dir.endsWith(".disabled")) continue; path = AppPath + "/packages/" + dir + "/image/kingdom/" + kingdom + "-back.png"; if (Backend.exists(path)) return AppPath + "/packages/" + dir + "/image/kingdom/"; @@ -119,3 +124,17 @@ function getGeneralCardDir(kingdom) { return GENERALCARD_DIR; } } + +function getRolePic(role) { + let path = ROLE_DIR + role + ".png"; + if (Backend.exists(path)) { + return path; + } else { + for (let dir of Backend.ls(AppPath + "/packages/")) { + if (dir.endsWith(".disabled")) continue; + path = AppPath + "/packages/" + dir + "/image/role/" + name + ".png"; + if (Backend.exists(path)) return path; + } + } + return ROLE_DIR + "unknown.png"; +} diff --git a/lua/client/client.lua b/lua/client/client.lua index 2cdf5844..f79424ab 100644 --- a/lua/client/client.lua +++ b/lua/client/client.lua @@ -585,21 +585,6 @@ fk.client_callback["ShowCard"] = function(jsonData) }) end -fk.client_callback["LoseSkill"] = function(jsonData) - -- jsonData: [ int player_id, string skill_name ] - local data = json.decode(jsonData) - local id, skill_name, prelight = data[1], data[2], data[3] - local target = ClientInstance:getPlayerById(id) - local skill = Fk.skills[skill_name] - if not prelight then - target:loseSkill(skill) - end - - if skill.visible then - ClientInstance:notifyUI("LoseSkill", jsonData) - end -end - -- 说是限定技,其实也适用于觉醒技、转换技、使命技 ---@param skill Skill ---@param times integer @@ -613,15 +598,99 @@ local function updateLimitSkill(pid, skill, times) end end +fk.client_callback["LoseSkill"] = function(jsonData) + -- jsonData: [ int player_id, string skill_name ] + local data = json.decode(jsonData) + local id, skill_name, fake = data[1], data[2], data[3] + local target = ClientInstance:getPlayerById(id) + local skill = Fk.skills[skill_name] + + if not fake then + target:loseSkill(skill) + if skill.visible then + ClientInstance:notifyUI("LoseSkill", jsonData) + end + elseif skill.visible then + -- 按理说能弄得更好的但还是复制粘贴舒服 + local sks = { table.unpack(skill.related_skills) } + --[[ 需要大伙都适配好main_skill或者讨论出更好方案才行。不敢轻举妄动 + local sks = table.filter(skill.related_skills, function(s) + return s.main_skill == skill + end) + --]] + table.insert(sks, skill) + table.removeOne(target.player_skills, skill) + local chk = false + + if table.find(sks, function(s) return s:isInstanceOf(TriggerSkill) end) then + chk = true + ClientInstance:notifyUI("LoseSkill", jsonData) + end + + local active = table.filter(sks, function(s) + return s:isInstanceOf(ActiveSkill) or s:isInstanceOf(ViewAsSkill) + end) + + if #active > 0 then + chk = true + ClientInstance:notifyUI("LoseSkill", json.encode { + id, skill_name, + }) + end + + if not chk then + ClientInstance:notifyUI("LoseSkill", json.encode { + id, skill_name, + }) + end + end + + updateLimitSkill(id, skill, -1) +end + fk.client_callback["AddSkill"] = function(jsonData) -- jsonData: [ int player_id, string skill_name ] local data = json.decode(jsonData) - local id, skill_name = data[1], data[2] + local id, skill_name, fake = data[1], data[2], data[3] local target = ClientInstance:getPlayerById(id) local skill = Fk.skills[skill_name] - target:addSkill(skill) - if skill.visible then - ClientInstance:notifyUI("AddSkill", jsonData) + + if not fake then + target:addSkill(skill) + if skill.visible then + ClientInstance:notifyUI("AddSkill", jsonData) + end + elseif skill.visible then + -- 添加假技能:服务器只会传一个主技能来。 + -- 若有主动技则添加按钮,若有触发技则添加预亮按钮。 + -- 无视状态技。 + local sks = { table.unpack(skill.related_skills) } + table.insert(sks, skill) + table.insert(target.player_skills, skill) + local chk = false + + if table.find(sks, function(s) return s:isInstanceOf(TriggerSkill) end) then + chk = true + ClientInstance:notifyUI("AddSkill", jsonData) + end + + local active = table.filter(sks, function(s) + return s:isInstanceOf(ActiveSkill) or s:isInstanceOf(ViewAsSkill) + end) + + if #active > 0 then + chk = true + ClientInstance:notifyUI("AddSkill", json.encode { + id, skill_name, + }) + end + + -- 面板上总得有点啥东西表明自己有技能吧 = = + if not chk then + ClientInstance:notifyUI("AddSkill", json.encode { + id, skill_name, + }) + end end if skill.frequency == Skill.Quest then diff --git a/lua/core/player.lua b/lua/core/player.lua index 61257d1a..224aa4aa 100644 --- a/lua/core/player.lua +++ b/lua/core/player.lua @@ -678,6 +678,13 @@ function Player:hasSkill(skill, ignoreNullified, ignoreAlive) return true end + if self:isInstanceOf(ServerPlayer) and -- isInstanceOf(nil) will return false + table.contains(self._fake_skills, skill) and + table.contains(self.prelighted_skills, skill) then + + return true + end + for _, v in pairs(self.derivative_skills) do if table.contains(v, skill) then return true diff --git a/lua/core/skill_type/trigger.lua b/lua/core/skill_type/trigger.lua index 799c6ecc..d1c5b538 100644 --- a/lua/core/skill_type/trigger.lua +++ b/lua/core/skill_type/trigger.lua @@ -56,8 +56,15 @@ end -- do cost and skill effect. -- DO NOT modify this function function TriggerSkill:doCost(event, target, player, data) + local start_time = os.getms() local ret = self:cost(event, target, player, data) + local end_time = os.getms() + local room = player.room + -- 对于那种cost直接返回true的锁定技,如果是预亮技,那么还是询问一下好 + if ret and player:isFakeSkill(self) and end_time - start_time < 10000 then + ret = room:askForSkillInvoke(player, self.name) + end local cost_data_bak = self.cost_data room.logic:trigger(fk.BeforeTriggerSkillUse, player, { skill = self, willUse = ret }) diff --git a/lua/core/skill_type/usable_skill.lua b/lua/core/skill_type/usable_skill.lua index 7612d947..4b1368fd 100644 --- a/lua/core/skill_type/usable_skill.lua +++ b/lua/core/skill_type/usable_skill.lua @@ -1,6 +1,7 @@ -- SPDX-License-Identifier: GPL-3.0-or-later ---@class UsableSkill : Skill +---@field public main_skill UsableSkill ---@field public max_use_time integer[] ---@field public expand_pile string local UsableSkill = Skill:subclass("UsableSkill") diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 935f4e47..8be1277a 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -42,6 +42,8 @@ end local function readUsableSpecToSkill(skill, spec) readCommonSpecToSkill(skill, spec) + assert(spec.main_skill == nil or spec.main_skill:isInstanceOf(UsableSkill)) + skill.main_skill = spec.main_skill skill.target_num = spec.target_num or skill.target_num skill.min_target_num = spec.min_target_num or skill.min_target_num skill.max_target_num = spec.max_target_num or skill.max_target_num diff --git a/lua/server/events/skill.lua b/lua/server/events/skill.lua index ff391338..1d3c304d 100644 --- a/lua/server/events/skill.lua +++ b/lua/server/events/skill.lua @@ -1,9 +1,14 @@ -- SPDX-License-Identifier: GPL-3.0-or-later GameEvent.functions[GameEvent.SkillEffect] = function(self) - local effect_cb, player, skill = table.unpack(self.data) + local effect_cb, player, _skill = table.unpack(self.data) local room = self.room local logic = room.logic + local skill = _skill.main_skill and _skill.main_skill or _skill + + if player then + player:addSkillUseHistory(skill.name) + end local cost_data_bak = skill.cost_data logic:trigger(fk.SkillEffect, player, skill) diff --git a/lua/server/room.lua b/lua/server/room.lua index 4bbeb212..2ad3f903 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -829,6 +829,15 @@ function Room:notifyMoveFocus(players, command) table.insert(ids, p.id) end + local tempSk = Fk.skills[command] + if tempSk and #players == 1 then + local p = players[1] + if p:isFakeSkill(tempSk) then + command = "" + ids = table.map(self.alive_players, Util.IdMapper) + end + end + self:doBroadcastNotify("MoveFocus", json.encode{ ids, command @@ -2987,7 +2996,6 @@ function Room:useSkill(player, skill, effect_cb) player:getSwitchSkillState(switchSkillName, true) ) end - player:addSkillUseHistory(skill.name) if effect_cb then return execGameEvent(GameEvent.SkillEffect, effect_cb, player, skill) diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index ac8dc28d..35ee989f 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -14,6 +14,8 @@ ---@field public phase_state table[] ---@field public phase_index integer ---@field public role_shown boolean +---@field private _fake_skills Skill[] +---@field public prelighted_skills Skill[] ---@field private _timewaste_count integer ---@field public ai AI ---@field public ai_data any @@ -35,6 +37,11 @@ function ServerPlayer:initialize(_self) self.reply_cancel = false self.phases = {} self.skipped_phases = {} + + self._fake_skills = {} + self.prelighted_skills = {} + self._prelighted_skills = {} + self._timewaste_count = 0 self.ai = RandomAI:new(self) end @@ -702,13 +709,70 @@ end -- Hegemony func +---@param skill Skill +function ServerPlayer:addFakeSkill(skill) + assert(skill:isInstanceOf(Skill)) + if table.contains(self._fake_skills, skill) then return end + + table.insert(self._fake_skills, skill) + for _, s in ipairs(skill.related_skills) do + -- if s.main_skill == skill then -- TODO: need more detailed + table.insert(self._fake_skills, s) + -- end + end + + -- TODO + self:doNotify("AddSkill", json.encode{ self.id, skill.name, true }) +end + +---@param skill Skill +function ServerPlayer:loseFakeSkill(skill) + assert(skill:isInstanceOf(Skill)) + if not table.contains(self._fake_skills, skill) then return end + + table.removeOne(self._fake_skills, skill) + for _, s in ipairs(skill.related_skills) do + table.removeOne(self._fake_skills, s) + end + + -- TODO + self:doNotify("LoseSkill", json.encode{ self.id, skill.name, true }) +end + +function ServerPlayer:isFakeSkill(skill) + if type(skill) == "string" then skill = Fk.skills[skill] end + assert(skill:isInstanceOf(Skill)) + return table.contains(self._fake_skills, skill) +end + +---@param skill string | Skill +---@param isPrelight boolean | nil function ServerPlayer:prelightSkill(skill, isPrelight) - if isPrelight then + if type(skill) == "string" then skill = Fk.skills[skill] end + assert(skill:isInstanceOf(Skill)) + + if not self._prelighted_skills[skill] and not self:hasSkill(skill) then + self._prelighted_skills[skill] = true + -- to attach skill to room self:addSkill(skill) - else self:loseSkill(skill) end - self:doNotify("PrelightSkill", json.encode{ skill, isPrelight }) + + if isPrelight then + -- self:addSkill(skill) + table.insert(self.prelighted_skills, skill) + for _, s in ipairs(skill.related_skills) do + table.insert(self.prelighted_skills, s) + end + else + -- self:loseSkill(skill) + table.removeOne(self.prelighted_skills, skill) + for _, s in ipairs(skill.related_skills) do + table.removeOne(self.prelighted_skills, s) + end + end + + self:doNotify("PrelightSkill", json.encode{ skill.name, isPrelight }) end function ServerPlayer:revealGeneral(isDeputy) @@ -725,10 +789,7 @@ function ServerPlayer:revealGeneral(isDeputy) local general = Fk.generals[generalName] for _, s in ipairs(general:getSkillNameList()) do local skill = Fk.skills[s] - if skill:isInstanceOf(TriggerSkill) or table.find(skill.related_skills, - function(s) return s:isInstanceOf(TriggerSkill) end) then - self:doNotify("LoseSkill", json.encode{ self.id, s, true }) - end + self:loseFakeSkill(skill) end local oldKingdom = self.kingdom diff --git a/packages/standard/hegemony.lua b/packages/standard/hegemony.lua index a84baaf4..3c083408 100644 --- a/packages/standard/hegemony.lua +++ b/packages/standard/hegemony.lua @@ -229,13 +229,7 @@ function HegLogic:attachSkillToPlayers() return end - -- room:handleAddLoseSkills(player, skillName, nil, false) - player:doNotify("AddSkill", json.encode{ player.id, skillName }) - - if skill:isInstanceOf(TriggerSkill) or table.find(skill.related_skills, - function(s) return s:isInstanceOf(TriggerSkill) end) then - player:doNotify("AddSkill", json.encode{ player.id, skillName, true }) - end + player:addFakeSkill(skill) end for _, p in ipairs(room.alive_players) do diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua index 340d76ea..216c2348 100644 --- a/packages/standard_cards/init.lua +++ b/packages/standard_cards/init.lua @@ -413,6 +413,7 @@ local nullificationSkill = fk.CreateActiveSkill{ can_use = function() return false end, + on_use = function() RoomInstance:delay(1200) end, on_effect = function(self, room, effect) if effect.responseToEvent then effect.responseToEvent.isCancellOut = true diff --git a/src/client/replayer.cpp b/src/client/replayer.cpp index 4f1a800b..e7ca3647 100644 --- a/src/client/replayer.cpp +++ b/src/client/replayer.cpp @@ -11,7 +11,12 @@ Replayer::Replayer(QObject *parent, const QString &filename) : { setObjectName("Replayer"); - QFile file("recording/" + filename); + auto s = filename; +#ifdef Q_OS_WIN + if (s.startsWith("file:///")) + s.replace(0, 8, "file://"); +#endif + QFile file(QUrl(s).path()); file.open(QIODevice::ReadOnly); QByteArray raw = file.readAll(); file.close(); diff --git a/src/server/room.cpp b/src/server/room.cpp index 9482b421..4ba6a7e5 100644 --- a/src/server/room.cpp +++ b/src/server/room.cpp @@ -234,6 +234,7 @@ void Room::removePlayer(ServerPlayer *player) { if (!gameStarted) { // 游戏还没开始的话,直接删除这名玩家 if (players.contains(player) && !players.isEmpty()) { + player->setReady(false); players.removeOne(player); } emit playerRemoved(player); @@ -533,10 +534,15 @@ void Room::gameOver() { gameStarted = false; runned_players.clear(); // 清理所有状态不是“在线”的玩家 + auto settings = QJsonDocument::fromJson(this->settings); + auto mode = settings["gameMode"].toString(); foreach (ServerPlayer *p, players) { if (p->getState() != Player::Online) { if (p->getState() == Player::Offline) { - server->temporarilyBan(p->getId()); + auto pid = p->getId(); + addRunRate(pid, mode); + addRunRate(pid, mode); + server->temporarilyBan(pid); } p->deleteLater(); } diff --git a/src/server/shell.cpp b/src/server/shell.cpp index 72d372f4..b6f5c552 100644 --- a/src/server/shell.cpp +++ b/src/server/shell.cpp @@ -28,9 +28,9 @@ void Shell::helpCommand(QStringList &) { 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 running rooms.", "lsroom"); - HELP_MSG("%s: Reload server config file.", "reloadconf"); + HELP_MSG("%s: Reload server config file.", "reloadconf/r"); HELP_MSG("%s: Kick a player by his .", "kick"); - HELP_MSG("%s: Broadcast message.", "msg"); + HELP_MSG("%s: Broadcast message.", "msg/m"); HELP_MSG("%s: Ban 1 or more accounts, IP, UUID by their .", "ban"); HELP_MSG("%s: Unban 1 or more accounts by their .", "unban"); HELP_MSG( @@ -49,6 +49,7 @@ void Shell::helpCommand(QStringList &) { "%s: Unban 1 or more UUID. " "At least 1 required.", "unbanuuid"); + HELP_MSG("%s: reset 's password to 1234.", "resetpassword/rp"); qInfo(); qInfo("===== Package commands ====="); HELP_MSG("%s: Install a new package from .", "install"); @@ -56,7 +57,7 @@ void Shell::helpCommand(QStringList &) { HELP_MSG("%s: List all packages.", "lspkg"); HELP_MSG("%s: Enable a package.", "enable"); HELP_MSG("%s: Disable a package.", "disable"); - HELP_MSG("%s: Upgrade a package. Leave empty to upgrade all.", "upgrade"); + HELP_MSG("%s: Upgrade a package. Leave empty to upgrade all.", "upgrade/u"); qInfo("For more commands, check the documentation."); #undef HELP_MSG @@ -356,6 +357,21 @@ void Shell::reloadConfCommand(QStringList &) { qInfo("Reloaded server config file."); } +void Shell::resetPasswordCommand(QStringList &list) { + if (list.isEmpty()) { + qWarning("The 'resetpassword' command needs at least 1 ."); + return; + } + + auto db = ServerInstance->getDatabase(); + foreach (auto name, list) { + // 重置为1234 + ExecSQL(db, QString("UPDATE userinfo SET password=\ + 'dbdc2ad3d9625407f55674a00b58904242545bfafedac67485ac398508403ade',\ + salt='00000000' WHERE name='%1';").arg(name)); + } +} + Shell::Shell() { setObjectName("Shell"); signal(SIGINT, sigintHandler); @@ -369,11 +385,13 @@ Shell::Shell() { 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; @@ -381,6 +399,9 @@ Shell::Shell() { handlers["banuuid"] = &Shell::banUuidCommand; handlers["unbanuuid"] = &Shell::unbanUuidCommand; handlers["reloadconf"] = &Shell::reloadConfCommand; + handlers["r"] = &Shell::reloadConfCommand; + handlers["resetpassword"] = &Shell::resetPasswordCommand; + handlers["rp"] = &Shell::resetPasswordCommand; } handler_map = handlers; } diff --git a/src/server/shell.h b/src/server/shell.h index 7d044417..6ebea4b3 100644 --- a/src/server/shell.h +++ b/src/server/shell.h @@ -32,6 +32,7 @@ private: void unbanipCommand(QStringList &); void unbanUuidCommand(QStringList &); void reloadConfCommand(QStringList &); + void resetPasswordCommand(QStringList &); }; #endif