local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local Map = ____lualib.Map local __TS__New = ____lualib.__TS__New local __TS__ArrayIncludes = ____lualib.__TS__ArrayIncludes local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith local __TS__ArraySort = ____lualib.__TS__ArraySort local __TS__ArrayIsArray = ____lualib.__TS__ArrayIsArray local __TS__ObjectValues = ____lualib.__TS__ObjectValues local __TS__ArrayFrom = ____lualib.__TS__ArrayFrom local __TS__ArrayMap = ____lualib.__TS__ArrayMap local __TS__ArraySome = ____lualib.__TS__ArraySome local __TS__Decorate = ____lualib.__TS__Decorate local ____exports = {} local ____tstl_2Dutils = require("lib.tstl-utils") local reloadable = ____tstl_2Dutils.reloadable require("utils.utils") local ____crystal_currency = require("crystal_currency") local CrystalCurrency = ____crystal_currency.CrystalCurrency local ____blackshop = require("blackshop") local BlackShop = ____blackshop.BlackShop local ____CardSystem = require("cards.CardSystem") local ShowCardSelectionToPlayer = ____CardSystem.ShowCardSelectionToPlayer local ____SpawnManager = require("SpawnManager") local SpawnManager = ____SpawnManager.SpawnManager local ____WaveManager = require("WaveManager") local WaveManager = ____WaveManager.WaveManager local ____DayNightCycleManager = require("DayNightCycleManager") local DayNightCycleManager = ____DayNightCycleManager.DayNightCycleManager local DOTA_ModifyXP_Unspecified = 0 ____exports.AdminMenuManager = __TS__Class() local AdminMenuManager = ____exports.AdminMenuManager AdminMenuManager.name = "AdminMenuManager" AdminMenuManager.____file_path = "scripts/vscripts/admin_menu.lua" function AdminMenuManager.prototype.____constructor(self) self.selectedEntities = __TS__New(Map) self.spawnZoneCounter = 0 end function AdminMenuManager.getInstance(self) if not ____exports.AdminMenuManager.instance then ____exports.AdminMenuManager.instance = __TS__New(____exports.AdminMenuManager) end return ____exports.AdminMenuManager.instance end function AdminMenuManager.prototype.initialize(self) CustomGameEventManager:RegisterListener( "admin_spawn_hero", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSpawnHero(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_spawn_target", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSpawnTarget(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_give_item", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleGiveItem(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_request_items_list", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleRequestItemsList(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_change_level", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleChangeLevel(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_toggle_invulnerable", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleToggleInvulnerable(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_toggle_scepter", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleToggleScepter(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_toggle_shard", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleToggleShard(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_change_side", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleChangeSide(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_reset_hero", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleResetHero(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_delete_hero", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleDeleteHero(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_delete_entity", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleDeleteEntity(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_toggle_setting", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleToggleSetting(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_refresh_spells", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleRefreshSpells(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_refresh_health", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleRefreshHealth(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_give_gold", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleGiveGold(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_change_luck", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleChangeLuck(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_change_physical_vampirism", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleChangePhysicalVampirism(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_change_magical_vampirism", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleChangeMagicalVampirism(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_give_crystals", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleGiveCrystals(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_pause_game", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handlePauseGame(playerId) end ) CustomGameEventManager:RegisterListener( "admin_exit_game", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleExitGame(playerId) end ) CustomGameEventManager:RegisterListener( "admin_set_timescale", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSetTimeScale(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_script_reload", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleScriptReload(playerId) end ) CustomGameEventManager:RegisterListener( "admin_spawn_zone_create", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSpawnZoneCreate(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_spawn_zone_delete_here", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSpawnZoneDeleteHere(playerId) end ) CustomGameEventManager:RegisterListener( "admin_toggle_spawn_debug_zones", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleToggleSpawnDebugZones(playerId) end ) CustomGameEventManager:RegisterListener( "admin_change_hero", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleChangeHero(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_request_steam_id", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleRequestSteamId(playerId) end ) CustomGameEventManager:RegisterListener( "admin_check_cheat_mode", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleCheckCheatMode(playerId) end ) CustomGameEventManager:RegisterListener( "admin_request_spawn_units_list", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleRequestSpawnUnitsList(playerId) end ) CustomGameEventManager:RegisterListener( "admin_spawn_units_once", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSpawnUnitsOnce(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_set_next_wave", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSetNextWave(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_force_morning", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleForceMorning(playerId) end ) CustomGameEventManager:RegisterListener( "admin_adjust_daynight_timer", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleAdjustDayNightTimer(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_set_daynight_timer", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleSetDayNightTimer(playerId, event) end ) CustomGameEventManager:RegisterListener( "admin_show_card_selection", function(source, event) local playerId = event.PlayerID ~= nil and event.PlayerID or source self:handleShowCardSelection(playerId, event) end ) print("[AdminMenu] Инициализирован менеджер админ-меню") end function AdminMenuManager.prototype.checkAdminAccess(self, playerId) if GameRules:IsCheatMode() or Convars:GetBool("sv_cheats") then return true end local steamId = tostring(PlayerResource:GetSteamAccountID(playerId)) local allowedSteamIds = {"877002179", "453736017", "170695158"} local hasAccess = __TS__ArrayIncludes(allowedSteamIds, steamId) if hasAccess then print(((("[AdminMenu] Доступ разрешен для игрока " .. tostring(playerId)) .. " (Steam ID: ") .. steamId) .. ")") else print(((("[AdminMenu] Доступ запрещен для игрока " .. tostring(playerId)) .. " (Steam ID: ") .. steamId) .. ")") end return hasAccess end function AdminMenuManager.prototype.handleToggleSpawnDebugZones(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к debug зонам спавна") return end SpawnManager:getInstance():ToggleDebugZones() end function AdminMenuManager.prototype.handleRequestSpawnUnitsList(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к списку юнитов спавна") return end local player = PlayerResource:GetPlayer(playerId) if not player then return end local units = {} do local function ____catch(e) print("[AdminMenu] Ошибка при загрузке npc_units_custom.txt: " .. tostring(e)) end local ____try, ____hasReturned = pcall(function() local kv = LoadKeyValues("scripts/npc/npc_units_custom.txt") if kv then for key in pairs(kv) do if type(key) == "string" and __TS__StringStartsWith(key, "npc_") then units[#units + 1] = key end end end end) if not ____try then ____catch(____hasReturned) end end __TS__ArraySort(units) CustomGameEventManager:Send_ServerToPlayer(player, "admin_spawn_units_list", {units = units}) end function AdminMenuManager.prototype.handleSpawnUnitsOnce(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к одноразовому спавну юнитов") return end local hero = PlayerResource:GetSelectedHeroEntity(playerId) if not hero or not IsValidEntity(hero) then print("[AdminMenu] Не найден валидный герой для одноразового спавна юнитов") return end local center = hero:GetAbsOrigin() local units = {} if event.units then local rawUnits = __TS__ArrayIsArray(event.units) and event.units or __TS__ObjectValues(event.units) for ____, u in ipairs(rawUnits) do if u and u.unitName ~= nil then local count = u.count and u.count > 0 and u.count or 1 units[#units + 1] = {unitName = u.unitName, count = count} end end end if #units == 0 then print("[AdminMenu] Одноразовый спавн отменён: список юнитов пуст") return end for ____, unitInfo in ipairs(units) do do local i = 0 while i < unitInfo.count do local angle = math.rad(RandomFloat(0, 360)) local distance = RandomFloat(0, 200) local pos = GetGroundPosition( Vector( center.x + distance * math.cos(angle), center.y + distance * math.sin(angle), center.z ), nil ) CreateUnitByName( unitInfo.unitName, pos, true, nil, nil, DOTA_TEAM_NEUTRALS ) i = i + 1 end end end end function AdminMenuManager.prototype.handleSpawnHero(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе") return end local heroName = event.heroName or "npc_dota_hero_crystal_maiden" local team = event.team or DOTA_TEAM_GOODGUYS local ____type = event.type or "ally" local player = PlayerResource:GetPlayer(playerId) local spawnPos if player then local hero = PlayerResource:GetSelectedHeroEntity(playerId) if hero and IsValidEntity(hero) then spawnPos = hero:GetAbsOrigin() else spawnPos = Vector(0, 0, 256) end else spawnPos = Vector(0, 0, 256) end PrecacheUnitByNameAsync( heroName, function() local unit = CreateUnitByName( heroName, spawnPos, true, nil, nil, team ) if unit and IsValidEntity(unit) then FindClearSpaceForUnit(unit, spawnPos, true) unit:SetControllableByPlayer(playerId, true) if unit:IsRealHero() then local hero = unit while hero:GetLevel() > 1 do hero:HeroLevelUp(false) end hero:SetAbilityPoints(1) end self.selectedEntities:set( unit:GetEntityIndex(), unit ) print((("[AdminMenu] Заспавнен " .. heroName) .. " для команды ") .. tostring(team)) end end ) end function AdminMenuManager.prototype.handleSpawnTarget(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе") return end local player = PlayerResource:GetPlayer(playerId) local spawnPos if player then local hero = PlayerResource:GetSelectedHeroEntity(playerId) if hero and IsValidEntity(hero) then local heroPos = hero:GetAbsOrigin() local heroForward = hero:GetForwardVector() local offset = Vector(heroForward.x * 300, heroForward.y * 300, 0) spawnPos = Vector(heroPos.x + offset.x, heroPos.y + offset.y, heroPos.z) spawnPos = GetGroundPosition(spawnPos, nil) else spawnPos = Vector(0, 0, 256) end else spawnPos = Vector(0, 0, 256) end local unit = CreateUnitByName( "npc_dummy_test", spawnPos, true, nil, nil, DOTA_TEAM_NEUTRALS ) if unit and IsValidEntity(unit) then FindClearSpaceForUnit(unit, spawnPos, true) unit:SetControllableByPlayer(playerId, true) if player then unit:SetOwner(player) end local dpsTracker = unit:AddNewModifier( unit, getModifierSourceAbility(nil, unit), "modifier_dps_tracker", {} ) self.selectedEntities:set( unit:GetEntityIndex(), unit ) print((((((("[AdminMenu] Заспавнена мишень npc_dummy_test на позиции " .. tostring(spawnPos.x)) .. ", ") .. tostring(spawnPos.y)) .. ", ") .. tostring(spawnPos.z)) .. ", управляемая игроком ") .. tostring(playerId)) else print("[AdminMenu] Ошибка: не удалось заспавнить мишень npc_dummy_test") end end function AdminMenuManager.prototype.handleGiveItem(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе") return end local itemName = event.itemName print((("[AdminMenu] handleGiveItem вызван для игрока " .. tostring(playerId)) .. ", предмет: ") .. tostring(itemName)) if not itemName then print("[AdminMenu] Ошибка: не указано имя предмета") return end local player = PlayerResource:GetPlayer(playerId) local targetUnit if self.selectedEntities.size > 0 then local firstEntity = __TS__ArrayFrom(self.selectedEntities:values())[1] if firstEntity and IsValidEntity(firstEntity) then targetUnit = firstEntity end end if not targetUnit and player then local hero = PlayerResource:GetSelectedHeroEntity(playerId) if hero and IsValidEntity(hero) then targetUnit = hero end end if not targetUnit or not IsValidEntity(targetUnit) then print("[AdminMenu] Ошибка: не найдена цель для выдачи предмета. Выбранных сущностей: " .. tostring(self.selectedEntities.size)) return end print((("[AdminMenu] Цель найдена: " .. targetUnit:GetUnitName()) .. ", является героем: ") .. tostring(targetUnit:IsRealHero())) local isBlackshopItem = string.sub(itemName, 1, 16) == "item_blackshop_" print((("[AdminMenu] Предмет является blackshop: " .. tostring(isBlackshopItem)) .. ", itemName: ") .. itemName) if isBlackshopItem then if targetUnit:IsRealHero() then local hero = targetUnit print("[AdminMenu] Создание blackshop предмета " .. itemName) local item = CreateItem(itemName, nil, nil) if item and IsValidEntity(item) then print("[AdminMenu] Предмет создан, добавление герою") local addedItem = hero:AddItem(item) if addedItem and IsValidEntity(addedItem) then print("[AdminMenu] Предмет добавлен, использование...") addedItem:CastAbility() print((("[AdminMenu] Выдан blackshop предмет " .. itemName) .. " игроку ") .. tostring(playerId)) else print(("[AdminMenu] Ошибка: не удалось добавить blackshop предмет " .. itemName) .. ", инвентарь полон?") UTIL_Remove(item) end else print("[AdminMenu] Ошибка: не удалось создать предмет " .. itemName) end else print("[AdminMenu] Ошибка: цель не является героем для blackshop предмета") end else if targetUnit:IsRealHero() then local hero = targetUnit print("[AdminMenu] Выдача обычного предмета " .. itemName) local addedItem = hero:AddItemByName(itemName) if addedItem ~= nil and addedItem ~= nil then print((("[AdminMenu] Выдан предмет " .. itemName) .. " игроку ") .. tostring(playerId)) else print(("[AdminMenu] Ошибка: не удалось выдать предмет " .. itemName) .. ", возможно инвентарь полон или предмет не существует") end else print("[AdminMenu] Цель не является героем, создаем предмет на земле рядом с " .. targetUnit:GetUnitName()) local unitPos = targetUnit:GetAbsOrigin() local forward = targetUnit:GetForwardVector() local dropPos = Vector(unitPos.x + forward.x * 100, unitPos.y + forward.y * 100, unitPos.z) local groundPos = GetGroundPosition(dropPos, nil) local item = CreateItem(itemName, nil, nil) if item and IsValidEntity(item) then CreateItemOnPositionForLaunch(groundPos, item) item:SetAbsOrigin(groundPos) print((("[AdminMenu] Предмет " .. itemName) .. " создан на земле рядом с ") .. targetUnit:GetUnitName()) else print("[AdminMenu] Ошибка: не удалось создать предмет " .. itemName) end end end end function AdminMenuManager.prototype.handleRequestItemsList(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local category = event.category or "default" local player = PlayerResource:GetPlayer(playerId) if not player then return end local itemsList = {} if category == "blackshop" then local blackShop = BlackShop:getInstance() local shopItems = blackShop.shopItems if shopItems and __TS__ArrayIsArray(shopItems) then local itemsWithQuality = __TS__ArrayMap( shopItems, function(____, item) return {name = item.name, quality = item.quality} end ) CustomGameEventManager:Send_ServerToPlayer(player, "admin_items_list", {category = category, items = itemsWithQuality}) print((("[AdminMenu] Отправка списка blackshop предметов с качеством для категории " .. category) .. ", количество: ") .. tostring(#itemsWithQuality)) return else print("[AdminMenu] Ошибка: не удалось получить список blackshop предметов") end elseif category == "util_items" then itemsList = self:getItemsFromKvByScriptPrefix({"scripts/npc/items/util_items.kv"}, {"items/util_items/"}) elseif category == "quest_items" then itemsList = self:getItemsFromKvByScriptPrefix({"scripts/npc/items/quest_items.kv"}, {"items/quest_items/"}, true) elseif category == "admin_items" then itemsList = {"item_blink", "item_test"} else itemsList = self:getItemsFromKvByScriptPrefix({"scripts/npc/items/custom_items.kv", "scripts/npc/npc_items_custom.txt"}, {"items/default_items/"}) end print((("[AdminMenu] Отправка списка предметов для категории " .. category) .. ", количество: ") .. tostring(#itemsList)) CustomGameEventManager:Send_ServerToPlayer(player, "admin_items_list", {category = category, items = itemsList}) print("[AdminMenu] Список предметов отправлен игроку " .. tostring(playerId)) end function AdminMenuManager.prototype.getItemsFromKvByScriptPrefix(self, kvPaths, scriptPrefixes, allowItemsWithoutScriptFile) if allowItemsWithoutScriptFile == nil then allowItemsWithoutScriptFile = false end do local function ____catch(e) print("[AdminMenu] Ошибка получения списка предметов из KV: " .. tostring(e)) return true, {} end local ____try, ____hasReturned, ____returnValue = pcall(function() local uniqueItems = {} for ____, kvPath in ipairs(kvPaths) do do local kv = LoadKeyValues(kvPath) if not kv then goto __continue130 end local abilitiesRoot = kv.DOTAAbilities or kv for key in pairs(abilitiesRoot) do do if not __TS__StringStartsWith(key, "item_") then goto __continue132 end if __TS__StringStartsWith(key, "item_recipe_") then goto __continue132 end if __TS__StringStartsWith(key, "item_blackshop_") then goto __continue132 end if key == "item_aghanims_shard" or key == "item_aghanims_shard_roshan" then goto __continue132 end local abilityDef = abilitiesRoot[key] local scriptFile = abilityDef and abilityDef.ScriptFile if type(scriptFile) == "string" and #tostring(scriptFile) > 0 then local scriptFilePath = tostring(scriptFile) local hasMatchedPrefix = __TS__ArraySome( scriptPrefixes, function(____, prefix) return __TS__StringStartsWith(scriptFilePath, prefix) end ) if not hasMatchedPrefix then goto __continue132 end elseif not allowItemsWithoutScriptFile then goto __continue132 end uniqueItems[key] = true end ::__continue132:: end end ::__continue130:: end local items = {} for itemName in pairs(uniqueItems) do items[#items + 1] = itemName end __TS__ArraySort(items) return true, items end) if not ____try then ____hasReturned, ____returnValue = ____catch(____hasReturned) end if ____hasReturned then return ____returnValue end end end function AdminMenuManager.prototype.handleChangeLevel(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local amount = event.amount or 1 local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then print("[AdminMenu] Нет выбранных сущностей для изменения уровня. Выделите существо или используйте кнопки +СОЮЗНИК/+ВРАГ/+МИШЕНЬ") return end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit local currentLevel = hero:GetLevel() local newLevel = math.min( math.max(currentLevel + amount, 1), 30 ) if newLevel > currentLevel then while hero:GetLevel() < newLevel do hero:HeroLevelUp(false) end hero:SetAbilityPoints(hero:GetAbilityPoints() + (newLevel - currentLevel)) elseif newLevel < currentLevel then local xpNeeded = hero:GetCurrentXP() hero:AddExperience(-xpNeeded, DOTA_ModifyXP_Unspecified, false, true) while hero:GetLevel() < newLevel do hero:HeroLevelUp(false) end end print((((("[AdminMenu] Уровень героя " .. hero:GetUnitName()) .. " изменен: ") .. tostring(currentLevel)) .. " -> ") .. tostring(newLevel)) end end end function AdminMenuManager.prototype.handleToggleInvulnerable(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) then local hasModifier = unit:HasModifier("modifier_fountain_glyph") if hasModifier then unit:RemoveModifierByName("modifier_fountain_glyph") print("[AdminMenu] Модификатор modifier_invulnerable удален у " .. unit:GetUnitName()) else unit:AddNewModifier( nil, getModifierSourceAbility(nil, nil), "modifier_fountain_glyph", {} ) print("[AdminMenu] Модификатор modifier_invulnerable добавлен " .. unit:GetUnitName()) end end end end function AdminMenuManager.prototype.handleToggleScepter(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit local existingBlessing = hero:FindItemInInventory("item_ultimate_scepter_2") if not existingBlessing then hero:AddItemByName("item_ultimate_scepter_2") print("[AdminMenu] Aghanim's Blessing добавлен " .. unit:GetUnitName()) else print(("[AdminMenu] У " .. unit:GetUnitName()) .. " уже есть Aghanim's Blessing") end end end end function AdminMenuManager.prototype.handleToggleShard(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then print("[AdminMenu] Нет выбранных сущностей для добавления Shard. Выделите существо или используйте кнопки +СОЮЗНИК/+ВРАГ/+МИШЕНЬ") return end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit if not HasShard(nil, hero) then local existingShard = hero:FindItemInInventory("item_aghanims_shard") if not existingShard then hero:AddItemByName("item_aghanims_shard") print("[AdminMenu] Aghanim's Shard добавлен " .. unit:GetUnitName()) else print(("[AdminMenu] У " .. unit:GetUnitName()) .. " уже есть Aghanim's Shard") end else print(("[AdminMenu] У " .. unit:GetUnitName()) .. " уже есть Shard") end end end end function AdminMenuManager.prototype.handleChangeSide(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then print("[AdminMenu] Нет выбранных сущностей для смены стороны. Выделите существо или используйте кнопки +СОЮЗНИК/+ВРАГ/+МИШЕНЬ") return end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) then local currentTeam = unit:GetTeamNumber() local ____temp_2 if currentTeam == DOTA_TEAM_GOODGUYS then ____temp_2 = DOTA_TEAM_BADGUYS else ____temp_2 = DOTA_TEAM_GOODGUYS end local newTeam = ____temp_2 unit:SetTeam(newTeam) print((((("[AdminMenu] Команда " .. unit:GetUnitName()) .. " изменена: ") .. tostring(currentTeam)) .. " -> ") .. tostring(newTeam)) end end end function AdminMenuManager.prototype.handleResetHero(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local heroName = event.heroName or "npc_dota_hero_crystal_maiden" local team = event.team or DOTA_TEAM_GOODGUYS local player = PlayerResource:GetPlayer(playerId) if not player then print(("[AdminMenu] Игрок " .. tostring(playerId)) .. " не найден") return end local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if not currentHero or not IsValidEntity(currentHero) then print(("[AdminMenu] У игрока " .. tostring(playerId)) .. " нет героя для замены") return end local spawnPos = currentHero:GetAbsOrigin() local currentTeam = currentHero:GetTeam() local finalTeam = team or currentTeam local entityIndex = currentHero:GetEntityIndex() self.selectedEntities:delete(entityIndex) print((((("[AdminMenu] Начинаем замену героя для игрока " .. tostring(playerId)) .. ": ") .. currentHero:GetUnitName()) .. " -> ") .. heroName) PrecacheUnitByNameAsync( heroName, function() local addon = GameRules.Addon if addon ~= nil then addon:resetWorldLightFixSpawnForPlayer(playerId) end local newHero = CreateUnitByName( heroName, spawnPos, false, player, player, finalTeam ) if not newHero or not IsValidEntity(newHero) then print("[AdminMenu] Ошибка: не удалось создать нового героя " .. heroName) return end print((("[AdminMenu] Новый герой " .. heroName) .. " создан, EntityIndex: ") .. tostring(newHero:GetEntityIndex())) FindClearSpaceForUnit(newHero, spawnPos, true) newHero:SetControllableByPlayer(playerId, true) newHero:SetOwner(player) if newHero:IsRealHero() then while newHero:GetLevel() > 1 do newHero:HeroLevelUp(false) end newHero:SetAbilityPoints(1) end player:SetAssignedHeroEntity(newHero) self.selectedEntities:set( newHero:GetEntityIndex(), newHero ) print((("[AdminMenu] Новый герой " .. heroName) .. " назначен игроку ") .. tostring(playerId)) Timers:CreateTimer( 0.1, function() if currentHero and IsValidEntity(currentHero) then currentHero:RemoveSelf() print(("[AdminMenu] Старый герой " .. currentHero:GetUnitName()) .. " удален") end end ) print((("[AdminMenu] Герой игрока " .. tostring(playerId)) .. " успешно заменен на ") .. heroName) end ) end function AdminMenuManager.prototype.handleDeleteHero(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end for ____, entityIndex in ipairs(entityIndices) do do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if not unit or not IsValidEntity(unit) then goto __continue231 end local isAssignedHero = false if unit:IsRealHero() then local hero = unit do local i = 0 while i < DOTA_MAX_TEAM_PLAYERS do if PlayerResource:IsValidPlayerID(i) then local player = PlayerResource:GetPlayer(i) if player then local assignedHero = player:GetAssignedHero() if assignedHero and assignedHero == hero then isAssignedHero = true print((("[AdminMenu] Нельзя удалить основного героя игрока " .. tostring(i)) .. ": ") .. hero:GetUnitName()) break end end end i = i + 1 end end end if not isAssignedHero then self.selectedEntities:delete(entityIndex) unit:RemoveSelf() print("[AdminMenu] Удален " .. unit:GetUnitName()) end end ::__continue231:: end end function AdminMenuManager.prototype.handleDeleteEntity(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе для удаления существ") return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices <= 1 and self.selectedEntities.size > 0 then local serverEntities = __TS__ArrayFrom(self.selectedEntities:keys()) if #serverEntities > #entityIndices then entityIndices = serverEntities print(((("[AdminMenu] Используем " .. tostring(#entityIndices)) .. " существ из selectedEntities на сервере (было передано ") .. tostring(#entityIndices == #serverEntities and 0 or 1)) .. ")") end end if #entityIndices == 0 then print("[AdminMenu] Нет выбранных существ для удаления. Выделите существо или используйте кнопки +СОЮЗНИК/+ВРАГ/+МИШЕНЬ") return end print( ("[AdminMenu] Начало удаления группы из " .. tostring(#entityIndices)) .. " существ. EntityIndices:", entityIndices ) local deletedCount = 0 local skippedCount = 0 for ____, entityIndex in ipairs(entityIndices) do do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if not unit or not IsValidEntity(unit) then skippedCount = skippedCount + 1 goto __continue250 end local unitPlayerId = unit:GetPlayerOwnerID() local hasPlayerId = unitPlayerId ~= -1 and PlayerResource:IsValidPlayerID(unitPlayerId) if not hasPlayerId then local isAssignedHero = false if unit:IsRealHero() then local hero = unit do local i = 0 while i < DOTA_MAX_TEAM_PLAYERS do if PlayerResource:IsValidPlayerID(i) then local player = PlayerResource:GetPlayer(i) if player then local assignedHero = player:GetAssignedHero() if assignedHero and assignedHero == hero then isAssignedHero = true print((("[AdminMenu] Нельзя удалить основного героя игрока " .. tostring(i)) .. ": ") .. hero:GetUnitName()) skippedCount = skippedCount + 1 break end end end i = i + 1 end end end if not isAssignedHero then self.selectedEntities:delete(entityIndex) unit:RemoveSelf() deletedCount = deletedCount + 1 print(((("[AdminMenu] Удалено существо без playerId: " .. unit:GetUnitName()) .. " (EntityIndex: ") .. tostring(entityIndex)) .. ")") end else skippedCount = skippedCount + 1 print((("[AdminMenu] Пропущено существо с playerId " .. tostring(unitPlayerId)) .. ": ") .. unit:GetUnitName()) end end ::__continue250:: end print(((((("[AdminMenu] Удаление группы завершено: удалено " .. tostring(deletedCount)) .. ", пропущено ") .. tostring(skippedCount)) .. " из ") .. tostring(#entityIndices)) .. " существ") end function AdminMenuManager.prototype.handleChangeHero(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local heroName = event.heroName or "npc_dota_hero_crystal_maiden" local team = event.team or DOTA_TEAM_GOODGUYS local player = PlayerResource:GetPlayer(playerId) if not player then print(("[AdminMenu] Игрок " .. tostring(playerId)) .. " не найден") return end local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if not currentHero or not IsValidEntity(currentHero) then print(("[AdminMenu] У игрока " .. tostring(playerId)) .. " нет героя для замены") return end local spawnPos = currentHero:GetAbsOrigin() local currentTeam = currentHero:GetTeam() local finalTeam = team or currentTeam local entityIndex = currentHero:GetEntityIndex() self.selectedEntities:delete(entityIndex) print((((("[AdminMenu] Начинаем замену героя для игрока " .. tostring(playerId)) .. ": ") .. currentHero:GetUnitName()) .. " -> ") .. heroName) PrecacheUnitByNameAsync( heroName, function() local addon = GameRules.Addon if addon ~= nil then addon:resetWorldLightFixSpawnForPlayer(playerId) end local newHero = CreateUnitByName( heroName, spawnPos, false, player, player, finalTeam ) if not newHero or not IsValidEntity(newHero) then print("[AdminMenu] Ошибка: не удалось создать нового героя " .. heroName) return end print((("[AdminMenu] Новый герой " .. heroName) .. " создан, EntityIndex: ") .. tostring(newHero:GetEntityIndex())) FindClearSpaceForUnit(newHero, spawnPos, true) newHero:SetControllableByPlayer(playerId, true) newHero:SetOwner(player) if newHero:IsRealHero() then while newHero:GetLevel() > 1 do newHero:HeroLevelUp(false) end newHero:SetAbilityPoints(1) end player:SetAssignedHeroEntity(newHero) self.selectedEntities:set( newHero:GetEntityIndex(), newHero ) print((("[AdminMenu] Новый герой " .. heroName) .. " назначен игроку ") .. tostring(playerId)) Timers:CreateTimer( 0.1, function() if currentHero and IsValidEntity(currentHero) then currentHero:RemoveSelf() print(("[AdminMenu] Старый герой " .. currentHero:GetUnitName()) .. " удален") end end ) print((("[AdminMenu] Герой игрока " .. tostring(playerId)) .. " успешно заменен на ") .. heroName) end ) end function AdminMenuManager.prototype.handleToggleSetting(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local setting = event.setting or "" local value = event.value or false repeat local ____switch276 = setting do print("[AdminMenu] Неизвестная настройка: " .. setting) break end until true end function AdminMenuManager.prototype.handleRefreshSpells(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) then do local i = 0 while i < unit:GetAbilityCount() do local ability = unit:GetAbilityByIndex(i) if ability and IsValidEntity(ability) then ability:EndCooldown() end i = i + 1 end end if unit:IsRealHero() then local hero = unit hero:SetMana(hero:GetMaxMana()) end print("[AdminMenu] Заклинания обновлены и мана восстановлена для " .. unit:GetUnitName()) end end end function AdminMenuManager.prototype.handleRefreshHealth(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) then unit:SetHealth(unit:GetMaxHealth()) print("[AdminMenu] Здоровье восстановлено для " .. unit:GetUnitName()) end end end function AdminMenuManager.prototype.handlePauseGame(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local isPaused = GameRules:IsGamePaused() if isPaused then SendToServerConsole("dota_pause") print("[AdminMenu] Игра возобновлена") else SendToServerConsole("dota_pause") print("[AdminMenu] Игра приостановлена") end end function AdminMenuManager.prototype.handleExitGame(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end print("[AdminMenu] Выход из игры") end function AdminMenuManager.prototype.handleScriptReload(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к script_reload") return end SendToServerConsole("script_reload") print("[AdminMenu] script_reload выполнен по запросу игрока " .. tostring(playerId)) end function AdminMenuManager.prototype.handleSpawnZoneCreate(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к созданию зоны спавна") return end local hero = PlayerResource:GetSelectedHeroEntity(playerId) if not hero or not IsValidEntity(hero) then print("[AdminMenu] Не найден валидный герой для создания зоны спавна") return end local center = hero:GetAbsOrigin() local shape = event.shape == "square" and "square" or "circle" local radius = event.radius and event.radius > 0 and event.radius or 600 local width = event.width and event.width > 0 and event.width or radius local height = event.height and event.height > 0 and event.height or radius local units = {} if event.units then local rawUnits = __TS__ArrayIsArray(event.units) and event.units or __TS__ObjectValues(event.units) for ____, u in ipairs(rawUnits) do if u and u.unitName ~= nil then local count = u.count and u.count > 0 and u.count or 1 units[#units + 1] = {unitName = u.unitName, count = count} end end end if #units == 0 then units[#units + 1] = {unitName = "npc_pig", count = 1} end local behaviorRaw = event.behavior local behavior = "aggressive" if behaviorRaw == "friendly" or behaviorRaw == "aggressive" or behaviorRaw == "neutral" then behavior = behaviorRaw end local spawnAtPointRaw = event.spawnAtPointHeight local spawnAtPointHeight = spawnAtPointRaw == true or spawnAtPointRaw == 1 local config = { units = units, position = center, radius = radius, interval = 10, team = DOTA_TEAM_NEUTRALS, behavior = behavior, shape = shape } if spawnAtPointHeight then config.spawnAtPointHeight = true end if shape == "square" then config.width = width config.height = height end local ____self_7, ____spawnZoneCounter_8 = self, "spawnZoneCounter" local ____self_spawnZoneCounter_9 = ____self_7[____spawnZoneCounter_8] ____self_7[____spawnZoneCounter_8] = ____self_spawnZoneCounter_9 + 1 local zoneId = "zone_admin_" .. tostring(____self_spawnZoneCounter_9) SpawnManager:getInstance():CreateZoneFromAdmin(zoneId, config) print((((((((((("[AdminMenu] Создана зона спавна '" .. zoneId) .. "' shape=") .. shape) .. ", radius=") .. tostring(radius)) .. ", width=") .. tostring(width)) .. ", height=") .. tostring(height)) .. ", units=") .. table.concat( __TS__ArrayMap( units, function(____, u) return (u.unitName .. "x") .. tostring(u.count) end ), ", " )) end function AdminMenuManager.prototype.handleSpawnZoneDeleteHere(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к удалению зоны спавна") return end local hero = PlayerResource:GetSelectedHeroEntity(playerId) if not hero or not IsValidEntity(hero) then print("[AdminMenu] Не найден валидный герой для удаления зоны спавна") return end local pos = hero:GetAbsOrigin() local removedId = SpawnManager:getInstance():RemoveZoneAtPosition(pos) if removedId then print((("[AdminMenu] Зона спавна '" .. removedId) .. "' удалена под героем игрока ") .. tostring(playerId)) else print("[AdminMenu] Зона спавна под героем не найдена") end end function AdminMenuManager.prototype.getAllHeroes(self) local heroes = {} do local i = 0 while i < DOTA_MAX_TEAM_PLAYERS do if PlayerResource:IsValidPlayerID(i) then local hero = PlayerResource:GetSelectedHeroEntity(i) if hero and IsValidEntity(hero) then heroes[#heroes + 1] = hero end end i = i + 1 end end return heroes end function AdminMenuManager.prototype.handleGiveGold(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local amount = event.amount or 1000 local goldAmount = math.min( 99999, math.max( 0, math.floor(amount) ) ) local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit local ownerPlayerId = hero:GetPlayerOwnerID() if ownerPlayerId >= 0 and PlayerResource:IsValidPlayerID(ownerPlayerId) then PlayerResource:ModifyGold(ownerPlayerId, goldAmount, false, DOTA_ModifyGold_Unspecified) print(((((("[AdminMenu] Выдано " .. tostring(goldAmount)) .. " золота игроку ") .. tostring(ownerPlayerId)) .. " (") .. hero:GetUnitName()) .. ")") end end end end function AdminMenuManager.prototype.handleChangeLuck(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local amount = event.amount or 0 local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit addLuck(nil, hero, amount) print((("[AdminMenu] Добавлено " .. tostring(amount)) .. " удачи герою ") .. hero:GetUnitName()) end end end function AdminMenuManager.prototype.handleChangePhysicalVampirism(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local amount = event.amount or 0 local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit addPhysicalVampirism(nil, hero, amount) print((("[AdminMenu] Добавлено " .. tostring(amount)) .. " физического вампиризма герою ") .. hero:GetUnitName()) end end end function AdminMenuManager.prototype.handleChangeMagicalVampirism(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local amount = event.amount or 0 local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit addMagicalVampirism(nil, hero, amount) print((("[AdminMenu] Добавлено " .. tostring(amount)) .. " магического вампиризма герою ") .. hero:GetUnitName()) end end end function AdminMenuManager.prototype.handleGiveCrystals(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local amount = event.amount or 1000 local crystalAmount = math.min( 999999, math.max( 0, math.floor(amount) ) ) local entityIndices = {} if event.entityIndices then if __TS__ArrayIsArray(event.entityIndices) then entityIndices = event.entityIndices else entityIndices = __TS__ObjectValues(event.entityIndices) end end if #entityIndices == 0 then local player = PlayerResource:GetPlayer(playerId) if player then local currentHero = player:GetAssignedHero() or PlayerResource:GetSelectedHeroEntity(playerId) if currentHero and IsValidEntity(currentHero) then entityIndices = {currentHero:GetEntityIndex()} end end end for ____, entityIndex in ipairs(entityIndices) do local unit = self.selectedEntities:get(entityIndex) if not unit or not IsValidEntity(unit) then unit = EntIndexToHScript(entityIndex) end if unit and IsValidEntity(unit) and unit:IsRealHero() then local hero = unit local ownerPlayerId = hero:GetPlayerOwnerID() if ownerPlayerId >= 0 and PlayerResource:IsValidPlayerID(ownerPlayerId) then local crystalCurrency = CrystalCurrency:getInstance() crystalCurrency:addCrystals(ownerPlayerId, crystalAmount) print(((((("[AdminMenu] Выдано " .. tostring(crystalAmount)) .. " кристаллов игроку ") .. tostring(ownerPlayerId)) .. " (") .. hero:GetUnitName()) .. ")") end end end end function AdminMenuManager.prototype.handleSetNextWave(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к управлению волнами") return end local waveManager = WaveManager:getInstance() local dayNightManager = DayNightCycleManager:getInstance() local rawNight = event.night local rawWave = event.wave if rawNight == nil and rawWave == nil then print("[AdminMenu] admin_set_next_wave: не переданы night / wave") return end if rawWave ~= nil then local targetWave = math.max( 1, math.floor(rawWave) ) waveManager:SetNextWaveIndex(targetWave) end local currentNight = waveManager:GetCurrentNight() local currentWave = waveManager:GetCurrentWave() + 1 if rawNight ~= nil then local targetNight = math.max( 1, math.floor(rawNight) ) print(((("[AdminMenu] Запрошена ночь " .. tostring(targetNight)) .. " через админ-меню (фактическая текущая ночь сейчас ") .. tostring(currentNight)) .. ", управление ночью оставлено циклу дня/ночи)") end dayNightManager:ForceNightIn(3) print(((("[AdminMenu] Установлена следующая волна через админ-меню: текущая ночь=" .. tostring(currentNight)) .. ", следующая волна=") .. tostring(currentWave)) .. ", ночь начнётся через 3 секунды (если сейчас день)") end function AdminMenuManager.prototype.handleForceMorning(self, playerId) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к 'сделать утро'") return end local dayNightManager = DayNightCycleManager:getInstance() dayNightManager:ForceDay() print("[AdminMenu] Утро принудительно установлено через админ-меню") end function AdminMenuManager.prototype.handleAdjustDayNightTimer(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к изменению таймера дня/ночи") return end local rawDelta = event.delta if rawDelta == nil or rawDelta == 0 then return end local delta = math.floor(rawDelta) local dayNightManager = DayNightCycleManager:getInstance() dayNightManager:AdjustTimeLeft(delta) print(((((("[AdminMenu] Таймер дня/ночи изменён на " .. tostring(delta)) .. " сек, новое значение: ") .. tostring(dayNightManager:GetTimeLeft())) .. " (isDay=") .. tostring(dayNightManager:IsDaytime())) .. ")") end function AdminMenuManager.prototype.handleSetDayNightTimer(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе к установке таймера дня/ночи") return end local rawSeconds = event.seconds if rawSeconds == nil then return end local seconds = math.floor(rawSeconds) local dayNightManager = DayNightCycleManager:getInstance() dayNightManager:SetTimeLeft(seconds) print(((((("[AdminMenu] Таймер дня/ночи установлен в " .. tostring(seconds)) .. " сек, текущее значение: ") .. tostring(dayNightManager:GetTimeLeft())) .. " (isDay=") .. tostring(dayNightManager:IsDaytime())) .. ")") end function AdminMenuManager.prototype.handleRequestSteamId(self, playerId) if not IsServer() then return end local player = PlayerResource:GetPlayer(playerId) if not player then print("[AdminMenu] Не удалось получить контроллер игрока " .. tostring(playerId)) return end local steamId = tostring(PlayerResource:GetSteamAccountID(playerId)) CustomGameEventManager:Send_ServerToPlayer(player, "admin_menu_steam_id", {steamId = steamId}) print((("[AdminMenu] Отправлен Steam ID " .. steamId) .. " игроку ") .. tostring(playerId)) end function AdminMenuManager.prototype.handleCheckCheatMode(self, playerId) if not IsServer() then return end local player = PlayerResource:GetPlayer(playerId) if not player then return end local isCheatMode = GameRules:IsCheatMode() or Convars:GetBool("sv_cheats") CustomGameEventManager:Send_ServerToPlayer(player, "admin_menu_cheat_mode", {isCheatMode = isCheatMode}) end function AdminMenuManager.prototype.handleShowCardSelection(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then print("[AdminMenu] Отказано в доступе для показа выбора карт") return end local targetPlayerId = playerId if event.entityIndices then local entityArray = {} if __TS__ArrayIsArray(event.entityIndices) then entityArray = event.entityIndices else entityArray = __TS__ObjectValues(event.entityIndices) end if #entityArray > 0 then local firstEntityIndex = entityArray[1] local firstEntity = EntIndexToHScript(firstEntityIndex) if firstEntity and IsValidEntity(firstEntity) and firstEntity:IsRealHero() then targetPlayerId = firstEntity:GetPlayerOwnerID() end end else local hero = PlayerResource:GetSelectedHeroEntity(playerId) if hero and IsValidEntity(hero) and hero:IsRealHero() then targetPlayerId = hero:GetPlayerOwnerID() end end ShowCardSelectionToPlayer(nil, targetPlayerId, 3, "admin_menu") print("[AdminMenu] Показан выбор карт для игрока " .. tostring(targetPlayerId)) end function AdminMenuManager.prototype.handleSetTimeScale(self, playerId, event) if not IsServer() then return end if not self:checkAdminAccess(playerId) then return end local timescale = event.timescale or 1 local clampedTimescale = math.min( 10, math.max(0, timescale) ) Convars:SetFloat("host_timescale", clampedTimescale) print("[AdminMenu] Скорость времени установлена: " .. tostring(clampedTimescale)) end AdminMenuManager.instance = nil AdminMenuManager = __TS__Decorate(AdminMenuManager, AdminMenuManager, {reloadable}, {kind = "class", name = "AdminMenuManager"}) ____exports.AdminMenuManager = AdminMenuManager return ____exports