From 9d081750780a295f44077d842cb67142f04c73fc Mon Sep 17 00:00:00 2001 From: Leshana Date: Fri, 12 Jan 2018 19:45:34 -0500 Subject: [PATCH] Fixes #4522 - Make maploader correctly read lists of numbers, paths, etc. * For non-assoc lists every value was being read as a string. For vars like "access_req" this is bad - it doesn't work. Therefore we add support for lists of numbers. * While I'm here, might as well add support for non-string keys of associative lists too, since that's required by things like vending machines. --- code/modules/maps/tg/reader.dm | 70 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/code/modules/maps/tg/reader.dm b/code/modules/maps/tg/reader.dm index e74977d0e5..484865ab81 100644 --- a/code/modules/maps/tg/reader.dm +++ b/code/modules/maps/tg/reader.dm @@ -239,7 +239,7 @@ var/global/use_preloader = FALSE if(variables_start)//if there's any variable full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}' - fields = readlist(full_def, ";") + fields = readlist(full_def, ";", TRUE) if(fields.len) if(!trim(fields[fields.len])) --fields.len @@ -377,8 +377,12 @@ var/global/use_preloader = FALSE //build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7)) +// text - variables in text form. Not including surrounding {} or list() +// delimiter - Delimiter between list entries +// keys_only_string - If true, text that looks like an associative list has its keys treated as var names, +// otherwise they are parsed as valid associative list keys. //return the filled list -/dmm_suite/proc/readlist(text as text, delimiter=",") +/dmm_suite/proc/readlist(text as text, delimiter=",", keys_only_string = FALSE) var/list/to_return = list() @@ -392,40 +396,46 @@ var/global/use_preloader = FALSE //check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo",var2=7)) var/equal_position = findtext(text,"=",old_position, position) - 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 + // part to the left of = (the key/var name), or the entire value. If treating it as a var name, strip quotes at the same time. + var/trim_left = trim_text(copytext(text,old_position,(equal_position ? equal_position : position)), keys_only_string) old_position = position + 1 + var/trim_right = trim_left 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_right = trim_text(copytext(text,equal_position+1,position))//the content of the variable + if(!keys_only_string) // We also need to evaluate the key for the types it is permitted to be + if(findtext(trim_left,"\"",1,2)) //Check for string + trim_left = copytext(trim_left,2,findtext(trim_left,"\"",3,0)) + else if(isnum(text2num(trim_left))) //Check for number + trim_left = text2num(trim_left) + else if(ispath(text2path(trim_left))) //Check for path + trim_left = text2path(trim_left) - //Check for string - if(findtext(trim_right,"\"",1,2)) - trim_right = copytext(trim_right,2,findtext(trim_right,"\"",3,0)) - - //Check for number - else if(isnum(text2num(trim_right))) - trim_right = text2num(trim_right) - - //Check for null - else if(trim_right == "null") - trim_right = null - - //Check for list - else if(copytext(trim_right,1,5) == "list") - trim_right = readlist(copytext(trim_right,6,length(trim_right))) - - //Check for file - else if(copytext(trim_right,1,2) == "'") - trim_right = file(copytext(trim_right,2,length(trim_right))) - - //Check for path - else if(ispath(text2path(trim_right))) - trim_right = text2path(trim_right) + // Parse the value in trim_right + //Check for string + if(findtext(trim_right,"\"",1,2)) + trim_right = copytext(trim_right,2,findtext(trim_right,"\"",3,0)) + //Check for number + else if(isnum(text2num(trim_right))) + trim_right = text2num(trim_right) + //Check for null + else if(trim_right == "null") + trim_right = null + //Check for list + else if(copytext(trim_right,1,5) == "list") + trim_right = readlist(copytext(trim_right,6,length(trim_right))) + //Check for file + else if(copytext(trim_right,1,2) == "'") + trim_right = file(copytext(trim_right,2,length(trim_right))) + //Check for path + else if(ispath(text2path(trim_right))) + trim_right = text2path(trim_right) + // Now put the trim_right into the result. Method by which we do so varies on if its assoc or not + if(equal_position) to_return[trim_left] = trim_right - - else//simple var - to_return[trim_left] = null + else + to_return += trim_right while(position != 0)