From b5ecf8a7f4a4c9210ed7adc150b8a1348484deeb Mon Sep 17 00:00:00 2001 From: Nicolas F Date: Sat, 7 Mar 2015 18:16:32 +0100 Subject: [PATCH 1/2] [genPOI] Work around JSON signs lol Mojang --- overviewer_core/aux_files/genPOI.py | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/overviewer_core/aux_files/genPOI.py b/overviewer_core/aux_files/genPOI.py index 0d0851b..77783b1 100755 --- a/overviewer_core/aux_files/genPOI.py +++ b/overviewer_core/aux_files/genPOI.py @@ -24,6 +24,7 @@ import urllib2 import multiprocessing import itertools import gzip +import json from collections import defaultdict from multiprocessing import Pool @@ -44,6 +45,35 @@ def replaceBads(s): x = x.replace(bad,"_") return x +# If you want to keep your stomach contents do not, under any circumstance, +# read the body of the following function. You have been warned. +def jsonText(s): + if (s.startswith('"') and s.endswith('"')) or \ + (s.startswith('{') and s.endswith('}')): + try: + js = json.loads(s) + except ValueError: + return s + + def parseLevel(foo): + bar = "" + if isinstance(foo, list): + for extra in foo: + bar += parseLevel(extra) + return bar + if isinstance(foo, dict): + if "text" in foo: + bar += foo["text"] + if "extra" in foo: + bar += parseLevel(foo["extra"]) + return bar + elif isinstance(foo, basestring): + return foo + + return parseLevel(js) + + else: + return s # yes there's a double parenthesis here # see below for when this is called, and why we do this @@ -59,6 +89,8 @@ def parseBucketChunks((bucket, rset, filters)): try: data = rset.get_chunk(b[0],b[1]) for poi in itertools.chain(data['TileEntities'], data['Entities']): + if poi['id'] == 'Sign': + poi = signWrangler(poi) for name, filter_function in filters: result = filter_function(poi) if result: @@ -76,6 +108,14 @@ def parseBucketChunks((bucket, rset, filters)): return markers +def signWrangler(poi): + """ + Just does the JSON things for signs + """ + for field in ["Text1", "Text2", "Text3", "Text4"]: + poi[field] = jsonText(poi[field]) + return poi + def handleEntities(rset, config, filters, markers): """ @@ -97,6 +137,8 @@ def handleEntities(rset, config, filters, markers): try: data = rset.get_chunk(x, z) for poi in itertools.chain(data['TileEntities'], data['Entities']): + if poi['id'] == 'Sign': # kill me + poi = signWrangler(poi) for name, __, filter_function, __, __, __ in filters: result = filter_function(poi) if result: From b35f8488557f817b312806bf7c07c37e746c12c4 Mon Sep 17 00:00:00 2001 From: Nicolas F Date: Sun, 8 Mar 2015 17:03:43 +0100 Subject: [PATCH 2/2] [genPOI] Work around utter plebbery --- overviewer_core/aux_files/genPOI.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/overviewer_core/aux_files/genPOI.py b/overviewer_core/aux_files/genPOI.py index 77783b1..4f1297f 100755 --- a/overviewer_core/aux_files/genPOI.py +++ b/overviewer_core/aux_files/genPOI.py @@ -47,7 +47,19 @@ def replaceBads(s): # If you want to keep your stomach contents do not, under any circumstance, # read the body of the following function. You have been warned. +# All of this could be replaced by a simple json.loads if Mojang had +# introduced a TAG_JSON, but they didn't. +# +# So here are a few curiosities how 1.7 signs get seen in 1.8 in Minecraft: +# - null -> +# - "null" -> null +# - ["Hello"] -> Hello +# - [Hello] -> Hello +# - [1,2,3] -> 123 +# Mojang just broke signs for everyone who ever used [, { and ". GG. def jsonText(s): + if s is None or s == "null": + return "" if (s.startswith('"') and s.endswith('"')) or \ (s.startswith('{') and s.endswith('}')): try: @@ -60,15 +72,14 @@ def jsonText(s): if isinstance(foo, list): for extra in foo: bar += parseLevel(extra) - return bar - if isinstance(foo, dict): + elif isinstance(foo, dict): if "text" in foo: bar += foo["text"] if "extra" in foo: bar += parseLevel(foo["extra"]) - return bar elif isinstance(foo, basestring): - return foo + bar = foo + return bar return parseLevel(js)