Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimization: initialize game directory only once and assign personal ID to it #550

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
338 changes: 141 additions & 197 deletions BunnymodXT/discord_integration.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions BunnymodXT/discord_integration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ namespace discord_integration
{"bschapter3", "Captive Freight"},
{"bschapter4", "Focal Point"},
{"bschapter5", "Power Struggle"},
{"bschapter6", "Captive Freight"},
{"bschapter6", "Captive Freight / A Leap of Faith"},
{"bschapter7", "Outro"},
{"bschapter8", "Hazard Course"},
{"bschapter9", "Living Quarters Outbound"},
Expand Down Expand Up @@ -830,7 +830,7 @@ namespace discord_integration
{"paraschool", "hrpchapter10"},
};

const std::unordered_set<std::string> urbicide_maps {
const std::unordered_set<std::string_view> urbicide_maps {
"urbicide1"s,
"urbicide2"s,
"urbicide3"s,
Expand Down
161 changes: 160 additions & 1 deletion BunnymodXT/helper_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace helper_functions
{
auto &cl = ClientDLL::GetInstance();
auto &sv = ServerDLL::GetInstance();
auto &hw = HwDLL::GetInstance();

void com_fixslashes(std::string &str)
{
// https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/game_shared/bot/nav_file.cpp#L680
Expand Down Expand Up @@ -44,7 +48,6 @@ namespace helper_functions
void disable_vsync()
{
#ifdef _WIN32
auto &hw = HwDLL::GetInstance();
if (hw.check_vsync)
{
const bool bxtDisableVSync = getenv("BXT_DISABLE_VSYNC");
Expand All @@ -60,4 +63,160 @@ namespace helper_functions
}
#endif
}

void _com_filebase(const char *in, int &len, int &start)
{
int end;

len = strlen(in);

// Scan backward for '.'
end = len - 1;
while (end && in[end] != '.' && in[end] != '/' && in[end] != '\\')
end--;

if (in[end] != '.') // No '.', copy to end
end = len - 1;
else
end--; // Found ',', copy to left of '.'

// Scan backward for '/'
start = len - 1;
while (start >= 0 && in[start] != '/' && in[start] != '\\')
start--;

if (in[start] != '/' && in[start] != '\\')
start = 0;
else
start++;

// Length of new string
len = end - start + 1;
}

void com_filebase(const char *in, char *out)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed in regular char form?

{
int len, start;
_com_filebase(in, len, start);
strncpy(out, &in[start], len);
out[len] = 0;
}

void com_filebase(const char *in, std::string &out)
{
int len, start;
_com_filebase(in, len, start);
out = std::string(&in[start], len);
}

void convert_to_lowercase(const char *str)
{
unsigned char *str_lw = (unsigned char *)str;
while (*str_lw)
{
*str_lw = tolower(*str_lw);
str_lw++;
}
}

void convert_to_lowercase(std::string &str)
{
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return tolower(c); });
}

double ret_bxt_time()
{
const auto& gt = CustomHud::GetTime();
return (gt.hours * 60 * 60) + (gt.minutes * 60) + gt.seconds + (gt.milliseconds / 1000);
}

void reset_gamedir()
{
hw.gamedir.clear();
hw.gamedir_lw.clear();
hw.GameDirMatchID = hw.GameDirStartsWithID = -1;
}

void set_gamedir_starts_with()
{
#define FIND_GAMEDIR_STARTS_WITH(name, id) \
if (!hw.GetGameDir().compare(0, sizeof(#name) - 1, #name)) \
{ \
hw.GameDirStartsWithID = BXT_CONCAT(GAMEDIR_STARTS_WITH_, id); \
return; \
}

FIND_GAMEDIR_STARTS_WITH(valve, HL)
FIND_GAMEDIR_STARTS_WITH(gearbox, OPFOR)
FIND_GAMEDIR_STARTS_WITH(czeror, CSCZDS)
FIND_GAMEDIR_STARTS_WITH(rewolf, GUNMAN)
FIND_GAMEDIR_STARTS_WITH(hunger, HUNGER)
FIND_GAMEDIR_STARTS_WITH(wantedsp, WANTED)
FIND_GAMEDIR_STARTS_WITH(aomdc, AOMDC)
FIND_GAMEDIR_STARTS_WITH(echoes, ECHOES)
FIND_GAMEDIR_STARTS_WITH(poke646, POKE646)
FIND_GAMEDIR_STARTS_WITH(cryoffear, COF)
FIND_GAMEDIR_STARTS_WITH(paranoia, PARANOIA)
FIND_GAMEDIR_STARTS_WITH(bshift, BSHIFT)

#undef FIND_GAMEDIR_STARTS_WITH
}

void set_gamedir_match()
{
#define FIND_GAMEDIR_MATCH(name, id) \
if (!hw.GetGameDir().compare(#name)) \
{ \
hw.GameDirMatchID = BXT_CONCAT(GAMEDIR_MATCH_, id); \
return; \
}

FIND_GAMEDIR_MATCH(valve, HL)
FIND_GAMEDIR_MATCH(gearbox, OPFOR)
FIND_GAMEDIR_MATCH(czeror, CSCZDS)
FIND_GAMEDIR_MATCH(rewolf, GUNMAN)
FIND_GAMEDIR_MATCH(hunger, HUNGER)
FIND_GAMEDIR_MATCH(wantedsp, WANTED)
FIND_GAMEDIR_MATCH(aomdc, AOMDC)
FIND_GAMEDIR_MATCH(echoes, ECHOES)
FIND_GAMEDIR_MATCH(poke646, POKE646)
FIND_GAMEDIR_MATCH(cryoffear, COF)
FIND_GAMEDIR_MATCH(paranoia, PARANOIA)
FIND_GAMEDIR_MATCH(bshift, BSHIFT)
FIND_GAMEDIR_MATCH(twhltower2, TWHLTOWER2)
FIND_GAMEDIR_MATCH(hl_urbicide, URBICIDE)
FIND_GAMEDIR_MATCH(visitors, VISITORS)
FIND_GAMEDIR_MATCH(hrp, HLRATS_PARASOMNIA)
FIND_GAMEDIR_MATCH(decay, DECAY)
FIND_GAMEDIR_MATCH(caged_fgs, CAGED)
FIND_GAMEDIR_MATCH(hc, HC2)
FIND_GAMEDIR_MATCH(blackops, BLACKOPS)
FIND_GAMEDIR_MATCH(timeline2, TIMELINE2)
FIND_GAMEDIR_MATCH(steamlink, UPLINK)
FIND_GAMEDIR_MATCH(hqtrilogy, HALFQUAKE)
FIND_GAMEDIR_MATCH(azuresheep, AZURESHEEP)
FIND_GAMEDIR_MATCH(shl, HLSWEET)
FIND_GAMEDIR_MATCH(biglolly, BIGLOLLY)
FIND_GAMEDIR_MATCH(lm_txp, TXP)
FIND_GAMEDIR_MATCH(htc, HTC)
FIND_GAMEDIR_MATCH(invasion, INVASION)

// Multiplayer-only games:
FIND_GAMEDIR_MATCH(tfc, MP_TFC)
FIND_GAMEDIR_MATCH(cstrike, MP_CS)
FIND_GAMEDIR_MATCH(czero, MP_CSCZ)
FIND_GAMEDIR_MATCH(dod, MP_DOD)
FIND_GAMEDIR_MATCH(dmc, MP_DMC)
FIND_GAMEDIR_MATCH(ricochet, MP_RICOCHET)

// Less worth mods start here:
FIND_GAMEDIR_MATCH(before, BEFORE)
FIND_GAMEDIR_MATCH(tetsu0_cot, CROWBAROFTIME)
FIND_GAMEDIR_MATCH(minimicus, MINIMICUS)
FIND_GAMEDIR_MATCH(gloom, GLOOM)
FIND_GAMEDIR_MATCH(construction, CONSTRUCTION)
FIND_GAMEDIR_MATCH(plague, PLAGUE)

#undef FIND_GAMEDIR_MATCH
}
};
15 changes: 15 additions & 0 deletions BunnymodXT/helper_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ namespace helper_functions
std::string swap_lib(const char* current_lib_path, std::string new_lib_path, const char *start);
void crash_if_failed(std::string str);
void disable_vsync();
void com_filebase(const char *in, char *out);
void com_filebase(const char *in, std::string &out);

/*
Using lowercase is specifically designed so as not to encounter case sensitivity when comparing to the name of the map or game directory (although game may not be happy about if the runner uses a name that does not match the original case from game files / folders, but the main thing is that on our side there should be no issue with this)
When you checking in code for a game directory or map name, always write the names in lowercase!
*/
void convert_to_lowercase(const char *str);
void convert_to_lowercase(std::string &str);

double ret_bxt_time();

void reset_gamedir();
void set_gamedir_starts_with();
void set_gamedir_match();

inline void allow_multiple_instances() // Make it possible to run multiple Half-Life instances.
{
Expand Down
88 changes: 5 additions & 83 deletions BunnymodXT/modules/ClientDLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1157,84 +1157,6 @@ void ClientDLL::StudioAdjustViewmodelAttachments(Vector &vOrigin)
vOrigin = last_vieworg + vOut;
}

void ClientDLL::FileBase(const char *in, char *out)
{
int len, start, end;

len = strlen(in);

// scan backward for '.'
end = len - 1;
while (0 != end && in[end] != '.' && in[end] != '/' && in[end] != '\\')
end--;

if (in[end] != '.') // no '.', copy to end
end = len - 1;
else
end--; // Found ',', copy to left of '.'

// Scan backward for '/'
start = len - 1;
while (start >= 0 && in[start] != '/' && in[start] != '\\')
start--;

if (in[start] != '/' && in[start] != '\\')
start = 0;
else
start++;

// Length of new sting
len = end - start + 1;

// Copy partial string
strncpy(out, &in[start], len);
// Terminate it
out[len] = 0;
}

void ClientDLL::ConvertToLowerCase(const char *str)
{
unsigned char *str_lw = (unsigned char *)str;
while (*str_lw) {
*str_lw = tolower(*str_lw);
str_lw++;
}
}

bool ClientDLL::DoesGameDirMatch(const char *game)
{
if (!pEngfuncs)
return false;

const char *gameDir = pEngfuncs->pfnGetGameDirectory();
char gd[1024];

if (gameDir && gameDir[0])
{
FileBase(gameDir, gd);
ConvertToLowerCase(gd);
}

return !std::strcmp(gd, game);
}

bool ClientDLL::DoesGameDirContain(const char *game)
{
if (!pEngfuncs)
return false;

const char *gameDir = pEngfuncs->pfnGetGameDirectory();
char gd[1024];

if (gameDir && gameDir[0])
{
FileBase(gameDir, gd);
ConvertToLowerCase(gd);
}

return std::strstr(gd, game);
}

size_t ClientDLL::GetMapName(char* dest, size_t count)
{
auto map_path = pEngfuncs->pfnGetLevelName();
Expand Down Expand Up @@ -1265,7 +1187,7 @@ bool ClientDLL::DoesMapNameMatch(const char *map)
GetMapName(map_name, ARRAYSIZE_HL(map_name));

if (map_name[0])
ConvertToLowerCase(map_name);
helper_functions::convert_to_lowercase(map_name);

return !std::strcmp(map_name, map);
}
Expand All @@ -1280,9 +1202,9 @@ bool ClientDLL::DoesMapNameContain(const char *map)
GetMapName(map_name, ARRAYSIZE_HL(map_name));

if (map_name[0])
ConvertToLowerCase(map_name);
helper_functions::convert_to_lowercase(map_name);

return std::strstr(map_name, map);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? It's called "DoesMapNameContain" not "DoesMapNameStartWith"

return !std::strncmp(map_name, map, strlen(map));
}

void ClientDLL::SetAngleSpeedCap(bool capped)
Expand Down Expand Up @@ -1861,7 +1783,7 @@ HOOK_DEF_1(ClientDLL, void, __cdecl, CStudioModelRenderer__StudioSetupBones_Linu
{
ptrdiff_t offpCurrentEntity_Linux;
ptrdiff_t offpStudioHeader_Linux;
if (DoesGameDirMatch("dod")) {
if (IsGameDirMatch(MP_DOD)) {
offpCurrentEntity_Linux = 52;
offpStudioHeader_Linux = 72;
} else {
Expand Down Expand Up @@ -1988,7 +1910,7 @@ HOOK_DEF_1(ClientDLL, void, __fastcall, CStudioModelRenderer__StudioRenderModel,
HOOK_DEF_1(ClientDLL, void, __cdecl, CStudioModelRenderer__StudioRenderModel_Linux, void*, thisptr)
{
ptrdiff_t offpCurrentEntity_Linux;
if (DoesGameDirMatch("dod"))
if (IsGameDirMatch(MP_DOD))
offpCurrentEntity_Linux = 52;
else
offpCurrentEntity_Linux = 44;
Expand Down
6 changes: 0 additions & 6 deletions BunnymodXT/modules/ClientDLL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ class ClientDLL : public IHookableNameFilter

void StudioAdjustViewmodelAttachments(Vector &vOrigin);

bool DoesGameDirMatch(const char *game);
bool DoesGameDirContain(const char *game);

size_t GetMapName(char* dest, size_t count);
bool DoesMapNameMatch(const char *map);
bool DoesMapNameContain(const char *map);
Expand Down Expand Up @@ -110,9 +107,6 @@ class ClientDLL : public IHookableNameFilter

void SetSpeedScaling(bool scaled);

void FileBase(const char *in, char *out);
void ConvertToLowerCase(const char *str);

void SetupTraceVectors(float start[3], float end[3]);

private:
Expand Down
Loading