Revert "Merge branch 'json' into Bleeding-Edge" (#14425)

This reverts commit 24f7c0a960, reversing
changes made to ff9b9664ea.
This commit is contained in:
sood
2017-03-24 22:19:34 -07:00
committed by GitHub
parent 7678fd914b
commit d0d4b09ec9
8 changed files with 378 additions and 62 deletions

View File

@@ -320,11 +320,11 @@
var/list/json[0]
for(var/datum/automation/A in automations)
json += list(A.Export())
return json_encode(json)
return list2json(json)
/obj/machinery/computer/general_air_control/atmos_automation/proc/ReadCode(var/jsonStr)
automations.len = 0
var/list/json=json_decode(jsonStr)
var/list/json=json2list(jsonStr)
if(json && json.len > 0)
for(var/list/cData in json)
if(isnull(cData) || !("type" in cData))

View File

@@ -3,11 +3,6 @@
*
* By N3X15
*******************************/
// For error handling.
#define PLAYLIST_INVALID -1 // When we don't get JSON back
#define PLAYLIST_EMPTY -2 // When our playlist came back empty
#define PLAYLIST_NULL_RESPONSE -3 // When the HTTP request returns null
#define PLAYLIST_SERVER_ERROR -4 // When the media server errors (N3X15's new code anyway)
#define JUKEMODE_SHUFFLE 1 // Default
#define JUKEMODE_REPEAT_SONG 2
@@ -20,51 +15,40 @@
#define JUKEBOX_RELOAD_COOLDOWN 600 // 60s
// Global juke playlist.
var/global/global_playlists = list()
/proc/load_juke_playlists()
if(!config.media_base_url)
return
for(var/playlist_id in list("bar", "jazz", "rock", "muzak", "emagged", "endgame", "clockwork", "vidyaone", "vidyatwo", "vidyathree", "vidyafour"))
var/playlist = get_playlist(playlist_id)
if(!istype(playlist, /list))
continue
global_playlists["[playlist_id]"] = playlist
var/url="[config.media_base_url]/index.php?playlist=[playlist_id]"
testing("Updating playlist from [url]...")
/proc/get_playlist(var/playlistid)
if(isnull(playlistid))
return
var/url="[config.media_base_url]/index.php?playlist=[playlistid]"
testing("Updating playlist from [url]...")
// Media Server 2 requires a secret key in order to tell the jukebox
// where the music files are. It's set in config with MEDIA_SECRET_KEY
// and MUST be the same as the media server's.
//
// Do NOT log this, it's like a password.
if(config.media_secret_key!="")
url += "&key=[config.media_secret_key]"
// Media Server 2 requires a secret key in order to tell the jukebox
// where the music files are. It's set in config with MEDIA_SECRET_KEY
// and MUST be the same as the media server's.
//
// Do NOT log this, it's like a password.
if(config.media_secret_key!="")
url += "&key=[config.media_secret_key]"
var/response = world.Export(url)
var/list/playlist=list()
if(response)
var/json = file2text(response["CONTENT"])
if("/>" in json)
return PLAYLIST_INVALID
var/list/songdata = json_decode(json)
if(!isnull(songdata["errors"])) // If we get back JSON that looks like {"errors:":[]}
return PLAYLIST_SERVER_ERROR
for(var/list/record in songdata)
playlist += new /datum/song_info(record)
if(playlist.len==0)
return PLAYLIST_EMPTY
return playlist
else
return PLAYLIST_NULL_RESPONSE
var/response = world.Export(url)
var/list/playlist=list()
if(response)
var/json = file2text(response["CONTENT"])
if("/>" in json)
continue
var/json_reader/reader = new()
reader.tokens = reader.ScanJson(json)
reader.i = 1
var/songdata = reader.read_value()
for(var/list/record in songdata)
playlist += new /datum/song_info(record)
if(playlist.len==0)
continue
global_playlists["[playlist_id]"] = playlist.Copy()
/obj/machinery/media/jukebox/proc/retrieve_playlist(var/playlistid = playlist_id)
if(!config.media_base_url || !playlistid)
if(!config.media_base_url)
return
playlist_id = playlistid
if(global_playlists["[playlistid]"])
@@ -72,20 +56,44 @@ var/global/global_playlists = list()
playlist = temp.Copy()
else
var/list_get = get_playlist(playlist_id)
if(istype(list_get, /list) && isnull(list_get["errors"])) // No errors
playlist = list_get
global_playlists["[playlistid]"] = playlist.Copy()
var/url="[config.media_base_url]/index.php?playlist=[playlist_id]"
testing("[src] - Updating playlist from [url]...")
// Media Server 2 requires a secret key in order to tell the jukebox
// where the music files are. It's set in config with MEDIA_SECRET_KEY
// and MUST be the same as the media server's.
//
// Do NOT log this, it's like a password.
if(config.media_secret_key!="")
url += "&key=[config.media_secret_key]"
var/response = world.Export(url)
playlist=list()
if(response)
var/json = file2text(response["CONTENT"])
if("/>" in json)
visible_message("<span class='warning'>[bicon(src)] \The [src] buzzes, unable to update its playlist.</span>","<em>You hear a buzz.</em>")
stat &= BROKEN
update_icon()
return 0
var/json_reader/reader = new()
reader.tokens = reader.ScanJson(json)
reader.i = 1
var/songdata = reader.read_value()
for(var/list/record in songdata)
playlist += new /datum/song_info(record)
if(playlist.len==0)
visible_message("<span class='warning'>[bicon(src)] \The [src] buzzes, unable to update its playlist.</span>","<em>You hear a buzz.</em>")
stat &= BROKEN
update_icon()
return 0
visible_message("<span class='notice'>[bicon(src)] \The [src] beeps, and the menu on its front fills with [playlist.len] items.</span>","<em>You hear a beep.</em>")
else // Something errored
if(PLAYLIST_NULL_RESPONSE)
testing("[src] failed to update playlist: Response null.")
visible_message("<span class='warning'>[bicon(src)] \The [src] buzzes, unable to update its playlist.</span>","<em>You hear a buzz.</em>")
// These lines would mean that the jukebox would have to be maintained every time the playlist failed to load
// But they also didn't break the juke in the first place because it should have been |= not &=
// stat &= BROKEN
//update_icon()
else
testing("[src] failed to update playlist: Response null.")
stat &= BROKEN
update_icon()
return 0
global_playlists["[playlistid]"] = playlist.Copy()
if(autoplay)
playing=1
autoplay=0

View File

@@ -0,0 +1,221 @@
json_token
var
value
New(v)
src.value = v
text
number
word
symbol
eof
json_reader
var
list
string = list("'", "\"")
symbols = list("{", "}", "\[", "]", ":", "\"", "'", ",")
sequences = list("b" = 8, "t" = 9, "n" = 10, "f" = 12, "r" = 13)
tokens
json
i = 1
proc
// scanner
ScanJson(json)
src.json = json
. = new/list()
src.i = 1
while(src.i <= length(json))
var/char = get_char()
if(is_whitespace(char))
i++
continue
if(string.Find(char))
. += read_string(char)
else if(symbols.Find(char))
. += new/json_token/symbol(char)
else if(is_digit(char))
. += read_number()
else
. += read_word()
i++
. += new/json_token/eof()
read_word()
var/val = ""
while(i <= length(json))
var/char = get_char()
if(is_whitespace(char) || symbols.Find(char))
i-- // let scanner handle this character
return new/json_token/word(val)
val += char
i++
read_string(delim)
var
escape = FALSE
val = ""
while(++i <= length(json))
var/char = get_char()
if(escape)
escape=FALSE // WHICH STUPID ASSHOLE FORGOT THIS - N3X
switch(char)
if("\\", "'", "\"", "/", "u")
val += char
else
// TODO: support octal, hex, unicode sequences
//testing("Having trouble with \"\\[char]\" in string \"[val]\"")
ASSERT(sequences.Find(char))
val += ascii2text(sequences[char])
else
if(char == delim)
return new/json_token/text(val)
else if(char == "\\")
escape = TRUE
else
val += char
CRASH("Unterminated string.")
read_number()
var/val = ""
var/char = get_char()
while(is_digit(char) || char == "." || lowertext(char) == "e")
val += char
i++
char = get_char()
i-- // allow scanner to read the first non-number character
return new/json_token/number(text2num(val))
check_char()
ASSERT(args.Find(get_char()))
get_char()
return copytext(json, i, i+1)
is_whitespace(char)
return char == " " || char == "\t" || char == "\n" || text2ascii(char) == 13
is_digit(char)
var/c = text2ascii(char)
return 48 <= c && c <= 57 || char == "+" || char == "-"
// parser
ReadArray(list/tokens)
src.tokens = tokens
i = 1
return read_array()
// parser
ReadObject(list/tokens)
src.tokens = tokens
. = new/list()
i = 1
read_token("{", /json_token/symbol)
while(i <= tokens.len)
var/json_token/K = get_token()
check_type(/json_token/word, /json_token/text)
next_token()
read_token(":", /json_token/symbol)
.[K.value] = read_value()
var/json_token/S = get_token()
check_type(/json_token/symbol)
if(!S)
die()
return
switch(S.value)
if(",")
next_token()
continue
if("}")
next_token()
return
else
die()
get_token()
return tokens[i]
next_token()
if(++i <= tokens.len)
return tokens[i]
return
read_token(val, type)
var/json_token/T = get_token()
if(!(T.value == val && istype(T, type)))
CRASH("Expected '[val]', found '[T.value]'.")
next_token()
return T
check_type(...)
var/json_token/T = get_token()
for(var/type in args)
if(istype(T, type))
return
CRASH("Bad token type: [T.type].")
check_value(...)
var/json_token/T = get_token()
ASSERT(args.Find(T.value))
read_key()
var/char = get_char()
if(char == "\"" || char == "'")
return read_string(char)
read_value()
var/json_token/T = get_token()
if(T)
switch(T.type)
if(/json_token/text, /json_token/number)
next_token()
return T.value
if(/json_token/word)
next_token()
switch(T.value)
if("true")
return TRUE
if("false")
return FALSE
if("null")
return null
if(/json_token/symbol)
switch(T.value)
if("\[")
return read_array()
if("{")
return ReadObject(tokens.Copy(i))
die()
read_array()
read_token("\[", /json_token/symbol)
. = new/list()
var/list/L = .
while(i <= tokens.len)
// Avoid using Add() or += in case a list is returned.
L.len++
L[L.len] = read_value()
var/json_token/T = get_token()
check_type(/json_token/symbol)
switch(T.value)
if(",")
next_token()
continue
if("]")
next_token()
return
else
die()
next_token()
CRASH("Unterminated array.")
die(json_token/T)
if(!T)
T = get_token()
CRASH("Unexpected token: [T.value] [json] index:[i] .")

View File

@@ -0,0 +1,63 @@
json_writer
proc
WriteObject(list/L)
. = list()
. += "{"
var/i = 1
for(var/k in L)
var/val = L[k]
. += {"\"[k]\":[write(val)]"}
if(i++ < L.len)
. += ","
.+= "}"
. = jointext(.,"")
write(val)
if(isnum(val))
return num2text(val, 100)
else if(isnull(val))
return "null"
else if(istype(val, /list))
if(is_associative(val))
return WriteObject(val)
else
return write_array(val)
else
. += write_string("[val]")
write_array(list/L)
. = list()
. += "\["
for(var/i = 1 to L.len)
. += write(L[i])
if(i < L.len)
. += ","
. += "]"
. = jointext(., "")
write_string(txt)
var/static/list/json_escape = list("\\", "\"", "'", "\n")
for(var/targ in json_escape)
var/start = 1
while(start <= length(txt))
var/i = findtext(txt, targ, start)
if(!i)
break
if(targ == "\n")
txt = copytext(txt, 1, i) + "\\n" + copytext(txt, i+2)
start = i + 1 // 1 character added
if(targ == "'")
txt = copytext(txt, 1, i) + "`" + copytext(txt, i+1) // apostrophes fuck shit up...
start = i + 1 // 1 character added
else
txt = copytext(txt, 1, i) + "\\" + copytext(txt, i)
start = i + 2 // 2 characters added
return {""[txt]""}
is_associative(list/L)
for(var/key in L)
// if the key is a list that means it's actually an array of lists (stupid Byond...)
if(!isnum(key) && !istype(key, /list))
return TRUE

View File

@@ -0,0 +1,21 @@
/*
n_Json v11.3.21
*/
proc
json2list(json)
var/static/json_reader/_jsonr = new()
// N3X: Array support.
if(dd_hasprefix(json,"\["))
return _jsonr.ReadArray(_jsonr.ScanJson(json))
else
return _jsonr.ReadObject(_jsonr.ScanJson(json))
list2json(list/L)
var/static/json_writer/_jsonw = new()
// Detect if it's just a list of things, or an associative list
// (Used to just assume associative, which broke things.)
if(_jsonw.is_associative(L))
return _jsonw.WriteObject(L)
else
return _jsonw.write_array(L)

View File

@@ -396,12 +396,12 @@ nanoui is used to open and update nano browser uis
var/template_data_json = "{}" // An empty JSON object
if (templates.len > 0)
template_data_json = json_encode(templates)
template_data_json = list2json(templates)
var/list/send_data = get_send_data(initial_data)
var/initial_data_json = json_encode(send_data)
var/initial_data_json = list2json(send_data)
var/url_parameters_json = json_encode(list("src" = "\ref[src]"))
var/url_parameters_json = list2json(list("src" = "\ref[src]"))
return {"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
@@ -489,9 +489,9 @@ nanoui is used to open and update nano browser uis
var/list/send_data = get_send_data(data)
// to_chat(user, json_encode(data))// used for debugging
// to_chat(user, list2json(data))// used for debugging
user << output(list2params(list(json_encode(send_data))),"[window_id].browser:receiveUpdateData")
user << output(list2params(list(list2json(send_data))),"[window_id].browser:receiveUpdateData")
/**
* This Topic() proc is called whenever a user clicks on a link within a Nano UI

View File

@@ -150,7 +150,7 @@ For the main html chat area
deets["clientData"]["ckey"] = owner.ckey
deets["clientData"]["ip"] = owner.address
deets["clientData"]["compid"] = owner.computer_id
var/data = json_encode(deets)
var/data = list2json(deets)
ehjax_send(data = data)
//Called by client, sent data to investigate (cookie history so far)
@@ -159,7 +159,7 @@ For the main html chat area
return
if(cookie != "none")
var/list/connData = json_decode(cookie)
var/list/connData = json2list(cookie)
if (connData && islist(connData) && connData.len > 0 && connData["connData"])
src.connectionHistory = connData["connData"] //lol fuck
var/list/found = new()

View File

@@ -1636,6 +1636,9 @@
#include "code\modules\mob\new_player\poll.dm"
#include "code\modules\mob\new_player\preferences_setup.dm"
#include "code\modules\mob\new_player\sprite_accessories.dm"
#include "code\modules\nano\_JSON.dm"
#include "code\modules\nano\JSON Reader.dm"
#include "code\modules\nano\JSON Writer.dm"
#include "code\modules\nano\nanoexternal.dm"
#include "code\modules\nano\nanomanager.dm"
#include "code\modules\nano\nanoui.dm"