From 192b24b9bd79f0c8d574bce1383065f085b20936 Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 13 Feb 2021 10:36:26 +0000 Subject: [PATCH] Improve JsonKeyReader This commit makes the following changes: - Uses XteaKeyDeserializer instead of reading the key array manually. - Adds support for an object of map squares to keys, which is the format used by the OpenOSRS XTEA endpoint. - Throws exceptions if the input is malformed, rather than silently ignoring problems. Signed-off-by: Graham --- .../org/openrs2/archive/key/JsonKeyReader.kt | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/archive/src/main/kotlin/org/openrs2/archive/key/JsonKeyReader.kt b/archive/src/main/kotlin/org/openrs2/archive/key/JsonKeyReader.kt index f9d1072d..ffa8de3d 100644 --- a/archive/src/main/kotlin/org/openrs2/archive/key/JsonKeyReader.kt +++ b/archive/src/main/kotlin/org/openrs2/archive/key/JsonKeyReader.kt @@ -1,8 +1,10 @@ package org.openrs2.archive.key import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.treeToValue import org.openrs2.crypto.XteaKey import org.openrs2.json.Json +import java.io.IOException import java.io.InputStream import javax.inject.Inject import javax.inject.Singleton @@ -12,21 +14,24 @@ public class JsonKeyReader @Inject constructor( @Json private val mapper: ObjectMapper ) : KeyReader { override fun read(input: InputStream): Sequence { - return sequence { - for (mapSquare in mapper.readTree(input)) { - val key = mapSquare["key"] ?: mapSquare["keys"] ?: continue + val keys = mutableListOf() + val root = mapper.readTree(input) - if (key.size() != 4) { - continue + when { + root.isArray -> { + for (entry in root) { + val key = entry["key"] ?: entry["keys"] ?: throw IOException("Missing 'key' or 'keys' field") + keys += mapper.treeToValue(key) ?: throw IOException("Key must be non-null") } - - val k0 = key[0].asText().toIntOrNull() ?: continue - val k1 = key[1].asText().toIntOrNull() ?: continue - val k2 = key[2].asText().toIntOrNull() ?: continue - val k3 = key[3].asText().toIntOrNull() ?: continue - - yield(XteaKey(k0, k1, k2, k3)) } + root.isObject -> { + for (entry in root.fields()) { + keys += mapper.treeToValue(entry.value) ?: throw IOException("Key must be non-null") + } + } + else -> throw IOException("Root element must be an array or object") } + + return keys.asSequence() } }