diff --git a/controllers/CharactersController.inc b/controllers/CharactersController.inc index 00180832..a1e0cc90 100644 --- a/controllers/CharactersController.inc +++ b/controllers/CharactersController.inc @@ -159,6 +159,9 @@ // No XP-level } $character['rank'] = $this->Characters->getXPRank($seminary['id'], $character['xps']); + if(!is_null($character['avatar_id'])) { + $character['avatar'] = $this->Avatars->getAvatarById($character['avatar_id']); + } // Get User $user = $this->Users->getUserById($character['user_id']); @@ -371,7 +374,6 @@ $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); // Set sort order and page - $selectedCharacters = array(); $sortorder = 'name'; if($this->request->getRequestMethod() == 'POST') @@ -443,7 +445,15 @@ $characters = $this->Characters->getCharactersForSeminarySorted($seminary['id'], $sortorder); foreach($characters as &$character) { - $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); + try { + $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No XP-level + } + if(!is_null($character['avatar_id'])) { + $character['avatar'] = $this->Avatars->getAvatarById($character['avatar_id']); + } $character['user'] = $this->Users->getUserById($character['user_id']); $character['characterroles'] = array_map(function($r) { return $r['name']; }, $this->Characterroles->getCharacterrolesForCharacterById($character['id'])); $character['characterfields'] = array(); diff --git a/db/create.sql b/db/create.sql index 5c7188cb..fd9f11ec 100644 --- a/db/create.sql +++ b/db/create.sql @@ -316,14 +316,14 @@ CREATE TABLE `cache_characters` ( `character_id` int(11) NOT NULL, `xps` int(10) unsigned NOT NULL, `quest_xps` int(10) unsigned NOT NULL, - `xplevel_id` int(11) NOT NULL, - `avatar_id` int(11) NOT NULL, + `xplevel_id` int(11) DEFAULT NULL, + `avatar_id` int(11) DEFAULT NULL, PRIMARY KEY (`character_id`), KEY `xplevel_id` (`xplevel_id`), KEY `avatar_id` (`avatar_id`), CONSTRAINT `cache_characters_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `cache_characters_ibfk_2` FOREIGN KEY (`xplevel_id`) REFERENCES `xplevels` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `cache_characters_ibfk_3` FOREIGN KEY (`avatar_id`) REFERENCES `avatars` (`id`) ON DELETE CASCADE ON UPDATE CASCADE + CONSTRAINT `cache_characters_ibfk_2` FOREIGN KEY (`xplevel_id`) REFERENCES `xplevels` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `cache_characters_ibfk_3` FOREIGN KEY (`avatar_id`) REFERENCES `avatars` (`id`) ON DELETE SET NULL ON UPDATE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1974,6 +1974,63 @@ CREATE TABLE `xplevels` ( CONSTRAINT `xplevels_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_xplevels_insert` +AFTER INSERT ON xplevels +FOR EACH ROW BEGIN + CALL update_cache_characters_xplevels(NEW.seminary_id, NEW.xps, NULL); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_xplevels_update` +AFTER UPDATE ON xplevels +FOR EACH ROW BEGIN + CALL update_cache_characters_xplevels(NEW.seminary_id, OLD.xps, NEW.xps); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_xplevels_delete` +AFTER DELETE ON xplevels +FOR EACH ROW BEGIN + CALL update_cache_characters_xplevels(OLD.seminary_id, OLD.xps, NULL); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Dumping routines for database 'z' @@ -2053,52 +2110,52 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -CREATE DEFINER=`z`@`%` PROCEDURE `update_cache_characters`( - IN CHARACTERID INT(11) +CREATE DEFINER=`z`@`%` PROCEDURE `update_cache_characters`( + IN CHARACTERID INT(11) ) -BEGIN - DECLARE QUESTXPS INT UNSIGNED; - DECLARE GROUPSXPS INT UNSIGNED; - DECLARE TOTALXPS INT UNSIGNED; - DECLARE XPLEVELID INT; - DECLARE AVATARID INT; - - - SELECT IFNULL(SUM(quests.xps),0) INTO QUESTXPS - FROM quests_characters - LEFT JOIN quests ON quests.id = quests_characters.quest_id - WHERE quests_characters.character_id = CHARACTERID AND quests_characters.status = 3; - SELECT IFNULL(SUM(cache_charactergroups.xps),0) INTO GROUPSXPS - FROM characters_charactergroups - LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = characters_charactergroups.charactergroup_id - WHERE characters_charactergroups.character_id = CHARACTERID; - SET TOTALXPS = QUESTXPS + GROUPSXPS; - - - SELECT ( - SELECT id - FROM xplevels - WHERE seminary_id = charactertypes.seminary_id AND xps = ( - SELECT MAX(xps) - FROM xplevels AS xplevels_sub - WHERE xps <= TOTALXPS - ) - ) INTO XPLEVELID - FROM characters - LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id - WHERE characters.id = CHARACTERID; - - - SELECT avatars.id INTO AVATARID - FROM characters - LEFT JOIN avatars ON avatars.charactertype_id = characters.charactertype_id AND avatars.xplevel_id = XPLEVELID - WHERE characters.id = CHARACTERID; - - - REPLACE INTO cache_characters - (character_id, xps, quest_xps, xplevel_id, avatar_id) - VALUES - (CHARACTERID, TOTALXPS, QUESTXPS, XPLEVELID, AVATARID); +BEGIN + DECLARE QUESTXPS INT UNSIGNED; + DECLARE GROUPSXPS INT UNSIGNED; + DECLARE TOTALXPS INT UNSIGNED; + DECLARE XPLEVELID INT; + DECLARE AVATARID INT; + + + SELECT IFNULL(SUM(quests.xps),0) INTO QUESTXPS + FROM quests_characters + LEFT JOIN quests ON quests.id = quests_characters.quest_id + WHERE quests_characters.character_id = CHARACTERID AND quests_characters.status = 3; + SELECT IFNULL(SUM(cache_charactergroups.xps),0) INTO GROUPSXPS + FROM characters_charactergroups + LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = characters_charactergroups.charactergroup_id + WHERE characters_charactergroups.character_id = CHARACTERID; + SET TOTALXPS = QUESTXPS + GROUPSXPS; + + + SELECT ( + SELECT id + FROM xplevels + WHERE seminary_id = charactertypes.seminary_id AND xps = ( + SELECT MAX(xplevels_sub.xps) + FROM xplevels AS xplevels_sub + WHERE xplevels_sub.seminary_id = charactertypes.seminary_id AND xps <= TOTALXPS + ) + ) INTO XPLEVELID + FROM characters + LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id + WHERE characters.id = CHARACTERID; + + + SELECT avatars.id INTO AVATARID + FROM characters + LEFT JOIN avatars ON avatars.charactertype_id = characters.charactertype_id AND avatars.xplevel_id = XPLEVELID + WHERE characters.id = CHARACTERID; + + + REPLACE INTO cache_characters + (character_id, xps, quest_xps, xplevel_id, avatar_id) + VALUES + (CHARACTERID, TOTALXPS, QUESTXPS, XPLEVELID, AVATARID); END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -2179,6 +2236,54 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `update_cache_characters_xplevels` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +CREATE DEFINER=`z`@`%` PROCEDURE `update_cache_characters_xplevels`( + IN SEMINARYID INT(11), + IN XPS_LOWER INT(11), + IN XPS_UPPER INT(11) +) +BEGIN + DECLARE CHARACTERID INT; + DECLARE done INT DEFAULT FALSE; + DECLARE characters_cursor CURSOR FOR + SELECT cache_characters.character_id + FROM charactertypes + INNER JOIN characters ON characters.charactertype_id = charactertypes.id + INNER JOIN cache_characters ON cache_characters.character_id = characters.id + WHERE charactertypes.seminary_id = SEMINARY_ID AND cache_characters.xps >= LEAST(XPS_LOWER, IFNULL(XPS_UPPER,XPS_LOWER)) AND (XPS_UPPER IS NULL OR cache_characters.xps <= GREATEST(XPS_LOWER, XPS_UPPER)); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + IF XPS_UPPER IS NULL THEN + SELECT MIN(xps) INTO XPS_UPPER + FROM xplevels + WHERE seminary_id = SEMINARYID AND xps > XPS_LOWER; + END IF; + + + SET done = 0; + OPEN characters_cursor; + get_characters: LOOP + FETCH characters_cursor INTO CHARACTERID; + IF done = TRUE THEN + LEAVE get_characters; + END IF; + CALL update_cache_characters(CHARACTERID); + END LOOP get_characters; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; diff --git a/db/procedures.sql b/db/procedures.sql index dedbf893..7ac2fae8 100644 --- a/db/procedures.sql +++ b/db/procedures.sql @@ -52,6 +52,44 @@ END $$ DELIMITER ; +DROP PROCEDURE IF EXISTS update_cache_characters_xplevels; +DELIMITER $$ +CREATE PROCEDURE update_cache_characters_xplevels( + IN SEMINARYID INT(11), + IN XPS_LOWER INT(11), + IN XPS_UPPER INT(11) +) +BEGIN + DECLARE CHARACTERID INT; + DECLARE done INT DEFAULT FALSE; + DECLARE characters_cursor CURSOR FOR + SELECT cache_characters.character_id + FROM charactertypes + INNER JOIN characters ON characters.charactertype_id = charactertypes.id + INNER JOIN cache_characters ON cache_characters.character_id = characters.id + WHERE charactertypes.seminary_id = SEMINARY_ID AND cache_characters.xps >= LEAST(XPS_LOWER, IFNULL(XPS_UPPER,XPS_LOWER)) AND (XPS_UPPER IS NULL OR cache_characters.xps <= GREATEST(XPS_LOWER, XPS_UPPER)); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + -- Get upper XPs + IF XPS_UPPER IS NULL THEN + SELECT MIN(xps) INTO XPS_UPPER + FROM xplevels + WHERE seminary_id = SEMINARYID AND xps > XPS_LOWER; + END IF; + + SET done = 0; + OPEN characters_cursor; + get_characters: LOOP + FETCH characters_cursor INTO CHARACTERID; + IF done = TRUE THEN + LEAVE get_characters; + END IF; + CALL update_cache_characters(CHARACTERID); + END LOOP get_characters; +END $$ +DELIMITER ; + + DROP PROCEDURE IF EXISTS update_cache_characters; DELIMITER $$ CREATE DEFINER = 'z'@'%' PROCEDURE update_cache_characters( @@ -80,9 +118,9 @@ BEGIN SELECT id FROM xplevels WHERE seminary_id = charactertypes.seminary_id AND xps = ( - SELECT MAX(xps) + SELECT MAX(xplevels_sub.xps) FROM xplevels AS xplevels_sub - WHERE xps <= TOTALXPS + WHERE xplevels_sub.seminary_id = charactertypes.seminary_id AND xps <= TOTALXPS ) ) INTO XPLEVELID FROM characters diff --git a/db/triggers.sql b/db/triggers.sql index 62ad5066..3ff9e1db 100644 --- a/db/triggers.sql +++ b/db/triggers.sql @@ -1,4 +1,4 @@ -/** Characters +Quests **/ +/** Characters + Quests **/ DROP TRIGGER IF EXISTS update_cache_characters_insert; DELIMITER $$ @@ -49,7 +49,7 @@ DELIMITER ; -/** Charactergroups +Charactergroupsquests **/ +/** Charactergroups + Charactergroupsquests **/ DROP TRIGGER IF EXISTS update_cache_charactergroups_insert; DELIMITER $$ @@ -100,7 +100,7 @@ DELIMITER ; -/** Characters → Charactergroups **/ +/** Characters + Charactergroups **/ DROP TRIGGER IF EXISTS update_cache_characters_charactergroups_insert; DELIMITER $$ @@ -153,3 +153,34 @@ FOR EACH ROW BEGIN END $$ DELIMITER ; + + + +/** XP-levels **/ + +DROP TRIGGER IF EXISTS update_cache_characters_xplevels_insert; +DELIMITER $$ +CREATE DEFINER = 'z'@'%' TRIGGER `update_cache_characters_xplevels_insert` +AFTER INSERT ON xplevels +FOR EACH ROW BEGIN + CALL update_cache_characters_xplevels(NEW.seminary_id, NEW.xps, NULL); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_characters_xplevels_update; +DELIMITER $$ +CREATE DEFINER = 'z'@'%' TRIGGER `update_cache_characters_xplevels_update` +AFTER UPDATE ON xplevels +FOR EACH ROW BEGIN + CALL update_cache_characters_xplevels(NEW.seminary_id, OLD.xps, NEW.xps); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_characters_xplevels_delete; +DELIMITER $$ +CREATE DEFINER = 'z'@'%' TRIGGER `update_cache_characters_xplevels_delete` +AFTER DELETE ON xplevels +FOR EACH ROW BEGIN + CALL update_cache_characters_xplevels(OLD.seminary_id, OLD.xps, NULL); +END $$ +DELIMITER ; diff --git a/views/html/achievements/edit.tpl b/views/html/achievements/edit.tpl index d341b7ee..bc67eb85 100644 --- a/views/html/achievements/edit.tpl +++ b/views/html/achievements/edit.tpl @@ -55,10 +55,14 @@
+ +
+ +

:

diff --git a/views/html/characters/character.tpl b/views/html/characters/character.tpl index 7e1689f8..f8510a94 100644 --- a/views/html/characters/character.tpl +++ b/views/html/characters/character.tpl @@ -61,7 +61,9 @@
+ +
@@ -84,7 +86,7 @@
  • - +

    .

    diff --git a/views/html/characters/manage.tpl b/views/html/characters/manage.tpl index 6595e6cc..92eb29ea 100644 --- a/views/html/characters/manage.tpl +++ b/views/html/characters/manage.tpl @@ -25,7 +25,9 @@
  • checked="checked" disabled="disabled"/>