use of com.viaversion.viaversion.api.protocol.remapper.PacketRemapper in project ViaVersion by ViaVersion.
the class SpawnPackets method register.
public static void register(Protocol1_9To1_8 protocol) {
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entity ID
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
// 1 - UUID
wrapper.write(Type.UUID, tracker.getEntityUUID(entityID));
}
});
// 2 - Type
map(Type.BYTE);
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
int typeID = wrapper.get(Type.BYTE, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addEntity(entityID, Entity1_10Types.getTypeFromId(typeID, true));
tracker.sendMetadataBuffer(entityID);
}
});
// 3 - X - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 4 - Y - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 5 - Z - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 6 - Pitch
map(Type.BYTE);
// 7 - Yaw
map(Type.BYTE);
// 8 - Data
map(Type.INT);
// Create last 3 shorts
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Data (1st Integer)
int data = wrapper.get(Type.INT, 0);
short vX = 0, vY = 0, vZ = 0;
if (data > 0) {
vX = wrapper.read(Type.SHORT);
vY = wrapper.read(Type.SHORT);
vZ = wrapper.read(Type.SHORT);
}
wrapper.write(Type.SHORT, vX);
wrapper.write(Type.SHORT, vY);
wrapper.write(Type.SHORT, vZ);
}
});
// Handle potions
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
final int entityID = wrapper.get(Type.VAR_INT, 0);
// Data
final int data = wrapper.get(Type.INT, 0);
int typeID = wrapper.get(Type.BYTE, 0);
if (Entity1_10Types.getTypeFromId(typeID, true) == Entity1_10Types.EntityType.SPLASH_POTION) {
// Convert this to meta data, woo!
PacketWrapper metaPacket = wrapper.create(ClientboundPackets1_9.ENTITY_METADATA, new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.VAR_INT, entityID);
List<Metadata> meta = new ArrayList<>();
// Potion
Item item = new DataItem(373, (byte) 1, (short) data, null);
// Rewrite so that it gets the right nbt
ItemRewriter.toClient(item);
// TEMP FIX FOR POTIONS UNTIL WE FIGURE OUT HOW TO TRANSFORM SENT PACKETS
Metadata potion = new Metadata(5, MetaType1_9.Slot, item);
meta.add(potion);
wrapper.write(Types1_9.METADATA_LIST, meta);
}
});
// Fix packet order
wrapper.send(Protocol1_9To1_8.class);
metaPacket.send(Protocol1_9To1_8.class);
wrapper.cancel();
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_EXPERIENCE_ORB, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entity ID
map(Type.VAR_INT);
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addEntity(entityID, Entity1_10Types.EntityType.EXPERIENCE_ORB);
tracker.sendMetadataBuffer(entityID);
}
});
// 1 - X - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 2 - Y - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 3 - Z - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 4 - Amount to spawn
map(Type.SHORT);
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_GLOBAL_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entity ID
map(Type.VAR_INT);
// 1 - Type
map(Type.BYTE);
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Currently only lightning uses this
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addEntity(entityID, Entity1_10Types.EntityType.LIGHTNING);
tracker.sendMetadataBuffer(entityID);
}
});
// 2 - X - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 3 - Y - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 4 - Z - Needs to be divide by 32
map(Type.INT, toNewDouble);
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_MOB, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entity ID
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
// 1 - UUID
wrapper.write(Type.UUID, tracker.getEntityUUID(entityID));
}
});
// 2 - Type
map(Type.UNSIGNED_BYTE);
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
int typeID = wrapper.get(Type.UNSIGNED_BYTE, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addEntity(entityID, Entity1_10Types.getTypeFromId(typeID, false));
tracker.sendMetadataBuffer(entityID);
}
});
// 3 - X - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 4 - Y - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 5 - Z - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 6 - Yaw
map(Type.BYTE);
// 7 - Pitch
map(Type.BYTE);
// 8 - Head Pitch
map(Type.BYTE);
// 9 - Velocity X
map(Type.SHORT);
// 10 - Velocity Y
map(Type.SHORT);
// 11 - Velocity Z
map(Type.SHORT);
map(Types1_8.METADATA_LIST, Types1_9.METADATA_LIST);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
if (tracker.hasEntity(entityId)) {
protocol.get(MetadataRewriter1_9To1_8.class).handleMetadata(entityId, metadataList, wrapper.user());
} else {
Via.getPlatform().getLogger().warning("Unable to find entity for metadata, entity ID: " + entityId);
metadataList.clear();
}
}
});
// Handler for meta data
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.handleMetadata(entityID, metadataList);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PAINTING, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entity ID
map(Type.VAR_INT);
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addEntity(entityID, Entity1_10Types.EntityType.PAINTING);
tracker.sendMetadataBuffer(entityID);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
// 1 - UUID
wrapper.write(Type.UUID, tracker.getEntityUUID(entityID));
}
});
// 2 - Title
map(Type.STRING);
// 3 - Position
map(Type.POSITION);
// 4 - Direction
map(Type.BYTE);
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PLAYER, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entity ID
map(Type.VAR_INT);
// 1 - Player UUID
map(Type.UUID);
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addEntity(entityID, Entity1_10Types.EntityType.PLAYER);
tracker.sendMetadataBuffer(entityID);
}
});
// 2 - X - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 3 - Y - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 4 - Z - Needs to be divide by 32
map(Type.INT, toNewDouble);
// 5 - Yaw
map(Type.BYTE);
// 6 - Pitch
map(Type.BYTE);
handler(new // Handle discontinued player hand item
PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
short item = wrapper.read(Type.SHORT);
if (item != 0) {
PacketWrapper packet = PacketWrapper.create(ClientboundPackets1_9.ENTITY_EQUIPMENT, null, wrapper.user());
packet.write(Type.VAR_INT, wrapper.get(Type.VAR_INT, 0));
packet.write(Type.VAR_INT, 0);
packet.write(Type.ITEM, new DataItem(item, (byte) 1, (short) 0, null));
try {
packet.send(Protocol1_9To1_8.class);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
map(Types1_8.METADATA_LIST, Types1_9.METADATA_LIST);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
if (tracker.hasEntity(entityId)) {
protocol.get(MetadataRewriter1_9To1_8.class).handleMetadata(entityId, metadataList, wrapper.user());
} else {
Via.getPlatform().getLogger().warning("Unable to find entity for metadata, entity ID: " + entityId);
metadataList.clear();
}
}
});
// Handler for meta data
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
List<Metadata> metadataList = wrapper.get(Types1_9.METADATA_LIST, 0);
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.handleMetadata(entityID, metadataList);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.DESTROY_ENTITIES, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Entities to destroy
map(Type.VAR_INT_ARRAY_PRIMITIVE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int[] entities = wrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0);
EntityTracker tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
for (int entity : entities) {
// EntityTracker
tracker.removeEntity(entity);
}
}
});
}
});
}
use of com.viaversion.viaversion.api.protocol.remapper.PacketRemapper in project ViaVersion by ViaVersion.
the class WorldPackets method register.
public static void register(Protocol protocol) {
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SIGN, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Sign Position
map(Type.POSITION);
// 1 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
// 2 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
// 3 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
// 4 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
}
});
protocol.registerClientbound(ClientboundPackets1_8.EFFECT, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Effect ID
map(Type.INT);
// 1 - Position
map(Type.POSITION);
// 2 - Data
map(Type.INT);
// 3 - Disable relative volume
map(Type.BOOLEAN);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int id = wrapper.get(Type.INT, 0);
id = Effect.getNewId(id);
wrapper.set(Type.INT, 0, id);
}
});
// Rewrite potion effect as it changed to use a dynamic registry
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int id = wrapper.get(Type.INT, 0);
if (id == 2002) {
int data = wrapper.get(Type.INT, 1);
int newData = ItemRewriter.getNewEffectID(data);
wrapper.set(Type.INT, 1, newData);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Sound Name
map(Type.STRING);
// 1 - Sound Category ID
// Everything else get's written through
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String name = wrapper.get(Type.STRING, 0);
SoundEffect effect = SoundEffect.getByName(name);
int catid = 0;
String newname = name;
if (effect != null) {
catid = effect.getCategory().getId();
newname = effect.getNewName();
}
wrapper.set(Type.STRING, 0, newname);
// Write Category ID
wrapper.write(Type.VAR_INT, catid);
if (effect != null && effect.isBreaksound()) {
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
// Position X
int x = wrapper.passthrough(Type.INT);
// Position Y
int y = wrapper.passthrough(Type.INT);
// Position Z
int z = wrapper.passthrough(Type.INT);
if (tracker.interactedBlockRecently((int) Math.floor(x / 8.0), (int) Math.floor(y / 8.0), (int) Math.floor(z / 8.0))) {
wrapper.cancel();
}
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
Chunk chunk = wrapper.read(new Chunk1_8Type(clientWorld));
long chunkHash = ClientChunks.toLong(chunk.getX(), chunk.getZ());
// Check if the chunk should be handled as an unload packet
if (chunk.isFullChunk() && chunk.getBitmask() == 0) {
wrapper.setPacketType(ClientboundPackets1_9.UNLOAD_CHUNK);
wrapper.write(Type.INT, chunk.getX());
wrapper.write(Type.INT, chunk.getZ());
// Remove commandBlocks on chunk unload
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.unloadChunk(wrapper.user(), chunk.getX(), chunk.getZ());
clientChunks.getLoadedChunks().remove(chunkHash);
// Unload the empty chunks
if (Via.getConfig().isChunkBorderFix()) {
for (BlockFace face : BlockFace.HORIZONTAL) {
int chunkX = chunk.getX() + face.modX();
int chunkZ = chunk.getZ() + face.modZ();
if (!clientChunks.getLoadedChunks().contains(ClientChunks.toLong(chunkX, chunkZ))) {
PacketWrapper unloadChunk = wrapper.create(ClientboundPackets1_9.UNLOAD_CHUNK);
unloadChunk.write(Type.INT, chunkX);
unloadChunk.write(Type.INT, chunkZ);
unloadChunk.send(Protocol1_9To1_8.class);
}
}
}
} else {
Type<Chunk> chunkType = new Chunk1_9_1_2Type(clientWorld);
wrapper.write(chunkType, chunk);
clientChunks.getLoadedChunks().add(chunkHash);
// Send empty chunks surrounding the loaded chunk to force 1.9+ clients to render the new chunk
if (Via.getConfig().isChunkBorderFix()) {
for (BlockFace face : BlockFace.HORIZONTAL) {
int chunkX = chunk.getX() + face.modX();
int chunkZ = chunk.getZ() + face.modZ();
if (!clientChunks.getLoadedChunks().contains(ClientChunks.toLong(chunkX, chunkZ))) {
PacketWrapper emptyChunk = wrapper.create(ClientboundPackets1_9.CHUNK_DATA);
Chunk c = new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], new int[256], new ArrayList<>());
emptyChunk.write(chunkType, c);
emptyChunk.send(Protocol1_9To1_8.class);
}
}
}
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
// Cancel the packet from being sent
wrapper.cancel();
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
Chunk[] chunks = wrapper.read(new ChunkBulk1_8Type(clientWorld));
Type<Chunk> chunkType = new Chunk1_9_1_2Type(clientWorld);
// Split into multiple chunk packets
for (Chunk chunk : chunks) {
PacketWrapper chunkData = wrapper.create(ClientboundPackets1_9.CHUNK_DATA);
chunkData.write(chunkType, chunk);
chunkData.send(Protocol1_9To1_8.class);
clientChunks.getLoadedChunks().add(ClientChunks.toLong(chunk.getX(), chunk.getZ()));
// Send empty chunks surrounding the loaded chunk to force 1.9+ clients to render the new chunk
if (Via.getConfig().isChunkBorderFix()) {
for (BlockFace face : BlockFace.HORIZONTAL) {
int chunkX = chunk.getX() + face.modX();
int chunkZ = chunk.getZ() + face.modZ();
if (!clientChunks.getLoadedChunks().contains(ClientChunks.toLong(chunkX, chunkZ))) {
PacketWrapper emptyChunk = wrapper.create(ClientboundPackets1_9.CHUNK_DATA);
Chunk c = new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], new int[256], new ArrayList<>());
emptyChunk.write(chunkType, c);
emptyChunk.send(Protocol1_9To1_8.class);
}
}
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ENTITY_DATA, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Block Position
map(Type.POSITION);
// 1 - Action
map(Type.UNSIGNED_BYTE);
// 2 - NBT (Might not be present)
map(Type.NBT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int action = wrapper.get(Type.UNSIGNED_BYTE, 0);
if (action == 1) {
// Update Spawner
CompoundTag tag = wrapper.get(Type.NBT, 0);
if (tag != null) {
if (tag.contains("EntityId")) {
String entity = (String) tag.get("EntityId").getValue();
CompoundTag spawn = new CompoundTag();
spawn.put("id", new StringTag(entity));
tag.put("SpawnData", spawn);
} else {
// EntityID does not exist
CompoundTag spawn = new CompoundTag();
// Make spawners show up as empty when no EntityId is given.
spawn.put("id", new StringTag("AreaEffectCloud"));
tag.put("SpawnData", spawn);
}
}
}
if (action == 2) {
// Update Command Block
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.addOrUpdateBlock(wrapper.user(), wrapper.get(Type.POSITION, 0), wrapper.get(Type.NBT, 0));
// To prevent window issues don't send updates
wrapper.cancel();
}
}
});
}
});
/* Incoming Packets */
protocol.registerServerbound(ServerboundPackets1_9.UPDATE_SIGN, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Sign Position
map(Type.POSITION);
// 1 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
// 2 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
// 3 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
// 4 - Sign Line (json)
map(Type.STRING, Protocol1_9To1_8.FIX_JSON);
}
});
protocol.registerServerbound(ServerboundPackets1_9.PLAYER_DIGGING, new PacketRemapper() {
@Override
public void registerMap() {
// Action
map(Type.VAR_INT);
// Position
map(Type.POSITION);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int status = wrapper.get(Type.VAR_INT, 0);
if (status == 6)
wrapper.cancel();
}
});
// Blocking
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int status = wrapper.get(Type.VAR_INT, 0);
if (status == 5 || status == 4 || status == 3) {
EntityTracker1_9 entityTracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
if (entityTracker.isBlocking()) {
entityTracker.setBlocking(false);
if (!Via.getConfig().isShowShieldWhenSwordInHand()) {
entityTracker.setSecondHand(null);
}
}
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_9.USE_ITEM, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int hand = wrapper.read(Type.VAR_INT);
// Wipe the input buffer
wrapper.clearInputBuffer();
// First set this packet ID to Block placement
wrapper.setId(0x08);
wrapper.write(Type.POSITION, new Position(-1, (short) -1, -1));
wrapper.write(Type.UNSIGNED_BYTE, (short) 255);
// Write item in hand
Item item = Protocol1_9To1_8.getHandItem(wrapper.user());
// Blocking patch
if (Via.getConfig().isShieldBlocking()) {
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
// Check if the shield is already there or if we have to give it here
boolean showShieldWhenSwordInHand = Via.getConfig().isShowShieldWhenSwordInHand();
// Method to identify the sword in hand
boolean isSword = showShieldWhenSwordInHand ? tracker.hasSwordInHand() : item != null && Protocol1_9To1_8.isSword(item.identifier());
if (isSword) {
if (hand == 0) {
if (!tracker.isBlocking()) {
tracker.setBlocking(true);
// Check if the shield is already in the offhand
if (!showShieldWhenSwordInHand && tracker.getItemInSecondHand() == null) {
// Set shield in offhand when interacting with main hand
Item shield = new DataItem(442, (byte) 1, (short) 0, null);
tracker.setSecondHand(shield);
}
}
}
// Use the main hand to trigger the blocking
boolean blockUsingMainHand = Via.getConfig().isNoDelayShieldBlocking() && !showShieldWhenSwordInHand;
if (blockUsingMainHand && hand == 1 || !blockUsingMainHand && hand == 0) {
wrapper.cancel();
}
} else {
if (!showShieldWhenSwordInHand) {
// Remove the shield from the offhand
tracker.setSecondHand(null);
}
tracker.setBlocking(false);
}
}
wrapper.write(Type.ITEM, item);
wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_9.PLAYER_BLOCK_PLACEMENT, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Position
map(Type.POSITION);
// 1 - Block Face
map(Type.VAR_INT, Type.UNSIGNED_BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// 2 - Hand
final int hand = wrapper.read(Type.VAR_INT);
if (hand != 0)
wrapper.cancel();
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = Protocol1_9To1_8.getHandItem(wrapper.user());
// 3 - Item
wrapper.write(Type.ITEM, item);
}
});
// 4 - X
map(Type.UNSIGNED_BYTE);
// 5 - Y
map(Type.UNSIGNED_BYTE);
// 6 - Z
map(Type.UNSIGNED_BYTE);
// Register block place to fix sounds
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int face = wrapper.get(Type.UNSIGNED_BYTE, 0);
if (face == 255)
return;
Position p = wrapper.get(Type.POSITION, 0);
int x = p.x();
int y = p.y();
int z = p.z();
switch(face) {
case 0:
y--;
break;
case 1:
y++;
break;
case 2:
z--;
break;
case 3:
z++;
break;
case 4:
x--;
break;
case 5:
x++;
break;
}
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.addBlockInteraction(new Position(x, y, z));
}
});
// Handle CommandBlocks
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
Position pos = wrapper.get(Type.POSITION, 0);
Optional<CompoundTag> tag = provider.get(wrapper.user(), pos);
// Send the Update Block Entity packet if present
if (tag.isPresent()) {
PacketWrapper updateBlockEntity = PacketWrapper.create(ClientboundPackets1_9.BLOCK_ENTITY_DATA, null, wrapper.user());
updateBlockEntity.write(Type.POSITION, pos);
updateBlockEntity.write(Type.UNSIGNED_BYTE, (short) 2);
updateBlockEntity.write(Type.NBT, tag.get());
updateBlockEntity.scheduleSend(Protocol1_9To1_8.class);
}
}
});
}
});
}
use of com.viaversion.viaversion.api.protocol.remapper.PacketRemapper in project ViaVersion by ViaVersion.
the class EntityPackets method registerPackets.
@Override
public void registerPackets() {
registerTrackerWithData(ClientboundPackets1_16_2.SPAWN_ENTITY, Entity1_17Types.FALLING_BLOCK);
registerTracker(ClientboundPackets1_16_2.SPAWN_MOB);
registerTracker(ClientboundPackets1_16_2.SPAWN_PLAYER, Entity1_17Types.PLAYER);
registerMetadataRewriter(ClientboundPackets1_16_2.ENTITY_METADATA, Types1_16.METADATA_LIST, Types1_17.METADATA_LIST);
protocol.registerClientbound(ClientboundPackets1_16_2.DESTROY_ENTITIES, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int[] entityIds = wrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
wrapper.cancel();
EntityTracker entityTracker = wrapper.user().getEntityTracker(Protocol1_17To1_16_4.class);
for (int entityId : entityIds) {
entityTracker.removeEntity(entityId);
// Send individual remove packets
PacketWrapper newPacket = wrapper.create(ClientboundPackets1_17.REMOVE_ENTITY);
newPacket.write(Type.VAR_INT, entityId);
newPacket.send(Protocol1_17To1_16_4.class);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.ENTITY_PROPERTIES, new PacketRemapper() {
@Override
public void registerMap() {
// Entity id
map(Type.VAR_INT);
handler(wrapper -> {
// Collection length is now a var int
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT));
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.PLAYER_POSITION, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BYTE);
map(Type.VAR_INT);
handler(wrapper -> {
// Dismount vehicle
wrapper.write(Type.BOOLEAN, false);
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.COMBAT_EVENT, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
// Combat packet actions have been split into individual packets (the content hasn't changed)
int type = wrapper.read(Type.VAR_INT);
ClientboundPacketType packetType;
switch(type) {
case 0:
packetType = ClientboundPackets1_17.COMBAT_ENTER;
break;
case 1:
packetType = ClientboundPackets1_17.COMBAT_END;
break;
case 2:
packetType = ClientboundPackets1_17.COMBAT_KILL;
break;
default:
throw new IllegalArgumentException("Invalid combat type received: " + type);
}
wrapper.setId(packetType.getId());
});
}
});
// The parent class of the other entity move packets that is never actually used has finally been removed from the id list
protocol.cancelClientbound(ClientboundPackets1_16_2.ENTITY_MOVEMENT);
}
use of com.viaversion.viaversion.api.protocol.remapper.PacketRemapper in project ViaVersion by ViaVersion.
the class InventoryPackets method registerPackets.
@Override
public void registerPackets() {
registerSetCooldown(ClientboundPackets1_16_2.COOLDOWN);
registerWindowItems(ClientboundPackets1_16_2.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
registerTradeList(ClientboundPackets1_16_2.TRADE_LIST, Type.FLAT_VAR_INT_ITEM);
registerSetSlot(ClientboundPackets1_16_2.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_16_2.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
registerEntityEquipmentArray(ClientboundPackets1_16_2.ENTITY_EQUIPMENT, Type.FLAT_VAR_INT_ITEM);
registerSpawnParticle(ClientboundPackets1_16_2.SPAWN_PARTICLE, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE);
new RecipeRewriter1_16(protocol).registerDefaultHandler(ClientboundPackets1_16_2.DECLARE_RECIPES);
registerCreativeInvAction(ServerboundPackets1_17.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
protocol.registerServerbound(ServerboundPackets1_17.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
}
});
protocol.registerServerbound(ServerboundPackets1_17.CLICK_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
// Window Id
map(Type.UNSIGNED_BYTE);
// Slot
map(Type.SHORT);
// Button
map(Type.BYTE);
// Action id - doesn't matter, as the sent out confirmation packet will be cancelled
handler(wrapper -> wrapper.write(Type.SHORT, (short) 0));
// Action
map(Type.VAR_INT);
handler(wrapper -> {
// Affected items - throw them away!
int length = wrapper.read(Type.VAR_INT);
for (int i = 0; i < length; i++) {
// Slot
wrapper.read(Type.SHORT);
wrapper.read(Type.FLAT_VAR_INT_ITEM);
}
// 1.17 clients send the then carried item, but 1.16 expects the clicked one
Item item = wrapper.read(Type.FLAT_VAR_INT_ITEM);
int action = wrapper.get(Type.VAR_INT, 0);
if (action == 5 || action == 1) {
// Quick craft (= dragging / mouse movement while clicking on an empty slot)
// OR Quick move (= shift click to move a whole stack to the other inventory)
// The server always expects an empty item here
item = null;
} else {
// Use the item sent
handleItemToServer(item);
}
wrapper.write(Type.FLAT_VAR_INT_ITEM, item);
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.WINDOW_CONFIRMATION, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
short inventoryId = wrapper.read(Type.UNSIGNED_BYTE);
short confirmationId = wrapper.read(Type.SHORT);
boolean accepted = wrapper.read(Type.BOOLEAN);
if (!accepted) {
// Use the new ping packet to replace the removed acknowledgement, extra bit for fast dismissal
int id = (1 << 30) | (inventoryId << 16) | (confirmationId & 0xFFFF);
wrapper.user().get(InventoryAcknowledgements.class).addId(id);
PacketWrapper pingPacket = wrapper.create(ClientboundPackets1_17.PING);
pingPacket.write(Type.INT, id);
pingPacket.send(Protocol1_17To1_16_4.class);
}
wrapper.cancel();
});
}
});
// New pong packet
protocol.registerServerbound(ServerboundPackets1_17.PONG, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int id = wrapper.read(Type.INT);
// Check extra bit for fast dismissal
if ((id & (1 << 30)) != 0 && wrapper.user().get(InventoryAcknowledgements.class).removeId(id)) {
// Decode our requested inventory acknowledgement
short inventoryId = (short) ((id >> 16) & 0xFF);
short confirmationId = (short) (id & 0xFFFF);
PacketWrapper packet = wrapper.create(ServerboundPackets1_16_2.WINDOW_CONFIRMATION);
packet.write(Type.UNSIGNED_BYTE, inventoryId);
packet.write(Type.SHORT, confirmationId);
// Accept
packet.write(Type.BOOLEAN, true);
packet.sendToServer(Protocol1_17To1_16_4.class);
}
wrapper.cancel();
});
}
});
}
use of com.viaversion.viaversion.api.protocol.remapper.PacketRemapper in project ViaVersion by ViaVersion.
the class WorldPackets method register.
public static void register(Protocol1_17To1_16_4 protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_16_2.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_16_2.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange(ClientboundPackets1_16_2.MULTI_BLOCK_CHANGE);
blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_16_2.ACKNOWLEDGE_PLAYER_DIGGING);
protocol.registerClientbound(ClientboundPackets1_16_2.WORLD_BORDER, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
// Border packet actions have been split into individual packets (the content hasn't changed)
int type = wrapper.read(Type.VAR_INT);
ClientboundPacketType packetType;
switch(type) {
case 0:
packetType = ClientboundPackets1_17.WORLD_BORDER_SIZE;
break;
case 1:
packetType = ClientboundPackets1_17.WORLD_BORDER_LERP_SIZE;
break;
case 2:
packetType = ClientboundPackets1_17.WORLD_BORDER_CENTER;
break;
case 3:
packetType = ClientboundPackets1_17.WORLD_BORDER_INIT;
break;
case 4:
packetType = ClientboundPackets1_17.WORLD_BORDER_WARNING_DELAY;
break;
case 5:
packetType = ClientboundPackets1_17.WORLD_BORDER_WARNING_DISTANCE;
break;
default:
throw new IllegalArgumentException("Invalid world border type received: " + type);
}
wrapper.setId(packetType.getId());
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.UPDATE_LIGHT, new PacketRemapper() {
@Override
public void registerMap() {
// x
map(Type.VAR_INT);
// y
map(Type.VAR_INT);
// trust edges
map(Type.BOOLEAN);
handler(wrapper -> {
int skyLightMask = wrapper.read(Type.VAR_INT);
int blockLightMask = wrapper.read(Type.VAR_INT);
// Now all written as a representation of BitSets
// Sky light mask
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, toBitSetLongArray(skyLightMask));
// Block light mask
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, toBitSetLongArray(blockLightMask));
// Empty sky light mask
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, toBitSetLongArray(wrapper.read(Type.VAR_INT)));
// Empty block light mask
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, toBitSetLongArray(wrapper.read(Type.VAR_INT)));
writeLightArrays(wrapper, skyLightMask);
writeLightArrays(wrapper, blockLightMask);
});
}
private void writeLightArrays(PacketWrapper wrapper, int bitMask) throws Exception {
List<byte[]> light = new ArrayList<>();
for (int i = 0; i < 18; i++) {
if (isSet(bitMask, i)) {
light.add(wrapper.read(Type.BYTE_ARRAY_PRIMITIVE));
}
}
// Now needs the length of the bytearray-array
wrapper.write(Type.VAR_INT, light.size());
for (byte[] bytes : light) {
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, bytes);
}
}
private long[] toBitSetLongArray(int bitmask) {
return new long[] { bitmask };
}
private boolean isSet(int mask, int i) {
return (mask & (1 << i)) != 0;
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
Chunk chunk = wrapper.read(new Chunk1_16_2Type());
if (!chunk.isFullChunk()) {
// All chunks are full chunk packets now (1.16 already stopped sending non-full chunks)
// Construct multi block change packets instead
// Height map updates are lost (unless we want to fully cache and resend entire chunks)
// Block entities are always empty for non-full chunks in Vanilla
writeMultiBlockChangePacket(wrapper, chunk);
wrapper.cancel();
return;
}
// Normal full chunk writing
wrapper.write(new Chunk1_17Type(chunk.getSections().length), chunk);
// 1.17 uses a bitset for the mask
chunk.setChunkMask(BitSet.valueOf(new long[] { chunk.getBitmask() }));
for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[s];
if (section == null)
continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
section.setPaletteEntry(i, protocol.getMappingData().getNewBlockStateId(old));
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
// Entity ID
map(Type.INT);
// Hardcore
map(Type.BOOLEAN);
// Gamemode
map(Type.UNSIGNED_BYTE);
// Previous Gamemode
map(Type.BYTE);
// World List
map(Type.STRING_ARRAY);
// Registry
map(Type.NBT);
// Current dimension
map(Type.NBT);
handler(wrapper -> {
// Add new dimension fields
CompoundTag dimensionRegistry = wrapper.get(Type.NBT, 0).get("minecraft:dimension_type");
ListTag dimensions = dimensionRegistry.get("value");
for (Tag dimension : dimensions) {
CompoundTag dimensionCompound = ((CompoundTag) dimension).get("element");
addNewDimensionData(dimensionCompound);
}
CompoundTag currentDimensionTag = wrapper.get(Type.NBT, 1);
addNewDimensionData(currentDimensionTag);
UserConnection user = wrapper.user();
user.getEntityTracker(Protocol1_17To1_16_4.class).addEntity(wrapper.get(Type.INT, 0), Entity1_17Types.PLAYER);
});
}
});
protocol.registerClientbound(ClientboundPackets1_16_2.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
CompoundTag dimensionData = wrapper.passthrough(Type.NBT);
addNewDimensionData(dimensionData);
});
}
});
blockRewriter.registerEffect(ClientboundPackets1_16_2.EFFECT, 1010, 2001);
}
Aggregations