179 lines
6.5 KiB
Lua
179 lines
6.5 KiB
Lua
local ____lualib = require("lualib_bundle")
|
|
local Set = ____lualib.Set
|
|
local __TS__New = ____lualib.__TS__New
|
|
local __TS__ArrayIsArray = ____lualib.__TS__ArrayIsArray
|
|
local ____exports = {}
|
|
local ____server_config = require("server_config")
|
|
local SERVER_CONFIG = ____server_config.SERVER_CONFIG
|
|
local ____api_helper = require("api_helper")
|
|
local encodeApiBody = ____api_helper.encodeApiBody
|
|
local setApiHeadersLong = ____api_helper.setApiHeadersLong
|
|
local ____real_lobby_player = require("utils.real_lobby_player")
|
|
local isRealLobbyPlayer = ____real_lobby_player.isRealLobbyPlayer
|
|
local ____difficulty_manager = require("difficulty_manager")
|
|
local Difficulty = ____difficulty_manager.Difficulty
|
|
local setupCheckSentThisPhase = false
|
|
local setupCheckInFlight = false
|
|
function ____exports.resetGameSetupLobbyCheckPhase(self)
|
|
setupCheckSentThisPhase = false
|
|
setupCheckInFlight = false
|
|
end
|
|
local function collectLobbyPlayersForSetupCheck(self)
|
|
local players = {}
|
|
local seen = __TS__New(Set)
|
|
do
|
|
local i = 0
|
|
while i < DOTA_MAX_PLAYERS do
|
|
do
|
|
local pid = i
|
|
if not isRealLobbyPlayer(nil, pid) then
|
|
goto __continue4
|
|
end
|
|
local steam = PlayerResource:GetSteamAccountID(pid)
|
|
if not steam or steam == 0 then
|
|
goto __continue4
|
|
end
|
|
local steamId = tostring(steam)
|
|
if seen:has(steamId) then
|
|
goto __continue4
|
|
end
|
|
seen:add(steamId)
|
|
local row = {
|
|
steam_id = steamId,
|
|
player_name = PlayerResource:GetPlayerName(pid)
|
|
}
|
|
local dsContract = Difficulty:getDeathSentenceContractPayloadForLossPenalty(pid)
|
|
if dsContract then
|
|
row.death_sentence_contract = dsContract
|
|
end
|
|
players[#players + 1] = row
|
|
end
|
|
::__continue4::
|
|
i = i + 1
|
|
end
|
|
end
|
|
return players
|
|
end
|
|
local function syncContractsForClosedGames(self, closedGames)
|
|
if not closedGames or not __TS__ArrayIsArray(closedGames) then
|
|
return
|
|
end
|
|
local steamIdsToSync = __TS__New(Set)
|
|
for ____, row in ipairs(closedGames) do
|
|
do
|
|
if not row or type(row) ~= "table" then
|
|
goto __continue11
|
|
end
|
|
local steamId = row.steam_id
|
|
if type(steamId) == "string" and #steamId > 0 then
|
|
steamIdsToSync:add(steamId)
|
|
end
|
|
end
|
|
::__continue11::
|
|
end
|
|
if steamIdsToSync.size == 0 then
|
|
return
|
|
end
|
|
do
|
|
local i = 0
|
|
while i < DOTA_MAX_PLAYERS do
|
|
do
|
|
local pid = i
|
|
if not isRealLobbyPlayer(nil, pid) then
|
|
goto __continue16
|
|
end
|
|
local steamId = tostring(PlayerResource:GetSteamAccountID(pid))
|
|
if not steamIdsToSync:has(steamId) then
|
|
goto __continue16
|
|
end
|
|
Difficulty:RequestDeathSentenceContractsSync(pid)
|
|
end
|
|
::__continue16::
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
--- Один запрос на фазу CUSTOM_GAME_SETUP (повтор — если в лобби ещё не было игроков).
|
|
function ____exports.sendGameSetupLobbyCheck(self)
|
|
if setupCheckInFlight then
|
|
return
|
|
end
|
|
if GameRules:State_Get() ~= DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP then
|
|
return
|
|
end
|
|
local players = collectLobbyPlayersForSetupCheck(nil)
|
|
if #players == 0 then
|
|
return
|
|
end
|
|
setupCheckInFlight = true
|
|
local request = CreateHTTPRequestScriptVM("POST", SERVER_CONFIG.API_URL .. "/game/setup-check")
|
|
setApiHeadersLong(nil, request)
|
|
request:SetHTTPRequestRawPostBody(
|
|
"application/json",
|
|
encodeApiBody(nil, {players = players})
|
|
)
|
|
request:Send(function(result)
|
|
setupCheckInFlight = false
|
|
if result.StatusCode < 200 or result.StatusCode >= 300 then
|
|
print("[GameSetupLobbyCheck] ⚠️ setup-check HTTP " .. tostring(result.StatusCode))
|
|
return
|
|
end
|
|
setupCheckSentThisPhase = true
|
|
do
|
|
local function ____catch(e)
|
|
print("[GameSetupLobbyCheck] ⚠️ Ошибка разбора ответа:", e)
|
|
end
|
|
local ____try, ____hasReturned = pcall(function()
|
|
local decoded = {json.decode(result.Body)}
|
|
local data = decoded
|
|
if __TS__ArrayIsArray(decoded) and #decoded > 0 then
|
|
data = decoded[1]
|
|
elseif decoded and type(decoded) == "table" and decoded.value ~= nil then
|
|
data = decoded.value
|
|
end
|
|
local ____opt_result_2
|
|
if data ~= nil then
|
|
____opt_result_2 = data.closed_games
|
|
end
|
|
local closed = ____opt_result_2
|
|
local closedCount = closed and __TS__ArrayIsArray(closed) and #closed or 0
|
|
if closedCount > 0 then
|
|
print("[GameSetupLobbyCheck] ✅ Закрыто зависших игр: " .. tostring(closedCount))
|
|
syncContractsForClosedGames(nil, closed)
|
|
end
|
|
do
|
|
local i = 0
|
|
while i < DOTA_MAX_PLAYERS do
|
|
do
|
|
local pid = i
|
|
if not isRealLobbyPlayer(nil, pid) then
|
|
goto __continue29
|
|
end
|
|
Difficulty:forceReloadDeathSentenceContractsFromBackend(pid)
|
|
end
|
|
::__continue29::
|
|
i = i + 1
|
|
end
|
|
end
|
|
end)
|
|
if not ____try then
|
|
____catch(____hasReturned)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
--- Периодически в сетапе, пока не ушли запросом (поздно зашедшие в лобби).
|
|
function ____exports.tryGameSetupLobbyCheckFromTicker(self)
|
|
if setupCheckSentThisPhase or setupCheckInFlight then
|
|
return
|
|
end
|
|
if GameRules:State_Get() ~= DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP then
|
|
return
|
|
end
|
|
if #collectLobbyPlayersForSetupCheck(nil) == 0 then
|
|
return
|
|
end
|
|
____exports.sendGameSetupLobbyCheck(nil)
|
|
end
|
|
return ____exports
|