Skip to content

Commit

Permalink
Support hashed format for entity string overrides.
Browse files Browse the repository at this point in the history
For compatibility with YQ2 mapfixes.

(cherry picked from commit 5b2d9f2)
  • Loading branch information
skullernet authored and res2k committed Jan 18, 2025
1 parent 1766086 commit d5c2fe3
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 33 deletions.
2 changes: 1 addition & 1 deletion inc/common/cmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void CM_Init(void);

void CM_FreeMap(cm_t *cm);
int CM_LoadMap(cm_t *cm, const char *name);
void CM_LoadOverrides(cm_t *cm, char *server, size_t server_size);
void CM_LoadOverride(cm_t *cm, char *server, size_t server_size);

const mnode_t *CM_NodeNum(const cm_t *cm, int number);
const mleaf_t *CM_LeafNum(const cm_t *cm, int number);
Expand Down
81 changes: 50 additions & 31 deletions src/common/cmodel.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/cmd.h"
#include "common/cmodel.h"
#include "common/common.h"
#include "common/crc.h"
#include "common/cvar.h"
#include "common/files.h"
#include "common/math.h"
Expand Down Expand Up @@ -50,20 +51,43 @@ enum {
OVERRIDE_ALL = MASK(3)
};

static void load_entstring_override(cm_t *cm, const char *server)
static void load_entstring_override(cm_t *cm)
{
char buffer[MAX_QPATH], *data = NULL;
int ret;
char buffer[MAX_QPATH], name[MAX_QPATH], *data = NULL;
const bsp_t *bsp = cm->cache;
const char *path = map_override_path->string;
int ret, crc = 0;

if (!*path)
return;

if (!Com_ParseMapName(name, bsp->name, sizeof(name)))
return;

if (Q_snprintf(buffer, sizeof(buffer), "%s/%s.ent", map_override_path->string, server) >= sizeof(buffer)) {
// last byte is excluded from CRC (why?)
if (bsp->numentitychars > 0)
crc = CRC_Block((const byte *)bsp->entitystring, bsp->numentitychars - 1);

// load entity string from `<mapname>@<hash>.ent'
if (Q_snprintf(buffer, sizeof(buffer), "%s/%s@%04x.ent", path, name, crc) >= sizeof(buffer)) {
ret = Q_ERR(ENAMETOOLONG);
goto fail;
}

ret = FS_LoadFileEx(buffer, (void **)&data, 0, TAG_CMODEL);
if (!data) {
if (ret == Q_ERR(ENOENT))
return;

// fall back to no hash
if (ret == Q_ERR(ENOENT)) {
Q_snprintf(buffer, sizeof(buffer), "%s/%s.ent", path, name);
ret = FS_LoadFileEx(buffer, (void **)&data, 0, TAG_CMODEL);
}
if (ret == Q_ERR(ENOENT))
return;

if (ret < 0)
goto fail;

if (ret < 2) {
ret = Q_ERR_FILE_TOO_SMALL;
goto fail;
}

Expand All @@ -77,14 +101,28 @@ static void load_entstring_override(cm_t *cm, const char *server)
Com_EPrintf("Couldn't load entity string from %s: %s\n", buffer, Q_ErrorString(ret));
}

static void load_binary_override(cm_t *cm, char *server, size_t server_size)
/*
==================
CM_LoadOverride
Load R1Q2-style binary override file.
Must be called before CM_LoadMap().
May modify server buffer if name override is in effect.
May allocate enstring, must be freed with CM_FreeMap().
==================
*/
void CM_LoadOverride(cm_t *cm, char *server, size_t server_size)
{
sizebuf_t sz;
char buffer[MAX_QPATH];
byte *data = NULL;
int ret, bits, len;
char *buf, name_buf[MAX_QPATH];

if (!*map_override_path->string)
return;

if (Q_snprintf(buffer, sizeof(buffer), "%s/%s.bsp.override", map_override_path->string, server) >= sizeof(buffer)) {
ret = Q_ERR(ENAMETOOLONG);
goto fail;
Expand Down Expand Up @@ -141,28 +179,6 @@ static void load_binary_override(cm_t *cm, char *server, size_t server_size)
FS_FreeFile(data);
}

/*
==================
CM_LoadOverrides
Ugly hack to override entstring and other parameters.
Must be called before CM_LoadMap.
May modify server buffer if name override is in effect.
May allocate enstring, must be freed with CM_FreeMap().
==================
*/
void CM_LoadOverrides(cm_t *cm, char *server, size_t server_size)
{
if (!*map_override_path->string)
return;

load_binary_override(cm, server, server_size);

if (!(cm->override_bits & OVERRIDE_ENTS))
load_entstring_override(cm, server);
}

/*
==================
CM_FreeMap
Expand Down Expand Up @@ -196,6 +212,9 @@ int CM_LoadMap(cm_t *cm, const char *name)
if (!cm->cache)
return ret;

if (!(cm->override_bits & OVERRIDE_ENTS))
load_entstring_override(cm);

if (!(cm->override_bits & OVERRIDE_CSUM))
cm->checksum = cm->cache->checksum;

Expand Down
2 changes: 1 addition & 1 deletion src/server/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ static bool parse_and_check_server(mapcmd_t *cmd, const char *server, bool nexts
break;

default:
CM_LoadOverrides(&cmd->cm, cmd->server, sizeof(cmd->server)); // may override server!
CM_LoadOverride(&cmd->cm, cmd->server, sizeof(cmd->server)); // may override server!
if (Q_concat(expanded, sizeof(expanded), "maps/", cmd->server, ".bsp") < sizeof(expanded))
ret = CM_LoadMap(&cmd->cm, expanded);
if (ret < 0) {
Expand Down

0 comments on commit d5c2fe3

Please sign in to comment.