From cc1d254b6a6e0c1823b409def8bd1ea7ee376f55 Mon Sep 17 00:00:00 2001 From: skull132 Date: Mon, 21 Nov 2016 01:01:40 +0200 Subject: [PATCH] Partially implement loading TODO: sanitization --- .../antagonism/01_candidacy.dm | 3 + .../preference_setup/antagonism/02_setup.dm | 4 + .../preference_setup/general/01_basic.dm | 9 ++ .../preference_setup/general/02_language.dm | 3 + .../preference_setup/general/03_body.dm | 17 ++- .../preference_setup/general/04_equipment.dm | 3 + .../preference_setup/general/05_background.dm | 7 ++ .../preference_setup/general/06_flavor.dm | 17 +++ .../client/preference_setup/global/01_ui.dm | 11 +- .../preference_setup/global/02_settings.dm | 3 + .../preference_setup/global/03_language.dm | 4 +- .../client/preference_setup/global/04_pai.dm | 2 + .../preference_setup/occupation/occupation.dm | 3 + .../preference_setup/preference_setup.dm | 101 +++++++++++++++++- .../client/preference_setup/skills/skills.dm | 3 + 15 files changed, 180 insertions(+), 10 deletions(-) diff --git a/code/modules/client/preference_setup/antagonism/01_candidacy.dm b/code/modules/client/preference_setup/antagonism/01_candidacy.dm index 94a86080253..0c9a4a0cb3d 100644 --- a/code/modules/client/preference_setup/antagonism/01_candidacy.dm +++ b/code/modules/client/preference_setup/antagonism/01_candidacy.dm @@ -8,6 +8,9 @@ /datum/category_item/player_setup_item/antagonism/candidacy/save_character(var/savefile/S) S["be_special"] << pref.be_special_role +/datum/category_item/player_setup_item/antagonism/candidacy/gather_load_query() + return list("ss13_characters" = list("vars" = list("be_special_role"), "args" = list("id"))) + /datum/category_item/player_setup_item/antagonism/candidacy/sanitize_character() if(!istype(pref.be_special_role)) pref.be_special_role = list() diff --git a/code/modules/client/preference_setup/antagonism/02_setup.dm b/code/modules/client/preference_setup/antagonism/02_setup.dm index 249d7bf2bb5..c84c2a6781f 100644 --- a/code/modules/client/preference_setup/antagonism/02_setup.dm +++ b/code/modules/client/preference_setup/antagonism/02_setup.dm @@ -12,6 +12,10 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None") S["uplinklocation"] << pref.uplinklocation S["exploit_record"] << pref.exploit_record +/datum/category_item/player_setup_item/antagonism/basic/gather_load_query() + return list("ss13_characters_flavour" = list("vars" = list("records_exploit" = "exploit_record"), "args" = list("char_id")), + "ss13_characters" = list("vars" = list("uplink_location" = "uplinklocation"), "args" = list("id"))) + /datum/category_item/player_setup_item/antagonism/basic/sanitize_character() pref.uplinklocation = sanitize_inlist(pref.uplinklocation, uplink_locations, initial(pref.uplinklocation)) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 440cf90e59c..ac430e4caac 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -19,6 +19,15 @@ S["spawnpoint"] << pref.spawnpoint S["OOC_Notes"] << pref.metadata +/datum/category_item/player_setup_item/general/basic/gather_load_query() + return list("ss13_characters" = list("vars" = list("name" = "real_name", + "random_name" = "be_random_name", + "gender", + "age", + "metadata", + "spawnpoint"), + "args" = list("id"))) + /datum/category_item/player_setup_item/general/basic/sanitize_character() pref.age = sanitize_integer(pref.age, AGE_MIN, AGE_MAX, initial(pref.age)) pref.gender = sanitize_inlist(pref.gender, valid_player_genders, pick(valid_player_genders)) diff --git a/code/modules/client/preference_setup/general/02_language.dm b/code/modules/client/preference_setup/general/02_language.dm index c7cb7afca74..96864e8eed8 100644 --- a/code/modules/client/preference_setup/general/02_language.dm +++ b/code/modules/client/preference_setup/general/02_language.dm @@ -8,6 +8,9 @@ /datum/category_item/player_setup_item/general/language/save_character(var/savefile/S) S["language"] << pref.alternate_languages +/datum/category_item/player_setup_item/general/language/gather_load_query() + return list("ss13_characters" = list("vars" = list("language" = "alternate_languages"), "args" = list("id"))) + /datum/category_item/player_setup_item/general/language/sanitize_character() if(!islist(pref.alternate_languages)) pref.alternate_languages = list() diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 08330e5e811..7c66c59901e 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -48,6 +48,21 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O S["organ_data"] << pref.organ_data S["rlimb_data"] << pref.rlimb_data +/datum/category_item/player_setup_item/general/body/gather_load_query() + return list("ss13_characters" = list("vars" = list("species", + "hair_colour", + "facial_colour", + "skin_tone" = "s_tone", + "skin_colour", + "hair_style" = "h_style", + "facial_style" = "f_style", + "eyes_colour", + "b_type", + "disabilities", + "organs_data" = "organ_data", + "organs_robotic" = "rlimb_data"), + "args" = list("id"))) + /datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S) if(!pref.species || !(pref.species in playable_species)) pref.species = "Human" @@ -210,7 +225,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.species = href_list["set_species"] if(prev_species != pref.species) mob_species = all_species[pref.species] - + //grab one of the valid hair styles for the newly chosen species var/list/valid_hairstyles = list() for(var/hairstyle in hair_styles_list) diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index bf933932b83..3d816dd6547 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -14,6 +14,9 @@ S["backbag"] << pref.backbag S["gear"] << pref.gear +/datum/category_item/player_setup_item/general/equipment/gather_load_query() + return list("ss13_characters" = list("vars" = list("underwear", "undershirt", "backbag", "gear"), "args" = list("id"))) + /datum/category_item/player_setup_item/general/equipment/sanitize_character() pref.backbag = sanitize_integer(pref.backbag, 1, backbaglist.len, initial(pref.backbag)) diff --git a/code/modules/client/preference_setup/general/05_background.dm b/code/modules/client/preference_setup/general/05_background.dm index 5708d3c757e..2abcb0bf989 100644 --- a/code/modules/client/preference_setup/general/05_background.dm +++ b/code/modules/client/preference_setup/general/05_background.dm @@ -22,6 +22,13 @@ S["religion"] << pref.religion S["nanotrasen_relation"] << pref.nanotrasen_relation +/datum/category_item/player_setup_item/general/background/gather_load_query() + return list("ss13_characters_flavour" = list("vars" = list("records_employment" = "gen_record", + "records_medical" = "med_record", + "records_security" = "sec_record"), + "args" = list("char_id")), + "ss13_characters" = list("vars" = list("home_system", "citizenship", "faction", "religion"), "args" = list("id"))) + /datum/category_item/player_setup_item/general/background/sanitize_character() if(!pref.home_system) pref.home_system = "Unset" if(!pref.citizenship) pref.citizenship = "None" diff --git a/code/modules/client/preference_setup/general/06_flavor.dm b/code/modules/client/preference_setup/general/06_flavor.dm index b312bb95e9b..19873858e61 100644 --- a/code/modules/client/preference_setup/general/06_flavor.dm +++ b/code/modules/client/preference_setup/general/06_flavor.dm @@ -33,6 +33,23 @@ for(var/module in robot_module_types) S["flavour_texts_robot_[module]"] << pref.flavour_texts_robot[module] +/datum/category_item/player_setup_item/general/flavor/gather_load_query() + var/list/var_list = list("flavour_general" = "flavor_texts/general", + "flavour_head" = "flavour_texts/head", + "flavour_face" = "flavour_texts/face", + "flavour_eyes" = "flavour_texts/eyes", + "flavour_torso" = "flavour_texts/torso", + "flavour_arms" = "flavour_texts/arms", + "flavour_hands" = "flavour_texts/hands", + "flavour_legs" = "flavour_texts/legs", + "flavour_feet" = "flavour_texts/feet", + "robot_default" = "flavour_texts_robot/default") + + for (var/module in robot_module_types) + var_list["robot_[module]"] = "flavour_texts_robot/[module]" + + return list("ss13_characters_flavour" = list("vars" = var_list, "args" = list("char_id"))) + /datum/category_item/player_setup_item/general/flavor/sanitize_character() return diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 777a51d3549..3f21b4f2622 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -14,6 +14,9 @@ S["UI_style_alpha"] << pref.UI_style_alpha S["ooccolor"] << pref.ooccolor +/datum/category_item/player_setup_item/player_global/ui/gather_load_query() + return list("ss13_player_preferences" = list("vars" = list("UI_style", "UI_style_color", "UI_style_alpha", "ooccolor"), "args" = list("ckey"))) + /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color)) @@ -24,14 +27,14 @@ . += "UI Settings
" . += "UI Style: [pref.UI_style]
" . += "Custom UI (recommended for White UI):
" - . += "-Color: [pref.UI_style_color] 
__
 reset
" - . += "-Alpha(transparency): [pref.UI_style_alpha] reset
" + . += "-Color: [pref.UI_style_color]�
__
�reset
" + . += "-Alpha(transparency): [pref.UI_style_alpha]�reset
" if(can_select_ooc_color(user)) - . += "OOC Color: " + . += "OOC Color:�" if(pref.ooccolor == initial(pref.ooccolor)) . += "Using Default
" else - . += "[pref.ooccolor]
__
 reset
" + . += "[pref.ooccolor]
__
�reset
" /datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user) if(href_list["select_style"]) diff --git a/code/modules/client/preference_setup/global/02_settings.dm b/code/modules/client/preference_setup/global/02_settings.dm index 7b61a86cb44..2e18610039e 100644 --- a/code/modules/client/preference_setup/global/02_settings.dm +++ b/code/modules/client/preference_setup/global/02_settings.dm @@ -12,6 +12,9 @@ S["default_slot"] << pref.default_slot S["toggles"] << pref.toggles +/datum/category_item/player_setup_item/player_global/settings/gather_load_query() + return list("ss13_player_preferences" = list("vars" = list("lastchangelog", "current_character", "toggles", "asfx_toggles"), "args" = list("ckey"))) + /datum/category_item/player_setup_item/player_global/settings/sanitize_preferences() pref.lastchangelog = sanitize_text(pref.lastchangelog, initial(pref.lastchangelog)) pref.default_slot = sanitize_integer(pref.default_slot, 1, config.character_slots, initial(pref.default_slot)) diff --git a/code/modules/client/preference_setup/global/03_language.dm b/code/modules/client/preference_setup/global/03_language.dm index fa3fdbe6e9b..bacb97564f4 100644 --- a/code/modules/client/preference_setup/global/03_language.dm +++ b/code/modules/client/preference_setup/global/03_language.dm @@ -8,6 +8,9 @@ /datum/category_item/player_setup_item/player_global/language/save_preferences(var/savefile/S) S["language_prefixes"] << pref.language_prefixes +/datum/category_item/player_setup_item/player_global/language/gather_load_query() + return list("ss13_player_preferences" = list("vars" = list("language_prefixes"), "args" = list("ckey"))) + /datum/category_item/player_setup_item/player_global/language/sanitize_preferences() if(isnull(pref.language_prefixes) || !pref.language_prefixes.len) pref.language_prefixes = config.language_prefixes.Copy() @@ -52,4 +55,3 @@ if(istype(prefixes) && prefixes.len) preferences["language_prefixes"] = prefixes.Copy() return 1 - diff --git a/code/modules/client/preference_setup/global/04_pai.dm b/code/modules/client/preference_setup/global/04_pai.dm index a7102069e1b..529a751f335 100644 --- a/code/modules/client/preference_setup/global/04_pai.dm +++ b/code/modules/client/preference_setup/global/04_pai.dm @@ -13,6 +13,8 @@ candidate.savefile_load(preference_mob()) +// #TODO-MERGE: Figure out how to handle pAI saving on SQL. + /datum/category_item/player_setup_item/player_global/pai/save_preferences(var/savefile/S) if(!candidate) return diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 92c6320c646..694efb92eeb 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -33,6 +33,9 @@ S["job_engsec_low"] << pref.job_engsec_low S["player_alt_titles"] << pref.player_alt_titles +/datum/category_item/player_setup_item/occupation/gather_load_query() + return list("ss13_characters" = list("vars" = list("jobs" = "unsanitized_jobs", "alternate_option", "alternate_titles" = "player_alt_titles"), "args" = list("id"))) + /datum/category_item/player_setup_item/occupation/sanitize_character() pref.alternate_option = sanitize_integer(pref.alternate_option, 0, 2, initial(pref.alternate_option)) pref.job_civilian_high = sanitize_integer(pref.job_civilian_high, 0, 65535, initial(pref.job_civilian_high)) diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 0fa0bfa10c8..7c9f7a055e5 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -125,12 +125,93 @@ for(var/datum/category_item/player_setup_item/PI in items) PI.sanitize_character() +// For loading character by category. Utilizes query caching. /datum/category_group/player_setup_category/proc/load_character_sql() - var/static/list/query_cache = list() - if (isnull(query_cache[type])) - var/query = "FROM ss13_characters" - for (var/datum/category_item/player_setup_item/PI in items) + var/static/list/query_cache + if (isnull(query_cache)) + query_cache = list() + + // This handles the generation of queries. One per category, total of 5 UNLESS one category wants to query more than one table. + // It uses like, 3+ levels of lists. But it works, and is only run once per category in the global sense. So technically, efficient! + // :D - Skull132 + if (!query_cache.len || isnull(query_cache[type])) + query_cache[type] = list() + var/list/tables = list() + + // First, consolidate the different lists into one. + for (var/datum/category_item/player_setup_item/PI in items) + var/list/pi_tables = PI.gather_load_query() + // Expected layout: list("table A name" = list("vars" = list("column name" = "var name"), "args" = list()), + // "table B name" = list("vars" = list(), "args" = list())) + + for (var/table in pi_tables) + var/list/A = pi_tables[table] + if (isnull(tables[table])) + tables[table] = list("vars" = list(), "args" = list()) + + tables[table]["vars"] |= A["vars"] + tables[table]["args"] |= A["args"] + + // Second, create the queries and save them. + for (var/table in tables) + var/query = "SELECT " + var/list/var_names = tables[table]["vars"] + var/count = var_names.len + + // Process the variables and rows we want. + var/i = 1 + for (var/name in var_names) + query += name + + if (!isnull(var_names[name])) + var/new_name = var_names[name] + var_names.Remove(name) + var_names.Insert(i, new_name) + + if (i != count) + query += ", " + else + query += " " + + i++ + + query += "FROM [table] WHERE " + + // Process the args. + var/list/arg_names = tables[table]["args"] + count = arg_names.len + for (i = 1, i <= count, i++) + query += "[arg_names[i]] = :[arg_names[i]]" + arg_names[i] = ":[arg_names[i]]" + + if (i != count) + query += " AND " + else + query += ";" + + // Save it. + query_cache[type][query] = var_names + + // Actually utilize the query. + var/list/arg_list = gather_load_parameters() + for (var/query in query_cache[type]) + var/DBQuery/query = dbcon.NewQuery(query) + query.Execute(arg_list, 1) + + // Each query should only return exactly 1 row. + var/list/var_names = query_cache[type] + if (query.NextRow()) + for (var/i = 1, i <= var_names.len, i++) + // We can do this, because when generating, we ensured that + preferences.vars[var_names[i]] = query.item[i] + +/datum/category_group/player_setup_category/proc/gather_load_parameters() + var/list/arg_list = list() + for (var/datum/category_item/player_setup_item/PI in items) + arg_list |= PI.gather_load_parameters() + + return arg_list /datum/category_group/player_setup_category/proc/save_character(var/savefile/S) // Sanitize all data, then save it @@ -219,6 +300,18 @@ /datum/category_item/player_setup_item/proc/update_setup(var/savefile/preferences, var/savefile/character) return 0 +/* +* Called when the owner category is composing its load query +*/ +/datum/category_item/player_setup_item/proc/gather_load_query() + return list() + +/* +* Called when the owner category is composing its query parameters for loading. +*/ +/datum/category_item/player_setup_item/proc/gather_load_parameters() + return list() + /datum/category_item/player_setup_item/proc/content() return diff --git a/code/modules/client/preference_setup/skills/skills.dm b/code/modules/client/preference_setup/skills/skills.dm index 1f60cd3bb7f..7d525f315b7 100644 --- a/code/modules/client/preference_setup/skills/skills.dm +++ b/code/modules/client/preference_setup/skills/skills.dm @@ -12,6 +12,9 @@ S["used_skillpoints"] << pref.used_skillpoints S["skill_specialization"] << pref.skill_specialization +/datum/category_item/player_setup_item/skills/gather_load_query() + return list("ss13_characters" = list("vars" = list("skills", "skill_specialization"), "args" = list("id"))) + /datum/category_item/player_setup_item/skills/sanitize_character() if(SKILLS == null) setup_skills() if(!pref.skills) pref.skills = list()