local PLUGIN = PLUGIN -- Таблица для отслеживания кулдаунов PLUGIN.voiceChatCooldowns = PLUGIN.voiceChatCooldowns or {} -- Функция для проверки доступа к TTS function PLUGIN:CanUseTTS(client) local character = client:GetCharacter() if not character then return false end return character:GetData("voice_chat_unlocked", false) end -- Функция для получения игроков в радиусе function PLUGIN:GetPlayersInRadius(origin, radius) local players = {} local radiusSqr = radius * radius for _, ply in ipairs(player.GetAll()) do if ply:GetPos():DistToSqr(origin) <= radiusSqr then table.insert(players, ply) end end return players end -- Функция для генерации TTS URL (Google Translate TTS) function PLUGIN:GenerateTTSURL(text) -- Кодируем текст для URL local encoded = text encoded = string.gsub(encoded, "([^%w%s%-%.%_%~])", function(c) return string.format("%%%02X", string.byte(c)) end) encoded = string.gsub(encoded, " ", "+") -- Google Translate TTS API (бесплатный, без ключа) -- lang=ru - русский язык return string.format("https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=ru&q=%s", encoded) end -- Команда чата для TTS function PLUGIN:OnPlayerChat(client, text, isTeam, isDead) local command = ix.config.Get("voiceChatCommand", "tts") local prefix = "!" .. command .. " " -- Проверяем, начинается ли сообщение с команды if not string.StartWith(text, prefix) then return end -- Проверяем доступ if not self:CanUseTTS(client) then client:Notify("У вас нет доступа к говорилке! Приобретите её в F4 меню.") return "" end -- Проверяем кулдаун local cooldownTime = ix.config.Get("voiceChatCooldown", 5) local lastUse = self.voiceChatCooldowns[client:SteamID()] or 0 if CurTime() - lastUse < cooldownTime then local remaining = math.ceil(cooldownTime - (CurTime() - lastUse)) client:Notify(string.format("Подождите %d секунд перед следующим использованием!", remaining)) return "" end -- Получаем текст сообщения local message = string.sub(text, #prefix + 1) message = string.Trim(message) -- Проверяем длину local maxLength = ix.config.Get("voiceChatMaxLength", 200) if #message == 0 then client:Notify("Введите текст после команды !" .. command) return "" end if #message > maxLength then client:Notify(string.format("Сообщение слишком длинное! Максимум %d символов.", maxLength)) return "" end -- Устанавливаем кулдаун self.voiceChatCooldowns[client:SteamID()] = CurTime() -- Генерируем URL для TTS local ttsURL = self:GenerateTTSURL(message) -- Получаем игроков в радиусе local radius = ix.config.Get("voiceChatRadius", 200) local nearbyPlayers = self:GetPlayersInRadius(client:GetPos(), radius) -- Отправляем TTS всем игрокам в радиусе local clientName = client:Name() for _, ply in ipairs(nearbyPlayers) do net.Start("ixVoiceChatPlay") net.WriteString(ttsURL) net.WriteString(clientName) net.WriteVector(client:GetPos()) net.Send(ply) end -- Показываем сообщение в чате local chatText = string.format("[TTS] %s: %s", clientName, message) for _, ply in ipairs(nearbyPlayers) do ply:ChatPrint(chatText) end -- Не показываем оригинальное сообщение return "" end -- Очистка кулдаунов при отключении игрока function PLUGIN:PlayerDisconnected(client) self.voiceChatCooldowns[client:SteamID()] = nil end -- Сетевой канал для отправки TTS клиентам if SERVER then util.AddNetworkString("ixVoiceChatPlay") end