diff --git a/rehlds/engine/client.h b/rehlds/engine/client.h index dfba5f4..8c01b2d 100644 --- a/rehlds/engine/client.h +++ b/rehlds/engine/client.h @@ -232,10 +232,10 @@ typedef struct client_state_s local_state_t predicted_frames[64]; int delta_sequence; int playernum; - event_t event_precache[256]; - model_t *model_precache[512]; + event_t event_precache[HL_EVENT_MAX]; + model_t *model_precache[HL_MODEL_MAX]; int model_precache_count; - sfx_s *sound_precache[512]; + sfx_s *sound_precache[HL_SOUND_MAX]; consistency_t consistency_list[512]; int num_consistency; int highentity; diff --git a/rehlds/engine/cmd.cpp b/rehlds/engine/cmd.cpp index 09c39fb..299f496 100644 --- a/rehlds/engine/cmd.cpp +++ b/rehlds/engine/cmd.cpp @@ -80,7 +80,9 @@ void Cbuf_AddText(char *text) // commands. void Cbuf_InsertText(char *text) { +#ifndef REHLDS_FIXES char *temp = NULL; +#endif // REHLDS_FIXES int addLen = Q_strlen(text); int currLen = cmd_text.cursize; @@ -93,24 +95,32 @@ void Cbuf_InsertText(char *text) if (currLen) { +#ifdef REHLDS_FIXES + memmove(cmd_text.data + addLen, cmd_text.data, currLen); +#else // REHLDS_FIXES temp = (char *)Z_Malloc(currLen); // TODO: Optimize: better use memmove without need for a temp buffer Q_memcpy(temp, cmd_text.data, currLen); SZ_Clear(&cmd_text); +#endif // REHLDS_FIXES } Cbuf_AddText(text); +#ifndef REHLDS_FIXES if (currLen) { SZ_Write(&cmd_text, temp, currLen); Z_Free(temp); } +#endif // REHLDS_FIXES } /* <4f05> ../engine/cmd.c:148 */ void Cbuf_InsertTextLines(char *text) { +#ifndef REHLDS_FIXES char *temp = NULL; +#endif // REHLDS_FIXES int addLen = Q_strlen(text); int currLen = cmd_text.cursize; @@ -123,20 +133,26 @@ void Cbuf_InsertTextLines(char *text) if (currLen) { +#ifdef REHLDS_FIXES + memmove(cmd_text.data + addLen, cmd_text.data, currLen); +#else // REHLDS_FIXES temp = (char *)Z_Malloc(currLen); Q_memcpy(temp, cmd_text.data, currLen); SZ_Clear(&cmd_text); +#endif // REHLDS_FIXES } Cbuf_AddText("\n"); // TODO: Why we need leading \n, if there is no commands in the start? Cbuf_AddText(text); Cbuf_AddText("\n"); +#ifndef REHLDS_FIXES if (currLen) { SZ_Write(&cmd_text, temp, currLen); Z_Free(temp); } +#endif // REHLDS_FIXES } /* <5d96> ../engine/cmd.c:193 */ @@ -167,6 +183,18 @@ void Cbuf_Execute(void) break; } +#ifdef REHLDS_FIXES + // save `i` if we truncate command + int len; + + if (i > MAX_CMD_LINE - 1) + len = MAX_CMD_LINE - 1; + else + len = i; + + Q_memcpy(line, text, len); + line[len] = 0; +#else // REHLDS_FIXES if (i > MAX_CMD_LINE - 1) { i = MAX_CMD_LINE - 1; @@ -174,6 +202,7 @@ void Cbuf_Execute(void) Q_memcpy(line, text, i); line[i] = 0; +#endif // REHLDS_FIXES // delete the text from the command buffer and move remaining commands down // this is necessary because commands (exec, alias) can insert data at the @@ -187,7 +216,12 @@ void Cbuf_Execute(void) { i++; cmd_text.cursize -= i; +#ifdef REHLDS_FIXES + // dst overlaps src + memmove(text, text + i, cmd_text.cursize); +#else // REHLDS_FIXES Q_memcpy(text, text + i, cmd_text.cursize); +#endif // REHLDS_FIXES } // execute the command line diff --git a/rehlds/engine/common.cpp b/rehlds/engine/common.cpp index 0dd6b4c..7931b66 100644 --- a/rehlds/engine/common.cpp +++ b/rehlds/engine/common.cpp @@ -2509,6 +2509,73 @@ void COM_UnMunge(unsigned char *data, int len, int seq) } } +#ifdef REHLDS_FIXES +// unrolled version +void COM_Munge2(unsigned char *data, int len, int seq) +{ + unsigned int *pc; + unsigned int *end; + unsigned int mSeq; + + mSeq = _byteswap_ulong(~seq) ^ seq; + len /= 4; + end = (unsigned int *)data + (len & ~15); + + for (pc = (unsigned int *)data; pc < end; pc += 16) + { + pc[0] = _byteswap_ulong(pc[0]) ^ mSeq ^ 0xFFFFE7A5; + pc[1] = _byteswap_ulong(pc[1]) ^ mSeq ^ 0xBFEFFFE5; + pc[2] = _byteswap_ulong(pc[2]) ^ mSeq ^ 0xFFBFEFFF; + pc[3] = _byteswap_ulong(pc[3]) ^ mSeq ^ 0xBFEFBFED; + pc[4] = _byteswap_ulong(pc[4]) ^ mSeq ^ 0xBFAFEFBF; + pc[5] = _byteswap_ulong(pc[5]) ^ mSeq ^ 0xFFBFAFEF; + pc[6] = _byteswap_ulong(pc[6]) ^ mSeq ^ 0xFFEFBFAD; + pc[7] = _byteswap_ulong(pc[7]) ^ mSeq ^ 0xFFFFEFBF; + pc[8] = _byteswap_ulong(pc[8]) ^ mSeq ^ 0xFFEFF7EF; + pc[9] = _byteswap_ulong(pc[9]) ^ mSeq ^ 0xBFEFE7F5; + pc[10] = _byteswap_ulong(pc[10]) ^ mSeq ^ 0xBFBFE7E5; + pc[11] = _byteswap_ulong(pc[11]) ^ mSeq ^ 0xFFAFB7E7; + pc[12] = _byteswap_ulong(pc[12]) ^ mSeq ^ 0xBFFFAFB5; + pc[13] = _byteswap_ulong(pc[13]) ^ mSeq ^ 0xBFAFFFAF; + pc[14] = _byteswap_ulong(pc[14]) ^ mSeq ^ 0xFFAFA7FF; + pc[15] = _byteswap_ulong(pc[15]) ^ mSeq ^ 0xFFEFA7A5; + } + + switch(len & 15) + { + case 15: + pc[14] = _byteswap_ulong(pc[14]) ^ mSeq ^ 0xFFAFA7FF; + case 14: + pc[13] = _byteswap_ulong(pc[13]) ^ mSeq ^ 0xBFAFFFAF; + case 13: + pc[12] = _byteswap_ulong(pc[12]) ^ mSeq ^ 0xBFFFAFB5; + case 12: + pc[11] = _byteswap_ulong(pc[11]) ^ mSeq ^ 0xFFAFB7E7; + case 11: + pc[10] = _byteswap_ulong(pc[10]) ^ mSeq ^ 0xBFBFE7E5; + case 10: + pc[9] = _byteswap_ulong(pc[9]) ^ mSeq ^ 0xBFEFE7F5; + case 9: + pc[8] = _byteswap_ulong(pc[8]) ^ mSeq ^ 0xFFEFF7EF; + case 8: + pc[7] = _byteswap_ulong(pc[7]) ^ mSeq ^ 0xFFFFEFBF; + case 7: + pc[6] = _byteswap_ulong(pc[6]) ^ mSeq ^ 0xFFEFBFAD; + case 6: + pc[5] = _byteswap_ulong(pc[5]) ^ mSeq ^ 0xFFBFAFEF; + case 5: + pc[4] = _byteswap_ulong(pc[4]) ^ mSeq ^ 0xBFAFEFBF; + case 4: + pc[3] = _byteswap_ulong(pc[3]) ^ mSeq ^ 0xBFEFBFED; + case 3: + pc[2] = _byteswap_ulong(pc[2]) ^ mSeq ^ 0xFFBFEFFF; + case 2: + pc[1] = _byteswap_ulong(pc[1]) ^ mSeq ^ 0xBFEFFFE5; + case 1: + pc[0] = _byteswap_ulong(pc[0]) ^ mSeq ^ 0xFFFFE7A5; + } +} +#else // REHLDS_FIXES /* <124de> ../engine/common.c:3104 */ void COM_Munge2(unsigned char *data, int len, int seq) { @@ -2539,7 +2606,75 @@ void COM_Munge2(unsigned char *data, int len, int seq) *pc = c; } } +#endif // REHLDS_FIXES +#ifdef REHLDS_FIXES +// unrolled version +void COM_UnMunge2(unsigned char *data, int len, int seq) +{ + unsigned int *pc; + unsigned int *end; + unsigned int mSeq; + + mSeq = _byteswap_ulong(~seq) ^ seq; + len /= 4; + end = (unsigned int *)data + (len & ~15); + + for (pc = (unsigned int *)data; pc < end; pc += 16) + { + pc[0] = _byteswap_ulong(pc[0] ^ mSeq ^ 0xFFFFE7A5); + pc[1] = _byteswap_ulong(pc[1] ^ mSeq ^ 0xBFEFFFE5); + pc[2] = _byteswap_ulong(pc[2] ^ mSeq ^ 0xFFBFEFFF); + pc[3] = _byteswap_ulong(pc[3] ^ mSeq ^ 0xBFEFBFED); + pc[4] = _byteswap_ulong(pc[4] ^ mSeq ^ 0xBFAFEFBF); + pc[5] = _byteswap_ulong(pc[5] ^ mSeq ^ 0xFFBFAFEF); + pc[6] = _byteswap_ulong(pc[6] ^ mSeq ^ 0xFFEFBFAD); + pc[7] = _byteswap_ulong(pc[7] ^ mSeq ^ 0xFFFFEFBF); + pc[8] = _byteswap_ulong(pc[8] ^ mSeq ^ 0xFFEFF7EF); + pc[9] = _byteswap_ulong(pc[9] ^ mSeq ^ 0xBFEFE7F5); + pc[10] = _byteswap_ulong(pc[10] ^ mSeq ^ 0xBFBFE7E5); + pc[11] = _byteswap_ulong(pc[11] ^ mSeq ^ 0xFFAFB7E7); + pc[12] = _byteswap_ulong(pc[12] ^ mSeq ^ 0xBFFFAFB5); + pc[13] = _byteswap_ulong(pc[13] ^ mSeq ^ 0xBFAFFFAF); + pc[14] = _byteswap_ulong(pc[14] ^ mSeq ^ 0xFFAFA7FF); + pc[15] = _byteswap_ulong(pc[15] ^ mSeq ^ 0xFFEFA7A5); + } + + switch(len & 15) + { + case 15: + pc[14] = _byteswap_ulong(pc[14] ^ mSeq ^ 0xFFAFA7FF); + case 14: + pc[13] = _byteswap_ulong(pc[13] ^ mSeq ^ 0xBFAFFFAF); + case 13: + pc[12] = _byteswap_ulong(pc[12] ^ mSeq ^ 0xBFFFAFB5); + case 12: + pc[11] = _byteswap_ulong(pc[11] ^ mSeq ^ 0xFFAFB7E7); + case 11: + pc[10] = _byteswap_ulong(pc[10] ^ mSeq ^ 0xBFBFE7E5); + case 10: + pc[9] = _byteswap_ulong(pc[9] ^ mSeq ^ 0xBFEFE7F5); + case 9: + pc[8] = _byteswap_ulong(pc[8] ^ mSeq ^ 0xFFEFF7EF); + case 8: + pc[7] = _byteswap_ulong(pc[7] ^ mSeq ^ 0xFFFFEFBF); + case 7: + pc[6] = _byteswap_ulong(pc[6] ^ mSeq ^ 0xFFEFBFAD); + case 6: + pc[5] = _byteswap_ulong(pc[5] ^ mSeq ^ 0xFFBFAFEF); + case 5: + pc[4] = _byteswap_ulong(pc[4] ^ mSeq ^ 0xBFAFEFBF); + case 4: + pc[3] = _byteswap_ulong(pc[3] ^ mSeq ^ 0xBFEFBFED); + case 3: + pc[2] = _byteswap_ulong(pc[2] ^ mSeq ^ 0xFFBFEFFF); + case 2: + pc[1] = _byteswap_ulong(pc[1] ^ mSeq ^ 0xBFEFFFE5); + case 1: + pc[0] = _byteswap_ulong(pc[0] ^ mSeq ^ 0xFFFFE7A5); + } +} +#else // REHLDS_FIXES /* <125b5> ../engine/common.c:3146 */ void COM_UnMunge2(unsigned char *data, int len, int seq) { @@ -2570,6 +2705,7 @@ void COM_UnMunge2(unsigned char *data, int len, int seq) *pc = c; } } +#endif // REHLDS_FIXES /* <1269c> ../engine/common.c:3190 */ void COM_Munge3(unsigned char *data, int len, int seq) diff --git a/rehlds/engine/pr_cmds.cpp b/rehlds/engine/pr_cmds.cpp index d993a3a..552beb6 100644 --- a/rehlds/engine/pr_cmds.cpp +++ b/rehlds/engine/pr_cmds.cpp @@ -134,7 +134,7 @@ void PF_setmodel_I(edict_t *e, const char *m) int i = 0; #ifdef REHLDS_CHECKS - for (; *check && i < 512; i++, check++) + for (; *check && i < HL_MODEL_MAX; i++, check++) #else for (; *check; i++, check++) #endif @@ -273,7 +273,6 @@ void PF_particle_I(const float *org, const float *dir, float color, float count) /* <786e7> ../engine/pr_cmds.c:390 */ void PF_ambientsound_I(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch) { - char **check; int i; int soundnum; int ent; @@ -291,19 +290,20 @@ void PF_ambientsound_I(edict_t *entity, float *pos, const char *samp, float vol, } else { - i = 0; - check = g_psv.sound_precache; - while (*check && Q_stricmp(*check, samp)) { - i++; - check++; + for (i = 0; i < HL_SOUND_MAX; i++) + { + if (g_psv.sound_precache[i] && !Q_stricmp(g_psv.sound_precache[i], samp)) + { + soundnum = i; + break; + } } - if (!check[0]) + + if (i == HL_SOUND_MAX) { Con_Printf("no precache: %s\n", samp); return; } - - soundnum = i; } ent = NUM_FOR_EDICT(entity); @@ -1059,41 +1059,37 @@ int PF_precache_sound_I(char *s) if (g_psv.state == ss_loading) { g_psv.sound_precache_hashedlookup_built = 0; - i = 0; - while (1) + + for (i = 0; i < HL_SOUND_MAX; i++) { if (!g_psv.sound_precache[i]) - break; + { + g_psv.sound_precache[i] = s; + return i; + } if (!Q_stricmp(g_psv.sound_precache[i], s)) return i; - - ++i; - if (i >= 512) - Host_Error( - "PF_precache_sound_I: Sound '%s' failed to precache because the item count is over the %d limit.\nReduce the number of brush models and/or regular models in the map to correct this.", - s, - 512); } - g_psv.sound_precache[i] = s; + + Host_Error( + "PF_precache_sound_I: Sound '%s' failed to precache because the item count is over the %d limit.\nReduce the number of brush models and/or regular models in the map to correct this.", + s, + HL_SOUND_MAX); } else { - i = 0; - while (1) + // precaching not enabled. check if already exists. + for (i = 0; i < HL_SOUND_MAX; i++) { - if (g_psv.sound_precache[i]) - { - if (!Q_stricmp(g_psv.sound_precache[i], s)) - break; - } - ++i; - if (i >= 512) - Host_Error("PF_precache_sound_I: '%s' Precache can only be done in spawn functions", s); + if (g_psv.sound_precache[i] && !Q_stricmp(g_psv.sound_precache[i], s)) + return i; } + + Host_Error("PF_precache_sound_I: '%s' Precache can only be done in spawn functions", s); } - return i; + return -1; // unreach } /* <79609> ../engine/pr_cmds.c:1455 */ @@ -1107,7 +1103,7 @@ short unsigned int EV_Precache(int type, const char *psz) if (g_psv.state == ss_loading) { - for (int i = 1; i < 256; i++) + for (int i = 1; i < HL_EVENT_MAX; i++) { struct event_s* ev = &g_psv.event_precache[i]; if (!ev->filename) @@ -1115,8 +1111,8 @@ short unsigned int EV_Precache(int type, const char *psz) if (type != 1) Host_Error("EV_Precache: only file type 1 supported currently\n"); - char szpath[260]; - _snprintf(szpath, 0x104u, "%s", psz); + char szpath[MAX_PATH]; + _snprintf(szpath, sizeof(szpath), "%s", psz); COM_FixSlashes(szpath); int scriptSize = 0; @@ -1139,7 +1135,7 @@ short unsigned int EV_Precache(int type, const char *psz) } else { - for (int i = 1; i < 256; i++) + for (int i = 1; i < HL_EVENT_MAX; i++) { struct event_s* ev = &g_psv.event_precache[i]; if (!Q_stricmp(ev->filename, psz)) @@ -1235,7 +1231,7 @@ void EV_Playback(int flags, const edict_t *pInvoker, short unsigned int eventind eargs.bparam1 = bparam1; eargs.bparam2 = bparam2; - if (eventindex < 1u || eventindex >= 0x100u) + if (eventindex < 1u || eventindex >= HL_EVENT_MAX) { Con_DPrintf("EV_Playback: index out of range %i\n", eventindex); return; @@ -1400,7 +1396,7 @@ int PF_precache_model_I(char *s) if (g_psv.state == ss_loading) { - for (int i = 0; i < 512; i++) + for (int i = 0; i < HL_MODEL_MAX; i++) { if (!g_psv.model_precache[i]) { @@ -1421,7 +1417,7 @@ int PF_precache_model_I(char *s) } else { - for (int i = 0; i < 512; i++) + for (int i = 0; i < HL_MODEL_MAX; i++) { if (!Q_stricmp(g_psv.model_precache[i], s)) return i; @@ -1442,7 +1438,7 @@ int PF_precache_generic_I(char *s) if (g_psv.state == ss_loading) { - for (int i = 0; i < 512; i++) + for (int i = 0; i < HL_GENERIC_MAX; i++) { if (!g_psv.generic_precache[i]) { @@ -1456,11 +1452,11 @@ int PF_precache_generic_I(char *s) Host_Error( "PF_precache_generic_I: Generic item '%s' failed to precache because the item count is over the %d limit.\nReduce the number of brush models and/or regular models in the map to correct this.", s, - 512); + HL_GENERIC_MAX); } else { - for (int i = 0; i < 512; i++) + for (int i = 0; i < HL_GENERIC_MAX; i++) { if (!Q_stricmp(g_psv.generic_precache[i], s)) return i; diff --git a/rehlds/engine/server.h b/rehlds/engine/server.h index 593601f..b0dd4b7 100644 --- a/rehlds/engine/server.h +++ b/rehlds/engine/server.h @@ -34,10 +34,12 @@ #include "maintypes.h" -#define MAX_CLIENTS 32 -#define MAX_EDICTS 900 -#define MAX_NAME 32 +// TODO: I think this defines must be in /common/ +#define MAX_CLIENTS 32 +#define MAX_EDICTS 900 +#define MAX_NAME 32 #define MAX_LIGHTSTYLES 64 +#define MAX_PACKET_ENTITIES 256 #include "custom_int.h" #include "crc.h" @@ -86,6 +88,8 @@ #define HL_SOUND_HASHLOOKUP_SIZE (HL_SOUND_MAX * 2 - 1) #define HL_MODEL_MAX 512 +#define HL_GENERIC_MAX 512 +#define HL_EVENT_MAX 256 // Authentication types #define AUTH_IDTYPE_UNKNOWN 0 @@ -131,15 +135,15 @@ typedef struct server_s int num_resources; consistency_t consistency_list[512]; int num_consistency; - char *model_precache[512]; - struct model_s *models[512]; - unsigned char model_precache_flags[512]; - struct event_s event_precache[256]; - char *sound_precache[512]; + char *model_precache[HL_MODEL_MAX]; + struct model_s *models[HL_MODEL_MAX]; + unsigned char model_precache_flags[HL_MODEL_MAX]; + struct event_s event_precache[HL_EVENT_MAX]; + char *sound_precache[HL_SOUND_MAX]; short int sound_precache_hashedlookup[HL_SOUND_HASHLOOKUP_SIZE]; qboolean sound_precache_hashedlookup_built; - char *generic_precache[512]; - char generic_precache_names[512][64]; + char *generic_precache[HL_GENERIC_MAX]; + char generic_precache_names[HL_GENERIC_MAX][64]; int num_generic_names; char *lightstyles[MAX_LIGHTSTYLES]; int num_edicts; diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index 444bdf6..3905746 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -32,7 +32,7 @@ typedef struct full_packet_entities_s { int num_entities; - entity_state_t entities[256]; + entity_state_t entities[MAX_PACKET_ENTITIES]; } full_packet_entities_t; /* ../engine/sv_main.c:102 */ @@ -493,6 +493,13 @@ void SV_AllocPacketEntities(client_frame_t *frame, int numents) { if (frame) { +#ifdef REHLDS_FIXES + frame->entities.num_entities = numents; + + // only alloc for max possible numents + if (!frame->entities.entities) + frame->entities.entities = (entity_state_t *)Mem_ZeroMalloc(sizeof(entity_state_t) * MAX_PACKET_ENTITIES); +#else // REHLDS_FIXES if (frame->entities.entities) SV_ClearPacketEntities(frame); @@ -502,6 +509,7 @@ void SV_AllocPacketEntities(client_frame_t *frame, int numents) frame->entities.num_entities = numents; frame->entities.entities = (entity_state_t *)Mem_ZeroMalloc(sizeof(entity_state_t) * allocatedslots); +#endif // REHLDS_FIXES } } @@ -853,14 +861,10 @@ int SV_LookupSoundIndex(const char *sample) { if (g_psv.state == ss_loading) { - index = 1; - while (g_psv.sound_precache[index]) + for (index = 1; index < HL_SOUND_MAX && g_psv.sound_precache[index]; index++) // TODO: why from 1? { if (!Q_stricmp(sample, g_psv.sound_precache[index])) return index; - index++; - if (index >= HL_SOUND_MAX) - return 0; } return 0; } @@ -1401,6 +1405,12 @@ void SV_WriteSpawn(sizebuf_t *msg) int i = 0; client_t *client = g_psvs.clients; +#ifdef REHLDS_FIXES + // do it before PutInServer to allow mods send messages from forward + SZ_Clear( &host_client->netchan.message ); + SZ_Clear( &host_client->datagram ); +#endif // REHLDS_FIXES + if (g_psv.loadgame) { if (host_client->proxy) @@ -1429,8 +1439,10 @@ void SV_WriteSpawn(sizebuf_t *msg) g_psv.state = ss_active; } +#ifndef REHLDS_FIXES SZ_Clear(&host_client->netchan.message); SZ_Clear(&host_client->datagram); +#endif // REHLDS_FIXES MSG_WriteByte(msg, svc_time); MSG_WriteFloat(msg, g_psv.time); @@ -1443,7 +1455,7 @@ void SV_WriteSpawn(sizebuf_t *msg) SV_FullClientUpdate(client, msg); } - for (i = 0; i < 64; i++) + for (i = 0; i < ARRAYSIZE( g_psv.lightstyles ); i++) { MSG_WriteByte(msg, svc_lightstyle); MSG_WriteByte(msg, i); @@ -1714,6 +1726,7 @@ int SV_GetFragmentSize(void *state) const char *val = Info_ValueForKey(cl->userinfo, "cl_dlmax"); if (val[0] != 0) { + size = Q_atoi( val ); size = clamp(size, 256, 1024); } } @@ -1736,7 +1749,7 @@ qboolean SV_FilterUser(USERID_t *userid) else { if (i + 1 < j) - memcpy(filter, &filter[1], sizeof(userfilter_t) * (j - i + 1)); + memmove(filter, &filter[1], sizeof(userfilter_t) * (j - i + 1)); numuserfilters = --j; } @@ -4375,7 +4388,10 @@ void SV_WriteEntitiesToClient(client_t *client, sizebuf_t *msg) gEntityInterface.pfnSetupVisibility((edict_t*)client->pViewEntity, client->edict, &pvs, &pas); unsigned char *pSet = pvs; +#ifndef REHLDS_FIXES + // don't reallocate entity states SV_ClearPacketEntities(frame); +#endif // REHLDS_FIXES packet_entities_t *pack = &frame->entities; fullpack.num_entities = 0; @@ -4383,6 +4399,33 @@ void SV_WriteEntitiesToClient(client_t *client, sizebuf_t *msg) int flags = client->lw != 0; +#ifdef REHLDS_FIXES + int e; + + for (e = 1; e <= g_psvs.maxclients; e++) + { + client_t *cl = &g_psvs.clients[e - 1]; + if( ( !cl->active && !cl->spawned ) || cl->proxy ) + continue; + + qboolean add = gEntityInterface.pfnAddToFullPack(&fullpack.entities[fullpack.num_entities], e, &g_psv.edicts[e], host_client->edict, flags, TRUE, pSet); + if (add) + ++fullpack.num_entities; + } + + for (; e < g_psv.num_edicts; e++) + { + if (fullpack.num_entities >= MAX_PACKET_ENTITIES) + { + Con_DPrintf("Too many entities in visible packet list.\n"); + break; + } + + qboolean add = gEntityInterface.pfnAddToFullPack(&fullpack.entities[fullpack.num_entities], e, &g_psv.edicts[e], host_client->edict, flags, FALSE, pSet); + if (add) + ++fullpack.num_entities; + } +#else // REHLDS_FIXES for (int e = 1; e < g_psv.num_edicts; e++) { edict_t *ent = &g_psv.edicts[e]; @@ -4396,7 +4439,7 @@ void SV_WriteEntitiesToClient(client_t *client, sizebuf_t *msg) player = 1; } - if (fullpack.num_entities >= 256) + if (fullpack.num_entities >= MAX_PACKET_ENTITIES) { Con_DPrintf("Too many entities in visible packet list.\n"); break; @@ -4406,6 +4449,7 @@ void SV_WriteEntitiesToClient(client_t *client, sizebuf_t *msg) if (add) ++fullpack.num_entities; } +#endif // REHLDS_FIXES SV_AllocPacketEntities(frame, fullpack.num_entities); if (pack->num_entities) @@ -4490,7 +4534,12 @@ void SV_UpdateToReliableMessages(void) host_client = client; +#ifdef REHLDS_FIXES + // skip update in this frame if would overflow + if (client->sendinfo && client->sendinfo_time <= realtime && ( 1 + 1 + 4 + ( int )strlen( client->userinfo ) + 1 + 16 + g_psv.reliable_datagram.cursize <= g_psv.reliable_datagram.maxsize ) ) +#else // REHLDS_FIXES if (client->sendinfo && client->sendinfo_time <= realtime) +#endif // REHLDS_FIXES { client->sendinfo = FALSE; client->sendinfo_time = realtime + 1.0; @@ -4800,7 +4849,7 @@ int SV_ModelIndex(const char *name) if (!name || !name[0]) return 0; - for (int i = 0; i < 512; i++) + for (int i = 0; i < HL_MODEL_MAX; i++) { if (!g_psv.model_precache[i]) break; @@ -4896,7 +4945,11 @@ void SV_CreateResourceList(void) event_t *ep; g_psv.num_resources = 0; +#ifdef REHLDS_CHECKS + for (i = 1, s = &g_psv.generic_precache[1]; i < HL_GENERIC_MAX && *s != NULL; i++, s++) +#else // REHLDS_CHECKS for (i = 1, s = &g_psv.generic_precache[1]; *s != NULL; i++, s++) +#endif // REHLDS_CHECKS { if (g_psvs.maxclients > 1) nSize = FS_FileSize(*s); @@ -4905,7 +4958,11 @@ void SV_CreateResourceList(void) SV_AddResource(t_generic, *s, nSize, 1, i); } +#ifdef REHLDS_CHECKS + for (i = 1, s = &g_psv.sound_precache[1]; i < HL_SOUND_MAX && *s != NULL; i++, s++) +#else // REHLDS_CHECKS for (i = 1, s = &g_psv.sound_precache[1]; *s != NULL; i++, s++) +#endif // REHLDS_CHECKS { if (**s == '!') { @@ -4923,7 +4980,11 @@ void SV_CreateResourceList(void) SV_AddResource(t_sound, *s, nSize, 0, i); } } +#ifdef REHLDS_CHECKS + for (i = 1, s = &g_psv.model_precache[1]; i < HL_MODEL_MAX && *s != NULL; i++, s++) +#else // REHLDS_CHECKS for (i = 1, s = &g_psv.model_precache[1]; *s != NULL; i++, s++) +#endif // REHLDS_CHECKS { if (g_psvs.maxclients > 1 && **s != '*') nSize = FS_FileSize(*s); @@ -4935,7 +4996,7 @@ void SV_CreateResourceList(void) for (i = 0; i < sv_decalnamecount; i++) SV_AddResource(t_decal, sv_decalnames[i].name, Draw_DecalSize(i), 0, i); - for (i = 1; i < 255; i++) + for (i = 1; i < HL_EVENT_MAX; i++) { ep = &g_psv.event_precache[i]; if (!ep->filename) @@ -4950,7 +5011,7 @@ void SV_ClearCaches(void) { int i; event_t *ep; - for (i = 1; i < 255; i++) + for (i = 1; i < HL_EVENT_MAX; i++) { ep = &g_psv.event_precache[i]; if (ep->filename == NULL) diff --git a/rehlds/engine/sv_user.cpp b/rehlds/engine/sv_user.cpp index be09f32..74f6ed7 100644 --- a/rehlds/engine/sv_user.cpp +++ b/rehlds/engine/sv_user.cpp @@ -215,12 +215,26 @@ void SV_ParseConsistencyResponse(client_t *pSenderClient) if (c > 0) { char dropmessage[256]; +#ifdef REHLDS_FIXES + dropmessage[0] = '\0'; + + if (gEntityInterface.pfnInconsistentFile(host_client->edict, g_psv.resourcelist[c - 1].szFileName, dropmessage)) + { + if (dropmessage[0]) + SV_ClientPrintf("%s", dropmessage); + + SV_DropClient(host_client, 0, "Bad file %s", g_psv.resourcelist[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)) { if (Q_strlen(dropmessage) > 0) SV_ClientPrintf("%s", dropmessage); + SV_DropClient(host_client, 0, "Bad file %s", dropmessage); } +#endif // REHLDS_FIXES + return; } @@ -230,7 +244,7 @@ void SV_ParseConsistencyResponse(client_t *pSenderClient) /* ../engine/sv_user.c:267 */ qboolean SV_FileInConsistencyList(const char *filename, consistency_t **ppconsist) { - for (int i = 0; i < 512; i++) + for (int i = 0; i < ARRAYSIZE(g_psv.consistency_list); i++) { if (!g_psv.consistency_list[i].filename) return 0; @@ -277,10 +291,6 @@ int SV_TransferConsistencyInfo(void) if (r->type == t_model) { - if (pc->check_type <= 0 || pc->check_type > 3) - { - - } if (pc->check_type == force_model_samebounds) { vec3_t mins; @@ -1784,8 +1794,16 @@ void SV_FullUpdate_f(void) return; } s_LastFullUpdate[entIndex] = g_psv.time; + +#ifdef REHLDS_FIXES + // it's not need until not active + SV_ForceFullClientsUpdate(); + gEntityInterface.pfnClientCommand( sv_player ); +#endif // REHLDS_FIXES } +#ifndef REHLDS_FIXES SV_ForceFullClientsUpdate(); gEntityInterface.pfnClientCommand(sv_player); +#endif // REHLDS_FIXES }