Skip to content

Commit

Permalink
refactor: shared empty JSON object and array (#5620)
Browse files Browse the repository at this point in the history
  • Loading branch information
MukjepScarlet authored Feb 14, 2025
1 parent 8ae833f commit 9292e62
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,46 +46,78 @@ inline fun <reified T> decode(reader: Reader): T = reader.use {
publicGson.fromJson(reader, object : TypeToken<T>() {}.type)
}

// Never add elements to it!
private val EMPTY_JSON_ARRAY = JsonArray(0)
private val EMPTY_JSON_OBJECT = JsonObject()

internal fun emptyJsonArray(): JsonArray = EMPTY_JSON_ARRAY
internal fun emptyJsonObject(): JsonObject = EMPTY_JSON_OBJECT

fun String.toJsonPrimitive(): JsonPrimitive = JsonPrimitive(this)
fun Char.toJsonPrimitive(): JsonPrimitive = JsonPrimitive(this)
fun Number.toJsonPrimitive(): JsonPrimitive = JsonPrimitive(this)
fun Boolean.toJsonPrimitive(): JsonPrimitive = JsonPrimitive(this)

fun jsonArrayOf(vararg values: JsonElement?): JsonArray = JsonArray(values.size).apply {
values.forEach(::add)
fun jsonArrayOf(vararg elements: JsonElement) = JsonArray(elements.size).apply {
elements.forEach { add(it) }
}

@JvmName("jsonArrayOfAny")
fun jsonArrayOf(vararg values: Any?): JsonArray = JsonArray(values.size).apply {
values.forEach {
when (it) {
null -> add(JsonNull.INSTANCE)
is JsonElement -> add(it)
is Boolean -> add(it)
is Number -> add(it)
is String -> add(it)
is Char -> add(it)
else -> throw IllegalArgumentException("Unsupported type: " + it.javaClass)
}
class JsonArrayBuilder(initialCapacity: Int) {
private val backend = JsonArray(initialCapacity)

operator fun JsonElement.unaryPlus() {
backend.add(this)
}
}

fun jsonObjectOf(vararg entries: Pair<String, JsonElement?>): JsonObject = JsonObject().apply {
entries.forEach { add(it.first, it.second) }
fun build() = backend
}

@JvmName("jsonObjectOfAny")
fun jsonObjectOf(vararg entries: Pair<String, Any?>): JsonObject = JsonObject().apply {
entries.forEach {
val (key, value) = it
inline fun jsonArray(
initialCapacity: Int = 10,
builderAction: JsonArrayBuilder.() -> Unit
) = JsonArrayBuilder(initialCapacity).apply(builderAction).build()

class JsonObjectBuilder {
private val backend = JsonObject()

infix fun String.to(value: JsonElement) {
backend.add(this, value)
}

infix fun String.to(value: Char) {
backend.addProperty(this, value)
}

infix fun String.to(value: Number) {
backend.addProperty(this, value)
}

infix fun String.to(value: String) {
backend.addProperty(this, value)
}

infix fun String.to(value: Boolean) {
backend.addProperty(this, value)
}

/**
* Fallback
*/
infix fun String.to(value: Any?) {
when (value) {
null -> add(key, JsonNull.INSTANCE)
is JsonElement -> add(key, value)
is Boolean -> add(key, JsonPrimitive(value))
is Number -> add(key, JsonPrimitive(value))
is String -> add(key, JsonPrimitive(value))
is Char -> add(key, JsonPrimitive(value))
else -> throw IllegalArgumentException("Unsupported type: " + it.javaClass)
null -> backend.add(this, JsonNull.INSTANCE)
is String -> backend.addProperty(this, value)
is Number -> backend.addProperty(this, value)
is Boolean -> backend.addProperty(this, value)
is JsonElement -> backend.add(this, value)
is JsonObjectBuilder -> backend.add(this, value.build())
else -> throw IllegalArgumentException("Unsupported type: ${value::class.java}")
}
}

fun build() = backend
}

inline fun json(
builderAction: JsonObjectBuilder.() -> Unit
) = JsonObjectBuilder().apply(builderAction).build()
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package net.ccbluex.liquidbounce.features.chat.packet

import com.google.gson.*
import net.ccbluex.liquidbounce.config.gson.publicGson
import net.ccbluex.liquidbounce.config.gson.util.emptyJsonObject
import java.lang.reflect.Type

/**
Expand Down Expand Up @@ -110,7 +111,7 @@ class PacketDeserializer : JsonDeserializer<Packet> {

if (!packetRegistry.containsKey(packetName)) return null

if (!packetObject.has("c")) packetObject.add("c", JsonObject())
if (!packetObject.has("c")) packetObject.add("c", emptyJsonObject())

return publicGson.fromJson(packetObject.get("c"), packetRegistry[packetName])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import net.ccbluex.liquidbounce.LiquidBounce.clientCommit
import net.ccbluex.liquidbounce.LiquidBounce.clientVersion
import net.ccbluex.liquidbounce.api.core.AsyncLazy
import net.ccbluex.liquidbounce.api.services.cdn.ClientCdn
import net.ccbluex.liquidbounce.config.gson.util.json
import net.ccbluex.liquidbounce.config.gson.util.jsonArrayOf
import net.ccbluex.liquidbounce.config.gson.util.jsonObjectOf
import net.ccbluex.liquidbounce.event.events.NotificationEvent
import net.ccbluex.liquidbounce.event.events.ServerConnectEvent
import net.ccbluex.liquidbounce.event.handler
Expand Down Expand Up @@ -169,15 +169,15 @@ object ModuleRichPresence : ClientModule("RichPresence", Category.CLIENT, state
setState(formatText(stateText))

setButtons(jsonArrayOf(
jsonObjectOf(
"label" to "Download",
"url" to "https://liquidbounce.net/",
),

jsonObjectOf(
"label" to "GitHub",
"url" to "https://github.com/CCBlueX/LiquidBounce",
),
json {
"label" to "Download"
"url" to "https://liquidbounce.net/"
},

json {
"label" to "GitHub"
"url" to "https://github.com/CCBlueX/LiquidBounce"
},
))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem
import io.netty.handler.codec.http.FullHttpResponse
import net.ccbluex.liquidbounce.api.core.formatAvatarUrl
import net.ccbluex.liquidbounce.config.gson.interopGson
import net.ccbluex.liquidbounce.config.gson.util.emptyJsonObject
import net.ccbluex.liquidbounce.event.EventManager
import net.ccbluex.liquidbounce.event.events.AccountManagerMessageEvent
import net.ccbluex.liquidbounce.features.misc.AccountManager
Expand Down Expand Up @@ -45,7 +46,7 @@ fun postNewMicrosoftAccount(requestObject: RequestObject): FullHttpResponse {
browseUrl(it)
EventManager.callEvent(AccountManagerMessageEvent("Opened login url in browser"))
}
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/clipboard
Expand All @@ -57,7 +58,7 @@ fun postClipboardMicrosoftAccount(requestObject: RequestObject): FullHttpRespons
EventManager.callEvent(AccountManagerMessageEvent("Copied login url to clipboard"))
}
}
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/new/cracked
Expand All @@ -67,7 +68,7 @@ fun postNewCrackedAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.newCrackedAccount(accountForm.username, accountForm.online ?: false)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/new/session
Expand All @@ -77,7 +78,7 @@ fun postNewSessionAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.newSessionAccount(accountForm.token)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/new/altening
Expand All @@ -86,7 +87,7 @@ fun postNewAlteningAccount(requestObject: RequestObject): FullHttpResponse {
data class AlteningForm(val token: String)
val accountForm = requestObject.asJson<AlteningForm>()
AccountManager.newAlteningAccount(accountForm.token)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/generate
Expand All @@ -96,7 +97,7 @@ fun postGenerateAlteningAccount(requestObject: RequestObject): FullHttpResponse
val accountForm = requestObject.asJson<AlteningGenForm>()

AccountManager.generateAlteningAccount(accountForm.apiToken)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/swap
Expand All @@ -106,7 +107,7 @@ fun postSwapAccounts(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.swapAccounts(accountForm.from, accountForm.to)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/order
Expand All @@ -116,7 +117,7 @@ fun postOrderAccounts(requestObject: RequestObject): FullHttpResponse {
val accountOrderRequest = requestObject.asJson<AccountOrderRequest>()

AccountManager.orderAccounts(accountOrderRequest.order)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/login
Expand All @@ -126,7 +127,7 @@ fun postLoginAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.loginAccount(accountForm.id)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/cracked
Expand All @@ -136,7 +137,7 @@ fun postLoginCrackedAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.loginCrackedAccount(accountForm.username, accountForm.online ?: false)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/session
Expand All @@ -146,7 +147,7 @@ fun postLoginSessionAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.loginSessionAccount(accountForm.token)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// POST /api/v1/client/accounts/restore
Expand All @@ -163,7 +164,7 @@ fun putFavoriteAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.favoriteAccount(accountForm.id)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// DELETE /api/v1/client/accounts/favorite
Expand All @@ -173,7 +174,7 @@ fun deleteFavoriteAccount(requestObject: RequestObject): FullHttpResponse {
val accountForm = requestObject.asJson<AccountForm>()

AccountManager.unfavoriteAccount(accountForm.id)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

// DELETE /api/v1/client/accounts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package net.ccbluex.liquidbounce.integration.interop.protocol.rest.v1.client

import com.google.gson.JsonArray
import com.google.gson.JsonObject
import net.ccbluex.liquidbounce.config.gson.util.emptyJsonObject
import net.ccbluex.liquidbounce.integration.interop.persistant.PersistentLocalStorage
import net.ccbluex.netty.http.model.RequestObject
import net.ccbluex.netty.http.util.httpForbidden
Expand Down Expand Up @@ -55,14 +56,14 @@ fun putLocalStorage(requestObject: RequestObject) = with(requestObject) {
val value = body["value"]?.asString ?: return@with httpForbidden("No value")

PersistentLocalStorage[key] = value
httpOk(JsonObject())
httpOk(emptyJsonObject())
}

// DELETE /api/v1/client/localStorage
fun deleteLocalStorage(requestObject: RequestObject) = with(requestObject) {
val key = queryParams["key"] ?: return@with httpForbidden("No key")
PersistentLocalStorage.remove(key)
httpOk(JsonObject())
httpOk(emptyJsonObject())
}

// GET /api/v1/client/localStorage/all
Expand Down Expand Up @@ -93,5 +94,5 @@ fun putAllLocalStorage(requestObject: RequestObject) = with(requestObject) {
PersistentLocalStorage[item.key] = item.value
}

httpOk(JsonObject())
httpOk(emptyJsonObject())
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import io.netty.handler.codec.http.HttpMethod
import net.ccbluex.liquidbounce.config.AutoConfig
import net.ccbluex.liquidbounce.config.ConfigSystem
import net.ccbluex.liquidbounce.config.gson.interopGson
import net.ccbluex.liquidbounce.config.gson.util.emptyJsonObject
import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.ModuleManager
import net.ccbluex.liquidbounce.features.module.ModuleManager.modulesConfigurable
Expand Down Expand Up @@ -109,7 +110,7 @@ fun postPanic(requestObject: RequestObject): FullHttpResponse {
}
}
}
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

data class ModuleRequest(val name: String) {
Expand All @@ -132,7 +133,7 @@ data class ModuleRequest(val name: String) {
logger.error("Failed to toggle module $name", it)
}
}
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

fun acceptGetSettingsRequest(): FullHttpResponse {
Expand All @@ -148,7 +149,7 @@ data class ModuleRequest(val name: String) {
}

ConfigSystem.storeConfigurable(modulesConfigurable)
return httpOk(JsonObject())
return httpOk(emptyJsonObject())
}

}
Loading

0 comments on commit 9292e62

Please sign in to comment.