-- ============================================================ -- SETUP -- ============================================================ CREATE SCHEMA IF NOT EXISTS hubmc; -- gen_random_uuid() из pgcrypto CREATE EXTENSION IF NOT EXISTS pgcrypto; -- ============================================================ -- LUCKPERMS TABLES (схема hubmc, правки из нового DDL) -- ============================================================ -- Таблица игроков LuckPerms CREATE TABLE IF NOT EXISTS hubmc.luckperms_players ( uuid VARCHAR(36) PRIMARY KEY, username VARCHAR(16) NOT NULL, primary_group VARCHAR(36) NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_luckperms_players_username ON hubmc.luckperms_players(username); -- Таблица групп LuckPerms CREATE TABLE IF NOT EXISTS hubmc.luckperms_groups ( name VARCHAR(36) PRIMARY KEY, created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Таблица прав пользователей LuckPerms -- (ужесточены NOT NULL для server/world/expiry/contexts как в новом DDL) CREATE TABLE IF NOT EXISTS hubmc.luckperms_user_permissions ( id SERIAL PRIMARY KEY, uuid VARCHAR(36) NOT NULL, permission VARCHAR(200) NOT NULL, value BOOLEAN NOT NULL, server VARCHAR(36) NOT NULL, world VARCHAR(64) NOT NULL, expiry BIGINT NOT NULL, contexts VARCHAR(200) NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW(), FOREIGN KEY (uuid) REFERENCES hubmc.luckperms_players(uuid) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_luckperms_user_permissions_uuid ON hubmc.luckperms_user_permissions(uuid); CREATE INDEX IF NOT EXISTS idx_luckperms_user_permissions_lookup ON hubmc.luckperms_user_permissions(uuid, permission, server, world); -- ============================================================ -- HUB TABLES (схема hubmc, правки из нового DDL) -- ============================================================ -- Таблица кулдаунов CREATE TABLE IF NOT EXISTS hubmc.hub_cooldowns ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), player_uuid VARCHAR(36) NOT NULL, cooldown_type VARCHAR(50) NOT NULL, expires_at TIMESTAMPTZ NOT NULL, cooldown_seconds INTEGER NOT NULL, metadata JSONB, created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW(), FOREIGN KEY (player_uuid) REFERENCES hubmc.luckperms_players(uuid) ON DELETE CASCADE ); CREATE UNIQUE INDEX IF NOT EXISTS idx_hub_cooldowns_player_type ON hubmc.hub_cooldowns(player_uuid, cooldown_type); CREATE INDEX IF NOT EXISTS idx_hub_cooldowns_expires ON hubmc.hub_cooldowns(expires_at); CREATE INDEX IF NOT EXISTS idx_hub_cooldowns_player_uuid ON hubmc.hub_cooldowns(player_uuid); -- Таблица домов игроков CREATE TABLE IF NOT EXISTS hubmc.hub_homes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), player_uuid VARCHAR(36) NOT NULL, name VARCHAR(255) NOT NULL, world TEXT NOT NULL, x DOUBLE PRECISION NOT NULL, y DOUBLE PRECISION NOT NULL, z DOUBLE PRECISION NOT NULL, yaw REAL DEFAULT 0.0, pitch REAL DEFAULT 0.0, is_public BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW(), FOREIGN KEY (player_uuid) REFERENCES hubmc.luckperms_players(uuid) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_hub_homes_player_uuid ON hubmc.hub_homes(player_uuid); CREATE UNIQUE INDEX IF NOT EXISTS idx_hub_homes_player_name ON hubmc.hub_homes(player_uuid, name); -- Таблица наказаний CREATE TABLE IF NOT EXISTS hubmc.hub_punishments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), player_uuid VARCHAR(36) NOT NULL, player_name VARCHAR(255) NOT NULL, player_ip INET, punishment_type VARCHAR(50) NOT NULL CHECK (punishment_type IN ('BAN', 'MUTE', 'KICK', 'WARN', 'TEMPBAN', 'TEMPMUTE')), reason TEXT NOT NULL, staff_uuid VARCHAR(36) NOT NULL, staff_name VARCHAR(255) NOT NULL, expires_at TIMESTAMPTZ, is_active BOOLEAN DEFAULT true, revoked_at TIMESTAMPTZ, revoked_by VARCHAR(36), revoked_reason TEXT, evidence_url TEXT, notes TEXT, created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW(), FOREIGN KEY (player_uuid) REFERENCES hubmc.luckperms_players(uuid) ON DELETE CASCADE, FOREIGN KEY (staff_uuid) REFERENCES hubmc.luckperms_players(uuid) ON DELETE SET NULL, FOREIGN KEY (revoked_by) REFERENCES hubmc.luckperms_players(uuid) ON DELETE SET NULL ); CREATE INDEX IF NOT EXISTS idx_hub_punishments_player_uuid ON hubmc.hub_punishments(player_uuid); CREATE INDEX IF NOT EXISTS idx_hub_punishments_player_active ON hubmc.hub_punishments(player_uuid, is_active) WHERE is_active = true; CREATE INDEX IF NOT EXISTS idx_hub_punishments_type_active ON hubmc.hub_punishments(punishment_type, is_active) WHERE is_active = true; CREATE INDEX IF NOT EXISTS idx_hub_punishments_player_ip ON hubmc.hub_punishments(player_ip) WHERE player_ip IS NOT NULL; -- Таблица варпов CREATE TABLE IF NOT EXISTS hubmc.hub_warps ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL UNIQUE, world TEXT NOT NULL, x DOUBLE PRECISION NOT NULL, y DOUBLE PRECISION NOT NULL, z DOUBLE PRECISION NOT NULL, yaw REAL DEFAULT 0.0, pitch REAL DEFAULT 0.0, is_public BOOLEAN DEFAULT true, description VARCHAR(500), created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_hub_warps_name ON hubmc.hub_warps(name); CREATE INDEX IF NOT EXISTS idx_hub_warps_world ON hubmc.hub_warps(world); CREATE INDEX IF NOT EXISTS idx_hub_warps_public ON hubmc.hub_warps(is_public) WHERE is_public = true; -- Таблица вайтлиста -- (как в новом DDL: без player_uuid; уникальность по player_name) CREATE TABLE IF NOT EXISTS hubmc.hub_whitelist ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), player_name VARCHAR(255) NOT NULL UNIQUE, added_by VARCHAR(255) NOT NULL, added_at TIMESTAMPTZ NOT NULL, expires_at TIMESTAMPTZ, is_active BOOLEAN DEFAULT true, reason VARCHAR(500), created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_hub_whitelist_player_name ON hubmc.hub_whitelist(player_name); CREATE INDEX IF NOT EXISTS idx_hub_whitelist_active ON hubmc.hub_whitelist(is_active) WHERE is_active = true; CREATE INDEX IF NOT EXISTS idx_hub_whitelist_expires ON hubmc.hub_whitelist(expires_at) WHERE expires_at IS NOT NULL; -- Таблица истории телепортаций CREATE TABLE IF NOT EXISTS hubmc.hub_teleport_history ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), player_uuid VARCHAR(36) NOT NULL, from_world TEXT, from_x DOUBLE PRECISION, from_y DOUBLE PRECISION, from_z DOUBLE PRECISION, to_world TEXT NOT NULL, to_x DOUBLE PRECISION NOT NULL, to_y DOUBLE PRECISION NOT NULL, to_z DOUBLE PRECISION NOT NULL, tp_type VARCHAR(50) NOT NULL, target_name VARCHAR(255), created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, FOREIGN KEY (player_uuid) REFERENCES hubmc.luckperms_players(uuid) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_hub_teleport_history_player_uuid ON hubmc.hub_teleport_history(player_uuid); CREATE INDEX IF NOT EXISTS idx_hub_teleport_history_created_at ON hubmc.hub_teleport_history(created_at); CREATE INDEX IF NOT EXISTS idx_hub_teleport_history_tp_type ON hubmc.hub_teleport_history(tp_type); -- ============================================================ -- COMMENTS -- ============================================================ COMMENT ON TABLE hubmc.luckperms_players IS 'LuckPerms player data'; COMMENT ON TABLE hubmc.luckperms_groups IS 'LuckPerms permission groups'; COMMENT ON TABLE hubmc.luckperms_user_permissions IS 'Individual player permissions'; COMMENT ON TABLE hubmc.hub_cooldowns IS 'Player cooldowns for various actions'; COMMENT ON TABLE hubmc.hub_homes IS 'Player home locations'; COMMENT ON TABLE hubmc.hub_punishments IS 'Player punishments (bans, mutes, etc.)'; COMMENT ON TABLE hubmc.hub_warps IS 'Server warp points'; COMMENT ON TABLE hubmc.hub_whitelist IS 'Server whitelist entries'; COMMENT ON TABLE hubmc.hub_teleport_history IS 'History of all player teleportations'; COMMENT ON COLUMN hubmc.hub_cooldowns.cooldown_type IS 'Type of cooldown: TP_DELAY, HOME_SET, COMBAT, etc.'; COMMENT ON COLUMN hubmc.hub_cooldowns.metadata IS 'Additional data in JSON format'; COMMENT ON COLUMN hubmc.hub_punishments.player_ip IS 'Player IP address for IP bans'; COMMENT ON COLUMN hubmc.hub_punishments.evidence_url IS 'URL to evidence (screenshot, video, etc.)'; COMMENT ON COLUMN hubmc.hub_punishments.notes IS 'Internal moderator notes'; COMMENT ON COLUMN hubmc.hub_whitelist.expires_at IS 'Expiration date for temporary whitelist'; COMMENT ON COLUMN hubmc.hub_whitelist.is_active IS 'Whether whitelist entry is currently active'; COMMENT ON COLUMN hubmc.hub_teleport_history.tp_type IS 'Type of teleport: HOME, WARP, TPA, TPAHERE, SPAWN, BACK, etc.'; COMMENT ON COLUMN hubmc.hub_teleport_history.target_name IS 'Target name for TPA/home/warp teleports'; -- ============================================================ -- FUNCTIONS (все в конце) -- ============================================================ -- Функция для автоматического обновления updated_at CREATE OR REPLACE FUNCTION hubmc.update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- ============================================================ -- TRIGGERS (после функций) -- ============================================================ -- LuckPerms DROP TRIGGER IF EXISTS update_luckperms_players_updated_at ON hubmc.luckperms_players; CREATE TRIGGER update_luckperms_players_updated_at BEFORE UPDATE ON hubmc.luckperms_players FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); DROP TRIGGER IF EXISTS update_luckperms_groups_updated_at ON hubmc.luckperms_groups; CREATE TRIGGER update_luckperms_groups_updated_at BEFORE UPDATE ON hubmc.luckperms_groups FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); DROP TRIGGER IF EXISTS update_luckperms_user_permissions_updated_at ON hubmc.luckperms_user_permissions; CREATE TRIGGER update_luckperms_user_permissions_updated_at BEFORE UPDATE ON hubmc.luckperms_user_permissions FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); -- HUB DROP TRIGGER IF EXISTS update_hub_cooldowns_updated_at ON hubmc.hub_cooldowns; CREATE TRIGGER update_hub_cooldowns_updated_at BEFORE UPDATE ON hubmc.hub_cooldowns FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); DROP TRIGGER IF EXISTS update_hub_homes_updated_at ON hubmc.hub_homes; CREATE TRIGGER update_hub_homes_updated_at BEFORE UPDATE ON hubmc.hub_homes FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); DROP TRIGGER IF EXISTS update_hub_punishments_updated_at ON hubmc.hub_punishments; CREATE TRIGGER update_hub_punishments_updated_at BEFORE UPDATE ON hubmc.hub_punishments FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); DROP TRIGGER IF EXISTS update_hub_warps_updated_at ON hubmc.hub_warps; CREATE TRIGGER update_hub_warps_updated_at BEFORE UPDATE ON hubmc.hub_warps FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column(); DROP TRIGGER IF EXISTS update_hub_whitelist_updated_at ON hubmc.hub_whitelist; CREATE TRIGGER update_hub_whitelist_updated_at BEFORE UPDATE ON hubmc.hub_whitelist FOR EACH ROW EXECUTE FUNCTION hubmc.update_updated_at_column();