123 lines
4.3 KiB
Lua
123 lines
4.3 KiB
Lua
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
|