forked from CFC-Servers/cfc_chat_transit
Feature/larynx (#40)
This commit is contained in:
parent
8d142056b9
commit
bcd5f73e9a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
.env
|
.env
|
||||||
|
.idea
|
||||||
|
1
lua/autorun/client/cfc_chat_transit_init.lua
Normal file
1
lua/autorun/client/cfc_chat_transit_init.lua
Normal file
@ -0,0 +1 @@
|
|||||||
|
return include("cfc_chat_transit/client/init.lua")
|
6
lua/autorun/server/sv_chat_transit_init.lua
Normal file
6
lua/autorun/server/sv_chat_transit_init.lua
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
require("steamlookup")
|
||||||
|
include("cfc_chat_transit/server/init.lua")
|
||||||
|
include("cfc_chat_transit/server/remote_messages.lua")
|
||||||
|
AddCSLuaFile("cfc_chat_transit/client/init.lua")
|
||||||
|
AddCSLuaFile("cfc_chat_transit/client/menu.lua")
|
||||||
|
return AddCSLuaFile("cfc_chat_transit/client/receive_remote_message.lua")
|
2
lua/cfc_chat_transit/client/init.lua
Normal file
2
lua/cfc_chat_transit/client/init.lua
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ChatTransit = { }
|
||||||
|
return include("receive_remote_message.lua")
|
31
lua/cfc_chat_transit/client/menu.lua
Normal file
31
lua/cfc_chat_transit/client/menu.lua
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
local alertPreference
|
||||||
|
alertPreference = function(val)
|
||||||
|
net.Start("CFC_ChatTransit_RemoteMessagePreference")
|
||||||
|
net.WriteBool(val)
|
||||||
|
return net.SendToServer()
|
||||||
|
end
|
||||||
|
local initHookName = "CFC_ChatTransit_AlertRemoteMessagePreference"
|
||||||
|
hook.Add("Think", initHookName, function()
|
||||||
|
hook.Remove("Think", initHookName)
|
||||||
|
alertPreference(ChatTransit.shouldReceiveRemoteMessages:GetBool())
|
||||||
|
return nil
|
||||||
|
end)
|
||||||
|
local populatePanel
|
||||||
|
populatePanel = function(panel)
|
||||||
|
local label = "Should show remote messages"
|
||||||
|
do
|
||||||
|
local _with_0 = panel:CheckBox(label, "cfc_chat_transit_remote_messages")
|
||||||
|
_with_0.OnChange = function(_, val)
|
||||||
|
return ChatTransit.alertPreference(val)
|
||||||
|
end
|
||||||
|
return _with_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hook.Add("AddToolMenuCategories", "CFC_ChatTransit_MenuCategory", function()
|
||||||
|
return AddToolCategory("Options", "CFC", "CFC")
|
||||||
|
end)
|
||||||
|
return hook.Add("PopulateToolMenu", "CFC_ChatTransit_MenuOption", function()
|
||||||
|
return AddToolMenuOption("Options", "CFC", "should_receive_remote_messages", "Remote Messages", "", "", function(panel)
|
||||||
|
return populatePanel(panel)
|
||||||
|
end)
|
||||||
|
end)
|
73
lua/cfc_chat_transit/client/receive_remote_message.lua
Normal file
73
lua/cfc_chat_transit/client/receive_remote_message.lua
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
local Start, Receive, ReadBool, ReadColor, ReadString, WriteBool, SendToServer
|
||||||
|
do
|
||||||
|
local _obj_0 = net
|
||||||
|
Start, Receive, ReadBool, ReadColor, ReadString, WriteBool, SendToServer = _obj_0.Start, _obj_0.Receive, _obj_0.ReadBool, _obj_0.ReadColor, _obj_0.ReadString, _obj_0.WriteBool, _obj_0.SendToServer
|
||||||
|
end
|
||||||
|
local AddToolCategory, AddToolMenuOption
|
||||||
|
do
|
||||||
|
local _obj_0 = spawnmenu
|
||||||
|
AddToolCategory, AddToolMenuOption = _obj_0.AddToolCategory, _obj_0.AddToolMenuOption
|
||||||
|
end
|
||||||
|
local shouldReceiveRemoteMessages = CreateConVar("cfc_chat_transit_remote_messages", 1, FCVAR_ARCHIVE, "Should receive remote messges in chat", 0, 1)
|
||||||
|
local colors = {
|
||||||
|
white = Color(255, 255, 255),
|
||||||
|
blurple = Color(142, 163, 247)
|
||||||
|
}
|
||||||
|
Receive("CFC_ChatTransit_RemoteMessageReceive", function()
|
||||||
|
if not (shouldReceiveRemoteMessages:GetBool()) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local author = ReadString()
|
||||||
|
local authorColor = ReadColor()
|
||||||
|
local message = ReadString()
|
||||||
|
if not (author) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not (authorColor) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not (message) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local addTextParams = {
|
||||||
|
colors.blurple,
|
||||||
|
"[Discord] ",
|
||||||
|
authorColor,
|
||||||
|
author,
|
||||||
|
colors.white,
|
||||||
|
": " .. tostring(message)
|
||||||
|
}
|
||||||
|
hook.Run("CFC_ChatTransit_RemoteMessageReceive", addTextParams)
|
||||||
|
return chat.AddText(unpack(addTextParams))
|
||||||
|
end)
|
||||||
|
local alertPreference
|
||||||
|
alertPreference = function(val)
|
||||||
|
Start("CFC_ChatTransit_RemoteMessagePreference")
|
||||||
|
WriteBool(val)
|
||||||
|
return SendToServer()
|
||||||
|
end
|
||||||
|
local initHookName = "CFC_ChatTransit_AlertRemoteMessagePreference"
|
||||||
|
hook.Add("Think", initHookName, function()
|
||||||
|
hook.Remove("Think", initHookName)
|
||||||
|
alertPreference(shouldReceiveRemoteMessages:GetBool())
|
||||||
|
return nil
|
||||||
|
end)
|
||||||
|
local populatePanel
|
||||||
|
populatePanel = function(panel)
|
||||||
|
local label = "Should show remote messages"
|
||||||
|
do
|
||||||
|
local _with_0 = panel:CheckBox(label, "cfc_chat_transit_remote_messages")
|
||||||
|
_with_0.OnChange = function(_, val)
|
||||||
|
return alertPreference(val)
|
||||||
|
end
|
||||||
|
return _with_0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hook.Add("AddToolMenuCategories", "CFC_ChatTransit_MenuCategory", function()
|
||||||
|
return AddToolCategory("Options", "CFC", "CFC")
|
||||||
|
end)
|
||||||
|
return hook.Add("PopulateToolMenu", "CFC_ChatTransit_MenuOption", function()
|
||||||
|
return AddToolMenuOption("Options", "CFC", "should_receive_remote_messages", "Remote Messages", "", "", function(panel)
|
||||||
|
return populatePanel(panel)
|
||||||
|
end)
|
||||||
|
end)
|
90
lua/cfc_chat_transit/server/avatar_service.lua
Normal file
90
lua/cfc_chat_transit/server/avatar_service.lua
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
local TableToJSON
|
||||||
|
TableToJSON = util.TableToJSON
|
||||||
|
local HTTP = HTTP
|
||||||
|
local avatarServiceAddress = CreateConVar("cfc_avatar_service_address", "", FCVAR_ARCHIVE + FCVAR_PROTECTED)
|
||||||
|
local AvatarService
|
||||||
|
do
|
||||||
|
local _class_0
|
||||||
|
local _base_0 = {
|
||||||
|
getAvatar = function(self, steamID64)
|
||||||
|
local url = steamID64 and "https://avatarservice.cfcservers.org/avatars/" .. tostring(steamID64) .. ".png" or nil
|
||||||
|
if self.processedIds[steamID64] then
|
||||||
|
url = url and tostring(url) .. "?processed=true"
|
||||||
|
end
|
||||||
|
return url
|
||||||
|
end,
|
||||||
|
processAvatar = function(self, avatarUrl, outlineColor, steamID64)
|
||||||
|
local body = TableToJSON({
|
||||||
|
avatarUrl = avatarUrl,
|
||||||
|
outlineColor = outlineColor,
|
||||||
|
steamID = steamID64
|
||||||
|
})
|
||||||
|
self.logger:debug("Sending data to outliner: ", body)
|
||||||
|
local failed
|
||||||
|
do
|
||||||
|
local _base_1 = self.logger
|
||||||
|
local _fn_0 = _base_1.error
|
||||||
|
failed = function(...)
|
||||||
|
return _fn_0(_base_1, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local success
|
||||||
|
success = function(code, body)
|
||||||
|
self.logger:debug("Avatar request succeeded with code: " .. tostring(code) .. " | Body: " .. tostring(body))
|
||||||
|
self.processedIds[steamID64] = true
|
||||||
|
end
|
||||||
|
return HTTP({
|
||||||
|
success = success,
|
||||||
|
failed = failed,
|
||||||
|
body = body,
|
||||||
|
url = self.outlinerUrl,
|
||||||
|
method = "POST",
|
||||||
|
type = "application/json"
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
outlineAvatar = function(self, ply, data)
|
||||||
|
self.logger:debug("Received request to outline avatar for ply: " .. tostring(ply:Nick()))
|
||||||
|
local avatar = data.response.players[1].avatarfull
|
||||||
|
local outlineColor = ChatTransit:GetTeamColor(ply:Team())
|
||||||
|
local steamID64 = ply:SteamID64()
|
||||||
|
return self:processAvatar(avatar, outlineColor, steamID64)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
_base_0.__index = _base_0
|
||||||
|
_class_0 = setmetatable({
|
||||||
|
__init = function(self, logger)
|
||||||
|
self.logger = logger:scope("AvatarService")
|
||||||
|
self.outlinerUrl = tostring(avatarServiceAddress:GetString()) .. "/outline"
|
||||||
|
self.processedIds = { }
|
||||||
|
end,
|
||||||
|
__base = _base_0,
|
||||||
|
__name = "AvatarService"
|
||||||
|
}, {
|
||||||
|
__index = _base_0,
|
||||||
|
__call = function(cls, ...)
|
||||||
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
|
cls.__init(_self_0, ...)
|
||||||
|
return _self_0
|
||||||
|
end
|
||||||
|
})
|
||||||
|
_base_0.__class = _class_0
|
||||||
|
AvatarService = _class_0
|
||||||
|
end
|
||||||
|
hook.Add("InitPostEntity", "CFC_ChatTrahsit_AvatarServiceInit", function()
|
||||||
|
ChatTransit.AvatarService = AvatarService(ChatTransit.Logger)
|
||||||
|
end)
|
||||||
|
return hook.Add("CFC_SteamLookup_SuccessfulPlayerData", "CFC_ChatTransit_AvatarService", function(dataName, ply, data)
|
||||||
|
if not (dataName == "PlayerSummary") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not (data) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local success, err = pcall(function()
|
||||||
|
return ChatTransit.AvatarService:outlineAvatar(ply, data)
|
||||||
|
end)
|
||||||
|
if not (success) then
|
||||||
|
ErrorNoHaltWithStack(err, dataName, ply)
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end)
|
89
lua/cfc_chat_transit/server/init.lua
Normal file
89
lua/cfc_chat_transit/server/init.lua
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
require("gwsockets")
|
||||||
|
require("logger")
|
||||||
|
ChatTransit = {
|
||||||
|
Logger = Logger("ChatTransit")
|
||||||
|
}
|
||||||
|
include("cfc_chat_transit/server/avatar_service.lua")
|
||||||
|
include("cfc_chat_transit/server/player_count.lua")
|
||||||
|
local Read
|
||||||
|
Read = file.Read
|
||||||
|
local GetColor
|
||||||
|
GetColor = team.GetColor
|
||||||
|
local TableToJSON
|
||||||
|
TableToJSON = util.TableToJSON
|
||||||
|
local logger = ChatTransit.Logger
|
||||||
|
local relayHost = CreateConVar("cfc_relay_host", "", FCVAR_NONE)
|
||||||
|
local loadHook = "ChatTransit_WebsocketLoad"
|
||||||
|
hook.Add("Think", loadHook, function()
|
||||||
|
hook.Remove("Think", loadHook)
|
||||||
|
ChatTransit.WebSocket = GWSockets.createWebSocket("wss://" .. tostring(relayHost:GetString()) .. "/relay", false)
|
||||||
|
ChatTransit.Realm = CreateConVar("cfc_realm", "unknown", FCVAR_REPLICATED + FCVAR_ARCHIVE, "The Realm Name")
|
||||||
|
do
|
||||||
|
local _with_0 = ChatTransit.WebSocket
|
||||||
|
_with_0.reconnectTimerName = "CFC_ChatTransit_WebsocketReconnect"
|
||||||
|
_with_0.onConnected = function(self)
|
||||||
|
logger:info("Established websocket connection")
|
||||||
|
return timer.Remove(_with_0.reconnectTimerName)
|
||||||
|
end
|
||||||
|
_with_0.onDisconnected = function(self)
|
||||||
|
logger:warn("Lost websocket connection!")
|
||||||
|
if timer.Exists(_with_0.reconnectTimerName) then
|
||||||
|
return logger:warn("Will retry " .. tostring(timer.RepsLeft(_with_0.reconnectTimerName)) .. " more times")
|
||||||
|
end
|
||||||
|
return timer.Create(_with_0.reconnectTimerName, 2, 30, function()
|
||||||
|
return _with_0:open()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
_with_0.onError = function(self, message)
|
||||||
|
return logger:error("Websocket Error!", message)
|
||||||
|
end
|
||||||
|
_with_0:open()
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end)
|
||||||
|
ChatTransit.Send = function(self, data)
|
||||||
|
logger:debug("Sending '" .. tostring(data.Type) .. "'")
|
||||||
|
local steamID64 = data.Data.SteamId
|
||||||
|
data.Data.Avatar = data.Data.Avatar or ChatTransit.AvatarService:getAvatar(steamID64)
|
||||||
|
data.Realm = self.Realm:GetString()
|
||||||
|
data.Data.SteamId = data.Data.SteamId or ""
|
||||||
|
return self.WebSocket:write(TableToJSON(data))
|
||||||
|
end
|
||||||
|
ChatTransit.TeamColorCache = { }
|
||||||
|
ChatTransit.GetTeamColor = function(self, teamName)
|
||||||
|
if self.TeamColorCache[teamName] then
|
||||||
|
return self.TeamColorCache[teamName]
|
||||||
|
end
|
||||||
|
local teamColor = tostring(GetColor(teamName))
|
||||||
|
self.TeamColorCache[teamName] = teamColor
|
||||||
|
return teamColor
|
||||||
|
end
|
||||||
|
ChatTransit.guard = function(f, delay)
|
||||||
|
return function(...)
|
||||||
|
local args = {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
local action
|
||||||
|
action = function()
|
||||||
|
local success, err = pcall(function()
|
||||||
|
return f(unpack(args))
|
||||||
|
end)
|
||||||
|
if not (success) then
|
||||||
|
return ErrorNoHaltWithStack(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if delay then
|
||||||
|
timer.Simple(delay, action)
|
||||||
|
else
|
||||||
|
action()
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
logger:info("Loading modules...")
|
||||||
|
local _list_0 = file.Find("cfc_chat_transit/server/modules/*.lua", "LUA")
|
||||||
|
for _index_0 = 1, #_list_0 do
|
||||||
|
local f = _list_0[_index_0]
|
||||||
|
logger:info("Loading modules/" .. tostring(f))
|
||||||
|
include("modules/" .. tostring(f))
|
||||||
|
end
|
37
lua/cfc_chat_transit/server/modules/anticrash.lua
Normal file
37
lua/cfc_chat_transit/server/modules/anticrash.lua
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
local guard
|
||||||
|
guard = ChatTransit.guard
|
||||||
|
local isstring
|
||||||
|
isstring = _G.isstring
|
||||||
|
ChatTransit.AnticrashEvent = function(self, eventText)
|
||||||
|
if not (isstring(eventText)) then
|
||||||
|
eventText = "Heavy lag detected!"
|
||||||
|
end
|
||||||
|
return self:Send({
|
||||||
|
Type = "anticrash_event",
|
||||||
|
Data = {
|
||||||
|
Content = eventText,
|
||||||
|
SteamName = "CFC Anticrash"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
hook.Add("z_anticrash_LagDetect", "CFC_ChatTransit_AnticrashEventListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.AnticrashEvent
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)()))
|
||||||
|
hook.Add("z_anticrash_LagStuck", "CFC_ChatTransit_AnticrashEventListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.AnticrashEvent
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)()))
|
||||||
|
return hook.Add("z_anticrash_CrashPrevented", "CFC_ChatTransit_AnticrashEventListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.AnticrashEvent
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)()))
|
34
lua/cfc_chat_transit/server/modules/chat.lua
Normal file
34
lua/cfc_chat_transit/server/modules/chat.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
local guard
|
||||||
|
guard = ChatTransit.guard
|
||||||
|
ChatTransit.ReceiveMessage = function(self, ply, text, teamChat)
|
||||||
|
local shouldRelay = hook.Run("CFC_ChatTransit_ShouldRelayChatMessage", ply, text, teamChat)
|
||||||
|
if shouldRelay == false then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if teamChat then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not (text) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if text == "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return self:Send({
|
||||||
|
Type = "message",
|
||||||
|
Data = {
|
||||||
|
Type = "message",
|
||||||
|
Content = text,
|
||||||
|
SteamName = ply:Nick(),
|
||||||
|
SteamId = ply:SteamID64(),
|
||||||
|
IrisId = "none"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
return hook.Add("PlayerSay", "CFC_ChatTransit_MessageListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.ReceiveMessage
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)()), HOOK_MONITOR_LOW)
|
48
lua/cfc_chat_transit/server/modules/connect.lua
Normal file
48
lua/cfc_chat_transit/server/modules/connect.lua
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
local delay, guard
|
||||||
|
do
|
||||||
|
local _obj_0 = ChatTransit
|
||||||
|
delay, guard = _obj_0.delay, _obj_0.guard
|
||||||
|
end
|
||||||
|
local SteamIDTo64
|
||||||
|
SteamIDTo64 = util.SteamIDTo64
|
||||||
|
ChatTransit.PlayerConnect = function(self, data)
|
||||||
|
local bot, name, steamId
|
||||||
|
bot, name, steamId = data.bot, data.name, data.networkid
|
||||||
|
bot = tobool(bot)
|
||||||
|
if bot then
|
||||||
|
steamId = nil
|
||||||
|
end
|
||||||
|
return self:Send({
|
||||||
|
Type = "connect",
|
||||||
|
Data = {
|
||||||
|
SteamName = name,
|
||||||
|
SteamId = steamId and SteamIDTo64(steamId),
|
||||||
|
PlayerCountCurrent = ChatTransit.playerCount,
|
||||||
|
PlayerCountMax = game:MaxPlayers()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
ChatTransit.PlayerInitialSpawn = function(self, ply)
|
||||||
|
return self:Send({
|
||||||
|
Type = "spawn",
|
||||||
|
Data = {
|
||||||
|
SteamName = ply:Nick(),
|
||||||
|
SteamId = ply:SteamID64()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
gameevent.Listen("player_connect")
|
||||||
|
hook.Add("player_connect", "CFC_ChatTransit_SpawnListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.PlayerConnect
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)(), 0))
|
||||||
|
return hook.Add("PlayerInitialSpawn", "CFC_ChatTransit_SpawnListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.PlayerInitialSpawn
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)()))
|
32
lua/cfc_chat_transit/server/modules/disconnect.lua
Normal file
32
lua/cfc_chat_transit/server/modules/disconnect.lua
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
local delay, guard
|
||||||
|
do
|
||||||
|
local _obj_0 = ChatTransit
|
||||||
|
delay, guard = _obj_0.delay, _obj_0.guard
|
||||||
|
end
|
||||||
|
local GetBySteamID
|
||||||
|
GetBySteamID = player.GetBySteamID
|
||||||
|
local SteamIDTo64
|
||||||
|
SteamIDTo64 = util.SteamIDTo64
|
||||||
|
ChatTransit.PlayerDisconnected = function(self, data)
|
||||||
|
local name, reason, steamId
|
||||||
|
name, reason, steamId = data.name, data.reason, data.networkid
|
||||||
|
local ply = GetBySteamID(steamId)
|
||||||
|
return self:Send({
|
||||||
|
Type = "disconnect",
|
||||||
|
Data = {
|
||||||
|
SteamName = ply and ply:Nick() or name,
|
||||||
|
SteamId = ply and ply:SteamID64() or SteamIDTo64(steamId),
|
||||||
|
PlayerCountCurrent = ChatTransit.playerCount,
|
||||||
|
PlayerCountMax = game:MaxPlayers(),
|
||||||
|
Content = reason
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
gameevent.Listen("player_disconnect")
|
||||||
|
return hook.Add("player_disconnect", "CFC_ChatTransit_DisconnectListener", guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.PlayerDisconnected
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)(), 0))
|
17
lua/cfc_chat_transit/server/modules/pvp.lua
Normal file
17
lua/cfc_chat_transit/server/modules/pvp.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
local guard
|
||||||
|
guard = ChatTransit.guard
|
||||||
|
ChatTransit.PvPEvent = function(self, ply, newMode)
|
||||||
|
local eventText = tostring(ply:Nick()) .. " has entered " .. tostring(newMode) .. " mode"
|
||||||
|
return self:Send({
|
||||||
|
Type = "pvp_status_change",
|
||||||
|
Data = {
|
||||||
|
Content = eventText
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
hook.Add("CFC_PvP_PlayerEnterPvp", "CFC_ChatTransit_Relay", guard(function(ply)
|
||||||
|
return ChatTransit:PvPEvent(ply, "PvP")
|
||||||
|
end))
|
||||||
|
return hook.Add("CFC_PvP_PlayerExitPvp", "CFC_ChatTransit_Relay", guard(function(ply)
|
||||||
|
return ChatTransit:PvPEvent(ply, "Build")
|
||||||
|
end))
|
26
lua/cfc_chat_transit/server/modules/startup.lua
Normal file
26
lua/cfc_chat_transit/server/modules/startup.lua
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
local guard
|
||||||
|
guard = ChatTransit.guard
|
||||||
|
local GetMap
|
||||||
|
GetMap = game.GetMap
|
||||||
|
ChatTransit.MapStartup = function(self, data)
|
||||||
|
local eventText = ""
|
||||||
|
local map = GetMap()
|
||||||
|
if SysTime() > 500 then
|
||||||
|
eventText = "Map switched to " .. map
|
||||||
|
else
|
||||||
|
eventText = "Server restarted! Current map is " .. map
|
||||||
|
end
|
||||||
|
return self:Send({
|
||||||
|
Type = "map_init",
|
||||||
|
Data = {
|
||||||
|
Content = eventText
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
return hook.Add("InitPostEntity", "CFC_ChatTransit_StartListener", timer.Simple(1, guard((function()
|
||||||
|
local _base_0 = ChatTransit
|
||||||
|
local _fn_0 = _base_0.MapStartup
|
||||||
|
return function(...)
|
||||||
|
return _fn_0(_base_0, ...)
|
||||||
|
end
|
||||||
|
end)())))
|
40
lua/cfc_chat_transit/server/modules/ulx.lua
Normal file
40
lua/cfc_chat_transit/server/modules/ulx.lua
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
_Msg = Msg
|
||||||
|
local guard
|
||||||
|
guard = ChatTransit.guard
|
||||||
|
local isstring
|
||||||
|
isstring = _G.isstring
|
||||||
|
local Replace
|
||||||
|
Replace = string.Replace
|
||||||
|
ChatTransit.ReceiveULXAction = function(self, msg)
|
||||||
|
msg = Replace(msg, "\n", "")
|
||||||
|
self.Logger:debug("Received global ULX message", msg)
|
||||||
|
return self:Send({
|
||||||
|
Type = "ulx_action",
|
||||||
|
Data = {
|
||||||
|
Type = "ulx_action",
|
||||||
|
Content = msg
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
local M
|
||||||
|
M = function(...)
|
||||||
|
_Msg(...)
|
||||||
|
return ChatTransit:ReceiveULXAction(...)
|
||||||
|
end
|
||||||
|
return hook.Add("InitPostEntity", "ChatTransit_WrapUlxLog", guard(function()
|
||||||
|
if not (ulx) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
ulx._ChatTransit_fancyLogAdmin = ulx._ChatTransit_fancyLogAdmin or ulx.fancyLogAdmin
|
||||||
|
ulx.fancyLogAdmin = function(...)
|
||||||
|
local args = {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
if not (isstring(args[2])) then
|
||||||
|
return ulx._ChatTransit_fancyLogAdmin(...)
|
||||||
|
end
|
||||||
|
Msg = M
|
||||||
|
ulx._ChatTransit_fancyLogAdmin(...)
|
||||||
|
Msg = _Msg
|
||||||
|
end
|
||||||
|
end))
|
42
lua/cfc_chat_transit/server/modules/voice.lua
Normal file
42
lua/cfc_chat_transit/server/modules/voice.lua
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
local IsValid
|
||||||
|
IsValid = _G.IsValid
|
||||||
|
local guard
|
||||||
|
guard = ChatTransit.guard
|
||||||
|
local proxVoice
|
||||||
|
local proxVoiceEnabled
|
||||||
|
proxVoiceEnabled = function()
|
||||||
|
proxVoice = proxVoice or GetConVar("force_proximity_voice")
|
||||||
|
if not (proxVoice) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return proxVoice:GetBool()
|
||||||
|
end
|
||||||
|
ChatTransit.ReceiveVoiceTranscript = function(self, steamID64, data)
|
||||||
|
if proxVoiceEnabled() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ply = player.GetBySteamID64(steamID64)
|
||||||
|
if not (IsValid(ply)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if ply.ulx_gagged then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if ply:GetInfoNum("proximity_voice_enabled", 0) ~= 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local shouldRelay = hook.Run("CFC_ChatTransit_ShouldRelayTranscript", ply, transcript)
|
||||||
|
if shouldRelay == false then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return self:Send({
|
||||||
|
Type = "voice_transcript",
|
||||||
|
Data = {
|
||||||
|
Type = "voice_transcript",
|
||||||
|
Content = data,
|
||||||
|
SteamName = ply:Nick(),
|
||||||
|
SteamId = ply:SteamID64(),
|
||||||
|
IrisId = "none"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
19
lua/cfc_chat_transit/server/player_count.lua
Normal file
19
lua/cfc_chat_transit/server/player_count.lua
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
ChatTransit.playerCount = 0
|
||||||
|
local increment
|
||||||
|
increment = function()
|
||||||
|
ChatTransit.playerCount = ChatTransit.playerCount + 1
|
||||||
|
end
|
||||||
|
local decrement
|
||||||
|
decrement = function()
|
||||||
|
ChatTransit.playerCount = ChatTransit.playerCount - 1
|
||||||
|
end
|
||||||
|
hook.Add("ClientSignOnStateChanged", "ChatTransit_PlayerCount", function(_, oldstate)
|
||||||
|
if not (oldstate == 7) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return increment()
|
||||||
|
end)
|
||||||
|
gameevent.Listen("player_connect")
|
||||||
|
hook.Add("player_connect", "ChatTransit_PlayerCount", increment)
|
||||||
|
gameevent.Listen("player_disconnect")
|
||||||
|
return hook.Add("player_disconnect", "ChatTransit_PlayerCount", decrement)
|
58
lua/cfc_chat_transit/server/remote_messages.lua
Normal file
58
lua/cfc_chat_transit/server/remote_messages.lua
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
local IsValid
|
||||||
|
IsValid = _G.IsValid
|
||||||
|
local AddNetworkString
|
||||||
|
AddNetworkString = util.AddNetworkString
|
||||||
|
local Start, Receive, ReadBool, WriteColor, WriteString, Send
|
||||||
|
do
|
||||||
|
local _obj_0 = net
|
||||||
|
Start, Receive, ReadBool, WriteColor, WriteString, Send = _obj_0.Start, _obj_0.Receive, _obj_0.ReadBool, _obj_0.WriteColor, _obj_0.WriteString, _obj_0.Send
|
||||||
|
end
|
||||||
|
local ToColor
|
||||||
|
ToColor = string.ToColor
|
||||||
|
AddNetworkString("CFC_ChatTransit_RemoteMessagePreference")
|
||||||
|
AddNetworkString("CFC_ChatTransit_RemoteMessageReceive")
|
||||||
|
local recipients = RecipientFilter()
|
||||||
|
local adminRecipients = RecipientFilter()
|
||||||
|
local shouldTransmit = CreateConVar("cfc_chat_transit_should_transmit_remote", 1, FCVAR_ARCHIVE, "Should transmit remote messages", 0, 1)
|
||||||
|
local adminOnly = CreateConVar("cfc_chat_transit_transmit_admin_only", 1, FCVAR_ARCHIVE, "Should only transmit to Admins?", 0, 1)
|
||||||
|
Receive("CFC_ChatTransit_RemoteMessagePreference", function(_, ply)
|
||||||
|
local shouldReceive = ReadBool()
|
||||||
|
if shouldReceive then
|
||||||
|
recipients:AddPlayer(ply)
|
||||||
|
if adminOnly:GetBool() and ply:IsAdmin() then
|
||||||
|
adminRecipients:AddPlayer(ply)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
recipients:RemovePlayer(ply)
|
||||||
|
return adminRecipients:RemovePlayer(ply)
|
||||||
|
end)
|
||||||
|
local broadcastMessage
|
||||||
|
broadcastMessage = function(ply, cmd, args, argStr)
|
||||||
|
if not (shouldTransmit:GetBool()) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if IsValid(ply) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local author = rawget(args, 1)
|
||||||
|
local authorColor = rawget(args, 2)
|
||||||
|
local message = rawget(args, 3)
|
||||||
|
if not (author) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not (authorColor) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not (message) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
authorColor = ToColor(authorColor)
|
||||||
|
local sendingTo = adminOnly:GetBool() and adminRecipients or recipients
|
||||||
|
Start("CFC_ChatTransit_RemoteMessageReceive")
|
||||||
|
WriteString(author)
|
||||||
|
WriteColor(authorColor)
|
||||||
|
WriteString(message)
|
||||||
|
return Send(sendingTo)
|
||||||
|
end
|
||||||
|
return concommand.Add("chat_transit", broadcastMessage)
|
@ -7,7 +7,7 @@ class AvatarService
|
|||||||
|
|
||||||
new: (logger) =>
|
new: (logger) =>
|
||||||
@logger = logger\scope "AvatarService"
|
@logger = logger\scope "AvatarService"
|
||||||
@outlinerUrl = "http://#{avatarServiceAddress\GetString!}/outline"
|
@outlinerUrl = "#{avatarServiceAddress\GetString!}/outline"
|
||||||
@processedIds = {}
|
@processedIds = {}
|
||||||
|
|
||||||
getAvatar: (steamID64) =>
|
getAvatar: (steamID64) =>
|
||||||
@ -18,11 +18,11 @@ class AvatarService
|
|||||||
|
|
||||||
processAvatar: (avatarUrl, outlineColor, steamID64) =>
|
processAvatar: (avatarUrl, outlineColor, steamID64) =>
|
||||||
body = TableToJSON { :avatarUrl, :outlineColor, steamID: steamID64 }
|
body = TableToJSON { :avatarUrl, :outlineColor, steamID: steamID64 }
|
||||||
@logger\info "Sending data to outliner: ", body
|
@logger\debug "Sending data to outliner: ", body
|
||||||
|
|
||||||
failed = @logger\error
|
failed = @logger\error
|
||||||
success = (code, body) ->
|
success = (code, body) ->
|
||||||
@logger\info "Avatar request succeeded with code: #{code} | Body: #{body}"
|
@logger\debug "Avatar request succeeded with code: #{code} | Body: #{body}"
|
||||||
@processedIds[steamID64] = true
|
@processedIds[steamID64] = true
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
@ -34,7 +34,7 @@ class AvatarService
|
|||||||
type: "application/json"
|
type: "application/json"
|
||||||
|
|
||||||
outlineAvatar: (ply, data) =>
|
outlineAvatar: (ply, data) =>
|
||||||
@logger\info "Received request to outline avatar for ply: #{ply\Nick!}"
|
@logger\debug "Received request to outline avatar for ply: #{ply\Nick!}"
|
||||||
avatar = data.response.players[1].avatarfull
|
avatar = data.response.players[1].avatarfull
|
||||||
outlineColor = ChatTransit\GetTeamColor ply\Team!
|
outlineColor = ChatTransit\GetTeamColor ply\Team!
|
||||||
steamID64 = ply\SteamID64!
|
steamID64 = ply\SteamID64!
|
||||||
|
@ -16,8 +16,8 @@ loadHook = "ChatTransit_WebsocketLoad"
|
|||||||
hook.Add "Think", loadHook, ->
|
hook.Add "Think", loadHook, ->
|
||||||
hook.Remove "Think", loadHook
|
hook.Remove "Think", loadHook
|
||||||
|
|
||||||
ChatTransit.WebSocket = GWSockets.createWebSocket "ws://#{relayHost\GetString!}/relay"
|
ChatTransit.WebSocket = GWSockets.createWebSocket "wss://#{relayHost\GetString!}/relay", false
|
||||||
ChatTransit.Realm = CreateConVar "cfc_realm", "", FCVAR_NONE, "CFC Realm Name"
|
ChatTransit.Realm = CreateConVar "cfc_realm", "unknown", FCVAR_REPLICATED + FCVAR_ARCHIVE, "The Realm Name"
|
||||||
|
|
||||||
with ChatTransit.WebSocket
|
with ChatTransit.WebSocket
|
||||||
.reconnectTimerName = "CFC_ChatTransit_WebsocketReconnect"
|
.reconnectTimerName = "CFC_ChatTransit_WebsocketReconnect"
|
||||||
@ -41,7 +41,7 @@ hook.Add "Think", loadHook, ->
|
|||||||
return nil
|
return nil
|
||||||
|
|
||||||
ChatTransit.Send = (data) =>
|
ChatTransit.Send = (data) =>
|
||||||
logger\info "Sending '#{data.Type}'"
|
logger\debug "Sending '#{data.Type}'"
|
||||||
steamID64 = data.Data.SteamId
|
steamID64 = data.Data.SteamId
|
||||||
|
|
||||||
data.Data.Avatar or= ChatTransit.AvatarService\getAvatar steamID64
|
data.Data.Avatar or= ChatTransit.AvatarService\getAvatar steamID64
|
||||||
|
30
moon/cfc_chat_transit/server/modules/voice.moon
Normal file
30
moon/cfc_chat_transit/server/modules/voice.moon
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import IsValid from _G
|
||||||
|
import guard from ChatTransit
|
||||||
|
|
||||||
|
local proxVoice
|
||||||
|
|
||||||
|
proxVoiceEnabled = ->
|
||||||
|
proxVoice or= GetConVar "force_proximity_voice"
|
||||||
|
return false unless proxVoice
|
||||||
|
return proxVoice\GetBool!
|
||||||
|
|
||||||
|
ChatTransit.ReceiveVoiceTranscript = (steamID64, data) =>
|
||||||
|
return if proxVoiceEnabled!
|
||||||
|
|
||||||
|
ply = player.GetBySteamID64 steamID64
|
||||||
|
return unless IsValid ply
|
||||||
|
|
||||||
|
return if ply.ulx_gagged
|
||||||
|
return if ply\GetInfoNum("proximity_voice_enabled", 0) ~= 0
|
||||||
|
|
||||||
|
shouldRelay = hook.Run "CFC_ChatTransit_ShouldRelayTranscript", ply, transcript
|
||||||
|
return if shouldRelay == false
|
||||||
|
|
||||||
|
@Send
|
||||||
|
Type: "voice_transcript"
|
||||||
|
Data:
|
||||||
|
Type: "voice_transcript"
|
||||||
|
Content: data
|
||||||
|
SteamName: ply\Nick!
|
||||||
|
SteamId: ply\SteamID64!
|
||||||
|
IrisId: "none"
|
@ -1,13 +1,14 @@
|
|||||||
FROM python:3.9.0
|
FROM python:3.9.0
|
||||||
|
|
||||||
RUN mkdir /avatars
|
|
||||||
RUN mkdir /avatar-service
|
|
||||||
WORKDIR /avatar-service
|
|
||||||
COPY . /avatar-service
|
|
||||||
|
|
||||||
RUN pip install -U --upgrade pip
|
RUN pip install -U --upgrade pip
|
||||||
|
|
||||||
|
RUN mkdir /avatars
|
||||||
|
WORKDIR /avatar-service
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
RUN pip install --upgrade -r ./requirements.txt
|
RUN pip install --upgrade -r ./requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
COPY entrypoint.sh /usr/bin/
|
COPY entrypoint.sh /usr/bin/
|
||||||
RUN chmod +x /usr/bin/entrypoint.sh
|
|
||||||
ENTRYPOINT ["entrypoint.sh"]
|
ENTRYPOINT ["entrypoint.sh"]
|
@ -12,7 +12,7 @@ services:
|
|||||||
service:
|
service:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.service
|
dockerfile: Dockerfile
|
||||||
command: flask run --host 0.0.0.0 --port 8080
|
command: flask run --host 0.0.0.0 --port 8080
|
||||||
container_name: "${REALM}_chat_transit_avatar_service"
|
container_name: "${REALM}_chat_transit_avatar_service"
|
||||||
ports:
|
ports:
|
||||||
@ -22,5 +22,4 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/build/src
|
|
||||||
- "$AVATARS_DIR:/avatars:z"
|
- "$AVATARS_DIR:/avatars:z"
|
||||||
|
0
web/avatar_service/entrypoint.sh
Normal file → Executable file
0
web/avatar_service/entrypoint.sh
Normal file → Executable file
@ -4,6 +4,10 @@ ENV GOPATH=/build
|
|||||||
ENV GOBIN=/usr/local/go/bin
|
ENV GOBIN=/usr/local/go/bin
|
||||||
|
|
||||||
WORKDIR $GOPATH/src
|
WORKDIR $GOPATH/src
|
||||||
|
COPY go.mod .
|
||||||
|
COPY go.sum .
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
ARG BRANCH=HEAD
|
ARG BRANCH=HEAD
|
||||||
|
@ -9,3 +9,4 @@ services:
|
|||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/build/src
|
- ./:/build/src
|
||||||
|
restart: always
|
||||||
|
@ -3,7 +3,8 @@ module github.com/cfc-servers/cfc_chat_transit
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.23.2
|
github.com/bwmarrin/discordgo v0.25.0
|
||||||
github.com/getsentry/sentry-go v0.9.0
|
github.com/getsentry/sentry-go v0.9.0
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||||
)
|
)
|
||||||
|
@ -9,6 +9,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
|
|||||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||||
github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
||||||
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||||
|
github.com/bwmarrin/discordgo v0.25.0 h1:NXhdfHRNxtwso6FPdzW2i3uBvvU7UIQTghmV2T4nqAs=
|
||||||
|
github.com/bwmarrin/discordgo v0.25.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
@ -96,6 +98,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
|
|||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
@ -141,6 +145,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
|
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
|
||||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
@ -150,6 +156,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -159,8 +166,12 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"github.com/cfc-servers/cfc_chat_transit/voice"
|
||||||
)
|
)
|
||||||
|
|
||||||
var discord *discordgo.Session
|
var discord *discordgo.Session
|
||||||
@ -30,11 +31,25 @@ type EventData struct {
|
|||||||
PlayerCountCurrent float32
|
PlayerCountCurrent float32
|
||||||
}
|
}
|
||||||
|
|
||||||
var MessageQueue = make(chan []byte, 100)
|
type VoiceMessageOperation struct {
|
||||||
|
Message string
|
||||||
|
MessageId string
|
||||||
|
SteamId string
|
||||||
|
SteamName string
|
||||||
|
Avatar string
|
||||||
|
IsFinal bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var MessageQueue = make(chan []byte, 10000)
|
||||||
|
|
||||||
var WebhookId string = os.Getenv("WEBHOOK_ID")
|
var WebhookId string = os.Getenv("WEBHOOK_ID")
|
||||||
var WebhookSecret string = os.Getenv("WEBHOOK_SECRET")
|
var WebhookSecret string = os.Getenv("WEBHOOK_SECRET")
|
||||||
|
|
||||||
|
var VoiceWebhookId string = os.Getenv("VOICE_WEBHOOK_ID")
|
||||||
|
var VoiceWebhookSecret string = os.Getenv("VOICE_WEBHOOK_SECRET")
|
||||||
|
|
||||||
|
var DiscordToken string = os.Getenv("DISCORD_TOKEN")
|
||||||
|
|
||||||
const urlRegexString = `https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)`
|
const urlRegexString = `https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)`
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -43,9 +58,11 @@ const (
|
|||||||
EMOJI_HALTED = "<:halted:398133588010336259>"
|
EMOJI_HALTED = "<:halted:398133588010336259>"
|
||||||
EMOJI_BUILD = "<:build:933512140395012107>"
|
EMOJI_BUILD = "<:build:933512140395012107>"
|
||||||
EMOJI_PVP = "<:bk:812130062379515906>"
|
EMOJI_PVP = "<:bk:812130062379515906>"
|
||||||
|
EMOJI_PLAY = "<:playbuttonsmaller:1017716044485382154>"
|
||||||
EMOJI_MAP = "🗺️"
|
EMOJI_MAP = "🗺️"
|
||||||
EMOJI_CONNECT = "📡"
|
EMOJI_CONNECT = "📡"
|
||||||
EMOJI_ULX = "⌨️"
|
EMOJI_ULX = "⌨️"
|
||||||
|
EMOJI_VOICE = "🗣️"
|
||||||
|
|
||||||
COLOR_RED = 0xE7373E
|
COLOR_RED = 0xE7373E
|
||||||
COLOR_GREEN = 0x37E73E
|
COLOR_GREEN = 0x37E73E
|
||||||
@ -89,7 +106,7 @@ func sendMessage(discord *discordgo.Session, message EventStruct) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendEvent(discord *discordgo.Session, event EventStruct, eventText string, color int, emoji string) {
|
func sendEvent(discord *discordgo.Session, event EventStruct, eventText string, color int, emoji string) *discordgo.Message {
|
||||||
params := &discordgo.WebhookParams{
|
params := &discordgo.WebhookParams{
|
||||||
AllowedMentions: &discordgo.MessageAllowedMentions{
|
AllowedMentions: &discordgo.MessageAllowedMentions{
|
||||||
Parse: []discordgo.AllowedMentionType{},
|
Parse: []discordgo.AllowedMentionType{},
|
||||||
@ -104,11 +121,13 @@ func sendEvent(discord *discordgo.Session, event EventStruct, eventText string,
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := discord.WebhookExecute(WebhookId, WebhookSecret, true, params)
|
message, err := discord.WebhookExecute(WebhookId, WebhookSecret, true, params)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendConnectMessage(discord *discordgo.Session, event EventStruct) {
|
func sendConnectMessage(discord *discordgo.Session, event EventStruct) {
|
||||||
@ -170,10 +189,88 @@ func sendPvpStatusChange(discord *discordgo.Session, event EventStruct) {
|
|||||||
sendEvent(discord, event, event.Data.Content, color, emoji)
|
sendEvent(discord, event, event.Data.Content, color, emoji)
|
||||||
}
|
}
|
||||||
|
|
||||||
func queueGroomer() {
|
func sendVoiceText(discord *discordgo.Session, data *voice.Session) string {
|
||||||
discord, err := discordgo.New("")
|
transcript := data.Message
|
||||||
|
steamName := data.SteamName
|
||||||
|
avatar := data.Avatar
|
||||||
|
// fileName := data.FileName
|
||||||
|
messageId := data.MessageId
|
||||||
|
// isFinal := data.Finished
|
||||||
|
|
||||||
log.Println(WebhookId, WebhookSecret)
|
// var voiceLink string
|
||||||
|
// if len(fileName) > 0 {
|
||||||
|
// voiceLink = fmt.Sprintf("https://larynx.cfcservers.org/%v.ogg", fileName)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var description string
|
||||||
|
|
||||||
|
// if isFinal && len(voiceLink) > 0 {
|
||||||
|
// description = fmt.Sprintf("%v [%v](%v) %v", EMOJI_VOICE, EMOJI_PLAY, voiceLink, transcript)
|
||||||
|
// } else {
|
||||||
|
// description = fmt.Sprintf("%v %v", EMOJI_VOICE, transcript)
|
||||||
|
// }
|
||||||
|
|
||||||
|
description := fmt.Sprintf("%v %v", EMOJI_VOICE, transcript)
|
||||||
|
|
||||||
|
embeds := []*discordgo.MessageEmbed{
|
||||||
|
{
|
||||||
|
Description: description,
|
||||||
|
Color: COLOR_BLUE,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(messageId) == 0 {
|
||||||
|
log.Println("Creating new message for voice")
|
||||||
|
params := &discordgo.WebhookParams{
|
||||||
|
AllowedMentions: &discordgo.MessageAllowedMentions{
|
||||||
|
Parse: []discordgo.AllowedMentionType{},
|
||||||
|
},
|
||||||
|
Username: steamName,
|
||||||
|
AvatarURL: avatar,
|
||||||
|
Embeds: embeds,
|
||||||
|
}
|
||||||
|
|
||||||
|
message, err := discord.WebhookExecute(VoiceWebhookId, VoiceWebhookSecret, true, params)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error sending webhook message create")
|
||||||
|
log.Println(err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.ID
|
||||||
|
} else {
|
||||||
|
log.Println("Updating existing message for voice")
|
||||||
|
params := &discordgo.WebhookEdit{
|
||||||
|
Embeds: embeds,
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(messageId)
|
||||||
|
log.Println(params.Embeds[0].Description)
|
||||||
|
|
||||||
|
message, err := discord.WebhookMessageEdit(VoiceWebhookId, VoiceWebhookSecret, messageId, params)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error sending webhook message edit")
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func processVoiceText(queueVoiceText func(string, string, string, string), event EventStruct) {
|
||||||
|
steamId := event.Data.SteamId
|
||||||
|
steamName := event.Data.SteamName
|
||||||
|
avatar := event.Data.Avatar
|
||||||
|
data := event.Data.Content
|
||||||
|
log.Println(data)
|
||||||
|
|
||||||
|
queueVoiceText(steamId, steamName, avatar, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func queueGroomer() {
|
||||||
|
discord, err := discordgo.New(DiscordToken)
|
||||||
|
voiceManager := voice.NewManager(discord, sendVoiceText)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("error connecting:", err)
|
log.Fatal("error connecting:", err)
|
||||||
@ -211,6 +308,9 @@ func queueGroomer() {
|
|||||||
sendUlxAction(discord, message)
|
sendUlxAction(discord, message)
|
||||||
case "pvp_status_change":
|
case "pvp_status_change":
|
||||||
sendPvpStatusChange(discord, message)
|
sendPvpStatusChange(discord, message)
|
||||||
|
case "voice_transcript":
|
||||||
|
processVoiceText(voiceManager.ReceiveVoiceTranscript, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
166
web/discord_relay/voice/voice.go
Normal file
166
web/discord_relay/voice/voice.go
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
package voice
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
"log"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
SteamId string
|
||||||
|
SteamName string
|
||||||
|
Message string
|
||||||
|
MessageId string
|
||||||
|
FileName string
|
||||||
|
Avatar string
|
||||||
|
Finished bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Operation struct {
|
||||||
|
Session *Session
|
||||||
|
}
|
||||||
|
|
||||||
|
type Manager struct {
|
||||||
|
Sessions map[string]*Session
|
||||||
|
Operations []*Operation
|
||||||
|
discord *discordgo.Session
|
||||||
|
opmutex *sync.Mutex
|
||||||
|
sendMessage func(*discordgo.Session, *Session) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageData The "Content" key of the Event that comes into the Main package
|
||||||
|
type MessageData struct {
|
||||||
|
Message string `json:"transcript"`
|
||||||
|
FileName string `json:"file_name"`
|
||||||
|
SessionID string `json:"session_id"`
|
||||||
|
IsFinal bool `json:"is_final"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Manager) runSendQueue() {
|
||||||
|
bucket := v.discord.Ratelimiter.GetBucket("voiceTranscriptions")
|
||||||
|
|
||||||
|
wait := func() {
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
wait()
|
||||||
|
|
||||||
|
// This should be a blocking call
|
||||||
|
// Unblocks when bucket has bandwidth
|
||||||
|
v.discord.Ratelimiter.LockBucketObject(bucket).Unlock()
|
||||||
|
|
||||||
|
if len(v.Operations) == 0 {
|
||||||
|
wait()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
v.opmutex.Lock()
|
||||||
|
|
||||||
|
firstOperation := v.Operations[0]
|
||||||
|
log.Printf("Processing message for session %v", firstOperation.Session.FileName)
|
||||||
|
v.Operations = v.Operations[1:]
|
||||||
|
|
||||||
|
session := firstOperation.Session
|
||||||
|
description := session.Message
|
||||||
|
|
||||||
|
if len(description) == 0 {
|
||||||
|
log.Printf("No description for session %v", session.FileName)
|
||||||
|
// What is this? Why are you showing this to me
|
||||||
|
v.opmutex.Unlock()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
messageId := v.sendMessage(v.discord, session)
|
||||||
|
|
||||||
|
if len(messageId) == 0 {
|
||||||
|
log.Println("Received no message ID from sendMessage")
|
||||||
|
// Failed to send/update message, send to back of queue
|
||||||
|
v.Operations = append(v.Operations, firstOperation)
|
||||||
|
v.opmutex.Unlock()
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
session.MessageId = messageId
|
||||||
|
}
|
||||||
|
|
||||||
|
v.opmutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Manager) ReceiveVoiceTranscript(steamId string, steamName string, avatar string, data string) {
|
||||||
|
messageData := MessageData{}
|
||||||
|
err := json.Unmarshal([]byte(data), &messageData)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error parsing voice message: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
newMessage := messageData.Message
|
||||||
|
isFinal := messageData.IsFinal
|
||||||
|
fileName := messageData.FileName
|
||||||
|
sessionId := messageData.SessionID
|
||||||
|
|
||||||
|
session, ok := v.Sessions[sessionId]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
session = &Session{
|
||||||
|
SteamId: steamId,
|
||||||
|
SteamName: steamName,
|
||||||
|
Message: newMessage,
|
||||||
|
MessageId: "",
|
||||||
|
Finished: isFinal,
|
||||||
|
Avatar: avatar,
|
||||||
|
FileName: fileName,
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Sessions[sessionId] = session
|
||||||
|
} else {
|
||||||
|
// Nothing changed - we don't need to queue an Operation for this
|
||||||
|
if !isFinal && session.Message == newMessage {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Message = newMessage
|
||||||
|
session.Finished = isFinal
|
||||||
|
session.FileName = fileName
|
||||||
|
}
|
||||||
|
|
||||||
|
if isFinal {
|
||||||
|
// Final message for this transcription, we can stop tracking it
|
||||||
|
// TODO: do I use delete here?
|
||||||
|
v.Sessions[sessionId] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v.opmutex.Lock()
|
||||||
|
defer v.opmutex.Unlock()
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
// Session already existed for sessionID
|
||||||
|
// Do we already have a pending Operation?
|
||||||
|
for _, operation := range v.Operations {
|
||||||
|
if operation.Session == session {
|
||||||
|
// If so, we don't need to add another operation
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Operations = append(v.Operations, &Operation{
|
||||||
|
Session: session,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewManager(discord *discordgo.Session, sendMessage func(*discordgo.Session, *Session) string) *Manager {
|
||||||
|
manager := &Manager{
|
||||||
|
Sessions: make(map[string]*Session),
|
||||||
|
Operations: make([]*Operation, 0),
|
||||||
|
discord: discord,
|
||||||
|
opmutex: &sync.Mutex{},
|
||||||
|
sendMessage: sendMessage,
|
||||||
|
}
|
||||||
|
|
||||||
|
go manager.runSendQueue()
|
||||||
|
return manager
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user