diff --git a/README.md b/README.md index d583bc5..95a5d8a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Bugfixed version of rehlds contains an additional cvars:
  • sv_rehlds_movecmdrate_max_burst // Max burst level of 'move' cmds for ban. Default: 2500
  • sv_rehlds_stringcmdrate_max_avg // Max average level of 'string' cmds for ban. Default: 80
  • sv_rehlds_stringcmdrate_max_burst // Max burst level of 'string' cmds for ban. Default: 400 +
  • sv_rehlds_userinfo_transmitted_fields // Userinfo fields only with these keys will be transmitted to clients via network. If not set then all fields will be transmitted (except prefixed with underscore). Each key must be prefixed by backslash, for example "\name\model\*sid\*hltv\bottomcolor\topcolor". Default: "" ## Build instructions diff --git a/rehlds/engine/info.cpp b/rehlds/engine/info.cpp index d9a9fe9..c433ba4 100644 --- a/rehlds/engine/info.cpp +++ b/rehlds/engine/info.cpp @@ -618,3 +618,51 @@ qboolean Info_IsValid(const char *s) return FALSE; } + +#ifdef REHLDS_FIXES +void Info_CollectFields(char *destInfo, const char *srcInfo, const char *collectedKeysOfFields) +{ + char keys[MAX_INFO_STRING]; + Q_strcpy(keys, collectedKeysOfFields); + + size_t userInfoLength = 0; + for (const char *key = strtok(keys, "\\"); key; key = strtok(nullptr, "\\")) + { + const char *value = Info_ValueForKey(srcInfo, key); + + if (value[0] == '\0') + continue; + + // Integer fields + if (!Q_strcmp(key, "*hltv") + || !Q_strcmp(key, "bottomcolor") + || !Q_strcmp(key, "topcolor")) + { + int intValue = Q_atoi(value); + + if (!intValue) + continue; + + destInfo[userInfoLength++] = '\\'; + Q_strcpy(&destInfo[userInfoLength], key); + userInfoLength += Q_strlen(key); + + destInfo[userInfoLength++] = '\\'; + userInfoLength += Q_sprintf(&destInfo[userInfoLength], "%d", intValue); + } + // String fields + else + { + destInfo[userInfoLength++] = '\\'; + Q_strcpy(&destInfo[userInfoLength], key); + userInfoLength += Q_strlen(key); + + destInfo[userInfoLength++] = '\\'; + Q_strcpy(&destInfo[userInfoLength], value); + userInfoLength += Q_strlen(value); + } + + } + destInfo[userInfoLength] = '\0'; +} +#endif \ No newline at end of file diff --git a/rehlds/engine/info.h b/rehlds/engine/info.h index 364aafa..e2d39db 100644 --- a/rehlds/engine/info.h +++ b/rehlds/engine/info.h @@ -57,5 +57,8 @@ void Info_SetValueForStarKey(char *s, const char *key, const char *value, int ma void Info_SetValueForKey(char *s, const char *key, const char *value, int maxsize); void Info_Print(const char *s); qboolean Info_IsValid(const char *s); +#ifdef REHLDS_FIXES +void Info_CollectFields(char *destInfo, const char *srcInfo, const char *collectedKeysOfFields); +#endif #endif // INFO__H diff --git a/rehlds/engine/server.h b/rehlds/engine/server.h index 6d0eb02..4c933c6 100644 --- a/rehlds/engine/server.h +++ b/rehlds/engine/server.h @@ -545,6 +545,7 @@ extern cvar_t sv_delayed_spray_upload; extern cvar_t sv_rehlds_force_dlmax; extern cvar_t sv_rehlds_hull_centering; extern cvar_t sv_rcon_condebug; +extern cvar_t sv_rehlds_userinfo_transmitted_fields; #endif extern int sv_playermodel; diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index 4bd0cb2..fa3ba52 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -306,6 +306,7 @@ cvar_t sv_rehlds_force_dlmax = { "sv_rehlds_force_dlmax", "0", 0, 0.0f, nullptr cvar_t listipcfgfile = { "listipcfgfile", "listip.cfg", 0, 0.0f, nullptr }; cvar_t sv_rehlds_hull_centering = { "sv_rehlds_hull_centering", "0", 0, 0.0f, nullptr }; cvar_t sv_rcon_condebug = { "sv_rcon_condebug", "1", 0, 1.0f, nullptr }; +cvar_t sv_rehlds_userinfo_transmitted_fields = { "sv_rehlds_userinfo_transmitted_fields", "", 0, 0.0f, nullptr }; #endif /* ../engine/sv_main.c:113 */ @@ -3829,9 +3830,18 @@ void SV_FullClientUpdate(client_t *cl, sizebuf_t *sb) { char info[MAX_INFO_STRING]; - Q_strncpy(info, cl->userinfo, sizeof(info) - 1); - info[sizeof(info) - 1] = 0; - Info_RemovePrefixedKeys(info, '_'); +#ifdef REHLDS_FIXES + if (sv_rehlds_userinfo_transmitted_fields.string[0] != '\0') + { + Info_CollectFields(info, cl->userinfo, sv_rehlds_userinfo_transmitted_fields.string); + } + else +#endif // REHLDS_FIXES + { + Q_strncpy(info, cl->userinfo, sizeof(info) - 1); + info[sizeof(info) - 1] = 0; + Info_RemovePrefixedKeys(info, '_'); + } g_RehldsHookchains.m_SV_WriteFullClientUpdate.callChain(SV_WriteFullClientUpdate_internal, GetRehldsApiClient(cl), info, MAX_INFO_STRING, sb, GetRehldsApiClient((sb == &g_psv.reliable_datagram) ? NULL : host_client)); } @@ -7801,6 +7811,7 @@ void SV_Init(void) Cvar_RegisterVariable(&sv_rehlds_force_dlmax); Cvar_RegisterVariable(&sv_rehlds_hull_centering); Cvar_RegisterVariable(&sv_rcon_condebug); + Cvar_RegisterVariable(&sv_rehlds_userinfo_transmitted_fields); #endif for (int i = 0; i < MAX_MODELS; i++)