mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-06 03:55:32 +03:00
502 lines
13 KiB
C++
502 lines
13 KiB
C++
/*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* In addition, as a special exception, the author gives permission to
|
|
* link the code of this program with the Half-Life Game Engine ("HL
|
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
* respects for all of the code used other than the HL Engine and MODs
|
|
* from Valve. If you modify this file, you may extend this exception
|
|
* to your version of the file, but you are not obligated to do so. If
|
|
* you do not wish to do so, delete this exception statement from your
|
|
* version.
|
|
*
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
|
|
CUtlVector<char *> g_fallbackLocalizationFiles;
|
|
char s_pBaseDir[512];
|
|
bool bLowViolenceBuild;
|
|
|
|
CSysModule *g_pFileSystemModule;
|
|
CreateInterfaceFn g_FileSystemFactory;
|
|
|
|
const char *GetBaseDirectory(void)
|
|
{
|
|
return s_pBaseDir;
|
|
}
|
|
|
|
NOXREF void *GetFileSystemFactory(void)
|
|
{
|
|
NOXREFCHECK;
|
|
|
|
return (void *)g_FileSystemFactory;
|
|
}
|
|
|
|
bool FileSystem_LoadDLL(CreateInterfaceFn filesystemFactory)
|
|
{
|
|
if (!filesystemFactory)
|
|
{
|
|
g_pFileSystemModule = Sys_LoadModule(STDIO_FILESYSTEM_LIB);
|
|
|
|
if (g_pFileSystemModule)
|
|
{
|
|
filesystemFactory = Sys_GetFactory(g_pFileSystemModule);
|
|
}
|
|
}
|
|
|
|
if (filesystemFactory)
|
|
{
|
|
g_FileSystemFactory = filesystemFactory;
|
|
|
|
g_pFileSystem = (IFileSystem *)filesystemFactory(FILESYSTEM_INTERFACE_VERSION, 0);
|
|
return g_pFileSystem != NULL;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FileSystem_UnloadDLL(void)
|
|
{
|
|
if (g_pFileSystemModule)
|
|
{
|
|
Sys_UnloadModule((CSysModule *)g_pFileSystemModule);
|
|
g_pFileSystemModule = NULL;
|
|
g_FileSystemFactory = NULL;
|
|
g_pFileSystem = NULL;
|
|
}
|
|
}
|
|
|
|
bool BEnabledHDAddon(void)
|
|
{
|
|
if (COM_CheckParm("-nohdmodels"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return (registry->ReadInt("hdmodels", 1) > 0);
|
|
}
|
|
|
|
bool BEnableAddonsFolder(void)
|
|
{
|
|
if (COM_CheckParm("-addons"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return (registry->ReadInt("addons_folder", 0) > 0);
|
|
}
|
|
|
|
void Host_SetHDModels_f(void)
|
|
{
|
|
if (g_pcls.state && Cmd_Argc() == 2)
|
|
{
|
|
bool bEnabled = (registry->ReadInt("hdmodels", 1) > 0);
|
|
|
|
registry->WriteInt("hdmodels", !Q_stricmp(Cmd_Argv(1), "1") ? 1 : 0);
|
|
|
|
if (bEnabled != BEnabledHDAddon())
|
|
{
|
|
COM_SetupDirectories();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Host_SetAddonsFolder_f(void)
|
|
{
|
|
if (g_pcls.state && Cmd_Argc() == 2)
|
|
{
|
|
bool bEnabled = (registry->ReadInt("addons_folder", 0) > 0);
|
|
|
|
registry->WriteInt("addons_folder", !Q_stricmp(Cmd_Argv(1), "1") ? 1 : 0);
|
|
|
|
if (bEnabled != BEnableAddonsFolder())
|
|
{
|
|
COM_SetupDirectories();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Host_SetVideoLevel_f(void)
|
|
{
|
|
if (g_pcls.state && Cmd_Argc() == 2)
|
|
{
|
|
registry->WriteInt("vid_level", !Q_stricmp(Cmd_Argv(1), "1") ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
int Host_GetVideoLevel(void)
|
|
{
|
|
return registry->ReadInt("vid_level", 0);
|
|
}
|
|
|
|
void CheckLiblistForFallbackDir(const char *pGameDir, bool bLanguage, const char *pLanguage, bool bLowViolenceBuild_)
|
|
{
|
|
char szTemp[512];
|
|
FileHandle_t hFile;
|
|
|
|
Q_snprintf(szTemp, sizeof(szTemp) - 1, "%s/liblist.gam", pGameDir);
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->GetLocalCopy(szTemp);
|
|
|
|
if (Q_stricmp(com_gamedir, pGameDir))
|
|
{
|
|
Q_snprintf(szTemp, 511, "../%s/liblist.gam", pGameDir);
|
|
COM_FixSlashes(szTemp);
|
|
hFile = FS_Open(szTemp, "rt");
|
|
}
|
|
else
|
|
hFile = FS_Open("liblist.gam", "rt");
|
|
|
|
if (!hFile)
|
|
return;
|
|
|
|
if (FS_EndOfFile(hFile))
|
|
{
|
|
FS_Close(hFile);
|
|
return;
|
|
}
|
|
|
|
char szFallback[128];
|
|
char szLine[512];
|
|
|
|
char *end;
|
|
char *start;
|
|
int bytesToCopy;
|
|
|
|
while (1)
|
|
{
|
|
szLine[0] = 0;
|
|
FS_ReadLine(szLine, sizeof(szLine) - 1, hFile);
|
|
szLine[511] = 0;
|
|
if (!Q_strnicmp(szLine, "fallback_dir", Q_strlen("fallback_dir")))
|
|
{
|
|
start = Q_strchr(szLine, '"');
|
|
if (!start)
|
|
{
|
|
FS_Close(hFile);
|
|
return;
|
|
}
|
|
|
|
end = Q_strchr(start + 1, '"');
|
|
if (!end)
|
|
{
|
|
FS_Close(hFile);
|
|
return;
|
|
}
|
|
|
|
bytesToCopy = (int)(end - start) - 1;
|
|
if (bytesToCopy > sizeof(szFallback) - 2)
|
|
{
|
|
FS_Close(hFile);
|
|
return;
|
|
}
|
|
|
|
if (bytesToCopy > 0)
|
|
break;
|
|
}
|
|
if (FS_EndOfFile(hFile))
|
|
{
|
|
FS_Close(hFile);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Q_strncpy(szFallback, start + 1, bytesToCopy);
|
|
szFallback[bytesToCopy] = 0;
|
|
|
|
if (!Q_stricmp(pGameDir, szFallback) )
|
|
{
|
|
FS_Close(hFile);
|
|
return;
|
|
}
|
|
if (bLowViolenceBuild)
|
|
{
|
|
Q_snprintf(szTemp, 511, "%s/%s_lv", GetBaseDirectory(), szFallback);
|
|
szTemp[511] = 0;
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->AddSearchPathNoWrite(szTemp, "GAME_FALLBACK");
|
|
}
|
|
if (BEnableAddonsFolder())
|
|
{
|
|
Q_snprintf(szTemp, 511, "%s/%s_addon", GetBaseDirectory(), szFallback);
|
|
szTemp[511] = 0;
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->AddSearchPathNoWrite(szTemp, "GAME_FALLBACK");
|
|
}
|
|
|
|
if (bLanguage && pLanguage)
|
|
{
|
|
char baseDir[4096];
|
|
char *tempPtr;
|
|
|
|
Q_snprintf(szTemp, 511, "%s/%s_%s", GetBaseDirectory(), szFallback, pLanguage);
|
|
szTemp[511] = 0;
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->AddSearchPath(szTemp, "GAME_FALLBACK");
|
|
|
|
if (!COM_CheckParm("-steam"))
|
|
{
|
|
Q_strncpy(baseDir, GetBaseDirectory(), sizeof(baseDir) - 1);
|
|
baseDir[sizeof(baseDir) - 1] = 0;
|
|
|
|
tempPtr = Q_strstr(baseDir, "\\game");
|
|
if (tempPtr)
|
|
{
|
|
*tempPtr = 0;
|
|
|
|
Q_snprintf(szTemp, 511, "%s\\localization\\%s_%s", baseDir, szFallback, pLanguage);
|
|
szTemp[511] = 0;
|
|
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->AddSearchPath(szTemp, "GAME_FALLBACK");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (BEnabledHDAddon())
|
|
{
|
|
Q_snprintf(szTemp, 511, "%s/%s_hd", GetBaseDirectory(), szFallback);
|
|
szTemp[511] = 0;
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->AddSearchPathNoWrite(szTemp, "GAME_FALLBACK");
|
|
}
|
|
|
|
Q_snprintf(szTemp, 511, "%s/%s", GetBaseDirectory(), szFallback);
|
|
szTemp[511] = 0;
|
|
COM_FixSlashes(szTemp);
|
|
g_pFileSystem->AddSearchPath(szTemp, "GAME_FALLBACK");
|
|
|
|
if (Q_stricmp(szFallback, "valve"))
|
|
{
|
|
const int BufLen = 128;
|
|
char *szFileName = new char[BufLen];
|
|
|
|
Q_snprintf(szFileName, BufLen - 1, "Resource/%s_%%language%%.txt", szFallback);
|
|
szFileName[BufLen - 1] = 0;
|
|
|
|
g_fallbackLocalizationFiles.AddToTail(szFileName);
|
|
CheckLiblistForFallbackDir(szFallback, bLanguage, pLanguage, bLowViolenceBuild);
|
|
}
|
|
FS_Close(hFile);
|
|
}
|
|
|
|
int FileSystem_SetGameDirectory(const char *pDefaultDir, const char *pGameDir)
|
|
{
|
|
char temp[512];
|
|
char language[256];
|
|
const char *pchLang;
|
|
|
|
g_pFileSystem->RemoveAllSearchPaths();
|
|
language[0] = 0;
|
|
|
|
if (!bLowViolenceBuild)
|
|
{
|
|
if (CRehldsPlatformHolder::get()->SteamApps() && GetGameAppID() == 70)
|
|
{
|
|
bLowViolenceBuild = CRehldsPlatformHolder::get()->SteamApps()->BIsLowViolence();
|
|
}
|
|
}
|
|
|
|
pchLang = CRehldsPlatformHolder::get()->SteamApps() ? CRehldsPlatformHolder::get()->SteamApps()->GetCurrentGameLanguage() : NULL;
|
|
Q_strncpy(language, pchLang ? pchLang : "english", ARRAYSIZE(language));
|
|
#ifdef REHLDS_CHECKS
|
|
language[ARRAYSIZE(language) - 1] = 0;
|
|
#endif
|
|
|
|
if (!g_bIsDedicatedServer && !IsGameSubscribed(pGameDir))
|
|
return 0;
|
|
|
|
CRehldsPlatformHolder::get()->SteamAPI_SetBreakpadAppID(GetGameAppID());
|
|
|
|
bool bEnableHDPack = BEnabledHDAddon();
|
|
bool bLanguage = (Q_strlen(language) != 0 && Q_stricmp(language, "english")) ? true : false;
|
|
|
|
if (!pGameDir)
|
|
pGameDir = pDefaultDir;
|
|
|
|
if (pGameDir)
|
|
{
|
|
if (bLowViolenceBuild)
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_lv", GetBaseDirectory(), pGameDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "GAME");
|
|
}
|
|
if (BEnableAddonsFolder())
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_addon", GetBaseDirectory(), pGameDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "GAME");
|
|
}
|
|
if (bLanguage)
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_%s", GetBaseDirectory(), pGameDir, language);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "GAME");
|
|
|
|
if (!COM_CheckParm("-steam"))
|
|
{
|
|
char baseDir[MAX_PATH];
|
|
Q_strncpy(baseDir, GetBaseDirectory(), sizeof(baseDir) - 1);
|
|
baseDir[sizeof(baseDir) - 1] = 0;
|
|
char* tempPtr = Q_strstr(baseDir, "\\game");
|
|
if (tempPtr)
|
|
{
|
|
*tempPtr = 0;
|
|
Q_snprintf(temp, 511, "%s\\localization\\%s_%s", baseDir, pGameDir, language);
|
|
temp[511] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "GAME");
|
|
}
|
|
}
|
|
}
|
|
if (bEnableHDPack)
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_hd", GetBaseDirectory(), pGameDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "GAME");
|
|
}
|
|
|
|
Q_snprintf(temp, 511, "%s/%s", GetBaseDirectory(), pGameDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPath(temp, "GAME");
|
|
g_pFileSystem->AddSearchPath(temp, "GAMECONFIG");
|
|
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_downloads", GetBaseDirectory(), pGameDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPath(temp, "GAMEDOWNLOAD");
|
|
|
|
CheckLiblistForFallbackDir(pGameDir, bLanguage, language, bLowViolenceBuild);
|
|
}
|
|
if (bLanguage)
|
|
{
|
|
if (bLowViolenceBuild)
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_lv", GetBaseDirectory(), pDefaultDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "DEFAULTGAME");
|
|
}
|
|
|
|
if (BEnableAddonsFolder())
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_addon", GetBaseDirectory(), pDefaultDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "DEFAULTGAME");
|
|
}
|
|
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_%s", GetBaseDirectory(), pDefaultDir, language);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "DEFAULTGAME");
|
|
if (!COM_CheckParm("-steam"))
|
|
{
|
|
char baseDir[MAX_PATH];
|
|
|
|
Q_strncpy(baseDir, GetBaseDirectory(), sizeof(baseDir) - 1);
|
|
baseDir[sizeof(baseDir) - 1] = 0;
|
|
char* tempPtr = Q_strstr(baseDir, "\\game");
|
|
if (tempPtr)
|
|
{
|
|
*tempPtr = 0;
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s\\localization\\%s_%s", baseDir, pDefaultDir, language);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "DEFAULTGAME");
|
|
}
|
|
}
|
|
}
|
|
if (bEnableHDPack)
|
|
{
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s_hd", GetBaseDirectory(), pDefaultDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "DEFAULTGAME");
|
|
}
|
|
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s", GetBaseDirectory());
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPath(temp, "BASE");
|
|
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/%s", GetBaseDirectory(), pDefaultDir);
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPathNoWrite(temp, "DEFAULTGAME");
|
|
|
|
Q_snprintf(temp, sizeof(temp) - 1, "%s/platform", GetBaseDirectory());
|
|
temp[sizeof(temp) - 1] = 0;
|
|
COM_FixSlashes(temp);
|
|
g_pFileSystem->AddSearchPath(temp, "PLATFORM");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
int FileSystem_AddFallbackGameDir(const char *pGameDir)
|
|
{
|
|
char language[128];
|
|
|
|
const char * pchLang = CRehldsPlatformHolder::get()->SteamApps() ? CRehldsPlatformHolder::get()->SteamApps()->GetCurrentGameLanguage() : NULL;
|
|
Q_strncpy(language, pchLang ? pchLang : "english", ARRAYSIZE(language));
|
|
#ifdef REHLDS_CHECKS
|
|
language[ARRAYSIZE(language) - 1] = 0;
|
|
#endif
|
|
|
|
if (Q_strlen(language) != 0 && Q_stricmp(language, "english"))
|
|
{
|
|
char temp[MAX_PATH];
|
|
Q_sprintf(temp, "%s/%s_%s", GetBaseDirectory(), pGameDir, language);
|
|
g_pFileSystem->AddSearchPath(temp, "GAME");
|
|
}
|
|
g_pFileSystem->AddSearchPath(pGameDir, "GAME");
|
|
return 1;
|
|
}
|
|
|
|
int FileSystem_Init(char *basedir, void *voidfilesystemFactory)
|
|
{
|
|
#ifdef REHLDS_CHECKS
|
|
Q_strncpy(s_pBaseDir, basedir, ARRAYSIZE(s_pBaseDir));
|
|
s_pBaseDir[ARRAYSIZE(s_pBaseDir) - 1] = 0;
|
|
#else
|
|
Q_strcpy(s_pBaseDir, basedir);
|
|
#endif
|
|
|
|
host_parms.basedir = s_pBaseDir;
|
|
|
|
if (FileSystem_LoadDLL((CreateInterfaceFn)voidfilesystemFactory))
|
|
{
|
|
return COM_SetupDirectories() != 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void FileSystem_Shutdown(void)
|
|
{
|
|
FS_RemoveAllSearchPaths();
|
|
FileSystem_UnloadDLL();
|
|
}
|