Skip to content

Commit

Permalink
Server: Split long HUD messages (#198)
Browse files Browse the repository at this point in the history
Resolves #198
  • Loading branch information
tmp64 committed Dec 16, 2023
1 parent 4f0973a commit d350dea
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 8 deletions.
68 changes: 60 additions & 8 deletions src/game/server/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,12 @@ void UTIL_ScreenFade(CBaseEntity *pEntity, const Vector &color, float fadeTime,
}

void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage)
{
const char *splitMsg = UTIL_SplitHudMessage(pMessage);
UTIL_HudMessageRaw(pEntity, textparms, splitMsg);
}

void UTIL_HudMessageRaw(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage)
{
if (!pEntity || !pEntity->IsNetClient())
return;
Expand Down Expand Up @@ -874,13 +880,13 @@ void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, cons

void UTIL_HudMessageAll(const hudtextparms_t &textparms, const char *pMessage)
{
int i;
const char *splitMsg = UTIL_SplitHudMessage(pMessage);

for (i = 1; i <= gpGlobals->maxClients; i++)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBaseEntity *pPlayer = UTIL_PlayerByIndex(i);
if (pPlayer)
UTIL_HudMessage(pPlayer, textparms, pMessage);
UTIL_HudMessageRaw(pPlayer, textparms, splitMsg);
}
}

Expand Down Expand Up @@ -968,7 +974,48 @@ char *UTIL_dtos4(int d)
return buf;
}

void UTIL_ShowMessage(const char *pString, CBaseEntity *pEntity)
char *UTIL_SplitHudMessage(const char *src)
{
// Copied from AMX Mod X: https://github.com/alliedmodders/amxmodx/blob/27f451a868c3154a0ab0d4d70e0a650074fd485d/amxmodx/util.cpp#L148-L183
// Licensed under the GNU General Public License, version 3 or higher.
static char message[512];
short b = 0, d = 0, e = 0, c = -1;

while (src[d] && e < 480)
{
if (src[d] == ' ')
{
c = e;
}
else if (src[d] == '\n')
{
c = -1;
b = 0;
}

message[e++] = src[d++];

if (++b == 69)
{
if (c == -1)
{
message[e++] = '\n';
b = 0;
}
else
{
message[c] = '\n';
b = e - c - 1;
c = -1;
}
}
}

message[e] = 0;
return message;
}

void UTIL_ShowMessageRaw(const char *pString, CBaseEntity *pEntity)
{
if (!pEntity || !pEntity->IsNetClient())
return;
Expand All @@ -978,17 +1025,22 @@ void UTIL_ShowMessage(const char *pString, CBaseEntity *pEntity)
MESSAGE_END();
}

void UTIL_ShowMessage(const char *pString, CBaseEntity *pEntity)
{
const char *splitMsg = UTIL_SplitHudMessage(pString);
UTIL_ShowMessageRaw(splitMsg, pEntity);
}

void UTIL_ShowMessageAll(const char *pString)
{
int i;
const char *splitMsg = UTIL_SplitHudMessage(pString);

// loop through all players

for (i = 1; i <= gpGlobals->maxClients; i++)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBaseEntity *pPlayer = UTIL_PlayerByIndex(i);
if (pPlayer)
UTIL_ShowMessage(pString, pPlayer);
UTIL_ShowMessageRaw(splitMsg, pPlayer);
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/game/server/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,19 @@ extern void UTIL_EmitAmbientSound(edict_t *entity, const Vector &vecOrigin, cons
extern void UTIL_ParticleEffect(const Vector &vecOrigin, const Vector &vecDirection, ULONG ulColor, ULONG ulCount);
extern void UTIL_ScreenShake(const Vector &center, float amplitude, float frequency, float duration, float radius);
extern void UTIL_ScreenShakeAll(const Vector &center, float amplitude, float frequency, float duration);

//! Splits any lines in a string longer than 68 characters.
//! Not UTF-8-aware. Will split by words if possible.
//! Prevents a client crash due to a buffer overflow.
//! See tmp64/BugfixedHL-Rebased#198 and ValveSoftware/halflife#3705.
//! @param src Original message text. Size after splitting is limited to 511 bytes.
//! @returns Pointer to a static buffer.
extern char *UTIL_SplitHudMessage(const char *src);

extern void UTIL_ShowMessageRaw(const char *pString, CBaseEntity *pPlayer);
extern void UTIL_ShowMessage(const char *pString, CBaseEntity *pPlayer);
extern void UTIL_ShowMessageAll(const char *pString);

extern void UTIL_ScreenFadeAll(const Vector &color, float fadeTime, float holdTime, int alpha, int flags);
extern void UTIL_ScreenFade(CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags);

Expand Down Expand Up @@ -376,6 +387,7 @@ typedef struct hudtextparms_s
// prints as transparent 'title' to the HUD
extern void UTIL_HudMessageAll(const hudtextparms_t &textparms, const char *pMessage);
extern void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage);
extern void UTIL_HudMessageRaw(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage);

// for handy use with ClientPrint params
extern char *UTIL_dtos1(int d);
Expand Down

0 comments on commit d350dea

Please sign in to comment.