2022-03-30 08:33:56 +00:00
|
|
|
---@class Room : Object
|
2022-03-31 05:29:23 +00:00
|
|
|
---@field room fk.Room
|
|
|
|
---@field server Server
|
|
|
|
---@field players table
|
|
|
|
---@field alive_players table
|
|
|
|
---@field game_finished boolean
|
|
|
|
---@field timeout number
|
2022-03-27 06:49:41 +00:00
|
|
|
local Room = class("Room")
|
2022-03-25 04:28:07 +00:00
|
|
|
|
2022-03-27 06:49:41 +00:00
|
|
|
function Room:initialize(_room)
|
|
|
|
self.room = _room
|
2022-03-31 05:29:23 +00:00
|
|
|
self.server = nil
|
2022-03-28 14:24:30 +00:00
|
|
|
self.players = {} -- ServerPlayer[]
|
2022-03-30 06:14:40 +00:00
|
|
|
self.alive_players = {}
|
|
|
|
self.game_finished = false
|
|
|
|
self.timeout = _room:getTimeout()
|
2022-03-27 06:49:41 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- When this function returns, the Room(C++) thread stopped.
|
|
|
|
function Room:run()
|
2022-03-31 05:29:23 +00:00
|
|
|
for _, p in fk.qlist(self.room:getPlayers()) do
|
2022-03-27 06:49:41 +00:00
|
|
|
local player = ServerPlayer:new(p)
|
2022-03-30 06:14:40 +00:00
|
|
|
player.state = p:getStateString()
|
2022-03-30 08:33:56 +00:00
|
|
|
player.room = self
|
2022-03-28 14:24:30 +00:00
|
|
|
table.insert(self.players, player)
|
|
|
|
self.server.players[player:getId()] = player
|
2022-03-27 06:49:41 +00:00
|
|
|
end
|
2022-03-28 14:24:30 +00:00
|
|
|
|
|
|
|
self.logic = GameLogic:new(self)
|
|
|
|
self.logic:run()
|
2022-03-27 06:49:41 +00:00
|
|
|
end
|
2022-03-25 04:28:07 +00:00
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param player ServerPlayer
|
|
|
|
---@param property string
|
2022-03-28 14:24:30 +00:00
|
|
|
function Room:broadcastProperty(player, property)
|
|
|
|
for _, p in ipairs(self.players) do
|
|
|
|
self:notifyProperty(p, player, property)
|
2022-03-27 06:49:41 +00:00
|
|
|
end
|
2022-03-25 04:28:07 +00:00
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param p ServerPlayer
|
|
|
|
---@param player ServerPlayer
|
|
|
|
---@param property string
|
2022-03-28 14:24:30 +00:00
|
|
|
function Room:notifyProperty(p, player, property)
|
|
|
|
p:doNotify("PropertyUpdate", json.encode{
|
|
|
|
player:getId(),
|
|
|
|
property,
|
|
|
|
player[property],
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param command string
|
|
|
|
---@param jsonData string
|
|
|
|
---@param players ServerPlayer[] # default all players
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:doBroadcastNotify(command, jsonData, players)
|
|
|
|
players = players or self.players
|
2022-03-31 05:29:23 +00:00
|
|
|
local tolist = fk.SPlayerList()
|
2022-03-30 06:14:40 +00:00
|
|
|
for _, p in ipairs(players) do
|
|
|
|
tolist:append(p.serverplayer)
|
|
|
|
end
|
|
|
|
self.room:doBroadcastNotify(tolist, command, jsonData)
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param player ServerPlayer
|
|
|
|
---@param command string
|
|
|
|
---@param jsonData string
|
|
|
|
---@param wait boolean # default true
|
|
|
|
---@return string | nil
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:doRequest(player, command, jsonData, wait)
|
|
|
|
if wait == nil then wait = true end
|
|
|
|
player:doRequest(command, jsonData, self.timeout)
|
|
|
|
|
|
|
|
if wait then
|
|
|
|
return player:waitForReply(self.timeout)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param command string
|
|
|
|
---@param players ServerPlayer[]
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:doBroadcastRequest(command, players)
|
|
|
|
players = players or self.players
|
|
|
|
self:notifyMoveFocus(players, command)
|
|
|
|
for _, p in ipairs(players) do
|
|
|
|
self:doRequest(p, command, p.request_data, false)
|
|
|
|
end
|
|
|
|
|
|
|
|
local remainTime = self.timeout
|
|
|
|
local currentTime = os.time()
|
|
|
|
local elapsed = 0
|
|
|
|
for _, p in ipairs(players) do
|
|
|
|
elapsed = os.time() - currentTime
|
|
|
|
remainTime = remainTime - elapsed
|
|
|
|
p:waitForReply(remainTime)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param players ServerPlayer | ServerPlayer[]
|
|
|
|
---@param command string
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:notifyMoveFocus(players, command)
|
|
|
|
if (players.class) then
|
|
|
|
players = {players}
|
|
|
|
end
|
|
|
|
|
|
|
|
local ids = {}
|
|
|
|
for _, p in ipairs(players) do
|
|
|
|
table.insert(ids, p:getId())
|
|
|
|
end
|
|
|
|
|
|
|
|
self:doBroadcastNotify("MoveFocus", json.encode{
|
|
|
|
ids,
|
|
|
|
command
|
|
|
|
})
|
2022-03-28 14:24:30 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function Room:adjustSeats()
|
|
|
|
local players = {}
|
|
|
|
local p = 0
|
|
|
|
|
|
|
|
for i = 1, #self.players do
|
|
|
|
if self.players[i].role == "lord" then
|
|
|
|
p = i
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for j = p, #self.players do
|
|
|
|
table.insert(players, self.players[j])
|
|
|
|
end
|
|
|
|
for j = 1, p - 1 do
|
|
|
|
table.insert(players, self.players[j])
|
|
|
|
end
|
|
|
|
|
|
|
|
self.players = players
|
|
|
|
|
|
|
|
local player_circle = {}
|
|
|
|
for i = 1, #self.players do
|
|
|
|
self.players[i].seat = i
|
|
|
|
table.insert(player_circle, self.players[i]:getId())
|
|
|
|
end
|
|
|
|
|
|
|
|
self:doBroadcastNotify("ArrangeSeats", json.encode(player_circle))
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@return ServerPlayer | nil
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:getLord()
|
|
|
|
local lord = self.players[1]
|
|
|
|
if lord.role == "lord" then return lord end
|
|
|
|
for _, p in ipairs(self.players) do
|
|
|
|
if p.role == "lord" then return p end
|
|
|
|
end
|
|
|
|
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param expect ServerPlayer
|
|
|
|
---@return ServerPlayer[]
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:getOtherPlayers(expect)
|
|
|
|
local ret = {table.unpack(self.players)}
|
|
|
|
table.removeOne(ret, expect)
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
2022-03-31 05:29:23 +00:00
|
|
|
---@param player ServerPlayer
|
|
|
|
---@param generals string[]
|
|
|
|
---@return string
|
2022-03-30 06:14:40 +00:00
|
|
|
function Room:askForGeneral(player, generals)
|
|
|
|
local command = "AskForGeneral"
|
|
|
|
self:notifyMoveFocus(player, command)
|
|
|
|
|
|
|
|
if #generals == 1 then return generals[1] end
|
|
|
|
local defaultChoice = generals[1]
|
|
|
|
|
|
|
|
if (player.state == "online") then
|
|
|
|
local result = self:doRequest(player, command, json.encode(generals))
|
|
|
|
if result == "" then
|
|
|
|
return defaultChoice
|
|
|
|
else
|
|
|
|
-- TODO: result is a JSON array
|
|
|
|
-- update here when choose multiple generals
|
|
|
|
return json.decode(result)[1]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return defaultChoice
|
|
|
|
end
|
|
|
|
|
2022-03-27 06:49:41 +00:00
|
|
|
function Room:gameOver()
|
2022-03-30 06:14:40 +00:00
|
|
|
self.game_finished = true
|
2022-03-27 06:49:41 +00:00
|
|
|
-- dosomething
|
|
|
|
self.room:gameOver()
|
2022-03-25 04:28:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return Room
|