130 lines
3.4 KiB
Lua
130 lines
3.4 KiB
Lua
-- 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
|