From 3fbb00d5f7e683cbdd15936a8fe95957f8ddf268 Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Wed, 3 Aug 2016 18:58:41 -0700 Subject: [PATCH] Can now save and load the cyberiad --- code/__HELPERS/text.dm | 37 ++++++++++++- code/modules/awaymissions/maploader/reader.dm | 15 ++++-- code/modules/awaymissions/maploader/writer.dm | 53 +++++++++++-------- code/modules/persistence/persistence.dm | 2 +- 4 files changed, 79 insertions(+), 28 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index b17cda4e560..19ed2c06383 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -389,4 +389,39 @@ proc/checkhtml(var/t) /proc/macro2html(text) var/static/regex/text_macro = new("(\\xFF.)(.*)$") - return text_macro.Replace(text, /proc/replace_text_macro) \ No newline at end of file + return text_macro.Replace(text, /proc/replace_text_macro) + +/proc/dmm_encode(text) + // First, go through and nix out any of our escape sequences so we don't leave ourselves open to some escape sequence attack + // Some coder will probably despise me for this, years down the line + + var/list/repl_chars = list(""", "{", "}") + for(var/char in repl_chars) + var/index = findtext(text, char) + var/keylength = length(char) + while(index) + log_debug("Bad string given to dmm encoder! [text]") + text = copytext(text, 1, index) + copytext(text, index+keylength) + index = findtext(text, char) + + // Then, replace characters as normal + var/list/repl_chars_2 = list("\"" = """, "{" = "{", "}" = "}") + for(var/char in repl_chars_2) + var/index = findtext(text, char) + var/keylength = length(char) + while(index) + text = copytext(text, 1, index) + repl_chars_2[char] + copytext(text, index+keylength) + index = findtext(text, char) + return text + + +/proc/dmm_decode(text) + // Replace what we extracted above + var/list/repl_chars = list(""" = "\"", "{" = "{", "}" = "}") + for(var/char in repl_chars) + var/index = findtext(text, char) + var/keylength = length(char) + while(index) + text = copytext(text, 1, index) + repl_chars[char] + copytext(text, index+keylength) + index = findtext(text, char) + return text diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index 3dc187f388a..55125186da9 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -228,10 +228,12 @@ var/global/dmm_suite/preloader/_preloader = new var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp} var/variables_start = findtext(full_def, "{") - var/atom_def = text2path(trim_text(copytext(full_def, 1, variables_start))) //path definition, e.g /obj/foo/bar + var/atom_text = trim_text(copytext(full_def, 1, variables_start)) + var/atom_def = text2path(atom_text) //path definition, e.g /obj/foo/bar old_position = dpos + 1 if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers! + log_debug("Bad path: [atom_text]") continue members.Add(atom_def) @@ -373,7 +375,6 @@ 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 - log_debug(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 @@ -381,7 +382,6 @@ var/global/dmm_suite/preloader/_preloader = new //Check for string // Make it read to the next delimiter, instead of the quote if(findtext(trim_right,quote,1,2)) - log_debug(trim_right) var/endquote = findtext(trim_right,quote,-1) if(!endquote) log_debug("Terminating quote not found!") @@ -449,8 +449,13 @@ var/global/dmm_suite/preloader/_preloader = new /dmm_suite/preloader/proc/load(atom/what) if(json_ready) - log_debug(attributes["map_json_data"]) - what.deserialize(json_decode(attributes["map_json_data"])) + var/json_data = attributes["map_json_data"] + json_data = dmm_decode(json_data) + try + what.deserialize(json_decode(json_data)) + catch(var/exception/e) + log_debug("Bad json data: '[json_data]'") + throw e else for(var/attribute in attributes) var/value = attributes[attribute] diff --git a/code/modules/awaymissions/maploader/writer.dm b/code/modules/awaymissions/maploader/writer.dm index 1727f9d9088..a2141194119 100644 --- a/code/modules/awaymissions/maploader/writer.dm +++ b/code/modules/awaymissions/maploader/writer.dm @@ -34,15 +34,16 @@ dmm_suite{ } var/map_prefix = "_maps/quicksave/" var/map_path = "[map_prefix][map_name].dmm" - var/file_text = write_map(t1,t2,flags) if(fexists(map_path)){ fdel(map_path) } - var/saved_map = file(map_path) - saved_map << file_text + var/saved_map = file(map_path) // We give the map writer the file directly + // Because repeated string appending is super murder for performance + var/map_text = write_map(t1,t2,flags,saved_map) + saved_map << map_text return saved_map } - write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){ + write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num, var/map_file as file){ //Check for valid turfs. if(!isturf(t1) || !isturf(t2)){ CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.") @@ -51,30 +52,41 @@ dmm_suite{ var/turf/sw = locate(min(t1.x,t2.x),min(t1.y,t2.y),min(t1.z,t2.z)) // Inner corner var/list/templates[0] var/template_buffer = {""} + var/buffer_line = {""} var/dmm_text = {""} + + + // // Don't write more than 1000 maps at once ;) + // var/static/cache_index = 0 + // if(cache_index > 1000) + // cache_index = 0 + // cache_index++ + // var/cache_prefix = "data/map_cache/" + // var/cache_name = "mapcache[cache_index].txt" + // var/cache_path = "[cache_prefix][cache_name]" + // if(fexists(cache_path)) + // fdel(cache_path) + // // Here's hoping file writes are less pricey than repeated string appends + // var/template_buffer_cache = file(cache_path) + for(var/pos_z in sw.z to ne.z){ - // log_debug("z: [pos_z]") for(var/pos_y = ne.y, pos_y >= sw.y, pos_y--){ // We're reversing this because the map format is silly - // log_debug("y: [pos_y]") for(var/pos_x in sw.x to ne.x){ - // log_debug("x: [pos_x]") var/turf/test_turf = locate(pos_x,pos_y,pos_z) var/test_template = make_template(test_turf, flags) var/template_number = templates.Find(test_template) - // log_debug("Template number: [template_number]") - // log_debug("Template string: [test_template]") if(!template_number){ templates.Add(test_template) template_number = templates.len } - template_buffer += "[template_number]," + buffer_line += "[template_number]," + CHECK_TICK } - template_buffer += ";" + template_buffer += "[buffer_line];" + buffer_line = "" } template_buffer += "." } - // log_debug("[template_buffer]") - // log_debug("We are done with the loop, doing log") if(templates.len == 0) CRASH("No templates found!") var/key_length = round/*floor*/(log(letter_digits.len,templates.len-1)+1) @@ -86,7 +98,7 @@ dmm_suite{ var/z_level = 0 for(var/z_pos=1;TRUE;z_pos=findtext(template_buffer,".",z_pos)+1){ if(z_pos>=length(template_buffer)){break} - if(z_level){dmm_text+={"\n"}} + if(z_level){dmm_text += {"\n"}} dmm_text += {"\n(1,1,[++z_level]) = {"\n"} var/z_block = copytext(template_buffer,z_pos,findtext(template_buffer,".",z_pos)) for(var/y_pos=1;TRUE;y_pos=findtext(z_block,";",y_pos)+1){ @@ -97,14 +109,13 @@ dmm_suite{ var/x_block = copytext(y_block,x_pos,findtext(y_block,",",x_pos)) var/key_number = text2num(x_block) var/temp_key = keys[key_number] - dmm_text += temp_key - sleep(-1) + buffer_line += temp_key + CHECK_TICK } - dmm_text += {"\n"} - sleep(-1) + dmm_text += {"[buffer_line]\n"} + buffer_line = "" } dmm_text += {"\"}"} - sleep(-1) } return dmm_text } @@ -171,9 +182,9 @@ dmm_suite{ var/list/yeah = A.serialize() // Remove useless info yeah -= "type" - var/json_stuff = json_encode(yeah) if(yeah.len) { - log_debug(json_stuff) + var/json_stuff = json_encode(yeah) + json_stuff = dmm_encode(json_stuff) attributes_text += {"map_json_data = "[json_stuff]""} } } diff --git a/code/modules/persistence/persistence.dm b/code/modules/persistence/persistence.dm index aa2784cd071..a803d6b2eb4 100644 --- a/code/modules/persistence/persistence.dm +++ b/code/modules/persistence/persistence.dm @@ -24,7 +24,7 @@ /atom // This is so specific atoms can override these, and ignore certain ones - var/list/vars_to_save = list("dir","name","color","icon","icon_state") + var/list/vars_to_save = list("dir","name","color","icon","icon_state", "pixel_x", "pixel_y") /atom/serialize() var/list/data = ..() for(var/thing in vars_to_save)