Skip to content

Commit

Permalink
fix listen server crashes
Browse files Browse the repository at this point in the history
a lot of other things are broken but at least maps load
  • Loading branch information
wootguy committed Nov 10, 2024
1 parent 63448e7 commit 26c6c72
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 17 deletions.
40 changes: 27 additions & 13 deletions dlls/eng_wrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ std::unordered_set<std::string> g_tryPrecacheSounds;
std::unordered_set<std::string> g_tryPrecacheGeneric;
std::unordered_set<std::string> g_tryPrecacheEvents;

std::unordered_map<std::string, string_t> g_allocedStrings;

Bsp g_bsp;

void LoadBsp() {
Expand Down Expand Up @@ -165,7 +167,7 @@ int PRECACHE_GENERIC(const char* path) {

if (g_serveractive) {
if (g_precachedGeneric.find(path) != g_precachedGeneric.end()) {
return g_engfuncs.pfnPrecacheGeneric(path);
return g_engfuncs.pfnPrecacheGeneric(STRING(ALLOC_STRING(path)));
}
else {
ALERT(at_warning, "PrecacheGeneric failed: %s\n", path);
Expand All @@ -184,7 +186,7 @@ int PRECACHE_GENERIC(const char* path) {

if (g_tryPrecacheGeneric.size() < MAX_PRECACHE) {
g_precachedGeneric.insert(path);
return g_engfuncs.pfnPrecacheGeneric(path);
return g_engfuncs.pfnPrecacheGeneric(STRING(ALLOC_STRING(path)));
}
else {
return -1;
Expand Down Expand Up @@ -217,7 +219,7 @@ int PRECACHE_SOUND_ENT(CBaseEntity* ent, const char* path) {

if (g_serveractive) {
if (g_precachedSounds.find(path) != g_precachedSounds.end()) {
return g_engfuncs.pfnPrecacheSound(path);
return g_engfuncs.pfnPrecacheSound(STRING(ALLOC_STRING(path)));
}
else {
ALERT(at_warning, "PrecacheSound failed: %s\n", path);
Expand All @@ -229,7 +231,7 @@ int PRECACHE_SOUND_ENT(CBaseEntity* ent, const char* path) {

if (g_tryPrecacheSounds.size() <= MAX_PRECACHE_SOUND) {
g_precachedSounds.insert(path);
return g_engfuncs.pfnPrecacheSound(path);
return g_engfuncs.pfnPrecacheSound(STRING(ALLOC_STRING(path)));
}
else {
return g_engfuncs.pfnPrecacheSound(NOT_PRECACHED_SOUND);
Expand Down Expand Up @@ -277,13 +279,15 @@ void PRECACHE_MODEL_EXTRAS(const char* path, studiohdr_t* mdl) {

// player model preview image
if (isPlayerModel) {
PRECACHE_GENERIC(UTIL_VarArgs("%s.bmp", pathWithoutExt.c_str()));
const char* bmp = UTIL_VarArgs("%s.bmp", pathWithoutExt.c_str());
PRECACHE_GENERIC(STRING(ALLOC_STRING(bmp)));
}

// external sequence models (01/02/03.mdl)
if (mdl->numseqgroups > 1) {
for (int m = 1; m < mdl->numseqgroups; m++) {
PRECACHE_GENERIC(UTIL_VarArgs("%s%02d.mdl", pathWithoutExt.c_str(), m));
const char* seqmdl = UTIL_VarArgs("%s%02d.mdl", pathWithoutExt.c_str(), m);
PRECACHE_GENERIC(STRING(ALLOC_STRING(seqmdl)));
}
}

Expand All @@ -304,7 +308,8 @@ void PRECACHE_MODEL_EXTRAS(const char* path, studiohdr_t* mdl) {
}

if (!isEmptyModel) {
PRECACHE_GENERIC(UTIL_VarArgs("%st.mdl", pathWithoutExt.c_str()));
const char* tmdl = UTIL_VarArgs("%st.mdl", pathWithoutExt.c_str());
PRECACHE_GENERIC(STRING(ALLOC_STRING(tmdl)));
}
}

Expand All @@ -326,10 +331,10 @@ void PRECACHE_MODEL_EXTRAS(const char* path, studiohdr_t* mdl) {
opt = opt.substr(1); // not sure why some models do this, it looks pointless.

// model sounds are loaded on demand, not precached
PRECACHE_GENERIC(normalize_path("sound/" + opt).c_str());
PRECACHE_GENERIC(STRING(ALLOC_STRING(normalize_path("sound/" + opt).c_str())));
}
if (evt->event == 5001 || evt->event == 5011 || evt->event == 5021 || evt->event == 5031) { // muzzleflash sprite
PRECACHE_GENERIC(normalize_path(opt).c_str());
PRECACHE_GENERIC(STRING(ALLOC_STRING(normalize_path(opt).c_str())));
}
if (evt->event == 5005) { // custom muzzleflash (sven co-op only, likely requires custom client)
std::string muzzle_txt = normalize_path("events/" + opt);
Expand Down Expand Up @@ -402,7 +407,7 @@ int PRECACHE_MODEL(const char* path) {

if (g_serveractive) {
if (g_precachedModels.find(path) != g_precachedModels.end()) {
return g_engfuncs.pfnPrecacheModel(path);
return g_engfuncs.pfnPrecacheModel(STRING(ALLOC_STRING(path)));
}
else {
ALERT(at_warning, "PrecacheModel failed: %s\n", path);
Expand All @@ -416,7 +421,7 @@ int PRECACHE_MODEL(const char* path) {
if (g_tryPrecacheModels.size() + g_bsp.entityBspModelCount + 1 <= MAX_PRECACHE_MODEL) {
if (g_precachedModels.find(path) == g_precachedModels.end())
g_precachedModels.insert(path);
int modelIdx = g_engfuncs.pfnPrecacheModel(path);
int modelIdx = g_engfuncs.pfnPrecacheModel(STRING(ALLOC_STRING(path)));

std::string pathstr = std::string(path);
if (pathstr.find(".mdl") == pathstr.size() - 4) {
Expand Down Expand Up @@ -465,7 +470,7 @@ int PRECACHE_EVENT(int id, const char* path) {
g_tryPrecacheEvents.insert(path);

if (g_tryPrecacheEvents.size() < MAX_PRECACHE_EVENT) {
g_precachedEvents[path] = g_engfuncs.pfnPrecacheEvent(id, path);
g_precachedEvents[path] = g_engfuncs.pfnPrecacheEvent(id, STRING(ALLOC_STRING(path)));
return g_precachedEvents[path];
}
else {
Expand Down Expand Up @@ -704,5 +709,14 @@ void PLAYBACK_EVENT_FULL(int flags, const edict_t* pInvoker, unsigned short even
}

EXPORT string_t ALLOC_STRING(const char* str) {
return g_engfuncs.pfnAllocString(str);
auto existing = g_allocedStrings.find(str);

if (existing != g_allocedStrings.end()) {
return existing->second;
}

string_t newStr = g_engfuncs.pfnAllocString(str);
g_allocedStrings[str] = newStr;

return newStr;
}
3 changes: 3 additions & 0 deletions dlls/eng_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ EXPORT extern std::unordered_set<std::string> g_tryPrecacheSounds;
EXPORT extern std::unordered_set<std::string> g_tryPrecacheGeneric;
EXPORT extern std::unordered_set<std::string> g_tryPrecacheEvents;

// find an already alloc'd string by its contents (used by ALLOC_STRING)
extern std::unordered_map<std::string, string_t> g_allocedStrings;

#ifdef CLIENT_DLL
#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel)
#define SET_MODEL (*g_engfuncs.pfnSetModel)
Expand Down
6 changes: 4 additions & 2 deletions dlls/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,9 @@ void GameDLLInit( void )

SERVER_COMMAND( "exec skill.cfg\n" );

RehldsApi_Init();
RegisterRehldsHooks();
if (IS_DEDICATED_SERVER()) {
RehldsApi_Init();
RegisterRehldsHooks();
}
}

3 changes: 3 additions & 0 deletions dlls/hooks/hlds_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,12 @@ void ServerDeactivate( void )
g_precachedModels.clear();
g_missingModels.clear();
g_precachedSounds.clear();
g_precachedEvents.clear();
g_tryPrecacheGeneric.clear();
g_tryPrecacheModels.clear();
g_tryPrecacheSounds.clear();
g_tryPrecacheEvents.clear();
g_allocedStrings.clear();
g_mapWeapons.clear();
g_wavInfos.clear();
g_weaponClassnames.clear();
Expand Down
1 change: 1 addition & 0 deletions dlls/singleplay_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern int gmsgMOTD;
//=========================================================
CHalfLifeRules::CHalfLifeRules( void )
{
mapcycle.items = NULL;
RefreshSkillData();
}

Expand Down
1 change: 1 addition & 0 deletions dlls/teamplay_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ CHalfLifeTeamplay :: CHalfLifeTeamplay()
{
m_DisableDeathMessages = FALSE;
m_DisableDeathPenalty = FALSE;
mapcycle.items = NULL;

memset( team_names, 0, sizeof(team_names) );
memset( team_scores, 0, sizeof(team_scores) );
Expand Down
4 changes: 2 additions & 2 deletions dlls/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2463,7 +2463,7 @@ void PrintEntindexStats() {
int totalFreeLowPrio = 0;
int totalFreeNormalPrio = 0;
int totalFreeHighPrio = 0;
int lowPrioMin = sv_max_client_edicts->value;
int lowPrioMin = sv_max_client_edicts ? sv_max_client_edicts->value : MAX_LEGACY_CLIENT_ENTS;
int normalPrioMin = 512;
int reservedSlots = gpGlobals->maxClients + 1;

Expand Down Expand Up @@ -2503,7 +2503,7 @@ CBaseEntity* RelocateEntIdx(CBaseEntity* pEntity) {
int iprio = pEntity->GetEntindexPriority();
int eidx = pEntity->entindex();
int bestIdx = eidx;
int lowPrioMin = sv_max_client_edicts->value;
int lowPrioMin = sv_max_client_edicts ? sv_max_client_edicts->value : MAX_LEGACY_CLIENT_ENTS;
int normalPrioMin = 512;
edict_t* edicts = ENT(0);

Expand Down

0 comments on commit 26c6c72

Please sign in to comment.