Adds achievement metadata table (#48007)

* Renames hub_id to database_id
Adds achievement_metadata table.

* Fixups

* enum
This commit is contained in:
AnturK
2019-11-30 08:34:42 +01:00
committed by Jordie
parent f24450a1a8
commit f28b2d60b9
10 changed files with 112 additions and 44 deletions

View File

@@ -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: 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 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. 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;
----------------------------------------------------- -----------------------------------------------------

View File

@@ -527,6 +527,14 @@ CREATE TABLE `achievements` (
PRIMARY KEY (`ckey`,`achievement_key`) PRIMARY KEY (`ckey`,`achievement_key`)
) ENGINE=InnoDB; ) 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 */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;

View File

@@ -527,6 +527,14 @@ CREATE TABLE `SS13_achievements` (
PRIMARY KEY (`ckey`,`achievement_key`) PRIMARY KEY (`ckey`,`achievement_key`)
) ENGINE=InnoDB; ) 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 */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;

View File

@@ -20,7 +20,7 @@
* *
* make sure you add an update to the schema_version stable in the db changelog * 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 //! ## Timing subsystem

View File

@@ -26,6 +26,8 @@ SUBSYSTEM_DEF(achievements)
scores[T] = instance scores[T] = instance
awards[T] = instance awards[T] = instance
update_metadata()
for(var/i in GLOB.clients) for(var/i in GLOB.clients)
var/client/C = i var/client/C = i
if(!C.player_details.achievements.initialized) if(!C.player_details.achievements.initialized)
@@ -45,3 +47,27 @@ SUBSYSTEM_DEF(achievements)
cheevos_to_save += PD.achievements.get_changed_data() cheevos_to_save += PD.achievements.get_changed_data()
SSdbcore.MassInsert(format_table_name("achievements"),cheevos_to_save,duplicate_key = TRUE) 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)

View File

@@ -47,7 +47,7 @@
if(!A || !A.name) //Skip abstract achievements types if(!A || !A.name) //Skip abstract achievements types
continue continue
if(!data[T]) 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] original_cached_data[T] = data[T]
///Updates local cache with db data for the given achievement type if it wasn't loaded yet. ///Updates local cache with db data for the given achievement type if it wasn't loaded yet.

View File

@@ -6,8 +6,10 @@
var/icon = "default" var/icon = "default"
var/category = "Normal" var/category = "Normal"
///What ID do we use on the hub? ///What ID do we use in db, limited to 32 characters
var/hub_id 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 //Value returned on db connection failure, in case we want to differ 0 and nonexistent later on
var/default_value = FALSE var/default_value = FALSE
@@ -16,20 +18,23 @@
/datum/award/proc/load(key) /datum/award/proc/load(key)
if(!SSdbcore.Connect()) if(!SSdbcore.Connect())
return default_value return default_value
if(!key || !hub_id || !name) if(!key || !database_id || !name)
return default_value return default_value
var/raw_value = get_raw_value(key) var/raw_value = get_raw_value(key)
return parse_value(raw_value) return parse_value(raw_value)
///This saves the changed data to the hub. ///This saves the changed data to the hub.
/datum/award/proc/get_changed_rows(key, value) /datum/award/proc/get_changed_rows(key, value)
if(!hub_id || !key || !name) if(!database_id || !key || !name)
return 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 ///Get raw numerical achievement value from the database
/datum/award/proc/get_raw_value(key) /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)) if(!Q.Execute(async = TRUE))
qdel(Q) qdel(Q)
return 0 return 0
@@ -51,6 +56,10 @@
/datum/award/achievement /datum/award/achievement
desc = "Achievement for epic people" desc = "Achievement for epic people"
/datum/award/achievement/get_metadata_row()
. = ..()
.["achievement_type"] = "'achievement'"
/datum/award/achievement/parse_value(raw_value) /datum/award/achievement/parse_value(raw_value)
return raw_value > 0 return raw_value > 0
@@ -72,8 +81,12 @@
if(track_high_scores) if(track_high_scores)
LoadHighScores() LoadHighScores()
/datum/award/score/get_metadata_row()
. = ..()
.["achievement_type"] = "'score'"
/datum/award/score/proc/LoadHighScores() /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)) if(!Q.Execute(async = TRUE))
qdel(Q) qdel(Q)
return return

View File

@@ -4,79 +4,79 @@
/datum/award/achievement/boss/tendril_exterminator /datum/award/achievement/boss/tendril_exterminator
name = "Tendril Exterminator" name = "Tendril Exterminator"
desc = "Watch your step" desc = "Watch your step"
hub_id = BOSS_MEDAL_TENDRIL database_id = BOSS_MEDAL_TENDRIL
/datum/award/achievement/boss/boss_killer /datum/award/achievement/boss/boss_killer
name = "Boss Killer" name = "Boss Killer"
desc = "You've come a long ways from asking how to switch hands." 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 /datum/award/achievement/boss/blood_miner_kill
name = "Blood-drunk Miner Killer" name = "Blood-drunk Miner Killer"
desc = "I guess he couldn't handle his drink that well." 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 /datum/award/achievement/boss/bubblegum_kill
name = "Bubblegum Killer" name = "Bubblegum Killer"
desc = "I guess he wasn't made of candy after all" 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 /datum/award/achievement/boss/colussus_kill
name = "Colussus Killer" name = "Colussus Killer"
desc = "The bigger they are... the better the loot" 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 /datum/award/achievement/boss/drake_kill
name = "Drake Killer" name = "Drake Killer"
desc = "Now I can wear Rune Platebodies!" desc = "Now I can wear Rune Platebodies!"
hub_id = BOSS_MEDAL_DRAKE database_id = BOSS_MEDAL_DRAKE
/datum/award/achievement/boss/hierophant_kill /datum/award/achievement/boss/hierophant_kill
name = "Hierophant Killer" name = "Hierophant Killer"
desc = "Hierophant, but not triumphant." desc = "Hierophant, but not triumphant."
hub_id = BOSS_MEDAL_HIEROPHANT database_id = BOSS_MEDAL_HIEROPHANT
/datum/award/achievement/boss/legion_kill /datum/award/achievement/boss/legion_kill
name = "Legion Killer" name = "Legion Killer"
desc = "We were many..now we are none." 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 /datum/award/achievement/boss/swarmer_beacon_kill
name = "Swarm Beacon Killer" name = "Swarm Beacon Killer"
desc = "GET THEM OFF OF ME!" desc = "GET THEM OFF OF ME!"
hub_id = BOSS_MEDAL_SWARMERS database_id = BOSS_MEDAL_SWARMERS
/datum/award/achievement/boss/blood_miner_crusher /datum/award/achievement/boss/blood_miner_crusher
name = "Blood-drunk Miner Crusher" name = "Blood-drunk Miner Crusher"
desc = "I guess he couldn't handle his drink that well." 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 /datum/award/achievement/boss/bubblegum_crusher
name = "Bubblegum Crusher" name = "Bubblegum Crusher"
desc = "I guess he wasn't made of candy after all" 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 /datum/award/achievement/boss/colussus_crusher
name = "Colussus Crusher" name = "Colussus Crusher"
desc = "The bigger they are... the better the loot" 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 /datum/award/achievement/boss/drake_crusher
name = "Drake Crusher" name = "Drake Crusher"
desc = "Now I can wear Rune Platebodies!" 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 /datum/award/achievement/boss/hierophant_crusher
name = "Hierophant Crusher" name = "Hierophant Crusher"
desc = "Hierophant, but not triumphant." desc = "Hierophant, but not triumphant."
hub_id = BOSS_MEDAL_HIEROPHANT_CRUSHER database_id = BOSS_MEDAL_HIEROPHANT_CRUSHER
/datum/award/achievement/boss/legion_crusher /datum/award/achievement/boss/legion_crusher
name = "Legion Crusher" name = "Legion Crusher"
desc = "We were many... now we are none." 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 /datum/award/achievement/boss/swarmer_beacon_crusher
name = "Swarm Beacon Crusher" name = "Swarm Beacon Crusher"
desc = "GET THEM OFF OF ME!" desc = "GET THEM OFF OF ME!"
hub_id = BOSS_MEDAL_SWARMERS_CRUSHER database_id = BOSS_MEDAL_SWARMERS_CRUSHER

View File

@@ -1,44 +1,44 @@
/datum/award/score/tendril_score /datum/award/score/tendril_score
name = "Tendril Score" name = "Tendril Score"
desc = "Watch your step" desc = "Watch your step"
hub_id = TENDRIL_CLEAR_SCORE database_id = TENDRIL_CLEAR_SCORE
/datum/award/score/boss_score /datum/award/score/boss_score
name = "Bosses Killed" name = "Bosses Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = BOSS_SCORE database_id = BOSS_SCORE
/datum/award/score/blood_miner_score /datum/award/score/blood_miner_score
name = "Blood-Drunk Miners Killed" name = "Blood-Drunk Miners Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = MINER_SCORE database_id = MINER_SCORE
/datum/award/score/bubblegum_score /datum/award/score/bubblegum_score
name = "Bubblegums Killed" name = "Bubblegums Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = BUBBLEGUM_SCORE database_id = BUBBLEGUM_SCORE
/datum/award/score/colussus_score /datum/award/score/colussus_score
name = "Colossus Killed" name = "Colossus Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = COLOSSUS_SCORE database_id = COLOSSUS_SCORE
/datum/award/score/drake_score /datum/award/score/drake_score
name = "Drakes Killed" name = "Drakes Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = DRAKE_SCORE database_id = DRAKE_SCORE
/datum/award/score/hierophant_score /datum/award/score/hierophant_score
name = "Hierophants Killed" name = "Hierophants Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = HIEROPHANT_SCORE database_id = HIEROPHANT_SCORE
/datum/award/score/legion_score /datum/award/score/legion_score
name = "Legions Killed" name = "Legions Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = LEGION_SCORE database_id = LEGION_SCORE
/datum/award/score/swarmer_beacon_score /datum/award/score/swarmer_beacon_score
name = "Swarmer Beacons Killed" name = "Swarmer Beacons Killed"
desc = "You've killed HOW many?" desc = "You've killed HOW many?"
hub_id = SWARMER_BEACON_SCORE database_id = SWARMER_BEACON_SCORE

View File

@@ -4,39 +4,39 @@
/datum/award/achievement/misc/meteor_examine /datum/award/achievement/misc/meteor_examine
name = "Your Life Before Your Eyes" name = "Your Life Before Your Eyes"
desc = "Take a close look at hurtling space debris" desc = "Take a close look at hurtling space debris"
hub_id = MEDAL_METEOR database_id = MEDAL_METEOR
/datum/award/achievement/misc/pulse /datum/award/achievement/misc/pulse
name = "Jackpot" name = "Jackpot"
desc = "Win a pulse rifle from an arcade machine" desc = "Win a pulse rifle from an arcade machine"
hub_id = MEDAL_PULSE database_id = MEDAL_PULSE
/datum/award/achievement/misc/time_waste /datum/award/achievement/misc/time_waste
name = "Time waster" name = "Time waster"
desc = "Speak no evil, hear no evil, see just errors" 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 /datum/award/achievement/misc/feat_of_strength
name = "Feat of Strength" name = "Feat of Strength"
desc = "If the rod is immovable, is it passing you or are you passing it?" 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 /datum/award/achievement/misc/round_and_full
name = "Round and Full" name = "Round and Full"
desc = "Well at least you aren't down the river, I hear they eat people there." 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 /datum/award/achievement/misc/the_best_driver
name = "The Best Driver" name = "The Best Driver"
desc = "100 honks later" desc = "100 honks later"
hub_id = MEDAL_THANKSALOT database_id = MEDAL_THANKSALOT
/datum/award/achievement/misc/helbitaljanken /datum/award/achievement/misc/helbitaljanken
name = "Helbitaljanken" name = "Helbitaljanken"
desc = "You janked hard" desc = "You janked hard"
hub_id = MEDAL_HELBITALJANKEN database_id = MEDAL_HELBITALJANKEN
/datum/award/achievement/misc/getting_an_upgrade /datum/award/achievement/misc/getting_an_upgrade
name = "Getting an upgrade" name = "Getting an upgrade"
desc = "Make your first unique material item!" desc = "Make your first unique material item!"
hub_id = MEDAL_MATERIALCRAFT database_id = MEDAL_MATERIALCRAFT