Last active
April 4, 2017 19:00
-
-
Save NeatNit/a0d67229734888009ca12e7639f78856 to your computer and use it in GitHub Desktop.
render hooks reverse engineering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local gmod = gmod | |
local pairs = pairs | |
local isfunction = isfunction | |
local isstring = isstring | |
local IsValid = IsValid | |
if CLIENT_DLL then require( "draw" ) end | |
local draw = draw | |
local render = render | |
local table = table | |
local CLIENT = CLIENT_DLL | |
local unpack = unpack | |
local print = print | |
local ipairs = ipairs | |
local tostring = tostring | |
local Color = Color | |
local cam = cam | |
local math = math | |
module( "hook" ) | |
local Hooks = {} | |
--[[--------------------------------------------------------- | |
Name: GetTable | |
Desc: Returns a table of all hooks. | |
-----------------------------------------------------------]] | |
function GetTable() return Hooks end | |
--[[--------------------------------------------------------- | |
Name: Add | |
Args: string hookName, any identifier, function func | |
Desc: Add a hook to listen to the specified event. | |
-----------------------------------------------------------]] | |
function Add( event_name, name, func ) | |
if ( !isfunction( func ) ) then return end | |
if ( !isstring( event_name ) ) then return end | |
if ( Hooks[ event_name ] == nil ) then | |
Hooks[ event_name ] = {} | |
end | |
Hooks[ event_name ][ name ] = func | |
end | |
--[[--------------------------------------------------------- | |
Name: Remove | |
Args: string hookName, identifier | |
Desc: Removes the hook with the given indentifier. | |
-----------------------------------------------------------]] | |
function Remove( event_name, name ) | |
if ( !isstring( event_name ) ) then return end | |
if ( !Hooks[ event_name ] ) then return end | |
Hooks[ event_name ][ name ] = nil | |
end | |
--[[--------------------------------------------------------- | |
Name: Run | |
Args: string hookName, vararg args | |
Desc: Calls hooks associated with the hook name. | |
-----------------------------------------------------------]] | |
function Run( name, ... ) | |
return Call( name, gmod and gmod.GetGamemode() or nil, ... ) | |
end | |
--[[--------------------------------------------------------- | |
Name: Run | |
Args: string hookName, table gamemodeTable, vararg args | |
Desc: Calls hooks associated with the hook name. | |
-----------------------------------------------------------]] | |
local function OrigCall( name, gm, ... ) | |
-- | |
-- Run hooks | |
-- | |
local HookTable = Hooks[ name ] | |
if ( HookTable != nil ) then | |
local a, b, c, d, e, f; | |
for k, v in pairs( HookTable ) do | |
if ( isstring( k ) ) then | |
-- | |
-- If it's a string, it's cool | |
-- | |
a, b, c, d, e, f = v( ... ) | |
else | |
-- | |
-- If the key isn't a string - we assume it to be an entity | |
-- Or panel, or something else that IsValid works on. | |
-- | |
if ( IsValid( k ) ) then | |
-- | |
-- If the object is valid - pass it as the first argument ( self ) | |
-- | |
a, b, c, d, e, f = v( k, ... ) | |
else | |
-- | |
-- If the object has become invalid - remove it | |
-- | |
HookTable[ k ] = nil | |
end | |
end | |
-- | |
-- Hook returned a value - it overrides the gamemode function | |
-- | |
if ( a != nil ) then | |
return a, b, c, d, e, f | |
end | |
end | |
end | |
-- | |
-- Call the gamemode function | |
-- | |
if ( !gm ) then return end | |
local GamemodeFunction = gm[ name ] | |
if ( GamemodeFunction == nil ) then return end | |
return GamemodeFunction( gm, ... ) | |
end | |
local function ConcatTable( t, sep ) | |
local r = {} | |
for _, v in ipairs( t ) do | |
table.insert( r, tostring( v ) ) | |
end | |
return table.concat( r, sep ) | |
end | |
local active = false | |
local info = {} | |
local rendering = false | |
local currentindex = 0 | |
local retindex = 1 | |
local retval = nil | |
local red = Color( 255, 0, 0 ) | |
local green = Color( 0, 255, 0 ) | |
local white = Color( 255, 255, 255 ) | |
local black = Color( 0, 0, 0 ) | |
local function CustomCall( name, ... ) | |
if not active then return OrigCall( name, ... ) end | |
local ret = { OrigCall( name, ... ) } | |
if name == "PreRender" then -- "PreRender" then | |
rendering = true | |
currentindex = 0 | |
info = {} | |
end | |
if rendering then | |
currentindex = currentindex + 1 | |
table.insert( info, { rt = render.GetRenderTarget(), name = name, output = ConcatTable( ret, ", " ) } ) | |
end | |
if name == "PostRender" then | |
rendering = false | |
cam.Start2D() | |
local pointercolor = white | |
if retval then | |
pointercolor = green | |
elseif retval == false then | |
pointercolor = red | |
end | |
draw.SimpleTextOutlined( "►", "Trebuchet18", 5, retindex*22 + 10, pointercolor, nil, nil, 1, black ) | |
for i, v in ipairs( info ) do | |
local tcolor = white | |
local outputtext = v.output | |
if i == retindex then | |
tcolor = pointercolor | |
if retval != nil then | |
if outputtext == "" then | |
outputtext = " ( instead of nothing )" | |
else | |
outputtext = " ( instead of: " .. outputtext .. " )" | |
end | |
outputtext = tostring( retval ) .. outputtext | |
end | |
end | |
draw.SimpleTextOutlined( tostring(v.rt), "Trebuchet18", 20, i*22 + 10, tcolor, nil, nil, 1, black ) | |
draw.SimpleTextOutlined( v.name, "Trebuchet18", 250, i*22 + 10, tcolor, nil, nil, 1, black ) | |
draw.SimpleTextOutlined( outputtext, "Trebuchet18", 500, i*22 + 10, tcolor, nil, nil, 1, black ) | |
end | |
cam.End2D() | |
end | |
if retindex == currentindex then | |
currentindex = -1 | |
if retval ~= nil then return retval end | |
end | |
return unpack( ret ) | |
end | |
function Call( ... ) | |
if CLIENT then | |
return CustomCall( ... ) | |
end | |
return OrigCall( ... ) | |
end | |
function SetActive( b ) active = b end | |
function ToggleActive() active = not active end | |
function PointerUp() | |
retindex = math.max( retindex-1, 1 ) | |
retval = nil | |
end | |
function PointerDown() | |
retindex = math.min( retindex+1, 55 ) -- artificial limit because I don't know how to calculate a proper one | |
retval = nil | |
end | |
function ToggleOutput() | |
if not retval then | |
retval = true | |
else | |
retval = false | |
end | |
end | |
-- bind p "lua_run_cl hook.ToggleActive()" | |
-- bind [ "lua_run_cl hook.PointerUp()" | |
-- bind ] "lua_run_cl hook.PointerDown()" | |
-- bind ' "lua_run_cl hook.ToggleOutput()" | |
-- one line: | |
-- bind p "lua_run_cl hook.ToggleActive()" ; bind [ "lua_run_cl hook.PointerUp()" ; bind ] "lua_run_cl hook.PointerDown()" ; bind ' "lua_run_cl hook.ToggleOutput()" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment