diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index 8ac8a1bb0e09a..a78fd062b8fab 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -2,12 +2,25 @@ Any time you make a change to the schema files, remember to increment the databa The latest database version is 5.4; The query to update the schema revision table is: -INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 4); +INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 5); or -INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 4); +INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 5); In any query remember to add a prefix to the table names if you use one. +----------------------------------------------------- + +Version 5.5, 26 October 2019 by Anturke +Added achievement_metadata table. + +DROP TABLE IF EXISTS `achievement_metadata`; +CREATE TABLE `achievement_metadata` ( + `achievement_key` VARCHAR(32) NOT NULL, + `achievement_version` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `achievement_type` enum('achievement','score','award') NULL DEFAULT NULL, + PRIMARY KEY (`achievement_key`) +) ENGINE=InnoDB; + ----------------------------------------------------- diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 1738f40151f7b..e89a3a99528b8 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -527,6 +527,14 @@ CREATE TABLE `achievements` ( PRIMARY KEY (`ckey`,`achievement_key`) ) ENGINE=InnoDB; +DROP TABLE IF EXISTS `achievement_metadata`; +CREATE TABLE `achievement_metadata` ( + `achievement_key` VARCHAR(32) NOT NULL, + `achievement_version` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `achievement_type` enum('achievement','score','award') NULL DEFAULT NULL, + PRIMARY KEY (`achievement_key`) +) ENGINE=InnoDB; + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 37d268d4c96fd..4e21ab06fd07f 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -527,6 +527,14 @@ CREATE TABLE `SS13_achievements` ( PRIMARY KEY (`ckey`,`achievement_key`) ) ENGINE=InnoDB; +DROP TABLE IF EXISTS `SS13_achievement_metadata`; +CREATE TABLE `SS13_achievement_metadata` ( + `achievement_key` VARCHAR(32) NOT NULL, + `achievement_version` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `achievement_type` enum('achievement','score','award') NULL DEFAULT NULL, + PRIMARY KEY (`achievement_key`) +) ENGINE=InnoDB; + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 22ddbc6619375..67014a478228c 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -20,7 +20,7 @@ * * make sure you add an update to the schema_version stable in the db changelog */ -#define DB_MINOR_VERSION 4 +#define DB_MINOR_VERSION 5 //! ## Timing subsystem diff --git a/code/controllers/subsystem/achievements.dm b/code/controllers/subsystem/achievements.dm index 369ffa6f6724a..c87b83771cc20 100644 --- a/code/controllers/subsystem/achievements.dm +++ b/code/controllers/subsystem/achievements.dm @@ -26,6 +26,8 @@ SUBSYSTEM_DEF(achievements) scores[T] = instance awards[T] = instance + update_metadata() + for(var/i in GLOB.clients) var/client/C = i if(!C.player_details.achievements.initialized) @@ -45,3 +47,27 @@ SUBSYSTEM_DEF(achievements) cheevos_to_save += PD.achievements.get_changed_data() SSdbcore.MassInsert(format_table_name("achievements"),cheevos_to_save,duplicate_key = TRUE) + +//Update the metadata if any are behind +/datum/controller/subsystem/achievements/proc/update_metadata() + var/list/current_metadata = list() + //select metadata here + var/datum/DBQuery/Q = SSdbcore.NewQuery("SELECT achievement_key,achievement_version FROM [format_table_name("achievement_metadata")]") + if(!Q.Execute(async = TRUE)) + qdel(Q) + return + else + while(Q.NextRow()) + current_metadata[Q.item[1]] = text2num(Q.item[2]) + qdel(Q) + + var/list/to_update = list() + for(var/T in awards) + var/datum/award/A = awards[T] + if(!A.database_id) + continue + if(!current_metadata[A.database_id] || current_metadata[A.database_id] < A.achievement_version) + to_update += list(A.get_metadata_row()) + + if(to_update.len) + SSdbcore.MassInsert(format_table_name("achievement_metadata"),to_update,duplicate_key = TRUE) diff --git a/code/datums/achievements/_achievement_data.dm b/code/datums/achievements/_achievement_data.dm index d9d491d74958a..2a000c15557cd 100644 --- a/code/datums/achievements/_achievement_data.dm +++ b/code/datums/achievements/_achievement_data.dm @@ -47,7 +47,7 @@ if(!A || !A.name) //Skip abstract achievements types continue if(!data[T]) - data[T] = A.parse_value(kv[A.hub_id]) + data[T] = A.parse_value(kv[A.database_id]) original_cached_data[T] = data[T] ///Updates local cache with db data for the given achievement type if it wasn't loaded yet. diff --git a/code/datums/achievements/_awards.dm b/code/datums/achievements/_awards.dm index 6c944118e96e2..db2added967b4 100644 --- a/code/datums/achievements/_awards.dm +++ b/code/datums/achievements/_awards.dm @@ -6,8 +6,10 @@ var/icon = "default" var/category = "Normal" - ///What ID do we use on the hub? - var/hub_id + ///What ID do we use in db, limited to 32 characters + var/database_id + //Bump this up if you're changing outdated table identifier and/or achievement type + var/achievement_version = 1 //Value returned on db connection failure, in case we want to differ 0 and nonexistent later on var/default_value = FALSE @@ -16,20 +18,23 @@ /datum/award/proc/load(key) if(!SSdbcore.Connect()) return default_value - if(!key || !hub_id || !name) + if(!key || !database_id || !name) return default_value var/raw_value = get_raw_value(key) return parse_value(raw_value) ///This saves the changed data to the hub. /datum/award/proc/get_changed_rows(key, value) - if(!hub_id || !key || !name) + if(!database_id || !key || !name) return - return list("ckey" = "'[sanitizeSQL(key)]'","achievement_key" = "'[sanitizeSQL(hub_id)]'", "value" = "'[sanitizeSQL(value)]'") + return list("ckey" = "'[sanitizeSQL(key)]'","achievement_key" = "'[sanitizeSQL(database_id)]'", "value" = "'[sanitizeSQL(value)]'") + +/datum/award/proc/get_metadata_row() + return list("achievement_key" = "'[sanitizeSQL(database_id)]'", "achievement_version" = "'[sanitizeSQL(achievement_version)]'", "achievement_type" = "'award'") ///Get raw numerical achievement value from the database /datum/award/proc/get_raw_value(key) - var/datum/DBQuery/Q = SSdbcore.NewQuery("SELECT value FROM [format_table_name("achievements")] WHERE ckey = '[sanitizeSQL(key)]' AND achievement_key = '[sanitizeSQL(hub_id)]'") + var/datum/DBQuery/Q = SSdbcore.NewQuery("SELECT value FROM [format_table_name("achievements")] WHERE ckey = '[sanitizeSQL(key)]' AND achievement_key = '[sanitizeSQL(database_id)]'") if(!Q.Execute(async = TRUE)) qdel(Q) return 0 @@ -51,6 +56,10 @@ /datum/award/achievement desc = "Achievement for epic people" +/datum/award/achievement/get_metadata_row() + . = ..() + .["achievement_type"] = "'achievement'" + /datum/award/achievement/parse_value(raw_value) return raw_value > 0 @@ -72,8 +81,12 @@ if(track_high_scores) LoadHighScores() +/datum/award/score/get_metadata_row() + . = ..() + .["achievement_type"] = "'score'" + /datum/award/score/proc/LoadHighScores() - var/datum/DBQuery/Q = SSdbcore.NewQuery("SELECT ckey,value FROM [format_table_name("achievements")] WHERE achievement_key = '[sanitizeSQL(hub_id)]' ORDER BY value DESC LIMIT 50") + var/datum/DBQuery/Q = SSdbcore.NewQuery("SELECT ckey,value FROM [format_table_name("achievements")] WHERE achievement_key = '[sanitizeSQL(database_id)]' ORDER BY value DESC LIMIT 50") if(!Q.Execute(async = TRUE)) qdel(Q) return diff --git a/code/datums/achievements/boss_achievements.dm b/code/datums/achievements/boss_achievements.dm index 4a6b1f2e451e2..d50c6a37203a4 100644 --- a/code/datums/achievements/boss_achievements.dm +++ b/code/datums/achievements/boss_achievements.dm @@ -4,79 +4,79 @@ /datum/award/achievement/boss/tendril_exterminator name = "Tendril Exterminator" desc = "Watch your step" - hub_id = BOSS_MEDAL_TENDRIL + database_id = BOSS_MEDAL_TENDRIL /datum/award/achievement/boss/boss_killer name = "Boss Killer" desc = "You've come a long ways from asking how to switch hands." - hub_id = "Boss Killer" + database_id = "Boss Killer" /datum/award/achievement/boss/blood_miner_kill name = "Blood-drunk Miner Killer" desc = "I guess he couldn't handle his drink that well." - hub_id = BOSS_MEDAL_MINER + database_id = BOSS_MEDAL_MINER /datum/award/achievement/boss/bubblegum_kill name = "Bubblegum Killer" desc = "I guess he wasn't made of candy after all" - hub_id = BOSS_MEDAL_BUBBLEGUM + database_id = BOSS_MEDAL_BUBBLEGUM /datum/award/achievement/boss/colussus_kill name = "Colussus Killer" desc = "The bigger they are... the better the loot" - hub_id = BOSS_MEDAL_COLOSSUS + database_id = BOSS_MEDAL_COLOSSUS /datum/award/achievement/boss/drake_kill name = "Drake Killer" desc = "Now I can wear Rune Platebodies!" - hub_id = BOSS_MEDAL_DRAKE + database_id = BOSS_MEDAL_DRAKE /datum/award/achievement/boss/hierophant_kill name = "Hierophant Killer" desc = "Hierophant, but not triumphant." - hub_id = BOSS_MEDAL_HIEROPHANT + database_id = BOSS_MEDAL_HIEROPHANT /datum/award/achievement/boss/legion_kill name = "Legion Killer" desc = "We were many..now we are none." - hub_id = BOSS_MEDAL_LEGION + database_id = BOSS_MEDAL_LEGION /datum/award/achievement/boss/swarmer_beacon_kill name = "Swarm Beacon Killer" desc = "GET THEM OFF OF ME!" - hub_id = BOSS_MEDAL_SWARMERS + database_id = BOSS_MEDAL_SWARMERS /datum/award/achievement/boss/blood_miner_crusher name = "Blood-drunk Miner Crusher" desc = "I guess he couldn't handle his drink that well." - hub_id = BOSS_MEDAL_MINER_CRUSHER + database_id = BOSS_MEDAL_MINER_CRUSHER /datum/award/achievement/boss/bubblegum_crusher name = "Bubblegum Crusher" desc = "I guess he wasn't made of candy after all" - hub_id = BOSS_MEDAL_BUBBLEGUM_CRUSHER + database_id = BOSS_MEDAL_BUBBLEGUM_CRUSHER /datum/award/achievement/boss/colussus_crusher name = "Colussus Crusher" desc = "The bigger they are... the better the loot" - hub_id = BOSS_MEDAL_COLOSSUS_CRUSHER + database_id = BOSS_MEDAL_COLOSSUS_CRUSHER /datum/award/achievement/boss/drake_crusher name = "Drake Crusher" desc = "Now I can wear Rune Platebodies!" - hub_id = BOSS_MEDAL_DRAKE_CRUSHER + database_id = BOSS_MEDAL_DRAKE_CRUSHER /datum/award/achievement/boss/hierophant_crusher name = "Hierophant Crusher" desc = "Hierophant, but not triumphant." - hub_id = BOSS_MEDAL_HIEROPHANT_CRUSHER + database_id = BOSS_MEDAL_HIEROPHANT_CRUSHER /datum/award/achievement/boss/legion_crusher name = "Legion Crusher" desc = "We were many... now we are none." - hub_id = BOSS_MEDAL_LEGION_CRUSHER + database_id = BOSS_MEDAL_LEGION_CRUSHER /datum/award/achievement/boss/swarmer_beacon_crusher name = "Swarm Beacon Crusher" desc = "GET THEM OFF OF ME!" - hub_id = BOSS_MEDAL_SWARMERS_CRUSHER + database_id = BOSS_MEDAL_SWARMERS_CRUSHER diff --git a/code/datums/achievements/boss_scores.dm b/code/datums/achievements/boss_scores.dm index 4e7930b8ba308..85a5e795f6cd7 100644 --- a/code/datums/achievements/boss_scores.dm +++ b/code/datums/achievements/boss_scores.dm @@ -1,44 +1,44 @@ /datum/award/score/tendril_score name = "Tendril Score" desc = "Watch your step" - hub_id = TENDRIL_CLEAR_SCORE + database_id = TENDRIL_CLEAR_SCORE /datum/award/score/boss_score name = "Bosses Killed" desc = "You've killed HOW many?" - hub_id = BOSS_SCORE + database_id = BOSS_SCORE /datum/award/score/blood_miner_score name = "Blood-Drunk Miners Killed" desc = "You've killed HOW many?" - hub_id = MINER_SCORE + database_id = MINER_SCORE /datum/award/score/bubblegum_score name = "Bubblegums Killed" desc = "You've killed HOW many?" - hub_id = BUBBLEGUM_SCORE + database_id = BUBBLEGUM_SCORE /datum/award/score/colussus_score name = "Colossus Killed" desc = "You've killed HOW many?" - hub_id = COLOSSUS_SCORE + database_id = COLOSSUS_SCORE /datum/award/score/drake_score name = "Drakes Killed" desc = "You've killed HOW many?" - hub_id = DRAKE_SCORE + database_id = DRAKE_SCORE /datum/award/score/hierophant_score name = "Hierophants Killed" desc = "You've killed HOW many?" - hub_id = HIEROPHANT_SCORE + database_id = HIEROPHANT_SCORE /datum/award/score/legion_score name = "Legions Killed" desc = "You've killed HOW many?" - hub_id = LEGION_SCORE + database_id = LEGION_SCORE /datum/award/score/swarmer_beacon_score name = "Swarmer Beacons Killed" desc = "You've killed HOW many?" - hub_id = SWARMER_BEACON_SCORE + database_id = SWARMER_BEACON_SCORE diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm index 59cc90ea394e9..51e72555d16f4 100644 --- a/code/datums/achievements/misc_achievements.dm +++ b/code/datums/achievements/misc_achievements.dm @@ -4,39 +4,39 @@ /datum/award/achievement/misc/meteor_examine name = "Your Life Before Your Eyes" desc = "Take a close look at hurtling space debris" - hub_id = MEDAL_METEOR + database_id = MEDAL_METEOR /datum/award/achievement/misc/pulse name = "Jackpot" desc = "Win a pulse rifle from an arcade machine" - hub_id = MEDAL_PULSE + database_id = MEDAL_PULSE /datum/award/achievement/misc/time_waste name = "Time waster" desc = "Speak no evil, hear no evil, see just errors" - hub_id = MEDAL_TIMEWASTE + database_id = MEDAL_TIMEWASTE /datum/award/achievement/misc/feat_of_strength name = "Feat of Strength" desc = "If the rod is immovable, is it passing you or are you passing it?" - hub_id = MEDAL_RODSUPLEX + database_id = MEDAL_RODSUPLEX /datum/award/achievement/misc/round_and_full name = "Round and Full" desc = "Well at least you aren't down the river, I hear they eat people there." - hub_id = MEDAL_CLOWNCARKING + database_id = MEDAL_CLOWNCARKING /datum/award/achievement/misc/the_best_driver name = "The Best Driver" desc = "100 honks later" - hub_id = MEDAL_THANKSALOT + database_id = MEDAL_THANKSALOT /datum/award/achievement/misc/helbitaljanken name = "Helbitaljanken" desc = "You janked hard" - hub_id = MEDAL_HELBITALJANKEN + database_id = MEDAL_HELBITALJANKEN /datum/award/achievement/misc/getting_an_upgrade name = "Getting an upgrade" desc = "Make your first unique material item!" - hub_id = MEDAL_MATERIALCRAFT + database_id = MEDAL_MATERIALCRAFT