refactor PacketTypes, clear kotlin packets structure

This commit is contained in:
Bixilon 2021-03-30 23:18:54 +02:00
parent 9089cecbfe
commit f2cfe4bf9b
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
13 changed files with 313 additions and 301 deletions

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.protocol
import de.bixilon.minosoft.protocol.network.Connection
interface ErrorHandler {
fun onError(connection: Connection) {}
}

View File

@ -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())); 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); throw new PacketNotImplementedException(data, packetType, this.connection);
} }
ClientboundPacket packet; ClientboundPacket packet;
try { try {
packet = instanceCreator.createNewInstance(data); packet = factory.invoke(data);
if (data.getBytesLeft() > 0) { 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())); 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); packet.check(this.connection);
} catch (Throwable exception) { } catch (Throwable exception) {
// ToDo: packet.onError(this.connection); var errorHandler = packetType.getErrorHandler();
if (errorHandler != null) {
errorHandler.onError(this.connection);
}
throw exception; throw exception;
} }
return new Pair<>(packetType, packet); return new Pair<>(packetType, packet);

View File

@ -18,7 +18,5 @@ abstract class ClientboundPacket : Packet {
open fun handle(connection: Connection) {} open fun handle(connection: Connection) {}
open fun onError(connection: Connection) {}
open fun check(connection: Connection) {} open fun check(connection: Connection) {}
} }

View File

@ -18,11 +18,10 @@ import de.bixilon.minosoft.protocol.packets.ClientboundPacket
import de.bixilon.minosoft.protocol.protocol.InByteBuffer import de.bixilon.minosoft.protocol.protocol.InByteBuffer
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
class PacketHeldItemChangeReceiving() : ClientboundPacket() { class PacketHeldItemChangeReceiving(buffer: InByteBuffer) : ClientboundPacket() {
var slot = 0 val slot: Int
private set
constructor(buffer: InByteBuffer) : this() { init {
slot = buffer.readByte().toInt() slot = buffer.readByte().toInt()
} }

View File

@ -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.data.world.biome.accessor.NoiseBiomeAccessor
import de.bixilon.minosoft.gui.rendering.util.VecUtil import de.bixilon.minosoft.gui.rendering.util.VecUtil
import de.bixilon.minosoft.modding.event.events.JoinGameEvent 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.network.Connection
import de.bixilon.minosoft.protocol.packets.ClientboundPacket import de.bixilon.minosoft.protocol.packets.ClientboundPacket
import de.bixilon.minosoft.protocol.protocol.InByteBuffer 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 de.bixilon.minosoft.util.nbt.tag.NBTTag
import kotlin.experimental.and import kotlin.experimental.and
class PacketJoinGame() : ClientboundPacket() { class PacketJoinGame(buffer: InByteBuffer) : ClientboundPacket() {
var entityId: Int = 0 val entityId: Int
var isHardcore: Boolean = false var isHardcore: Boolean = false
var gamemode: Gamemodes = Gamemodes.SPECTATOR var gamemode: Gamemodes = Gamemodes.SPECTATOR
var dimension: Dimension? = null var dimension: Dimension? = null
@ -50,7 +51,7 @@ class PacketJoinGame() : ClientboundPacket() {
var hashedSeed: Long = 0L var hashedSeed: Long = 0L
var dimensions: HashBiMap<ResourceLocation, Dimension> = HashBiMap.create() var dimensions: HashBiMap<ResourceLocation, Dimension> = HashBiMap.create()
constructor(buffer: InByteBuffer) : this() { init {
entityId = buffer.readInt() entityId = buffer.readInt()
if (buffer.versionId < V_20W27A) { if (buffer.versionId < V_20W27A) {
@ -70,10 +71,9 @@ class PacketJoinGame() : ClientboundPacket() {
if (buffer.versionId >= ProtocolVersions.V_13W42B) { if (buffer.versionId >= ProtocolVersions.V_13W42B) {
levelType = LevelTypes.byType(buffer.readString()) levelType = LevelTypes.byType(buffer.readString())
} }
if (buffer.versionId < ProtocolVersions.V_14W29A) { if (buffer.versionId >= ProtocolVersions.V_14W29A) {
return isReducedDebugScreen = buffer.readBoolean()
} }
isReducedDebugScreen = buffer.readBoolean()
} }
if (buffer.versionId >= ProtocolVersions.V_1_16_PRE6) { if (buffer.versionId >= ProtocolVersions.V_1_16_PRE6) {
@ -124,7 +124,6 @@ class PacketJoinGame() : ClientboundPacket() {
if (buffer.versionId >= ProtocolVersions.V_19W36A) { if (buffer.versionId >= ProtocolVersions.V_19W36A) {
isEnableRespawnScreen = buffer.readBoolean() isEnableRespawnScreen = buffer.readBoolean()
} }
return
} }
override fun handle(connection: Connection) { 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)) 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) { companion object : ErrorHandler {
connection.disconnect()
override fun onError(connection: Connection) {
connection.disconnect()
}
} }
} }

View File

@ -24,17 +24,24 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.nbt.tag.CompoundTag import de.bixilon.minosoft.util.nbt.tag.CompoundTag
class PacketRespawn() : ClientboundPacket() { class PacketRespawn(buffer: InByteBuffer) : ClientboundPacket() {
var dimension: Dimension? = null lateinit var dimension: Dimension
var difficulty: Difficulties? = null private set
var gamemode: Gamemodes? = null var difficulty: Difficulties = Difficulties.NORMAL
var levelType: LevelTypes? = null private set
var hashedSeed: Long = 0 val gamemode: Gamemodes
var levelType: LevelTypes = LevelTypes.UNKNOWN
private set
var hashedSeed = 0L
private set
var isDebug = false var isDebug = false
private set
var isFlat = false var isFlat = false
private set
var copyMetaData = false var copyMetaData = false
private set
constructor(buffer: InByteBuffer) : this() { init {
when { when {
buffer.versionId < ProtocolVersions.V_20W21A -> { 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. 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 -> { 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 -> { else -> {
buffer.readNBT() as CompoundTag // current dimension data buffer.readNBT() as CompoundTag // current dimension data
@ -54,7 +61,7 @@ class PacketRespawn() : ClientboundPacket() {
difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt()) difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt())
} }
if (buffer.versionId >= ProtocolVersions.V_20W22A) { 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) { if (buffer.versionId >= ProtocolVersions.V_19W36A) {
hashedSeed = buffer.readLong() hashedSeed = buffer.readLong()

View File

@ -19,11 +19,12 @@ import de.bixilon.minosoft.protocol.protocol.InByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
class PacketServerDifficulty() : ClientboundPacket() { class PacketServerDifficulty(buffer: InByteBuffer) : ClientboundPacket() {
lateinit var difficulty: Difficulties val difficulty: Difficulties
var locked = false var locked = false
private set
constructor(buffer: InByteBuffer) : this() { init {
difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt()) difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt())
if (buffer.versionId > ProtocolVersions.V_19W11A) { if (buffer.versionId > ProtocolVersions.V_19W11A) {
locked = buffer.readBoolean() locked = buffer.readBoolean()

View File

@ -19,37 +19,41 @@ import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.packets.ClientboundPacket import de.bixilon.minosoft.protocol.packets.ClientboundPacket
import de.bixilon.minosoft.protocol.protocol.InByteBuffer import de.bixilon.minosoft.protocol.protocol.InByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions 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.chunk.LightUtil.readLightPacket
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
import glm_.vec2.Vec2i import glm_.vec2.Vec2i
import java.util.*
class PacketUpdateLight() : ClientboundPacket() { class PacketUpdateLight(buffer: InByteBuffer) : ClientboundPacket() {
private var position: Vec2i? = null val position: Vec2i
private var lightAccessor: LightAccessor? = null var trustEdges: Boolean = false
private set
val lightAccessor: LightAccessor
constructor(buffer: InByteBuffer) : this() { init {
position = Vec2i(buffer.readVarInt(), buffer.readVarInt()) position = Vec2i(buffer.readVarInt(), buffer.readVarInt())
if (buffer.versionId >= ProtocolVersions.V_1_16_PRE3) { if (buffer.versionId >= ProtocolVersions.V_1_16_PRE3) {
val trustEdges = buffer.readBoolean() 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()
} }
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!!) lightAccessor = readLightPacket(buffer, skyLightMask, blockLightMask, emptyBlockLightMask, emptySkyLightMask, buffer.connection.player.world.dimension!!)
} }
@ -59,12 +63,12 @@ class PacketUpdateLight() : ClientboundPacket() {
} }
override fun handle(connection: Connection) { 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) { 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 { } else {
chunk.lightAccessor = lightAccessor chunk.lightAccessor = lightAccessor
} }
connection.renderer.renderWindow.worldRenderer.prepareChunk(position!!, chunk) connection.renderer.renderWindow.worldRenderer.prepareChunk(position, chunk)
} }
} }

View File

@ -21,8 +21,8 @@ import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.enum.ValuesEnum import de.bixilon.minosoft.util.enum.ValuesEnum
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
class PacketTitle() : ClientboundPacket() { class PacketTitle(buffer: InByteBuffer) : ClientboundPacket() {
lateinit var action: TitleActions val action: TitleActions
// fields depend on action // fields depend on action
var text: ChatComponent? = null var text: ChatComponent? = null
@ -31,7 +31,7 @@ class PacketTitle() : ClientboundPacket() {
var stayTime = 0 var stayTime = 0
var fadeOutTime = 0 var fadeOutTime = 0
constructor(buffer: InByteBuffer) : this() { init {
action = buffer.connection.mapping.titleActionsRegistry.get(buffer.readVarInt())!! action = buffer.connection.mapping.titleActionsRegistry.get(buffer.readVarInt())!!
when (action) { when (action) {
TitleActions.SET_TITLE -> this.text = buffer.readChatComponent() TitleActions.SET_TITLE -> this.text = buffer.readChatComponent()

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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])
}
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.util package de.bixilon.minosoft.util
import de.bixilon.minosoft.util.enum.AliasableEnum import de.bixilon.minosoft.util.enum.AliasableEnum
import java.util.*
object KUtil { object KUtil {
@ -32,4 +33,8 @@ object KUtil {
return ret.toMap() return ret.toMap()
} }
fun bitSetOf(long: Long): BitSet {
return BitSet.valueOf(longArrayOf(long))
}
} }

View File

@ -22,14 +22,14 @@ import java.util.*
object LightUtil { 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 // ToDo
val skyLight = if (dimension.hasSkyLight) { val skyLight = if (dimension.hasSkyLight) {
readLightArray(buffer, BitSet.valueOf(skyLightMask), dimension) readLightArray(buffer, skyLightMask, dimension)
} else { } else {
mutableMapOf() mutableMapOf()
} }
val blockLight = readLightArray(buffer, BitSet.valueOf(blockLightMask), dimension) val blockLight = readLightArray(buffer, blockLightMask, dimension)
return ChunkLightAccessor(blockLight, skyLight) return ChunkLightAccessor(blockLight, skyLight)
} }