From f2cfe4bf9b5d7b0bf6843b3f50b3816f7e0e9e38 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Tue, 30 Mar 2021 23:18:54 +0200 Subject: [PATCH] refactor PacketTypes, clear kotlin packets structure --- .../bixilon/minosoft/protocol/ErrorHandler.kt | 21 ++ .../minosoft/protocol/network/Network.java | 12 +- .../protocol/packets/ClientboundPacket.kt | 2 - .../play/PacketHeldItemChangeReceiving.kt | 7 +- .../clientbound/play/PacketJoinGame.kt | 20 +- .../packets/clientbound/play/PacketRespawn.kt | 25 +- .../play/PacketServerDifficulty.kt | 7 +- .../clientbound/play/PacketUpdateLight.kt | 52 ++-- .../clientbound/play/title/PacketTitle.kt | 6 +- .../protocol/protocol/PacketTypes.java | 240 ------------------ .../minosoft/protocol/protocol/PacketTypes.kt | 211 +++++++++++++++ .../java/de/bixilon/minosoft/util/KUtil.kt | 5 + .../bixilon/minosoft/util/chunk/LightUtil.kt | 6 +- 13 files changed, 313 insertions(+), 301 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/protocol/ErrorHandler.kt delete mode 100644 src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.java create mode 100644 src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt diff --git a/src/main/java/de/bixilon/minosoft/protocol/ErrorHandler.kt b/src/main/java/de/bixilon/minosoft/protocol/ErrorHandler.kt new file mode 100644 index 000000000..7c1d901a5 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/protocol/ErrorHandler.kt @@ -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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.protocol + +import de.bixilon.minosoft.protocol.network.Connection + +interface ErrorHandler { + + fun onError(connection: Connection) {} +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/Network.java b/src/main/java/de/bixilon/minosoft/protocol/network/Network.java index eae1e975c..5bb800b23 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/Network.java +++ b/src/main/java/de/bixilon/minosoft/protocol/network/Network.java @@ -69,21 +69,25 @@ public abstract class Network { throw new UnknownPacketException(String.format("Server sent us an unknown packet (id=0x%x, length=%d, data=%s)", data.getPacketTypeId(), bytes.length, data.getBase64())); } - PacketTypes.PacketInstanceCreator instanceCreator = packetType.getCreator(); + var factory = packetType.getFactory(); - if (instanceCreator == null) { + if (factory == null) { throw new PacketNotImplementedException(data, packetType, this.connection); } ClientboundPacket packet; try { - packet = instanceCreator.createNewInstance(data); + packet = factory.invoke(data); if (data.getBytesLeft() > 0) { throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d)", packetType, data.getPosition(), data.getBytesLeft(), data.getLength())); } packet.check(this.connection); } catch (Throwable exception) { - // ToDo: packet.onError(this.connection); + var errorHandler = packetType.getErrorHandler(); + if (errorHandler != null) { + errorHandler.onError(this.connection); + } + throw exception; } return new Pair<>(packetType, packet); diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/ClientboundPacket.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/ClientboundPacket.kt index dcd534143..5d7ebb53e 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/ClientboundPacket.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/ClientboundPacket.kt @@ -18,7 +18,5 @@ abstract class ClientboundPacket : Packet { open fun handle(connection: Connection) {} - open fun onError(connection: Connection) {} - open fun check(connection: Connection) {} } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketHeldItemChangeReceiving.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketHeldItemChangeReceiving.kt index e2fd19ba7..9863f62c8 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketHeldItemChangeReceiving.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketHeldItemChangeReceiving.kt @@ -18,11 +18,10 @@ import de.bixilon.minosoft.protocol.packets.ClientboundPacket import de.bixilon.minosoft.protocol.protocol.InByteBuffer import de.bixilon.minosoft.util.logging.Log -class PacketHeldItemChangeReceiving() : ClientboundPacket() { - var slot = 0 - private set +class PacketHeldItemChangeReceiving(buffer: InByteBuffer) : ClientboundPacket() { + val slot: Int - constructor(buffer: InByteBuffer) : this() { + init { slot = buffer.readByte().toInt() } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt index 8d4c0b0e7..a82825c15 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketJoinGame.kt @@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.world.biome.accessor.BlockBiomeAccessor import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor import de.bixilon.minosoft.gui.rendering.util.VecUtil import de.bixilon.minosoft.modding.event.events.JoinGameEvent +import de.bixilon.minosoft.protocol.ErrorHandler import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.packets.ClientboundPacket import de.bixilon.minosoft.protocol.protocol.InByteBuffer @@ -36,8 +37,8 @@ import de.bixilon.minosoft.util.nbt.tag.ListTag import de.bixilon.minosoft.util.nbt.tag.NBTTag import kotlin.experimental.and -class PacketJoinGame() : ClientboundPacket() { - var entityId: Int = 0 +class PacketJoinGame(buffer: InByteBuffer) : ClientboundPacket() { + val entityId: Int var isHardcore: Boolean = false var gamemode: Gamemodes = Gamemodes.SPECTATOR var dimension: Dimension? = null @@ -50,7 +51,7 @@ class PacketJoinGame() : ClientboundPacket() { var hashedSeed: Long = 0L var dimensions: HashBiMap = HashBiMap.create() - constructor(buffer: InByteBuffer) : this() { + init { entityId = buffer.readInt() if (buffer.versionId < V_20W27A) { @@ -70,10 +71,9 @@ class PacketJoinGame() : ClientboundPacket() { if (buffer.versionId >= ProtocolVersions.V_13W42B) { levelType = LevelTypes.byType(buffer.readString()) } - if (buffer.versionId < ProtocolVersions.V_14W29A) { - return + if (buffer.versionId >= ProtocolVersions.V_14W29A) { + isReducedDebugScreen = buffer.readBoolean() } - isReducedDebugScreen = buffer.readBoolean() } if (buffer.versionId >= ProtocolVersions.V_1_16_PRE6) { @@ -124,7 +124,6 @@ class PacketJoinGame() : ClientboundPacket() { if (buffer.versionId >= ProtocolVersions.V_19W36A) { isEnableRespawnScreen = buffer.readBoolean() } - return } override fun handle(connection: Connection) { @@ -180,7 +179,10 @@ class PacketJoinGame() : ClientboundPacket() { Log.protocol(String.format("[IN] Receiving join game packet (entityId=%s, gamemode=%s, dimension=%s, difficulty=%s, hardcore=%s, viewDistance=%d)", entityId, gamemode, dimension, difficulty, isHardcore, viewDistance)) } - override fun onError(connection: Connection) { - connection.disconnect() + companion object : ErrorHandler { + + override fun onError(connection: Connection) { + connection.disconnect() + } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketRespawn.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketRespawn.kt index b75622231..a3e18b663 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketRespawn.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketRespawn.kt @@ -24,17 +24,24 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.nbt.tag.CompoundTag -class PacketRespawn() : ClientboundPacket() { - var dimension: Dimension? = null - var difficulty: Difficulties? = null - var gamemode: Gamemodes? = null - var levelType: LevelTypes? = null - var hashedSeed: Long = 0 +class PacketRespawn(buffer: InByteBuffer) : ClientboundPacket() { + lateinit var dimension: Dimension + private set + var difficulty: Difficulties = Difficulties.NORMAL + private set + val gamemode: Gamemodes + var levelType: LevelTypes = LevelTypes.UNKNOWN + private set + var hashedSeed = 0L + private set var isDebug = false + private set var isFlat = false + private set var copyMetaData = false + private set - constructor(buffer: InByteBuffer) : this() { + init { when { buffer.versionId < ProtocolVersions.V_20W21A -> { dimension = buffer.connection.mapping.dimensionRegistry.get(if (buffer.versionId < ProtocolVersions.V_1_8_9) { // ToDo: this should be 108 but wiki.vg is wrong. In 1.8 it is an int. @@ -44,7 +51,7 @@ class PacketRespawn() : ClientboundPacket() { }) } buffer.versionId < ProtocolVersions.V_1_16_2_PRE3 -> { - dimension = buffer.connection.mapping.dimensionRegistry.get(buffer.readResourceLocation()) + dimension = buffer.connection.mapping.dimensionRegistry.get(buffer.readResourceLocation())!! } else -> { buffer.readNBT() as CompoundTag // current dimension data @@ -54,7 +61,7 @@ class PacketRespawn() : ClientboundPacket() { difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt()) } if (buffer.versionId >= ProtocolVersions.V_20W22A) { - dimension = buffer.connection.mapping.dimensionRegistry.get(buffer.readResourceLocation()) + dimension = buffer.connection.mapping.dimensionRegistry.get(buffer.readResourceLocation())!! } if (buffer.versionId >= ProtocolVersions.V_19W36A) { hashedSeed = buffer.readLong() diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt index bad1e3e7e..7cadbf0ac 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt @@ -19,11 +19,12 @@ import de.bixilon.minosoft.protocol.protocol.InByteBuffer import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.util.logging.Log -class PacketServerDifficulty() : ClientboundPacket() { - lateinit var difficulty: Difficulties +class PacketServerDifficulty(buffer: InByteBuffer) : ClientboundPacket() { + val difficulty: Difficulties var locked = false + private set - constructor(buffer: InByteBuffer) : this() { + init { difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt()) if (buffer.versionId > ProtocolVersions.V_19W11A) { locked = buffer.readBoolean() diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt index 98222db20..5a1e34d7a 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt @@ -19,37 +19,41 @@ import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.packets.ClientboundPacket import de.bixilon.minosoft.protocol.protocol.InByteBuffer import de.bixilon.minosoft.protocol.protocol.ProtocolVersions +import de.bixilon.minosoft.util.KUtil import de.bixilon.minosoft.util.chunk.LightUtil.readLightPacket import de.bixilon.minosoft.util.logging.Log import glm_.vec2.Vec2i +import java.util.* -class PacketUpdateLight() : ClientboundPacket() { - private var position: Vec2i? = null - private var lightAccessor: LightAccessor? = null +class PacketUpdateLight(buffer: InByteBuffer) : ClientboundPacket() { + val position: Vec2i + var trustEdges: Boolean = false + private set + val lightAccessor: LightAccessor - constructor(buffer: InByteBuffer) : this() { + init { position = Vec2i(buffer.readVarInt(), buffer.readVarInt()) if (buffer.versionId >= ProtocolVersions.V_1_16_PRE3) { - val trustEdges = buffer.readBoolean() - } - val skyLightMask: LongArray - val blockLightMask: LongArray - val emptySkyLightMask: LongArray - val emptyBlockLightMask: LongArray - if (buffer.versionId < ProtocolVersions.V_20W49A) { - // was a varInt before 20w45a, should we change this? - skyLightMask = longArrayOf(buffer.readVarLong()) - blockLightMask = longArrayOf(buffer.readVarLong()) - emptyBlockLightMask = longArrayOf(buffer.readVarLong()) - emptySkyLightMask = longArrayOf(buffer.readVarLong()) - } else { - skyLightMask = buffer.readLongArray() - blockLightMask = buffer.readLongArray() - emptySkyLightMask = buffer.readLongArray() - emptyBlockLightMask = buffer.readLongArray() + trustEdges = buffer.readBoolean() } + val skyLightMask: BitSet + val blockLightMask: BitSet + val emptySkyLightMask: BitSet + val emptyBlockLightMask: BitSet + + if (buffer.versionId < ProtocolVersions.V_20W49A) { + skyLightMask = KUtil.bitSetOf(buffer.readVarLong()) + blockLightMask = KUtil.bitSetOf(buffer.readVarLong()) + emptyBlockLightMask = KUtil.bitSetOf(buffer.readVarLong()) + emptySkyLightMask = KUtil.bitSetOf(buffer.readVarLong()) + } else { + skyLightMask = BitSet.valueOf(buffer.readLongArray()) + blockLightMask = BitSet.valueOf(buffer.readLongArray()) + emptySkyLightMask = BitSet.valueOf(buffer.readLongArray()) + emptyBlockLightMask = BitSet.valueOf(buffer.readLongArray()) + } lightAccessor = readLightPacket(buffer, skyLightMask, blockLightMask, emptyBlockLightMask, emptySkyLightMask, buffer.connection.player.world.dimension!!) } @@ -59,12 +63,12 @@ class PacketUpdateLight() : ClientboundPacket() { } override fun handle(connection: Connection) { - val chunk = connection.player.world.getOrCreateChunk(position!!) + val chunk = connection.player.world.getOrCreateChunk(position) if (chunk.lightAccessor != null && chunk.lightAccessor is ChunkLightAccessor && lightAccessor is ChunkLightAccessor) { - (chunk.lightAccessor as ChunkLightAccessor).merge(lightAccessor as ChunkLightAccessor) + (chunk.lightAccessor as ChunkLightAccessor).merge(lightAccessor) } else { chunk.lightAccessor = lightAccessor } - connection.renderer.renderWindow.worldRenderer.prepareChunk(position!!, chunk) + connection.renderer.renderWindow.worldRenderer.prepareChunk(position, chunk) } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/title/PacketTitle.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/title/PacketTitle.kt index afe920f6f..40f16ac42 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/title/PacketTitle.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/title/PacketTitle.kt @@ -21,8 +21,8 @@ import de.bixilon.minosoft.util.KUtil import de.bixilon.minosoft.util.enum.ValuesEnum import de.bixilon.minosoft.util.logging.Log -class PacketTitle() : ClientboundPacket() { - lateinit var action: TitleActions +class PacketTitle(buffer: InByteBuffer) : ClientboundPacket() { + val action: TitleActions // fields depend on action var text: ChatComponent? = null @@ -31,7 +31,7 @@ class PacketTitle() : ClientboundPacket() { var stayTime = 0 var fadeOutTime = 0 - constructor(buffer: InByteBuffer) : this() { + init { action = buffer.connection.mapping.titleActionsRegistry.get(buffer.readVarInt())!! when (action) { TitleActions.SET_TITLE -> this.text = buffer.readChatComponent() diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.java deleted file mode 100644 index 90af6ac9c..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 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 . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.protocol; - -import de.bixilon.minosoft.protocol.packets.ClientboundPacket; -import de.bixilon.minosoft.protocol.packets.clientbound.login.*; -import de.bixilon.minosoft.protocol.packets.clientbound.play.*; -import de.bixilon.minosoft.protocol.packets.clientbound.play.title.PacketTitle; -import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusPong; -import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusResponse; - -import javax.annotation.Nullable; - -public class PacketTypes { - - public enum Serverbound { - HANDSHAKING_HANDSHAKE, - STATUS_PING, - STATUS_REQUEST, - LOGIN_LOGIN_START, - LOGIN_ENCRYPTION_RESPONSE, - LOGIN_PLUGIN_RESPONSE, - PLAY_TELEPORT_CONFIRM, - PLAY_QUERY_BLOCK_NBT, - PLAY_SET_DIFFICULTY, - PLAY_CHAT_MESSAGE, - PLAY_CLIENT_STATUS, - PLAY_CLIENT_SETTINGS, - PLAY_TAB_COMPLETE, - PLAY_WINDOW_CONFIRMATION, - PLAY_CLICK_WINDOW_BUTTON, - PLAY_CLICK_WINDOW, - PLAY_CLOSE_WINDOW, - PLAY_PLUGIN_MESSAGE, - PLAY_EDIT_BOOK, - PLAY_ENTITY_NBT_REQUEST, - PLAY_INTERACT_ENTITY, - PLAY_KEEP_ALIVE, - PLAY_LOCK_DIFFICULTY, - PLAY_PLAYER_POSITION, - PLAY_PLAYER_POSITION_AND_ROTATION, - PLAY_PLAYER_ROTATION, - PLAY_VEHICLE_MOVE, - PLAY_STEER_BOAT, - PLAY_PICK_ITEM, - PLAY_CRAFT_RECIPE_REQUEST, - PLAY_PLAYER_ABILITIES, - PLAY_PLAYER_DIGGING, - PLAY_ENTITY_ACTION, - PLAY_STEER_VEHICLE, - PLAY_RECIPE_BOOK_DATA, - PLAY_NAME_ITEM, - PLAY_RESOURCE_PACK_STATUS, - PLAY_ADVANCEMENT_TAB, - PLAY_SELECT_TRADE, - PLAY_SET_BEACON_EFFECT, - PLAY_HELD_ITEM_CHANGE, - PLAY_UPDATE_COMMAND_BLOCK, - PLAY_CREATIVE_INVENTORY_ACTION, - PLAY_UPDATE_JIGSAW_BLOCK, - PLAY_UPDATE_STRUCTURE_BLOCK, - PLAY_UPDATE_SIGN, - PLAY_ANIMATION, - PLAY_SPECTATE, - PLAY_PLAYER_BLOCK_PLACEMENT, - PLAY_USE_ITEM, - PLAY_UPDATE_COMMAND_BLOCK_MINECART, - PLAY_GENERATE_STRUCTURE, - PLAY_SET_DISPLAYED_RECIPE, - PLAY_SET_RECIPE_BOOK_STATE, - PLAY_PLAYER_GROUND_CHANGE, - PLAY_PREPARE_CRAFTING_GRID, - PLAY_VEHICLE_MOVEMENT, - PLAY_QUERY_ENTITY_NBT; - - private final ConnectionStates state; - - Serverbound() { - this.state = ConnectionStates.valueOf(name().split("_")[0]); - } - - public ConnectionStates getState() { - return this.state; - } - } - - public enum Clientbound { - STATUS_RESPONSE(PacketStatusResponse::new, false), - STATUS_PONG(PacketStatusPong::new, false), - LOGIN_DISCONNECT(PacketLoginDisconnect::new, false), - LOGIN_ENCRYPTION_REQUEST(PacketEncryptionRequest::new, false), - LOGIN_LOGIN_SUCCESS(PacketLoginSuccess::new, false), - LOGIN_SET_COMPRESSION(PacketLoginSetCompression::new, false), - LOGIN_PLUGIN_REQUEST(PacketLoginPluginRequest::new), - PLAY_SPAWN_MOB(PacketSpawnMob::new, false), - PLAY_SPAWN_EXPERIENCE_ORB(PacketSpawnExperienceOrb::new, false), - PLAY_SPAWN_WEATHER_ENTITY(PacketSpawnWeatherEntity::new, false), - PLAY_SPAWN_PAINTING(PacketSpawnPainting::new, false), - PLAY_SPAWN_PLAYER(PacketSpawnPlayer::new, false), - PLAY_ENTITY_ANIMATION(PacketEntityAnimation::new), - PLAY_STATS_RESPONSE(PacketStatistics::new), - PLAY_ACKNOWLEDGE_PLAYER_DIGGING(PacketAcknowledgePlayerDigging::new), - PLAY_BLOCK_BREAK_ANIMATION(PacketBlockBreakAnimation::new), - PLAY_BLOCK_ENTITY_DATA(PacketBlockEntityMetadata::new), - PLAY_BLOCK_ACTION(PacketBlockAction::new), - PLAY_BLOCK_CHANGE(PacketBlockChange::new), - PLAY_BOSS_BAR(PacketBossBar::new), - PLAY_SERVER_DIFFICULTY(PacketServerDifficulty::new), - PLAY_CHAT_MESSAGE(PacketChatMessageReceiving::new), - PLAY_MULTIBLOCK_CHANGE(PacketMultiBlockChange::new), - PLAY_TAB_COMPLETE(PacketTabCompleteReceiving::new), - PLAY_DECLARE_COMMANDS(PacketDeclareCommands::new), - PLAY_WINDOW_CONFIRMATION(PacketConfirmTransactionReceiving::new), - PLAY_CLOSE_WINDOW(PacketCloseWindowReceiving::new), - PLAY_WINDOW_ITEMS(PacketWindowItems::new), - PLAY_WINDOW_PROPERTY(PacketWindowProperty::new), - PLAY_SET_SLOT(PacketSetSlot::new), - PLAY_SET_COOLDOWN(PacketSetCooldown::new), - PLAY_PLUGIN_MESSAGE(PacketPluginMessageReceiving::new), - PLAY_NAMED_SOUND_EFFECT(PacketNamedSoundEffect::new), - PLAY_DISCONNECT(PacketDisconnect::new, false), - PLAY_ENTITY_EVENT(PacketEntityEvent::new), - PLAY_EXPLOSION(PacketExplosion::new), - PLAY_UNLOAD_CHUNK(PacketUnloadChunk::new), - PLAY_CHANGE_GAME_STATE(PacketChangeGameState::new), - PLAY_OPEN_HORSE_WINDOW(PacketOpenHorseWindow::new), - PLAY_KEEP_ALIVE(PacketKeepAlive::new), - PLAY_CHUNK_DATA(PacketChunkData::new), - PLAY_EFFECT(PacketEffect::new), - PLAY_PARTICLE(PacketParticle::new), - PLAY_UPDATE_LIGHT(PacketUpdateLight::new), - PLAY_JOIN_GAME(PacketJoinGame::new, false), - PLAY_MAP_DATA(PacketMapData::new), - PLAY_TRADE_LIST(PacketTradeList::new), - PLAY_ENTITY_MOVEMENT_AND_ROTATION(PacketEntityMovementAndRotation::new), - PLAY_ENTITY_ROTATION(PacketEntityRotation::new), - PLAY_ENTITY_MOVEMENT(PacketEntityMovement::new), - PLAY_VEHICLE_MOVEMENT(PacketVehicleMovement::new), - PLAY_OPEN_BOOK(PacketOpenBook::new), - PLAY_OPEN_WINDOW(PacketOpenWindow::new), - PLAY_OPEN_SIGN_EDITOR(PacketOpenSignEditor::new), - PLAY_CRAFT_RECIPE_RESPONSE(PacketCraftRecipeResponse::new), - PLAY_PLAYER_ABILITIES(PacketPlayerAbilitiesReceiving::new), - PLAY_COMBAT_EVENT(PacketCombatEvent::new), - PLAY_PLAYER_LIST_ITEM(PacketPlayerListItem::new), - PLAY_FACE_PLAYER(PacketFacePlayer::new), - PLAY_PLAYER_POSITION_AND_ROTATION(PacketPlayerPositionAndRotation::new), - PLAY_UNLOCK_RECIPES(PacketUnlockRecipes::new), - PLAY_DESTROY_ENTITIES(PacketDestroyEntity::new), - PLAY_REMOVE_ENTITY_EFFECT(PacketRemoveEntityStatusEffect::new), - PLAY_RESOURCE_PACK_SEND(PacketResourcePackSend::new), - PLAY_RESPAWN(PacketRespawn::new, false), - PLAY_ENTITY_HEAD_ROTATION(PacketEntityHeadRotation::new), - PLAY_SELECT_ADVANCEMENT_TAB(PacketSelectAdvancementTab::new), - PLAY_WORLD_BORDER(PacketWorldBorder::new), - PLAY_CAMERA(PacketCamera::new), - PLAY_HELD_ITEM_CHANGE(PacketHeldItemChangeReceiving::new), - PLAY_UPDATE_VIEW_POSITION(PacketUpdateViewPosition::new), - PLAY_DISPLAY_SCOREBOARD(PacketScoreboardDisplayScoreboard::new), - PLAY_ENTITY_METADATA(PacketEntityMetadata::new), - PLAY_ATTACH_ENTITY(PacketAttachEntity::new), - PLAY_ENTITY_VELOCITY(PacketEntityVelocity::new), - PLAY_ENTITY_EQUIPMENT(PacketEntityEquipment::new), - PLAY_SET_EXPERIENCE(PacketSetExperience::new), - PLAY_UPDATE_HEALTH(PacketUpdateHealth::new), - PLAY_SCOREBOARD_OBJECTIVE(PacketScoreboardObjective::new), - PLAY_SET_PASSENGERS(PacketSetPassenger::new), - PLAY_TEAMS(PacketTeams::new), - PLAY_UPDATE_SCORE(PacketScoreboardUpdateScore::new), - PLAY_SPAWN_POSITION(PacketSpawnPosition::new), - PLAY_TIME_UPDATE(PacketTimeUpdate::new), - PLAY_ENTITY_SOUND_EFFECT(PacketEntitySoundEffect::new), - PLAY_SOUND_EFFECT(PacketSoundEffect::new), - PLAY_STOP_SOUND(PacketStopSound::new), - PLAY_PLAYER_LIST_HEADER_AND_FOOTER(PacketTabHeaderAndFooter::new), - PLAY_NBT_QUERY_RESPONSE(PacketNBTQueryResponse::new), - PLAY_COLLECT_ITEM(PacketCollectItem::new), - PLAY_ENTITY_TELEPORT(PacketEntityTeleport::new, false), - PLAY_ADVANCEMENTS(PacketAdvancements::new), - PLAY_ENTITY_PROPERTIES(PacketEntityProperties::new), - PLAY_ENTITY_EFFECT(PacketEntityEffect::new), - PLAY_DECLARE_RECIPES(PacketDeclareRecipes::new), - PLAY_TAGS(PacketTags::new), - PLAY_USE_BED(PacketUseBed::new), - PLAY_UPDATE_VIEW_DISTANCE(PacketUpdateViewDistance::new), - PLAY_CHUNK_BULK(PacketChunkBulk::new), - PLAY_UPDATE_SIGN(PacketUpdateSignReceiving::new), - PLAY_STATISTICS(PacketStatistics::new), - PLAY_SPAWN_ENTITY(PacketSpawnObject::new, false), - PLAY_TITLE(PacketTitle::new), - PLAY_ENTITY_INITIALISATION(PacketEntityInitialisation::new, false), - PLAY_SET_COMPRESSION(PacketSetCompression::new, false), - PLAY_ADVANCEMENT_PROGRESS(null), - PLAY_SCULK_VIBRATION_SIGNAL(PacketSculkVibrationSignal::new); - - private final ConnectionStates state; - private final boolean isThreadSafe; - private final PacketInstanceCreator creator; - - Clientbound(PacketInstanceCreator creator) { - this.state = ConnectionStates.valueOf(name().split("_")[0]); - this.creator = creator; - this.isThreadSafe = true; - } - - Clientbound(PacketInstanceCreator creator, boolean isThreadSafe) { - this.state = ConnectionStates.valueOf(name().split("_")[0]); - this.creator = creator; - this.isThreadSafe = isThreadSafe; - } - - public ConnectionStates getState() { - return this.state; - } - - @Nullable - public PacketInstanceCreator getCreator() { - return this.creator; - } - - public boolean isThreadSafe() { - return this.isThreadSafe; - } - } - - public interface PacketInstanceCreator { - ClientboundPacket createNewInstance(InByteBuffer buffer) throws Exception; - } -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt new file mode 100644 index 000000000..f9da50964 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt @@ -0,0 +1,211 @@ +/* + * Minosoft + * Copyright (C) 2020 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 . + * + * This software is not affiliated with Mojang AB, + the original developer of Minecraft. + */ +package de.bixilon.minosoft.protocol.protocol + +import de.bixilon.minosoft.protocol.ErrorHandler +import de.bixilon.minosoft.protocol.packets.ClientboundPacket +import de.bixilon.minosoft.protocol.packets.clientbound.login.* +import de.bixilon.minosoft.protocol.packets.clientbound.play.* +import de.bixilon.minosoft.protocol.packets.clientbound.play.title.PacketTitle +import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusPong +import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusResponse + +class PacketTypes { + enum class Serverbound { + HANDSHAKING_HANDSHAKE, + STATUS_PING, + STATUS_REQUEST, + LOGIN_LOGIN_START, + LOGIN_ENCRYPTION_RESPONSE, + LOGIN_PLUGIN_RESPONSE, + PLAY_TELEPORT_CONFIRM, + PLAY_QUERY_BLOCK_NBT, + PLAY_SET_DIFFICULTY, + PLAY_CHAT_MESSAGE, + PLAY_CLIENT_STATUS, + PLAY_CLIENT_SETTINGS, + PLAY_TAB_COMPLETE, + PLAY_WINDOW_CONFIRMATION, + PLAY_CLICK_WINDOW_BUTTON, + PLAY_CLICK_WINDOW, + PLAY_CLOSE_WINDOW, + PLAY_PLUGIN_MESSAGE, + PLAY_EDIT_BOOK, + PLAY_ENTITY_NBT_REQUEST, + PLAY_INTERACT_ENTITY, + PLAY_KEEP_ALIVE, + PLAY_LOCK_DIFFICULTY, + PLAY_PLAYER_POSITION, + PLAY_PLAYER_POSITION_AND_ROTATION, + PLAY_PLAYER_ROTATION, + PLAY_VEHICLE_MOVE, + PLAY_STEER_BOAT, + PLAY_PICK_ITEM, + PLAY_CRAFT_RECIPE_REQUEST, + PLAY_PLAYER_ABILITIES, + PLAY_PLAYER_DIGGING, + PLAY_ENTITY_ACTION, + PLAY_STEER_VEHICLE, + PLAY_RECIPE_BOOK_DATA, + PLAY_NAME_ITEM, + PLAY_RESOURCE_PACK_STATUS, + PLAY_ADVANCEMENT_TAB, + PLAY_SELECT_TRADE, + PLAY_SET_BEACON_EFFECT, + PLAY_HELD_ITEM_CHANGE, + PLAY_UPDATE_COMMAND_BLOCK, + PLAY_CREATIVE_INVENTORY_ACTION, + PLAY_UPDATE_JIGSAW_BLOCK, + PLAY_UPDATE_STRUCTURE_BLOCK, + PLAY_UPDATE_SIGN, + PLAY_ANIMATION, + PLAY_SPECTATE, + PLAY_PLAYER_BLOCK_PLACEMENT, + PLAY_USE_ITEM, + PLAY_UPDATE_COMMAND_BLOCK_MINECART, + PLAY_GENERATE_STRUCTURE, + PLAY_SET_DISPLAYED_RECIPE, + PLAY_SET_RECIPE_BOOK_STATE, + PLAY_PLAYER_GROUND_CHANGE, + PLAY_PREPARE_CRAFTING_GRID, + PLAY_VEHICLE_MOVEMENT, + PLAY_QUERY_ENTITY_NBT, + ; + + val state: ConnectionStates = ConnectionStates.valueOf(name.split("_".toRegex()).toTypedArray()[0]) + } + + + enum class Clientbound( + val factory: ((buffer: InByteBuffer) -> ClientboundPacket)? = null, + val isThreadSafe: Boolean = true, + val errorHandler: ErrorHandler? = null, + ) { + STATUS_RESPONSE({ PacketStatusResponse(it) }, false), + STATUS_PONG({ PacketStatusPong(it) }, false), + LOGIN_DISCONNECT({ PacketLoginDisconnect(it) }, false), + LOGIN_ENCRYPTION_REQUEST({ PacketEncryptionRequest(it) }, false), + LOGIN_LOGIN_SUCCESS({ PacketLoginSuccess(it) }, false), + LOGIN_SET_COMPRESSION({ PacketLoginSetCompression(it) }, false), + LOGIN_PLUGIN_REQUEST({ PacketLoginPluginRequest(it) }), + PLAY_SPAWN_MOB({ PacketSpawnMob(it) }, false), + PLAY_SPAWN_EXPERIENCE_ORB({ PacketSpawnExperienceOrb(it) }, false), + PLAY_SPAWN_WEATHER_ENTITY({ PacketSpawnWeatherEntity(it) }, false), + PLAY_SPAWN_PAINTING({ PacketSpawnPainting(it) }, false), + PLAY_SPAWN_PLAYER({ PacketSpawnPlayer(it) }, false), + PLAY_ENTITY_ANIMATION({ PacketEntityAnimation(it) }), + PLAY_STATS_RESPONSE({ PacketStatistics(it) }), + PLAY_ACKNOWLEDGE_PLAYER_DIGGING({ PacketAcknowledgePlayerDigging(it) }), + PLAY_BLOCK_BREAK_ANIMATION({ PacketBlockBreakAnimation(it) }), + PLAY_BLOCK_ENTITY_DATA({ PacketBlockEntityMetadata(it) }), + PLAY_BLOCK_ACTION({ PacketBlockAction(it) }), + PLAY_BLOCK_CHANGE({ PacketBlockChange(it) }), + PLAY_BOSS_BAR({ PacketBossBar(it) }), + PLAY_SERVER_DIFFICULTY({ PacketServerDifficulty(it) }), + PLAY_CHAT_MESSAGE({ PacketChatMessageReceiving(it) }), + PLAY_MULTIBLOCK_CHANGE({ PacketMultiBlockChange(it) }), + PLAY_TAB_COMPLETE({ PacketTabCompleteReceiving(it) }), + PLAY_DECLARE_COMMANDS({ PacketDeclareCommands(it) }), + PLAY_WINDOW_CONFIRMATION({ PacketConfirmTransactionReceiving(it) }), + PLAY_CLOSE_WINDOW({ PacketCloseWindowReceiving(it) }), + PLAY_WINDOW_ITEMS({ PacketWindowItems(it) }), + PLAY_WINDOW_PROPERTY({ PacketWindowProperty(it) }), + PLAY_SET_SLOT({ PacketSetSlot(it) }), + PLAY_SET_COOLDOWN({ PacketSetCooldown(it) }), + PLAY_PLUGIN_MESSAGE({ PacketPluginMessageReceiving(it) }), + PLAY_NAMED_SOUND_EFFECT({ PacketNamedSoundEffect(it) }), + PLAY_DISCONNECT({ PacketDisconnect(it) }, false), + PLAY_ENTITY_EVENT({ PacketEntityEvent(it) }), + PLAY_EXPLOSION({ PacketExplosion(it) }), + PLAY_UNLOAD_CHUNK({ PacketUnloadChunk(it) }), + PLAY_CHANGE_GAME_STATE({ PacketChangeGameState(it) }), + PLAY_OPEN_HORSE_WINDOW({ PacketOpenHorseWindow(it) }), + PLAY_KEEP_ALIVE({ PacketKeepAlive(it) }), + PLAY_CHUNK_DATA({ PacketChunkData(it) }), + PLAY_EFFECT({ PacketEffect(it) }), + PLAY_PARTICLE({ PacketParticle(it) }), + PLAY_UPDATE_LIGHT({ PacketUpdateLight(it) }), + PLAY_JOIN_GAME({ PacketJoinGame(it) }, false, PacketJoinGame), + PLAY_MAP_DATA({ PacketMapData(it) }), + PLAY_TRADE_LIST({ PacketTradeList(it) }), + PLAY_ENTITY_MOVEMENT_AND_ROTATION({ PacketEntityMovementAndRotation(it) }), + PLAY_ENTITY_ROTATION({ PacketEntityRotation(it) }), + PLAY_ENTITY_MOVEMENT({ PacketEntityMovement(it) }), + PLAY_VEHICLE_MOVEMENT({ PacketVehicleMovement(it) }), + PLAY_OPEN_BOOK({ PacketOpenBook(it) }), + PLAY_OPEN_WINDOW({ PacketOpenWindow(it) }), + PLAY_OPEN_SIGN_EDITOR({ PacketOpenSignEditor(it) }), + PLAY_CRAFT_RECIPE_RESPONSE({ PacketCraftRecipeResponse(it) }), + PLAY_PLAYER_ABILITIES({ PacketPlayerAbilitiesReceiving(it) }), + PLAY_COMBAT_EVENT({ PacketCombatEvent(it) }), + PLAY_PLAYER_LIST_ITEM({ PacketPlayerListItem(it) }), + PLAY_FACE_PLAYER({ PacketFacePlayer(it) }), + PLAY_PLAYER_POSITION_AND_ROTATION({ PacketPlayerPositionAndRotation(it) }), + PLAY_UNLOCK_RECIPES({ PacketUnlockRecipes(it) }), + PLAY_DESTROY_ENTITIES({ PacketDestroyEntity(it) }), + PLAY_REMOVE_ENTITY_EFFECT({ PacketRemoveEntityStatusEffect(it) }), + PLAY_RESOURCE_PACK_SEND({ PacketResourcePackSend(it) }), + PLAY_RESPAWN({ PacketRespawn(it) }, false), + PLAY_ENTITY_HEAD_ROTATION({ PacketEntityHeadRotation(it) }), + PLAY_SELECT_ADVANCEMENT_TAB({ PacketSelectAdvancementTab(it) }), + PLAY_WORLD_BORDER({ PacketWorldBorder(it) }), + PLAY_CAMERA({ PacketCamera(it) }), + PLAY_HELD_ITEM_CHANGE({ PacketHeldItemChangeReceiving(it) }), + PLAY_UPDATE_VIEW_POSITION({ PacketUpdateViewPosition(it) }), + PLAY_DISPLAY_SCOREBOARD({ PacketScoreboardDisplayScoreboard(it) }), + PLAY_ENTITY_METADATA({ PacketEntityMetadata(it) }), + PLAY_ATTACH_ENTITY({ PacketAttachEntity(it) }), + PLAY_ENTITY_VELOCITY({ PacketEntityVelocity(it) }), + PLAY_ENTITY_EQUIPMENT({ PacketEntityEquipment(it) }), + PLAY_SET_EXPERIENCE({ PacketSetExperience(it) }), + PLAY_UPDATE_HEALTH({ PacketUpdateHealth(it) }), + PLAY_SCOREBOARD_OBJECTIVE({ PacketScoreboardObjective(it) }), + PLAY_SET_PASSENGERS({ PacketSetPassenger(it) }), + PLAY_TEAMS({ PacketTeams(it) }), + PLAY_UPDATE_SCORE({ PacketScoreboardUpdateScore(it) }), + PLAY_SPAWN_POSITION({ PacketSpawnPosition(it) }), + PLAY_TIME_UPDATE({ PacketTimeUpdate(it) }), + PLAY_ENTITY_SOUND_EFFECT({ PacketEntitySoundEffect(it) }), + PLAY_SOUND_EFFECT({ PacketSoundEffect(it) }), + PLAY_STOP_SOUND({ PacketStopSound(it) }), + PLAY_PLAYER_LIST_HEADER_AND_FOOTER({ PacketTabHeaderAndFooter(it) }), + PLAY_NBT_QUERY_RESPONSE({ PacketNBTQueryResponse(it) }), + PLAY_COLLECT_ITEM({ PacketCollectItem(it) }), + PLAY_ENTITY_TELEPORT({ PacketEntityTeleport(it) }, false), + PLAY_ADVANCEMENTS({ PacketAdvancements(it) }), + PLAY_ENTITY_PROPERTIES({ PacketEntityProperties(it) }), + PLAY_ENTITY_EFFECT({ PacketEntityEffect(it) }), + PLAY_DECLARE_RECIPES({ PacketDeclareRecipes(it) }), + PLAY_TAGS({ PacketTags(it) }), + PLAY_USE_BED({ PacketUseBed(it) }), + PLAY_UPDATE_VIEW_DISTANCE({ PacketUpdateViewDistance(it) }), + PLAY_CHUNK_BULK({ PacketChunkBulk(it) }), + PLAY_UPDATE_SIGN({ PacketUpdateSignReceiving(it) }), + PLAY_STATISTICS({ PacketStatistics(it) }), + PLAY_SPAWN_ENTITY({ PacketSpawnObject(it) }, false), + PLAY_TITLE({ PacketTitle(it) }), + PLAY_ENTITY_INITIALISATION({ PacketEntityInitialisation(it) }, false), + PLAY_SET_COMPRESSION({ PacketSetCompression(it) }, false), + PLAY_ADVANCEMENT_PROGRESS({ TODO() }), + PLAY_SCULK_VIBRATION_SIGNAL({ PacketSculkVibrationSignal(it) }), + ; + + + val state: ConnectionStates = ConnectionStates.valueOf(name.split("_".toRegex()).toTypedArray()[0]) + } +} diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt index 95968c666..315bebd3e 100644 --- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft.util import de.bixilon.minosoft.util.enum.AliasableEnum +import java.util.* object KUtil { @@ -32,4 +33,8 @@ object KUtil { return ret.toMap() } + + fun bitSetOf(long: Long): BitSet { + return BitSet.valueOf(longArrayOf(long)) + } } diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt index 09121a405..eaef7467e 100644 --- a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt @@ -22,14 +22,14 @@ import java.util.* object LightUtil { - fun readLightPacket(buffer: InByteBuffer, skyLightMask: LongArray, blockLightMask: LongArray, emptyBlockLightMask: LongArray, emptySkyLightMask: LongArray, dimension: Dimension): LightAccessor { + fun readLightPacket(buffer: InByteBuffer, skyLightMask: BitSet, blockLightMask: BitSet, emptyBlockLightMask: BitSet, emptySkyLightMask: BitSet, dimension: Dimension): LightAccessor { // ToDo val skyLight = if (dimension.hasSkyLight) { - readLightArray(buffer, BitSet.valueOf(skyLightMask), dimension) + readLightArray(buffer, skyLightMask, dimension) } else { mutableMapOf() } - val blockLight = readLightArray(buffer, BitSet.valueOf(blockLightMask), dimension) + val blockLight = readLightArray(buffer, blockLightMask, dimension) return ChunkLightAccessor(blockLight, skyLight) }