mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-16 03:32:34 +08:00
parent
29fdfca9bb
commit
3dfff72836
|
@ -64,6 +64,14 @@ io = nil
|
||||||
package = nil
|
package = nil
|
||||||
load = nil
|
load = nil
|
||||||
loadfile = nil
|
loadfile = nil
|
||||||
|
local _dofile = dofile
|
||||||
|
dofile = function(f)
|
||||||
|
local errmsg = "Refusing dofile that not in game directory"
|
||||||
|
assert(not f:startsWith("/"), errmsg)
|
||||||
|
assert(not f:startsWith(".."), errmsg)
|
||||||
|
assert(not f:find(":"), errmsg)
|
||||||
|
return _dofile(f)
|
||||||
|
end
|
||||||
|
|
||||||
-- 初始化Engine类并置于Fk全局变量中,这里会加载拓展包
|
-- 初始化Engine类并置于Fk全局变量中,这里会加载拓展包
|
||||||
dofile "lua/fk_ex.lua"
|
dofile "lua/fk_ex.lua"
|
||||||
|
|
|
@ -61,9 +61,13 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
||||||
for _, info in ipairs(data.moveInfo) do
|
for _, info in ipairs(data.moveInfo) do
|
||||||
local realFromArea = self:getCardArea(info.cardId)
|
local realFromArea = self:getCardArea(info.cardId)
|
||||||
local playerAreas = { Player.Hand, Player.Equip, Player.Judge, Player.Special }
|
local playerAreas = { Player.Hand, Player.Equip, Player.Judge, Player.Special }
|
||||||
|
local virtualEquip
|
||||||
|
|
||||||
if table.contains(playerAreas, realFromArea) and data.from then
|
if table.contains(playerAreas, realFromArea) and data.from then
|
||||||
self:getPlayerById(data.from):removeCards(realFromArea, { info.cardId }, info.fromSpecialName)
|
local from = self:getPlayerById(data.from)
|
||||||
|
from:removeCards(realFromArea, { info.cardId }, info.fromSpecialName)
|
||||||
|
virtualEquip = from:getVirualEquip(info.cardId)
|
||||||
|
|
||||||
elseif realFromArea ~= Card.Unknown then
|
elseif realFromArea ~= Card.Unknown then
|
||||||
local fromAreaIds = {}
|
local fromAreaIds = {}
|
||||||
if realFromArea == Card.Processing then
|
if realFromArea == Card.Processing then
|
||||||
|
@ -80,7 +84,10 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
if table.contains(playerAreas, data.toArea) and data.to then
|
if table.contains(playerAreas, data.toArea) and data.to then
|
||||||
self:getPlayerById(data.to):addCards(data.toArea, { info.cardId }, data.specialName)
|
local to = self:getPlayerById(data.to)
|
||||||
|
if virtualEquip then to:addVirtualEquip(virtualEquip) end
|
||||||
|
to:addCards(data.toArea, { info.cardId }, data.specialName)
|
||||||
|
|
||||||
else
|
else
|
||||||
local toAreaIds = {}
|
local toAreaIds = {}
|
||||||
if data.toArea == Card.Processing then
|
if data.toArea == Card.Processing then
|
||||||
|
|
129
lua/server/request.lua
Normal file
129
lua/server/request.lua
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
-- SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
local function tellRoomToObserver(self, player)
|
||||||
|
local observee = self.players[1]
|
||||||
|
player:doNotify("Setup", json.encode{
|
||||||
|
observee.id,
|
||||||
|
observee.serverplayer:getScreenName(),
|
||||||
|
observee.serverplayer:getAvatar(),
|
||||||
|
})
|
||||||
|
player:doNotify("EnterRoom", json.encode{
|
||||||
|
#self.players, self.timeout, self.settings
|
||||||
|
})
|
||||||
|
|
||||||
|
-- send player data
|
||||||
|
for _, p in ipairs(self:getOtherPlayers(observee, true, true)) do
|
||||||
|
player:doNotify("AddPlayer", json.encode{
|
||||||
|
p.id,
|
||||||
|
p.serverplayer:getScreenName(),
|
||||||
|
p.serverplayer:getAvatar(),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local player_circle = {}
|
||||||
|
for i = 1, #self.players do
|
||||||
|
table.insert(player_circle, self.players[i].id)
|
||||||
|
end
|
||||||
|
player:doNotify("ArrangeSeats", json.encode(player_circle))
|
||||||
|
|
||||||
|
for _, p in ipairs(self.players) do
|
||||||
|
self:notifyProperty(player, p, "general")
|
||||||
|
self:notifyProperty(player, p, "deputyGeneral")
|
||||||
|
p:marshal(player)
|
||||||
|
end
|
||||||
|
|
||||||
|
player:doNotify("UpdateDrawPile", #self.draw_pile)
|
||||||
|
player:doNotify("UpdateRoundNum", self:getTag("RoundCount") or 0)
|
||||||
|
|
||||||
|
table.insert(self.observers, {observee.id, player})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function addObserver(self, id)
|
||||||
|
local all_observers = self.room:getObservers()
|
||||||
|
for _, p in fk.qlist(all_observers) do
|
||||||
|
if p:getId() == id then
|
||||||
|
tellRoomToObserver(self, p)
|
||||||
|
self:doBroadcastNotify("AddObserver", json.encode{
|
||||||
|
p:getId(),
|
||||||
|
p:getScreenName(),
|
||||||
|
p:getAvatar()
|
||||||
|
})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function removeObserver(self, id)
|
||||||
|
for _, t in ipairs(self.observers) do
|
||||||
|
local __, p = table.unpack(t)
|
||||||
|
if p:getId() == id then
|
||||||
|
table.removeOne(self.observers, t)
|
||||||
|
self:doBroadcastNotify("RemoveObserver", json.encode{
|
||||||
|
p:getId(),
|
||||||
|
})
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local request_handlers = {}
|
||||||
|
request_handlers["reconnect"] = function(room, id, reqlist)
|
||||||
|
local p = room:getPlayerById(id)
|
||||||
|
p:reconnect()
|
||||||
|
end
|
||||||
|
|
||||||
|
request_handlers["observe"] = function(room, id, reqlist)
|
||||||
|
addObserver(room, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
request_handlers["leave"] = function(room, id, reqlist)
|
||||||
|
removeObserver(room, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
request_handlers["prelight"] = function(room, id, reqlist)
|
||||||
|
local p = room:getPlayerById(id)
|
||||||
|
p:prelightSkill(reqlist[3], reqlist[4] == "true")
|
||||||
|
end
|
||||||
|
|
||||||
|
request_handlers["changeself"] = function(room, id, reqlist)
|
||||||
|
local p = room:getPlayerById(id)
|
||||||
|
local toId = tonumber(reqlist[3])
|
||||||
|
local from = p
|
||||||
|
local to = room:getPlayerById(toId)
|
||||||
|
local from_sp = from._splayer
|
||||||
|
|
||||||
|
-- 注意发来信息的玩家的主视角可能已经不是自己了
|
||||||
|
-- 先换成正确的玩家
|
||||||
|
from = table.find(room.players, function(p)
|
||||||
|
return table.contains(p._observers, from_sp)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- 切换视角
|
||||||
|
table.removeOne(from._observers, from_sp)
|
||||||
|
table.insert(to._observers, from_sp)
|
||||||
|
from_sp:doNotify("ChangeSelf", json.encode {
|
||||||
|
id = toId,
|
||||||
|
handcards = to:getCardIds(Player.Hand),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function requestLoop(self, rest_time)
|
||||||
|
while true do
|
||||||
|
local ret = false
|
||||||
|
local request = self.room:fetchRequest()
|
||||||
|
if request ~= "" then
|
||||||
|
ret = true
|
||||||
|
local reqlist = request:split(",")
|
||||||
|
local id = tonumber(reqlist[1])
|
||||||
|
local command = reqlist[2]
|
||||||
|
request_handlers[command](self, id, reqlist)
|
||||||
|
elseif rest_time > 10 then
|
||||||
|
-- let current thread sleep 10ms
|
||||||
|
-- otherwise CPU usage will be 100% (infinite yield <-> resume loop)
|
||||||
|
fk.QThread_msleep(10)
|
||||||
|
end
|
||||||
|
coroutine.yield(ret)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return requestLoop
|
|
@ -630,119 +630,7 @@ function Room:doRaceRequest(command, players, jsonData)
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
-- main loop for the request handling coroutine
|
Room.requestLoop = require "server.request"
|
||||||
--- 这是个私有函数,不用管。
|
|
||||||
function Room:requestLoop(rest_time)
|
|
||||||
local function tellRoomToObserver(player)
|
|
||||||
local observee = self.players[1]
|
|
||||||
player:doNotify("Setup", json.encode{
|
|
||||||
observee.id,
|
|
||||||
observee.serverplayer:getScreenName(),
|
|
||||||
observee.serverplayer:getAvatar(),
|
|
||||||
})
|
|
||||||
player:doNotify("EnterRoom", json.encode{
|
|
||||||
#self.players, self.timeout, self.settings
|
|
||||||
})
|
|
||||||
|
|
||||||
-- send player data
|
|
||||||
for _, p in ipairs(self:getOtherPlayers(observee, true, true)) do
|
|
||||||
player:doNotify("AddPlayer", json.encode{
|
|
||||||
p.id,
|
|
||||||
p.serverplayer:getScreenName(),
|
|
||||||
p.serverplayer:getAvatar(),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local player_circle = {}
|
|
||||||
for i = 1, #self.players do
|
|
||||||
table.insert(player_circle, self.players[i].id)
|
|
||||||
end
|
|
||||||
player:doNotify("ArrangeSeats", json.encode(player_circle))
|
|
||||||
|
|
||||||
for _, p in ipairs(self.players) do
|
|
||||||
self:notifyProperty(player, p, "general")
|
|
||||||
self:notifyProperty(player, p, "deputyGeneral")
|
|
||||||
p:marshal(player)
|
|
||||||
end
|
|
||||||
|
|
||||||
player:doNotify("UpdateDrawPile", #self.draw_pile)
|
|
||||||
player:doNotify("UpdateRoundNum", self:getTag("RoundCount") or 0)
|
|
||||||
|
|
||||||
table.insert(self.observers, {observee.id, player})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function addObserver(id)
|
|
||||||
local all_observers = self.room:getObservers()
|
|
||||||
for _, p in fk.qlist(all_observers) do
|
|
||||||
if p:getId() == id then
|
|
||||||
tellRoomToObserver(p)
|
|
||||||
self:doBroadcastNotify("AddObserver", json.encode{
|
|
||||||
p:getId(),
|
|
||||||
p:getScreenName(),
|
|
||||||
p:getAvatar()
|
|
||||||
})
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function removeObserver(id)
|
|
||||||
for _, t in ipairs(self.observers) do
|
|
||||||
local __, p = table.unpack(t)
|
|
||||||
if p:getId() == id then
|
|
||||||
table.removeOne(self.observers, t)
|
|
||||||
self:doBroadcastNotify("RemoveObserver", json.encode{
|
|
||||||
p:getId(),
|
|
||||||
})
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local ret = false
|
|
||||||
local request = self.room:fetchRequest()
|
|
||||||
if request ~= "" then
|
|
||||||
ret = true
|
|
||||||
local reqlist = request:split(",")
|
|
||||||
local id = tonumber(reqlist[1])
|
|
||||||
local command = reqlist[2]
|
|
||||||
if command == "reconnect" then
|
|
||||||
self:getPlayerById(id):reconnect()
|
|
||||||
elseif command == "observe" then
|
|
||||||
addObserver(id)
|
|
||||||
elseif command == "leave" then
|
|
||||||
removeObserver(id)
|
|
||||||
elseif command == "prelight" then
|
|
||||||
self:getPlayerById(id):prelightSkill(reqlist[3], reqlist[4] == "true")
|
|
||||||
elseif command == "changeself" then
|
|
||||||
local toId = tonumber(reqlist[3])
|
|
||||||
local from = self:getPlayerById(id)
|
|
||||||
local to = self:getPlayerById(toId)
|
|
||||||
local from_sp = from._splayer
|
|
||||||
|
|
||||||
-- 注意发来信息的玩家的主视角可能已经不是自己了
|
|
||||||
-- 先换成正确的玩家
|
|
||||||
from = table.find(self.players, function(p)
|
|
||||||
return table.contains(p._observers, from_sp)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- 切换视角
|
|
||||||
table.removeOne(from._observers, from_sp)
|
|
||||||
table.insert(to._observers, from_sp)
|
|
||||||
from_sp:doNotify("ChangeSelf", json.encode {
|
|
||||||
id = toId,
|
|
||||||
handcards = to:getCardIds(Player.Hand),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
elseif rest_time > 10 then
|
|
||||||
-- let current thread sleep 10ms
|
|
||||||
-- otherwise CPU usage will be 100% (infinite yield <-> resume loop)
|
|
||||||
fk.QThread_msleep(10)
|
|
||||||
end
|
|
||||||
coroutine.yield(ret)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- 延迟一段时间。
|
--- 延迟一段时间。
|
||||||
---
|
---
|
||||||
|
@ -2016,6 +1904,15 @@ function Room:doCardEffect(cardEffectEvent)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if not table.contains(players, p) then
|
||||||
|
for _, s in ipairs(p.player_skills) do
|
||||||
|
if s.pattern and Exppattern:Parse("nullification"):matchExp(s.pattern)
|
||||||
|
and not table.contains(cardEffectEvent.disresponsiveList or {}, p.id) then
|
||||||
|
table.insert(players, p)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local prompt = ""
|
local prompt = ""
|
||||||
|
|
|
@ -670,9 +670,13 @@ local lightningSkill = fk.CreateActiveSkill{
|
||||||
local nextp = to
|
local nextp = to
|
||||||
repeat
|
repeat
|
||||||
nextp = nextp:getNextAlive()
|
nextp = nextp:getNextAlive()
|
||||||
if nextp == to then return end
|
if nextp == to then break end
|
||||||
until not nextp:hasDelayedTrick("lightning")
|
until not nextp:hasDelayedTrick("lightning")
|
||||||
|
|
||||||
|
if effect.card:isVirtual() then
|
||||||
|
nextp:addVirtualEquip(effect.card)
|
||||||
|
end
|
||||||
|
|
||||||
room:moveCards{
|
room:moveCards{
|
||||||
ids = room:getSubcardsByRule(effect.card, { Card.Processing }),
|
ids = room:getSubcardsByRule(effect.card, { Card.Processing }),
|
||||||
to = nextp.id,
|
to = nextp.id,
|
||||||
|
|
|
@ -101,6 +101,7 @@ local test_active = fk.CreateActiveSkill{
|
||||||
}
|
}
|
||||||
local test_vs = fk.CreateViewAsSkill{
|
local test_vs = fk.CreateViewAsSkill{
|
||||||
name = "test_vs",
|
name = "test_vs",
|
||||||
|
pattern = "nullification",
|
||||||
card_filter = function(self, to_select, selected)
|
card_filter = function(self, to_select, selected)
|
||||||
return #selected == 0
|
return #selected == 0
|
||||||
end,
|
end,
|
||||||
|
@ -113,6 +114,8 @@ local test_vs = fk.CreateViewAsSkill{
|
||||||
"dismantlement",
|
"dismantlement",
|
||||||
"savage_assault",
|
"savage_assault",
|
||||||
"archery_attack",
|
"archery_attack",
|
||||||
|
"lightning",
|
||||||
|
"nullification",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -83,6 +83,7 @@ Item {
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: screenNameEdit
|
id: screenNameEdit
|
||||||
|
maximumLength: 32
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
placeholderText: qsTr("Username")
|
placeholderText: qsTr("Username")
|
||||||
text: ""
|
text: ""
|
||||||
|
@ -103,6 +104,7 @@ Item {
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: passwordEdit
|
id: passwordEdit
|
||||||
|
maximumLength: 64
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
placeholderText: qsTr("Password")
|
placeholderText: qsTr("Password")
|
||||||
text: ""
|
text: ""
|
||||||
|
|
|
@ -15,6 +15,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: roomName
|
id: roomName
|
||||||
|
maximumLength: 64
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
text: Backend.translate("$RoomName").arg(Self.screenName)
|
text: Backend.translate("$RoomName").arg(Self.screenName)
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ ColumnLayout {
|
||||||
SpinBox {
|
SpinBox {
|
||||||
id: generalNum
|
id: generalNum
|
||||||
from: 3
|
from: 3
|
||||||
to: 8
|
to: 18
|
||||||
value: config.preferredGeneralNum
|
value: config.preferredGeneralNum
|
||||||
|
|
||||||
onValueChanged: {
|
onValueChanged: {
|
||||||
|
|
|
@ -27,6 +27,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: avatarName
|
id: avatarName
|
||||||
|
maximumLength: 64
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
text: Self.avatar
|
text: Self.avatar
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,12 +68,13 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
// tmp
|
// tmp
|
||||||
Button {
|
DelayButton {
|
||||||
id: quitButton
|
id: quitButton
|
||||||
text: "quit"
|
text: "quit"
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onClicked: {
|
delay: Debugging ? 10 : 1000
|
||||||
|
onActivated: {
|
||||||
// ClientInstance.clearPlayers();
|
// ClientInstance.clearPlayers();
|
||||||
ClientInstance.notifyServer("QuitRoom", "[]");
|
ClientInstance.notifyServer("QuitRoom", "[]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ Item {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
TextField {
|
TextField {
|
||||||
id: screenNameEdit
|
id: screenNameEdit
|
||||||
|
maximumLength: 32
|
||||||
text: "player"
|
text: "player"
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
passwordEdit.text = "";
|
passwordEdit.text = "";
|
||||||
|
@ -35,6 +36,7 @@ Item {
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: passwordEdit
|
id: passwordEdit
|
||||||
|
maximumLength: 64
|
||||||
text: ""
|
text: ""
|
||||||
echoMode: TextInput.Password
|
echoMode: TextInput.Password
|
||||||
passwordCharacter: "*"
|
passwordCharacter: "*"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user