Skip to content

Commit

Permalink
Region file legacy conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
NichtStudioCode committed Jun 6, 2024
1 parent 291ef36 commit 9b0de19
Show file tree
Hide file tree
Showing 27 changed files with 463 additions and 254 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
format.version = "1.1"

[versions]
cbf = "0.10"
cbf = "0.11"
configurate = "4.2.0-SNAPSHOT"
invui = "1.31"
kotlin = "2.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ internal object NovaCommand : Command("nova") {
private fun reregisterNetworkNodes(ctx: CommandContext<CommandSourceStack>) {
val nodes = Bukkit.getWorlds().asSequence()
.flatMap { it.loadedChunks.asList() }
.flatMap { NetworkManager.getNodes(it.pos) }
.flatMap { runBlocking { NetworkManager.getNodes(it.pos) } }
.toList()

for (node in nodes) {
Expand Down Expand Up @@ -708,7 +708,7 @@ internal object NovaCommand : Command("nova") {
}

private fun showNetworkNodeInfo(pos: BlockPos, ctx: CommandContext<CommandSourceStack>) {
val node = NetworkManager.getNode(pos)
val node = runBlocking { NetworkManager.getNode(pos) }
if (node != null) {
NetworkManager.queueRead(pos.world) { state ->
val connectedNodes = state.getConnectedNodes(node)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ abstract class DataHolder internal constructor(includePersistent: Boolean) {

@PublishedApi
internal val persistentData: Compound by lazy {
data["global"] // legacy name TODO: remove legacy support at some point
?: data["persistent"]
?: Compound().also { if (includePersistent) data["persistent"] = it }
data.rename("global", "persistent") // legacy conversion
data["persistent"] ?: Compound().also { if (includePersistent) data["persistent"] = it }
}

/**
Expand Down Expand Up @@ -59,10 +58,18 @@ abstract class DataHolder internal constructor(includePersistent: Boolean) {
return data.get(type, key) ?: persistentData.get(type, key)
}

internal fun hasData(key: String): Boolean =
data.contains(key) || persistentData.contains(key)
/**
* Checks whether there is data stored under the given [key],
* regardless of whether it is persistent or not.
*/
fun hasData(key: String): Boolean =
key in data || key in persistentData

internal fun removeData(key: String) {
/**
* Removes the data stored under the given [key],
* regardless of whether it is persistent or not.
*/
fun removeData(key: String) {
data.remove(key)
persistentData.remove(key)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,48 @@
package xyz.xenondevs.nova.data.serialization.cbf.adapter

import net.minecraft.resources.ResourceLocation
import org.bukkit.inventory.ItemStack
import xyz.xenondevs.cbf.CBF
import xyz.xenondevs.cbf.Compound
import xyz.xenondevs.cbf.adapter.BinaryAdapter
import xyz.xenondevs.cbf.adapter.ComplexBinaryAdapter
import xyz.xenondevs.cbf.io.ByteReader
import xyz.xenondevs.cbf.io.ByteWriter
import xyz.xenondevs.nova.item.behavior.UnknownItemFilter
import xyz.xenondevs.nova.registry.NovaRegistries
import xyz.xenondevs.nova.tileentity.network.type.item.ItemFilter
import xyz.xenondevs.nova.tileentity.network.type.item.ItemFilterType
import xyz.xenondevs.nova.util.nmsCopy
import kotlin.reflect.KType

internal object ItemFilterBinaryAdapter : BinaryAdapter<ItemFilter<*>> {
internal object ItemFilterBinaryAdapter : ComplexBinaryAdapter<ItemFilter<*>> {

override fun read(type: KType, reader: ByteReader): ItemFilter<*> {
val id = ResourceLocation(reader.readString())
val filterType = NovaRegistries.ITEM_FILTER_TYPE[id]
val compound = CBF.read<Compound>(reader)!!
override fun read(type: KType, id: UByte, reader: ByteReader): ItemFilter<*> {
if (id == 1.toUByte())
return readLegacy(reader)

val filterTypeId = ResourceLocation(reader.readString())
return createFilter(
filterTypeId,
NovaRegistries.ITEM_FILTER_TYPE[filterTypeId],
CBF.read<Compound>(reader)!!
)
}

private fun readLegacy(reader: ByteReader): ItemFilter<*> {
val whitelist = reader.readBoolean()
val nbt = reader.readBoolean()
val size = reader.readVarInt()
val items = Array<ItemStack?>(size) { CBF.read(reader) }

val id = ResourceLocation("logistics", if (nbt) "nbt_item_filter" else "type_item_filter")
val compound = Compound()
compound["items"] = items.map { it.nmsCopy }
compound["whitelist"] = whitelist

return createFilter(id, NovaRegistries.ITEM_FILTER_TYPE[id], compound)
}

private fun createFilter(id: ResourceLocation, filterType: ItemFilterType<*>?, compound: Compound): ItemFilter<*> {
if (filterType == null)
return UnknownItemFilter(id, compound)
return filterType.deserialize(compound)
Expand All @@ -29,6 +54,8 @@ internal object ItemFilterBinaryAdapter : BinaryAdapter<ItemFilter<*>> {
write(obj, writer)

private fun <T : ItemFilter<T>> write(filter: ItemFilter<T>, writer: ByteWriter) {
writer.writeUnsignedByte(2.toUByte())

if (filter is UnknownItemFilter) {
writer.writeString(filter.originalId.toString())
CBF.write(filter.originalData, writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import xyz.xenondevs.cbf.io.ByteWriter
import xyz.xenondevs.nova.util.NMSUtils
import xyz.xenondevs.nova.util.bukkitMirror
import xyz.xenondevs.nova.util.nmsVersion
import java.io.ByteArrayInputStream
import kotlin.reflect.KType
import net.minecraft.world.item.ItemStack as MojangStack
import org.bukkit.inventory.ItemStack as BukkitStack
Expand All @@ -32,7 +33,8 @@ internal object ItemStackSerializer {
}

private fun readLegacy(reader: ByteReader): ItemStack {
var nbt = NbtIo.readCompressed(reader.asInputStream(), NbtAccounter.unlimitedHeap())
val data = reader.readBytes(reader.readVarInt())
var nbt = NbtIo.readCompressed(ByteArrayInputStream(data), NbtAccounter.unlimitedHeap())
nbt = tryFix(nbt, 3700, NMSUtils.DATA_VERSION)
return ItemStack.of(nbt)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("LeakingThis")

package xyz.xenondevs.nova.tileentity

import org.bukkit.block.BlockFace
Expand Down Expand Up @@ -38,6 +40,13 @@ abstract class NetworkedTileEntity(
final override val holders: MutableSet<EndPointDataHolder> = HashSet()
override val linkedNodes: Set<NetworkNode> = emptySet()

init {
// legacy conversion
DefaultEnergyHolder.tryConvertLegacy(this)?.let { storeData("energyHolder", it) }
DefaultItemHolder.tryConvertLegacy(this)?.let { storeData("itemHolder", it) }
DefaultFluidHolder.tryConvertLegacy(this)?.let { storeData("fluidHolder", it) }
}

/**
* Retrieves the [EnergyHolder] previously stored or creates a new one and registers it in the [holders] map.
*
Expand All @@ -53,7 +62,7 @@ abstract class NetworkedTileEntity(
defaultConnectionConfig: () -> Map<BlockFace, NetworkConnectionType> = { CUBE_FACES.associateWithTo(enumMap()) { allowedConnectionType } }
): DefaultEnergyHolder {
val holder = DefaultEnergyHolder(
storedValue("energyHolder", ::Compound), // TODO: legacy conversion
storedValue("energyHolder", ::Compound),
maxEnergy,
allowedConnectionType,
defaultConnectionConfig
Expand Down Expand Up @@ -91,7 +100,7 @@ abstract class NetworkedTileEntity(
allowedConnectionTypes[mergedInventory] = NetworkConnectionType.of(allowedConnectionTypes.values)

val holder = DefaultItemHolder(
storedValue("itemHolder", ::Compound), // TODO: legacy conversion
storedValue("itemHolder", ::Compound),
allowedConnectionTypes,
mergedInventory,
// map from VirtualInventory to NetworkedInventory or use mergedInventory for all sides
Expand Down Expand Up @@ -122,8 +131,9 @@ abstract class NetworkedTileEntity(
defaultConnectionConfig: (() -> Map<BlockFace, NetworkConnectionType>)? = null
): DefaultItemHolder {
val allInventories = buildMap { this += inventory; this += inventories }

val holder = DefaultItemHolder(
storedValue("itemHolder", ::Compound), // TODO: legacy conversion
storedValue("itemHolder", ::Compound),
allInventories,
mergedInventory,
defaultInventoryConfig,
Expand Down Expand Up @@ -151,9 +161,9 @@ abstract class NetworkedTileEntity(

/**
* Retrieves the [FluidHolder] previously stored or creates a new one and registers it in the [holders] map.
*
*
* The fluid holder uses the containers and connection types provided ([container], [containers]).
*
*
* If the [FluidHolder] is created for the first time, [defaultContainerConfig] and [defaultConnectionConfig]
* are used to determine the correct [NetworkedFluidContainer] and [NetworkConnectionType] for each side.
*/
Expand All @@ -164,7 +174,7 @@ abstract class NetworkedTileEntity(
defaultConnectionConfig: () -> EnumMap<BlockFace, NetworkConnectionType> = DefaultFluidHolder.DEFAULT_CONNECTION_CONFIG
): DefaultFluidHolder {
val fluidHolder = DefaultFluidHolder(
storedValue("fluidHolder", ::Compound), // TODO: legacy conversion
storedValue("fluidHolder", ::Compound),
buildMap { this += container; this += containers },
defaultContainerConfig,
defaultConnectionConfig
Expand All @@ -173,6 +183,18 @@ abstract class NetworkedTileEntity(
return fluidHolder
}

override fun handleEnable() {
super.handleEnable()

// legacy conversion
if (hasData("connectedNodes") || hasData("networks")) {
removeData("connectedNodes")
removeData("networks")

NetworkManager.queueAddEndPoint(this)
}
}

override fun handlePlace(ctx: Context<BlockPlace>) {
super.handlePlace(ctx)
NetworkManager.queueAddEndPoint(this)
Expand Down
10 changes: 3 additions & 7 deletions nova/src/main/kotlin/xyz/xenondevs/nova/tileentity/TileEntity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -328,21 +328,17 @@ abstract class TileEntity(

// legacy conversion
val legacyName = "fluidContainer.$uuid"
var legacyAmount: Long = 0
var legacyType: FluidType? = null
if (hasData(legacyName)) {
val legacyData = retrieveDataOrNull<Compound>(legacyName)!!
legacyAmount = legacyData["amount"]!!
legacyType = legacyData["type"]
val compound = retrieveDataOrNull<Compound>(legacyName)!!
removeData(legacyName)
storeData(name, compound, persistent)
}

val container = DynamicFluidContainer(
storedValue(name, persistent, ::Compound),
uuid,
allowedTypes,
storedValue("${name}_type", persistent) { legacyType },
capacity,
storedValue("${name}_value", persistent) { legacyAmount },
)

if (updateHandler != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import org.bukkit.Bukkit
import org.bukkit.World
import org.bukkit.block.BlockFace
import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
import org.bukkit.event.world.ChunkLoadEvent
import org.bukkit.event.world.ChunkUnloadEvent
import org.bukkit.event.world.WorldLoadEvent
import org.bukkit.event.world.WorldUnloadEvent
import xyz.xenondevs.nova.initialize.DisableFun
import xyz.xenondevs.nova.initialize.InitFun
import xyz.xenondevs.nova.initialize.InternalInit
import xyz.xenondevs.nova.initialize.InternalInitStage
Expand All @@ -33,13 +35,12 @@ import xyz.xenondevs.nova.util.runTaskTimer
import xyz.xenondevs.nova.world.BlockPos
import xyz.xenondevs.nova.world.ChunkPos
import xyz.xenondevs.nova.world.format.NetworkState
import xyz.xenondevs.nova.world.format.WorldDataManager
import xyz.xenondevs.nova.world.pos
import java.util.concurrent.ConcurrentHashMap

@InternalInit(
stage = InternalInitStage.POST_WORLD,
dependsOn = [WorldDataManager::class, DefaultNetworkTypes::class]
dependsOn = [DefaultNetworkTypes::class]
)
object NetworkManager : Listener {

Expand All @@ -63,11 +64,23 @@ object NetworkManager : Listener {

@InitFun
private fun init() {
Bukkit.getWorlds().forEach(::makeConfigurator)
for (world in Bukkit.getWorlds()) {
makeConfigurator(world)

for (chunk in world.loadedChunks) {
queueLoadChunk(chunk.pos)
}
}

runTaskTimer(0, 1, ticker::tick)
registerEvents()
}

@DisableFun
private fun disable() {
// TODO: await completion of all network tasks
}

private fun makeConfigurator(world: World) {
configurators[world] = NetworkConfigurator(world, ticker)
}
Expand Down Expand Up @@ -185,15 +198,15 @@ object NetworkManager : Listener {
* Gets all [NetworkNodes][NetworkNode] in the chunk at [pos]
* using the registered [NetworkNodeProviders][NetworkNodeProvider].
*/
fun getNodes(pos: ChunkPos): Sequence<NetworkNode> {
return nodeProviders.asSequence().flatMap { it.getNodes(pos) }
suspend fun getNodes(pos: ChunkPos): List<NetworkNode> {
return nodeProviders.flatMap { it.getNodes(pos) }
}

/**
* Gets the [NetworkNode] at the specified block [pos] using the registered
* [NetworkNodeProviders][NetworkNodeProvider] or null if there is none.
*/
fun getNode(pos: BlockPos): NetworkNode? {
suspend fun getNode(pos: BlockPos): NetworkNode? {
for (nodeProvider in nodeProviders) {
val node = nodeProvider.getNode(pos)
if (node != null)
Expand All @@ -213,7 +226,7 @@ object NetworkManager : Listener {
removeConfigurator(event.world)
}

@EventHandler
@EventHandler(priority = EventPriority.LOWEST)
private fun handleChunkLoad(event: ChunkLoadEvent) {
queueLoadChunk(event.chunk.pos)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ interface NetworkNodeProvider {
/**
* Gets the [NetworkNode] at the specified block [pos] or null if there is none.
*/
fun getNode(pos: BlockPos): NetworkNode?
suspend fun getNode(pos: BlockPos): NetworkNode?

/**
* Gets all [NetworkNodes][NetworkNode] in the specified chunk [pos].
*/
fun getNodes(pos: ChunkPos): Sequence<NetworkNode>
suspend fun getNodes(pos: ChunkPos): Sequence<NetworkNode>

}

Expand All @@ -29,12 +29,12 @@ interface NetworkNodeProvider {
*/
internal object NovaNetworkNodeProvider : NetworkNodeProvider {

override fun getNode(pos: BlockPos): NetworkNode? {
return WorldDataManager.getTileEntity(pos) as? NetworkNode
override suspend fun getNode(pos: BlockPos): NetworkNode? {
return WorldDataManager.getOrLoadTileEntity(pos) as? NetworkNode
}

override fun getNodes(pos: ChunkPos): Sequence<NetworkNode> {
return WorldDataManager.getTileEntities(pos)
override suspend fun getNodes(pos: ChunkPos): Sequence<NetworkNode> {
return WorldDataManager.getOrLoadTileEntities(pos)
.asSequence()
.filterIsInstance<NetworkNode>()
}
Expand All @@ -47,12 +47,12 @@ internal object NovaNetworkNodeProvider : NetworkNodeProvider {
*/
internal object VanillaNetworkNodeProvider : NetworkNodeProvider {

override fun getNode(pos: BlockPos): NetworkNode? {
return WorldDataManager.getVanillaTileEntity(pos) as? NetworkNode
override suspend fun getNode(pos: BlockPos): NetworkNode? {
return WorldDataManager.getOrLoadVanillaTileEntity(pos) as? NetworkNode
}

override fun getNodes(pos: ChunkPos): Sequence<NetworkNode> {
return WorldDataManager.getVanillaTileEntities(pos)
override suspend fun getNodes(pos: ChunkPos): Sequence<NetworkNode> {
return WorldDataManager.getOrLoadVanillaTileEntities(pos)
.asSequence()
.filterIsInstance<NetworkNode>()
}
Expand Down
Loading

0 comments on commit 9b0de19

Please sign in to comment.