Skip to content
Merged
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
105 changes: 65 additions & 40 deletions src/game/client/swarm/rd_png_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vgui_controls/Controls.h>
#include <vgui/ISurface.h>
#include "vpklib/packedstore.h"
#include "fmtstr.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
Expand Down Expand Up @@ -84,59 +85,83 @@ void CRD_PNG_Texture::SetRotation( int iRotation )
{
}

void CRD_PNG_Texture::CleanLocalCachedTextures( const char *szDirectory )
void CRD_PNG_Texture::CleanLocalCachedTextures(const char* szDirectory)
{
// Delete textures that are in the local cache folder but also in pak01_vpk.dir.
//
// This can happen if an item is added to the schema and seen in-game before the
// update that adds the pre-cached texture to the game's files is released.
//
// We don't check mods (so replacing an item icon in an addon doesn't affect this)
// (The "MOD" path below refers to a Source Engine game's raw files, not addons.)

// Don't do this if we are loading the VPK with lower priority than loose files.
if ( CommandLine()->FindParm( "-override_vpk" ) )
if (CommandLine()->FindParm("-override_vpk"))
return;

static CPackedStore pak01{ "pak01", g_pFullFileSystem };
static CPackedStore pak02{ "pak02", g_pFullFileSystem };
static char szGameRootPath[MAX_PATH];
static bool bPathInitialized = false;

// Add the materials/ prefix here so we match the directory naming scheme in Init.
char szFullDirectory[MAX_PATH];
V_snprintf( szFullDirectory, sizeof( szFullDirectory ), "materials/%s", szDirectory );

// Do a separate pass for materials and for textures just in case the user already
// deleted one or something went wrong during generation.
char szMaterialWildcard[MAX_PATH], szTextureWildcard[MAX_PATH];
V_snprintf( szMaterialWildcard, sizeof( szMaterialWildcard ), "%s/*.vmt", szFullDirectory );
V_snprintf( szTextureWildcard, sizeof( szTextureWildcard ), "%s/*.vtf", szFullDirectory );

FileFindHandle_t hFind = FILESYSTEM_INVALID_FIND_HANDLE;
for ( const char *szName = g_pFullFileSystem->FindFirstEx( szMaterialWildcard, "MOD", &hFind ); szName; szName = g_pFullFileSystem->FindNext( hFind ) )
if (!bPathInitialized)
{
char szVerifyPath[MAX_PATH];
V_snprintf( szVerifyPath, sizeof( szVerifyPath ), "%s/%s", szFullDirectory, szName );

if ( pak01.OpenFile( szVerifyPath ) )
const char* szGameInfoPath = "gameinfo.txt";
if (g_pFullFileSystem->FileExists(szGameInfoPath, "MOD"))
{
char szFullPath[MAX_PATH];
g_pFullFileSystem->RelativePathToFullPath(szGameInfoPath, "MOD", szFullPath, sizeof(szFullPath));
V_ExtractFilePath(szFullPath, szGameRootPath, sizeof(szGameRootPath));
V_FixSlashes(szGameRootPath);
V_AppendSlash(szGameRootPath, sizeof(szGameRootPath));
bPathInitialized = true;
}
else
{
Msg( "Removing local cached file %s\n", szVerifyPath );
g_pFullFileSystem->RemoveFile( szVerifyPath, "MOD" );
return;
}
}
g_pFullFileSystem->FindClose( hFind );

for ( const char *szName = g_pFullFileSystem->FindFirstEx( szTextureWildcard, "MOD", &hFind ); szName; szName = g_pFullFileSystem->FindNext( hFind ) )
{
char szVerifyPath[MAX_PATH];
V_snprintf( szVerifyPath, sizeof( szVerifyPath ), "%s/%s", szFullDirectory, szName );
static CPackedStore s_pak01(CFmtStr("%spak01", szGameRootPath), g_pFullFileSystem);
static CPackedStore s_pak02(CFmtStr("%spak02", szGameRootPath), g_pFullFileSystem);

struct CleanupRule {
std::initializer_list<const char*> extensions;
std::initializer_list<CPackedStore*> targetPaks;
};

const std::initializer_list<CleanupRule> cleanupRules = {
{ {".vtf"}, {&s_pak02} },
{ {".vmt"}, {&s_pak01} },
};

if ( pak02.OpenFile( szVerifyPath ) )
char szBasePath[MAX_PATH];
V_ComposeFileName("materials", szDirectory, szBasePath, sizeof(szBasePath));
V_FixSlashes(szBasePath);
V_AppendSlash(szBasePath, sizeof(szBasePath));

for (const auto& rule : cleanupRules)
{
for (const char* szExtension : rule.extensions)
{
Msg( "Removing local cached file %s\n", szVerifyPath );
g_pFullFileSystem->RemoveFile( szVerifyPath, "MOD" );
char szWildcard[MAX_PATH];
V_ComposeFileName(szBasePath, CFmtStr("*%s", szExtension), szWildcard, sizeof(szWildcard));

FileFindHandle_t hFind;
for (const char* szFilename = g_pFullFileSystem->FindFirstEx(szWildcard, "MOD", &hFind);
szFilename;
szFilename = g_pFullFileSystem->FindNext(hFind))
{
char szVerifyPath[MAX_PATH];
V_ComposeFileName(szBasePath, szFilename, szVerifyPath, sizeof(szVerifyPath));

for (CPackedStore* pPak : rule.targetPaks)
{
if (pPak->OpenFile(szVerifyPath))
{
char szFullPath[MAX_PATH];
if (g_pFullFileSystem->RelativePathToFullPath(szVerifyPath, "MOD", szFullPath, sizeof(szFullPath)) &&
g_pFullFileSystem->FileExists(szFullPath))
{
Msg("[Cleanup] Removing: %s\n", szFullPath);
g_pFullFileSystem->RemoveFile(szFullPath);
break;
}
}
}
}
g_pFullFileSystem->FindClose(hFind);
}
}
g_pFullFileSystem->FindClose( hFind );
}

bool CRD_PNG_Texture::Init( const char *szDirectory, uint32_t iHash, bool bForceLoadRemote )
Expand Down