correct map issues clientside

but be loud about it instead of I_Error´ing
most of those would be fatal anyways, so screw vanilla desyncing if they crash eitherways
This commit is contained in:
alufolie91 committed 2026-06-22 20:53:49 +02:00
1 parent 568f29ed1c
commit 029c21eae8
4 files changed
+85 -27

No files matched your search

+3
View File
@@ -1310,6 +1310,7 @@ static void G_DoLoadLevel(boolean resetplayer)
{
// fail so reset game stuff
Command_ExitGame_f();
P_FreeCorruptMapWarnings();
return;
}
@@ -1343,6 +1344,8 @@ static void G_DoLoadLevel(boolean resetplayer)
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
// print any map errors now due to clearhud above :chaosleep:
P_PrintCorruptMapWarnings();
server_lagless = !cv_gentlemens.value;
+3
View File
@@ -3590,8 +3590,11 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
if (!P_SetupLevel(true, reloading))
{
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
P_FreeCorruptMapWarnings();
return false;
}
P_PrintCorruptMapWarnings();
}
else
{
+76 -27
View File
@@ -188,6 +188,57 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
I_Error("Invalid or corrupt map.\nLook in log file or text console for technical details.");
}
static char **mapwarnings = NULL;
static size_t nummapwarnings = 0;
// collect map errors we can fix clientside
// we then can print em when the map finishes loading
// so they actually appear and raise awareness shits fucked
// see G_DoLoadLevel as to why :chaosleep:
static void CorruptMapWarning(const char *msg)
{
#ifdef PARANOIA
// just error out
I_Error("%sThis WILL crash Vanilla clients!\n", msg);
#endif
nummapwarnings++;
mapwarnings = Z_Realloc(mapwarnings, nummapwarnings * sizeof(*mapwarnings), PU_STATIC, NULL);
mapwarnings[nummapwarnings-1] = Z_StrDup(msg);
}
void P_PrintCorruptMapWarnings(void)
{
size_t i;
if (!nummapwarnings)
return;
for (i = 0; i < nummapwarnings; i++)
{
CONS_Alert(CONS_ERROR, "%sAttempting to fix... This WILL crash Vanilla clients!\n", mapwarnings[i]);
}
P_FreeCorruptMapWarnings();
}
void P_FreeCorruptMapWarnings(void)
{
size_t i;
if (!nummapwarnings)
return;
for (i = 0; i < nummapwarnings; i++)
{
Z_Free(mapwarnings[i]);
mapwarnings[i] = NULL;
}
Z_Free(mapwarnings);
mapwarnings = NULL;
nummapwarnings = 0;
}
#define NUMLAPS_DEFAULT 3
static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
@@ -449,11 +500,10 @@ static void P_LoadSegs(UINT8 *data)
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
{
if ((unsigned)v1 >= numvertexes)
I_Error("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1);
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
if ((unsigned)v2 >= numvertexes)
I_Error("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2);
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
/*
if (li->sidedef == &sides[li->linedef->sidenum[0]])
{
li->v1 = lines[ml->linedef].v1;
@@ -464,7 +514,6 @@ static void P_LoadSegs(UINT8 *data)
li->v1 = lines[ml->linedef].v2;
li->v2 = lines[ml->linedef].v1;
}
*/
}
else
{
@@ -502,8 +551,8 @@ static void P_LoadSegs(UINT8 *data)
//e6y: fix wrong side index
if (rawside != 0 && rawside != 1)
{
I_Error("P_LoadSegs: seg %s contains wrong side index %d.\n", sizeu1(i), rawside);
//rawside = 1;
CorruptMapWarning(va("P_LoadSegs: seg %s contains wrong side index %d.\n", sizeu1(i), rawside));
rawside = 1;
}
//e6y: check for wrong indexes
@@ -521,8 +570,8 @@ static void P_LoadSegs(UINT8 *data)
* referencing the back of a 1S line */
if (ldef->sidenum[rawside] == NO_INDEX)
{
I_Error("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i));
//li->frontsector = 0;
CorruptMapWarning(va("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i)));
li->frontsector = NULL;
}
else
{
@@ -533,7 +582,7 @@ static void P_LoadSegs(UINT8 *data)
{
if (ldef->sidenum[rawside^1] == NO_INDEX)
{
I_Error("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i));
CorruptMapWarning(va("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i)));
li->backsector = NULL;
}
else
@@ -828,17 +877,17 @@ static void P_LoadNodes(UINT8 *data)
// haleyjd 11/06/10: check for invalid subsector reference
if (child >= numsubsectors)
{
I_Error("P_LoadNodes: BSP tree %s references invalid subsector %d\n", sizeu1(i), child);
//child = 0;
CorruptMapWarning(va("P_LoadNodes: BSP tree %s references invalid subsector %d\n", sizeu1(i), child));
child = 0;
}
child |= NF_SUBSECTOR;
}
else if (child >= numnodes)
{
I_Error("P_LoadNodes: BSP node %s references invalid node.\n", sizeu1(i));
CorruptMapWarning(va("P_LoadNodes: BSP node %s references invalid node.\n", sizeu1(i)));
//I_Error("P_LoadNodes: BSP node %d references invalid node %d.\n", sizeu1(i), Index(((node_t *)no->children[j])));
//child = 0;
child = 0;
}
no->children[j] = child;
@@ -1852,16 +1901,11 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
// http://www.doomworld.com/idgames/index.php?id=12935
if (!P_VerifyBlockMap(count))
{
#ifdef PARANOIA
I_Error("P_LoadBlockMap: erroneous BLOCKMAP lump may cause crashes.\n");
#endif
CONS_Alert(CONS_ERROR, "P_LoadBlockMap: erroneous BLOCKMAP lump may cause crashes.\n");
//Z_Free(blockmaplump);
//blockmaplump = NULL;
//return false; // ideally we would just let the game rebuild the blockmap
// but this has a chance of desynching vanilla clients
// not sure whats worse honestly and i do not want to decide that :chaosleep:
CorruptMapWarning(va("P_LoadBlockMap: corrupted or invalid BLOCKMAP lump! Check the log for more information.\n"));
// vanilla WILL crash here anyways so just rebuild it ourselves
Z_Free(blockmaplump);
blockmaplump = NULL;
return false;
}
// clear out mobj chains
@@ -2004,11 +2048,16 @@ static void P_LoadReject(UINT8 *data, size_t rejectsize)
{
if (rejectsize < neededsize)
{
#ifdef PARANOIA
I_Error("REJECT is %s byte%s too small. REJECT might be invalid and crash vanilla clients!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s");
#endif
CONS_Alert(CONS_ERROR, "REJECT is %s byte%s too small. REJECT might be invalid and crash vanilla clients!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s");
CorruptMapWarning(va("P_LoadReject: REJECT is %s byte%s too small. REJECT might be invalid!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s"));
#ifdef COMPAT_VANILLA
// we can pad this and somewhat prevent desyncs
// probs not cool if the reject is from a completely different map
// but whatever
allocsize = neededsize;
#else
rejectmatrix = NULL;
return;
#endif
}
rejectmatrix = Z_Calloc(allocsize, PU_LEVEL, NULL); // allocate memory for the reject matrix
+3
View File
@@ -114,6 +114,9 @@ size_t P_PrecacheLevelFlats(void);
void P_AllocMapHeader(INT16 i);
void P_PrintCorruptMapWarnings(void);
void P_FreeCorruptMapWarnings(void);
#ifdef __cplusplus
} // extern "C"
#endif