Logic problem

There is a script I use to catch cheaters on my server, I have caught quite a few with random checks. When I do these these random checks I get a screenshot from each player to check for cheat menus or HUD additions. The problem I had was is that the windows aren’t titled with the player’s name, so it takes me a while to narrow down who the cheater is after I see it.

I tried to add the player’s name and steamid to window but if another screenshot is called before the current one appears then the variable “target” that I use gets overwritten and when the windows appear they both have the same player in the title. I’m not sure how to stop this from happening. Here is the code, lines 78 and 110 are where I put my garbage in.



if SERVER then
util.AddNetworkString("ClientMenu") --Opens a list of all players
util.AddNetworkString("RequestScreen") -- Requests Player's screen
util.AddNetworkString("WarrantRequest") -- Requests server to ask for a screenshot
util.AddNetworkString("GetScreen") -- Sends the player's screen to server
util.AddNetworkString("SendToCaller") -- Sends to screen data from server to the origional

function UserMenu(ply, text, public)
	if (string.sub(string.lower(text), 1, 11) == "/screenmenu") then -- if they say /screenmenu then send the menu to them
		if ply:IsSuperAdmin() then -- There are the checks, there are more in the menu (cl_screengrab)
	    	net.Start("ClientMenu")
	    	net.Send(ply)
	    	return ""
   		end
    end
end
hook.Add("PlayerSay", "ActiveMenu", UserMenu)

net.Receive("WarrantRequest", function()
	local caller = net.ReadEntity()
	local victim = net.ReadEntity()

	net.Start("RequestScreen")
		net.WriteEntity(caller)
	net.Send(victim)
end)

net.Receive("GetScreen", function()
	local caller = net.ReadEntity()
	local data = net.ReadString()
	if caller:IsSuperAdmin() then
		net.Start("SendToCaller")
			net.WriteString( data )
		net.Send(caller)
	end
end)
end

if CLIENT then
function Box(w, h, col)
	surface.SetDrawColor(col)
	surface.DrawRect(0, 0 , w, h)
	surface.SetDrawColor(255,255,255,5)
	surface.DrawRect(5, 2 , w - 10, h * 0.3)
	surface.SetDrawColor(color_black)
	surface.DrawOutlinedRect(0, 0, w, h)
end

net.Receive("ClientMenu", function()
	/* OPENS A MENU OF ALL CLIENTS */
	local MenuFrame = vgui.Create("DFrame")
		MenuFrame:SetSize(170, 20 + (#player.GetAll() * 31))
		MenuFrame:MakePopup()
		MenuFrame:SetTitle("Player List")
		MenuFrame:SetPos(2, ScrH() / 2 - MenuFrame:GetTall()  / 2)
		MenuFrame.Paint = function()
			Box(MenuFrame:GetWide(), MenuFrame:GetTall(), Color(30,30,30,255))
		end
	local Panel = vgui.Create("DPanelList", MenuFrame)
		Panel:SetSize(165, MenuFrame:GetTall() - 28)
		Panel:SetPos(3,25)
		--Panel:SetText("Player List")
		Panel:SetPadding( 5 )
		Panel:SetSpacing( 5 )
	for k, v in pairs(player.GetAll()) do
		local button = Panel:Add("DButton")
		button:SetSize(120,30)
		button:Dock( 4 )
		button:SetText(v:Name())
		button.Paint = function()
			Box(button:GetWide(), button:GetTall(), Color(0,0,255,255))
		end
		button.DoClick = function()
			if LocalPlayer():IsSuperAdmin() then
			net.Start("WarrantRequest")
				net.WriteEntity(LocalPlayer())
				net.WriteEntity(v)
				target = v
			net.SendToServer()
			end
		end
	end
end)

net.Receive("RequestScreen", function()
	local screen = {}
	screen.format = "jpeg"
	screen.h = ScrH()
	screen.w = ScrW()
	screen.quality = 0.1
	screen.x = 0
	screen.y = 0

	local data = render.Capture( screen )
	local Requestee = net.ReadEntity()

	net.Start("GetScreen")
		net.WriteEntity(Requestee)
		net.WriteString( util.Base64Encode(data) )
	net.SendToServer()
end)

net.Receive("SendToCaller", function()
	local data = net.ReadString()

	local frame = vgui.Create("DFrame")
		frame:SetSize(ScrW() * 0.8, ScrH() * 0.8)
		frame:Center()
		print(v)
		frame:SetTitle(string.format("screenshot - %s %s", target:Name(), target:SteamID()))
		frame.Paint = function()
			Box(frame:GetWide(), frame:GetTall(), Color(30,30,30,255))
		end

	local html = frame:Add("HTML")
		html:SetHTML([[
		<style type="text/css">
			body {
				margin: 0;
				padding: 0;
				overflow: hidden;
			}
			img {
				width: 100%;
				height: 100%;
			}
		</style>
		<img src="data:image/jpg;base64,]] .. data .. [[">]])
	html:Dock( FILL )
end)
end



net.Start("GetScreen")
		net.WriteEntity(Requestee)
		net.WriteString( util.Base64Encode(data) )
	net.SendToServer()

Write local player here.



net.Receive("SendToCaller", function()
	local data = net.ReadString()

And read the player here, as target.

-snip-

Misread the problem

Robotboy, I’m actually wrong because that message is sent to the player who’s screen he’s capping, so the 2nd arg would be the player he’s capping.

I messed it up. target is returning “Entity [0][worldspawn]” which I guess is the server.



	net.Start("GetScreen")
		net.WriteEntity(Requestee)
		net.WriteString( util.Base64Encode(data) )
		net.WriteEntity(LocalPlayer())
	net.SendToServer()
end)

net.Receive("SendToCaller", function()
	local data = net.ReadString()
	local target = net.ReadEntity()


You must read in the same order as you write.



	net.Start("GetScreen")
		net.WriteEntity(Requestee)
		net.WriteString( util.Base64Encode(data) )
	        net.WriteEntity(LocalPlayer())
	net.SendToServer()
end)

net.Receive("SendToCaller", function()
	local target = net.ReadEntity()
	local data = net.ReadString()


And you still manage to fuck it up? Swap the net.WriteEntity functions.

[editline]30th January 2014[/editline]

If you send the caller first, you read the caller first.
If you send the data second, you read it second.



	net.Start("GetScreen")
                net.WriteEntity(LocalPlayer())
		net.WriteEntity(Requestee)
		net.WriteString( util.Base64Encode(data) )
	net.SendToServer()
end)

net.Receive("SendToCaller", function()
	local target = net.ReadEntity()
	local data = net.ReadString()


I already tried every order possible including this one and this



	net.Start("GetScreen")
                net.WriteEntity(LocalPlayer())
		net.WriteString( util.Base64Encode(data) )
                net.WriteEntity(Requestee)
	net.SendToServer()
end)

net.Receive("SendToCaller", function()
	local target = net.ReadEntity()
	local data = net.ReadString()


Well, good talk. Anyone else?