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