Files
VnUtest/garrysmod/gamemodes/militaryrp/plugins/voice_chat/sv_plugin.lua
2026-03-31 10:27:04 +03:00

123 lines
4.3 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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