Skip to content

Instantly share code, notes, and snippets.

@Earu
Last active August 22, 2021 09:39
Show Gist options
  • Save Earu/de79917e686ad4733f5fe3e900cac0e1 to your computer and use it in GitHub Desktop.
Save Earu/de79917e686ad4733f5fe3e900cac0e1 to your computer and use it in GitHub Desktop.
POC for taking a screenshot of a client's playermodel from a random angle from the server.
local TAG = "SCREENSHOT_SV"
if SERVER then
util.AddNetworkString(TAG)
local token_base = "1234567890_@#$abcdefghijklmnopqrstuvwxyz"
local function generate_token()
local ret = ""
for _ = 1, math.random(10, 32) do
local char = token_base[math.random(#token_base)]
if math.random() > 0.5 then
char = char:upper()
end
ret = math.random() > 0.5 and ret .. char or char .. ret
end
return ret
end
local token = generate_token()
function SCREENSHOT(ply, pos)
net.Start(TAG)
net.WriteString(token)
net.WriteVector(pos)
net.Send(ply)
end
net.Receive(TAG, function(_, ply)
local token = net.ReadString()
local len = net.ReadInt(32)
local compressed_data = net.ReadData(len)
print(base64)
end)
end
if CLIENT then
local function rand_vec(lim, min, max)
local x = math.random() > 0.5 and math.random(lim, max) or math.random(min, lim)
local y = math.random() > 0.5 and math.random(lim, max) or math.random(min, lim)
local z = math.random() > 0.5 and math.random(lim, max) or math.random(min, lim)
return Vector(x, y, z)
end
local MAX_RETRIES = 20
local function compute_rand_angle(ent, pos)
local vec = rand_vec(100, 0, 500)
local tr = util.TraceLine({
start = pos,
endpos = pos + vec,
})
local retries = 0
while tr.Entity ~= ent do
vec = rand_vec(100, 0, 500)
tr = util.TraceLine({
start = pos,
endpos = pos + vec,
})
retries = retries + 1
if retries >= MAX_RETRIES then break end
end
return pos + vec
end
net.Receive(TAG, function()
local token = net.ReadString()
local pos = net.ReadVector()
local cam_pos = compute_rand_angle(LocalPlayer(), pos)
hook.Add("CalcView", TAG, function(ply, _, _, fov)
return {
origin = cam_pos,
angles = (pos - cam_pos):Angle(),
fov = fov,
drawviewer = true
}
end)
timer.Simple(1, function()
hook.Add("PostRender", TAG, function()
local data = render.Capture({
format = "png",
x = 0,
y = 0,
w = ScrW(),
h = ScrH(),
})
local compressed_data = util.Compress(util.Base64Encode(data))
print(#compressed_data)
net.Start(TAG)
net.WriteString(token)
net.WriteInt(#compressed_data, 32)
net.WriteData(compressed_data, #compressed_data)
net.SendToServer()
hook.Remove("PostRender", TAG)
hook.Remove("CalcView", TAG)
end)
end)
end)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment