"Говорилка" для автодоната. Главная тема

Собрал в этой теме все самое важное с этих, чтобы все было в одном месте:

:warning: Эта тема является WIKI темой и ее может редактировать каждый. Если у вас есть какие-то предложения или правки - можете вносить прямо в это сообщение


Вариант 1 - от @Riky

Когда игрок с купленным предметом “govorilka” пишет что-то в чат, это воспроизводится у всех. Работает только на DarkRP из-за хука PostPlayerSay

Сам скрипт установить сюда:

addons/igs-modification/lua/autorun/sh_govorilka.lua

if SERVER then
	util.AddNetworkString("SayTTS")

	hook.Add("PostPlayerSay", "TTSFTW", function(ply, text, team, dead)
		if ply:HasPurchase("govorilka") and not dead then
			net.Start("SayTTS")
				net.WriteString(text)
				net.WriteEntity(ply)
			net.Broadcast()
		end
	end)
else
	local char_to_hex = function(c) return string.format("%%%02X", string.byte(c)) end
	local function urlencode(url)
		return url:gsub("\n", "\r\n")
			:gsub("([^%w ])", char_to_hex)
			:gsub(" ", "+")
	end

	net.Receive("SayTTS", function()
		local text = net.ReadString()
		local ply  = net.ReadEntity()
		if LocalPlayer():GetPos():Distance(ply:GetPos()) > 1000 then return end

		sound.PlayURL("https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=" .. urlencode(text) .. "&tl=ru", "3d", function(snd)
			if IsValid(snd) and IsValid(ply) then
				snd:SetPos(ply:GetPos())
				snd:SetVolume(1)
				snd:Play()
				snd:Set3DFadeDistance(200, 1000)
				ply.tts_snd = snd
			end
		end)
	end)

	hook.Add("Think", "FollowPlayerSound", function()
		for _, ply in pairs(player.GetAll()) do
			if IsValid(ply.tts_snd) then
				ply.tts_snd:SetPos( ply:GetPos() )
			end
		end
	end)
end

В IGS создать предмет govorilka:

addons\igs-modification\lua\igs\settings\sh_additems.lua

IGS("Говорилка", "govorilka")
	:SetPrice(400)
	:SetTerm(30)

Вариант 2 от меня без гарантий

Для тех, кто “на опыте” предоставляю как есть свою “говорилку”, которую в свое время писал для своего проекта

tts.zip (2.2 КБ)

Если вариант сверху не работает, а он конечно и не будет работать, если его не подогнать под ваш проект, то есть еще такой вариант от @Helix_Drew: tts.zip (2.0 КБ), но за работоспособность тоже не отвечаю

Инструкции по установке не даю, как и не оказываю поддержку по ней, так как она требует некоторых зависимостей

Если кто-то портирует этот модуль, чтобы он работал на любом проекте, то сразу получит медаль “Моддер” и попадет в группу LEADERS

P.S. Продавал вот так:

IGS("Синтез речи","tts", 1499):SetDiscountedFrom(2000)
	:SetPerma()
	:SetCategory(IGS_CAT_FUN)
	:SetDescription(
		"С этой херней все ваши сообщения будут воспроизведены компьютером, словно в терминаторе!" ..
		"\n\nДорого? Да нихуя! Я мог бы сделать эту хрень дешевле, но тогда бы ваши уши начали кровоточить от обилия войс месседжей на сервере." ..
		"\n\nПосле покупки напишите нам в ВК и мы расскажем одну интересную байду"
	)
	:SetIcon("http://i.imgur.com/mUWW0U1.png")

Может пригодиться

function string:URLEncode()
	return string.gsub(string.gsub(self, '\n', '\r\n'), '([^%w.])', function(c)
		return string.format('%%%02X', string.byte(c))
	end)
end

Вариант 3, не помню откуда, но вроде работает

googlespeech.zip (9.1 КБ) Закинуть в addons

В sh_additems.lua добавить вот такое:

IGS("Говорилка на 30 дней", "govorilka")
	:SetPrice(100)
	:SetTerm(30)
	:SetDescription("Если хочешь чтобы твой текст озвучивался, то эта штука для тебя")
	:SetNetworked(true)

Бонус. Yandex вместо Google

Гугл ссылки подменить на подобную:

https://tts.voicetech.yandex.net/tts?speaker=alyss&text=Привет-мир

А куда закидывать файлы из 3-го способа?

addons…

моя версия

Связанная тема:

Без зависимостей, с “активной” позицией звука.
Без привязки доната.

if SERVER then
    function Encode(str)
        return (str:gsub("[^%w _~%.%-]", function(char) return string.format("%%%02X", char:byte()) end):gsub(" ", "+"))
    end
    util.AddNetworkString('PlaySendChatTextVoice')
    hook.Add("PlayerSay", "PlaySendChatTextVoice", function(pl, txt)
        txt = string.Trim(txt)
        if not IsValid(pl) or txt:len() == 0 then return end-- проверка от пустого пробела
        net.Start('PlaySendChatTextVoice')
        net.WriteString(Encode(txt))
        net.WriteEntity(pl)
        net.Broadcast()
    end)
else
    net.Receive('PlaySendChatTextVoice', function()
        local str = net.ReadString()
        local owner = net.ReadEntity()
        if not IsValid(owner) then return end

        sound.PlayURL(string.format("https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=%s&tl=ru",str), "3d", function(chan)
            if not IsValid(chan) then return end
            chan:SetPos(owner:GetPos())
            chan:Play()
            chan:Set3DFadeDistance(200, 896)
            local T = CurTime()

            hook.Add("Think", "ChatVoiceOnline" .. T, function()
                if chan:GetState() == 0 then
                    hook.Remove("Think", "ChatVoiceOnline" .. T)
                end

                chan:SetPos(owner:GetPos())
            end)
        end)
    end)
end
1 лайк

Как менять голоса через гугл?

1 способ походу уже походу умер

Что именно не работает? Я перешел по ссылке и звук воспроизводится

https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=блаблабла&tl=ru

метод должен работать значит

Теперь работает очень странно. Вчера ночью возникла ошибка, что-то вроде: ‘sound.PlayURL’. Она не распознавала аргумент ‘PlayURL’

пример реквеста yandex cloud tts:
https://tts.voicetech.yandex.net/tts?speaker=alyss&text=Привет-мир

Скрипт на озвучку текста в чате для GM-DONATE

Мой старый скрипт на озвучку думаю будет полезен многим серверам.

Скрипт вставлять в путь: addons/igs-modification/lua/igs/extensions/govorilka.lua

Скрипт:


local STORE_ITEM = FindMetaTable("IGSItem")

function STORE_ITEM:SetSoundURL(url)
    return self:SetMeta("sound_url", url)
end

function STORE_ITEM:SetTTSPattern(pattern)
    return self:SetMeta("tts_pattern", pattern)
end

function STORE_ITEM:IsScriptPurchased(ply)

    return ply:HasPurchase("ozvuchkateksta")
end

local function SpeakText(text, voice, sender)
    http.Fetch("https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=" .. voice .. "&q=" .. text,
        function(body, size, headers, code)
            if code == 200 then

                if SERVER then
                    net.Start("IGS.PLAYSOUND")
                    net.WriteEntity(sender)
                    net.WriteString(body)
                    net.Broadcast()
                end
            else

            end
        end,
        function(error)

        end
    )
end

local function OpenVoiceMenu(ply)
    if ply:HasPurchase("ozvuchkateksta") or (ply:IsUserGroup("vip") or ply:IsUserGroup("premium") or ply:IsUserGroup("moderator") or ply:IsUserGroup("admin")) then
        local menu = DermaMenu()

        menu:AddOption("Озвучка женским голосом", function()
            ply:SetNWString("voice", "женский")
            ply:ChatPrint("Вы выбрали озвучку женским голосом.")
        end):SetImage("icon16/user_female.png")

        menu:AddOption("Озвучка мужским голосом", function()
            ply:SetNWString("voice", "мужской")
            ply:ChatPrint("Вы выбрали озвучку мужским голосом.")
        end):SetImage("icon16/user.png")

        menu:AddSpacer()

        local speechEnabled = ply:GetNWBool("speechEnabled", false)

        if speechEnabled then
            menu:AddOption("Выключить озвучивание текста", function()
                ply:SetNWBool("speechEnabled", false)
                ply:ChatPrint("Вы выключили озвучку текста в чате.")
            end):SetImage("icon16/sound_mute.png")
        else
            menu:AddOption("Включить озвучивание текста", function()
                ply:SetNWBool("speechEnabled", true)
                ply:ChatPrint("Вы включили озвучку текста в чате.")
            end):SetImage("icon16/sound.png")
        end

        local textLabel = vgui.Create("DLabel")
        textLabel:SetText("Озвучка текста сделана для сервера ViperRolePlay (2022) от Faulin'a")
        textLabel:SetContentAlignment(5)
        textLabel:SetTextColor(Color(255, 255, 255))
        textLabel:SetFont("DermaDefault")
        textLabel:SizeToContents()
        menu:AddPanel(textLabel)


        menu:AddOption("Закрыть", function() end):SetImage("icon16/cross.png")


        menu:SetSize(200, 320)
        menu:Center()
        menu:MakePopup()
        menu:DoModal()
    else
        ply:ChatPrint("Доступ к озвучке текста необходимо приобрести в донат магазине.")
    end
end

if SERVER then
    util.AddNetworkString("IGS.PLAYSOUND")

    local function phraseToTTSUrl(phrase)
        local GOOGLE = "https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=%s&tl=ru"
        return GOOGLE:format(phrase:URLEncode())
    end

    hook.Add("IGS.PlayerPurchasedItem", "IGS.PLAYSOUND", function(pl, ITEM)
        if not ITEM:IsScriptPurchased(pl) then
            return
        end

        local url

        local tts_pattern = ITEM:GetMeta("tts_pattern")
        if tts_pattern then
            local txt = tts_pattern:gsub("{nick}", pl:Nick())
            url = phraseToTTSUrl(txt)
        else
            url = ITEM:GetMeta("sound_url")
        end

        if url then
            net.Start("IGS.PLAYSOUND")
            net.WriteEntity(pl)
            net.WriteString(url)
            net.Broadcast()
        end
    end)

else
    local function PlayURL(url, sender)
        if sender:GetPos():Distance(LocalPlayer():GetPos()) <= 400 then
            sound.PlayURL(url, "3d", function(chan)
                if chan and chan:IsValid() then
                    chan:Play()
                end
            end)
        end
    end

    net.Receive("IGS.PLAYSOUND", function()
        local sender = net.ReadEntity()
        local url = net.ReadString()
        PlayURL(url, sender)
    end)

    hook.Add("PlayerSay", "TextToSpeechCommand", function(ply, text)
        local command = string.lower(text)
        if command == "/ozvuchka" then

            if ply:HasPurchase("ozvuchkateksta") and (ply:IsUserGroup("vip") or ply:IsUserGroup("premium") or ply:IsUserGroup("moderator") or ply:IsUserGroup("admin")) then
                OpenVoiceMenu(ply)
            else
                ply:ChatPrint("Доступ к озвучке текста необходимо приобрести в донат магазине.")
            end
        end
    end)

    hook.Add("PlayerSay", "TextToSpeech", function(ply, text)
        local speechEnabled = ply:GetNWBool("speechEnabled", false)

        if speechEnabled then
            local voice = ply:GetNWString("voice", "женский")

            SpeakText(text, voice, ply)
        end
    end)
end

Услуга в sh_additems.lua

IGS("Говорилка на 1 месяц", "ozvuchkateksta")
    :SetPrice(200)
    :SetTerm(30)
    :SetDescription("Ваш текст будет озвучиваться")
    :SetCategory("Дополнительное")