From 14c11b6d4c77aa61d4df94a0c7ce5654c7cc20bc Mon Sep 17 00:00:00 2001 From: Erki Date: Mon, 29 Jan 2018 23:11:11 +0200 Subject: [PATCH] Fixes #4164 in a really scary way (#4191) Map loading was to blame. Basically. All vending machines which had custom instances defined in maps would have the associative list keys (code expects paths) loaded as strings. This traced back to DMMS casting all associate list keys into strings. The fix is to make list keys also run through the type inferring system, same as with values. The inferring system was updated with two special cases: Keys cannot be numbers, this will otherwise break things. If no valid type is given, instead of returning null, the original string is returned. This will ensure that nothing that's been fine thus far breaks. --- code/modules/maps/reader.dm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/code/modules/maps/reader.dm b/code/modules/maps/reader.dm index 3840b5745c3..ad1b9b55c2a 100644 --- a/code/modules/maps/reader.dm +++ b/code/modules/maps/reader.dm @@ -376,13 +376,15 @@ var/global/dmm_suite/preloader/_preloader = new return next_delimiter -/dmm_suite/proc/readlistitem(text as text) +/dmm_suite/proc/readlistitem(text as text, is_key = FALSE) //Check for string if(findtext(text,"\"",1,2)) . = copytext(text,2,findtext(text,"\"",3,0)) //Check for number - else if(isnum(text2num(text))) + // Keys cannot safely be numbers. This implementation will return null if + // an assoc key is a number. + else if(!is_key && isnum(text2num(text))) . = text2num(text) //Check for null @@ -390,7 +392,7 @@ var/global/dmm_suite/preloader/_preloader = new . = null //Check for list - else if(copytext(text,1,5) == "list") + else if(copytext(text,1,6) == "list(") . = readlist(copytext(text,6,length(text))) //Check for file @@ -401,6 +403,11 @@ var/global/dmm_suite/preloader/_preloader = new else if(ispath(text2path(text))) . = text2path(text) + // Associative keys are fed in without quotation marks. + // So if none of the other cases apply, return simply the string that was given. + else if(is_key) + . = text + //build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7)) //return the filled list /dmm_suite/proc/readlist(text as text, delimiter=",") @@ -420,8 +427,9 @@ var/global/dmm_suite/preloader/_preloader = new var/trim_left = trim_text(copytext(text,old_position,(equal_position ? equal_position : position)),1)//the name of the variable, must trim quotes to build a BYOND compliant associatives list old_position = position + 1 - if(equal_position)//associative var, so do the association + if(equal_position) //associative var, so do the association var/trim_right = trim_text(copytext(text,equal_position+1,position))//the content of the variable + trim_left = readlistitem(trim_left, TRUE) // Assoc vars can be anything that isn't a num! to_return[trim_left] = readlistitem(trim_right) list_index++ else if (length(trim_left)) //simple var