• 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://www.facepunch.com/fp/rating/heart.png[/img][img]http://www.facepunch.com/fp/rating/wrench.png[/img]
THANK YOUUUUUu!!!!!!!!!!!!
[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.