147 lines
4 KiB
Lua
147 lines
4 KiB
Lua
local CHATPRINT_COLOR = CreateClientConVar("cbox_chatprint_color", "151 211 255", true, false, "Color for system messages")
|
|
local JOINLEAVE_COLOR = CreateClientConVar("cbox_joinleave_color", "161 255 161", true, false, "Color for join/leave messages")
|
|
local TEAM_COLOR = CreateClientConVar("cbox_team_color", "24 161 35", true, false, "Color for the team tag")
|
|
local DEAD_COLOR = CreateClientConVar("cbox_dead_color", "255 24 35", true, false, "Color for the dead tag")
|
|
|
|
local color_white = Color(255, 255, 255)
|
|
|
|
local hookTable = {}
|
|
if cbox.hooks then
|
|
hookTable = cbox.hooks.GetTable()
|
|
end
|
|
|
|
cbox.hooks = cbox.hooks or {}
|
|
|
|
---Returns all hooks
|
|
---@return table
|
|
function cbox.hooks.GetTable()
|
|
return hookTable
|
|
end
|
|
|
|
---@alias ValidHooks
|
|
---| '"PreChatAddText"' # Runs before the true chat.AddText is called, allows modification to arguments
|
|
---| '"PrePlayerChat"' # Runs before player chat calls chat.AddText
|
|
|
|
---Adds a hook
|
|
---@param name ValidHooks
|
|
---@param identifier string
|
|
---@param callback function
|
|
function cbox.hooks.Add(name, identifier, callback)
|
|
hookTable[name] = hookTable[name] or {}
|
|
hookTable[name][identifier] = callback
|
|
end
|
|
|
|
---Removes a hook
|
|
---@param name ValidHooks
|
|
---@param identifier string
|
|
function cbox.hooks.Remove(name, identifier)
|
|
if not hookTable[name] then return end
|
|
hookTable[name][identifier] = nil
|
|
end
|
|
|
|
cbox.detours = cbox.detours or {}
|
|
|
|
cbox.detours.chat_AddText = cbox.detours.chat_AddText or chat.AddText
|
|
local origChatAddText = cbox.detours.chat_AddText
|
|
|
|
function chat.AddText(...)
|
|
local args = {...}
|
|
|
|
local hooks = hookTable.PreChatAddText or {}
|
|
for id, callback in next, hooks do
|
|
local function catch(err)
|
|
cbox.utils.RealmError(("Failed to run callback for PreChatAddText hook %q:"):format(id), err)
|
|
end
|
|
|
|
local ok, ret = xpcall(callback, catch, args)
|
|
if not ok then continue end
|
|
|
|
if ret ~= nil then
|
|
if not istable(ret) then
|
|
cbox.utils.RealmError(("Got return for PreChatAddText hook %q, but it was not a table."):format(id))
|
|
|
|
continue
|
|
end
|
|
args = ret
|
|
end
|
|
end
|
|
|
|
origChatAddText(unpack(args))
|
|
|
|
hook.Run("OnChatAddText", args)
|
|
end
|
|
|
|
hook.Add("ChatText", "cbox.chattext", function(index, name, text, type)
|
|
local col = cbox.utils.ParseColorStringToColor(CHATPRINT_COLOR:GetString())
|
|
if type == "joinleave" then
|
|
col = cbox.utils.ParseColorStringToColor(JOINLEAVE_COLOR:GetString())
|
|
end
|
|
|
|
chat.AddText(col, text)
|
|
|
|
return true
|
|
end)
|
|
|
|
local function OverrideOnPlayerChat()
|
|
cbox.detours.OnPlayerChat = cbox.detours.OnPlayerChat or GAMEMODE.OnPlayerChat
|
|
|
|
function GAMEMODE:OnPlayerChat(ply, text, is_team, is_dead, ...)
|
|
local oldChatAddText = chat.AddText
|
|
local args = {}
|
|
chat.AddText = function(...)
|
|
args = {...}
|
|
end
|
|
cbox.detours.OnPlayerChat(self, ply, text, is_team, is_dead, ...)
|
|
chat.AddText = oldChatAddText
|
|
|
|
local new_args = {}
|
|
|
|
for i, arg in ipairs(args) do
|
|
new_args[i] = arg
|
|
|
|
if isstring(arg) then
|
|
if arg == "*DEAD* " then
|
|
new_args[i - 1] = cbox.utils.ParseColorStringToColor(DEAD_COLOR:GetString())
|
|
elseif arg == "(TEAM) " then
|
|
new_args[i - 1] = cbox.utils.ParseColorStringToColor(TEAM_COLOR:GetString())
|
|
elseif arg == "Console" then
|
|
table.insert(new_args, i, Color(160, 160, 160))
|
|
elseif arg:StartsWith(": ") and #arg > 2 then
|
|
local text = arg:sub(3)
|
|
new_args[i] = ": "
|
|
table.insert(new_args, i + 1, text)
|
|
end
|
|
end
|
|
end
|
|
|
|
local hooks = hookTable.PrePlayerChat or {}
|
|
for id, callback in next, hooks do
|
|
local function catch(err)
|
|
cbox.utils.RealmError(("Failed to run callback for PrePlayerChat hook %q:"):format(id), err)
|
|
end
|
|
|
|
local ok, ret = xpcall(callback, catch, new_args)
|
|
if not ok then continue end
|
|
|
|
if ret ~= nil then
|
|
if not istable(ret) then
|
|
cbox.utils.RealmError(("Got return for PrePlayerChat hook %q, but it was not a table."):format(id))
|
|
|
|
continue
|
|
end
|
|
new_args = ret
|
|
end
|
|
end
|
|
|
|
chat.AddText(unpack(new_args))
|
|
|
|
return true
|
|
end
|
|
end
|
|
|
|
hook.Add("Initialize", "cbox.onplayerchat", function()
|
|
OverrideOnPlayerChat()
|
|
end)
|
|
if GAMEMODE then
|
|
OverrideOnPlayerChat()
|
|
end
|