Skip to content

Commit b2b8dd7

Browse files
committed
archive records from players with active bans
1 parent db48034 commit b2b8dd7

File tree

6 files changed

+1413
-28
lines changed

6 files changed

+1413
-28
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
-- Migration: Add table for storing banned players' records
2+
-- This table stores records from permanently banned players
3+
-- Records are moved here when a permanent ban is detected
4+
5+
-- Charset and collation settings
6+
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
7+
SET collation_connection = 'utf8mb4_unicode_ci';
8+
9+
-------------------------------------------------------------------
10+
-- Banned Records Archive Table
11+
-- Structure mirrors kz_records_partitioned for easy data migration
12+
-- Records here are excluded from leaderboards but preserved for auditing
13+
-------------------------------------------------------------------
14+
15+
CREATE TABLE IF NOT EXISTS kz_banned_records (
16+
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
17+
original_record_id BIGINT UNSIGNED NULL COMMENT 'Original ID from kz_records_partitioned',
18+
original_id BIGINT UNSIGNED NULL COMMENT 'Original ID from source API data',
19+
20+
-- Player info (stored directly since player may be deleted)
21+
player_id INT UNSIGNED NOT NULL,
22+
steamid64 VARCHAR(20) NOT NULL,
23+
24+
-- Map and server info
25+
map_id INT UNSIGNED NOT NULL,
26+
server_id INT UNSIGNED NOT NULL,
27+
28+
-- Record details
29+
mode VARCHAR(32) NOT NULL,
30+
stage TINYINT UNSIGNED NOT NULL DEFAULT 0,
31+
time DECIMAL(10,3) NOT NULL,
32+
teleports SMALLINT UNSIGNED NOT NULL DEFAULT 0,
33+
points INT NOT NULL DEFAULT 0,
34+
tickrate SMALLINT UNSIGNED NOT NULL DEFAULT 128,
35+
36+
-- Additional metadata
37+
record_filter_id INT NOT NULL DEFAULT 0,
38+
replay_id INT UNSIGNED NOT NULL DEFAULT 0,
39+
updated_by INT NOT NULL DEFAULT 0,
40+
41+
-- Original timestamps from the record
42+
record_created_on DATETIME NOT NULL COMMENT 'When the record was originally created',
43+
record_updated_on DATETIME NOT NULL COMMENT 'When the record was last updated',
44+
45+
-- Archive metadata
46+
ban_id INT NULL COMMENT 'Reference to the ban that caused this archive',
47+
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'When the record was archived',
48+
archived_reason VARCHAR(100) DEFAULT 'permanent_ban' COMMENT 'Reason for archiving',
49+
50+
-- Indexes for querying archived records
51+
INDEX idx_steamid64 (steamid64),
52+
INDEX idx_player_id (player_id),
53+
INDEX idx_map_id (map_id),
54+
INDEX idx_archived_at (archived_at DESC),
55+
INDEX idx_ban_id (ban_id),
56+
INDEX idx_original_record_id (original_record_id)
57+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
58+
59+
-------------------------------------------------------------------
60+
-- Stored Procedure: Archive records for a banned player
61+
-- Moves records from kz_records_partitioned to kz_banned_records
62+
-- Only for permanent bans (expires_on IS NULL)
63+
-------------------------------------------------------------------
64+
65+
DELIMITER $$
66+
67+
DROP PROCEDURE IF EXISTS archive_banned_player_records$$
68+
CREATE PROCEDURE archive_banned_player_records(
69+
IN p_steamid64 VARCHAR(20),
70+
IN p_ban_id INT
71+
)
72+
BEGIN
73+
DECLARE v_records_archived INT DEFAULT 0;
74+
DECLARE v_already_archived INT DEFAULT 0;
75+
76+
-- Check how many records are already archived for this player
77+
SELECT COUNT(*) INTO v_already_archived
78+
FROM kz_banned_records
79+
WHERE steamid64 = p_steamid64;
80+
81+
-- Only archive if there are records to archive
82+
IF v_already_archived = 0 THEN
83+
-- Insert records into archive table
84+
INSERT INTO kz_banned_records (
85+
original_record_id,
86+
original_id,
87+
player_id,
88+
steamid64,
89+
map_id,
90+
server_id,
91+
mode,
92+
stage,
93+
time,
94+
teleports,
95+
points,
96+
tickrate,
97+
record_filter_id,
98+
replay_id,
99+
updated_by,
100+
record_created_on,
101+
record_updated_on,
102+
ban_id,
103+
archived_reason
104+
)
105+
SELECT
106+
r.id,
107+
r.original_id,
108+
r.player_id,
109+
r.steamid64,
110+
r.map_id,
111+
r.server_id,
112+
r.mode,
113+
r.stage,
114+
r.time,
115+
r.teleports,
116+
r.points,
117+
r.tickrate,
118+
r.record_filter_id,
119+
r.replay_id,
120+
r.updated_by,
121+
r.created_on,
122+
r.updated_on,
123+
p_ban_id,
124+
'permanent_ban'
125+
FROM kz_records_partitioned r
126+
WHERE r.steamid64 = p_steamid64;
127+
128+
SET v_records_archived = ROW_COUNT();
129+
130+
-- Delete records from main table
131+
IF v_records_archived > 0 THEN
132+
DELETE FROM kz_records_partitioned
133+
WHERE steamid64 = p_steamid64;
134+
135+
-- Also delete from non-partitioned table if it exists
136+
DELETE FROM kz_records
137+
WHERE steamid64 = p_steamid64;
138+
END IF;
139+
END IF;
140+
141+
SELECT v_records_archived AS records_archived, v_already_archived AS already_archived;
142+
END$$
143+
144+
-------------------------------------------------------------------
145+
-- Stored Procedure: Restore records for an unbanned player
146+
-- Moves records back from kz_banned_records to kz_records_partitioned
147+
-- Used when a permanent ban is lifted
148+
-------------------------------------------------------------------
149+
150+
DROP PROCEDURE IF EXISTS restore_unbanned_player_records$$
151+
CREATE PROCEDURE restore_unbanned_player_records(
152+
IN p_steamid64 VARCHAR(20)
153+
)
154+
BEGIN
155+
DECLARE v_records_restored INT DEFAULT 0;
156+
157+
-- Insert archived records back into main table
158+
INSERT INTO kz_records_partitioned (
159+
original_id,
160+
player_id,
161+
steamid64,
162+
map_id,
163+
server_id,
164+
mode,
165+
stage,
166+
time,
167+
teleports,
168+
points,
169+
tickrate,
170+
record_filter_id,
171+
replay_id,
172+
updated_by,
173+
created_on,
174+
updated_on
175+
)
176+
SELECT
177+
original_id,
178+
player_id,
179+
steamid64,
180+
map_id,
181+
server_id,
182+
mode,
183+
stage,
184+
time,
185+
teleports,
186+
points,
187+
tickrate,
188+
record_filter_id,
189+
replay_id,
190+
updated_by,
191+
record_created_on,
192+
record_updated_on
193+
FROM kz_banned_records
194+
WHERE steamid64 = p_steamid64;
195+
196+
SET v_records_restored = ROW_COUNT();
197+
198+
-- Delete from archive table
199+
IF v_records_restored > 0 THEN
200+
DELETE FROM kz_banned_records
201+
WHERE steamid64 = p_steamid64;
202+
END IF;
203+
204+
SELECT v_records_restored AS records_restored;
205+
END$$
206+
207+
-------------------------------------------------------------------
208+
-- Stored Procedure: Batch archive records for multiple banned players
209+
-- More efficient for processing many bans at once
210+
-------------------------------------------------------------------
211+
212+
DROP PROCEDURE IF EXISTS batch_archive_banned_records$$
213+
CREATE PROCEDURE batch_archive_banned_records()
214+
BEGIN
215+
DECLARE v_total_archived INT DEFAULT 0;
216+
DECLARE v_players_processed INT DEFAULT 0;
217+
218+
-- Create temp table with permanently banned players who have records
219+
DROP TEMPORARY TABLE IF EXISTS tmp_to_archive;
220+
CREATE TEMPORARY TABLE tmp_to_archive AS
221+
SELECT DISTINCT
222+
p.steamid64,
223+
b.id AS ban_id
224+
FROM kz_players p
225+
INNER JOIN kz_bans b ON p.steamid64 = b.steamid64
226+
WHERE p.is_banned = TRUE
227+
AND b.expires_on = '9999-12-31 23:59:59' -- Only permanent bans
228+
AND NOT EXISTS (
229+
SELECT 1 FROM kz_banned_records br
230+
WHERE br.steamid64 = p.steamid64
231+
LIMIT 1
232+
)
233+
AND EXISTS (
234+
SELECT 1 FROM kz_records_partitioned r
235+
WHERE r.steamid64 = p.steamid64
236+
LIMIT 1
237+
);
238+
239+
SELECT COUNT(*) INTO v_players_processed FROM tmp_to_archive;
240+
241+
IF v_players_processed > 0 THEN
242+
-- Archive all records for these players
243+
INSERT INTO kz_banned_records (
244+
original_record_id,
245+
original_id,
246+
player_id,
247+
steamid64,
248+
map_id,
249+
server_id,
250+
mode,
251+
stage,
252+
time,
253+
teleports,
254+
points,
255+
tickrate,
256+
record_filter_id,
257+
replay_id,
258+
updated_by,
259+
record_created_on,
260+
record_updated_on,
261+
ban_id,
262+
archived_reason
263+
)
264+
SELECT
265+
r.id,
266+
r.original_id,
267+
r.player_id,
268+
r.steamid64,
269+
r.map_id,
270+
r.server_id,
271+
r.mode,
272+
r.stage,
273+
r.time,
274+
r.teleports,
275+
r.points,
276+
r.tickrate,
277+
r.record_filter_id,
278+
r.replay_id,
279+
r.updated_by,
280+
r.created_on,
281+
r.updated_on,
282+
ta.ban_id,
283+
'permanent_ban'
284+
FROM kz_records_partitioned r
285+
INNER JOIN tmp_to_archive ta ON r.steamid64 = ta.steamid64;
286+
287+
SET v_total_archived = ROW_COUNT();
288+
289+
-- Delete archived records from main table
290+
DELETE r FROM kz_records_partitioned r
291+
INNER JOIN tmp_to_archive ta ON r.steamid64 = ta.steamid64;
292+
293+
-- Also delete from non-partitioned table
294+
DELETE r FROM kz_records r
295+
INNER JOIN tmp_to_archive ta ON r.steamid64 = ta.steamid64;
296+
END IF;
297+
298+
DROP TEMPORARY TABLE IF EXISTS tmp_to_archive;
299+
300+
SELECT v_total_archived AS records_archived, v_players_processed AS players_processed;
301+
END$$
302+
303+
DELIMITER ;
304+
305+
-------------------------------------------------------------------
306+
-- View: Statistics for banned records archive
307+
-------------------------------------------------------------------
308+
309+
CREATE OR REPLACE VIEW v_banned_records_stats AS
310+
SELECT
311+
COUNT(*) AS total_records,
312+
COUNT(DISTINCT steamid64) AS unique_players,
313+
COUNT(DISTINCT map_id) AS unique_maps,
314+
MIN(archived_at) AS first_archive,
315+
MAX(archived_at) AS last_archive
316+
FROM kz_banned_records;

0 commit comments

Comments
 (0)