From 5e3050c2d31b135ce858d63731d3e46ce9c6a8af Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 17 May 2026 13:32:57 -0300 Subject: [PATCH] feat(Core/DB): split debug command RBAC into three permission tiers (#25882) Co-authored-by: Claude Sonnet 4.6 --- .../pending_db_auth/rev_debug_rbac_tiers.sql | 34 ++++++ src/server/game/Accounts/RBAC.h | 2 + src/server/scripts/Commands/cs_debug.cpp | 106 +++++++++--------- 3 files changed, 89 insertions(+), 53 deletions(-) create mode 100644 data/sql/updates/pending_db_auth/rev_debug_rbac_tiers.sql diff --git a/data/sql/updates/pending_db_auth/rev_debug_rbac_tiers.sql b/data/sql/updates/pending_db_auth/rev_debug_rbac_tiers.sql new file mode 100644 index 000000000..1c0150c6e --- /dev/null +++ b/data/sql/updates/pending_db_auth/rev_debug_rbac_tiers.sql @@ -0,0 +1,34 @@ +-- Split RBAC_PERM_COMMAND_DEBUG (300) into three permission tiers: +-- +-- 300 (Command: debug) -- state-modifying commands (unchanged) +-- 920 (Command: debug info) -- read-only / informational commands +-- 921 (Command: debug cosmetic) -- client-side / cosmetic commands +-- +-- Backward compatibility: perm 300 links to both 920 and 921, so any account +-- or role that already held perm 300 automatically receives the new sub-perms +-- via RBAC expansion. No existing setups are affected. +-- +-- Informational (920): threat, threatinfo, combat, hostile, getvalue, +-- getitemvalue, getitemstate, lootrecipient, los, loot, visibilitydata, +-- objectcount, mapdata, factionchange, zonestats +-- +-- Cosmetic (921): play *, send (all except opcode/setphaseshift), anim, +-- areatriggers, boundary, wpgps +-- +-- State-modifying (300, unchanged): setbit, Mod32Value, setaurastate, +-- setitemvalue, setvalue, spawnvehicle, setvid, entervehicle, uws, update, +-- itemexpire, arena, bg, lfg, cooldown, moveflags, unitstate, dummy, +-- send opcode, send setphaseshift + +DELETE FROM `rbac_permissions` WHERE `id` IN (920, 921); +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(920, 'Command: debug info'), +(921, 'Command: debug cosmetic'); + +-- Existing holders of perm 300 automatically receive both new sub-perms. +-- Role 197 (GM Commands) already includes perm 300, so it reaches 920 and 921 +-- transitively — no direct links to role 197 are needed or added. +DELETE FROM `rbac_linked_permissions` WHERE `id` = 300 AND `linkedId` IN (920, 921); +INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES +(300, 920), +(300, 921); diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index d926ea791..26cd4c3c6 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -681,6 +681,8 @@ enum RBACPermissions RBAC_PERM_COMMAND_RESPAWN_GAMEOBJECT_GUID = 917, RBAC_PERM_COMMAND_RESPAWN_CREATURE_ENTRY = 918, RBAC_PERM_COMMAND_RESPAWN_GAMEOBJECT_ENTRY = 919, + RBAC_PERM_COMMAND_DEBUG_INFO = 920, + RBAC_PERM_COMMAND_DEBUG_COSMETIC = 921, // custom permissions 1000+ RBAC_PERM_MAX }; diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 401446077..9df9d39c5 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -58,71 +58,71 @@ public: { static ChatCommandTable debugPlayCommandTable = { - { "cinematic", HandleDebugPlayCinematicCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "movie", HandleDebugPlayMovieCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "sound", HandleDebugPlaySoundCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "music", HandleDebugPlayMusicCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "visual", HandleDebugVisualCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No } + { "cinematic", HandleDebugPlayCinematicCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "movie", HandleDebugPlayMovieCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "sound", HandleDebugPlaySoundCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "music", HandleDebugPlayMusicCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "visual", HandleDebugVisualCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No } }; static ChatCommandTable debugSendCommandTable = { - { "buyerror", HandleDebugSendBuyErrorCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "channelnotify", HandleDebugSendChannelNotifyCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "chatmessage", HandleDebugSendChatMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "equiperror", HandleDebugSendEquipErrorCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "largepacket", HandleDebugSendLargePacketCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "opcode", HandleDebugSendOpcodeCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "qpartymsg", HandleDebugSendQuestPartyMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "qinvalidmsg", HandleDebugSendQuestInvalidMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "sellerror", HandleDebugSendSellErrorCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "setphaseshift", HandleDebugSendSetPhaseShiftCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "spellfail", HandleDebugSendSpellFailCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No } + { "buyerror", HandleDebugSendBuyErrorCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "channelnotify", HandleDebugSendChannelNotifyCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "chatmessage", HandleDebugSendChatMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "equiperror", HandleDebugSendEquipErrorCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "largepacket", HandleDebugSendLargePacketCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "opcode", HandleDebugSendOpcodeCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "qpartymsg", HandleDebugSendQuestPartyMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "qinvalidmsg", HandleDebugSendQuestInvalidMsgCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "sellerror", HandleDebugSendSellErrorCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "setphaseshift", HandleDebugSendSetPhaseShiftCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "spellfail", HandleDebugSendSpellFailCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No } }; static ChatCommandTable debugCommandTable = { - { "setbit", HandleDebugSet32BitCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "threat", HandleDebugThreatListCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "threatinfo", HandleDebugThreatInfoCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "combat", HandleDebugCombatListCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "hostile", HandleDebugHostileRefListCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "anim", HandleDebugAnimCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "arena", HandleDebugArenaCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "bg", HandleDebugBattlegroundCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, - { "cooldown", HandleDebugCooldownCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "getitemstate", HandleDebugGetItemStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "lootrecipient", HandleDebugGetLootRecipientCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "getvalue", HandleDebugGetValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "getitemvalue", HandleDebugGetItemValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "Mod32Value", HandleDebugMod32ValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "setbit", HandleDebugSet32BitCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "threat", HandleDebugThreatListCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "threatinfo", HandleDebugThreatInfoCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "combat", HandleDebugCombatListCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "hostile", HandleDebugHostileRefListCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "anim", HandleDebugAnimCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "arena", HandleDebugArenaCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "bg", HandleDebugBattlegroundCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, + { "cooldown", HandleDebugCooldownCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "getitemstate", HandleDebugGetItemStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "lootrecipient", HandleDebugGetLootRecipientCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "getvalue", HandleDebugGetValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "getitemvalue", HandleDebugGetItemValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "Mod32Value", HandleDebugMod32ValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, { "play", debugPlayCommandTable }, { "send", debugSendCommandTable }, - { "setaurastate", HandleDebugSetAuraStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "setitemvalue", HandleDebugSetItemValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "setvalue", HandleDebugSetValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "spawnvehicle", HandleDebugSpawnVehicleCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "setvid", HandleDebugSetVehicleIdCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "entervehicle", HandleDebugEnterVehicleCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "uws", HandleDebugUpdateWorldStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "update", HandleDebugUpdateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "itemexpire", HandleDebugItemExpireCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "areatriggers", HandleDebugAreaTriggersCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "lfg", HandleDebugDungeonFinderCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, - { "loot", HandleDebugLootCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, - { "los", HandleDebugLoSCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "moveflags", HandleDebugMoveflagsCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "unitstate", HandleDebugUnitStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "objectcount", HandleDebugObjectCountCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, - { "dummy", HandleDebugDummyCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "mapdata", HandleDebugMapDataCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "boundary", HandleDebugBoundaryCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "visibilitydata", HandleDebugVisibilityDataCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, - { "factionchange", HandleDebugFactionChangeCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, - { "zonestats", HandleDebugZoneStatsCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes} + { "setaurastate", HandleDebugSetAuraStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "setitemvalue", HandleDebugSetItemValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "setvalue", HandleDebugSetValueCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "spawnvehicle", HandleDebugSpawnVehicleCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "setvid", HandleDebugSetVehicleIdCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "entervehicle", HandleDebugEnterVehicleCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "uws", HandleDebugUpdateWorldStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "update", HandleDebugUpdateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "itemexpire", HandleDebugItemExpireCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "areatriggers", HandleDebugAreaTriggersCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "lfg", HandleDebugDungeonFinderCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::Yes}, + { "loot", HandleDebugLootCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::Yes}, + { "los", HandleDebugLoSCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "moveflags", HandleDebugMoveflagsCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "unitstate", HandleDebugUnitStateCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "objectcount", HandleDebugObjectCountCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::Yes}, + { "dummy", HandleDebugDummyCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }, + { "mapdata", HandleDebugMapDataCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "boundary", HandleDebugBoundaryCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No }, + { "visibilitydata", HandleDebugVisibilityDataCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::No }, + { "factionchange", HandleDebugFactionChangeCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::Yes}, + { "zonestats", HandleDebugZoneStatsCommand, rbac::RBAC_PERM_COMMAND_DEBUG_INFO, Console::Yes} }; static ChatCommandTable commandTable = { { "debug", debugCommandTable }, - { "wpgps", HandleWPGPSCommand, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No } + { "wpgps", HandleWPGPSCommand, rbac::RBAC_PERM_COMMAND_DEBUG_COSMETIC, Console::No } }; return commandTable; }