From 9411ce53876f45d75febbe6ba0a96650bef357a0 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 18 Sep 2025 12:45:22 +0100 Subject: [PATCH] Environment::read/writeModuleName: Convert lumpnums to a netsafe form for transit - Introduces new functions - W_LumpIntoNetSave - W_LumpFromNetSave - Essentially shims the upper 16 bits to account for unimportant files --- src/acs/vm/ACSVM/Environment.cpp | 10 +++- src/w_wad.cpp | 87 ++++++++++++++++++++++++++++++++ src/w_wad.h | 3 ++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/acs/vm/ACSVM/Environment.cpp b/src/acs/vm/ACSVM/Environment.cpp index 6461ec514..3a2af3c40 100644 --- a/src/acs/vm/ACSVM/Environment.cpp +++ b/src/acs/vm/ACSVM/Environment.cpp @@ -25,6 +25,7 @@ #include "Script.hpp" #include "Serial.hpp" #include "Thread.hpp" +#include "../../../w_wad.h" #include #include @@ -596,7 +597,12 @@ namespace ACSVM ModuleName Environment::readModuleName(Serial &in) const { auto s = readString(in); - auto i = ReadVLN(in); + size_t i = ReadVLN(in); + + if ((i = W_LumpFromNetSave(i)) == LUMPERROR) + { + CONS_Debug(DBG_GAMELOGIC, "lumpnum not found for ACS module '%s'\n", s->str); + } return {s, nullptr, i}; } @@ -768,7 +774,7 @@ namespace ACSVM void Environment::writeModuleName(Serial &out, ModuleName const &in) const { writeString(out, in.s); - WriteVLN(out, in.i); + WriteVLN(out, W_LumpIntoNetSave(in.i)); } // diff --git a/src/w_wad.cpp b/src/w_wad.cpp index b188c2a00..e69d4b36d 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1634,6 +1634,93 @@ UINT8 W_LumpExists(const char *name) return false; } +// Thanks to the introduction of "client side WAD files", +// a notion which is insanity in any other branch of DOOM, +// any direct wadnum ID is not a guaranteed index (and +// lumpnum_t, which has it in their upper bits, suffer too) +// We can do an O(n) conversion back and forth, which is +// better than nothing, but still kind of annoying to do. +// It was either this or killing musicwads lmao ~toast 180925 + +lumpnum_t W_LumpIntoNetSave(lumpnum_t lump) +{ + UINT32 wad = (lump >> 16); + if (lump == LUMPERROR // Bad already + || wad < mainwads) // Same between client/server + { + // Give what we get. + return lump; + } + + if (wad >= numwadfiles // Outside of range + || !wadfiles[wad]->important) // Can't convert local lumpnum + { + // No good return result! + return LUMPERROR; + } + + // Count previous local files the client might not have. + UINT32 i = (mainwads + musicwads), localoffset = 0; + for (; i < wad; i++) + { + if (wadfiles[i]->important) + continue; + + localoffset++; + } + + if (!localoffset) + { + // No local files, return unchanged. + return lump; + } + + if (localoffset <= wad) + { + // Success, return with the conversion. + return ((wad - localoffset) << 16) | (lump & UINT16_MAX); + } + + // Death!! + return LUMPERROR; +} + +lumpnum_t W_LumpFromNetSave(lumpnum_t lump) +{ + UINT32 netwad = (lump >> 16); + if (lump == LUMPERROR // Bad already + || netwad < mainwads) // Same between client/server + { + // Give what we get. + return lump; + } + + // Count previous local files the server would ignore. + UINT32 i = (mainwads + musicwads), localoffset = 0; + for (; (i - localoffset) <= netwad && i < numwadfiles; i++) + { + if (wadfiles[i]->important) + continue; + + localoffset++; + } + + if (!localoffset) + { + // No local files, return unchanged. + return lump; + } + + if (netwad + localoffset < numwadfiles) + { + // Success, return with the conversion. + return ((netwad + localoffset) << 16) | (lump & UINT16_MAX); + } + + // Death!! + return LUMPERROR; +} + size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump) { if (!TestValidLump(wad, lump)) diff --git a/src/w_wad.h b/src/w_wad.h index 06553ea28..7024826dc 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -188,6 +188,9 @@ lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, con lumpnum_t W_CheckNumForNameInFolder(const char *lump, const char *folder); UINT8 W_LumpExists(const char *name); // Lua uses this. +lumpnum_t W_LumpIntoNetSave(lumpnum_t lump); +lumpnum_t W_LumpFromNetSave(lumpnum_t lump); + size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump); size_t W_LumpLength(lumpnum_t lumpnum);