Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

printColor rewrite #2937

Merged
merged 3 commits into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions lua/entities/gmod_wire_expression2/core/cl_debug.lua
Original file line number Diff line number Diff line change
@@ -1,30 +1,48 @@
CreateClientConVar( "wire_expression2_print_max", 15, true, true )
CreateClientConVar( "wire_expression2_print_max_length", 1000, true, true )
CreateClientConVar( "wire_expression2_print_delay", 0.3, true, true )
local cvar_warn = CreateClientConVar("wire_expression2_printcolor_warn", 1, true, true, "Shows a warning when someone uses printColorDriver on you")

local chips = {}
local not_warned = not game.SinglePlayer()

hook.Add("EntityRemoved", "wire_expression2_printColor", function(ent)
chips[ent] = nil
end)
local RED = Color(255, 0, 0)

local printcolor_readers = {
[1] = function() return tostring(net.ReadDouble()) end,
[2] = function() return net.ReadString() end,
[3] = function() return net.ReadColor(false) end,
[4] = function()
local e = net.ReadEntity() -- Passing directly will set color as the player's color which isn't desirable I believe
return e:IsValid() and (e:IsPlayer() and e:GetName() or e:GetClass()) or "NULL" -- Also, MsgC doesn't have this feature, so adds parity
end
}

net.Receive("wire_expression2_printColor", function( len, ply )
local chip = net.ReadEntity()
net.Receive("wire_expression2_printColor", function()
local ply = net.ReadEntity()
local console = net.ReadBool()
if chip and not chips[chip] then
chips[chip] = true
-- printColorDriver is used for the first time on us by this chip
chat.AddText(Color(255,0,0),"While in somone's seat/car/whatever, printColorDriver can be used to 100% realistically fake people talking, including admins.")
chat.AddText(Color(255,0,0),"Don't trust a word you hear while in a seat after seeing this message!")

local msg = {}

for i = 1, 1024 do
local head = net.ReadUInt(4)
if head == 0 then break end
msg[i] = printcolor_readers[head]()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be safer from lua errors

local reader = printcolor_readers[net.ReadUInt(4)]
if not reader then break end
msg[i] = reader()

end

if console then
MsgC(unpack(net.ReadTable()))
MsgC(unpack(msg))
else
chat.AddText(unpack(net.ReadTable()))
if not_warned and ply ~= LocalPlayer() then
not_warned = false
if cvar_warn:GetBool() then
chat.AddText(RED, "While in somone's seat/car/whatever, printColorDriver can be used to 100% realistically fake people talking, including admins.\
Don't trust a word you hear while in a seat after seeing this message!")
end
end
chat.AddText(unpack(msg))
end
end)

net.Receive("wire_expression2_print", function(len, ply)
net.Receive("wire_expression2_print", function()
chat.AddText(net.ReadString())
end)
180 changes: 123 additions & 57 deletions lua/entities/gmod_wire_expression2/core/debug.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ local defaultPrintDelay = 0.3
-- the amount of "charges" a player has by default
local defaultMaxPrints = 15
-- default max print length
local defaultMaxLength = 1000
local defaultMaxLength = game.SinglePlayer() and 10000 or 1000

-- Contains the amount of "charges" a player has, i.e. the amount of print-statements can be executed before
-- the messages being omitted. The defaultPrintDelay is the time required to add one additional charge to the
Expand Down Expand Up @@ -303,94 +303,160 @@ __e2setcost(150)
util.AddNetworkString("wire_expression2_printColor")
util.AddNetworkString("wire_expression2_print")

local printColor_typeids = {
n = tostring,
s = function(text) return string.Left(text,249) end,
v = function(v) return Color(v[1],v[2],v[3]) end,
xv4 = function(v) return Color(v[1],v[2],v[3],v[4]) end,
e = function(e) return IsValid(e) and e:IsPlayer() and e or "" end,
}

local function printColorVarArg(chip, ply, console, typeids, vararg)
if not IsValid(ply) then return end
if not checkDelay(ply) then return end
local bytes = 0
local max_len = 0

-- Proprietary type IDs just for placebo network saving:
-- 0 - EOF
-- 1 - number
-- 2 - string
-- 3 - color
-- 4 - entity
local function pc_number_writer(n)
bytes = bytes + 8
net.WriteUInt(1, 4)
net.WriteDouble(n)
end

local i = 1
for i,tp in ipairs(typeids) do
if printColor_typeids[tp] then
vararg[i] = printColor_typeids[tp](vararg[i])
else
vararg[i] = ""
end
if i == 256 then break end
i = i + 1
local function pc_string_writer(text)
local len = bytes + #text
net.WriteUInt(2, 4)
if len >= max_len then
net.WriteString(string.sub(text, 1, max_len - bytes))
else
net.WriteString(text)
end
bytes = len + 1
end

net.Start("wire_expression2_printColor")
net.WriteEntity(chip)
net.WriteBool(console)
net.WriteTable(vararg)
net.Send(ply)
local function pc_entity_writer(e)
bytes = bytes + 2 -- edict is 13 bits oh well
net.WriteUInt(4, 4)
net.WriteEntity(e)
end

local function pc_vector_writer(v)
bytes = bytes + 24
net.WriteUInt(3, 4)
net.WriteUInt(v[1], 8)
net.WriteUInt(v[2], 8)
net.WriteUInt(v[3], 8)
end

local printColor_types = {
number = tostring,
string = function(text) return string.Left(text,249) end,
Vector = function(v) return Color(v[1],v[2],v[3]) end,
table = function(tbl)
for i,v in pairs(tbl) do
if not isnumber(i) then return "" end
if not isnumber(v) then return "" end
if i < 1 or i > 4 then return "" end
local printcolor_writers = {
[TYPE_NUMBER] = pc_number_writer,
[TYPE_STRING] = pc_string_writer,
[TYPE_VECTOR] = pc_vector_writer,
[TYPE_TABLE] = function(t)
if IsColor(t) then
bytes = bytes + 24
net.WriteUInt(3, 4)
net.WriteColor(t, false)
else
for i, v in pairs(t) do
if not isnumber(i) then return end
if not isnumber(v) then return end
if i < 1 or i > 4 then return end
end
bytes = bytes + 24
net.WriteUInt(3, 4)
net.WriteUInt(t[1], 8)
net.WriteUInt(t[2], 8)
net.WriteUInt(t[3], 8)
end
return Color(tbl[1] or 0, tbl[2] or 0,tbl[3] or 0,tbl[4])
end,
Player = function(e) return IsValid(e) and e:IsPlayer() and e or "" end,
[TYPE_ENTITY] = pc_entity_writer,

n = pc_number_writer,
s = pc_string_writer,
v = pc_vector_writer,
e = pc_entity_writer,
xv4 = function(t)
bytes = bytes + 24
net.WriteUInt(3, 4)
net.WriteUInt(t[1], 8)
net.WriteUInt(t[2], 8)
net.WriteUInt(t[3], 8)
end,
}

local function printColorArray(chip, ply, console, arr)
local function printColorVarArg(self, ply, console, typeids, vararg)
if not IsValid(ply) then return end
if not checkDelay( ply ) then return end
if not checkDelay(ply) then return end
bytes = 0

local send_array = {}
max_len = math.min(maxLength:GetInt(), self.player:GetInfoNum("wire_expression2_print_max_length", defaultMaxLength))
max_len = math.min(max_len + math.floor(max_len / 3), 65532) -- Add a third just to be nice

local i = 1
for i,tp in ipairs_map(arr,type) do
if printColor_types[tp] then
send_array[i] = printColor_types[tp](arr[i])
else
send_array[i] = ""
net.Start("wire_expression2_printColor")
net.WriteEntity(self.entity:GetPlayer()) -- CHANGE THIS TO WritePlayer LATER!!!
net.WriteBool(console)

for i, tp in ipairs(typeids) do
local fn = printcolor_writers[tp]
if fn then
fn(vararg[i])
else
pc_string_writer(repr(self, vararg[i], tp))
end
if bytes >= max_len then break end
end
if i == 256 then break end
i = i + 1
end

net.WriteUInt(0, 4)

net.Send(ply)

self.prf = self.prf + bytes / 8
end

local function printColorArray(self, ply, console, arr)
if not IsValid(ply) then return end
if not checkDelay(ply) then return end
bytes = 0

max_len = math.min(maxLength:GetInt(), self.player:GetInfoNum("wire_expression2_print_max_length", defaultMaxLength))
max_len = math.min(max_len + math.floor(max_len / 3), 65532)

net.Start("wire_expression2_printColor")
net.WriteEntity(chip)
net.WriteEntity(self.entity:GetPlayer())
net.WriteBool(console)
net.WriteTable(send_array)

for _, v in ipairs(arr) do
local fn = printcolor_writers[TypeID(v)]
if fn then
fn(v)
else
pc_string_writer(tostring(v))
end
if bytes >= max_len then break end
end

net.WriteUInt(0, 4)

net.Send(ply)

self.prf = self.prf + bytes / 8
end


--- Works like [[chat.AddText]](...). Parameters can be any amount and combination of numbers, strings, player entities, color vectors (both 3D and 4D).
e2function void printColor(...args)
printColorVarArg(nil, self.player, false, typeids, args)
printColorVarArg(self, self.player, false, typeids, args)
end

--- Like printColor(...), except taking an array containing all the parameters.
e2function void printColor(array arr)
printColorArray(nil, self.player, false, arr)
printColorArray(self, self.player, false, arr)
end

--- Works like MsgC(...). Parameters can be any amount and combination of numbers, strings, player entities, color vectors (both 3D and 4D).
e2function void printColorC(...args)
printColorVarArg(nil, self.player, true, typeids, args)
printColorVarArg(self, self.player, true, typeids, args)
end

--- Like printColorC(...), except taking an array containing all the parameters.
e2function void printColorC(array arr)
printColorArray(nil, self.player, true, arr)
printColorArray(self, self.player, true, arr)
end

--- Like printColor(...), except printing in <this>'s driver's chat area instead of yours.
Expand All @@ -402,7 +468,7 @@ e2function void entity:printColorDriver(...args)

if not checkDelay( driver ) then return end

printColorVarArg(self.entity, driver, false, typeids, args)
printColorVarArg(self, driver, false, typeids, args)
end

--- Like printColor(R), except printing in <this>'s driver's chat area instead of yours.
Expand All @@ -414,5 +480,5 @@ e2function void entity:printColorDriver(array arr)

if not checkDelay( driver ) then return end

printColorArray(self.entity, driver, false, arr)
printColorArray(self, driver, false, arr)
end
Loading