Skip to content

Commit

Permalink
Support 1.18 format changes (Fixes #3)
Browse files Browse the repository at this point in the history
  • Loading branch information
skyrising committed Jul 17, 2022
1 parent f6cd471 commit d563e98
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 17 deletions.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ repositories {
dependencies {
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("it.unimi.dsi:fastutil:8.5.2")
implementation("it.unimi.dsi:fastutil:8.5.8")
implementation("net.sf.jopt-simple:jopt-simple:6.0-alpha-3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")

testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = 0.2.0
version = 0.3.0
8 changes: 8 additions & 0 deletions src/main/kotlin/de/skyrising/mc/scanner/constants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package de.skyrising.mc.scanner

object DataVersion {
const val FLATTENING = 1451 // 17w47a
const val NON_PACKED_BLOCK_STATES = 2529 // 20w17a
const val BLOCK_STATES_CONTAINERIZED = 2832 // 1.18_experimental-snapshot-7 + 1
const val REMOVE_LEVEL_TAG = 2842 // 21w42a + 2
}
41 changes: 30 additions & 11 deletions src/main/kotlin/de/skyrising/mc/scanner/region.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ data class RegionFile(private val path: Path) : Scannable {
val itemNeedles: Set<ItemType> = needles.filterIsInstanceTo(mutableSetOf())
RegionReader(Files.newByteChannel(path, StandardOpenOption.READ)).use {
it.accept(RegionVisitor.visitAllChunks { x, z, version, data ->
scanChunk(results, blockIdNeedles, blockStateNeedles, itemNeedles, statsMode, ChunkPos(dimension, x, z), version, data)
scanChunk(results, blockIdNeedles, blockStateNeedles, itemNeedles, statsMode, ChunkPos(dimension, (this.x shl 5) or x, (this.z shl 5) or z), version, data)
})
}
return results
Expand All @@ -49,9 +49,27 @@ data class RegionFile(private val path: Path) : Scannable {
}
}

fun getPalette(section: CompoundTag, version: Int): List<CompoundTag>? {
if (version <= DataVersion.BLOCK_STATES_CONTAINERIZED) {
return if (section.has("Palette", Tag.LIST)) section.getList("Palette") else null
}
if (!section.has("block_states", Tag.COMPOUND)) return null
val container = section.getCompound("block_states")
return if (container.has("palette", Tag.LIST)) container.getList("palette") else null
}

fun getBlockStates(section: CompoundTag, version: Int): LongArray? {
if (version <= DataVersion.BLOCK_STATES_CONTAINERIZED) {
return if (section.has("BlockStates", Tag.LONG_ARRAY)) section.getLongArray("BlockStates") else null
}
if (!section.has("block_states", Tag.COMPOUND)) return null
val container = section.getCompound("block_states")
return if (container.has("data", Tag.LONG_ARRAY)) container.getLongArray("data") else null
}

fun scanChunk(results: MutableList<SearchResult>, blockIdNeedles: Set<BlockIdMask>, blockStateNeedles: Set<BlockState>, itemNeedles: Set<ItemType>, statsMode: Boolean, chunkPos: ChunkPos, version: Int, data: CompoundTag) {
val dimension = chunkPos.dimension
val flattened = version >= 1451 // 17w47a
val flattened = version >= DataVersion.FLATTENING
if (!flattened && blockIdNeedles.isNotEmpty()) {
val sections = data.getList<CompoundTag>("Sections")
val matches = Object2IntOpenHashMap<BlockIdMask>()
Expand All @@ -72,11 +90,11 @@ fun scanChunk(results: MutableList<SearchResult>, blockIdNeedles: Set<BlockIdMas
}
}
if (flattened && blockStateNeedles.isNotEmpty()) {
val sections = data.getList<CompoundTag>("Sections")
val sections = data.getList<CompoundTag>(if (version < DataVersion.REMOVE_LEVEL_TAG) "Sections" else "sections")
val matches = Object2IntOpenHashMap<BlockState>()
for (section in sections) {
if (!section.has("Palette", Tag.LIST)) continue
val palette = section.getList<CompoundTag>("Palette")
val palette = getPalette(section, version) ?: continue
val blockStates = getBlockStates(section, version) ?: continue
val matchingPaletteEntries = Int2ObjectOpenHashMap<BlockState>()
palette.forEachIndexed { index, paletteEntry ->
val state = BlockState.from(paletteEntry)
Expand All @@ -85,8 +103,7 @@ fun scanChunk(results: MutableList<SearchResult>, blockIdNeedles: Set<BlockIdMas
}
}
if (matchingPaletteEntries.isEmpty()) continue
val blockStates = section.getLongArray("BlockStates")
val counts = scanBlockStates(matchingPaletteEntries, blockStates, palette.size, version < 2529)
val counts = scanBlockStates(matchingPaletteEntries, blockStates, palette.size, version < DataVersion.NON_PACKED_BLOCK_STATES)
for (e in counts.object2IntEntrySet()) {
matches[e.key] = matches.getInt(e.key) + e.intValue
}
Expand All @@ -96,17 +113,19 @@ fun scanChunk(results: MutableList<SearchResult>, blockIdNeedles: Set<BlockIdMas
}
}
if (itemNeedles.isNotEmpty() || statsMode) {
if (data.has("TileEntities", Tag.LIST)) {
for (blockEntity in data.getList<CompoundTag>("TileEntities")) {
val blockEntitiesTag = if (version >= DataVersion.REMOVE_LEVEL_TAG) "block_entities" else "TileEntities"
if (data.has(blockEntitiesTag, Tag.LIST)) {
for (blockEntity in data.getList<CompoundTag>(blockEntitiesTag)) {
if (!blockEntity.has("Items", Tag.LIST)) continue
val contents = scanInventory(blockEntity.getList("Items"), itemNeedles, statsMode)
val pos = BlockPos(dimension, blockEntity.getInt("x"), blockEntity.getInt("y"), blockEntity.getInt("z"))
val container = Container(blockEntity.getString("id"), pos)
addResults(results, container, contents, statsMode)
}
}
if (data.has("Entities", Tag.LIST)) {
for (entity in data.getList<CompoundTag>("Entities")) {
val entitiesTag = if (version >= DataVersion.REMOVE_LEVEL_TAG) "entities" else "Entities"
if (data.has(entitiesTag, Tag.LIST)) {
for (entity in data.getList<CompoundTag>(entitiesTag)) {
val id = entity.getString("id")
val items = mutableListOf<CompoundTag>()
if (entity.has("HandItems", Tag.LIST)) items.addAll(entity.getList("HandItems"))
Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/de/skyrising/mc/scanner/region/io.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class RegionReader(private val channel: SeekableByteChannel): AutoCloseable {
fun accept(visitor: RegionVisitor) {
channel.position(0)
fileSize = channel.size()
if (fileSize == 0L) return
if (fileSize < 1024 * 2 * 4) throw IOException("File is too small")
val tableBuf = ByteBuffer.allocateDirect(1024 * 2 * 4)
readFully(channel, tableBuf)
tableBuf.flip()
Expand Down Expand Up @@ -93,10 +95,11 @@ class RegionReader(private val channel: SeekableByteChannel): AutoCloseable {
visitor.onInvalidData(IllegalArgumentException("No data version"))
return
}
if (!chunk.has("Level", Tag.COMPOUND)) {
val version = chunk.getInt("DataVersion");
if (!chunk.has("Level", Tag.COMPOUND) && version < DataVersion.REMOVE_LEVEL_TAG) {
visitor.onInvalidData(IllegalArgumentException("No level tag"))
return
}
visitor.visit(chunk.getInt("DataVersion"), chunk.getCompound("Level"))
visitor.visit(version, if (version >= DataVersion.REMOVE_LEVEL_TAG) chunk else chunk.getCompound("Level"))
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/de/skyrising/mc/scanner/scanner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ fun runScan(path: Path, outPath: Path, executor: ExecutorService, needles: Colle
val matrix = result.needle.matrix
for (i in 0 until stride) {
inventoryCounts.addTo(types[i], 1)
val map = stats.computeIfAbsent(types[i]) { Object2DoubleOpenHashMap() }
val map = stats.computeIfAbsent(types[i], Object2ObjectFunction { Object2DoubleOpenHashMap() })
for (j in 0 until stride) {
val type = types[j]
val value = matrix[i * stride + j]
Expand Down

0 comments on commit d563e98

Please sign in to comment.