more sounds

This commit is contained in:
Bixilon 2021-05-24 18:25:24 +02:00
parent 52f873c5f8
commit 504302025f
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 182 additions and 68 deletions

View File

@ -26,6 +26,7 @@ import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.ElementRenderer
import de.bixilon.minosoft.gui.rendering.shader.Shader import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.util.VecUtil import de.bixilon.minosoft.gui.rendering.util.VecUtil
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.BitByte.isBit import de.bixilon.minosoft.util.BitByte.isBit
@ -165,7 +166,7 @@ class BlockOutlineRenderer(
collisionMesh?.unload() collisionMesh?.unload()
outlineMesh = BlockOutlineMesh() outlineMesh = BlockOutlineMesh()
val blockOffset = raycastHit.blockPosition.getWorldOffset(raycastHit.blockState.block).plus(raycastHit.blockPosition) val blockOffset = raycastHit.blockPosition.toVec3 + raycastHit.blockPosition.getWorldOffset(raycastHit.blockState.block)
drawVoxelShape(raycastHit.blockState.outlineShape, blockOffset, outlineMesh) drawVoxelShape(raycastHit.blockState.outlineShape, blockOffset, outlineMesh)
outlineMesh.load() outlineMesh.load()

View File

@ -29,6 +29,7 @@ import de.bixilon.minosoft.gui.rendering.textures.TextureTransparencies
import de.bixilon.minosoft.gui.rendering.util.VecUtil import de.bixilon.minosoft.gui.rendering.util.VecUtil
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
import de.bixilon.minosoft.gui.rendering.util.VecUtil.rotate import de.bixilon.minosoft.gui.rendering.util.VecUtil.rotate
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import glm_.vec3.Vec3 import glm_.vec3.Vec3
class ElementRenderer( class ElementRenderer(
@ -83,7 +84,7 @@ class ElementRenderer(
for ((drawPositionIndex, texturePositionIndex) in DRAW_ODER) { for ((drawPositionIndex, texturePositionIndex) in DRAW_ODER) {
val input = drawPositions[drawPositionIndex] val input = drawPositions[drawPositionIndex]
val output = context.blockPosition plus context.offset + input + DRAW_OFFSET val output = context.blockPosition.toVec3 + input + DRAW_OFFSET + context.offset
mesh.addVertex( mesh.addVertex(
position = output, position = output,
textureCoordinates = texturePositions[texturePositionIndex]!!, textureCoordinates = texturePositions[texturePositionIndex]!!,

View File

@ -29,6 +29,7 @@ import de.bixilon.minosoft.modding.event.events.BlockBreakAckEvent
import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockBreakC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.BlockBreakC2SP
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import glm_.pow import glm_.pow
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
@ -131,6 +132,8 @@ class LeftClickHandler(
connection.sendPacket(BlockBreakC2SP(BlockBreakC2SP.BreakType.FINISHED_DIGGING, raycastHit.blockPosition, raycastHit.hitDirection)) connection.sendPacket(BlockBreakC2SP(BlockBreakC2SP.BreakType.FINISHED_DIGGING, raycastHit.blockPosition, raycastHit.hitDirection))
clearDigging() clearDigging()
connection.world.setBlockState(raycastHit.blockPosition, null) connection.world.setBlockState(raycastHit.blockPosition, null)
renderWindow.rendering.audioPlayer.playSoundEvent(connection.registries.soundEventRegistry[BLOCK_BREAK_SOUND]!!) // ToDO
} }
val canStartBreaking = currentTime - breakSent >= ProtocolDefinition.TICK_TIME val canStartBreaking = currentTime - breakSent >= ProtocolDefinition.TICK_TIME
@ -268,4 +271,8 @@ class LeftClickHandler(
} }
swingArm() swingArm()
} }
companion object {
val BLOCK_BREAK_SOUND = "minecraft:block.metal.break".asResourceLocation()
}
} }

View File

@ -22,19 +22,20 @@ import de.bixilon.minosoft.gui.rendering.Rendering
import de.bixilon.minosoft.gui.rendering.sound.sounds.Sound import de.bixilon.minosoft.gui.rendering.sound.sounds.Sound
import de.bixilon.minosoft.gui.rendering.sound.sounds.SoundList import de.bixilon.minosoft.gui.rendering.sound.sounds.SoundList
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ConnectionStates
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.CountUpAndDownLatch import de.bixilon.minosoft.util.CountUpAndDownLatch
import de.bixilon.minosoft.util.KUtil.asResourceLocation import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.KUtil.synchronizedListOf
import de.bixilon.minosoft.util.KUtil.toSynchronizedList
import de.bixilon.minosoft.util.Queue
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.logging.LogMessageType
import org.lwjgl.BufferUtils.createShortBuffer
import org.lwjgl.openal.AL import org.lwjgl.openal.AL
import org.lwjgl.openal.AL10.*
import org.lwjgl.openal.ALC import org.lwjgl.openal.ALC
import org.lwjgl.openal.ALC10.* import org.lwjgl.openal.ALC10.*
import org.lwjgl.openal.EXTThreadLocalContext.alcSetThreadContext import org.lwjgl.openal.EXTThreadLocalContext.alcSetThreadContext
import org.lwjgl.stb.STBVorbis.stb_vorbis_get_samples_short_interleaved
import org.lwjgl.system.MemoryUtil import org.lwjgl.system.MemoryUtil
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.IntBuffer import java.nio.IntBuffer
@ -53,16 +54,35 @@ class AudioPlayer(
private var device = 0L private var device = 0L
private var context = 0L private var context = 0L
private var source = 0 private val queue = Queue()
private lateinit var listener: SoundListener
private val sources: MutableList<SoundSource> = synchronizedListOf()
private var pcm: ShortBuffer? = null private var pcm: ShortBuffer? = null
private fun preloadSounds() {
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Preloading sounds..." }
if (SoundConstants.DISABLE_PRELOADING) {
return
}
for (soundList in sounds.values) {
for (sound in soundList.sounds) {
if (SoundConstants.PRELOAD_ALL_SOUNDS || sound.preload) {
sound.load(connection.assetsManager)
}
}
}
}
fun init(latch: CountUpAndDownLatch) { fun init(latch: CountUpAndDownLatch) {
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "Loading OpenAL..." } Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "Loading OpenAL..." }
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Loading sounds.json" }
loadSounds() loadSounds()
preloadSounds()
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Initializing OpenAL..." } Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Initializing OpenAL..." }
@ -77,59 +97,84 @@ class AudioPlayer(
val deviceCaps = ALC.createCapabilities(device) val deviceCaps = ALC.createCapabilities(device)
AL.createCapabilities(deviceCaps) AL.createCapabilities(deviceCaps)
val listener = SoundListener() listener = SoundListener()
val source = SoundSource(false)
// Testing, ToDo
val sound = sounds[connection.registries.soundEventRegistry[0]]!!.sounds.iterator().next()
sound.load(connection.assetsManager)
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "OpenAL loaded!" } Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "OpenAL loaded!" }
val pcm = createShortBuffer(sound.samplesLength)
pcm.limit(stb_vorbis_get_samples_short_interleaved(sound.handle, sound.channels, pcm) * sound.channels)
val buffer = alGenBuffers()
alBufferData(buffer, sound.format, pcm, sound.sampleRate)
source.buffer = buffer
source.play()
while (source.isPlaying) {
Thread.sleep(1L)
}
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "Sound played!" }
initialized = true initialized = true
latch.countDown() latch.countDown()
} }
fun playSoundEvent(soundEvent: SoundEvent) {
playSound(sounds[soundEvent]!!.getRandom())
}
private fun getAvailableSource(): SoundSource? {
for (source in sources.toSynchronizedList()) {
if (source.available) {
return source
}
}
// no source available
if (sources.size > SoundConstants.MAX_SOURCES_AMOUNT) {
return null
}
val source = SoundSource(false)
sources += source
return source
}
fun playSound(sound: Sound) {
queue += add@{
sound.load(connection.assetsManager)
if (sound.loadFailed) {
return@add
}
val source = getAvailableSource() ?: let {
Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.WARN) { "Can not play sound: No source available!" }
return@add
}
source.sound = sound
source.play()
}
}
fun startLoop() { fun startLoop() {
while (connection.isConnected) { while (connection.connectionState != ConnectionStates.DISCONNECTING) {
queue.work()
Thread.sleep(1L) Thread.sleep(1L)
} }
} }
fun exit() { fun exit() {
// alDeleteBuffers(buffers) Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "Unloading OpenAL..." }
alDeleteSources(source)
//MemoryUtil.memFree(buffers) Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Unloading sounds..." }
for (soundList in sounds.values) {
for (sound in soundList.sounds) {
sound.unload()
}
}
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Unloading sources..." }
for (source in sources.toSynchronizedList()) {
source.unload()
}
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Destroying OpenAL context..." }
MemoryUtil.memFree(pcm) MemoryUtil.memFree(pcm)
alcSetThreadContext(MemoryUtil.NULL) alcSetThreadContext(MemoryUtil.NULL)
alcDestroyContext(context) alcDestroyContext(context)
alcCloseDevice(device) alcCloseDevice(device)
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.INFO) { "Unloaded OpenAL!" }
} }
private fun loadSounds() { private fun loadSounds() {
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Loading sounds.json" }
val data = connection.assetsManager.readJsonAsset(SOUNDS_INDEX_FILE) val data = connection.assetsManager.readJsonAsset(SOUNDS_INDEX_FILE)
for ((soundEventResourceLocation, json) in data.entrySet()) { for ((soundEventResourceLocation, json) in data.entrySet()) {

View File

@ -0,0 +1,21 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.sound
object SoundConstants {
const val PRELOAD_ALL_SOUNDS = false
const val DISABLE_PRELOADING = false
const val MAX_SOURCES_AMOUNT = 32
}

View File

@ -24,6 +24,7 @@ class SoundListener(position: Vec3 = Vec3.EMPTY) {
alListener3f(AL_POSITION, value.x, value.y, value.z) alListener3f(AL_POSITION, value.x, value.y, value.z)
field = value field = value
} }
var velocity: Vec3 = Vec3.EMPTY var velocity: Vec3 = Vec3.EMPTY
set(value) { set(value) {
alListener3f(AL_VELOCITY, value.x, value.y, value.z) alListener3f(AL_VELOCITY, value.x, value.y, value.z)

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.rendering.sound package de.bixilon.minosoft.gui.rendering.sound
import de.bixilon.minosoft.gui.rendering.sound.sounds.Sound
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import org.lwjgl.openal.AL10.* import org.lwjgl.openal.AL10.*
@ -52,15 +53,23 @@ class SoundSource(loop: Boolean = false) {
field = value field = value
} }
var buffer: Int = -1 var sound: Sound? = null
set(value) { set(value) {
alSourcei(source, AL_BUFFER, value) stop()
if (value?.loaded != true || value.loadFailed) {
field = null
return
}
alSourcei(source, AL_BUFFER, value.buffer)
field = value field = value
} }
val isPlaying: Boolean val isPlaying: Boolean
get() = alGetSourcei(source, AL_SOURCE_STATE) == AL_PLAYING get() = alGetSourcei(source, AL_SOURCE_STATE) == AL_PLAYING
val available: Boolean
get() = isPlaying
fun play() { fun play() {
alSourcePlay(source) alSourcePlay(source)
} }
@ -73,7 +82,7 @@ class SoundSource(loop: Boolean = false) {
alSourceStop(source) alSourceStop(source)
} }
fun delete() { fun unload() {
stop() stop()
alDeleteSources(source) alDeleteSources(source)
} }

View File

@ -19,8 +19,7 @@ import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.logging.LogMessageType
import org.lwjgl.BufferUtils import org.lwjgl.BufferUtils
import org.lwjgl.openal.AL10.AL_FORMAT_MONO16 import org.lwjgl.openal.AL10.*
import org.lwjgl.openal.AL10.AL_FORMAT_STEREO16
import org.lwjgl.stb.STBVorbis.* import org.lwjgl.stb.STBVorbis.*
import org.lwjgl.stb.STBVorbisInfo import org.lwjgl.stb.STBVorbisInfo
import org.lwjgl.system.MemoryUtil import org.lwjgl.system.MemoryUtil
@ -41,47 +40,74 @@ data class Sound(
private set private set
var loadFailed: Boolean = false var loadFailed: Boolean = false
private set private set
var buffer: ByteBuffer? = null
var handle: Long = -1L
var channels: Int = -1 var channels: Int = -1
private set
var sampleRate: Int = -1 var sampleRate: Int = -1
private set
var samplesLength: Int = -1 var samplesLength: Int = -1
private set
var sampleSeconds: Float = -1.0f var sampleSeconds: Float = -1.0f
private set
var buffer = -1
private set
var format: Int = -1 private var vorbisBuffer: ByteBuffer? = null
@Synchronized
fun load(assetsManager: AssetsManager) { fun load(assetsManager: AssetsManager) {
if (loaded || loadFailed) { if (loaded || loadFailed) {
return return
} }
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Loading audio file: $path" } Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Loading audio file: $path" }
try { try {
val vorbisBuffer = assetsManager.readByteAsset(path)
val buffer = assetsManager.readByteAsset(path) this.vorbisBuffer = vorbisBuffer
this.buffer = buffer
val error = BufferUtils.createIntBuffer(1) val error = BufferUtils.createIntBuffer(1)
handle = stb_vorbis_open_memory(buffer, error, null) val vorbis = stb_vorbis_open_memory(vorbisBuffer, error, null)
if (handle == MemoryUtil.NULL) { if (vorbis == MemoryUtil.NULL) {
throw IllegalStateException("Can not load vorbis: ${path}: ${error[0]}") throw IllegalStateException("Can not load vorbis: ${path}: ${error[0]}")
} }
val info = stb_vorbis_get_info(handle, STBVorbisInfo.malloc()) val info = stb_vorbis_get_info(vorbis, STBVorbisInfo.malloc())
channels = info.channels() channels = info.channels()
format = when (channels) { val format = when (channels) {
1 -> AL_FORMAT_MONO16 1 -> AL_FORMAT_MONO16
2 -> AL_FORMAT_STEREO16 2 -> AL_FORMAT_STEREO16
else -> TODO("Channels: $channels") else -> TODO("Channels: $channels")
} }
sampleRate = info.sample_rate() sampleRate = info.sample_rate()
samplesLength = stb_vorbis_stream_length_in_samples(handle) samplesLength = stb_vorbis_stream_length_in_samples(vorbis)
sampleSeconds = stb_vorbis_stream_length_in_seconds(handle) sampleSeconds = stb_vorbis_stream_length_in_seconds(vorbis)
val pcm = BufferUtils.createShortBuffer(samplesLength)
pcm.limit(stb_vorbis_get_samples_short_interleaved(vorbis, channels, pcm) * channels)
//ToDo: Somehow crashed?: MemoryUtil.memFree(vorbisBuffer)
this.buffer = alGenBuffers()
alBufferData(buffer, format, pcm, sampleRate)
loaded = true loaded = true
} catch (exception: FileNotFoundException) { } catch (exception: FileNotFoundException) {
loadFailed = true loadFailed = true
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.WARN) { "Can not load sound: $path: $exception" } Log.log(LogMessageType.RENDERING_LOADING, LogLevels.WARN) { "Can not load sound: $path: $exception" }
} }
} }
@Synchronized
fun unload() {
if (!loaded) {
return
}
alDeleteBuffers(buffer)
vorbisBuffer?.let { MemoryUtil.memFree(it) }
buffer = -1
channels = -1
sampleRate = -1
samplesLength = -1
sampleSeconds = -1.0f
loaded = false
}
} }

View File

@ -148,14 +148,10 @@ object VecUtil {
} }
val Vec3i.entityPosition: Vec3 val Vec3i.entityPosition: Vec3
get() { get() = Vec3(x + 0.5f, y, z + 0.5f) // ToDo
return Vec3(x + 0.5f, y, z + 0.5f) // ToDo
}
val Vec3.blockPosition: Vec3i val Vec3.blockPosition: Vec3i
get() { get() = Vec3i((x - 0.5f).toInt(), y.toInt(), (z - 0.5f).toInt()) // ToDo
return Vec3i((x - 0.5f).toInt(), y.toInt(), (z - 0.5f).toInt()) // ToDo
}
fun Vec3i.Companion.of(chunkPosition: Vec2i, sectionHeight: Int, inChunkSectionPosition: Vec3i): Vec3i { fun Vec3i.Companion.of(chunkPosition: Vec2i, sectionHeight: Int, inChunkSectionPosition: Vec3i): Vec3i {
return Vec3i( return Vec3i(
@ -198,8 +194,8 @@ object VecUtil {
fun Vec3i.getWorldOffset(block: Block): Vec3 { fun Vec3i.getWorldOffset(block: Block): Vec3 {
if (block.randomOffsetType == null || !Minosoft.config.config.game.other.flowerRandomOffset) { if (block.randomOffsetType == null || !Minosoft.config.config.game.other.flowerRandomOffset) {
return EMPTY_VEC3 return EMPTY_VEC3
} }
val positionHash = generatePositionHash(x, 0, z) val positionHash = generatePositionHash(x, 0, z)
val maxModelOffset = 0.25f // ToDo: use block.model.max_model_offset val maxModelOffset = 0.25f // ToDo: use block.model.max_model_offset
@ -239,18 +235,22 @@ object VecUtil {
position[axis].ceilInt - 1 position[axis].ceilInt - 1
} }
} }
fun getLengthMultiplier(direction: Vec3, position: Vec3, axis: Axes): Float { fun getLengthMultiplier(direction: Vec3, position: Vec3, axis: Axes): Float {
return (getTarget(direction, position, axis) - position[axis]) / direction[axis] return (getTarget(direction, position, axis) - position[axis]) / direction[axis]
} }
val directionXDistance = getLengthMultiplier(direction, position, Axes.X) val directionXDistance = getLengthMultiplier(direction, position, Axes.X)
val directionYDistance = getLengthMultiplier(direction, position, Axes.Y) val directionYDistance = getLengthMultiplier(direction, position, Axes.Y)
val directionZDistance = getLengthMultiplier(direction, position, Axes.Z) val directionZDistance = getLengthMultiplier(direction, position, Axes.Z)
return glm.min(directionXDistance, directionYDistance, directionZDistance) return glm.min(directionXDistance, directionYDistance, directionZDistance)
} }
val Vec3.min: Float get() = glm.min(this.x, this.y, this.z) val Vec3.min: Float
get() = glm.min(this.x, this.y, this.z)
val Vec3.max: Float get() = glm.max(this.x, this.y, this.z) val Vec3.max: Float
get() = glm.max(this.x, this.y, this.z)
val Vec3.signs: Vec3 val Vec3.signs: Vec3
get() { get() {
@ -283,8 +283,11 @@ object VecUtil {
return minDistanceDirection return minDistanceDirection
} }
val Vec3i.toVec3: Vec3
get() = Vec3(this)
operator fun Vec3.get(axis: Axes): Float { operator fun Vec3.get(axis: Axes): Float {
return when(axis) { return when (axis) {
Axes.X -> this.x Axes.X -> this.x
Axes.Y -> this.y Axes.Y -> this.y
Axes.Z -> this.z Axes.Z -> this.z

View File

@ -26,7 +26,7 @@ import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.logging.LogMessageType
class ContainerOpenS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() { class ContainerOpenS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
val containerId = if (buffer.versionId <= V_1_16) { // ToDo: This is completely guessed val containerId = if (buffer.versionId <= V_1_14) { // ToDo: This is completely guessed, it has changed between 1.13 and 1.14, same as #L38
buffer.readUnsignedByte() buffer.readUnsignedByte()
} else { } else {
buffer.readVarInt() buffer.readVarInt()
@ -35,7 +35,7 @@ class ContainerOpenS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
buffer.versionId < V_14W03B -> { buffer.versionId < V_14W03B -> {
buffer.connection.registries.containerTypeRegistry[buffer.readUnsignedByte()] buffer.connection.registries.containerTypeRegistry[buffer.readUnsignedByte()]
} }
buffer.versionId >= V_1_16 -> { // ToDo: This is completely guessed buffer.versionId >= V_1_14 -> { // ToDo: This is completely guessed
buffer.connection.registries.containerTypeRegistry[buffer.readVarInt()] buffer.connection.registries.containerTypeRegistry[buffer.readVarInt()]
} }
else -> { else -> {

View File

@ -27,7 +27,7 @@ class Queue {
add(runnable) add(runnable)
} }
fun work(maxJobs: Int) { fun work(maxJobs: Int = Int.MAX_VALUE) {
var jobsDone = 0 var jobsDone = 0
for (runnable in queue.toSynchronizedList()) { for (runnable in queue.toSynchronizedList()) {
this.queue.remove(runnable) this.queue.remove(runnable)