2024-08-19 04:17:05 +00:00
--@name DECTalk
--@author Minori
--@include https://gist.githubusercontent.com/sr229/5e6f3a5b03181704a871207c14706499/raw/2ee5b6cfb3a875a5ad2024a38d0131cfb5278785/url-encode.lua as henke.txt
--@shared
local DEBUG = true
local references = { }
require ( " henke.txt " )
if SERVER then
-- haaugh
--chip():setNoDraw(true)
hook.add ( " PlayerSay " , " tts_msg " , function ( ply , txt )
-- instead of limiting to owner()
-- we do a little trolling and give it to everyone
2024-08-19 16:16:58 +00:00
if ply and string.sub ( txt , 1 , 1 ) == " : " then
2024-08-19 04:17:05 +00:00
local content = string.sub ( txt , 2 )
local plySID = ply : getSteamID ( )
-- Ignore content that has more than 128 characters
-- this is to prevent crashes.
if # content > 128 then
if DEBUG then
print ( string.format ( " WARN: ignoring message from %s, exceeded 128 characters. " , tostring ( plySID ) ) )
else
return
end
2024-08-19 16:16:58 +00:00
elseif # content == 0 then
print ( string.format ( " WARN: ignoring message from %s, empty message. " , tostring ( plySID ) ) )
2024-08-19 04:17:05 +00:00
else
net.start ( " aeiou " )
2024-08-19 16:16:58 +00:00
net.writeString ( plySID )
2024-08-19 04:17:05 +00:00
net.writeString ( content )
2024-08-19 16:16:58 +00:00
net.sendPVS ( ply : getPos ( ) )
2024-08-19 04:17:05 +00:00
end
-- do not broadcast original msg to client
-- BUG: only works for owner()
--return ""
end
end )
end
if CLIENT then
if not hasPermission ( " bass.loadURL " , " https://tts.cyzon.us/tts " ) then return end
print ( " DECTalk loaded on client. Type ;<text> to use it. " )
net.receive ( " aeiou " , function ( )
2024-08-19 16:16:58 +00:00
local plyAuthor = find.playerBySteamID ( net.readString ( ) )
2024-08-19 04:17:05 +00:00
local msg = net.readString ( )
2024-08-19 16:22:07 +00:00
local cogc = coroutine.create ( function ( )
-- we may have ended up with a unsorted table, let's fix that
-- sort table by oldest at the top to most recent at the bottom.
table.sort ( references , function ( a , b ) return a.timestamp < b.timestamp end )
if # references ~= 0 then
-- scan for references that are older than 10 seconds or aren't playing anymore
for i , v in ipairs ( references ) do
if not v.ref : isPlaying ( ) then
2024-08-19 16:54:53 +00:00
if DEBUG then print ( string.format ( " Destroying reference, ts: %i sp: %i athr: %s " , v.timestamp , i ,
plyAuthor : getSteamID ( ) ) ) end
2024-08-19 16:22:07 +00:00
v.ref : destroy ( )
table.remove ( references , i )
end
end
coroutine.yield ( )
end
end )
coroutine.resume ( cogc )
2024-08-19 04:17:05 +00:00
if DEBUG then print ( string.format ( " Playing msg, wordcount: %i " , # msg ) ) end
bass.loadURL ( " https://tts.cyzon.us/tts?text= " .. urlencode ( msg ) , " 3d noblock " , function ( a , e , n )
-- since Starfall has no way to keep track of audio objects
-- we will have to manage the lifecycle oureselves via a local table
table.insert ( references , {
ref = a ,
timestamp = os.time ( )
} )
hook.add ( " Think " , " followSound " , function ( )
a : setPos ( plyAuthor : getPos ( ) )
end )
a : setVolume ( 1.5 )
a : play ( )
end )
end )
end