Skip to content

🐛 GetNPCByID and GetMobByID emit spurious warnings for content-disabled entities #9617

@eyes-and-brain

Description

@eyes-and-brain

I affirm:

  • I understand that if I do not agree to the following points by completing the checkboxes my issue will be ignored.
  • I have read and understood the Contributing Guide and the Code of Conduct.
  • I have searched existing issues to see if the issue has already been opened, and I have checked the commit log to see if the issue has been resolved since my server was last updated.

Summary

When RESTRICT_CONTENT = 1 and one or more ENABLE_* flags are set to 0 in
settings/main.lua, any NPC or mob whose content_tag matches a disabled
expansion is intentionally skipped during LoadNPCList / LoadMOBList. However,
scripts that call GetNPCByID or GetMobByID on those IDs still trigger a
ShowWarning log entry, even though the absence of the entity is expected
behavior.

This floods the server log with false-positive warnings, making it harder to
spot genuine issues.

Reproduction steps

  1. Set RESTRICT_CONTENT = 1 in settings/main.lua.
  2. Set any expansion flag to 0, e.g. ENABLE_COP = 0.
  3. Start the map server.
  4. Observe repeated luautils::GetNPCByID NPC doesn't exist (XXXXXXXX) and
    luautils::GetMobByID Mob doesn't exist (XXXXXXXX) warnings in the log for
    NPCs / mobs whose content_tag is COP.

Expected behavior

No warning should be emitted when GetNPCByID / GetMobByID is called for an
entity that was intentionally excluded from loading due to its content_tag.

Proposed fix

After LoadNPCList and LoadMOBList complete, build an in-memory set of
disabled entity IDs by querying npc_list and mob_spawn_points JOIN mob_groups
for rows whose content_tag maps to a disabled ENABLE_* key. Then, in
GetNPCByID / GetMobByID, skip ShowWarning when the requested ID is found
in that set.

// zoneutils.h
extern std::unordered_set<uint32> disabledContentNpcIds;
extern std::unordered_set<uint32> disabledContentMobIds;
void BuildDisabledContentSets();

// zoneutils.cpp — called once after LoadNPCList + LoadMOBList
void BuildDisabledContentSets() {
    auto rsetNpc = db::preparedStmt(
        "SELECT npcid, content_tag FROM npc_list WHERE content_tag IS NOT NULL");
    while (rsetNpc->next()) {
        if (!luautils::IsContentEnabled(rsetNpc->get<std::string>("content_tag")))
            disabledContentNpcIds.insert(rsetNpc->get<uint32>("npcid"));
    }
    auto rsetMob = db::preparedStmt(
        "SELECT mob_spawn_points.mobid, mob_groups.content_tag "
        "FROM mob_spawn_points "
        "INNER JOIN mob_groups ON mob_spawn_points.groupid = mob_groups.groupid "
        "WHERE mob_groups.content_tag IS NOT NULL");
    while (rsetMob->next()) {
        if (!luautils::IsContentEnabled(rsetMob->get<std::string>("content_tag")))
            disabledContentMobIds.insert(rsetMob->get<uint32>("mobid"));
    }
}

// luautils.cpp — GetNPCByID
if (!PNpc) {
    if (zoneutils::disabledContentNpcIds.find(npcid) ==
        zoneutils::disabledContentNpcIds.end())
        ShowWarning("luautils::GetNPCByID NPC doesn't exist (%d)", npcid);
    return nullptr;
}

Environment

  • OS: Windows 11
  • Branch: base

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions