- 调度器善后
- 修复可用不足警告
- 创房时可以全选或者反选
- 重连时候不可以重新开大
- 顶号
This commit is contained in:
notify 2023-06-16 13:26:02 +08:00 committed by GitHub
parent e2c4d326c5
commit 02e22024f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 175 additions and 54 deletions

View File

@ -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();
}
}
}

View File

@ -25,16 +25,36 @@ Flickable {
text: "禁用Lua拓展 (重启后生效)"
}
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);
}
}
}
}
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,6 +110,14 @@ Flickable {
checked: pkg_enabled
onCheckedChanged: {
checkPackage(orig_name, checked);
}
}
}
}
}
function checkPackage(orig_name, checked) {
const packs = config.disabledPack;
if (checked) {
const idx = packs.indexOf(orig_name);
@ -83,10 +125,8 @@ Flickable {
} else {
packs.push(orig_name);
}
}
}
}
}
Backend.callLuaFunction("UpdatePackageEnable", [orig_name, checked]);
config.disabledPackChanged();
}
Component.onCompleted: {

View File

@ -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);
}

View File

@ -215,6 +215,10 @@
<source>others logged in with this name</source>
<translation></translation>
</message>
<message>
<source>others logged in again with this name</source>
<translation></translation>
</message>
<message>
<source>invalid user name</source>
<translation></translation>

View File

@ -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

View File

@ -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

View File

@ -46,6 +46,8 @@ Fk:loadTranslationTable{
["Package Settings"] = "拓展包设置",
["General Packages"] = "武将拓展包",
["Card Packages"] = "卡牌拓展包",
["Select All"] = "全选",
["Revert Selection"] = "反选",
["Give Flower"] = "送花",
["Give Egg"] = "砸蛋",

View File

@ -19,7 +19,6 @@
---@field public cards Card[] @ 所有卡牌
---@field public translations table<string, table<string, string>> @ 翻译表
---@field public game_modes table<string, GameMode> @ 所有游戏模式
---@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

View File

@ -541,9 +541,8 @@ function Player:setSkillUseHistory(skill_name, num, scope)
return
end
if self.skillUsedHistory[skill_name] then
self.skillUsedHistory[skill_name] = self.skillUsedHistory[skill_name] or {0, 0, 0, 0}
self.skillUsedHistory[skill_name][scope] = num
end
end
--- 获取玩家使用特定牌的历史次数。

View File

@ -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

View File

@ -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
-- 供调度器使用的函数。能让房间开始运行/从挂起状态恢复。

View File

@ -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

View File

@ -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;

View File

@ -105,6 +105,7 @@ void ServerPlayer::prepareForRequest(const QString &command,
}
void ServerPlayer::kick() {
setState(Player::Offline);
if (socket != nullptr) {
socket->disconnectFromHost();
}