diff --git a/code/modules/modular_computers/file_system/reports/crew_record.dm b/code/modules/modular_computers/file_system/reports/crew_record.dm index 83063cf559c..c60e799c7f8 100644 --- a/code/modules/modular_computers/file_system/reports/crew_record.dm +++ b/code/modules/modular_computers/file_system/reports/crew_record.dm @@ -199,8 +199,9 @@ var/global/arrest_security_status = "Arrest" //Should only be used for OOC stuff, for player-facing stuff you must go through the network. /proc/get_crewmember_record(var/name) + var/sanitized_name = sanitize(name) for(var/datum/computer_file/report/crew_record/CR in global.all_crew_records) - if(CR.get_name() == name) + if(CR.get_name() == sanitized_name) return CR return null diff --git a/mods/persistence/controllers/subsystems/persistence.dm b/mods/persistence/controllers/subsystems/persistence.dm index 928b1140cbf..5c5ab153e68 100644 --- a/mods/persistence/controllers/subsystems/persistence.dm +++ b/mods/persistence/controllers/subsystems/persistence.dm @@ -597,7 +597,7 @@ . = one_off.AddToLimbo(things, key, limbo_type, metadata, metadata2, modify) if(.) // Clear it from the queued removals. for(var/list/queued in limbo_removals) - if(queued[1] == key && queued[2] == limbo_type) + if(queued[1] == sanitize_sql(key) && queued[2] == limbo_type) limbo_removals -= list(queued) if(new_db_connection) close_save_db_connection() @@ -619,7 +619,7 @@ new_db_connection = TRUE . = one_off.DeserializeOneOff(limbo_key, limbo_type, remove_after) if(remove_after) - limbo_removals += list(list(limbo_key, limbo_type)) + limbo_removals += list(list(sanitize_sql(limbo_key), limbo_type)) if(new_db_connection) close_save_db_connection() diff --git a/mods/persistence/modules/chargen/launch_pod.dm b/mods/persistence/modules/chargen/launch_pod.dm index f3df4ddd7e6..37de28d6178 100644 --- a/mods/persistence/modules/chargen/launch_pod.dm +++ b/mods/persistence/modules/chargen/launch_pod.dm @@ -77,7 +77,7 @@ // Add the mob to limbo for safety. Mark for removal on the next save. SSpersistence.AddToLimbo(list(user, user.mind), user.mind.unique_id, LIMBO_MIND, user.mind.key, user.mind.current.real_name, TRUE) - SSpersistence.limbo_removals += list(list(user.mind.unique_id, LIMBO_MIND)) + SSpersistence.limbo_removals += list(list(sanitize_sql(user.mind.unique_id), LIMBO_MIND)) for(var/turf/T in global.latejoin_cryo_locations) var/obj/machinery/cryopod/C = locate() in T diff --git a/mods/persistence/modules/client/preferences.dm b/mods/persistence/modules/client/preferences.dm index 34efab65224..bfc9d26c526 100644 --- a/mods/persistence/modules/client/preferences.dm +++ b/mods/persistence/modules/client/preferences.dm @@ -72,7 +72,7 @@ to_chat(usr, "[real_name] is already a name in use! Please select a different name.") real_name = null return - var/DBQuery/char_query = dbcon.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata2` = '[real_name]'") + var/DBQuery/char_query = dbcon.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata2` = '[sanitize_sql(real_name)]'") if(!char_query.Execute()) to_world_log("DUPLICATE NAME CHECK DESERIALIZATION FAILED: [char_query.ErrorMsg()].") if(char_query.NextRow()) @@ -83,7 +83,7 @@ if(check_rights(R_DEBUG) || check_rights(R_ADMIN)) slots+=2 var/count = 0 - char_query = dbcon.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[client.key]'") + char_query = dbcon.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[sanitize_sql(client.key)]'") if(!char_query.Execute()) to_world_log("CHARACTER DESERIALIZATION FAILED: [char_query.ErrorMsg()].") for(var/i=1,i>=slots,i++) @@ -97,12 +97,12 @@ save_preferences() save_character() - + if(isnewplayer(client.mob)) close_char_dialog(usr) var/mob/new_player/M = client.mob M.AttemptLateSpawn(SSjobs.get_by_path(global.using_map.default_job_type)) - + if(href_list["save"]) save_preferences() diff --git a/mods/persistence/modules/mob/new_player.dm b/mods/persistence/modules/mob/new_player.dm index bf5c9c331b3..542d0e8c15d 100644 --- a/mods/persistence/modules/mob/new_player.dm +++ b/mods/persistence/modules/mob/new_player.dm @@ -14,7 +14,12 @@ virtual_mob = null // Hear no evil, speak no evil var/datum/browser/charselect - var/selected_char_name + + var/list/characters + +/mob/new_player/Destroy() + characters?.Cut() + . = ..() /mob/new_player/show_lobby_menu(force = FALSE) if(!SScharacter_setup.initialized && !force) @@ -35,7 +40,7 @@ output += "
" output += "
" - if(check_rights(R_DEBUG, 0, client)) + if(check_rights(R_DEBUG, FALSE, client)) output += "Observe" output += "Refresh" output += "
" @@ -61,7 +66,7 @@ if(href_list["setupCharacter"]) newCharacterPanel() return 0 - + if(href_list["deleteCharacter"]) characterSelect(CHARSELECTDELETE) return 0 @@ -88,26 +93,32 @@ show_lobby_menu() if(href_list["Load"]) - selected_char_name = href_list["Load"] + var/char_index = text2num(href_list["Load"]) + if(!char_index || char_index > length(characters)) + return if(charselect) charselect.close() charselect = null - joinGame() + joinGame(characters[char_index]) if(href_list["Delete"]) - var/char_name = href_list["Delete"] + var/char_index = text2num(href_list["Delete"]) + if(!char_index || char_index > length(characters)) + return if(charselect) charselect.close() charselect = null + + var/char_name = characters[char_index] if(input("Are you SURE you want to delete [char_name]? THIS IS PERMANENT. Enter the character\'s full name to confirm.", "DELETE A CHARACTER", "") == char_name) - + var/new_db_connection = FALSE if(!check_save_db_connection()) if(!establish_save_db_connection()) CRASH("new_player: Couldn't establish DB connection while deleting a character!") new_db_connection = TRUE - - var/DBQuery/char_query = dbcon_save.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[key]' AND `metadata2` = '[char_name]'") + + var/DBQuery/char_query = dbcon_save.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[sanitize_sql(key)]' AND `metadata2` = '[sanitize_sql(char_name)]'") if(!char_query.Execute()) to_world_log("CHARACTER DESERIALIZATION FAILED: [char_query.ErrorMsg()].") if(char_query.NextRow()) @@ -117,7 +128,7 @@ to_chat(src, SPAN_NOTICE("Character Delete Completed.")) else to_chat(src, SPAN_NOTICE("Delete Failed! Contact a developer.")) - + if(new_db_connection) close_save_db_connection() @@ -126,15 +137,15 @@ if(M.loc && !istype(M, /mob/new_player) && (M.saved_ckey == ckey || M.saved_ckey == "@[ckey]")) to_chat(src, SPAN_NOTICE("You already have a character in game!")) return - - if(!check_rights(R_DEBUG)) + + if(!check_rights(R_DEBUG, FALSE, src)) client.prefs.real_name = null // This will force players to set a new character name every time they open character creator // Meaning they cant just click finalize as soon as they open the character creator. They are forced to engage. client.prefs.open_setup_window(src) return /mob/new_player/proc/characterSelect(var/func = CHARSELECTLOAD) - if(!config.enter_allowed && !check_rights(R_ADMIN)) + if(!config.enter_allowed && !check_rights(R_ADMIN, FALSE, src)) to_chat(src, SPAN_WARNING("There is an administrative lock on entering the game!")) return if(func == CHARSELECTLOAD) @@ -149,11 +160,14 @@ target_mind.current.on_persistent_join() qdel(src) return + + characters = list() + var/func_text = "Load" if(func == CHARSELECTDELETE) func_text = "Delete" var/slots = 2 - if(check_rights(R_DEBUG) || check_rights(R_ADMIN)) + if(check_rights(R_DEBUG, FALSE, src) || check_rights(R_ADMIN, FALSE, src)) slots+=2 var/output = list() output += "
" @@ -165,8 +179,7 @@ CRASH("new_player: Couldn't establish DB connection while selecting a character!") new_db_connection = TRUE - - var/DBQuery/char_query = dbcon_save.NewQuery("SELECT `metadata2` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[key]'") + var/DBQuery/char_query = dbcon_save.NewQuery("SELECT `metadata2` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[sanitize_sql(key)]'") if(!char_query.Execute()) to_world_log("CHARACTER DESERIALIZATION FAILED: [char_query.ErrorMsg()].") for(var/i=1, i<=slots, i++) @@ -174,7 +187,8 @@ var/list/char_items = char_query.GetRowData() var/char_name = char_items["metadata2"] if(char_name) - output += "[char_name]
" + characters += char_name + output += "[char_name]
" else output += "*Open Slot*
" output += "
" @@ -185,19 +199,17 @@ if(new_db_connection) close_save_db_connection() -/mob/new_player/proc/joinGame() +/mob/new_player/proc/joinGame(selected_char_name) if(GAME_STATE < RUNLEVEL_GAME) to_chat(src, SPAN_NOTICE("Wait until the round starts to join.")) return - if(!config.enter_allowed && !check_rights(R_ADMIN)) + if(!config.enter_allowed && !check_rights(R_ADMIN, FALSE, src)) to_chat(src, SPAN_WARNING("There is an administrative lock on entering the game!")) return if(spawning) to_chat(src, SPAN_NOTICE("Already set to spawning.")) return - if(!selected_char_name) - to_chat(src, SPAN_NOTICE("No Selected char name!")) - return + for(var/datum/mind/target_mind in global.player_minds) // A mob with a matching saved_ckey is already in the game, put the player back where they were. if(cmptext(target_mind.key, key)) if(!target_mind.current || istype(target_mind.current, /mob/new_player) || QDELETED(target_mind.current)) @@ -217,7 +229,7 @@ new_db_connection = TRUE spawning = TRUE - var/DBQuery/char_query = dbcon_save.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[key]' AND `metadata2` = '[selected_char_name]'") + var/DBQuery/char_query = dbcon_save.NewQuery("SELECT `key` FROM `limbo` WHERE `type` = '[LIMBO_MIND]' AND `metadata` = '[sanitize_sql(key)]' AND `metadata2` = '[sanitize_sql(selected_char_name)]'") if(!char_query.Execute()) to_world_log("CHARACTER DESERIALIZATION FAILED: [char_query.ErrorMsg()].") if(char_query.NextRow()) @@ -244,7 +256,7 @@ person.key = key person.on_persistent_join() qdel(src) - + if(new_db_connection) close_save_db_connection() return diff --git a/mods/persistence/modules/world_save/serializers/one_off_serializer.dm b/mods/persistence/modules/world_save/serializers/one_off_serializer.dm index 9002b37d187..bd1857d6876 100644 --- a/mods/persistence/modules/world_save/serializers/one_off_serializer.dm +++ b/mods/persistence/modules/world_save/serializers/one_off_serializer.dm @@ -179,7 +179,7 @@ var/encoded_p_ids = json_encode(thing_p_ids) // Insert into the limbo table, a metadata holder that allows for access to the limbo_assoc key by 'type' and 'key'. var/DBQuery/insert_query - insert_query = dbcon_save.NewQuery("INSERT INTO `[SQLS_TABLE_LIMBO]` (`key`,`type`,`p_ids`,`metadata`,`limbo_assoc`, `metadata2`) VALUES('[key]', '[limbo_type]', '[encoded_p_ids]', '[metadata]', '[limbo_assoc]', '[metadata2]')") + insert_query = dbcon_save.NewQuery("INSERT INTO `[SQLS_TABLE_LIMBO]` (`key`,`type`,`p_ids`,`metadata`,`limbo_assoc`,`metadata2`) VALUES('[key]', '[limbo_type]', '[encoded_p_ids]', '[metadata]', '[limbo_assoc]', '[metadata2]')") try SQLS_EXECUTE_AND_REPORT_ERROR(insert_query, "LIMBO ADDITION FAILED:") @@ -207,6 +207,9 @@ // Removes an object from the limbo table. This should always be called after an object is deserialized from limbo into the world. /serializer/sql/one_off/proc/RemoveFromLimbo(var/limbo_key, var/limbo_type) + + limbo_key = sanitize_sql(limbo_key) + var/DBQuery/limbo_query = dbcon_save.NewQuery("SELECT `limbo_assoc` FROM `[SQLS_TABLE_LIMBO]` WHERE `key` = '[limbo_key]' AND `type` = '[limbo_type]';") var/limbo_assoc SQLS_EXECUTE_AND_REPORT_ERROR(limbo_query, "LIMBO QUERY FAILED DURING LIMBO REMOVAL:")