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:")