mirror of
https://github.com/sr229/metastruct-experiments.git
synced 2024-09-20 06:30:36 +00:00
e7503545df
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
154 lines
No EOL
5.3 KiB
Lua
154 lines
No EOL
5.3 KiB
Lua
--@name Starfall-TTS (Shared)
|
|
--@author Minori, Henke, Empy, et al.
|
|
--@include https://raw.githubusercontent.com/sr229/metastruct-experiments/master/starfallex/google_tts/libraries/hasvalue.lua as hasvalue.txt
|
|
--@include https://raw.githubusercontent.com/sr229/metastruct-experiments/master/starfallex/google_tts/libraries/urlencode.lua as urlencode.txt
|
|
--@shared
|
|
|
|
-- constants
|
|
local DEFAULT_LANGUAGE = "en-gb"
|
|
local DEBUG = true
|
|
local REMOTE_INDEX = "https://raw.githubusercontent.com/sr229/metastruct-experiments/master/starfall_metadata/allowed_google_voices.json"
|
|
local BASS_REFERENCES = {}
|
|
|
|
-- top level requires
|
|
require("urlencode.txt")
|
|
require("hasvalue.txt")
|
|
|
|
|
|
if SERVER then
|
|
-- Userdata will collect the Player ID and the language.
|
|
-- Layout may look something like this:
|
|
-- userdata = {
|
|
-- [1] = "en-gb"
|
|
-- }
|
|
local userdata = {}
|
|
-- This is the server's copy of the remote index.
|
|
local srvidx = {}
|
|
-- if you just want to hide it from the idiots around you
|
|
-- chip():setOwner(true)
|
|
local function getRemoteLanguageIndex()
|
|
print("SERVER: Building language index. Please be patient...")
|
|
|
|
http.get(REMOTE_INDEX, function(body, len)
|
|
if len > 0 then
|
|
local rawData = json.decode(body)
|
|
|
|
if rawData then
|
|
for i, v in pairs(rawData.voices) do
|
|
table.insert(srvidx, i, v)
|
|
end
|
|
else
|
|
error("Could not decode JSON")
|
|
end
|
|
end
|
|
|
|
if #srvidx > 0 then
|
|
print("SERVER: Serverside hook initialized.")
|
|
print(string.format("Available Languages: %s", table.concat(srvidx, ", ")))
|
|
end
|
|
end)
|
|
end
|
|
|
|
getRemoteLanguageIndex()
|
|
|
|
hook.add("PlayerSay", "msgHandler", function(ply, msg)
|
|
if ply and string.sub(msg, 1, 1) == ";" and userdata[ply:getUserID()] then
|
|
|
|
net.start("broadcast_tts")
|
|
net.writeInt(ply:getUserID(), 32)
|
|
net.writeString(userdata[ply:getUserID()])
|
|
net.writeString(tostring(string.sub(msg, 2)))
|
|
net.send()
|
|
elseif ply and string.sub(msg, 1, 1) == ";" then
|
|
-- initialize the user
|
|
table.insert(userdata, ply:getUserID(), DEFAULT_LANGUAGE)
|
|
|
|
net.start("broadcast_tts")
|
|
net.writeInt(ply:getUserID(), 32)
|
|
net.writeString(userdata[ply:getUserID()])
|
|
net.writeString(tostring(string.sub(msg, 2)))
|
|
net.send()
|
|
end
|
|
|
|
if ply and string.sub(msg, 1, 1) == ":" and userdata[ply:getUserID()] then
|
|
local preferredLang = tostring(string.sub(msg, 2))
|
|
|
|
if HasValue(srvidx, preferredLang) then
|
|
print(string.format("Swtiched to %s", preferredLang))
|
|
userdata[ply:getUserID()] = preferredLang
|
|
else
|
|
print("WARN: Invalid Language! No changes were made.")
|
|
end
|
|
elseif ply and string.sub(msg, 1, 1) == ":" then
|
|
local preferredLang = tostring(string.sub(msg, 2))
|
|
print("No preferences found for you. Initializing you with your preferred language.")
|
|
if HasValue(srvidx, preferredLang) then
|
|
table.insert(userdata, ply:getUserID(), preferredLang)
|
|
else
|
|
print("WARN: Your preferred language is not valid! Initializing you with the default one instead.")
|
|
table.insert(userdata, ply:getUserID(), DEFAULT_LANGUAGE)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
if CLIENT then
|
|
-- Check if client has permission
|
|
if not hasPermission("bass.loadURL", "https://translate.google.com/translate_tts") then
|
|
print("WARNING: Your starfall settings prevents this chip from working, please redo your settings.")
|
|
else
|
|
print("CLIENT: Clientside hook initialized.")
|
|
end
|
|
|
|
local function requestTTS(txt, lng, callback)
|
|
local url = string.format("https://translate.google.com/translate_tts?ie=UTF-8&q=%s&tl=%s&client=tw-ob", txt, lng)
|
|
bass.loadURL(url, "3d noblock", callback)
|
|
end
|
|
|
|
local function doTTS(ply, sound)
|
|
|
|
-- check for validity
|
|
if not sound then
|
|
error("Sound is invalid or nil!")
|
|
end
|
|
|
|
table.insert(BASS_REFERENCES, {
|
|
ref = sound,
|
|
timestamp = os.time()
|
|
})
|
|
|
|
hook.add("think", "soundFollow", function()
|
|
if sound:isValid() then
|
|
sound:setPos(ply:getPos())
|
|
else
|
|
hook.remove("think", "soundFollow")
|
|
end
|
|
end)
|
|
|
|
sound:setVolume(1.3)
|
|
sound:play()
|
|
end
|
|
|
|
local function gc()
|
|
table.sort(BASS_REFERENCES, function(a, b) return a.timestamp < b.timestamp end)
|
|
|
|
if #BASS_REFERENCES ~= 0 and #BASS_REFERENCES > 2 then
|
|
BASS_REFERENCES[1].ref:destroy()
|
|
table.remove(BASS_REFERENCES, 1)
|
|
end
|
|
end
|
|
|
|
net.receive("broadcast_tts", function()
|
|
local ply = player(net.readInt(32))
|
|
local lang = net.readString()
|
|
local msg = net.readString()
|
|
|
|
if DEBUG then print(string.format("DEBUG: Ply: %s, Lang: %s, Msg: %s", ply:getName(), lang, msg)) end
|
|
requestTTS(UrlEncode(msg), lang, function(s)
|
|
if s then
|
|
doTTS(ply, s)
|
|
gc()
|
|
end
|
|
end)
|
|
end)
|
|
end |