From 415240ecded13f9794b86791e2b108a328a1d1a0 Mon Sep 17 00:00:00 2001 From: WPMGPRoSToTeMa Date: Sat, 6 Feb 2016 08:35:28 +0300 Subject: [PATCH] Extended max resource count to 4096 Extended max generic resource count to 4096 Added backward slash replace in PF_precache_generic_I Removed local copying in SV_CreateGenericResources Added moving checked resources to first positions in resource list --- rehlds/engine/pr_cmds.cpp | 57 +++++++++++++++---- rehlds/engine/server.h | 9 +++ rehlds/engine/sv_main.cpp | 71 +++++++++++++++++++++++- rehlds/engine/sv_user.cpp | 18 +++++- rehlds/rehlds/rehlds_interfaces_impl.cpp | 4 ++ 5 files changed, 142 insertions(+), 17 deletions(-) diff --git a/rehlds/engine/pr_cmds.cpp b/rehlds/engine/pr_cmds.cpp index 3057579..abd738a 100644 --- a/rehlds/engine/pr_cmds.cpp +++ b/rehlds/engine/pr_cmds.cpp @@ -1551,6 +1551,7 @@ int EXT_FUNC PF_precache_model_I(const char *s) } } +#ifdef REHLDS_FIXES /* <79a3f> ../engine/pr_cmds.c:1903 */ int EXT_FUNC PF_precache_generic_I(char *s) // TODO: Call to Con_Printf is replaced with Host_Error in 6153 @@ -1561,14 +1562,51 @@ int EXT_FUNC PF_precache_generic_I(char *s) if (PR_IsEmptyString(s)) Host_Error("PF_precache_generic_I: Bad string '%s'", s); -#ifdef REHLDS_FIXES - size_t soundPrefixLength = sizeof("sound/") - 1; - bool isSoundPrefixed = !Q_strnicmp(s, "sound/", soundPrefixLength); + char resName[MAX_QPATH]; + Q_strncpy(resName, s, sizeof(resName)); + resName[sizeof(resName) - 1] = '\0'; + ForwardSlashes(resName); - if ((isSoundPrefixed && SV_LookupSoundIndex(&s[soundPrefixLength])) || - SV_LookupModelIndex(s)) + size_t soundPrefixLength = sizeof("sound/") - 1; + bool isSoundPrefixed = !Q_strnicmp(resName, "sound/", soundPrefixLength); + + // TODO: check sound with index 0? + // UPD: no, not need, because engine do this: g_psv.sound_precache[0] = pr_strings; + if ((isSoundPrefixed && SV_LookupSoundIndex(&resName[soundPrefixLength])) || + SV_LookupModelIndex(resName)) return 0; -#endif // REHLDS_FIXES + + size_t resCount = g_rehlds_sv.precachedGenericResourceCount; + for (size_t i = 0; i < resCount; i++) + { + if (!Q_stricmp(g_rehlds_sv.precachedGenericResourceNames[i], resName)) + return i; + } + + if (g_psv.state != ss_loading) + Host_Error("PF_precache_generic_I: '%s' Precache can only be done in spawn functions", resName); + + if (resCount >= ARRAYSIZE(g_rehlds_sv.precachedGenericResourceNames)) + Host_Error( + "PF_precache_generic_I: Generic item '%s' failed to precache because the item count is over the %d limit.\n\ +Reduce the number of brush models and/or regular models in the map to correct this.", + resName, + ARRAYSIZE(g_rehlds_sv.precachedGenericResourceNames)); + + Q_strcpy(g_rehlds_sv.precachedGenericResourceNames[resCount], resName); + + return g_rehlds_sv.precachedGenericResourceCount++; +} +#else // REHLDS_FIXES +/* <79a3f> ../engine/pr_cmds.c:1903 */ +int EXT_FUNC PF_precache_generic_I(char *s) +// TODO: Call to Con_Printf is replaced with Host_Error in 6153 +{ + if (!s) + Host_Error("PF_precache_generic_I: NULL pointer"); + + if (PR_IsEmptyString(s)) + Host_Error("PF_precache_generic_I: Bad string '%s'", s); if (g_psv.state == ss_loading) { @@ -1576,12 +1614,7 @@ int EXT_FUNC PF_precache_generic_I(char *s) { if (!g_psv.generic_precache[i]) { -#ifdef REHLDS_FIXES - // For more information, see EV_Precache - g_psv.generic_precache[i] = ED_NewString(s); -#else g_psv.generic_precache[i] = s; -#endif // REHLDS_FIXES return i; } @@ -1602,8 +1635,8 @@ int EXT_FUNC PF_precache_generic_I(char *s) } Host_Error("PF_precache_generic_I: '%s' Precache can only be done in spawn functions", s); } - } +#endif // REHLDS_FIXES /* <79a93> ../engine/pr_cmds.c:1944 */ int EXT_FUNC PF_IsMapValid_I(char *mapname) diff --git a/rehlds/engine/server.h b/rehlds/engine/server.h index 24fdd6d..b37b4b8 100644 --- a/rehlds/engine/server.h +++ b/rehlds/engine/server.h @@ -81,6 +81,10 @@ #define MSG_FL_PAS BIT(2) // Send to PAS #define MSG_FL_ONE BIT(7) // Send to single client +#define RESOURCE_INDEX_BITS 12 +#ifdef REHLDS_FIXES +#define RESOURCE_MAX_COUNT (1 << RESOURCE_INDEX_BITS) +#endif // REHLDS_FIXES #define HL_SOUND_MAX 512 #define HL_SOUND_HASHLOOKUP_SIZE (HL_SOUND_MAX * 2 - 1) @@ -168,6 +172,11 @@ struct rehlds_server_t { // Extended net buffers uint8_t reliableDatagramBuffer[NET_MAX_PAYLOAD]; uint8_t signonData[NET_MAX_PAYLOAD]; + + // Extended resource list + resource_t resources[RESOURCE_MAX_COUNT]; + char precachedGenericResourceNames[RESOURCE_MAX_COUNT][MAX_QPATH]; + size_t precachedGenericResourceCount; #endif }; diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index dd89aab..2d7197a 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -1300,14 +1300,18 @@ void SV_SendResources(sizebuf_t *msg) MSG_WriteByte(msg, svc_resourcelist); MSG_StartBitWriting(msg); - MSG_WriteBits(g_psv.num_resources, 12); + MSG_WriteBits(g_psv.num_resources, RESOURCE_INDEX_BITS); +#ifdef REHLDS_FIXES + resource_t *r = g_rehlds_sv.resources; +#else // REHLDS_FIXES resource_t *r = g_psv.resourcelist; +#endif for (int i = 0; i < g_psv.num_resources; i++, r++) { MSG_WriteBits(r->type, 4); MSG_WriteBitString(r->szFileName); - MSG_WriteBits(r->nIndex, 12); + MSG_WriteBits(r->nIndex, RESOURCE_INDEX_BITS); MSG_WriteBits(r->nDownloadSize, 24); MSG_WriteBits(r->ucFlags & (RES_WASMISSING | RES_FATALIFMISSING), 3); @@ -4989,10 +4993,20 @@ int SV_ModelIndex(const char *name) void EXT_FUNC SV_AddResource(resourcetype_t type, const char *name, int size, unsigned char flags, int index) { resource_t *r; +#ifdef REHLDS_FIXES + if (g_psv.num_resources >= ARRAYSIZE(g_rehlds_sv.resources)) +#else // REHLDS_FIXES if (g_psv.num_resources >= MAX_RESOURCE_LIST) +#endif // REHLDS_FIXES + { Sys_Error("Too many resources on server."); + } +#ifdef REHLDS_FIXES + r = &g_rehlds_sv.resources[g_psv.num_resources++]; +#else // REHLDS_FIXES r = &g_psv.resourcelist[g_psv.num_resources++]; +#endif r->type = type; Q_strncpy(r->szFileName, name, sizeof(r->szFileName) - 1); r->szFileName[sizeof(r->szFileName) - 1] = 0; @@ -5054,10 +5068,17 @@ void SV_CreateGenericResources(void) Con_Printf("Can't precache .dll files: %s\n", com_token); else { + // In fixed version of PrecacheGeneric we don't need local copy +#ifdef REHLDS_FIXES + PF_precache_generic_I(com_token); + Con_DPrintf(" %s\n", com_token); + g_psv.num_generic_names++; +#else // REHLDS_FIXES Q_strncpy(g_psv.generic_precache_names[g_psv.num_generic_names], com_token, sizeof(g_psv.generic_precache_names[g_psv.num_generic_names]) - 1); g_psv.generic_precache_names[g_psv.num_generic_names][sizeof(g_psv.generic_precache_names[g_psv.num_generic_names]) - 1] = 0; PF_precache_generic_I(g_psv.generic_precache_names[g_psv.num_generic_names]); Con_DPrintf(" %s\n", g_psv.generic_precache_names[g_psv.num_generic_names++]); +#endif // REHLDS_FIXES } } Con_DPrintf("----------------------------------\n"); @@ -5074,6 +5095,19 @@ void SV_CreateResourceList(void) event_t *ep; g_psv.num_resources = 0; + +#ifdef REHLDS_FIXES + // Generic resources can be indexed from 0, because client ignores resourceIndex for generic resources + for (size_t i = 0; i < g_rehlds_sv.precachedGenericResourceCount; i++) + { + if (g_psvs.maxclients > 1) + nSize = FS_FileSize(g_rehlds_sv.precachedGenericResourceNames[i]); + else + nSize = 0; + + SV_AddResource(t_generic, g_rehlds_sv.precachedGenericResourceNames[i], nSize, RES_FATALIFMISSING, i); + } +#else // REHLDS_FIXES #ifdef REHLDS_CHECKS for (i = 1, s = &g_psv.generic_precache[1]; i < HL_GENERIC_MAX && *s != NULL; i++, s++) #else // REHLDS_CHECKS @@ -5087,6 +5121,8 @@ void SV_CreateResourceList(void) SV_AddResource(t_generic, *s, nSize, RES_FATALIFMISSING, i); } +#endif // REHLDS_FIXES + #ifdef REHLDS_CHECKS for (i = 1, s = &g_psv.sound_precache[1]; i < HL_SOUND_MAX && *s != NULL; i++, s++) #else // REHLDS_CHECKS @@ -5409,6 +5445,29 @@ void SetCStrikeFlags(void) } } +#ifdef REHLDS_FIXES +void MoveCheckedResourcesToFirstPositions() +{ + resource_t *pResources = g_rehlds_sv.resources; + size_t j = 0; + for (size_t i = 0; i < (size_t)g_psv.num_resources; i++) + { + if (!(pResources[i].ucFlags & RES_CHECKFILE)) + continue; + if (i == j) + { + j++; + continue; + } + + resource_t temp = pResources[i]; + pResources[i] = pResources[j]; + pResources[j] = temp; + j++; + } +} +#endif // REHLDS_FIXES + void SV_ActivateServer(int runPhysics) { g_RehldsHookchains.m_SV_ActivateServer.callChain(SV_ActivateServer_internal, runPhysics); @@ -5466,6 +5525,9 @@ void EXT_FUNC SV_ActivateServer_internal(int runPhysics) SV_CreateBaseline(); SV_CreateResourceList(); g_psv.num_consistency = SV_TransferConsistencyInfo(); +#ifdef REHLDS_FIXES + MoveCheckedResourcesToFirstPositions(); +#endif // REHLDS_FIXES for (i = 0, cl = g_psvs.clients; i < g_psvs.maxclients; cl++, i++) { if (!cl->fakeclient && (cl->active || cl->connected)) @@ -5606,6 +5668,9 @@ int SV_SpawnServer(qboolean bIsDemo, char *server, char *startspot) #ifdef REHLDS_OPT_PEDANTIC g_rehlds_sv.modelsMap.clear(); #endif +#ifdef REHLDS_FIXES + g_rehlds_sv.precachedGenericResourceCount = 0; +#endif // REHLDS_FIXES Q_strncpy(g_psv.oldname, oldname, sizeof(oldname) - 1); g_psv.oldname[sizeof(oldname) - 1] = 0; @@ -5738,7 +5803,9 @@ int SV_SpawnServer(qboolean bIsDemo, char *server, char *startspot) g_psv.sound_precache[0] = pr_strings; g_psv.model_precache[0] = pr_strings; +#ifndef REHLDS_FIXES g_psv.generic_precache[0] = pr_strings; +#endif // REHLDS_FIXES for (i = 1; i < g_psv.worldmodel->numsubmodels; i++) { diff --git a/rehlds/engine/sv_user.cpp b/rehlds/engine/sv_user.cpp index 0c5afc7..71b8c95 100644 --- a/rehlds/engine/sv_user.cpp +++ b/rehlds/engine/sv_user.cpp @@ -136,8 +136,12 @@ void SV_ParseConsistencyResponse(client_t *pSenderClient) break; } +#ifdef REHLDS_FIXES + resource_t *r = &g_rehlds_sv.resources[idx]; +#else // REHLDS_FIXES resource_t *r = &g_psv.resourcelist[idx]; - if (!(g_psv.resourcelist[idx].ucFlags & RES_CHECKFILE)) +#endif // REHLDS_FIXES + if (!(r->ucFlags & RES_CHECKFILE)) { c = -1; break; @@ -223,12 +227,12 @@ void SV_ParseConsistencyResponse(client_t *pSenderClient) #ifdef REHLDS_FIXES dropmessage[0] = '\0'; - if (gEntityInterface.pfnInconsistentFile(host_client->edict, g_psv.resourcelist[c - 1].szFileName, dropmessage)) + if (gEntityInterface.pfnInconsistentFile(host_client->edict, g_rehlds_sv.resources[c - 1].szFileName, dropmessage)) { if (dropmessage[0]) SV_ClientPrintf("%s", dropmessage); - SV_DropClient(host_client, FALSE, "Bad file %s", g_psv.resourcelist[c - 1].szFileName); // only filename. reason was printed in console if exists. + SV_DropClient(host_client, FALSE, "Bad file %s", g_rehlds_sv.resources[c - 1].szFileName); // only filename. reason was printed in console if exists. } #else // REHLDS_FIXES if (gEntityInterface.pfnInconsistentFile(host_client->edict, g_psv.resourcelist[c - 1].szFileName, dropmessage)) @@ -278,7 +282,11 @@ int EXT_FUNC SV_TransferConsistencyInfo_internal(void) int c = 0; for (int i = 0; i < g_psv.num_resources; i++) { +#ifdef REHLDS_FIXES + resource_t *r = &g_rehlds_sv.resources[i]; +#else // REHLDS_FIXES resource_t *r = &g_psv.resourcelist[i]; +#endif // REHLDS_FIXES if (r->ucFlags == (RES_CUSTOM | RES_REQUESTED | RES_UNK_6) || (r->ucFlags & RES_CHECKFILE)) continue; @@ -345,7 +353,11 @@ void SV_SendConsistencyList(sizebuf_t *msg) int delta = 0; int lastcheck = 0; +#ifdef REHLDS_FIXES + resource_t *r = g_rehlds_sv.resources; +#else // REHLDS_FIXES resource_t *r = g_psv.resourcelist; +#endif // REHLDS_FIXES MSG_WriteBits(1, 1); diff --git a/rehlds/rehlds/rehlds_interfaces_impl.cpp b/rehlds/rehlds/rehlds_interfaces_impl.cpp index d7814e6..557a21b 100644 --- a/rehlds/rehlds/rehlds_interfaces_impl.cpp +++ b/rehlds/rehlds/rehlds_interfaces_impl.cpp @@ -235,7 +235,11 @@ void EXT_FUNC CRehldsServerData::SetResourcesNum(int num) { } struct resource_s *EXT_FUNC CRehldsServerData::GetResource(int index) { +#ifdef REHLDS_FIXES + return &g_rehlds_sv.resources[index]; +#else // REHLDS_FIXES return &g_psv.resourcelist[index]; +#endif // REHLDS_FIXES } void Rehlds_Interfaces_FreeClients()