diff --git a/Fk/LobbyElement/RoomGeneralSettings.qml b/Fk/LobbyElement/RoomGeneralSettings.qml
index 7b6e2d8f..fa400c7b 100644
--- a/Fk/LobbyElement/RoomGeneralSettings.qml
+++ b/Fk/LobbyElement/RoomGeneralSettings.qml
@@ -87,7 +87,12 @@ Flickable {
Text {
id: warning
anchors.rightMargin: 8
- visible: JSON.parse(Backend.callLuaFunction("GetAvailableGeneralsNum", [])) < config.preferredGeneralNum * config.preferedPlayerNum
+ visible: {
+ const avail = JSON.parse(Backend.callLuaFunction("GetAvailableGeneralsNum", []));
+ config.disabledPack; // 没什么用,只是为了禁包刷新时刷新visible罢了
+ const ret = avail < config.preferredGeneralNum * config.preferedPlayerNum;
+ return ret;
+ }
text: Backend.translate("No enough generals")
color: "red"
}
@@ -159,6 +164,7 @@ Flickable {
text: Backend.translate("OK")
enabled: !(warning.visible)
onClicked: {
+ config.saveConf();
root.finished();
mainWindow.busy = true;
@@ -208,6 +214,11 @@ Flickable {
}
playerNum.value = config.preferedPlayerNum;
+
+ config.disabledPack.forEach(p => {
+ Backend.callLuaFunction("UpdatePackageEnable", [p, false]);
+ });
+ config.disabledPackChanged();
}
}
}
diff --git a/Fk/LobbyElement/RoomPackageSettings.qml b/Fk/LobbyElement/RoomPackageSettings.qml
index 7e218745..2e2c648f 100644
--- a/Fk/LobbyElement/RoomPackageSettings.qml
+++ b/Fk/LobbyElement/RoomPackageSettings.qml
@@ -25,16 +25,36 @@ Flickable {
text: "禁用Lua拓展 (重启后生效)"
}
- Text {
- text: Backend.translate("General Packages")
- font.bold: true
+ RowLayout {
+ Text {
+ text: Backend.translate("General Packages")
+ font.bold: true
+ }
+ Button {
+ text: Backend.translate("Select All")
+ onClicked: {
+ for (let i = 0; i < gpacks.count; i++) {
+ const item = gpacks.itemAt(i);
+ item.checked = true;
+ }
+ }
+ }
+ Button {
+ text: Backend.translate("Revert Selection")
+ onClicked: {
+ for (let i = 0; i < gpacks.count; i++) {
+ const item = gpacks.itemAt(i);
+ item.checked = !item.checked;
+ }
+ }
+ }
}
GridLayout {
- id: gpacks
columns: 2
Repeater {
+ id: gpacks
model: ListModel {
id: gpacklist
}
@@ -45,28 +65,42 @@ Flickable {
enabled: orig_name !== "test_p_0"
onCheckedChanged: {
- const packs = config.disabledPack;
- if (checked) {
- const idx = packs.indexOf(orig_name);
- if (idx !== -1) packs.splice(idx, 1);
- } else {
- packs.push(orig_name);
- }
+ checkPackage(orig_name, checked);
}
}
}
}
- Text {
- text: Backend.translate("Card Packages")
- font.bold: true
+ RowLayout {
+ Text {
+ text: Backend.translate("Card Packages")
+ font.bold: true
+ }
+ Button {
+ text: Backend.translate("Select All")
+ onClicked: {
+ for (let i = 0; i < cpacks.count; i++) {
+ const item = cpacks.itemAt(i);
+ item.checked = true;
+ }
+ }
+ }
+ Button {
+ text: Backend.translate("Revert Selection")
+ onClicked: {
+ for (let i = 0; i < cpacks.count; i++) {
+ const item = cpacks.itemAt(i);
+ item.checked = !item.checked;
+ }
+ }
+ }
}
GridLayout {
- id: cpacks
columns: 2
Repeater {
+ id: cpacks
model: ListModel {
id: cpacklist
}
@@ -76,19 +110,25 @@ Flickable {
checked: pkg_enabled
onCheckedChanged: {
- const packs = config.disabledPack;
- if (checked) {
- const idx = packs.indexOf(orig_name);
- if (idx !== -1) packs.splice(idx, 1);
- } else {
- packs.push(orig_name);
- }
+ checkPackage(orig_name, checked);
}
}
}
}
}
+ function checkPackage(orig_name, checked) {
+ const packs = config.disabledPack;
+ if (checked) {
+ const idx = packs.indexOf(orig_name);
+ if (idx !== -1) packs.splice(idx, 1);
+ } else {
+ packs.push(orig_name);
+ }
+ Backend.callLuaFunction("UpdatePackageEnable", [orig_name, checked]);
+ config.disabledPackChanged();
+ }
+
Component.onCompleted: {
const g = JSON.parse(Backend.callLuaFunction("GetAllGeneralPack", []));
for (let orig of g) {
diff --git a/Fk/Pages/Room.qml b/Fk/Pages/Room.qml
index 8e1ab8a5..51f46825 100644
--- a/Fk/Pages/Room.qml
+++ b/Fk/Pages/Room.qml
@@ -410,10 +410,19 @@ Item {
anchors.rightMargin: 20
color: "#88EEEEEE"
radius: 8
- visible: roomScene.state === "playing" && (specialCardSkills ?? false)
- && (specialCardSkills.count > 1
- || ((specialCardSkills.model ?? false)
- && specialCardSkills.model[0] !== "_normal_use"))
+ visible: {
+ if (roomScene.state !== "playing") {
+ return false;
+ }
+ if (!specialCardSkills) {
+ return false;
+ }
+ if (specialCardSkills.count > 1) {
+ return true;
+ }
+ return (specialCardSkills.model ?? false)
+ && specialCardSkills.model[0] !== "_normal_use"
+ }
width: childrenRect.width
height: childrenRect.height - 20
@@ -487,21 +496,20 @@ Item {
onSourceChanged: {
if (item === null)
return;
- item.finished.connect(function(){
+ item.finished.connect(() => {
sourceComponent = undefined;
});
- item.widthChanged.connect(function(){
+ item.widthChanged.connect(() => {
popupBox.moveToCenter();
});
- item.heightChanged.connect(function(){
+ item.heightChanged.connect(() => {
popupBox.moveToCenter();
});
moveToCenter();
}
onSourceComponentChanged: sourceChanged();
- function moveToCenter()
- {
+ function moveToCenter() {
item.x = Math.round((roomArea.width - item.width) / 2);
item.y = Math.round(roomArea.height * 0.67 - item.height / 2);
}
diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts
index 15aebdeb..83e40c2b 100644
--- a/lang/zh_CN.ts
+++ b/lang/zh_CN.ts
@@ -215,6 +215,10 @@
已经有人用这个名字登入了
+
+
+ 其他人用你的用户名和密码登陆到了服务器,请检查密码是否泄漏
+
用户名不合法,只能含有英数字和汉字
diff --git a/lua/client/client.lua b/lua/client/client.lua
index 4b24ece7..c6f43608 100644
--- a/lua/client/client.lua
+++ b/lua/client/client.lua
@@ -43,6 +43,9 @@ function Client:initialize()
for class, skills in pairs(Fk.global_status_skill) do
self.status_skills[class] = {table.unpack(skills)}
end
+
+ self.disabled_packs = {}
+ self.disabled_generals = {}
end
---@param id integer
@@ -236,8 +239,8 @@ fk.client_callback["EnterRoom"] = function(jsonData)
local data = json.decode(jsonData)[3]
ClientInstance.room_settings = data
- Fk.disabled_packs = data.disabledPack
- Fk.disabled_generals = data.disabledGenerals
+ ClientInstance.disabled_packs = data.disabledPack
+ ClientInstance.disabled_generals = data.disabledGenerals
ClientInstance:notifyUI("EnterRoom", jsonData)
end
@@ -750,6 +753,7 @@ end
fk.client_callback["ChangeSelf"] = function(jsonData)
local data = json.decode(jsonData)
ClientInstance:getPlayerById(data.id).player_cards[Player.Hand] = data.handcards
+ ClientInstance:getPlayerById(data.id).special_cards = data.special_cards
ClientInstance:notifyUI("ChangeSelf", data.id)
end
diff --git a/lua/client/client_util.lua b/lua/client/client_util.lua
index 3f95e750..f26e3dd9 100644
--- a/lua/client/client_util.lua
+++ b/lua/client/client_util.lua
@@ -126,6 +126,14 @@ function GetGenerals(pack_name)
return json.encode(ret)
end
+function UpdatePackageEnable(pkg, enabled)
+ if enabled then
+ table.removeOne(ClientInstance.disabled_packs, pkg)
+ else
+ table.insertIfNeed(ClientInstance.disabled_packs, pkg)
+ end
+end
+
function GetAvailableGeneralsNum()
local generalPool = Fk:getAllGenerals()
local except = {}
@@ -552,8 +560,8 @@ function ResetClientLua()
ClientInstance.discard_pile = {}
ClientInstance.room_settings = data
- Fk.disabled_packs = data.disabledPack
- Fk.disabled_generals = data.disabledGenerals
+ ClientInstance.disabled_packs = data.disabledPack
+ ClientInstance.disabled_generals = data.disabledGenerals
-- ClientInstance:notifyUI("EnterRoom", jsonData)
end
diff --git a/lua/client/i18n/zh_CN.lua b/lua/client/i18n/zh_CN.lua
index beec9da6..d101e66f 100644
--- a/lua/client/i18n/zh_CN.lua
+++ b/lua/client/i18n/zh_CN.lua
@@ -46,6 +46,8 @@ Fk:loadTranslationTable{
["Package Settings"] = "拓展包设置",
["General Packages"] = "武将拓展包",
["Card Packages"] = "卡牌拓展包",
+ ["Select All"] = "全选",
+ ["Revert Selection"] = "反选",
["Give Flower"] = "送花",
["Give Egg"] = "砸蛋",
diff --git a/lua/core/engine.lua b/lua/core/engine.lua
index b2f3d064..4199a3c8 100644
--- a/lua/core/engine.lua
+++ b/lua/core/engine.lua
@@ -19,7 +19,6 @@
---@field public cards Card[] @ 所有卡牌
---@field public translations table> @ 翻译表
---@field public game_modes table @ 所有游戏模式
----@field public disabled_packs string[] @ 禁用的拓展包列表
---@field public currentResponsePattern string @ 要求用牌的种类(如要求用特定花色的桃···)
---@field public currentResponseReason string @ 要求用牌的原因(如濒死,被特定牌指定,使用特定技能···)
local Engine = class("Engine")
@@ -49,14 +48,31 @@ function Engine:initialize()
self.cards = {} -- Card[]
self.translations = {} -- srcText --> translated
self.game_modes = {}
- self.disabled_packs = {}
- self.disabled_generals = {}
self.kingdoms = {}
self:loadPackages()
self:addSkills(AuxSkills)
end
+local _foreign_keys = {
+ "currentResponsePattern",
+ "currentResponseReason",
+}
+
+function Engine:__index(k)
+ if table.contains(_foreign_keys, k) then
+ return self:currentRoom()[k]
+ end
+end
+
+function Engine:__newindex(k, v)
+ if table.contains(_foreign_keys, k) then
+ self:currentRoom()[k] = v
+ else
+ rawset(self, k, v)
+ end
+end
+
--- 向Engine中加载一个拓展包。
---
--- 会加载这个拓展包含有的所有武将、卡牌以及游戏模式。
@@ -204,6 +220,12 @@ function Engine:addGenerals(generals)
end
end
+local function canUseGeneral(g)
+ local r = Fk:currentRoom()
+ return not table.contains(r.disabled_packs, Fk.generals[g].package.name) and
+ not table.contains(r.disabled_generals, g)
+end
+
--- 根据武将名称,获取它的同名武将。
---
--- 注意以此法返回的同名武将列表不包含他自己。
@@ -214,9 +236,7 @@ function Engine:getSameGenerals(name)
local tName = tmp[#tmp]
local ret = self.same_generals[tName] or {}
return table.filter(ret, function(g)
- return g ~= name and self.generals[g] ~= nil and
- not table.contains(self.disabled_packs, self.generals[g].package.name) and
- not table.contains(self.disabled_generals, g)
+ return g ~= name and self.generals[g] ~= nil and canUseGeneral(g)
end)
end
@@ -336,7 +356,7 @@ function Engine:getAllGenerals(except)
local result = {}
for _, general in pairs(self.generals) do
if not (except and table.contains(except, general)) then
- if not table.contains(self.disabled_packs, general.package.name) and not table.contains(self.disabled_generals, general.name) then
+ if canUseGeneral(general.name) then
table.insert(result, general)
end
end
@@ -352,7 +372,7 @@ function Engine:getAllCardIds(except)
local result = {}
for _, card in ipairs(self.cards) do
if not (except and table.contains(except, card.id)) then
- if not table.contains(self.disabled_packs, card.package.name) then
+ if not table.contains(self:currentRoom().disabled_packs, card.package.name) then
table.insert(result, card.id)
end
end
diff --git a/lua/core/player.lua b/lua/core/player.lua
index 635e09df..70f93bac 100644
--- a/lua/core/player.lua
+++ b/lua/core/player.lua
@@ -541,9 +541,8 @@ function Player:setSkillUseHistory(skill_name, num, scope)
return
end
- if self.skillUsedHistory[skill_name] then
- self.skillUsedHistory[skill_name][scope] = num
- end
+ self.skillUsedHistory[skill_name] = self.skillUsedHistory[skill_name] or {0, 0, 0, 0}
+ self.skillUsedHistory[skill_name][scope] = num
end
--- 获取玩家使用特定牌的历史次数。
diff --git a/lua/server/request.lua b/lua/server/request.lua
index dadc7823..7d13e284 100644
--- a/lua/server/request.lua
+++ b/lua/server/request.lua
@@ -131,6 +131,7 @@ request_handlers["changeself"] = function(room, id, reqlist)
from_sp:doNotify("ChangeSelf", json.encode {
id = toId,
handcards = to:getCardIds(Player.Hand),
+ special_cards = to.special_cards,
})
end
diff --git a/lua/server/room.lua b/lua/server/room.lua
index 90713596..6868b021 100644
--- a/lua/server/room.lua
+++ b/lua/server/room.lua
@@ -90,8 +90,8 @@ function Room:initialize(_room)
self.skill_costs = {}
self.settings = json.decode(self.room:settings())
- Fk.disabled_packs = self.settings.disabledPack
- Fk.disabled_generals = self.settings.disabledGenerals
+ self.disabled_packs = self.settings.disabledPack
+ self.disabled_generals = self.settings.disabledGenerals
end
-- 供调度器使用的函数。能让房间开始运行/从挂起状态恢复。
diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua
index bb54813a..3f8f192d 100644
--- a/lua/server/serverplayer.lua
+++ b/lua/server/serverplayer.lua
@@ -233,12 +233,26 @@ function ServerPlayer:marshal(player)
}
table.insert(card_moves, move)
end
+
+ for k, v in pairs(self.special_cards) do
+ local info = {}
+ for _, i in ipairs(v) do
+ table.insert(info, { cardId = i, fromArea = Card.DrawPile })
+ end
+ local move = {
+ moveInfo = info,
+ to = self.id,
+ toArea = Card.PlayerSpecial,
+ specialName = k,
+ specialVisible = self == player,
+ }
+ table.insert(card_moves, move)
+ end
+
if #card_moves > 0 then
room:notifyMoveCards({ player }, card_moves)
end
- -- TODO: pile
-
for k, v in pairs(self.mark) do
player:doNotify("SetPlayerMark", json.encode{self.id, k, v})
end
@@ -254,8 +268,11 @@ function ServerPlayer:marshal(player)
end
for k, v in pairs(self.skillUsedHistory) do
- if v[1] > 0 then
- player:doNotify("AddSkillUseHistory", json.encode{self.id, k, v[1]})
+ if v[4] > 0 then
+ player:doNotify("SetSkillUseHistory", json.encode{self.id, k, v[1], 1})
+ player:doNotify("SetSkillUseHistory", json.encode{self.id, k, v[2], 2})
+ player:doNotify("SetSkillUseHistory", json.encode{self.id, k, v[3], 3})
+ player:doNotify("SetSkillUseHistory", json.encode{self.id, k, v[4], 4})
end
end
diff --git a/src/server/server.cpp b/src/server/server.cpp
index b3d1a2ed..8e677747 100644
--- a/src/server/server.cpp
+++ b/src/server/server.cpp
@@ -397,6 +397,12 @@ void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
error_msg = "username or password error";
} else {
auto player = players.value(id);
+ // 顶号机制,如果在线的话就让他变成不在线
+ if (player->getState() == Player::Online) {
+ player->doNotify("ErrorMsg", "others logged in again with this name");
+ emit player->kicked();
+ }
+
if (player->getState() == Player::Offline) {
auto room = player->getRoom();
player->setSocket(client);
@@ -417,7 +423,7 @@ void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
} else {
// 懒得处理掉线玩家在大厅了!踢掉得了
player->doNotify("ErrorMsg", "Unknown Error");
- player->kicked();
+ emit player->kicked();
}
return;
diff --git a/src/server/serverplayer.cpp b/src/server/serverplayer.cpp
index 6e88973c..637a9f1c 100644
--- a/src/server/serverplayer.cpp
+++ b/src/server/serverplayer.cpp
@@ -105,6 +105,7 @@ void ServerPlayer::prepareForRequest(const QString &command,
}
void ServerPlayer::kick() {
+ setState(Player::Offline);
if (socket != nullptr) {
socket->disconnectFromHost();
}