Skip to content

Commit

Permalink
Merge remote-tracking branch 'HalfLife_Updated/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
SamVanheer committed Jan 7, 2024
2 parents 9530bc8 + 1dd67a8 commit 860342d
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 12 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ All changes from Half-Life Updated up until Beta 5 are included.

# Half-Life Updated changelog

## Changes in V1.0.0 Release Candidate 004

### Bug fixes

* Disabled GCC optimization that prevents mod dlls from unloading after engine calls dlclose
* Fixed third party libraries possibly not being linked to when building Linux server dll (Thanks a1batross)

### Features

* Mods made with this SDK will now shut down if they detect they are being run from a Valve game directory (e.g. by placing the dlls in `Half-Life/valve/cl_dlls` and `Half-Life/valve/dlls`). This is not supported and puts users at risk of being VAC banned. Run mods from their intended location only

## Changes in V1.0.0 Release Candidate 003

### Bug fixes
Expand Down
32 changes: 28 additions & 4 deletions cl_dll/cdll_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// this implementation handles the linking of the engine to the DLL
//

#include <SDL2/SDL_messagebox.h>

#include "hud.h"
#include "cl_util.h"
#include "netadr.h"
Expand Down Expand Up @@ -108,6 +110,28 @@ void DLLEXPORT HUD_PlayerMove(struct playermove_s* ppmove, int server)
PM_Move(ppmove, server);
}

static bool CL_InitClient()
{
EV_HookEvents();
CL_LoadParticleMan();

if (!FileSystem_LoadFileSystem())
{
return false;
}

if (UTIL_IsValveGameDirectory())
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error",
"This mod has detected that it is being run from a Valve game directory which is not supported\n"
"Run this mod from its intended location\n\nThe game will now shut down", nullptr);
return false;
}

// get tracker interface, if any
return true;
}

int DLLEXPORT Initialize(cl_enginefunc_t* pEnginefuncs, int iVersion)
{
gEngfuncs = *pEnginefuncs;
Expand All @@ -119,15 +143,15 @@ int DLLEXPORT Initialize(cl_enginefunc_t* pEnginefuncs, int iVersion)

memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t));

EV_HookEvents();
CL_LoadParticleMan();
const bool result = CL_InitClient();

if (!FileSystem_LoadFileSystem())
if (!result)
{
gEngfuncs.Con_DPrintf("Error initializing client\n");
gEngfuncs.pfnClientCmd("quit\n");
return 0;
}

// get tracker interface, if any
return 1;
}

Expand Down
20 changes: 19 additions & 1 deletion dlls/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,23 @@ cvar_t sk_player_leg3 = {"sk_player_leg3", "1"};

// END Cvars for Skill Level settings

static bool SV_InitServer()
{
if (!FileSystem_LoadFileSystem())
{
return false;
}

if (UTIL_IsValveGameDirectory())
{
g_engfuncs.pfnServerPrint("This mod has detected that it is being run from a Valve game directory which is not supported\n"
"Run this mod from its intended location\n\nThe game will now shut down\n");
return false;
}

return true;
}

// Register your console variables here
// This gets called one time when the game is initialied
void GameDLLInit()
Expand All @@ -465,8 +482,9 @@ void GameDLLInit()
g_footsteps = CVAR_GET_POINTER("mp_footsteps");
g_psv_cheats = CVAR_GET_POINTER("sv_cheats");

if (!FileSystem_LoadFileSystem())
if (!SV_InitServer())
{
g_engfuncs.pfnServerPrint("Error initializing server\n");
//Shut the game down as soon as possible.
SERVER_COMMAND("quit\n");
return;
Expand Down
44 changes: 38 additions & 6 deletions game_shared/filesystem_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ static CSysModule* g_pFileSystemModule = nullptr;
// The engine's filesystem doesn't provide functions to do this so we have to work around it.
static std::string g_GameDirectory;
static std::string g_ModDirectory;
static std::string g_ModDirectoryName;

static bool FileSystem_InitializeGameDirectory()
{
Expand Down Expand Up @@ -97,18 +98,17 @@ static bool FileSystem_InitializeGameDirectory()

gameDirectory.shrink_to_fit();

std::string modDirectory;
modDirectory.resize(BufferSize);
g_ModDirectoryName.resize(BufferSize);

#ifdef CLIENT_DLL
modDirectory = gEngfuncs.pfnGetGameDirectory();
g_ModDirectoryName = gEngfuncs.pfnGetGameDirectory();
#else
g_engfuncs.pfnGetGameDir(modDirectory.data());
modDirectory.resize(std::strlen(modDirectory.c_str()));
g_engfuncs.pfnGetGameDir(g_ModDirectoryName.data());
g_ModDirectoryName.resize(std::strlen(g_ModDirectoryName.c_str()));
#endif

g_GameDirectory = std::move(gameDirectory);
g_ModDirectory = g_GameDirectory + DefaultPathSeparatorChar + modDirectory;
g_ModDirectory = g_GameDirectory + DefaultPathSeparatorChar + g_ModDirectoryName;

return true;
}
Expand Down Expand Up @@ -181,6 +181,11 @@ void FileSystem_FreeFileSystem()
}
}

const std::string& FileSystem_GetModDirectoryName()
{
return g_ModDirectoryName;
}

void FileSystem_FixSlashes(std::string& fileName)
{
std::replace(fileName.begin(), fileName.end(), AlternatePathSeparatorChar, DefaultPathSeparatorChar);
Expand Down Expand Up @@ -310,3 +315,30 @@ bool FileSystem_WriteTextToFile(const char* fileName, const char* text, const ch

return false;
}

constexpr const char* ValveGameDirectoryPrefixes[] =
{
"valve",
"gearbox",
"bshift",
"ricochet",
"dmc",
"cstrike",
"czero", // Also covers Deleted Scenes (czeror)
"dod",
"tfc"};

bool UTIL_IsValveGameDirectory()
{
const std::string& modDirectoryName = FileSystem_GetModDirectoryName();

for (const auto prefix : ValveGameDirectoryPrefixes)
{
if (strnicmp(modDirectoryName.c_str(), prefix, strlen(prefix)) == 0)
{
return true;
}
}

return false;
}
11 changes: 11 additions & 0 deletions game_shared/filesystem_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ inline IFileSystem* g_pFileSystem = nullptr;
bool FileSystem_LoadFileSystem();
void FileSystem_FreeFileSystem();

/**
* @brief Returns the mod directory name. Only valid to call after calling FileSystem_LoadFileSystem.
*/
const std::string& FileSystem_GetModDirectoryName();

/**
* @brief Replaces occurrences of ::AlternatePathSeparatorChar with ::DefaultPathSeparatorChar.
*/
Expand Down Expand Up @@ -102,6 +107,12 @@ std::vector<std::byte> FileSystem_LoadFileIntoBuffer(const char* fileName, FileC
*/
bool FileSystem_WriteTextToFile(const char* fileName, const char* text, const char* pathID = nullptr);

/**
* @brief Returns @c true if the current game directory is that of a Valve game.
* Any directory whose name starts with that of a Valve game's directory name is considered to be one, matching Steam's behavior.
*/
bool UTIL_IsValveGameDirectory();

/**
* @brief Helper class to automatically close the file handle associated with a file.
*/
Expand Down
2 changes: 1 addition & 1 deletion linux/Makefile.hldll
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ dirs:
-mkdir -p $(COMMON_OBJ_DIR)

hl.$(SHLIBEXT): $(HLDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS)
$(CPLUS) $(LDFLAGS) $(CPP_LIB) $(SHLIBLDFLAGS) -o $(BUILD_DIR)/$@ $(HLDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS)
$(CPLUS) $(LDFLAGS) $(SHLIBLDFLAGS) -o $(BUILD_DIR)/$@ $(HLDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(CPP_LIB)
./gendbg.sh $(BUILD_DIR)/hl.$(SHLIBEXT)

$(HLDLL_OBJ_DIR)/%.o : $(HLDLL_SRC_DIR)/%.cpp
Expand Down

0 comments on commit 860342d

Please sign in to comment.