From c19eb950adc283c31ce24cf402e5590b74662147 Mon Sep 17 00:00:00 2001 From: Krill Date: Mon, 22 Jun 2026 18:44:31 -0500 Subject: [PATCH 1/2] Add Anti-Cheat (account+character) and DebugVis marker-pool DB updates (matching server PRs) Co-Authored-By: Claude Opus 4.8 (1M context) --- ...2_04_002_Character_Anticheat_Violation.sql | 120 +++++++++++++++++ .../Rel22_04_039_DebugVis_Marker_Pool.sql | 125 ++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 Character/Updates/Rel22/Rel22_04_002_Character_Anticheat_Violation.sql create mode 100644 World/Updates/Rel22/Rel22_04_039_DebugVis_Marker_Pool.sql diff --git a/Character/Updates/Rel22/Rel22_04_002_Character_Anticheat_Violation.sql b/Character/Updates/Rel22/Rel22_04_002_Character_Anticheat_Violation.sql new file mode 100644 index 0000000..a6f6d67 --- /dev/null +++ b/Character/Updates/Rel22/Rel22_04_002_Character_Anticheat_Violation.sql @@ -0,0 +1,120 @@ +-- ---------------------------------------------------------------- +-- This is an attempt to create a full transactional MaNGOS update +-- Now compatible with newer MySql Databases (v1.5) +-- ---------------------------------------------------------------- +DROP PROCEDURE IF EXISTS `update_mangos`; + +DELIMITER $$ + +CREATE DEFINER=`root`@`localhost` PROCEDURE `update_mangos`() +BEGIN + DECLARE bRollback BOOL DEFAULT FALSE ; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `bRollback` = TRUE; + + -- Current Values (TODO - must be a better way to do this) + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `structure` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + + -- Expected Values + SET @cOldVersion = '22'; + SET @cOldStructure = '04'; + SET @cOldContent = '001'; + + -- New Values + SET @cNewVersion = '22'; + SET @cNewStructure = '04'; + SET @cNewContent = '002'; + -- DESCRIPTION IS 30 Characters MAX + SET @cNewDescription = 'Character_Anticheat_Violation'; + + -- COMMENT is 150 Characters MAX + SET @cNewComment = 'Add character_anticheat_violation table: persisted anti-cheat / movement-validation detection events recorded by AntiCheatMgr.'; + + -- Evaluate all settings + SET @cCurResult := (SELECT `description` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @oldResult := (SELECT `description` FROM `db_version` WHERE `version`=@cOldVersion AND `structure`=@cOldStructure AND `content`=@cOldContent); + SET @newResult := (SELECT `description` FROM `db_version` WHERE `version`=@cNewVersion AND `structure`=@cNewStructure AND `content`=@cNewContent); + + IF (@cCurResult = @oldResult) THEN -- Does the current version match the expected version + -- APPLY UPDATE + START TRANSACTION; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- PLACE UPDATE SQL BELOW -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + + -- Anti-Cheat / Movement-Validation framework (Slice 1) + -- Character database: persisted detection events. + -- Consumed by AntiCheatMgr::RecordViolation (insert) and `.anticheat report` (select). + -- Apply to the characters database (e.g. character0). + + CREATE TABLE IF NOT EXISTS `character_anticheat_violation` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `guid` INT UNSIGNED NOT NULL COMMENT 'character low-guid', + `account` INT UNSIGNED NOT NULL DEFAULT 0, + `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `type` TINYINT UNSIGNED NOT NULL COMMENT 'AntiCheatViolationType', + `score` SMALLINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'decayed score at event time', + `map` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `x` FLOAT NOT NULL DEFAULT 0, + `y` FLOAT NOT NULL DEFAULT 0, + `z` FLOAT NOT NULL DEFAULT 0, + `speed` FLOAT NOT NULL DEFAULT 0, + `latency` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `detail` VARCHAR(128) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + KEY `idx_guid_time` (`guid`, `time`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Anti-cheat detection events'; + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- PLACE UPDATE SQL ABOVE -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + + -- If we get here ok, commit the changes + IF bRollback = TRUE THEN + ROLLBACK; + SHOW ERRORS; + SELECT '* UPDATE FAILED *' AS `===== Status =====`,@cCurResult AS `===== DB is on Version: =====`; + ELSE + COMMIT; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- UPDATE THE DB VERSION + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + INSERT INTO `db_version` VALUES (@cNewVersion, @cNewStructure, @cNewContent, @cNewDescription, @cNewComment); + SET @newResult := (SELECT `description` FROM `db_version` WHERE `version`=@cNewVersion AND `structure`=@cNewStructure AND `content`=@cNewContent); + + SELECT '* UPDATE COMPLETE *' AS `===== Status =====`,@newResult AS `===== DB is now on Version =====`; + END IF; + ELSE -- Current version is not the expected version + IF (@cCurResult = @newResult) THEN -- Does the current version match the new version + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@cCurResult AS `===== DB is already on Version =====`; + ELSE -- Current version is not one related to this update + IF(@cCurResult IS NULL) THEN -- Something has gone wrong + SELECT '* UPDATE FAILED *' AS `===== Status =====`,'Unable to locate DB Version Information' AS `============= Error Message =============`; + ELSE + IF(@oldResult IS NULL) THEN -- Something has gone wrong + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `STRUCTURE` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `Content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurOutput = CONCAT(@cCurVersion, '_', @cCurStructure, '_', @cCurContent, ' - ',@cCurResult); + SET @oldResult = CONCAT('Rel',@cOldVersion, '_', @cOldStructure, '_', @cOldContent, ' - ','IS NOT APPLIED'); + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@oldResult AS `=== Expected ===`,@cCurOutput AS `===== Found Version =====`; + ELSE + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `STRUCTURE` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `Content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurOutput = CONCAT(@cCurVersion, '_', @cCurStructure, '_', @cCurContent, ' - ',@cCurResult); + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@oldResult AS `=== Expected ===`,@cCurOutput AS `===== Found Version =====`; + END IF; + END IF; + END IF; + END IF; +END $$ + +DELIMITER ; + +-- Execute the procedure +CALL update_mangos(); + +-- Drop the procedure +DROP PROCEDURE IF EXISTS `update_mangos`; diff --git a/World/Updates/Rel22/Rel22_04_039_DebugVis_Marker_Pool.sql b/World/Updates/Rel22/Rel22_04_039_DebugVis_Marker_Pool.sql new file mode 100644 index 0000000..02042b5 --- /dev/null +++ b/World/Updates/Rel22/Rel22_04_039_DebugVis_Marker_Pool.sql @@ -0,0 +1,125 @@ +-- ---------------------------------------------------------------- +-- This is an attempt to create a full transactional MaNGOS update +-- Now compatible with newer MySql Databases (v1.5) +-- ---------------------------------------------------------------- +DROP PROCEDURE IF EXISTS `update_mangos`; + +DELIMITER $$ + +CREATE DEFINER=`root`@`localhost` PROCEDURE `update_mangos`() +BEGIN + DECLARE bRollback BOOL DEFAULT FALSE ; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `bRollback` = TRUE; + + -- Current Values (TODO - must be a better way to do this) + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `structure` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + + -- Expected Values + SET @cOldVersion = '22'; + SET @cOldStructure = '04'; + SET @cOldContent = '038'; + + -- New Values + SET @cNewVersion = '22'; + SET @cNewStructure = '04'; + SET @cNewContent = '039'; + -- DESCRIPTION IS 30 Characters MAX + SET @cNewDescription = 'DebugVis_Marker_Pool'; + + -- COMMENT is 150 Characters MAX + SET @cNewComment = 'Reserve gameobject_template entries 305000..305511 as a labeled-marker pool ring-allocated by the debug visualizer at runtime.'; + + -- Evaluate all settings + SET @cCurResult := (SELECT `description` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @oldResult := (SELECT `description` FROM `db_version` WHERE `version`=@cOldVersion AND `structure`=@cOldStructure AND `content`=@cOldContent); + SET @newResult := (SELECT `description` FROM `db_version` WHERE `version`=@cNewVersion AND `structure`=@cNewStructure AND `content`=@cNewContent); + + IF (@cCurResult = @oldResult) THEN -- Does the current version match the expected version + -- APPLY UPDATE + START TRANSACTION; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- PLACE UPDATE SQL BELOW -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + + -- DebugVis labeled-marker pool (Slice 13). + -- + -- Reserves a block of generic gameobject_template entries the debug visualizer + -- ring-allocates at runtime. Each labeled marker gets its own entry so the + -- client (which caches GO name/type per entry) shows that marker's verbose + -- tooltip. The model/colour is overridden per-instance via GAMEOBJECT_DISPLAYID, + -- so the template displayId here is only a harmless default. + -- + -- Range 305000..305511 sits just above the current MAX(entry) (~300153), so + -- sGOStorage's index array grows only marginally. + -- + -- type=10 = GAMEOBJECT_TYPE_GOOBER. This matters: the vanilla client only shows + -- a name tooltip / mouse-over highlight for *interactive* gameobjects. type=5 + -- GENERIC (decorative doodads: auras, columns) render but never show a tooltip, + -- so the per-instance hover label would be invisible. GOOBER shows the name on + -- hover with a harmless click. All goober data fields are 0 (no lock, no quest, + -- no spell), so clicking does nothing meaningful. Safe to re-run. + + DELETE FROM `gameobject_template` WHERE `entry` BETWEEN 305000 AND 305511; + + INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `faction`, `flags`, `size`) + WITH RECURSIVE seq(n) AS ( + SELECT 305000 + UNION ALL + SELECT n + 1 FROM seq WHERE n < 305511 + ) + SELECT n, 10, 263, 'DebugVis Marker', 0, 0, 1 FROM seq; + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- PLACE UPDATE SQL ABOVE -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + + -- If we get here ok, commit the changes + IF bRollback = TRUE THEN + ROLLBACK; + SHOW ERRORS; + SELECT '* UPDATE FAILED *' AS `===== Status =====`,@cCurResult AS `===== DB is on Version: =====`; + ELSE + COMMIT; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- UPDATE THE DB VERSION + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + INSERT INTO `db_version` VALUES (@cNewVersion, @cNewStructure, @cNewContent, @cNewDescription, @cNewComment); + SET @newResult := (SELECT `description` FROM `db_version` WHERE `version`=@cNewVersion AND `structure`=@cNewStructure AND `content`=@cNewContent); + + SELECT '* UPDATE COMPLETE *' AS `===== Status =====`,@newResult AS `===== DB is now on Version =====`; + END IF; + ELSE -- Current version is not the expected version + IF (@cCurResult = @newResult) THEN -- Does the current version match the new version + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@cCurResult AS `===== DB is already on Version =====`; + ELSE -- Current version is not one related to this update + IF(@cCurResult IS NULL) THEN -- Something has gone wrong + SELECT '* UPDATE FAILED *' AS `===== Status =====`,'Unable to locate DB Version Information' AS `============= Error Message =============`; + ELSE + IF(@oldResult IS NULL) THEN -- Something has gone wrong + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `STRUCTURE` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `Content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurOutput = CONCAT(@cCurVersion, '_', @cCurStructure, '_', @cCurContent, ' - ',@cCurResult); + SET @oldResult = CONCAT('Rel',@cOldVersion, '_', @cOldStructure, '_', @cOldContent, ' - ','IS NOT APPLIED'); + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@oldResult AS `=== Expected ===`,@cCurOutput AS `===== Found Version =====`; + ELSE + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `STRUCTURE` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `Content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurOutput = CONCAT(@cCurVersion, '_', @cCurStructure, '_', @cCurContent, ' - ',@cCurResult); + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@oldResult AS `=== Expected ===`,@cCurOutput AS `===== Found Version =====`; + END IF; + END IF; + END IF; + END IF; +END $$ + +DELIMITER ; + +-- Execute the procedure +CALL update_mangos(); + +-- Drop the procedure +DROP PROCEDURE IF EXISTS `update_mangos`; From ea79af6a3f295d31509ac9b80ea98b7fafb20dd6 Mon Sep 17 00:00:00 2001 From: Krill Date: Tue, 23 Jun 2026 08:06:47 -0500 Subject: [PATCH 2/2] Add Anti-Cheat and DebugVis command-table rows (matching server PRs) --- ...l22_04_040_Anticheat_DebugVis_Commands.sql | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 World/Updates/Rel22/Rel22_04_040_Anticheat_DebugVis_Commands.sql diff --git a/World/Updates/Rel22/Rel22_04_040_Anticheat_DebugVis_Commands.sql b/World/Updates/Rel22/Rel22_04_040_Anticheat_DebugVis_Commands.sql new file mode 100644 index 0000000..a8a0f6d --- /dev/null +++ b/World/Updates/Rel22/Rel22_04_040_Anticheat_DebugVis_Commands.sql @@ -0,0 +1,127 @@ +-- ---------------------------------------------------------------- +-- This is an attempt to create a full transactional MaNGOS update +-- Now compatible with newer MySql Databases (v1.5) +-- ---------------------------------------------------------------- +DROP PROCEDURE IF EXISTS `update_mangos`; + +DELIMITER $$ + +CREATE DEFINER=`root`@`localhost` PROCEDURE `update_mangos`() +BEGIN + DECLARE bRollback BOOL DEFAULT FALSE ; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `bRollback` = TRUE; + + -- Current Values (TODO - must be a better way to do this) + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `structure` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + + -- Expected Values + SET @cOldVersion = '22'; + SET @cOldStructure = '04'; + SET @cOldContent = '039'; + + -- New Values + SET @cNewVersion = '22'; + SET @cNewStructure = '04'; + SET @cNewContent = '040'; + -- DESCRIPTION IS 30 Characters MAX + SET @cNewDescription = 'Anticheat_DebugVis_Commands'; + + -- COMMENT is 150 Characters MAX + SET @cNewComment = 'Add .anticheat and .debug vis / .debug visual GM command-table rows mirroring the non-cluster GM commands added by the server PRs.'; + + -- Evaluate all settings + SET @cCurResult := (SELECT `description` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @oldResult := (SELECT `description` FROM `db_version` WHERE `version`=@cOldVersion AND `structure`=@cOldStructure AND `content`=@cOldContent); + SET @newResult := (SELECT `description` FROM `db_version` WHERE `version`=@cNewVersion AND `structure`=@cNewStructure AND `content`=@cNewContent); + + IF (@cCurResult = @oldResult) THEN -- Does the current version match the expected version + -- APPLY UPDATE + START TRANSACTION; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- PLACE UPDATE SQL BELOW -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + + -- Add the non-cluster Anti-Cheat and Debug Visualizer GM commands mirroring + -- the server-side command tables (Chat.cpp anticheatCommandTable / + -- debugVisCommandTable + .debug visual). Cluster (.cluster*) and gateway + -- (.gateway*) commands are intentionally EXCLUDED -- they are fork-specific + -- and not upstreamed. Security values map to this fork's AccountTypes enum + -- (SharedDefines/ServerDefines.h): SEC_GAMEMASTER=2, SEC_ADMINISTRATOR=3. + + INSERT INTO `command` (`id`, `command_text`, `security`, `help_text`) VALUES + (812,'anticheat',2,'Syntax: .anticheat $subcommand\r\n\r\nParent group for the Anti-Cheat console. Use a subcommand (status, top, report, reload, set, warn, jail, unjail, delete, test, rubberband, score) to inspect or manage detection state.'), + (813,'anticheat status',2,'Syntax: .anticheat status [$playername]\r\n\r\nShows the current Anti-Cheat detection state for a player (or yourself with no arg): active detectors, recent violation counts and current score.'), + (814,'anticheat top',2,'Syntax: .anticheat top [$count]\r\n\r\nLists the players with the highest current Anti-Cheat violation scores. Optional count limits how many rows are shown.'), + (815,'anticheat report',2,'Syntax: .anticheat report [$playername]\r\n\r\nPrints a detailed Anti-Cheat violation report for the named player (or yourself), breaking the score down by detector category.'), + (816,'anticheat reload',2,'Syntax: .anticheat reload\r\n\r\nReloads the Anti-Cheat configuration (thresholds, toggles and tunables) from the server config without a restart.'), + (817,'anticheat set',3,'Syntax: .anticheat set $option $value\r\n\r\nSets an Anti-Cheat runtime option (threshold or toggle) to the given value. Administrator-only.'), + (818,'anticheat warn',2,'Syntax: .anticheat warn $playername\r\n\r\nIssues an Anti-Cheat warning to the named player, raising their tracked violation state.'), + (819,'anticheat jail',2,'Syntax: .anticheat jail $playername\r\n\r\nJails (restricts/teleports to holding) the named player flagged by the Anti-Cheat system.'), + (820,'anticheat unjail',2,'Syntax: .anticheat unjail $playername\r\n\r\nReleases the named player from Anti-Cheat jail and clears the jailed state.'), + (821,'anticheat delete',3,'Syntax: .anticheat delete $playername\r\n\r\nDeletes the stored Anti-Cheat violation records for the named player. Administrator-only.'), + (822,'anticheat test',3,'Syntax: .anticheat test $detector\r\n\r\nFires a synthetic Anti-Cheat detection for the named detector to validate the pipeline. Administrator-only.'), + (823,'anticheat rubberband',2,'Syntax: .anticheat rubberband $playername\r\n\r\nForces a corrective rubberband (position snap-back) on the named player via the Anti-Cheat movement system.'), + (824,'anticheat score',3,'Syntax: .anticheat score $playername $value\r\n\r\nManually sets the Anti-Cheat violation score for the named player. Administrator-only.'), + (825,'debug vis',2,'Syntax: .debug vis $subcommand\r\n\r\nParent group for the in-game debug visualizer. Use a subcommand (cells, los, path, collision, height, clear) to spawn or clear diagnostic markers.'), + (826,'debug vis cells',2,'Syntax: .debug vis cells\r\n\r\nVisualizes the grid/cell boundaries around your current position using debug markers.'), + (827,'debug vis los',2,'Syntax: .debug vis los\r\n\r\nVisualizes the line-of-sight ray from you to your target, marking blocking geometry.'), + (828,'debug vis path',2,'Syntax: .debug vis path\r\n\r\nVisualizes the navmesh path your selected creature would take to its current destination.'), + (829,'debug vis collision',2,'Syntax: .debug vis collision\r\n\r\nVisualizes nearby VMAP/collision geometry around your current position with debug markers.'), + (830,'debug vis height',2,'Syntax: .debug vis height\r\n\r\nVisualizes sampled terrain/VMAP height under and around your current position.'), + (831,'debug vis clear',2,'Syntax: .debug vis clear\r\n\r\nRemoves all debug-visualizer markers previously spawned by the .debug vis commands.'), + (832,'debug visual',2,'Syntax: .debug visual\r\n\r\nToggles or spawns a debug visual marker at your current position for quick on-the-fly checks.'); + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- PLACE UPDATE SQL ABOVE -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + + -- If we get here ok, commit the changes + IF bRollback = TRUE THEN + ROLLBACK; + SHOW ERRORS; + SELECT '* UPDATE FAILED *' AS `===== Status =====`,@cCurResult AS `===== DB is on Version: =====`; + ELSE + COMMIT; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- UPDATE THE DB VERSION + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + INSERT INTO `db_version` VALUES (@cNewVersion, @cNewStructure, @cNewContent, @cNewDescription, @cNewComment); + SET @newResult := (SELECT `description` FROM `db_version` WHERE `version`=@cNewVersion AND `structure`=@cNewStructure AND `content`=@cNewContent); + + SELECT '* UPDATE COMPLETE *' AS `===== Status =====`,@newResult AS `===== DB is now on Version =====`; + END IF; + ELSE -- Current version is not the expected version + IF (@cCurResult = @newResult) THEN -- Does the current version match the new version + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@cCurResult AS `===== DB is already on Version =====`; + ELSE -- Current version is not one related to this update + IF(@cCurResult IS NULL) THEN -- Something has gone wrong + SELECT '* UPDATE FAILED *' AS `===== Status =====`,'Unable to locate DB Version Information' AS `============= Error Message =============`; + ELSE + IF(@oldResult IS NULL) THEN -- Something has gone wrong + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `STRUCTURE` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `Content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurOutput = CONCAT(@cCurVersion, '_', @cCurStructure, '_', @cCurContent, ' - ',@cCurResult); + SET @oldResult = CONCAT('Rel',@cOldVersion, '_', @cOldStructure, '_', @cOldContent, ' - ','IS NOT APPLIED'); + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@oldResult AS `=== Expected ===`,@cCurOutput AS `===== Found Version =====`; + ELSE + SET @cCurVersion := (SELECT `version` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurStructure := (SELECT `STRUCTURE` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurContent := (SELECT `Content` FROM `db_version` ORDER BY `version` DESC, `STRUCTURE` DESC, `CONTENT` DESC LIMIT 0,1); + SET @cCurOutput = CONCAT(@cCurVersion, '_', @cCurStructure, '_', @cCurContent, ' - ',@cCurResult); + SELECT '* UPDATE SKIPPED *' AS `===== Status =====`,@oldResult AS `=== Expected ===`,@cCurOutput AS `===== Found Version =====`; + END IF; + END IF; + END IF; + END IF; +END $$ + +DELIMITER ; + +-- Execute the procedure +CALL update_mangos(); + +-- Drop the procedure +DROP PROCEDURE IF EXISTS `update_mangos`;