535 lines
18 KiB
SQL
535 lines
18 KiB
SQL
-- Playerbot Database Schema
|
|
-- This creates all necessary tables for the Playerbot module
|
|
|
|
-- --------------------------------------------------------
|
|
-- Account Management Tables
|
|
-- --------------------------------------------------------
|
|
|
|
-- Table: playerbot_accounts
|
|
-- Purpose: Track bot accounts and their metadata
|
|
CREATE TABLE IF NOT EXISTS `playerbot_accounts` (
|
|
`account_id` INT UNSIGNED NOT NULL,
|
|
`is_bot` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`character_count` INT UNSIGNED NOT NULL DEFAULT 0,
|
|
`last_login` TIMESTAMP NULL DEFAULT NULL,
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`account_id`),
|
|
KEY `idx_is_bot` (`is_bot`),
|
|
KEY `idx_is_active` (`is_active`),
|
|
KEY `idx_character_count` (`character_count`),
|
|
CONSTRAINT `chk_character_limit` CHECK (`character_count` <= 10)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Metadata for bot-controlled accounts';
|
|
|
|
-- --------------------------------------------------------
|
|
-- Name Management Tables
|
|
-- --------------------------------------------------------
|
|
|
|
-- Table: playerbots_names
|
|
-- Purpose: Pool of unique names for bot character generation
|
|
-- IMPORTANT: Each name can only be used ONCE across all characters
|
|
CREATE TABLE IF NOT EXISTS `playerbots_names` (
|
|
`name_id` INT(11) NOT NULL AUTO_INCREMENT,
|
|
`name` VARCHAR(255) NOT NULL,
|
|
`gender` TINYINT(3) UNSIGNED NOT NULL COMMENT '0 = male, 1 = female',
|
|
PRIMARY KEY (`name_id`),
|
|
UNIQUE KEY `name` (`name`),
|
|
KEY `idx_gender` (`gender`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
|
COMMENT='Random bot name pool';
|
|
|
|
-- Table: playerbots_names_used
|
|
-- Purpose: Track which names are currently in use
|
|
CREATE TABLE IF NOT EXISTS `playerbots_names_used` (
|
|
`name_id` INT(11) NOT NULL,
|
|
`character_guid` INT UNSIGNED NOT NULL,
|
|
`used_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`name_id`),
|
|
UNIQUE KEY `idx_character` (`character_guid`),
|
|
CONSTRAINT `fk_name_id` FOREIGN KEY (`name_id`)
|
|
REFERENCES `playerbots_names` (`name_id`) ON DELETE RESTRICT
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
|
COMMENT='Tracks which bot is using which name';
|
|
|
|
-- --------------------------------------------------------
|
|
-- Character Management Tables
|
|
-- --------------------------------------------------------
|
|
|
|
-- Table: playerbot_characters
|
|
-- Purpose: Track bot characters and their properties
|
|
CREATE TABLE IF NOT EXISTS `playerbot_characters` (
|
|
`guid` INT UNSIGNED NOT NULL,
|
|
`account_id` INT UNSIGNED NOT NULL,
|
|
`name` VARCHAR(50) NOT NULL,
|
|
`race` TINYINT UNSIGNED NOT NULL,
|
|
`class` TINYINT UNSIGNED NOT NULL,
|
|
`level` TINYINT UNSIGNED NOT NULL DEFAULT 1,
|
|
`role` ENUM('tank', 'healer', 'dps', 'hybrid') DEFAULT 'dps',
|
|
`last_login` TIMESTAMP NULL DEFAULT NULL,
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`guid`),
|
|
KEY `idx_account` (`account_id`),
|
|
KEY `idx_level` (`level`),
|
|
KEY `idx_role` (`role`),
|
|
CONSTRAINT `fk_bot_account` FOREIGN KEY (`account_id`)
|
|
REFERENCES `playerbot_accounts` (`account_id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Bot character metadata';
|
|
|
|
-- --------------------------------------------------------
|
|
-- Character Distribution Tables
|
|
-- --------------------------------------------------------
|
|
|
|
-- Table: playerbot_race_distribution
|
|
-- Purpose: Configurable race distribution for bot generation
|
|
CREATE TABLE IF NOT EXISTS `playerbot_race_distribution` (
|
|
`race` TINYINT UNSIGNED NOT NULL,
|
|
`weight` FLOAT NOT NULL DEFAULT 1.0,
|
|
`male_ratio` FLOAT NOT NULL DEFAULT 0.5,
|
|
`faction` ENUM('alliance', 'horde', 'neutral') NOT NULL,
|
|
`enabled` TINYINT(1) DEFAULT 1,
|
|
PRIMARY KEY (`race`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Race distribution weights for bot generation';
|
|
|
|
-- Insert default race distribution based on WoW statistics
|
|
INSERT INTO `playerbot_race_distribution` (`race`, `weight`, `male_ratio`, `faction`) VALUES
|
|
(1, 29.5, 0.52, 'alliance'), -- Human
|
|
(2, 8.7, 0.75, 'horde'), -- Orc
|
|
(3, 7.2, 0.75, 'alliance'), -- Dwarf
|
|
(4, 20.8, 0.35, 'alliance'), -- Night Elf
|
|
(5, 11.2, 0.70, 'horde'), -- Undead
|
|
(6, 6.4, 0.72, 'horde'), -- Tauren
|
|
(7, 5.3, 0.50, 'alliance'), -- Gnome
|
|
(8, 7.1, 0.70, 'horde'), -- Troll
|
|
(10, 35.8, 0.35, 'horde'), -- Blood Elf
|
|
(11, 8.9, 0.40, 'alliance') -- Draenei
|
|
ON DUPLICATE KEY UPDATE weight = VALUES(weight);
|
|
|
|
-- Table: playerbot_class_distribution
|
|
-- Purpose: Configurable class distribution for bot generation
|
|
CREATE TABLE IF NOT EXISTS `playerbot_class_distribution` (
|
|
`class` TINYINT UNSIGNED NOT NULL,
|
|
`weight` FLOAT NOT NULL DEFAULT 1.0,
|
|
`tank_capable` TINYINT(1) DEFAULT 0,
|
|
`healer_capable` TINYINT(1) DEFAULT 0,
|
|
`enabled` TINYINT(1) DEFAULT 1,
|
|
PRIMARY KEY (`class`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Class distribution weights for bot generation';
|
|
|
|
-- Insert default class distribution based on WoW statistics
|
|
INSERT INTO `playerbot_class_distribution` (`class`, `weight`, `tank_capable`, `healer_capable`) VALUES
|
|
(1, 9.8, 1, 0), -- Warrior
|
|
(2, 11.5, 1, 1), -- Paladin
|
|
(3, 11.8, 0, 0), -- Hunter
|
|
(4, 7.3, 0, 0), -- Rogue
|
|
(5, 8.7, 0, 1), -- Priest
|
|
(6, 9.2, 1, 0), -- Death Knight
|
|
(7, 6.2, 0, 1), -- Shaman
|
|
(8, 8.4, 0, 0), -- Mage
|
|
(9, 6.8, 0, 0), -- Warlock
|
|
(10, 1.5, 1, 1), -- Monk
|
|
(11, 10.9, 1, 1), -- Druid
|
|
(12, 7.9, 1, 0) -- Demon Hunter
|
|
ON DUPLICATE KEY UPDATE weight = VALUES(weight);
|
|
|
|
-- Table: playerbot_race_class_multipliers
|
|
-- Purpose: Adjust probability of specific race/class combinations
|
|
CREATE TABLE IF NOT EXISTS `playerbot_race_class_multipliers` (
|
|
`race` TINYINT UNSIGNED NOT NULL,
|
|
`class` TINYINT UNSIGNED NOT NULL,
|
|
`multiplier` FLOAT NOT NULL DEFAULT 1.0 COMMENT 'Higher = more common',
|
|
PRIMARY KEY (`race`, `class`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Race/class combination probability multipliers';
|
|
|
|
-- Insert popular combinations with higher multipliers
|
|
INSERT INTO `playerbot_race_class_multipliers` (`race`, `class`, `multiplier`) VALUES
|
|
(10, 2, 2.5), -- Blood Elf Paladin
|
|
(4, 12, 3.0), -- Night Elf Demon Hunter
|
|
(1, 2, 2.0), -- Human Paladin
|
|
(10, 3, 2.0), -- Blood Elf Hunter
|
|
(4, 11, 2.2), -- Night Elf Druid
|
|
(1, 1, 1.8), -- Human Warrior
|
|
(2, 1, 2.0), -- Orc Warrior
|
|
(5, 4, 1.8), -- Undead Rogue
|
|
(6, 11, 2.0), -- Tauren Druid
|
|
(3, 3, 1.8) -- Dwarf Hunter
|
|
ON DUPLICATE KEY UPDATE multiplier = VALUES(multiplier);
|
|
|
|
-- --------------------------------------------------------
|
|
-- Configuration Tables
|
|
-- --------------------------------------------------------
|
|
|
|
-- Table: playerbot_config
|
|
-- Purpose: Store runtime configuration values
|
|
CREATE TABLE IF NOT EXISTS `playerbot_config` (
|
|
`key` VARCHAR(100) NOT NULL,
|
|
`value` TEXT,
|
|
`description` TEXT,
|
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`key`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Runtime configuration for playerbot system';
|
|
|
|
-- Insert default configuration values
|
|
INSERT INTO `playerbot_config` (`key`, `value`, `description`) VALUES
|
|
('schema_version', '1', 'Database schema version'),
|
|
('max_characters_per_account', '10', 'Maximum characters per bot account'),
|
|
('strict_character_limit', '1', 'Enforce character limit strictly'),
|
|
('auto_fix_character_limit', '0', 'Automatically fix character limit violations')
|
|
ON DUPLICATE KEY UPDATE value = VALUES(value);
|
|
|
|
-- --------------------------------------------------------
|
|
-- Performance Monitoring Tables
|
|
-- --------------------------------------------------------
|
|
|
|
-- Table: playerbot_performance_metrics
|
|
-- Purpose: Track performance metrics for optimization
|
|
CREATE TABLE IF NOT EXISTS `playerbot_performance_metrics` (
|
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`metric_name` VARCHAR(100) NOT NULL,
|
|
`value` FLOAT NOT NULL,
|
|
`recorded_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_metric_time` (`metric_name`, `recorded_at`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Performance metrics tracking';
|
|
|
|
-- --------------------------------------------------------
|
|
-- Database Triggers for Character Count Management
|
|
-- --------------------------------------------------------
|
|
|
|
DELIMITER $$
|
|
|
|
-- Trigger: Update character count on character creation
|
|
DROP TRIGGER IF EXISTS `trg_bot_character_insert`$$
|
|
CREATE TRIGGER `trg_bot_character_insert`
|
|
AFTER INSERT ON `characters`
|
|
FOR EACH ROW
|
|
BEGIN
|
|
IF EXISTS (SELECT 1 FROM playerbot_accounts WHERE account_id = NEW.account AND is_bot = 1) THEN
|
|
UPDATE playerbot_accounts
|
|
SET character_count = character_count + 1
|
|
WHERE account_id = NEW.account;
|
|
END IF;
|
|
END$$
|
|
|
|
-- Trigger: Update character count on character deletion
|
|
DROP TRIGGER IF EXISTS `trg_bot_character_delete`$$
|
|
CREATE TRIGGER `trg_bot_character_delete`
|
|
AFTER DELETE ON `characters`
|
|
FOR EACH ROW
|
|
BEGIN
|
|
IF EXISTS (SELECT 1 FROM playerbot_accounts WHERE account_id = OLD.account AND is_bot = 1) THEN
|
|
UPDATE playerbot_accounts
|
|
SET character_count = GREATEST(0, character_count - 1)
|
|
WHERE account_id = OLD.account;
|
|
|
|
-- Also release the name
|
|
DELETE FROM playerbots_names_used WHERE character_guid = OLD.guid;
|
|
END IF;
|
|
END$$
|
|
|
|
DELIMITER ;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Indexes for Performance
|
|
-- --------------------------------------------------------
|
|
|
|
-- Helper procedure to add index if not exists (MySQL-compatible)
|
|
DROP PROCEDURE IF EXISTS `pb_safe_add_index`;
|
|
DELIMITER //
|
|
CREATE PROCEDURE `pb_safe_add_index`(
|
|
IN p_table VARCHAR(64),
|
|
IN p_index VARCHAR(64),
|
|
IN p_columns VARCHAR(255)
|
|
)
|
|
BEGIN
|
|
DECLARE index_exists INT DEFAULT 0;
|
|
|
|
SELECT COUNT(*) INTO index_exists
|
|
FROM `information_schema`.`STATISTICS`
|
|
WHERE `TABLE_SCHEMA` = DATABASE()
|
|
AND `TABLE_NAME` = p_table
|
|
AND `INDEX_NAME` = p_index;
|
|
|
|
IF index_exists = 0 THEN
|
|
SET @sql = CONCAT('CREATE INDEX `', p_index, '` ON `', p_table, '`(', p_columns, ')');
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
END IF;
|
|
END //
|
|
DELIMITER ;
|
|
|
|
CALL `pb_safe_add_index`('playerbots_names', 'idx_playerbots_names_gender', 'gender');
|
|
CALL `pb_safe_add_index`('playerbots_names', 'idx_playerbots_names_name_gender', 'name, gender');
|
|
|
|
DROP PROCEDURE IF EXISTS `pb_safe_add_index`;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Views for Statistics and Monitoring
|
|
-- --------------------------------------------------------
|
|
|
|
-- View: v_available_names
|
|
-- Purpose: Show available names by gender
|
|
DROP VIEW IF EXISTS v_available_names;
|
|
CREATE VIEW v_available_names AS
|
|
SELECT
|
|
pn.name_id,
|
|
pn.name,
|
|
pn.gender,
|
|
CASE WHEN pnu.name_id IS NULL THEN 1 ELSE 0 END AS is_available
|
|
FROM playerbots_names pn
|
|
LEFT JOIN playerbots_names_used pnu ON pn.name_id = pnu.name_id;
|
|
|
|
-- View: v_name_usage_stats
|
|
-- Purpose: Name usage statistics
|
|
DROP VIEW IF EXISTS v_name_usage_stats;
|
|
CREATE VIEW v_name_usage_stats AS
|
|
SELECT
|
|
(SELECT COUNT(*) FROM playerbots_names) AS total_names,
|
|
(SELECT COUNT(*) FROM playerbots_names WHERE gender = 0) AS total_male_names,
|
|
(SELECT COUNT(*) FROM playerbots_names WHERE gender = 1) AS total_female_names,
|
|
(SELECT COUNT(*) FROM playerbots_names_used) AS used_names,
|
|
(SELECT COUNT(*) FROM playerbots_names pn
|
|
LEFT JOIN playerbots_names_used pnu ON pn.name_id = pnu.name_id
|
|
WHERE pnu.name_id IS NULL AND pn.gender = 0) AS available_male_names,
|
|
(SELECT COUNT(*) FROM playerbots_names pn
|
|
LEFT JOIN playerbots_names_used pnu ON pn.name_id = pnu.name_id
|
|
WHERE pnu.name_id IS NULL AND pn.gender = 1) AS available_female_names;
|
|
|
|
-- View: v_bot_account_stats
|
|
-- Purpose: Bot account statistics
|
|
DROP VIEW IF EXISTS v_bot_account_stats;
|
|
CREATE VIEW v_bot_account_stats AS
|
|
SELECT
|
|
COUNT(*) AS total_accounts,
|
|
SUM(is_active) AS active_accounts,
|
|
SUM(character_count) AS total_characters,
|
|
AVG(character_count) AS avg_characters_per_account,
|
|
MAX(character_count) AS max_characters,
|
|
SUM(CASE WHEN character_count > 10 THEN 1 ELSE 0 END) AS accounts_over_limit
|
|
FROM playerbot_accounts
|
|
WHERE is_bot = 1;
|
|
|
|
-- View: v_bot_character_distribution
|
|
-- Purpose: Show distribution of bot characters by race and class
|
|
DROP VIEW IF EXISTS v_bot_character_distribution;
|
|
CREATE VIEW v_bot_character_distribution AS
|
|
SELECT
|
|
race,
|
|
class,
|
|
COUNT(*) as count,
|
|
AVG(level) as avg_level
|
|
FROM playerbot_characters
|
|
GROUP BY race, class;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Stored Procedures for Name Management
|
|
-- --------------------------------------------------------
|
|
|
|
DELIMITER $$
|
|
|
|
-- Procedure: GetRandomAvailableName
|
|
-- Purpose: Get a random available name for a given gender
|
|
DROP PROCEDURE IF EXISTS GetRandomAvailableName$$
|
|
CREATE PROCEDURE GetRandomAvailableName(
|
|
IN p_gender TINYINT(3),
|
|
OUT p_name_id INT(11),
|
|
OUT p_name VARCHAR(255)
|
|
)
|
|
BEGIN
|
|
DECLARE v_count INT;
|
|
|
|
-- Get count of available names for gender
|
|
SELECT COUNT(*) INTO v_count
|
|
FROM playerbots_names pn
|
|
LEFT JOIN playerbots_names_used pnu ON pn.name_id = pnu.name_id
|
|
WHERE pn.gender = p_gender
|
|
AND pnu.name_id IS NULL;
|
|
|
|
-- If no names available, return NULL
|
|
IF v_count = 0 THEN
|
|
SET p_name_id = NULL;
|
|
SET p_name = NULL;
|
|
ELSE
|
|
-- Get random available name
|
|
SELECT pn.name_id, pn.name
|
|
INTO p_name_id, p_name
|
|
FROM playerbots_names pn
|
|
LEFT JOIN playerbots_names_used pnu ON pn.name_id = pnu.name_id
|
|
WHERE pn.gender = p_gender
|
|
AND pnu.name_id IS NULL
|
|
ORDER BY RAND()
|
|
LIMIT 1;
|
|
END IF;
|
|
END$$
|
|
|
|
-- Procedure: AllocateName
|
|
-- Purpose: Allocate a name to a character
|
|
DROP PROCEDURE IF EXISTS AllocateName$$
|
|
CREATE PROCEDURE AllocateName(
|
|
IN p_gender TINYINT(3),
|
|
IN p_character_guid INT,
|
|
OUT p_name_id INT(11),
|
|
OUT p_name VARCHAR(255),
|
|
OUT p_success BOOLEAN
|
|
)
|
|
BEGIN
|
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
|
BEGIN
|
|
ROLLBACK;
|
|
SET p_success = FALSE;
|
|
END;
|
|
|
|
START TRANSACTION;
|
|
|
|
-- Get random available name
|
|
CALL GetRandomAvailableName(p_gender, p_name_id, p_name);
|
|
|
|
IF p_name_id IS NOT NULL THEN
|
|
-- Mark name as used
|
|
INSERT INTO playerbots_names_used (name_id, character_guid)
|
|
VALUES (p_name_id, p_character_guid);
|
|
|
|
SET p_success = TRUE;
|
|
COMMIT;
|
|
ELSE
|
|
SET p_success = FALSE;
|
|
ROLLBACK;
|
|
END IF;
|
|
END$$
|
|
|
|
-- Procedure: ReleaseName
|
|
-- Purpose: Release a name back to the pool
|
|
DROP PROCEDURE IF EXISTS ReleaseName$$
|
|
CREATE PROCEDURE ReleaseName(
|
|
IN p_character_guid INT
|
|
)
|
|
BEGIN
|
|
DELETE FROM playerbots_names_used
|
|
WHERE character_guid = p_character_guid;
|
|
END$$
|
|
|
|
-- Procedure: CheckAccountCharacterLimit
|
|
-- Purpose: Check if account has reached character limit
|
|
DROP PROCEDURE IF EXISTS CheckAccountCharacterLimit$$
|
|
CREATE PROCEDURE CheckAccountCharacterLimit(
|
|
IN p_account_id INT,
|
|
OUT p_can_create BOOLEAN,
|
|
OUT p_current_count INT
|
|
)
|
|
BEGIN
|
|
SELECT character_count INTO p_current_count
|
|
FROM playerbot_accounts
|
|
WHERE account_id = p_account_id AND is_bot = 1;
|
|
|
|
IF p_current_count IS NULL THEN
|
|
-- Not a bot account
|
|
SET p_can_create = TRUE;
|
|
SET p_current_count = 0;
|
|
ELSEIF p_current_count >= 10 THEN
|
|
-- Already at limit
|
|
SET p_can_create = FALSE;
|
|
ELSE
|
|
SET p_can_create = TRUE;
|
|
END IF;
|
|
END$$
|
|
|
|
DELIMITER ;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Function to check name availability
|
|
-- --------------------------------------------------------
|
|
|
|
DELIMITER $$
|
|
|
|
DROP FUNCTION IF EXISTS IsNameAvailable$$
|
|
CREATE FUNCTION IsNameAvailable(p_name VARCHAR(255))
|
|
RETURNS BOOLEAN
|
|
DETERMINISTIC
|
|
READS SQL DATA
|
|
BEGIN
|
|
DECLARE v_is_available BOOLEAN DEFAULT FALSE;
|
|
DECLARE v_name_id INT;
|
|
|
|
-- Get name_id for the name
|
|
SELECT name_id INTO v_name_id
|
|
FROM playerbots_names
|
|
WHERE name = p_name
|
|
LIMIT 1;
|
|
|
|
-- Check if name_id exists and is not in use
|
|
IF v_name_id IS NOT NULL THEN
|
|
SELECT NOT EXISTS(
|
|
SELECT 1 FROM playerbots_names_used
|
|
WHERE name_id = v_name_id
|
|
) INTO v_is_available;
|
|
END IF;
|
|
|
|
RETURN v_is_available;
|
|
END$$
|
|
|
|
-- Function to get character count for account
|
|
DROP FUNCTION IF EXISTS GetAccountCharacterCount$$
|
|
CREATE FUNCTION GetAccountCharacterCount(p_account_id INT)
|
|
RETURNS INT
|
|
DETERMINISTIC
|
|
READS SQL DATA
|
|
BEGIN
|
|
DECLARE v_count INT DEFAULT 0;
|
|
|
|
SELECT character_count INTO v_count
|
|
FROM playerbot_accounts
|
|
WHERE account_id = p_account_id AND is_bot = 1;
|
|
|
|
IF v_count IS NULL THEN
|
|
SET v_count = 0;
|
|
END IF;
|
|
|
|
RETURN v_count;
|
|
END$$
|
|
|
|
DELIMITER ;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Cleanup procedure for old performance metrics
|
|
-- --------------------------------------------------------
|
|
|
|
DELIMITER $$
|
|
|
|
DROP PROCEDURE IF EXISTS CleanupOldMetrics$$
|
|
CREATE PROCEDURE CleanupOldMetrics(
|
|
IN p_days_to_keep INT
|
|
)
|
|
BEGIN
|
|
DELETE FROM playerbot_performance_metrics
|
|
WHERE recorded_at < DATE_SUB(NOW(), INTERVAL p_days_to_keep DAY);
|
|
|
|
OPTIMIZE TABLE playerbot_performance_metrics;
|
|
END$$
|
|
|
|
DELIMITER ;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Initial data validation
|
|
-- --------------------------------------------------------
|
|
|
|
-- Check for accounts violating the 10 character limit
|
|
SELECT
|
|
'WARNING: Bot accounts with more than 10 characters:' AS message,
|
|
account_id,
|
|
character_count
|
|
FROM playerbot_accounts
|
|
WHERE is_bot = 1 AND character_count > 10;
|
|
|
|
-- --------------------------------------------------------
|
|
-- Grant permissions (adjust as needed for your setup)
|
|
-- --------------------------------------------------------
|
|
|
|
-- Example: GRANT ALL PRIVILEGES ON playerbot.* TO 'trinity'@'localhost';
|