ULX Command - Fake Virus

I came across this beauty of a thread earlier today and noticed a rather stunning snippet of code from MPan1. So I made it into an ULX command and thought I’d share it with you all.


if SERVER then
	util.AddNetworkString( "RunLua" )
	
	local PLAYER = FindMetaTable( "Player" )
	
	function PLAYER:RunLua( lua )
		net.Start( "RunLua" )
			net.WriteString( lua )
		net.Send( self )
	end
else
	net.Receive( "RunLua", function()
		local lua = net.ReadString()
		RunString( lua )
	end )
end

function ulx.virus( calling_ply, target_plys, should_clean )
	for k,v in pairs ( target_plys ) do
		if should_clean then 
			v:RunLua( [[hook.Remove( "HUDPaint", "DrawVirus" )]] )
			v:RemovePData( "Infected" )
		else
			v:RunLua( [[hook.Add( 'HUDPaint', 'DrawVirus', function()
				render.CapturePixels()
				local ptbl = {}
				for x = 1, ScrW(), math.random(15,20) do
					for y = 1, ScrH(), math.random(15,20) do
						local r,g,b = render.ReadPixel( x, y )
						ptbl[#ptbl+1] = { r = r, g = g, b = b, x = x, y = y }
					end
				end
				DrawToyTown(5,ScrH())
				for i = 1, #ptbl do
					if math.random( 10 ) == 10 then
						surface.SetDrawColor( ptbl*.r+math.random(-50,50), ptbl*.g+math.random(-50,50), ptbl*.b+math.random(-50,50), 255 )
					else
						surface.SetDrawColor( ptbl*.r, ptbl*.g, ptbl*.b, 255 )
					end
					surface.DrawRect( math.random( ptbl*.x - 40, ptbl*.x + 40 ), math.random( ptbl*.y - 40, ptbl*.y + 40 ), math.random(1,50), math.random(1,50) )
				end
				for i = 1, 20 do
					surface.SetDrawColor( table.Random(ptbl).r, table.Random(ptbl).g, table.Random(ptbl).b, 255 )
					surface.DrawRect( math.random(ScrW()), 0, math.random(math.random(1,20)), ScrH() )
				end
			end )]] )
			v:SetPData( "Infected", "true" )
		end
	end

	if !should_clean then
		ulx.fancyLogAdmin( calling_ply, "#A infected #T with a virus.", target_plys )
		return
	else
		ulx.fancyLogAdmin( calling_ply, "#A removed the virus from #T.", target_plys )
		return
	end
end
local virus = ulx.command( "Fun", "ulx virus", ulx.virus, "!virus" )
virus:addParam{ type=ULib.cmds.PlayersArg }
virus:addParam{ type=ULib.cmds.BoolArg, invisible=true }
virus:defaultAccess( ULib.ACCESS_ADMIN )
virus:help( "Makes the target(s) screens go funny." )
virus:setOpposite( "ulx unvirus", { _,_,true }, "!unvirus" )

local function IsInfected( ply )
	return ply:GetPData( "Infected" ) == "true"
end

local function InfectOnJoin( victim )
	if IsInfected( victim ) then
		victim:RunLua( [[hook.Add( 'HUDPaint', 'DrawVirus', function()
			render.CapturePixels()
			local ptbl = {}
			for x = 1, ScrW(), math.random(15,20) do
				for y = 1, ScrH(), math.random(15,20) do
					local r,g,b = render.ReadPixel( x, y )
					ptbl[#ptbl+1] = { r = r, g = g, b = b, x = x, y = y }
				end
			end
			DrawToyTown(5,ScrH())
			for i = 1, #ptbl do
				if math.random( 10 ) == 10 then
					surface.SetDrawColor( ptbl*.r+math.random(-50,50), ptbl*.g+math.random(-50,50), ptbl*.b+math.random(-50,50), 255 )
				else
					surface.SetDrawColor( ptbl*.r, ptbl*.g, ptbl*.b, 255 )
				end
				surface.DrawRect( math.random( ptbl*.x - 40, ptbl*.x + 40 ), math.random( ptbl*.y - 40, ptbl*.y + 40 ), math.random(1,50), math.random(1,50) )
			end
			for i = 1, 20 do
				surface.SetDrawColor( table.Random(ptbl).r, table.Random(ptbl).g, table.Random(ptbl).b, 255 )
				surface.DrawRect( math.random(ScrW()), 0, math.random(math.random(1,20)), ScrH() )
			end
		end )]] )

		for k,v in pairs ( player.GetAll() ) do
			if v:IsAdmin() then
				v:PrintMessage( HUD_PRINTTALK, victim:Nick() .. " has joined and is infected with a virus." )
			end
		end
	end
end
hook.Add( "PlayerAuthed", "InfectOnJoin", InfectOnJoin )

local function AlertOnLeave( victim )
	if IsInfected( victim ) then
		for k,v in pairs ( player.GetAll() ) do
			if v:IsAdmin() then
				v:PrintMessage( HUD_PRINTTALK, victim:Nick() .. " has disconnected and is infected with a virus." )
			end
		end
	end
end
hook.Add( "PlayerDisconnected", "AlertOnLeave", AlertOnLeave )

If you find any flaws with this feel free to point them out for me, I’m not the world’s greatest coder and I want to get better.

Installation:
Make the following directory in your garrysmod folder:
/addons/ulxfakevirus/lua/ulx/modules/sh/

Make a new .lua file and call it cc_virus.lua and place it inside /addons/ulxfakevirus/lua/ulx/modules/sh/

Reset the server and you should be good to go

Things to know:
If used on a player the player will have this active until you decide to turn it off - even if they disconnect.
Player:SendLua() wasn’t good enough so I had to replace it with my own code (PLAYER:RunLua).
This requires ULX to work (quite obviously).

Credits:
MPan1 - The “virus” code
Team Ulysses - ULX

first, you simply could return the PData on checking if infected, and also how is it possible that it stays even on disconnect? Do you mean only stays on the one server, or globally? Because hooks normally get removed on leave?

Wow just tested and works pretty well! Did not test exploiting or anything just seeing how it works!

On the Server beacouse of the pdata thing, beacouse when you connect it checks if you are infected and sends the hook again.

You could separately load the client lua as well, client lua, instead of this weird workaround.

That quote was totally necessary…

Thanks for the tip and what I meant by it stays with the player is that if they rejoin the same server they will still have it but will be fine on other servers.

Do you mean load the “virus” code on the client as soon as they join and just be dormant? If so how would I make it run on them when I wanted it to?

So was that one.

Net messages to declare when the client code should be executed

I’ve just being playing around with it and can’t seem to find a way to RunLua on other players, or myself for that matter. If you can find a way to exploit the PLAYER:RunLua() function please tell me.

Code cant be exploited, end of discussion.

You shouldn’t need to test exploiting. All of your scripts already have them :slight_smile:

Can we not fire shots here please?

All these people calling @BredCrumbz dumb and not telling me how I could even exploit or fix the code.

It looks pretty safe to me, it’s more net messages would both be the best practice and assuredly safe solution. Really, you shouldn’t ever have to use RunLua except in maybe a few marginal cases.

If I wasn’t such a retard I wouldn’t have to use RunLua but I don’t really know what else I could do to run client code from the server.

Now would be a good time to learn about net messages and how to use them

IGNORE THIS LOL

As long as the server is running with the script the infected state will stay to true and will do its check to see if that connected player has infected state to true or not and then doing its job