Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 62 additions & 23 deletions include/AddonWhiteList.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
#define ADDONWHITELIST_H

#include "Bootil/Bootil.h"
#include "Addon_Util.h"

//
//
//
//
namespace Addon
{
namespace WhiteList
{
static const char* Wildcard[] =
// Entries that start with ! invalidate all previous matches
// Caveat: Order of these now matters
// Ideally Bootil would support something like /**/ for "only one folder" or "no slashes" (or backwards to mimic gitignore)
static const Bootil::BString Allowed[] =
{
"lua/*.lua",
"scenes/*.vcd",
Expand All @@ -35,12 +35,15 @@ namespace Addon
"materials/*.jpeg",
"materials/colorcorrection/*.raw",
"models/*.mdl",
"models/*.vtx",
"models/*.phy",
"models/*.ani",
"models/*.vvd",

"models/*.vtx",

"gamemodes/*/*.txt",
"gamemodes/*/*.fgd",

"gamemodes/*/logo.png",
"gamemodes/*/icon24.png",
"gamemodes/*/gamemode/*.lua",
Expand All @@ -51,10 +54,12 @@ namespace Addon
"gamemodes/*/backgrounds/*.jpg",
"gamemodes/*/backgrounds/*.jpeg",
"gamemodes/*/content/models/*.mdl",
"gamemodes/*/content/models/*.vtx",
"gamemodes/*/content/models/*.phy",
"gamemodes/*/content/models/*.ani",
"gamemodes/*/content/models/*.vvd",

"gamemodes/*/content/models/*.vtx",

"gamemodes/*/content/materials/*.vmt",
"gamemodes/*/content/materials/*.vtf",
"gamemodes/*/content/materials/*.png",
Expand All @@ -76,40 +81,74 @@ namespace Addon

// static version of the data/ folder
// (because you wouldn't be able to modify these)
// We only allow filetypes here that are not already allowed above
"data_static/*.txt",
"data_static/*.dat",
"data_static/*.json",
"data_static/*.xml",
"data_static/*.csv",
"data_static/*.dem",
"data_static/*.vcd",

"data_static/*.vtf",
"data_static/*.vmt",
"data_static/*.png",
"data_static/*.jpg",
"data_static/*.jpeg",
"",
};

"data_static/*.mp3",
"data_static/*.wav",
"data_static/*.ogg",
static const Bootil::BString Blocked[] =
{
"!models/*.sw.vtx", // These variations are unused by the game
"!models/*.360.vtx",
"!models/*.xbox.vtx",

NULL
"!gamemodes/*/*/*.txt", // Only in the root gamemode folder please!
"!gamemodes/*/*/*.fgd",

"!gamemodes/*/content/models/*.sw.vtx",
"!gamemodes/*/content/models/*.360.vtx",
"!gamemodes/*/content/models/*.xbox.vtx",

"",
};

//
// Call on a filename including relative path to determine
// whether file is allowed to be in the addon.
// Call on a filename including relative path to determine whether file is allowed to be in the addon.
// This whitelist only serves to warn about bad files at upload stage - the game has its own whitelist.
//
inline bool Check( const Bootil::BString& strname )
{
bool bValid = false;

for ( int i = 0;; i++ )
for ( int i = 0;; ++i )
{
if ( WhiteList::Allowed[i].empty() ) break;

if ( CheckWildcard( Allowed[i], strname ) )
{
bValid = true;
break;
}
}

for ( int i = 0;; ++i )
{
if ( WhiteList::Blocked[i].empty() ) break;

if ( CheckWildcard( Blocked[i], strname ) )
{
bValid = false;
break;
}
}

if ( !bValid )
{
if ( bValid || WhiteList::Wildcard[i] == NULL ) break;
for ( int i = 0;; ++i )
{
if ( WhiteList::Allowed[i].empty() ) break;

bValid = Bootil::String::Test::Wildcard( Wildcard[i], strname );
if ( CheckWildcard( Allowed[i], strname ) )
{
bValid = true;
break;
}
}
}

return bValid;
Expand Down
178 changes: 178 additions & 0 deletions include/AddonWriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@

#ifndef ADDONWRITER_H
#define ADDONWRITER_H

#include <stdint.h>
#include "Bootil/Bootil.h"
#include "AddonFormat.h"

//
//
//
//
namespace Addon
{
class Writer : public Bootil::AutoBuffer
{
public:

Writer( Bootil::BString strOutput, bool nobuffer )
{
m_usebuffer = !nobuffer;
m_writeblocks = false;
m_output = strOutput;
m_written = 0;

remove( strOutput.c_str() );
m_file.open( strOutput, std::ios::out | std::ios::binary | std::ios::app );
if ( !m_file.is_open() )
{
Bootil::Output::Error( "Failed to open %s!\n", strOutput );
}
}

uint64_t GetWritten()
{
if ( m_usebuffer )
return AutoBuffer::GetWritten() + m_written;

return m_written;
}

bool EnsureCapacity( uint64_t iSize )
{
if ( m_usebuffer )
{
uint64_t max = INT_MAX / 1.5; // ~1.4GB will be ready for the buffer. If we try to use more, it will fail to allocate it for some reason.
if ( iSize > max )
{
m_writeblocks = true;
iSize = max;
}

return AutoBuffer::EnsureCapacity( iSize );
}

return true;
}

void Reset()
{
m_iPos = 0;
m_iWritten = 0;
}

void WriteBuffer( const Bootil::Buffer & bufferOut )
{
if ( m_usebuffer )
{
if ( m_writeblocks && ( this->GetSize() - AutoBuffer::GetWritten() ) <= bufferOut.GetWritten() )
{
m_file.write( reinterpret_cast<char*>( this->GetBase() ), AutoBuffer::GetWritten() );
m_written += AutoBuffer::GetWritten();
Reset();

if ( bufferOut.GetWritten() >= this->GetSize() )
{
m_file.write( reinterpret_cast<char*>( bufferOut.GetBase() ), bufferOut.GetWritten() );
m_written += bufferOut.GetWritten();
}
else
{
AutoBuffer::WriteBuffer( bufferOut );
}
}
else
{
AutoBuffer::WriteBuffer( bufferOut );
}
}
else
{
if ( AutoBuffer::GetWritten() > 0 )
{
m_file.write( reinterpret_cast<char*>( this->GetBase() ), AutoBuffer::GetWritten() );
m_written += AutoBuffer::GetWritten();
Reset();
}

m_file.write( reinterpret_cast<char*>( bufferOut.GetBase() ), bufferOut.GetWritten() );
m_written += bufferOut.GetWritten();
}
}

bool WriteFile()
{
if ( m_usebuffer )
{
if ( m_writeblocks )
{
m_written += AutoBuffer::GetWritten();
m_file.write( reinterpret_cast<char*>( this->GetBase() ), AutoBuffer::GetWritten() );
return true;
}
else
{
return Bootil::File::Write( m_output, *(Bootil::AutoBuffer*)this );
}
}

Close();

return true;
}

uint32_t CRC()
{
if ( !m_usebuffer || m_writeblocks )
return 0;

return Bootil::Hasher::CRC32::Easy( this->GetBase(), this->GetWritten() );
}

void Close()
{
if ( m_usebuffer )
{
AutoBuffer::Clear();
}
else
{
m_file.close();
}
}

Bootil::BString FormatSize() // Bootil::String::Format::Memory has a 2GB limit.
{
uint64_t iBytes = GetWritten();
float gb = iBytes / 1024.0f / 1024.0f / 1024.0f;
if ( gb >= 1.0 )
{
return Bootil::String::Format::Print( "%.1f GB", gb );
}

float mb = iBytes / 1024.0f / 1024.0f;
if ( mb >= 1.0 )
{
return Bootil::String::Format::Print( "%.1f MB", mb );
}

float kb = iBytes / 1024.0f;
if ( kb >= 1.0 )
{
return Bootil::String::Format::Print( "%.1f KB", kb );
}

return Bootil::String::Format::Print( "%i B", iBytes );
}

private:
Bootil::BString m_output;
std::ofstream m_file;
bool m_usebuffer;
bool m_writeblocks;
uint64_t m_written;
};
}

#endif
Loading