gmcl_downloadfilter - Filter for the resource queue
59 replies, posted
‬This module gives you the ability to decide which files you want to download from the downloadables string table. It works in a similar way to the cl_downloadfilter ConVar, except it's not restricted to just sounds and all/none.
You will need to load your code in the menu environment to access the hook.
Return true or nil to let the download through.
[B][U]Example:[/U][/B]
[lua]require("downloadfilter")
hook.Add("ShouldDownload", "DownloadFilter", function(filename)
local ext = string.GetExtensionFromFilename(filename)
if ((ext != "bsp") && (ext != "dua")) then --Filter out everything except the map and the datapack
return false
end
end )[/lua]
[B][U]Changes (GMT):[/U][/B]
[07/06/10, 22:23] - Added Detours/SigScan wrappers to tidy up code a bit
[B][U]Download:[/U][/B]
[url]http://christopherthorne.googlecode.com/svn/trunk/gmcl_downloadfilter/[/url]
How many awesome modules are you still gonna make?
Oh wow, this is really useful, thank you!
Holy shit, awsome!
Brilliant.
Holy shit, that's awesome.
We get nothing new from your for a month or two then out of no where you blow us away with 2 epic modules
Finally!
Now I can make a menu to select the filetypes I don't wanna download.
Not just "No Sounds" or "Nothing".
ShouldDownload_Sig.Init((unsigned char *)"\xF7\x05\x54\xCB\xD2\x0D\x00\x10\x00\x00\x74\x16\x8B\x4C\x24\x04", "xx????xxxxx?xxxx", 16);
How do you find the hex/?x patterns and get at referencing things that aren't exposed normally?
[QUOTE=bringitonbitch;22432996]ShouldDownload_Sig.Init((unsigned char *)"\xF7\x05\x54\xCB\xD2\x0D\x00\x10\x00\x00\x74\x16\x8B\x4C\x24\x04", "xx????xxxxx?xxxx", 16);
How do you find the hex/?x patterns and get at referencing things that aren't exposed normally?[/QUOTE]
Well, first of all I tried hooking to INetChannel::RequestFile, a function that is exposed publicly. This seemed to work fine, except I ran into a major problem - downloads that were filtered stayed in the queue, therefore rendering it useless. I found a hacky workaround by changing the file name requested to something that didn't exist on the client, but if the server didn't have the file it would be spammed with errors + this was pretty dumb anyway.
After that, I tried hooking to the function that processes string table updates (which is also exposed) to prevent filtered files going through. However, I couldn't find an easy way of doing this as the buffer given in the update function was compressed, therefore useless to me. Technically I could have gone through the update function and worked out how it extracted the data, but this would have been a lot more complex than the final result.
I ended up following the use of the cl_downloadfilter ConVar around as I figured this is where the download queue is processed. Eventually I came into a function which returned 1/0 (true/false) and took a file name as its only argument. This isn't ideal and I would have preferred the second attempt to have succeeded, but it works in the same way as cl_downloadfilter and gets the job done without any hacky code.
Finally
[QUOTE=Skondra;22436171]Well, first of all I tried hooking to INetChannel::RequestFile, a function that is exposed publicly. This seemed to work fine, except I ran into a major problem - downloads that were filtered stayed in the queue, therefore rendering it useless. I found a hacky workaround by changing the file name requested to something that didn't exist on the client, but if the server didn't have the file it would be spammed with errors + this was pretty dumb anyway.
After that, I tried hooking to the function that processes string table updates (which [I]is[/I] also exposed) to prevent filtered files going through. However, I couldn't find an easy way of doing this as the buffer given in the update function was encoded/encrypted, therefore useless to me. Technically I could have gone through the update function and worked out how it extracted the data, but this would have been a lot more complex than the final result.
I ended up following the use of the cl_downloadfilter ConVar around as I figured this is where the download queue is processed. Eventually I came into a function which returned 1/0 (true/false) and took a file name as its only argument. This isn't ideal and I would have preferred the second attempt to have succeeded, but it works in the same way as cl_downloadfilter and gets the job done without any hacky code.[/QUOTE]
Mind telling how you get the sigs though?
[QUOTE=Tobba;22448647]Mind telling how you get the sigs though?[/QUOTE]
Through a debugger - I use [url="http://www.ollydbg.de/"]OllyDbg[/url].
[img]http://dl.dropbox.com/u/5766132/Pcwizdan/Screenshots/ScreenShot001.png[/img]
[url=http://www.garrysmod.org/downloads/?a=view&id=101071][img]http://www.garrysmod.org/img/?t=dll&id=101071[/img][/url]
SVN:
[url]http://gmod-downloadfilter-gui.googlecode.com/svn/trunk/[/url]
NOTE: if you can't see it well on my shitty computer's resolution, to open the menu, go to Extensions in your garrysmod main menu. Also please notify me if I forgot an extension that is important (it allows unknown extensions by default).
[QUOTE=Lau;22568230][img]http://dl.dropbox.com/u/5766132/Pcwizdan/Screenshots/ScreenShot001.png[/img]
[url=http://www.garrysmod.org/downloads/?a=view&id=101071][img]http://www.garrysmod.org/img/?t=dll&id=101071[/img][/url]
SVN:
[url]http://gmod-downloadfilter-gui.googlecode.com/svn/trunk/[/url][/QUOTE]
Thanks, you saved me the work.
[QUOTE=Skondra;22436171]Well, first of all I tried hooking to INetChannel::RequestFile, a function that is exposed publicly. This seemed to work fine, except I ran into a major problem - downloads that were filtered stayed in the queue, therefore rendering it useless. I found a hacky workaround by changing the file name requested to something that didn't exist on the client, but if the server didn't have the file it would be spammed with errors + this was pretty dumb anyway.
After that, I tried hooking to the function that processes string table updates (which [I]is[/I] also exposed) to prevent filtered files going through. However, I couldn't find an easy way of doing this as the buffer given in the update function was encoded/encrypted, therefore useless to me. Technically I could have gone through the update function and worked out how it extracted the data, but this would have been a lot more complex than the final result.
I ended up following the use of the cl_downloadfilter ConVar around as I figured this is where the download queue is processed. Eventually I came into a function which returned 1/0 (true/false) and took a file name as its only argument. This isn't ideal and I would have preferred the second attempt to have succeeded, but it works in the same way as cl_downloadfilter and gets the job done without any hacky code.[/QUOTE]
My god. I took the EXACT path you did, except I stopped at paragraph 2 because paragraph 3 never passed my mind back when I tried to accomplish this.
I'm glad you figured it out :smile:
This stopped working after a map change. Just fyi :/ Still really good for those loaded sandbox servers.
[QUOTE=thegrb93;22674514]This stopped working after a map change. Just fyi :/ Still really good for those loaded sandbox servers.[/QUOTE]
It works fine for me. Are you sure it was still loaded?
Yeah, I played a round of zombie survival and the map change made me download all the materials and models. Are you using Lau's script? That is what I am using. I'll just use the original script if that is the problem. I'll get back with results when I can.
[QUOTE=thegrb93;22740884]Yeah, I played a round of zombie survival and the map change made me download all the materials and models. Are you using Lau's script? That is what I am using. I'll just use the original script if that is the problem. I'll get back with results when I can.[/QUOTE]
Are you running the code in the menu environment?
garrysmod/lua/vgui right?
Code in lua/vgui
Module where it should be, and put this ontop of the file:
if ClientsideModel then return end
so it only runs in the menu env
I'll check back when I get to testing. It's really hard to test when I keep getting told "Invalid Steam key size" every time I try joining a server.
Probbably latest update broke it
Figured I would bump this because I recently started using it.
I fixed up the extensions menu code above to work, I guess an update broke it. It will now save your settings forever so you don't have to set it each time you startup gmod.
[lua]require( "downloadfilter" )
local AvailableFilters = {
"dua",
"bsp",
"wav",
"ogg",
"mp3",
"txt",
"mdl",
"phy",
"vtx",
"vvd",
"vtf",
"vmt",
"vcs",
"ini",
"jpg",
"ani",
"ain",
"pcf"
}
local ActiveFilters = {}
for _,filetype in pairs( AvailableFilters ) do
ActiveFilters[ filetype ] = true -- Default all settings to be enabled
end
if file.Exists( "downloadfilter/filters.txt" ) then
for filetype, val in pairs( glon.decode( file.Read( "downloadfilter/filters.txt" ) ) ) do
ActiveFilters[ filetype ] = val
end
end
local PANEL = {}
surface.CreateFont( "Tahoma", 17, 1000, true, false, "LargeBold", false )
function PANEL:Init()
self:Dock( TOP )
self:DockMargin( 1, 1, 1, 0 )
self:SetHeight( 32 )
self.alt = false
self.Label = vgui.Create( "DLabel", self )
self.Label:Dock( LEFT )
self.Label:DockMargin( 16, 0, 0, 0 )
self.Label:SetWidth( 300 )
self.Label:SetFont( "LargeBold" )
self.Label:SetExpensiveShadow( 1, Color( 0, 0, 0, 130 ) )
self.CheckBox = vgui.Create( "DCheckBox", self )
self.CheckBox:Dock( RIGHT )
self.CheckBox:SetWidth( 16 )
self.CheckBox:DockMargin( 10, 8, 10, 8 )
end
function PANEL:Setup( ext, rowid, bool )
self.alt = math.fmod( rowid, 2 ) == 1
self.available = true
self.Label:SetText( ext )
self.CheckBox:SetValue( bool )
function self.CheckBox.OnChange( checkbox, val )
self:UpdateColor()
ActiveFilters[ ext ] = val
file.Write( "downloadfilter/filters.txt", glon.encode( ActiveFilters ) )
end
self:UpdateColor()
end
function PANEL:PerformLayout()
self:UpdateColor()
end
function PANEL:UpdateColor()
self.Label:SetAlpha( 255 )
self.Label:SetColor( Color( 255, 255, 255, 255 ) )
if ( !self.CheckBox:GetChecked() || !self.available ) then
self:SetBackgroundColor( Color( 100, 100, 100, 255 ) )
self.Label:SetColor( Color( 255, 255, 255, 255 ) )
self.Label:SetAlpha( 100 )
elseif ( self.alt ) then
self:SetBackgroundColor( Color( 163, 163, 163, 255 ) )
else
self:SetBackgroundColor( Color( 185, 185, 185, 255 ) )
end
end
local pnlRow = vgui.RegisterTable( PANEL, "DPanel" )
local PANEL = {}
function PANEL:Init()
self:EnableVerticalScrollbar()
self:SetPadding( 1 )
self:DockMargin( 8, 8, 8, 8 )
local label = Label( "Check an extension to allow these file types", self )
label:Dock( BOTTOM )
label:SetContentAlignment( 5 )
label:SetColor( Color( 255, 30, 30 ) )
local savedval = true
for k, v in SortedPairs( AvailableFilters ) do
local row = vgui.CreateFromTable( pnlRow, self )
self:AddItem( row )
savedval = ActiveFilters[ v ]
row:Setup( v, k - 1, savedval )
end
self:Dock( FILL )
end
local pnlDFilter = vgui.RegisterTable( PANEL, "DScrollPanel" )
function debug.getupvalues( f )
local t, i, k, v = {}, 1, debug.getupvalue( f, 1 )
while k do
t[k] = v
i = i+1
k,v = debug.getupvalue( f, i )
end
return t
end
local ExtensionsCMD = debug.getupvalues( concommand.Run ).CommandList["menu_extensions"]
local extensionspanel = nil
if ExtensionsCMD and type( ExtensionsCMD ) == "function" then
ExtensionsCMD()
extensionspanel = debug.getupvalues( ExtensionsCMD ).Extensions
end
if IsValid( extensionspanel ) then
local DownloadFilter = vgui.CreateFromTable( pnlDFilter )
-- HACK RIGHT INTO THAT BITCH
extensionspanel.PropertySheet:AddSheet( Localize( "Download Filter" ), DownloadFilter, "gui/silkicons/box" )
extensionspanel:PerformLayout()
extensionspanel:SetVisible( false )
else
-- Made just for you garry.
Derma_Message( "WARNING: Unable to get extensions panel.\nThis may have been caused by an update that removed this functionality.\nPlease check for updates for mod ( \"Advanced Download Filter\" )", "ERROR: No extensions" )
end
hook.Add( "ShouldDownload", "DownloadFilter", function( filename )
local ext = string.GetExtensionFromFilename( filename:gsub( ".bz2", "" ) ) -- Don't think this issue was ever addressed, the .bz2 was added after the filetype extentsion confusing our filter
if ActiveFilters[ ext ] != nil and ActiveFilters[ ext ] == false then -- Shouldnt ever be nil
--extras.AddText( Color( 255, 174, 201 ), "DownloadFilter", Color( 255, 255, 255 ), ": " .. filename ) -- Print out the blocked file
return false -- Block the download
elseif ActiveFilters[ ext ] == nil or ActiveFilters[ ext ] == true then
return true -- If the filter for a file doesn't exist or if we are allowing it, download
end
end )[/lua]
Thanks alot man! :D
Where are ogg sounds used? :v:
:iiam:
Sorry, you need to Log In to post a reply to this thread.