update via + try to cleanup some 1.7 protocol

This commit is contained in:
creeper123123321 2021-03-31 15:58:23 -03:00
parent 1b327b1a2b
commit 883c88727b
16 changed files with 1422 additions and 1333 deletions

View File

@ -45,8 +45,8 @@ repositories {
}
dependencies {
implementation("us.myles:viaversion:3.3.0-21w11a") { isTransitive = false }
implementation("nl.matsv:viabackwards:3.3.0-21w11a") { isTransitive = false }
implementation("us.myles:viaversion:3.3.0-21w13a") { isTransitive = false }
implementation("nl.matsv:viabackwards:3.3.0-21w13a") { isTransitive = false }
implementation("com.github.ViaVersion.ViaRewind:viarewind-all:dev-SNAPSHOT") { isTransitive = false }
implementation("io.netty:netty-all:4.1.61.Final")
implementation("org.yaml:snakeyaml:1.28")

View File

@ -12,6 +12,7 @@ import io.netty.channel.ChannelFutureListener
import io.netty.handler.codec.DecoderException
import org.slf4j.LoggerFactory
import us.myles.ViaVersion.api.protocol.ProtocolVersion
import us.myles.ViaVersion.api.type.Type
import java.math.BigInteger
import java.net.InetAddress
import java.net.InetSocketAddress
@ -152,7 +153,7 @@ fun writeFlushClose(ch: Channel, obj: Any) {
ch.writeAndFlush(obj).addListener(ChannelFutureListener.CLOSE)
}
fun readableToByteArray(byteBuf: ByteBuf) = ByteArray(byteBuf.readableBytes()).also { byteBuf.readBytes(it) }
fun readRemainingBytes(byteBuf: ByteBuf) = Type.REMAINING_BYTES.read(byteBuf)
suspend fun hasJoined(username: String, hash: String): JsonObject {
return httpClient.get(

View File

@ -9,7 +9,7 @@ import com.github.creeper123123321.viaaas.packet.UnknownPacket
import com.github.creeper123123321.viaaas.packet.play.Kick
import com.github.creeper123123321.viaaas.packet.play.PluginMessage
import com.github.creeper123123321.viaaas.parseProtocol
import com.github.creeper123123321.viaaas.readableToByteArray
import com.github.creeper123123321.viaaas.readRemainingBytes
import com.github.creeper123123321.viaaas.writeFlushClose
import com.google.gson.JsonPrimitive
import io.netty.buffer.ByteBufAllocator
@ -47,7 +47,7 @@ object PlayState : MinecraftConnectionState {
val buf = ByteBufAllocator.DEFAULT.buffer()
try {
Type.STRING.write(buf, brand)
pluginMessage.data = readableToByteArray(buf)
pluginMessage.data = readRemainingBytes(buf)
} finally {
buf.release()
}

View File

@ -1,13 +1,13 @@
package com.github.creeper123123321.viaaas.packet
import com.github.creeper123123321.viaaas.readableToByteArray
import com.github.creeper123123321.viaaas.readRemainingBytes
import io.netty.buffer.ByteBuf
class UnknownPacket(val id: Int) : Packet {
lateinit var content: ByteArray
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
content = readableToByteArray(byteBuf)
content = readRemainingBytes(byteBuf)
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {

View File

@ -1,7 +1,7 @@
package com.github.creeper123123321.viaaas.packet.login
import com.github.creeper123123321.viaaas.packet.Packet
import com.github.creeper123123321.viaaas.readableToByteArray
import com.github.creeper123123321.viaaas.readRemainingBytes
import io.netty.buffer.ByteBuf
import us.myles.ViaVersion.api.type.Type
import kotlin.properties.Delegates
@ -13,7 +13,7 @@ class PluginRequest : Packet {
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
id = Type.VAR_INT.readPrimitive(byteBuf)
channel = Type.STRING.read(byteBuf)
data = readableToByteArray(byteBuf)
data = readRemainingBytes(byteBuf)
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {

View File

@ -1,7 +1,7 @@
package com.github.creeper123123321.viaaas.packet.login
import com.github.creeper123123321.viaaas.packet.Packet
import com.github.creeper123123321.viaaas.readableToByteArray
import com.github.creeper123123321.viaaas.readRemainingBytes
import io.netty.buffer.ByteBuf
import us.myles.ViaVersion.api.type.Type
import kotlin.properties.Delegates
@ -14,7 +14,7 @@ class PluginResponse : Packet {
id = Type.VAR_INT.readPrimitive(byteBuf)
success = byteBuf.readBoolean()
if (success) {
data = readableToByteArray(byteBuf)
data = readRemainingBytes(byteBuf)
}
}

View File

@ -1,7 +1,7 @@
package com.github.creeper123123321.viaaas.packet.play
import com.github.creeper123123321.viaaas.packet.Packet
import com.github.creeper123123321.viaaas.readableToByteArray
import com.github.creeper123123321.viaaas.readRemainingBytes
import io.netty.buffer.ByteBuf
import us.myles.ViaVersion.api.protocol.ProtocolVersion
import us.myles.ViaVersion.api.type.Type
@ -15,7 +15,7 @@ class PluginMessage : Packet {
data = if (protocolVersion <= ProtocolVersion.v1_7_6.version) {
ByteArray(readExtendedForgeShort(byteBuf)).also { byteBuf.readBytes(it) }
} else {
readableToByteArray(byteBuf)
readRemainingBytes(byteBuf)
}
}

View File

@ -1,7 +1,10 @@
package com.github.creeper123123321.viaaas.protocol
import us.myles.ViaVersion.api.PacketWrapper
import us.myles.ViaVersion.api.minecraft.Position
import us.myles.ViaVersion.api.remapper.ValueReader
import us.myles.ViaVersion.api.remapper.ValueTransformer
import us.myles.ViaVersion.api.remapper.ValueWriter
import us.myles.ViaVersion.api.type.Type
val INSERT_DASHES: ValueTransformer<String, String> = object : ValueTransformer<String, String>(Type.STRING) {
@ -13,4 +16,33 @@ val INSERT_DASHES: ValueTransformer<String, String> = object : ValueTransformer<
builder.insert(8, "-")
return builder.toString()
}
}
val xyzToPosition = ValueReader { packetWrapper: PacketWrapper ->
val x = packetWrapper.read(Type.INT)
val y = packetWrapper.read(Type.INT).toShort()
val z = packetWrapper.read(Type.INT)
Position(x, y, z)
}
val xyzUBytePos = ValueReader { packetWrapper: PacketWrapper ->
val x = packetWrapper.read(Type.INT)
val y = packetWrapper.read(Type.UNSIGNED_BYTE)
val z = packetWrapper.read(Type.INT)
Position(x, y, z)
}
val xyzUBytePosWriter: ValueWriter<Position> = ValueWriter<Position> { packetWrapper: PacketWrapper, pos: Position ->
packetWrapper.write(Type.INT, pos.x.toInt())
packetWrapper.write(Type.UNSIGNED_BYTE, pos.y.toShort())
packetWrapper.write(Type.INT, pos.z.toInt())
}
val xyzShortPosWriter: ValueWriter<Position> = ValueWriter<Position> { packetWrapper: PacketWrapper, pos: Position ->
packetWrapper.write(Type.INT, pos.x.toInt())
packetWrapper.write(Type.SHORT, pos.y.toShort())
packetWrapper.write(Type.INT, pos.z.toInt())
}
val xyzShortPos: ValueReader<Position> = ValueReader<Position> { packetWrapper: PacketWrapper ->
val x = packetWrapper.read(Type.INT)
val y = packetWrapper.read(Type.SHORT)
val z = packetWrapper.read(Type.INT)
Position(x, y, z)
}

View File

@ -1,16 +1,30 @@
package com.github.creeper123123321.viaaas.protocol.id47toid5.chunks
class Chunk1_8to1_7_6_10(data: ByteArray?, private val primaryBitMask: Int, addBitMask: Int, private val skyLight: Boolean, private val groundUp: Boolean) {
import com.github.creeper123123321.viaaas.readRemainingBytes
import io.netty.buffer.ByteBufAllocator
class Chunk1_8to1_7_6_10(
data: ByteArray?,
private val primaryBitMask: Int,
addBitMask: Int,
private val skyLight: Boolean,
private val groundUp: Boolean
) {
var storageArrays = arrayOfNulls<ExtendedBlockStorage>(16)
var blockBiomeArray = ByteArray(256)
fun filterChunk(storageArray: ExtendedBlockStorage?, i: Int) =
storageArray != null && primaryBitMask and 1 shl i != 0
&& (!groundUp || storageArray.isEmpty)
fun get1_8Data(): ByteArray {
var finalSize = 0
val columns = Integer.bitCount(primaryBitMask)
val buffer = ByteArray(columns * 10240 + (if (skyLight) columns * 2048 else 0) + 256)
for (i in storageArrays.indices) {
if (storageArrays[i] != null && primaryBitMask and 1 shl i != 0 && (!groundUp || storageArrays[i]!!.isEmpty)) {
val blockIds = storageArrays[i]!!.blockLSBArray
val nibblearray = storageArrays[i]!!.metadataArray
val buf = ByteBufAllocator.DEFAULT.buffer()
try {
var finalSize = 0
val filteredChunks = storageArrays.filterIndexed { i, value -> filterChunk(value, i) }.filterNotNull()
filteredChunks.forEach {
val blockIds = it.blockLSBArray
val nibblearray = it.metadataArray
for (ind in blockIds.indices) {
val id = blockIds[ind].toInt() and 255
val px = ind and 15
@ -20,34 +34,25 @@ class Chunk1_8to1_7_6_10(data: ByteArray?, private val primaryBitMask: Int, addB
//data = SpigotDebreakifier.getCorrectedData(id, data);
val `val` = (id shl 4 or data).toChar()
buffer[finalSize++] = (`val`.toInt() and 255).toByte()
buffer[finalSize++] = (`val`.toInt() shr 8 and 255).toByte()
buf.writeByte(`val`.toInt() and 255)
buf.writeByte(`val`.toInt() shr 8 and 255)
}
}
}
for (i in storageArrays.indices) {
if (storageArrays[i] != null && primaryBitMask and 1 shl i != 0 && (!groundUp || storageArrays[i]!!.isEmpty)) {
val nibblearray = storageArrays[i]!!.blocklightArray
System.arraycopy(nibblearray.handle, 0, buffer, finalSize, nibblearray.handle.size)
finalSize += nibblearray.handle.size
filteredChunks.forEach {
buf.writeBytes(it.blocklightArray.handle)
}
}
if (skyLight) {
for (i in storageArrays.indices) {
if (storageArrays[i] != null && primaryBitMask and 1 shl i != 0 && (!groundUp || storageArrays[i]!!.isEmpty)) {
val nibblearray = storageArrays[i]!!.skylightArray
System.arraycopy(nibblearray!!.handle, 0, buffer, finalSize, nibblearray!!.handle.size)
finalSize += nibblearray!!.handle.size
if (skyLight) {
filteredChunks.forEach {
buf.writeBytes(it.skylightArray!!.handle)
}
}
if (groundUp) {
buf.writeBytes(blockBiomeArray)
}
return readRemainingBytes(buf)
} finally {
buf.release()
}
if (groundUp) {
System.arraycopy(blockBiomeArray, 0, buffer, finalSize, blockBiomeArray.size)
finalSize += blockBiomeArray.size
}
val finaldata = ByteArray(finalSize)
System.arraycopy(buffer, 0, finaldata, 0, finalSize)
return finaldata
}
init {
@ -56,8 +61,8 @@ class Chunk1_8to1_7_6_10(data: ByteArray?, private val primaryBitMask: Int, addB
if (primaryBitMask and 1 shl i != 0) {
if (storageArrays[i] == null) storageArrays[i] = ExtendedBlockStorage(i shl 4, skyLight)
val blockIds = storageArrays[i]!!.blockLSBArray
System.arraycopy(data, dataSize, blockIds, 0, blockIds!!.size)
dataSize += blockIds!!.size
System.arraycopy(data, dataSize, blockIds, 0, blockIds.size)
dataSize += blockIds.size
} else if (storageArrays[i] != null && groundUp) {
storageArrays[i] = null
}
@ -65,23 +70,23 @@ class Chunk1_8to1_7_6_10(data: ByteArray?, private val primaryBitMask: Int, addB
for (i in storageArrays.indices) {
if (primaryBitMask and 1 shl i != 0 && storageArrays[i] != null) {
val nibblearray = storageArrays[i]!!.metadataArray
System.arraycopy(data, dataSize, nibblearray!!.handle, 0, nibblearray!!.handle.size)
dataSize += nibblearray!!.handle.size
System.arraycopy(data, dataSize, nibblearray.handle, 0, nibblearray.handle.size)
dataSize += nibblearray.handle.size
}
}
for (i in storageArrays.indices) {
if (primaryBitMask and 1 shl i != 0 && storageArrays[i] != null) {
val nibblearray = storageArrays[i]!!.blocklightArray
System.arraycopy(data, dataSize, nibblearray!!.handle, 0, nibblearray!!.handle.size)
dataSize += nibblearray!!.handle.size
System.arraycopy(data, dataSize, nibblearray.handle, 0, nibblearray.handle.size)
dataSize += nibblearray.handle.size
}
}
if (skyLight) {
for (i in storageArrays.indices) {
if (primaryBitMask and 1 shl i != 0 && storageArrays[i] != null) {
val nibblearray = storageArrays[i]!!.skylightArray
System.arraycopy(data, dataSize, nibblearray!!.handle, 0, nibblearray!!.handle.size)
dataSize += nibblearray!!.handle.size
System.arraycopy(data, dataSize, nibblearray!!.handle, 0, nibblearray.handle.size)
dataSize += nibblearray.handle.size
}
}
}
@ -94,8 +99,8 @@ class Chunk1_8to1_7_6_10(data: ByteArray?, private val primaryBitMask: Int, addB
if (nibblearray == null) {
nibblearray = storageArrays[i]!!.createBlockMSBArray()
}
System.arraycopy(data, dataSize, nibblearray!!.handle, 0, nibblearray!!.handle.size)
dataSize += nibblearray!!.handle.size
System.arraycopy(data, dataSize, nibblearray!!.handle, 0, nibblearray.handle.size)
dataSize += nibblearray.handle.size
}
} else if (groundUp && storageArrays[i] != null && storageArrays[i]!!.blockMSBArray != null) {
storageArrays[i]!!.clearMSBArray()

View File

@ -60,7 +60,7 @@ object ChunkPacketTransformer {
buffer.writeBoolean(groundUp)
buffer.writeShort(primaryBitMask)
val finaldata = chunk.get1_8Data()
Type.VAR_INT.write(buffer, finaldata.size)
Type.VAR_INT.writePrimitive(buffer, finaldata.size)
buffer.writeBytes(finaldata)
}
@ -117,7 +117,7 @@ object ChunkPacketTransformer {
i++
}
packetWrapper.write(Type.BOOLEAN, skyLightSent)
packetWrapper.write(Type.VAR_INT, columnCount as Int)
packetWrapper.write(Type.VAR_INT, columnCount)
i = 0
while (i < columnCount) {
packetWrapper.write(Type.INT, chunkX[i])

View File

@ -0,0 +1,401 @@
package com.github.creeper123123321.viaaas.protocol.id47toid5.packets
import com.github.creeper123123321.viaaas.protocol.id47toid5.Protocol1_8To1_7_6
import com.github.creeper123123321.viaaas.protocol.id47toid5.metadata.MetadataRewriter
import com.github.creeper123123321.viaaas.protocol.id47toid5.storage.EntityTracker
import com.github.creeper123123321.viaaas.protocol.id47toid5.type.CustomIntType
import com.github.creeper123123321.viaaas.protocol.xyzToPosition
import de.gerrygames.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10
import us.myles.ViaVersion.api.entities.Entity1_10Types
import us.myles.ViaVersion.api.remapper.PacketRemapper
import us.myles.ViaVersion.api.remapper.TypeRemapper
import us.myles.ViaVersion.api.type.Type
import us.myles.ViaVersion.api.type.types.version.Types1_8
import us.myles.ViaVersion.packets.State
import kotlin.experimental.and
fun Protocol1_8To1_7_6.registerEntityPackets() {
//Entity Equipment
this.registerOutgoing(State.PLAY, 0x04, 0x04, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.SHORT) //Slot
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM) //Item
}
})
//Animation
this.registerOutgoing(State.PLAY, 0x0B, 0x0B, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val entityId: Int = packetWrapper.read(Type.VAR_INT) //Entity Id
val animation: Short = packetWrapper.read(Type.UNSIGNED_BYTE) //Animation
packetWrapper.clearInputBuffer()
if (animation.toInt() == 104 || animation.toInt() == 105) {
packetWrapper.id = 0x1C //Entity Metadata
packetWrapper.write(Type.VAR_INT, entityId) //Entity Id
packetWrapper.write(Type.UNSIGNED_BYTE, 0.toShort()) //Index
packetWrapper.write(Type.UNSIGNED_BYTE, 0.toShort()) //Type
packetWrapper.write(Type.BYTE, (if (animation.toInt() == 104) 0x02 else 0x00).toByte()) //Value (sneaking/not sneaking)
packetWrapper.write(Type.UNSIGNED_BYTE, 255.toShort()) //end
} else {
packetWrapper.write(Type.VAR_INT, entityId) //Entity Id
packetWrapper.write(Type.UNSIGNED_BYTE, animation) //Animation
}
}
}
})
//Collect Item
this.registerOutgoing(State.PLAY, 0x0D, 0x0D, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Collected Entity ID
map(Type.INT, Type.VAR_INT) //Collector Entity ID
}
})
//Spawn Object
this.registerOutgoing(State.PLAY, 0x0E, 0x0E, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT)
map(Type.BYTE)
map(Type.INT)
map(Type.INT)
map(Type.INT)
map(Type.BYTE)
map(Type.BYTE)
map(Type.INT)
handler { packetWrapper ->
val type: Byte = packetWrapper.get(Type.BYTE, 0)
var x: Int = packetWrapper.get(Type.INT, 0)
var y: Int = packetWrapper.get(Type.INT, 1)
var z: Int = packetWrapper.get(Type.INT, 2)
var yaw: Byte = packetWrapper.get(Type.BYTE, 2)
var data: Int = packetWrapper.get(Type.INT, 3)
if (type.toInt() == 71) {
when (data) {
0 -> {
z += 32
yaw = 0
}
1 -> {
x -= 32
yaw = 64.toByte()
}
2 -> {
z -= 32
yaw = 128.toByte()
}
3 -> {
x += 32
yaw = 192.toByte()
}
}
}
if (type.toInt() == 70) {
val id = data
val metadata = data shr 16
data = id or metadata shl 12
}
if (type.toInt() == 50 || type.toInt() == 70 || type.toInt() == 74) y -= 16
packetWrapper.set(Type.INT, 0, x)
packetWrapper.set(Type.INT, 1, y)
packetWrapper.set(Type.INT, 2, z)
packetWrapper.set(Type.BYTE, 2, yaw)
packetWrapper.set(Type.INT, 3, data)
}
handler { packetWrapper ->
val entityID: Int = packetWrapper.get(Type.VAR_INT, 0)
val typeID = packetWrapper.get(Type.BYTE, 0).toInt()
val tracker = packetWrapper.user().get(EntityTracker::class.java)!!
val type: Entity1_10Types.EntityType = Entity1_10Types.getTypeFromId(typeID, true)
tracker.clientEntityTypes[entityID] = type
tracker.sendMetadataBuffer(entityID)
}
}
})
//Spawn Mob
this.registerOutgoing(State.PLAY, 0x0F, 0x0F, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT)
map(Type.UNSIGNED_BYTE)
map(Type.INT)
map(Type.INT)
map(Type.INT)
map(Type.BYTE)
map(Type.BYTE)
map(Type.BYTE)
map(Type.SHORT)
map(Type.SHORT)
map(Type.SHORT)
map(Types1_7_6_10.METADATA_LIST, Types1_8.METADATA_LIST)
handler { packetWrapper ->
val entityID: Int = packetWrapper.get(Type.VAR_INT, 0)
val typeID = packetWrapper.get(Type.UNSIGNED_BYTE, 0).toInt()
val tracker = packetWrapper.user().get(EntityTracker::class.java)!!
tracker.clientEntityTypes.put(entityID, Entity1_10Types.getTypeFromId(typeID, false))
tracker.sendMetadataBuffer(entityID)
}
handler { wrapper ->
val metadataList = wrapper.get(Types1_8.METADATA_LIST, 0)
val entityID: Int = wrapper.get(Type.VAR_INT, 0)
val tracker = wrapper.user().get(EntityTracker::class.java)!!
if (tracker.clientEntityTypes.containsKey(entityID)) {
MetadataRewriter.transform(tracker.clientEntityTypes[entityID], metadataList)
} else {
wrapper.cancel()
}
}
}
})
//Spawn Painting
this.registerOutgoing(State.PLAY, 0x10, 0x10, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT) //Entity Id
map(Type.STRING) //Title
map(xyzToPosition, TypeRemapper(Type.POSITION)) //Position
map(Type.INT, Type.BYTE) //Rotation
handler { packetWrapper ->
val entityID = packetWrapper.get(Type.VAR_INT, 0)
val tracker = packetWrapper.user().get(EntityTracker::class.java)!!
tracker.clientEntityTypes.put(entityID, Entity1_10Types.EntityType.PAINTING)
tracker.sendMetadataBuffer(entityID)
}
}
})
//Spawn Experience Orb
this.registerOutgoing(State.PLAY, 0x11, 0x11, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT)
map(Type.INT)
map(Type.INT)
map(Type.INT)
map(Type.SHORT)
handler { packetWrapper ->
val entityID: Int = packetWrapper.get(Type.VAR_INT, 0)
val tracker = packetWrapper.user().get(EntityTracker::class.java)!!
tracker.clientEntityTypes.put(entityID, Entity1_10Types.EntityType.EXPERIENCE_ORB)
tracker.sendMetadataBuffer(entityID)
}
}
})
//Entity Velocity
this.registerOutgoing(State.PLAY, 0x12, 0x12, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.SHORT) //velX
map(Type.SHORT) //velY
map(Type.SHORT) //velZ
}
})
//Destroy Entities
this.registerOutgoing(State.PLAY, 0x13, 0x13, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val amount = packetWrapper.read(Type.BYTE).toInt()
val customIntType = CustomIntType(amount)
val entityIds = packetWrapper.read(customIntType)
packetWrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, entityIds)
} //Entity Id Array
handler { packetWrapper ->
val tracker = packetWrapper.user().get(EntityTracker::class.java)!!
for (entityId in packetWrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0)) tracker.removeEntity(entityId)
}
}
})
//Entity
this.registerOutgoing(State.PLAY, 0x14, 0x14, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
}
})
//Entity Relative Move
this.registerOutgoing(State.PLAY, 0x15, 0x15, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.BYTE) //x
map(Type.BYTE) //y
map(Type.BYTE) //z
create { packetWrapper ->
packetWrapper.write(Type.BOOLEAN, true) //OnGround
}
}
})
//Entity Look
this.registerOutgoing(State.PLAY, 0x16, 0x16, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.BYTE) //yaw
map(Type.BYTE) //pitch
create { packetWrapper ->
packetWrapper.write(Type.BOOLEAN, true) //OnGround
}
}
})
//Entity Look and Relative Move
this.registerOutgoing(State.PLAY, 0x17, 0x17, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.BYTE) //x
map(Type.BYTE) //y
map(Type.BYTE) //z
map(Type.BYTE) //yaw
map(Type.BYTE) //pitch
create { packetWrapper ->
packetWrapper.write(Type.BOOLEAN, true) //OnGround
}
}
})
//Entity Teleport
this.registerOutgoing(State.PLAY, 0x18, 0x18, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.INT) //x
map(Type.INT) //y
map(Type.INT) //z
map(Type.BYTE) //yaw
map(Type.BYTE) //pitch
create { packetWrapper ->
packetWrapper.write(Type.BOOLEAN, true) //OnGround
}
}
})
//Entity Head Look
this.registerOutgoing(State.PLAY, 0x19, 0x19, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.BYTE) //Head yaw
}
})
//Entity MetadataType
this.registerOutgoing(State.PLAY, 0x1C, 0x1C, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Types1_7_6_10.METADATA_LIST, Types1_8.METADATA_LIST) //MetadataType
handler { wrapper ->
val metadataList = wrapper.get(Types1_8.METADATA_LIST, 0)
val entityID: Int = wrapper.get(Type.VAR_INT, 0)
val tracker = wrapper.user().get(EntityTracker::class.java)!!
if (tracker.clientEntityTypes.containsKey(entityID)) {
MetadataRewriter.transform(tracker.clientEntityTypes[entityID], metadataList)
if (metadataList.isEmpty()) wrapper.cancel()
} else {
tracker.addMetadataToBuffer(entityID, metadataList)
wrapper.cancel()
}
}
}
})
//Entity Effect
this.registerOutgoing(State.PLAY, 0x1D, 0x1D, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.BYTE) //Effect Id
map(Type.BYTE) //Amplifier
map(Type.SHORT, Type.VAR_INT) //Duration
create { packetWrapper -> packetWrapper.write(Type.BOOLEAN, false) } //Hide Particles
}
})
//Remove Entity Effect
this.registerOutgoing(State.PLAY, 0x1E, 0x1E, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(Type.BYTE) //Effect Id
}
})
//Entity Properties
this.registerOutgoing(State.PLAY, 0x20, 0x20, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
handler { packetWrapper ->
val amount: Int = packetWrapper.read(Type.INT)
packetWrapper.write(Type.INT, amount)
for (i in 0 until amount) {
packetWrapper.passthrough(Type.STRING)
packetWrapper.passthrough(Type.DOUBLE)
val modifierlength = packetWrapper.read(Type.SHORT).toInt()
packetWrapper.write(Type.VAR_INT, modifierlength)
for (j in 0 until modifierlength) {
packetWrapper.passthrough(Type.UUID)
packetWrapper.passthrough(Type.DOUBLE)
packetWrapper.passthrough(Type.BYTE)
}
}
}
}
})
//Spawn Global Entity
this.registerOutgoing(State.PLAY, 0x2C, 0x2C, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT)
map(Type.BYTE)
map(Type.INT)
map(Type.INT)
map(Type.INT)
handler { packetWrapper ->
val entityID: Int = packetWrapper.get(Type.VAR_INT, 0)
val tracker = packetWrapper.user().get(EntityTracker::class.java)!!
tracker.clientEntityTypes[entityID] = Entity1_10Types.EntityType.LIGHTNING
tracker.sendMetadataBuffer(entityID)
}
}
})
//Use Entity
this.registerIncoming(State.PLAY, 0x02, 0x02, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT, Type.INT)
handler { packetWrapper ->
val mode: Int = packetWrapper.read(Type.VAR_INT)
if (mode == 2) {
packetWrapper.write(Type.BYTE, 0.toByte())
packetWrapper.read(Type.FLOAT)
packetWrapper.read(Type.FLOAT)
packetWrapper.read(Type.FLOAT)
} else {
packetWrapper.write(Type.BYTE, mode.toByte())
}
}
}
})
//Entity Action
this.registerIncoming(State.PLAY, 0x0B, 0x0B, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT, Type.INT) //Entity Id
handler { packetWrapper -> packetWrapper.write(Type.BYTE, (packetWrapper.read(Type.VAR_INT) + 1).toByte()) } //Action Id
map(Type.VAR_INT, Type.INT) //Action Paramter
}
})
//Steer Vehicle
this.registerIncoming(State.PLAY, 0x0C, 0x0C, object : PacketRemapper() {
override fun registerMap() {
map(Type.FLOAT) //Sideways
map(Type.FLOAT) //Forwards
handler { packetWrapper ->
val flags: Short = packetWrapper.read(Type.UNSIGNED_BYTE)
packetWrapper.write(Type.BOOLEAN, flags and 1 == 1.toShort()) //Jump
packetWrapper.write(Type.BOOLEAN, flags and 2 == 2.toShort()) //Unmount
}
}
})
}

View File

@ -0,0 +1,106 @@
package com.github.creeper123123321.viaaas.protocol.id47toid5.packets
import com.github.creeper123123321.viaaas.protocol.id47toid5.Protocol1_8To1_7_6
import com.github.creeper123123321.viaaas.protocol.id47toid5.storage.Windows
import de.gerrygames.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10
import us.myles.ViaVersion.api.minecraft.item.Item
import us.myles.ViaVersion.api.remapper.PacketRemapper
import us.myles.ViaVersion.api.type.Type
import us.myles.ViaVersion.packets.State
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8
import us.myles.viaversion.libs.kyori.adventure.text.Component
import us.myles.viaversion.libs.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
fun Protocol1_8To1_7_6.registerInventoryPackets() {
//Open Window
this.registerOutgoing(State.PLAY, 0x2D, 0x2D, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val windowId: Short = packetWrapper.read(Type.UNSIGNED_BYTE)
packetWrapper.write(Type.UNSIGNED_BYTE, windowId)
val windowType: Short = packetWrapper.read(Type.UNSIGNED_BYTE)
packetWrapper.user().get(Windows::class.java)!!.types[windowId] = windowType
packetWrapper.write(Type.STRING, getInventoryString(windowType.toInt())) //Inventory Type
var title: String = packetWrapper.read(Type.STRING) //Title
val slots: Short = packetWrapper.read(Type.UNSIGNED_BYTE)
val useProvidedWindowTitle: Boolean = packetWrapper.read(Type.BOOLEAN) //Use provided window title
title = if (useProvidedWindowTitle) {
Protocol1_9To1_8.fixJson(title).toString()
} else {
LegacyComponentSerializer.legacySection().serialize(Component.translatable(title)) // todo
}
packetWrapper.write(Type.STRING, title) //Window title
packetWrapper.write(Type.UNSIGNED_BYTE, slots)
if (packetWrapper.get(Type.UNSIGNED_BYTE, 0) == 11.toShort()) packetWrapper.passthrough(Type.INT) //Entity Id
}
}
})
//Set Slot
this.registerOutgoing(State.PLAY, 0x2F, 0x2F, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val windowId: Short = packetWrapper.read(Type.BYTE).toShort() //Window Id
val windowType: Short = packetWrapper.user().get(Windows::class.java)!!.get(windowId).toShort()
packetWrapper.write(Type.BYTE, windowId.toByte())
var slot = packetWrapper.read(Type.SHORT).toInt()
if (windowType.toInt() == 4 && slot >= 1) slot += 1
packetWrapper.write(Type.SHORT, slot.toShort()) //Slot
}
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM) //Item
}
})
//Window Items
this.registerOutgoing(State.PLAY, 0x30, 0x30, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val windowId: Short = packetWrapper.passthrough(Type.UNSIGNED_BYTE) //Window Id
val windowType: Short = packetWrapper.user().get(Windows::class.java)!![windowId]
var items = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY)
if (windowType.toInt() == 4) {
val old = items
items = arrayOfNulls(old.size + 1)
items[0] = old[0]
System.arraycopy(old, 1, items, 2, old.size - 1)
items[1] = Item(351, 3.toByte(), 4.toShort(), null)
}
packetWrapper.write(Type.ITEM_ARRAY, items) //Items
}
}
})
//Click Window
this.registerIncoming(State.PLAY, 0x0E, 0x0E, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val windowId: Short = packetWrapper.read(Type.UNSIGNED_BYTE) //Window Id
packetWrapper.write(Type.BYTE, windowId.toByte())
val windowType: Short = packetWrapper.user().get(Windows::class.java)!![windowId]
var slot: Int = packetWrapper.read(Type.SHORT).toInt()
if (windowType.toInt() == 4) {
if (slot == 1) {
packetWrapper.cancel()
} else if (slot > 1) {
slot -= 1
}
}
packetWrapper.write(Type.SHORT, slot.toShort()) //Slot
}
map(Type.BYTE) //Button
map(Type.SHORT) //Action Number
map(Type.BYTE) //Mode
map(Type.ITEM, Types1_7_6_10.COMPRESSED_NBT_ITEM)
}
})
//Creative Inventory Action
this.registerIncoming(State.PLAY, 0x10, 0x10, object : PacketRemapper() {
override fun registerMap() {
map(Type.SHORT) //Slot
map(Type.ITEM, Types1_7_6_10.COMPRESSED_NBT_ITEM) //Item
}
})
}

View File

@ -0,0 +1,38 @@
package com.github.creeper123123321.viaaas.protocol.id47toid5.packets
import com.github.creeper123123321.viaaas.protocol.id47toid5.Protocol1_8To1_7_6
import us.myles.ViaVersion.api.remapper.PacketRemapper
import us.myles.ViaVersion.api.type.Type
import us.myles.ViaVersion.api.type.types.CustomByteType
import us.myles.ViaVersion.packets.State
fun Protocol1_8To1_7_6.registerLoginPackets() {
//Encryption Request
this.registerOutgoing(State.LOGIN, 0x01, 0x01, object : PacketRemapper() {
override fun registerMap() {
map(Type.STRING) //Server ID
handler { packetWrapper ->
val publicKeyLength = packetWrapper.read(Type.SHORT).toInt()
packetWrapper.write(Type.VAR_INT, publicKeyLength)
packetWrapper.passthrough(CustomByteType(publicKeyLength))
val verifyTokenLength = packetWrapper.read(Type.SHORT).toInt()
packetWrapper.write(Type.VAR_INT, verifyTokenLength)
packetWrapper.passthrough(CustomByteType(verifyTokenLength))
}
}
})
//Encryption Response
this.registerIncoming(State.LOGIN, 0x01, 0x01, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val sharedSecretLength: Int = packetWrapper.read(Type.VAR_INT)
packetWrapper.write(Type.SHORT, sharedSecretLength.toShort())
packetWrapper.passthrough(CustomByteType(sharedSecretLength))
val verifyTokenLength: Int = packetWrapper.read(Type.VAR_INT)
packetWrapper.write(Type.SHORT, verifyTokenLength.toShort())
packetWrapper.passthrough(CustomByteType(verifyTokenLength))
}
}
})
}

View File

@ -0,0 +1,489 @@
package com.github.creeper123123321.viaaas.protocol.id47toid5.packets
import com.github.creeper123123321.viaaas.protocol.id47toid5.Protocol1_8To1_7_6
import com.github.creeper123123321.viaaas.protocol.id47toid5.metadata.MetadataRewriter
import com.github.creeper123123321.viaaas.protocol.id47toid5.storage.EntityTracker
import com.github.creeper123123321.viaaas.protocol.id47toid5.storage.Scoreboard
import com.github.creeper123123321.viaaas.protocol.id47toid5.storage.Tablist
import com.github.creeper123123321.viaaas.protocol.xyzToPosition
import com.github.creeper123123321.viaaas.protocol.xyzUBytePos
import com.google.common.base.Charsets
import de.gerrygames.viarewind.protocol.protocol1_7_6_10to1_8.types.CustomStringType
import de.gerrygames.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10
import de.gerrygames.viarewind.utils.ChatUtil
import io.netty.buffer.Unpooled
import us.myles.ViaVersion.api.PacketWrapper
import us.myles.ViaVersion.api.Via
import us.myles.ViaVersion.api.entities.Entity1_10Types
import us.myles.ViaVersion.api.minecraft.item.Item
import us.myles.ViaVersion.api.minecraft.metadata.Metadata
import us.myles.ViaVersion.api.remapper.PacketRemapper
import us.myles.ViaVersion.api.remapper.TypeRemapper
import us.myles.ViaVersion.api.type.Type
import us.myles.ViaVersion.api.type.types.CustomByteType
import us.myles.ViaVersion.api.type.types.version.Types1_8
import us.myles.ViaVersion.packets.State
import us.myles.ViaVersion.util.ChatColorUtil
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag
import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag
import java.nio.charset.StandardCharsets
import java.util.*
import kotlin.experimental.and
fun Protocol1_8To1_7_6.registerPlayerPackets() {
//Keep Alive
this.registerOutgoing(State.PLAY, 0x00, 0x00, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT)
}
})
//Join Game
this.registerOutgoing(State.PLAY, 0x01, 0x01, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT) //Entiy Id
map(Type.UNSIGNED_BYTE) //Gamemode
map(Type.BYTE) //Dimension
map(Type.UNSIGNED_BYTE) //Difficulty
map(Type.UNSIGNED_BYTE) //Max players
map(Type.STRING) //Level Type
create { packetWrapper ->
packetWrapper.write(Type.BOOLEAN, false) //Reduced Debug Info
}
}
})
//Chat Message
this.registerOutgoing(State.PLAY, 0x02, 0x02, object : PacketRemapper() {
override fun registerMap() {
map(Type.STRING) //Chat Message
create { packetWrapper ->
packetWrapper.write(Type.BYTE, 0.toByte()) //Position (chat box)
}
}
})
//Spawn Position
this.registerOutgoing(State.PLAY, 0x05, 0x05, object : PacketRemapper() {
override fun registerMap() {
map(xyzToPosition, TypeRemapper(Type.POSITION)) //Position
}
})
//Update Health
this.registerOutgoing(State.PLAY, 0x06, 0x06, object : PacketRemapper() {
override fun registerMap() {
map(Type.FLOAT) //Health
map(Type.SHORT, Type.VAR_INT) //Food
map(Type.FLOAT) //Food Saturation
}
})
//Player Position And Look
this.registerOutgoing(State.PLAY, 0x08, 0x08, object : PacketRemapper() {
override fun registerMap() {
map(Type.DOUBLE) //x
handler { packetWrapper ->
val y: Double = packetWrapper.read(Type.DOUBLE)
packetWrapper.write(Type.DOUBLE, y - 1.62) //y - fixed value
}
map(Type.DOUBLE) //z
map(Type.FLOAT) //pitch
map(Type.FLOAT) //yaw
handler { packetWrapper ->
packetWrapper.read(Type.BOOLEAN) //OnGround
packetWrapper.write(Type.BYTE, 0.toByte()) //BitMask
}
}
})
//Use Bed
this.registerOutgoing(State.PLAY, 0x0A, 0x0A, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT, Type.VAR_INT) //Entity Id
map(xyzUBytePos, TypeRemapper(Type.POSITION))
}
})
//Spawn Player
this.registerOutgoing(State.PLAY, 0x0C, 0x0C, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val entityId: Int = packetWrapper.passthrough(Type.VAR_INT) //Entity Id
val uuid = UUID.fromString(packetWrapper.read(Type.STRING)) //UUID
packetWrapper.write(Type.UUID, uuid)
val name: String = ChatColorUtil.stripColor(packetWrapper.read(Type.STRING)) //Name
val dataCount: Int = packetWrapper.read(Type.VAR_INT) //DataCunt
val properties = ArrayList<Tablist.Property>()
for (i in 0 until dataCount) {
val key: String = packetWrapper.read(Type.STRING) //Name
val value: String = packetWrapper.read(Type.STRING) //Value
val signature: String = packetWrapper.read(Type.STRING) //Signature
properties.add(Tablist.Property(key, value, signature))
}
val x: Int = packetWrapper.passthrough(Type.INT) //x
val y: Int = packetWrapper.passthrough(Type.INT) //y
val z: Int = packetWrapper.passthrough(Type.INT) //z
val yaw: Byte = packetWrapper.passthrough(Type.BYTE) //yaw
val pitch: Byte = packetWrapper.passthrough(Type.BYTE) //pitch
val item: Short = packetWrapper.passthrough(Type.SHORT) //Item in hand
val metadata = packetWrapper.read(Types1_7_6_10.METADATA_LIST) //Metadata
MetadataRewriter.transform(Entity1_10Types.EntityType.PLAYER, metadata)
packetWrapper.write<List<Metadata>>(Types1_8.METADATA_LIST, metadata)
val tablist = packetWrapper.user().get(Tablist::class.java)!!
var entryByName = tablist.getTabListEntry(name)
if (entryByName == null && name.length > 14) entryByName = tablist.getTabListEntry(name.substring(0, 14))
val entryByUUID = tablist.getTabListEntry(uuid)
if (entryByName == null || entryByUUID == null) {
if (entryByName != null || entryByUUID != null) {
val remove = PacketWrapper(0x38, null, packetWrapper.user())
remove.write(Type.VAR_INT, 4)
remove.write(Type.VAR_INT, 1)
remove.write(Type.UUID, entryByName?.uuid ?: entryByUUID!!.uuid)
tablist.remove(entryByName ?: entryByUUID!!)
remove.send(Protocol1_8To1_7_6::class.java)
}
val packetPlayerListItem = PacketWrapper(0x38, null, packetWrapper.user())
val newentry = Tablist.TabListEntry(name, uuid)
if (entryByName != null || entryByUUID != null) {
newentry.displayName = if (entryByUUID != null) entryByUUID.displayName else entryByName!!.displayName
}
newentry.properties = properties
tablist.add(newentry)
packetPlayerListItem.write(Type.VAR_INT, 0)
packetPlayerListItem.write(Type.VAR_INT, 1)
packetPlayerListItem.write(Type.UUID, newentry.uuid)
packetPlayerListItem.write(Type.STRING, newentry.name)
packetPlayerListItem.write(Type.VAR_INT, dataCount)
for (property in newentry.properties) {
packetPlayerListItem.write(Type.STRING, property.name)
packetPlayerListItem.write(Type.STRING, property.value)
packetPlayerListItem.write(Type.BOOLEAN, property.signature != null)
if (property.signature != null) packetPlayerListItem.write(Type.STRING, property.signature)
}
packetPlayerListItem.write(Type.VAR_INT, 0)
packetPlayerListItem.write(Type.VAR_INT, 0)
packetPlayerListItem.write(Type.BOOLEAN, newentry.displayName != null)
if (newentry.displayName != null) {
packetPlayerListItem.write(Type.STRING, newentry.displayName)
}
packetPlayerListItem.send(Protocol1_8To1_7_6::class.java)
packetWrapper.cancel()
val delayedPacket = PacketWrapper(0x0C, null, packetWrapper.user())
delayedPacket.write(Type.VAR_INT, entityId)
delayedPacket.write(Type.UUID, uuid)
delayedPacket.write(Type.INT, x)
delayedPacket.write(Type.INT, y)
delayedPacket.write(Type.INT, z)
delayedPacket.write(Type.BYTE, yaw)
delayedPacket.write(Type.BYTE, pitch)
delayedPacket.write(Type.SHORT, item)
delayedPacket.write<List<Metadata>>(Types1_8.METADATA_LIST, metadata)
Via.getPlatform().runSync({
try {
delayedPacket.send(Protocol1_8To1_7_6::class.java)
} catch (ex: Exception) {
ex.printStackTrace()
}
}, 1L)
} else {
entryByUUID.properties = properties
}
}
handler { packetWrapper ->
val entityID: Int = packetWrapper.get(Type.VAR_INT, 0)
val tracker: EntityTracker = packetWrapper.user().get(EntityTracker::class.java)!!
tracker.clientEntityTypes[entityID] = Entity1_10Types.EntityType.PLAYER
tracker.sendMetadataBuffer(entityID)
}
}
})
//Set Experience
this.registerOutgoing(State.PLAY, 0x1F, 0x1F, object : PacketRemapper() {
override fun registerMap() {
map(Type.FLOAT) //Experience bar
map(Type.SHORT, Type.VAR_INT) //Level
map(Type.SHORT, Type.VAR_INT) //Total Experience
}
})
//Player List Item
this.registerOutgoing(State.PLAY, 0x38, 0x38, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val name: String = packetWrapper.read(Type.STRING)
val displayName: String? = null
val online: Boolean = packetWrapper.read(Type.BOOLEAN)
val ping: Short = packetWrapper.read(Type.SHORT)
val tablist: Tablist = packetWrapper.user().get(Tablist::class.java)!!
var entry = tablist.getTabListEntry(name)
if (!online && entry != null) {
packetWrapper.write(Type.VAR_INT, 4)
packetWrapper.write(Type.VAR_INT, 1)
packetWrapper.write(Type.UUID, entry.uuid)
tablist.remove(entry)
} else if (online && entry == null) {
entry = Tablist.TabListEntry(name, UUID.nameUUIDFromBytes("OfflinePlayer:$name".toByteArray(Charsets.UTF_8)))
entry.displayName = displayName
tablist.add(entry)
packetWrapper.write(Type.VAR_INT, 0) // Add
packetWrapper.write(Type.VAR_INT, 1) // Entries
packetWrapper.write(Type.UUID, entry.uuid)
packetWrapper.write(Type.STRING, entry.name)
packetWrapper.write(Type.VAR_INT, entry.properties.size)
for (property in entry.properties) {
packetWrapper.write(Type.STRING, property.name)
packetWrapper.write(Type.STRING, property.value)
packetWrapper.write(Type.BOOLEAN, property.signature != null)
if (property.signature != null) packetWrapper.write(Type.STRING, property.signature)
}
packetWrapper.write(Type.VAR_INT, 0)
packetWrapper.write(Type.VAR_INT, ping.toInt())
packetWrapper.write(Type.BOOLEAN, entry.displayName != null)
if (entry.displayName != null) {
packetWrapper.write(Type.STRING, entry.displayName)
}
} else if (online && Tablist.shouldUpdateDisplayName(entry!!.displayName, displayName)) {
entry.displayName = displayName
packetWrapper.write(Type.VAR_INT, 3)
packetWrapper.write(Type.VAR_INT, 1)
packetWrapper.write(Type.UUID, entry.uuid)
packetWrapper.write(Type.BOOLEAN, entry.displayName != null)
if (entry.displayName != null) {
packetWrapper.write(Type.STRING, entry.displayName)
}
} else if (online) {
entry!!.ping = ping.toInt()
packetWrapper.write(Type.VAR_INT, 2) // Update ping
packetWrapper.write(Type.VAR_INT, 1) // Entries
packetWrapper.write(Type.UUID, entry.uuid)
packetWrapper.write(Type.VAR_INT, ping.toInt())
} else {
packetWrapper.write(Type.VAR_INT, 0)
packetWrapper.write(Type.VAR_INT, 0)
}
}
}
})
//Scoreboard Objective
this.registerOutgoing(State.PLAY, 0x3B, 0x3B, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val name: String = packetWrapper.passthrough(Type.STRING)
val value: String = packetWrapper.read(Type.STRING)
val mode: Byte = packetWrapper.read(Type.BYTE)
packetWrapper.write(Type.BYTE, mode)
if (mode.toInt() == 0 || mode.toInt() == 2) {
packetWrapper.write(Type.STRING, value)
packetWrapper.write(Type.STRING, "integer")
}
}
}
})
//Update Score
this.registerOutgoing(State.PLAY, 0x3C, 0x3C, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val name: String = packetWrapper.passthrough(Type.STRING)
val mode: Byte = packetWrapper.passthrough(Type.BYTE)
if (mode.toInt() != 1) {
val objective: String = packetWrapper.passthrough(Type.STRING)
packetWrapper.user().get(Scoreboard::class.java)!!.put(name, objective)
packetWrapper.write(Type.VAR_INT, packetWrapper.read(Type.INT))
} else {
val objective: String = packetWrapper.user().get(Scoreboard::class.java)!!.get(name)
packetWrapper.write(Type.STRING, objective)
}
}
}
})
//Scoreboard Teams
this.registerOutgoing(State.PLAY, 0x3E, 0x3E, object : PacketRemapper() {
override fun registerMap() {
map(Type.STRING)
handler { packetWrapper ->
val mode: Byte = packetWrapper.read(Type.BYTE)
packetWrapper.write(Type.BYTE, mode)
if (mode.toInt() == 0 || mode.toInt() == 2) {
packetWrapper.passthrough(Type.STRING)
packetWrapper.passthrough(Type.STRING)
packetWrapper.passthrough(Type.STRING)
packetWrapper.passthrough(Type.BYTE)
packetWrapper.write(Type.STRING, "always")
packetWrapper.write(Type.BYTE, 0.toByte())
}
if (mode.toInt() == 0 || mode.toInt() == 3 || mode.toInt() == 4) {
val count = packetWrapper.read(Type.SHORT).toInt()
val type = CustomStringType(count)
val entries: Array<String> = packetWrapper.read(type)
packetWrapper.write<Array<String>>(Type.STRING_ARRAY, entries)
}
}
}
})
//Custom Payload
this.registerOutgoing(State.PLAY, 0x3F, 0x3F, object : PacketRemapper() {
override fun registerMap() {
map(Type.STRING)
handler { packetWrapper ->
val channel: String = packetWrapper.get(Type.STRING, 0)
val length: Short = packetWrapper.read(Type.SHORT)
if (channel == "MC|Brand") {
val data: ByteArray = packetWrapper.read(CustomByteType(length.toInt()))
val brand = String(data, StandardCharsets.UTF_8)
packetWrapper.write(Type.STRING, brand)
} else if (channel == "MC|AdvCdm") {
val type: Byte = packetWrapper.passthrough(Type.BYTE)
if (type.toInt() == 0) {
packetWrapper.passthrough(Type.INT)
packetWrapper.passthrough(Type.INT)
packetWrapper.passthrough(Type.INT)
packetWrapper.passthrough(Type.STRING)
packetWrapper.passthrough(Type.BOOLEAN)
} else if (type.toInt() == 1) {
packetWrapper.passthrough(Type.INT)
packetWrapper.passthrough(Type.STRING)
packetWrapper.passthrough(Type.BOOLEAN)
}
packetWrapper.write(Type.BYTE, 1.toByte())
}
if (channel.equals("MC|TrList", ignoreCase = true)) {
packetWrapper.passthrough(Type.INT) //Window Id
val size: Int = packetWrapper.passthrough(Type.UNSIGNED_BYTE).toInt() //Size
for (i in 0 until size) {
var item: Item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM)
packetWrapper.write(Type.ITEM, item) //Buy Item 1
item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM)
packetWrapper.write(Type.ITEM, item) //Buy Item 3
val has3Items: Boolean = packetWrapper.passthrough(Type.BOOLEAN)
if (has3Items) {
item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM)
packetWrapper.write(Type.ITEM, item) //Buy Item 2
}
packetWrapper.passthrough(Type.BOOLEAN) //Unavailable
packetWrapper.write(Type.INT, 0) //Uses
packetWrapper.write(Type.INT, 0) //Max Uses
}
}
}
}
})
//Keep Alive
this.registerIncoming(State.PLAY, 0x00, 0x00, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT, Type.INT)
}
})
//Custom Payload
this.registerIncoming(State.PLAY, 0x17, 0x17, object : PacketRemapper() {
override fun registerMap() {
map(Type.STRING)
handler { packetWrapper ->
val channel: String = packetWrapper.get(Type.STRING, 0)
if (channel.equals("MC|ItemName", ignoreCase = true)) {
val name: ByteArray = packetWrapper.read(Type.STRING).toByteArray(Charsets.UTF_8)
packetWrapper.write(Type.REMAINING_BYTES, name)
} else if (channel.equals("MC|BEdit", ignoreCase = true) || channel.equals("MC|BSign", ignoreCase = true)) {
packetWrapper.read(Type.SHORT) //length
val book: Item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM)
val tag: CompoundTag? = book.tag
if (tag != null && tag.contains("pages")) {
val pages = tag.get<ListTag>("pages")
if (pages != null) {
(0 until pages.size()).forEach { i ->
val page = pages.get<StringTag>(i)
var value: String? = page.value
value = ChatUtil.jsonToLegacy(value)
page.value = value
}
}
}
packetWrapper.write(Type.ITEM, book)
}
packetWrapper.cancel()
packetWrapper.id = -1
val newPacketBuf = Unpooled.buffer()
packetWrapper.writeToBuffer(newPacketBuf)
val newWrapper = PacketWrapper(0x17, newPacketBuf, packetWrapper.user())
newWrapper.passthrough(Type.STRING)
newWrapper.write(Type.SHORT, newPacketBuf.readableBytes().toShort())
newWrapper.sendToServer(Protocol1_8To1_7_6::class.java, true, true)
}
}
})
//Player Position
this.registerIncoming(State.PLAY, 0x04, 0x04, object : PacketRemapper() {
override fun registerMap() {
map(Type.DOUBLE) //X
handler { packetWrapper ->
val feetY: Double = packetWrapper.passthrough(Type.DOUBLE)
packetWrapper.write(Type.DOUBLE, feetY + 1.62) //HeadY
}
map(Type.DOUBLE) //Z
map(Type.BOOLEAN) //OnGround
}
})
//Player Position And Look
this.registerIncoming(State.PLAY, 0x06, 0x06, object : PacketRemapper() {
override fun registerMap() {
map(Type.DOUBLE) //X
handler { packetWrapper ->
val feetY: Double = packetWrapper.passthrough(Type.DOUBLE)
packetWrapper.write(Type.DOUBLE, feetY + 1.62) //HeadY
}
map(Type.DOUBLE) //Z
map(Type.FLOAT) //Yaw
map(Type.FLOAT) //Pitch
map(Type.BOOLEAN) //OnGround
}
})
//Animation
this.registerIncoming(State.PLAY, 0x0A, 0x0A, object : PacketRemapper() {
override fun registerMap() {
create { packetWrapper ->
packetWrapper.write(Type.INT, 0) //Entity Id, hopefully 0 is ok
packetWrapper.write(Type.BYTE, 1.toByte()) //Animation
}
}
})
//Client Settings
this.registerIncoming(State.PLAY, 0x15, 0x15, object : PacketRemapper() {
override fun registerMap() {
map(Type.STRING)
map(Type.BYTE)
map(Type.BYTE)
map(Type.BOOLEAN)
create { packetWrapper -> packetWrapper.write(Type.BYTE, 0.toByte()) }
handler { packetWrapper ->
val flags: Short = packetWrapper.read(Type.UNSIGNED_BYTE)
packetWrapper.write(Type.BOOLEAN, flags and 1 == 1.toShort())
}
}
})
//Tab-Complete
this.registerIncoming(State.PLAY, 0x14, 0x14, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val text: String = packetWrapper.read(Type.STRING)
packetWrapper.clearInputBuffer()
packetWrapper.write(Type.STRING, text)
}
}
})
}

View File

@ -0,0 +1,251 @@
package com.github.creeper123123321.viaaas.protocol.id47toid5.packets
import com.github.creeper123123321.viaaas.protocol.*
import com.github.creeper123123321.viaaas.protocol.id47toid5.Protocol1_8To1_7_6
import com.github.creeper123123321.viaaas.protocol.id47toid5.chunks.ChunkPacketTransformer
import com.github.creeper123123321.viaaas.protocol.id47toid5.data.Particle1_8to1_7
import com.github.creeper123123321.viaaas.protocol.id47toid5.storage.MapStorage
import de.gerrygames.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10
import us.myles.ViaVersion.api.minecraft.Position
import us.myles.ViaVersion.api.minecraft.item.Item
import us.myles.ViaVersion.api.remapper.PacketRemapper
import us.myles.ViaVersion.api.remapper.TypeRemapper
import us.myles.ViaVersion.api.type.Type
import us.myles.ViaVersion.api.type.types.CustomByteType
import us.myles.ViaVersion.packets.State
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8
import us.myles.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import us.myles.viaversion.libs.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import kotlin.experimental.and
fun Protocol1_8To1_7_6.registerWorldPackets() {
//Chunk Data
this.registerOutgoing(State.PLAY, 0x21, 0x21, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper -> ChunkPacketTransformer.transformChunk(packetWrapper) }
}
})
//Multi Block Change
this.registerOutgoing(State.PLAY, 0x22, 0x22, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper -> ChunkPacketTransformer.transformMultiBlockChange(packetWrapper) }
}
})
//Block Change
this.registerOutgoing(State.PLAY, 0x23, 0x23, object : PacketRemapper() {
override fun registerMap() {
map(xyzUBytePos, TypeRemapper(Type.POSITION)) //Position
handler { packetWrapper ->
val blockId: Int = packetWrapper.read(Type.VAR_INT)
val meta = packetWrapper.read(Type.UNSIGNED_BYTE).toInt()
packetWrapper.write(Type.VAR_INT, blockId shl 4 or (meta and 15))
} //Block Data
}
})
//Block Action
this.registerOutgoing(State.PLAY, 0x24, 0x24, object : PacketRemapper() {
override fun registerMap() {
map(xyzShortPos, TypeRemapper(Type.POSITION)) //Position
map(Type.UNSIGNED_BYTE)
map(Type.UNSIGNED_BYTE)
map(Type.VAR_INT)
}
})
//Block Break Animation
this.registerOutgoing(State.PLAY, 0x25, 0x25, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT) //Entity Id
map(xyzToPosition, TypeRemapper(Type.POSITION)) //Position
map(Type.BYTE) //Progress
}
})
//Map Chunk Bulk
this.registerOutgoing(State.PLAY, 0x26, 0x26, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper -> ChunkPacketTransformer.transformChunkBulk(packetWrapper) }
}
})
//Effect
this.registerOutgoing(State.PLAY, 0x28, 0x28, object : PacketRemapper() {
override fun registerMap() {
map(Type.INT) // id
map(xyzUBytePos, TypeRemapper(Type.POSITION))
map(Type.INT) // data
map(Type.BOOLEAN) // relative volume
handler { packetWrapper ->
if (packetWrapper.get(Type.INT, 0) == 2006) { // id
packetWrapper.cancel()
}
}
}
})
//Particle
this.registerOutgoing(State.PLAY, 0x2A, 0x2A, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val parts: Array<String> = packetWrapper.read(Type.STRING).split("_").toTypedArray()
var particle = Particle1_8to1_7.find(parts[0])
if (particle == null) particle = Particle1_8to1_7.CRIT
packetWrapper.write(Type.INT, particle.ordinal)
packetWrapper.write(Type.BOOLEAN, false)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.FLOAT)
packetWrapper.passthrough(Type.INT)
var i = 0
while (i < particle.extra) {
var toWrite = 0
if (parts.size - 1 > i) {
try {
toWrite = parts[i + 1].toInt()
if (particle.extra == 1 && parts.size == 3) {
++i
toWrite = toWrite or (parts[i + 1].toInt() shl 12)
}
} catch (ignored: NumberFormatException) {
}
}
packetWrapper.write(Type.VAR_INT, toWrite)
++i
}
}
}
})
//Update Sign
this.registerOutgoing(State.PLAY, 0x33, 0x33, object : PacketRemapper() {
override fun registerMap() {
map(xyzShortPos, TypeRemapper(Type.POSITION)) //Position
handler { packetWrapper ->
for (i in 0..3) {
packetWrapper.write(Type.STRING,
Protocol1_9To1_8.fixJson(packetWrapper.read(Type.STRING)).toString()
)
}
}
}
})
//Update Block Entity
this.registerOutgoing(State.PLAY, 0x35, 0x35, object : PacketRemapper() {
override fun registerMap() {
map(xyzShortPos, TypeRemapper(Type.POSITION)) //Position
map(Type.UNSIGNED_BYTE) //Action
map(Types1_7_6_10.COMPRESSED_NBT, Type.NBT)
}
})
//Map
this.registerOutgoing(State.PLAY, 0x34, 0x34, object : PacketRemapper() {
override fun registerMap() {
map(Type.VAR_INT)
handler { packetWrapper ->
val id: Int = packetWrapper.get(Type.VAR_INT, 0)
val length: Int = packetWrapper.read(Type.SHORT).toInt()
val data: ByteArray = packetWrapper.read(CustomByteType(length))
val mapStorage = packetWrapper.user().get(MapStorage::class.java)!!
var mapData = mapStorage.getMapData(id)
if (mapData == null) mapStorage.putMapData(id, MapStorage.MapData().also { mapData = it })
if (data[0] == 1.toByte()) {
val count = (data.size - 1) / 3
mapData!!.mapIcons = Array(count) { i ->
MapStorage.MapIcon((data[i * 3 + 1].toInt() shr 4).toByte(), (data[i * 3 + 1] and 0xF), data[i * 3 + 2], data[i * 3 + 3])
}
} else if (data[0] == 2.toByte()) {
mapData!!.scale = data[1]
}
packetWrapper.write(Type.BYTE, mapData!!.scale)
packetWrapper.write(Type.VAR_INT, mapData!!.mapIcons.size)
for (mapIcon in mapData!!.mapIcons) {
packetWrapper.write(Type.BYTE, (mapIcon.direction.toInt() shl 4 or mapIcon.type.toInt() and 0xF).toByte())
packetWrapper.write(Type.BYTE, mapIcon.x)
packetWrapper.write(Type.BYTE, mapIcon.z)
}
if (data[0] == 0.toByte()) {
val x = data[1]
val z = data[2]
val rows = data.size - 3
packetWrapper.write(Type.BYTE, 1.toByte())
packetWrapper.write(Type.BYTE, rows.toByte())
packetWrapper.write(Type.BYTE, x)
packetWrapper.write(Type.BYTE, z)
val newData = ByteArray(rows)
for (i in 0 until rows) {
newData[i] = data[i + 3]
}
packetWrapper.write(Type.BYTE_ARRAY_PRIMITIVE, newData)
} else {
packetWrapper.write(Type.BYTE, 0.toByte())
}
}
}
})
//Open Sign Editor
this.registerOutgoing(State.PLAY, 0x36, 0x36, object : PacketRemapper() {
override fun registerMap() {
map(xyzToPosition, TypeRemapper(Type.POSITION)) //Position
}
})
//Player Digging
this.registerIncoming(State.PLAY, 0x07, 0x07, object : PacketRemapper() {
override fun registerMap() {
map(Type.UNSIGNED_BYTE, Type.BYTE) //Status
map(TypeRemapper(Type.POSITION), xyzUBytePosWriter)
map(Type.BYTE) //Face
}
})
//Player Block Placement
this.registerIncoming(State.PLAY, 0x08, 0x08, object : PacketRemapper() {
override fun registerMap() {
handler { packetWrapper ->
val pos: Position = packetWrapper.read(Type.POSITION) //Position
val x: Int = pos.x
val y: Short = pos.y.toShort()
val z: Int = pos.z
// https://github.com/ViaVersion/ViaVersion/pull/1379
packetWrapper.write(Type.INT, x)
packetWrapper.write(Type.UNSIGNED_BYTE, y)
packetWrapper.write(Type.INT, z)
val direction: Byte = packetWrapper.passthrough(Type.BYTE) //Direction
val item: Item = packetWrapper.read(Type.ITEM)
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item)
if (isPlayerInsideBlock(x.toLong(), y.toLong(), z.toLong(), direction) && !isPlaceable(item.identifier)) packetWrapper.cancel()
for (i in 0..2) {
if (packetWrapper.isReadable(Type.BYTE, 0)) {
packetWrapper.passthrough(Type.BYTE)
} else {
val cursor: Short = packetWrapper.read(Type.UNSIGNED_BYTE)
packetWrapper.write(Type.BYTE, cursor.toByte())
}
}
}
}
})
//Update Sign
this.registerIncoming(State.PLAY, 0x12, 0x12, object : PacketRemapper() {
override fun registerMap() {
map(TypeRemapper(Type.POSITION), xyzShortPosWriter)
handler { packetWrapper ->
for (i in 0..3)
packetWrapper.write(Type.STRING, LegacyComponentSerializer.legacySection()
.serialize(GsonComponentSerializer.gson().deserialize(packetWrapper.read(Type.STRING))))
}
}
})
}