Cobblesync GUI and Packet Handler Update
This commit is contained in:
75
src/main/kotlin/co/sirblob/network/CobbleSyncPackets.kt
Normal file
75
src/main/kotlin/co/sirblob/network/CobbleSyncPackets.kt
Normal file
@@ -0,0 +1,75 @@
|
||||
package co.sirblob.network
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Network packet definitions for CobbleSync client-server communication
|
||||
*/
|
||||
object CobbleSyncPackets {
|
||||
|
||||
// Packet IDs
|
||||
val SYNC_REQUEST_ID = CustomPacketPayload.Type<SyncRequestPayload>(
|
||||
ResourceLocation.fromNamespaceAndPath("cobblesync", "sync_request")
|
||||
)
|
||||
val LOAD_REQUEST_ID = CustomPacketPayload.Type<LoadRequestPayload>(
|
||||
ResourceLocation.fromNamespaceAndPath("cobblesync", "load_request")
|
||||
)
|
||||
val SYNC_RESPONSE_ID = CustomPacketPayload.Type<SyncResponsePayload>(
|
||||
ResourceLocation.fromNamespaceAndPath("cobblesync", "sync_response")
|
||||
)
|
||||
|
||||
/**
|
||||
* Client -> Server: Request to sync Box 30
|
||||
*/
|
||||
class SyncRequestPayload : CustomPacketPayload {
|
||||
override fun type(): CustomPacketPayload.Type<out CustomPacketPayload> = SYNC_REQUEST_ID
|
||||
|
||||
companion object {
|
||||
val STREAM_CODEC: StreamCodec<FriendlyByteBuf, SyncRequestPayload> = StreamCodec.of(
|
||||
{ _, _ -> }, // encode - nothing to write
|
||||
{ _ -> SyncRequestPayload() } // decode - just create instance
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client -> Server: Request to load Pokemon to Box 1
|
||||
*/
|
||||
class LoadRequestPayload : CustomPacketPayload {
|
||||
override fun type(): CustomPacketPayload.Type<out CustomPacketPayload> = LOAD_REQUEST_ID
|
||||
|
||||
companion object {
|
||||
val STREAM_CODEC: StreamCodec<FriendlyByteBuf, LoadRequestPayload> = StreamCodec.of(
|
||||
{ _, _ -> },
|
||||
{ _ -> LoadRequestPayload() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Server -> Client: Response with status message
|
||||
*/
|
||||
class SyncResponsePayload(
|
||||
val success: Boolean,
|
||||
val message: String
|
||||
) : CustomPacketPayload {
|
||||
override fun type(): CustomPacketPayload.Type<out CustomPacketPayload> = SYNC_RESPONSE_ID
|
||||
|
||||
companion object {
|
||||
val STREAM_CODEC: StreamCodec<FriendlyByteBuf, SyncResponsePayload> = StreamCodec.of(
|
||||
{ buf, payload ->
|
||||
buf.writeBoolean(payload.success)
|
||||
buf.writeUtf(payload.message)
|
||||
},
|
||||
{ buf ->
|
||||
val success = buf.readBoolean()
|
||||
val message = buf.readUtf()
|
||||
SyncResponsePayload(success, message)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
135
src/main/kotlin/co/sirblob/network/ServerPacketHandler.kt
Normal file
135
src/main/kotlin/co/sirblob/network/ServerPacketHandler.kt
Normal file
@@ -0,0 +1,135 @@
|
||||
package co.sirblob.network
|
||||
|
||||
import co.sirblob.HTTPException
|
||||
import co.sirblob.Request
|
||||
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 org.json.JSONObject
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
/** Server-side packet handlers for CobbleSync operations */
|
||||
object ServerPacketHandler {
|
||||
|
||||
private val logger = LoggerFactory.getLogger("cobblesync")
|
||||
private val request = Request("https://authserver.sirblob.co")
|
||||
|
||||
fun register() {
|
||||
// Register packet types
|
||||
PayloadTypeRegistry.playC2S()
|
||||
.register(
|
||||
CobbleSyncPackets.SYNC_REQUEST_ID,
|
||||
CobbleSyncPackets.SyncRequestPayload.STREAM_CODEC
|
||||
)
|
||||
PayloadTypeRegistry.playC2S()
|
||||
.register(
|
||||
CobbleSyncPackets.LOAD_REQUEST_ID,
|
||||
CobbleSyncPackets.LoadRequestPayload.STREAM_CODEC
|
||||
)
|
||||
PayloadTypeRegistry.playS2C()
|
||||
.register(
|
||||
CobbleSyncPackets.SYNC_RESPONSE_ID,
|
||||
CobbleSyncPackets.SyncResponsePayload.STREAM_CODEC
|
||||
)
|
||||
|
||||
// Register handlers
|
||||
ServerPlayNetworking.registerGlobalReceiver(CobbleSyncPackets.SYNC_REQUEST_ID) { _, context
|
||||
->
|
||||
val player = context.player()
|
||||
context.server().execute { handleSyncRequest(player) }
|
||||
}
|
||||
|
||||
ServerPlayNetworking.registerGlobalReceiver(CobbleSyncPackets.LOAD_REQUEST_ID) { _, context
|
||||
->
|
||||
val player = context.player()
|
||||
context.server().execute { handleLoadRequest(player) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSyncRequest(player: ServerPlayer) {
|
||||
try {
|
||||
val box30 = player.pc().boxes[29]
|
||||
var pokemonCount = 0
|
||||
|
||||
box30.filterNotNull().forEach { pokemon ->
|
||||
logger.info("Syncing Pokémon: ${pokemon.species.name} (Level ${pokemon.level})")
|
||||
pokemonCount++
|
||||
}
|
||||
|
||||
if (pokemonCount < 1) {
|
||||
sendResponse(player, false, "Box 30 is empty!")
|
||||
return
|
||||
}
|
||||
|
||||
if (pokemonCount > 12) {
|
||||
sendResponse(player, false, "Box 30 has too many Pokémon! (Max 12)")
|
||||
return
|
||||
}
|
||||
|
||||
val obj = box30.saveToJSON(JsonObject(), player.registryAccess())
|
||||
|
||||
val payload = JSONObject().put("pokemon", obj.toString()).put("count", pokemonCount)
|
||||
|
||||
logger.info("/api/cobblesync/${player.uuid}")
|
||||
|
||||
val response = request.POST("/api/cobblesync/${player.uuid}", payload)
|
||||
logger.info(response.toString())
|
||||
|
||||
sendResponse(player, true, "Successfully synced $pokemonCount Pokémon!")
|
||||
} catch (e: HTTPException) {
|
||||
logger.error("HTTP Exception: ${e.message}")
|
||||
sendResponse(player, false, "Server error: ${e.message}")
|
||||
} catch (e: Exception) {
|
||||
logger.error("Exception: ${e.message}")
|
||||
sendResponse(player, false, "An unexpected error occurred!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLoadRequest(player: ServerPlayer) {
|
||||
try {
|
||||
val pc = player.pc()
|
||||
val box1 = pc.boxes[0]
|
||||
|
||||
var pokemonCount = 0
|
||||
box1.filterNotNull().forEach { _ -> pokemonCount++ }
|
||||
|
||||
if (pokemonCount > 0) {
|
||||
sendResponse(player, false, "Box 1 is not empty!")
|
||||
return
|
||||
}
|
||||
|
||||
val response = request.GET("/api/cobblesync/${player.uuid}")
|
||||
logger.info(response.toString())
|
||||
|
||||
if (response.getInt("status") != 200) {
|
||||
sendResponse(player, false, "No saved Pokémon found!")
|
||||
return
|
||||
}
|
||||
|
||||
val obj = JsonParser.parseString(response.getString("pokemon")).asJsonObject
|
||||
val newBox = box1.loadFromJSON(obj, player.registryAccess())
|
||||
|
||||
var loadedCount = 0
|
||||
newBox.pc.filterNotNull().forEach { pokemon ->
|
||||
logger.info("Loading Pokémon: ${pokemon.species.name} (Level ${pokemon.level})")
|
||||
box1.pc.add(pokemon)
|
||||
loadedCount++
|
||||
}
|
||||
|
||||
sendResponse(player, true, "Successfully loaded $loadedCount Pokémon!")
|
||||
} catch (e: HTTPException) {
|
||||
logger.error("HTTP Exception: ${e.message}")
|
||||
sendResponse(player, false, "Server error: ${e.message}")
|
||||
} catch (e: Exception) {
|
||||
logger.error("Exception: ${e.message}")
|
||||
sendResponse(player, false, "An unexpected error occurred!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendResponse(player: ServerPlayer, success: Boolean, message: String) {
|
||||
ServerPlayNetworking.send(player, CobbleSyncPackets.SyncResponsePayload(success, message))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user