From e7503545dfe91d998646556ee47a5c3853aac0f8 Mon Sep 17 00:00:00 2001 From: Ayane Satomi Date: Fri, 16 Dec 2022 22:07:52 +0800 Subject: [PATCH] Include Google TTS v4 Signed-off-by: Ayane Satomi --- ....lua => add_state_change_listener_ctp.glua | 0 afk_hook.lua => afk_hook.glua | 0 ...audio.lua => custom_taunts_with_audio.glua | 0 ...tseeking.lua => disengage_heatseeking.glua | 0 ...ing_minori.lua => heat_seeking_minori.glua | 0 jsonparse_test.lua => jsonparse_test.glua | 0 lmao.lua => lmao.glua | 0 ...lua => remove_playerstepsoundtime_ctp.glua | 0 starfallex/google_tts/libraries/hasvalue.lua | 7 + starfallex/google_tts/libraries/urlencode.lua | 23 +++ starfallex/google_tts/tts.lua | 154 ++++++++++++++++++ verify_luadev.lua => verify_luadev.glua | 0 12 files changed, 184 insertions(+) rename add_state_change_listener_ctp.lua => add_state_change_listener_ctp.glua (100%) rename afk_hook.lua => afk_hook.glua (100%) rename custom_taunts_with_audio.lua => custom_taunts_with_audio.glua (100%) rename disengage_heatseeking.lua => disengage_heatseeking.glua (100%) rename heat_seeking_minori.lua => heat_seeking_minori.glua (100%) rename jsonparse_test.lua => jsonparse_test.glua (100%) rename lmao.lua => lmao.glua (100%) rename remove_playerstepsoundtime_ctp.lua => remove_playerstepsoundtime_ctp.glua (100%) create mode 100644 starfallex/google_tts/libraries/hasvalue.lua create mode 100644 starfallex/google_tts/libraries/urlencode.lua create mode 100644 starfallex/google_tts/tts.lua rename verify_luadev.lua => verify_luadev.glua (100%) diff --git a/add_state_change_listener_ctp.lua b/add_state_change_listener_ctp.glua similarity index 100% rename from add_state_change_listener_ctp.lua rename to add_state_change_listener_ctp.glua diff --git a/afk_hook.lua b/afk_hook.glua similarity index 100% rename from afk_hook.lua rename to afk_hook.glua diff --git a/custom_taunts_with_audio.lua b/custom_taunts_with_audio.glua similarity index 100% rename from custom_taunts_with_audio.lua rename to custom_taunts_with_audio.glua diff --git a/disengage_heatseeking.lua b/disengage_heatseeking.glua similarity index 100% rename from disengage_heatseeking.lua rename to disengage_heatseeking.glua diff --git a/heat_seeking_minori.lua b/heat_seeking_minori.glua similarity index 100% rename from heat_seeking_minori.lua rename to heat_seeking_minori.glua diff --git a/jsonparse_test.lua b/jsonparse_test.glua similarity index 100% rename from jsonparse_test.lua rename to jsonparse_test.glua diff --git a/lmao.lua b/lmao.glua similarity index 100% rename from lmao.lua rename to lmao.glua diff --git a/remove_playerstepsoundtime_ctp.lua b/remove_playerstepsoundtime_ctp.glua similarity index 100% rename from remove_playerstepsoundtime_ctp.lua rename to remove_playerstepsoundtime_ctp.glua diff --git a/starfallex/google_tts/libraries/hasvalue.lua b/starfallex/google_tts/libraries/hasvalue.lua new file mode 100644 index 0000000..c1482fa --- /dev/null +++ b/starfallex/google_tts/libraries/hasvalue.lua @@ -0,0 +1,7 @@ +function HasValue(tab, val) + for _, v in pairs(tab) do + if v == val then return true end + end + + return false +end \ No newline at end of file diff --git a/starfallex/google_tts/libraries/urlencode.lua b/starfallex/google_tts/libraries/urlencode.lua new file mode 100644 index 0000000..328cb09 --- /dev/null +++ b/starfallex/google_tts/libraries/urlencode.lua @@ -0,0 +1,23 @@ +Char2Hex = function(c) return string.format("%%%02X", string.byte(c)) end + +function UrlEncode(url) + if url == nil then return end + url = url:gsub("\n", "\r\n") + url = url:gsub("([^%w ])", Char2Hex) + url = url:gsub(" ", "+") + + return url +end + +Hex2Char = function(x) return string.char(tonumber(x, 16)) end + +UrlDecode = function(url) + if url == nil then return end + url = url:gsub("+", " ") + url = url:gsub("%%(%x%x)", Hex2Char) + + return url +end +-- ref: https://gist.github.com/ignisdesign/4323051 +-- ref: http://stackoverflow.com/questions/20282054/how-to-urldecode-a-request-uri-string-in-lua +-- to encode table as parameters, see https://github.com/stuartpb/tvtropes-lua/blob/master/urlencode.lua \ No newline at end of file diff --git a/starfallex/google_tts/tts.lua b/starfallex/google_tts/tts.lua new file mode 100644 index 0000000..048d61f --- /dev/null +++ b/starfallex/google_tts/tts.lua @@ -0,0 +1,154 @@ +--@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 \ No newline at end of file diff --git a/verify_luadev.lua b/verify_luadev.glua similarity index 100% rename from verify_luadev.lua rename to verify_luadev.glua