diff --git a/bin/main/db/migration/V3__migrate_chastity_game_set.sql b/bin/main/db/migration/V3__migrate_chastity_game_set.sql new file mode 100644 index 0000000..81f4c42 --- /dev/null +++ b/bin/main/db/migration/V3__migrate_chastity_game_set.sql @@ -0,0 +1,215 @@ +-- Migration: Inhalte aus chastity_game_set in die normalen Aufgabengruppen-Tabellen übernehmen. +-- +-- Jedes chastity_game_set eines Users wird zu einer privaten CHASTITY_ONLY-Aufgabengruppe: +-- aufgaben (JSON) → aufgabe + aufgabe_benoetigt_passiv +-- zeitstrafen (JSON) → sperre + sperre_sperre_fuer +-- finisher (JSON) → finisher +-- +-- Die Prozedur prüft zuerst, ob chastity_game_set existiert – auf leeren Datenbanken +-- ist sie dadurch ein No-op. + +DROP PROCEDURE IF EXISTS proc_migrate_chastity_game_set; + +CREATE PROCEDURE proc_migrate_chastity_game_set() +BEGIN + DECLARE v_set_id VARCHAR(36); + DECLARE v_owner_id VARCHAR(36); + DECLARE v_set_name VARCHAR(255); + DECLARE v_user_name VARCHAR(255); + DECLARE v_aufgaben_json TEXT; + DECLARE v_zeitstr_json TEXT; + DECLARE v_finisher_json TEXT; + + DECLARE v_gruppe_id VARCHAR(36); + DECLARE v_aufgabe_id VARCHAR(36); + DECLARE v_sperre_id VARCHAR(36); + DECLARE v_finisher_id VARCHAR(36); + + DECLARE v_outer_count INT; + DECLARE v_inner_count INT; + DECLARE i INT; + DECLARE j INT; + + DECLARE tbl_exists INT DEFAULT 0; + DECLARE done INT DEFAULT FALSE; + + DECLARE cur CURSOR FOR + SELECT id, owner_id, name, aufgaben, zeitstrafen, finisher + FROM chastity_game_set; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + -- Add columns that may not yet exist (Hibernate ddl-auto runs after Flyway) + IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'aufgabe' AND COLUMN_NAME = 'level') THEN + ALTER TABLE aufgabe ADD COLUMN level INT NULL; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sperre' AND COLUMN_NAME = 'level') THEN + ALTER TABLE sperre ADD COLUMN level INT NULL; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sperre' AND COLUMN_NAME = 'temp_unlock_before_required') THEN + ALTER TABLE sperre ADD COLUMN temp_unlock_before_required TINYINT(1) NULL; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sperre' AND COLUMN_NAME = 'temp_unlock_after_required') THEN + ALTER TABLE sperre ADD COLUMN temp_unlock_after_required TINYINT(1) NULL; + END IF; + + SELECT COUNT(*) INTO tbl_exists + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'chastity_game_set'; + + IF tbl_exists > 0 THEN + + OPEN cur; + + set_loop: LOOP + FETCH cur INTO v_set_id, v_owner_id, v_set_name, + v_aufgaben_json, v_zeitstr_json, v_finisher_json; + IF done THEN LEAVE set_loop; END IF; + + SELECT name INTO v_user_name + FROM user + WHERE user_id = v_owner_id + LIMIT 1; + + SET v_gruppe_id = UUID(); + + -- ── Aufgabengruppe anlegen ─────────────────────────────────────── + INSERT INTO aufgaben_gruppe + (gruppen_id, name, beschreibung, user_id, private_gruppe, bild, von, available_in) + VALUES + (v_gruppe_id, + v_set_name, + 'Importiert aus Chastity Game Set', + v_owner_id, + TRUE, + NULL, + v_user_name, + 'CHASTITY_ONLY'); + + -- ── Aufgaben ──────────────────────────────────────────────────── + -- GameSetAufgabe.minutes → sekunden_von / sekunden_bis (× 60) + -- GameSetAufgabe.benoetigt → aufgabe_benoetigt_passiv + SET v_outer_count = IFNULL(JSON_LENGTH(v_aufgaben_json), 0); + SET i = 0; + WHILE i < v_outer_count DO + SET v_aufgabe_id = UUID(); + + INSERT INTO aufgabe + (aufgabe_id, kurz_text, text, level, sekunden_von, sekunden_bis, gruppe_id) + VALUES ( + v_aufgabe_id, + JSON_UNQUOTE(JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].title'))), + JSON_UNQUOTE(JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].description'))), + CAST(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].level'))), 'null') AS SIGNED), + CASE + WHEN JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].minutes')) IS NOT NULL + THEN CAST(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].minutes'))), 'null') AS SIGNED) * 60 + ELSE NULL + END, + CASE + WHEN JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].minutes')) IS NOT NULL + THEN CAST(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].minutes'))), 'null') AS SIGNED) * 60 + ELSE NULL + END, + v_gruppe_id + ); + + SET v_inner_count = IFNULL( + JSON_LENGTH(JSON_EXTRACT(v_aufgaben_json, CONCAT('$[', i, '].benoetigt'))), + 0); + SET j = 0; + WHILE j < v_inner_count DO + SET @wz = NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_aufgaben_json, + CONCAT('$[', i, '].benoetigt[', j, ']'))), 'null'); + IF @wz IS NOT NULL AND @wz != '' THEN + INSERT IGNORE INTO aufgabe_benoetigt_passiv (aufgabe_id, werkzeug) + VALUES (v_aufgabe_id, @wz); + END IF; + SET j = j + 1; + END WHILE; + + SET i = i + 1; + END WHILE; + + -- ── Zeitstrafen → Sperren ──────────────────────────────────────── + -- GameSetZeitstrafe.minMinutes / maxMinutes → minuten_von / minuten_bis + -- GameSetZeitstrafe.level / tempUnlock* → level / temp_unlock_before/after_required + -- GameSetZeitstrafe.sperrt → sperre_sperre_fuer + SET v_outer_count = IFNULL(JSON_LENGTH(v_zeitstr_json), 0); + SET i = 0; + WHILE i < v_outer_count DO + SET v_sperre_id = UUID(); + + INSERT INTO sperre + (sperre_id, kurz_text, text, release_text, minuten_von, minuten_bis, + level, temp_unlock_before_required, temp_unlock_after_required, gruppe_id) + VALUES ( + v_sperre_id, + JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].title'))), + JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].description'))), + IF(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].releaseText')) IS NOT NULL, + JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].releaseText'))), + NULL), + CAST(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].minMinutes'))), 'null') AS SIGNED), + CAST(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].maxMinutes'))), 'null') AS SIGNED), + CAST(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].level'))), 'null') AS SIGNED), + CASE JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].tempUnlockBeforeRequired'))) + WHEN 'true' THEN 1 WHEN 'false' THEN 0 ELSE NULL END, + CASE JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].tempUnlockAfterRequired'))) + WHEN 'true' THEN 1 WHEN 'false' THEN 0 ELSE NULL END, + v_gruppe_id + ); + + SET v_inner_count = IFNULL( + JSON_LENGTH(JSON_EXTRACT(v_zeitstr_json, CONCAT('$[', i, '].sperrt'))), + 0); + SET j = 0; + WHILE j < v_inner_count DO + SET @wz = NULLIF(JSON_UNQUOTE(JSON_EXTRACT(v_zeitstr_json, + CONCAT('$[', i, '].sperrt[', j, ']'))), 'null'); + IF @wz IS NOT NULL AND @wz != '' THEN + INSERT IGNORE INTO sperre_sperre_fuer (sperre_id, werkzeug) + VALUES (v_sperre_id, @wz); + END IF; + SET j = j + 1; + END WHILE; + + SET i = i + 1; + END WHILE; + + -- ── Finisher ───────────────────────────────────────────────────── + -- GameSetFinisher hat kein geschlecht und keine benoetigt-Listen + -- tempUnlockBeforeRequired / tempUnlockAfterRequired haben kein Gegenstück in finisher + SET v_outer_count = IFNULL(JSON_LENGTH(v_finisher_json), 0); + SET i = 0; + WHILE i < v_outer_count DO + SET v_finisher_id = UUID(); + + INSERT INTO finisher + (finisher_id, kurz_text, text, geschlecht, gruppe_id) + VALUES ( + v_finisher_id, + JSON_UNQUOTE(JSON_EXTRACT(v_finisher_json, CONCAT('$[', i, '].title'))), + JSON_UNQUOTE(JSON_EXTRACT(v_finisher_json, CONCAT('$[', i, '].description'))), + NULL, + v_gruppe_id + ); + + SET i = i + 1; + END WHILE; + + END LOOP; + + CLOSE cur; + + END IF; + +END; + +CALL proc_migrate_chastity_game_set(); + +DROP PROCEDURE IF EXISTS proc_migrate_chastity_game_set; diff --git a/bin/main/de/oaa/xxx/games/bdsm/AufgabeAnzeige.class b/bin/main/de/oaa/xxx/games/bdsm/AufgabeAnzeige.class index 2c6c444..819da98 100644 Binary files a/bin/main/de/oaa/xxx/games/bdsm/AufgabeAnzeige.class and b/bin/main/de/oaa/xxx/games/bdsm/AufgabeAnzeige.class differ diff --git a/bin/main/de/oaa/xxx/games/bdsm/controller/FinisherController.class b/bin/main/de/oaa/xxx/games/bdsm/controller/FinisherController.class index 41de71e..fb0681c 100644 Binary files a/bin/main/de/oaa/xxx/games/bdsm/controller/FinisherController.class and b/bin/main/de/oaa/xxx/games/bdsm/controller/FinisherController.class differ diff --git a/bin/main/de/oaa/xxx/games/bdsm/controller/SperreController.class b/bin/main/de/oaa/xxx/games/bdsm/controller/SperreController.class index fb60e89..b81ca8a 100644 Binary files a/bin/main/de/oaa/xxx/games/bdsm/controller/SperreController.class and b/bin/main/de/oaa/xxx/games/bdsm/controller/SperreController.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/GameState.class b/bin/main/de/oaa/xxx/games/chastity/common/GameState.class new file mode 100644 index 0000000..4b3c8ba Binary files /dev/null and b/bin/main/de/oaa/xxx/games/chastity/common/GameState.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/LockGameController.class b/bin/main/de/oaa/xxx/games/chastity/common/LockGameController.class new file mode 100644 index 0000000..85bfb11 Binary files /dev/null and b/bin/main/de/oaa/xxx/games/chastity/common/LockGameController.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/LockGameEntity.class b/bin/main/de/oaa/xxx/games/chastity/common/LockGameEntity.class index 7ffadf8..56bf323 100644 Binary files a/bin/main/de/oaa/xxx/games/chastity/common/LockGameEntity.class and b/bin/main/de/oaa/xxx/games/chastity/common/LockGameEntity.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockEntity.class b/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockEntity.class index d88eab1..70bb24a 100644 Binary files a/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockEntity.class and b/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockEntity.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockRepository.class b/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockRepository.class new file mode 100644 index 0000000..384c216 Binary files /dev/null and b/bin/main/de/oaa/xxx/games/chastity/common/LockGameLockRepository.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/LockGameRepository.class b/bin/main/de/oaa/xxx/games/chastity/common/LockGameRepository.class new file mode 100644 index 0000000..1d57c2a Binary files /dev/null and b/bin/main/de/oaa/xxx/games/chastity/common/LockGameRepository.class differ diff --git a/bin/main/de/oaa/xxx/games/chastity/common/LockGameService.class b/bin/main/de/oaa/xxx/games/chastity/common/LockGameService.class index 71ebaae..841c367 100644 Binary files a/bin/main/de/oaa/xxx/games/chastity/common/LockGameService.class and b/bin/main/de/oaa/xxx/games/chastity/common/LockGameService.class differ diff --git a/bin/main/de/oaa/xxx/games/common/aufgaben/Sperre.class b/bin/main/de/oaa/xxx/games/common/aufgaben/Sperre.class index 0d02203..b92ef14 100644 Binary files a/bin/main/de/oaa/xxx/games/common/aufgaben/Sperre.class and b/bin/main/de/oaa/xxx/games/common/aufgaben/Sperre.class differ diff --git a/bin/main/de/oaa/xxx/games/common/entity/SperreEntity.class b/bin/main/de/oaa/xxx/games/common/entity/SperreEntity.class index 9df1c31..765dca3 100644 Binary files a/bin/main/de/oaa/xxx/games/common/entity/SperreEntity.class and b/bin/main/de/oaa/xxx/games/common/entity/SperreEntity.class differ diff --git a/bin/main/de/oaa/xxx/games/common/repository/FinisherRepository.class b/bin/main/de/oaa/xxx/games/common/repository/FinisherRepository.class index b2a20d8..fcc61d5 100644 Binary files a/bin/main/de/oaa/xxx/games/common/repository/FinisherRepository.class and b/bin/main/de/oaa/xxx/games/common/repository/FinisherRepository.class differ diff --git a/bin/main/static/games/aufgaben/aufgaben.html b/bin/main/static/games/aufgaben/aufgaben.html index 5085716..d7e7641 100644 --- a/bin/main/static/games/aufgaben/aufgaben.html +++ b/bin/main/static/games/aufgaben/aufgaben.html @@ -416,7 +416,7 @@