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.
  • Loading branch information
skullernet committed Jan 2, 2025
1 parent a5b8927 commit 5b2d9f2
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 @@ -286,7 +286,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 5b2d9f2

Please sign in to comment.