CobbleSync Json Parser Fix
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,3 +40,4 @@ replay_*.log
|
||||
*.jfr
|
||||
|
||||
remappedSrc/
|
||||
.kotlin/
|
||||
@@ -4,6 +4,7 @@ import co.sirblob.network.ServerPacketHandler
|
||||
import com.cobblemon.mod.common.api.text.blue
|
||||
import com.cobblemon.mod.common.api.text.green
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.pc
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
@@ -14,318 +15,331 @@ import net.fabricmc.api.ModInitializer
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback
|
||||
import net.minecraft.commands.CommandSourceStack
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.json.JSONObject
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
object CobbleSync : ModInitializer {
|
||||
|
||||
private val logger = LoggerFactory.getLogger("cobblesync")
|
||||
private val request = Request("https://authserver.sirblob.co")
|
||||
private val logger = LoggerFactory.getLogger("cobblesync")
|
||||
private val request = Request("https://authserver.sirblob.co")
|
||||
|
||||
override fun onInitialize() {
|
||||
logger.info("CobbleSync initializing...")
|
||||
override fun onInitialize() {
|
||||
logger.info("CobbleSync initializing...")
|
||||
|
||||
// Register network packet handlers for GUI communication
|
||||
ServerPacketHandler.register()
|
||||
logger.info("Registered CobbleSync network handlers")
|
||||
// Register network packet handlers for GUI communication
|
||||
ServerPacketHandler.register()
|
||||
logger.info("Registered CobbleSync network handlers")
|
||||
|
||||
CommandRegistrationCallback.EVENT.register(
|
||||
CommandRegistrationCallback { dispatcher, _, _ ->
|
||||
dispatcher.register(
|
||||
LiteralArgumentBuilder.literal<CommandSourceStack>("cobblesync")
|
||||
.then(
|
||||
LiteralArgumentBuilder.literal<CommandSourceStack>(
|
||||
"sync"
|
||||
)
|
||||
.executes(
|
||||
Command<CommandSourceStack> {
|
||||
context:
|
||||
CommandContext<
|
||||
CommandSourceStack>
|
||||
->
|
||||
val player =
|
||||
context.source
|
||||
.playerOrException
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Syncing box..."
|
||||
)
|
||||
.red()
|
||||
)
|
||||
CommandRegistrationCallback.EVENT.register(
|
||||
CommandRegistrationCallback { dispatcher, _, _ ->
|
||||
dispatcher.register(
|
||||
LiteralArgumentBuilder.literal<CommandSourceStack>("cobblesync")
|
||||
.then(
|
||||
LiteralArgumentBuilder.literal<CommandSourceStack>(
|
||||
"sync"
|
||||
)
|
||||
.executes(
|
||||
Command<CommandSourceStack> {
|
||||
context:
|
||||
CommandContext<
|
||||
CommandSourceStack>
|
||||
->
|
||||
val player =
|
||||
context.source
|
||||
.playerOrException
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Syncing box..."
|
||||
)
|
||||
.red()
|
||||
)
|
||||
|
||||
val box30 =
|
||||
player.pc().boxes.get(29)
|
||||
var pokemonCount = 0
|
||||
val box30 =
|
||||
player.pc().boxes.get(29)
|
||||
var pokemonCount = 0
|
||||
|
||||
box30.filterNotNull().forEach {
|
||||
pokemon ->
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Syncing Pokémon: ${pokemon.species.name} (Level ${pokemon.level})"
|
||||
)
|
||||
.blue()
|
||||
)
|
||||
pokemonCount++
|
||||
}
|
||||
box30.filterNotNull().forEach {
|
||||
pokemon ->
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Syncing Pokémon: ${pokemon.species.name} (Level ${pokemon.level})"
|
||||
)
|
||||
.blue()
|
||||
)
|
||||
pokemonCount++
|
||||
}
|
||||
|
||||
if (pokemonCount < 1) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"[Sync Failed] Box 1 is empty!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
} else if (pokemonCount > 12) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"[Sync Failed] Box 1 has too many pokemon!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
if (pokemonCount < 1) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"[Sync Failed] Box 1 is empty!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
} else if (pokemonCount > 12) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"[Sync Failed] Box 1 has too many pokemon!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
var obj =
|
||||
box30.saveToJSON(
|
||||
JsonObject(),
|
||||
player.registryAccess()
|
||||
)
|
||||
var obj =
|
||||
box30.saveToJSON(
|
||||
JsonObject(),
|
||||
player.registryAccess()
|
||||
)
|
||||
|
||||
val payload =
|
||||
JSONObject()
|
||||
.put(
|
||||
"pokemon",
|
||||
obj.toString()
|
||||
)
|
||||
.put(
|
||||
"count",
|
||||
pokemonCount
|
||||
)
|
||||
// Remove held items from the JSON to prevent duping/transferring items
|
||||
obj.entrySet().forEach { entry ->
|
||||
if (entry.value.isJsonObject) {
|
||||
entry.value.asJsonObject.remove("HeldItem")
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(
|
||||
"/api/cobblesync/" +
|
||||
player.uuid
|
||||
.toString()
|
||||
)
|
||||
val payload =
|
||||
JSONObject()
|
||||
.put(
|
||||
"pokemon",
|
||||
obj.toString()
|
||||
)
|
||||
.put(
|
||||
"count",
|
||||
pokemonCount
|
||||
)
|
||||
|
||||
try {
|
||||
var response =
|
||||
request.POST(
|
||||
"/api/cobblesync/" +
|
||||
player.uuid
|
||||
.toString(),
|
||||
payload
|
||||
)
|
||||
logger.info(
|
||||
"/api/cobblesync/" +
|
||||
player.uuid
|
||||
.toString()
|
||||
)
|
||||
|
||||
logger.info(response.toString())
|
||||
try {
|
||||
var response =
|
||||
request.POST(
|
||||
"/api/cobblesync/" +
|
||||
player.uuid
|
||||
.toString(),
|
||||
payload
|
||||
)
|
||||
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Box 30 synced successfully!"
|
||||
)
|
||||
.green()
|
||||
)
|
||||
} catch (e: HTTPException) {
|
||||
logger.error(
|
||||
"HTTP Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Error syncing box 30!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
} catch (e: Exception) {
|
||||
logger.error(
|
||||
"Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"An unexpected error occurred!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
logger.info(response.toString())
|
||||
|
||||
1
|
||||
}
|
||||
)
|
||||
)
|
||||
.then(
|
||||
LiteralArgumentBuilder.literal<CommandSourceStack>(
|
||||
"load"
|
||||
)
|
||||
.executes(
|
||||
Command<CommandSourceStack> {
|
||||
context:
|
||||
CommandContext<
|
||||
CommandSourceStack>
|
||||
->
|
||||
val player =
|
||||
context.source
|
||||
.playerOrException
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Box 30 synced successfully!"
|
||||
)
|
||||
.green()
|
||||
)
|
||||
} catch (e: HTTPException) {
|
||||
logger.error(
|
||||
"HTTP Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Error syncing box 30!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
} catch (e: Exception) {
|
||||
logger.error(
|
||||
"Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"An unexpected error occurred!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
val pc = player.pc()
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Loading Pokémon..."
|
||||
)
|
||||
.green()
|
||||
)
|
||||
1
|
||||
}
|
||||
)
|
||||
)
|
||||
.then(
|
||||
LiteralArgumentBuilder.literal<CommandSourceStack>(
|
||||
"load"
|
||||
)
|
||||
.executes(
|
||||
Command<CommandSourceStack> {
|
||||
context:
|
||||
CommandContext<
|
||||
CommandSourceStack>
|
||||
->
|
||||
val player =
|
||||
context.source
|
||||
.playerOrException
|
||||
|
||||
try {
|
||||
var response =
|
||||
request.GET(
|
||||
"/api/cobblesync/" +
|
||||
player.uuid
|
||||
.toString()
|
||||
)
|
||||
logger.info(response.toString())
|
||||
val pc = player.pc()
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Loading Pokémon..."
|
||||
)
|
||||
.green()
|
||||
)
|
||||
|
||||
if (response.getInt("status") !=
|
||||
200
|
||||
) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"No saved Pokémon found!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
try {
|
||||
var response =
|
||||
request.GET(
|
||||
"/api/cobblesync/" +
|
||||
player.uuid
|
||||
.toString()
|
||||
)
|
||||
logger.info(response.toString())
|
||||
|
||||
var obj =
|
||||
JsonParser.parseString(
|
||||
response.getString(
|
||||
"pokemon"
|
||||
)
|
||||
)
|
||||
.asJsonObject
|
||||
if (response.getInt("status") == 403) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Player already synced/loaded"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
// Use a
|
||||
// temporary
|
||||
// box to
|
||||
// parse the
|
||||
// JSON
|
||||
val tempBox =
|
||||
pc.boxes[0]
|
||||
.loadFromJSON(
|
||||
obj,
|
||||
player.registryAccess()
|
||||
)
|
||||
val pokemonToLoad =
|
||||
tempBox.pc
|
||||
.filterNotNull()
|
||||
.toMutableList()
|
||||
if (response.getInt("status") !=
|
||||
200
|
||||
) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"No saved Pokémon found!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
if (pokemonToLoad.isEmpty()) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"No Pokémon to load!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
var obj =
|
||||
JsonParser.parseString(
|
||||
response.getString(
|
||||
"pokemon"
|
||||
)
|
||||
)
|
||||
.asJsonObject
|
||||
|
||||
// Count
|
||||
// available
|
||||
// empty
|
||||
// slots
|
||||
var emptySlots = 0
|
||||
for (box in pc.boxes) {
|
||||
for (slot in 0 until 30) {
|
||||
if (box[slot] == null) {
|
||||
emptySlots++
|
||||
}
|
||||
}
|
||||
}
|
||||
val pokemonToLoad = mutableListOf<Pokemon>()
|
||||
obj.entrySet().forEach { entry ->
|
||||
if (entry.key.startsWith("Slot")) {
|
||||
val pokemonJson = entry.value.asJsonObject
|
||||
val pokemon = Pokemon.loadFromJSON(player.registryAccess()!!, pokemonJson)
|
||||
if (pokemon != null) {
|
||||
pokemonToLoad.add(pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (emptySlots <
|
||||
pokemonToLoad
|
||||
.size
|
||||
) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Not enough empty slots! Need ${pokemonToLoad.size}, have $emptySlots"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
if (pokemonToLoad.isEmpty()) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"No Pokémon to load!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
// Add
|
||||
// Pokemon
|
||||
// to empty
|
||||
// slots
|
||||
// across
|
||||
// all boxes
|
||||
var loadedCount = 0
|
||||
for (pokemon in pokemonToLoad) {
|
||||
var placed = false
|
||||
for (box in pc.boxes) {
|
||||
if (placed) break
|
||||
for (slot in
|
||||
0 until 30) {
|
||||
if (box[slot] ==
|
||||
null
|
||||
) {
|
||||
box[slot] =
|
||||
pokemon
|
||||
player.sendSystemMessage(
|
||||
Component
|
||||
.literal(
|
||||
"Received Pokémon: ${pokemon.species.name} (Level ${pokemon.level})"
|
||||
)
|
||||
.blue()
|
||||
)
|
||||
loadedCount++
|
||||
placed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Count
|
||||
// available
|
||||
// empty
|
||||
// slots
|
||||
var emptySlots = 0
|
||||
for (box in pc.boxes) {
|
||||
for (slot in 0 until 30) {
|
||||
if (box[slot] == null) {
|
||||
emptySlots++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Successfully loaded $loadedCount Pokémon to empty slots!"
|
||||
)
|
||||
.green()
|
||||
)
|
||||
} catch (e: HTTPException) {
|
||||
logger.error(
|
||||
"HTTP Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Error loading Pokémon!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
} catch (e: Exception) {
|
||||
logger.error(
|
||||
"Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"An unexpected error occurred!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
if (emptySlots <
|
||||
pokemonToLoad
|
||||
.size
|
||||
) {
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Not enough empty slots! Need ${pokemonToLoad.size}, have $emptySlots"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
1
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
// Add
|
||||
// Pokemon
|
||||
// to empty
|
||||
// slots
|
||||
// across
|
||||
// all boxes
|
||||
var loadedCount = 0
|
||||
for (pokemon in pokemonToLoad) {
|
||||
var placed = false
|
||||
for (box in pc.boxes) {
|
||||
if (placed) break
|
||||
for (slot in
|
||||
0 until 30) {
|
||||
if (box[slot] ==
|
||||
null
|
||||
) {
|
||||
box[slot] =
|
||||
pokemon
|
||||
player.sendSystemMessage(
|
||||
Component
|
||||
.literal(
|
||||
"Received Pokémon: ${pokemon.species.name} (Level ${pokemon.level})"
|
||||
)
|
||||
.blue()
|
||||
)
|
||||
loadedCount++
|
||||
placed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Successfully loaded $loadedCount Pokémon to empty slots!"
|
||||
)
|
||||
.green()
|
||||
)
|
||||
} catch (e: HTTPException) {
|
||||
logger.error(
|
||||
"HTTP Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"Error loading Pokémon!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
} catch (e: Exception) {
|
||||
logger.error(
|
||||
"Exception: ${e.message}"
|
||||
)
|
||||
player.sendSystemMessage(
|
||||
Component.literal(
|
||||
"An unexpected error occurred!"
|
||||
)
|
||||
.red()
|
||||
)
|
||||
return@Command 1
|
||||
}
|
||||
|
||||
1
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,17 @@ package co.sirblob.network
|
||||
|
||||
import co.sirblob.HTTPException
|
||||
import co.sirblob.Request
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.pc
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.network.chat.Component
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import org.json.JSONObject
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@@ -70,6 +75,13 @@ object ServerPacketHandler {
|
||||
}
|
||||
|
||||
val obj = box30.saveToJSON(JsonObject(), player.registryAccess())
|
||||
|
||||
// Remove held items from the JSON to prevent duping/transferring items
|
||||
obj.entrySet().forEach { entry ->
|
||||
if (entry.value.isJsonObject) {
|
||||
entry.value.asJsonObject.remove("HeldItem")
|
||||
}
|
||||
}
|
||||
|
||||
val payload = JSONObject().put("pokemon", obj.toString()).put("count", pokemonCount)
|
||||
|
||||
@@ -96,6 +108,11 @@ object ServerPacketHandler {
|
||||
val response = request.GET("/api/cobblesync/${player.uuid}")
|
||||
logger.info(response.toString())
|
||||
|
||||
if (response.getInt("status") == 403) {
|
||||
sendResponse(player, false, "Player already synced/loaded")
|
||||
return
|
||||
}
|
||||
|
||||
if (response.getInt("status") != 200) {
|
||||
sendResponse(player, false, "No saved Pokémon found!")
|
||||
return
|
||||
@@ -103,9 +120,16 @@ object ServerPacketHandler {
|
||||
|
||||
val obj = JsonParser.parseString(response.getString("pokemon")).asJsonObject
|
||||
|
||||
// Use a temporary box to parse the JSON data
|
||||
val tempBox = pc.boxes[0].loadFromJSON(obj, player.registryAccess())
|
||||
val pokemonToLoad = tempBox.pc.filterNotNull().toMutableList()
|
||||
val pokemonToLoad = mutableListOf<Pokemon>()
|
||||
obj.entrySet().forEach { entry ->
|
||||
if (entry.key.startsWith("Slot")) {
|
||||
val pokemonJson = entry.value.asJsonObject
|
||||
val pokemon = Pokemon.loadFromJSON(player.registryAccess()!!, pokemonJson)
|
||||
if (pokemon != null) {
|
||||
pokemonToLoad.add(pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pokemonToLoad.isEmpty()) {
|
||||
sendResponse(player, false, "No Pokémon to load!")
|
||||
|
||||
Reference in New Issue
Block a user