From 5cfe0c8ea50650976d0ff7117f765e8f8162195b Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Sun, 17 Dec 2023 21:23:37 -0700 Subject: [PATCH] starting stuff --- LICENSE | 2 +- lua/autorun/cbox_init.lua | 1 + lua/cbox/cl_hooks.lua | 62 ++++++++++++++ lua/cbox/modules/cl_greentext.lua | 20 +++++ lua/cbox/modules/cl_timestamps.lua | 36 +++++++++ lua/cbox/sh_init.lua | 33 ++++++++ lua/cbox/sh_utils.lua | 126 +++++++++++++++++++++++++++++ 7 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 lua/autorun/cbox_init.lua create mode 100644 lua/cbox/cl_hooks.lua create mode 100644 lua/cbox/modules/cl_greentext.lua create mode 100644 lua/cbox/modules/cl_timestamps.lua create mode 100644 lua/cbox/sh_init.lua create mode 100644 lua/cbox/sh_utils.lua diff --git a/LICENSE b/LICENSE index acf8e3b..938af82 100644 --- a/LICENSE +++ b/LICENSE @@ -220,7 +220,7 @@ If you develop a new program, and you want it to be of the greatest possible use To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. cbox - Copyright (C) 2023 Cynosphere-gmod + Copyright (C) 2023 Cynthia Foxwell This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/lua/autorun/cbox_init.lua b/lua/autorun/cbox_init.lua new file mode 100644 index 0000000..7417b6f --- /dev/null +++ b/lua/autorun/cbox_init.lua @@ -0,0 +1 @@ +include("cbox/sh_init.lua") diff --git a/lua/cbox/cl_hooks.lua b/lua/cbox/cl_hooks.lua new file mode 100644 index 0000000..20e9495 --- /dev/null +++ b/lua/cbox/cl_hooks.lua @@ -0,0 +1,62 @@ +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 + +---Adds a hook +---@param name "PreChatAddText" +---@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 "PreChatAddText" +---@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 diff --git a/lua/cbox/modules/cl_greentext.lua b/lua/cbox/modules/cl_greentext.lua new file mode 100644 index 0000000..ada79f9 --- /dev/null +++ b/lua/cbox/modules/cl_greentext.lua @@ -0,0 +1,20 @@ +local ENABLED = CreateClientConVar("cbox_greentext", "1", true, false, "Enables greentext", 0, 1) +local COLOR = CreateClientConVar("cbox_greentext_color", "175 201 96", true, false, "Color greentext should be") + +local color_white = Color(255, 255, 255) + +cbox.hooks.Add("PreChatAddText", "cbox.greentext", function(args) + if not ENABLED:GetBool() then return end + + for i, arg in ipairs(args) do + if isstring(arg) and arg:StartsWith(": >") then + args[i] = arg:sub(3) + table.insert(args, i, cbox.utils.ParseColorString(COLOR:GetString())) + table.insert(args, i, ": ") + table.insert(args, i, color_white) + break + end + end + + return args +end) diff --git a/lua/cbox/modules/cl_timestamps.lua b/lua/cbox/modules/cl_timestamps.lua new file mode 100644 index 0000000..4f7458f --- /dev/null +++ b/lua/cbox/modules/cl_timestamps.lua @@ -0,0 +1,36 @@ +local ENABLED = CreateClientConVar("cbox_timestamps", "1", true, false, "Enables timestamps", 0, 1) +local TRUETIME = CreateClientConVar("cbox_timestamps_24hr", "1", true, false, "Whether timestamps should be 24 hour instead of 12 hour", 0, 1) +local SECONDS = CreateClientConVar("cbox_timestamps_seconds", "0", true, false, "Whether timestamps should display seconds", 0, 1) +local COLOR = CreateClientConVar("cbox_timestamps_color", "151 211 255", true, false, "Color timestamps should be") + +local color_white = Color(255, 255, 255) + +cbox.hooks.Add("PreChatAddText", "cbox.timestamps", function(args) + if not ENABLED:GetBool() then return end + + local use24 = TRUETIME:GetBool() + local stamp = "" + + if use24 then + stamp = stamp .. os.date("%H:") + else + stamp = stamp .. os.date("%I:") + end + + stamp = stamp .. os.date("%M") + + if SECONDS:GetBool() then + stamp = stamp .. os.date(":%S") + end + + if not use24 then + stamp = stamp .. os.date(" %p") + end + + local new_args = {cbox.utils.ParseColorString(COLOR:GetString()), stamp, color_white, " - "} + for _, arg in ipairs(args) do + new_args[#new_args + 1] = arg + end + + return new_args +end) diff --git a/lua/cbox/sh_init.lua b/lua/cbox/sh_init.lua new file mode 100644 index 0000000..5917927 --- /dev/null +++ b/lua/cbox/sh_init.lua @@ -0,0 +1,33 @@ +AddCSLuaFile() + +cbox = cbox or {} + +include("cbox/sh_utils.lua") + +if SERVER then + AddCSLuaFile("cbox/cl_hooks.lua") +elseif CLIENT then + include("cbox/cl_hooks.lua") +end + +local module_files = file.Find("cbox/modules/*", "LUA") +for _, name in ipairs(module_files) do + local full_path = "cbox/modules/" .. name + if name:StartsWith("cl_") then + if SERVER then + AddCSLuaFile(full_path) + elseif CLIENT then + cbox.utils.RealmPrint("Loading module:", name) + include(full_path) + end + elseif name:StartsWith("sv_") and SERVER then + cbox.utils.RealmPrint("Loading module:", name) + include(full_path) + else + if SERVER then + AddCSLuaFile(full_path) + end + cbox.utils.SharedPrint("Loading module:", name) + include(full_path) + end +end diff --git a/lua/cbox/sh_utils.lua b/lua/cbox/sh_utils.lua new file mode 100644 index 0000000..dc0a62e --- /dev/null +++ b/lua/cbox/sh_utils.lua @@ -0,0 +1,126 @@ +AddCSLuaFile() + +local cbox = cbox + +local MsgC = MsgC +local Color = Color +local ipairs = ipairs +local tonumber = tonumber +local tostring = tostring + +local string = string + +local string_Explode = string.Explode + +local color_white = Color(255, 255, 255) + +local utils = {} +utils.colors = { + BRAND = Color(132, 206, 181), + CLIENT = Color(143, 218, 230), + SERVER = Color(230, 218, 112), + SHARED = Color( 93, 200, 92), + ERROR = Color(255, 90, 90), +} + +---Parses a string into a color +---@param str string Input color as "R G B" or "R G B A" +---@param alpha? boolean Whether to parse alpha or not (default false) +---@return Color +function utils.ParseColorString(str, alpha) + alpha = alpha ~= nil and alpha or false + + local split = string_Explode(" ", str) + local r = tonumber(split[1]) or 255 + local g = tonumber(split[2]) or 255 + local b = tonumber(split[3]) or 255 + local a = alpha and tonumber(split[4] or 255) or 255 + + return Color(r, g, b, a) +end + +---Prints to console with realm prefix +---@vararg any +function utils.RealmPrint(...) + local args = {...} + for i, arg in ipairs(args) do + args[i] = tostring(arg) + end + + MsgC(utils.colors.BRAND, "[cbox -> ") + + local realm, realm_color = "???", utils.colors.SHARED + if CLIENT then + realm = "CLIENT" + realm_color = utils.colors.CLIENT + elseif SERVER then + realm = "SERVER" + realm_color = utils.colors.SERVER + end + MsgC(realm_color, realm) + + MsgC(utils.colors.BRAND, "] ") + + MsgC(color_white, table.concat(args, " "), "\n") +end + +---Prints to console with the "shared" prefix +---@vararg any +function utils.SharedPrint(...) + local args = {...} + for i, arg in ipairs(args) do + args[i] = tostring(arg) + end + + MsgC(utils.colors.BRAND, "[cbox -> ") + + MsgC(utils.colors.SHARED, "SHARED") + + MsgC(utils.colors.BRAND, "] ") + + MsgC(color_white, table.concat(args, " "), "\n") +end + +---Prints to console with realm prefix, but in red +---@vararg any +function utils.RealmError(...) + local args = {...} + for i, arg in ipairs(args) do + args[i] = tostring(arg) + end + + MsgC(utils.colors.BRAND, "[cbox -> ") + + local realm, realm_color = "???", utils.colors.SHARED + if CLIENT then + realm = "CLIENT" + realm_color = utils.colors.CLIENT + elseif SERVER then + realm = "SERVER" + realm_color = utils.colors.SERVER + end + MsgC(realm_color, realm) + + MsgC(utils.colors.BRAND, "] ") + + MsgC(utils.colors.ERROR, table.concat(args, " "), "\n") +end + +---Prints to console with the "shared" prefix, but in red +---@vararg any +function utils.SharedError(...) + local args = {...} + for i, arg in ipairs(args) do + args[i] = tostring(arg) + end + + MsgC(utils.colors.BRAND, "[cbox -> ") + + MsgC(utils.colors.SHARED, "SHARED") + + MsgC(utils.colors.BRAND, "] ") + + MsgC(utils.colors.ERROR, table.concat(args, " "), "\n") +end + +cbox.utils = utils