use of com.viaversion.viaversion.api.minecraft.Position in project ViaBackwards by ViaVersion.
the class BlockItemPackets1_16 method registerPackets.
@Override
protected void registerPackets() {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14);
RecipeRewriter1_14 recipeRewriter = new RecipeRewriter1_14(protocol);
// Remove new smithing type, only in this handler
protocol.registerClientbound(ClientboundPackets1_16.DECLARE_RECIPES, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int size = wrapper.passthrough(Type.VAR_INT);
int newSize = size;
for (int i = 0; i < size; i++) {
String originalType = wrapper.read(Type.STRING);
String type = originalType.replace("minecraft:", "");
if (type.equals("smithing")) {
newSize--;
wrapper.read(Type.STRING);
wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT);
wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT);
wrapper.read(Type.FLAT_VAR_INT_ITEM);
continue;
}
wrapper.write(Type.STRING, originalType);
// Recipe Identifier
String id = wrapper.passthrough(Type.STRING);
recipeRewriter.handle(wrapper, type);
}
wrapper.set(Type.VAR_INT, 0, newSize);
});
}
});
registerSetCooldown(ClientboundPackets1_16.COOLDOWN);
registerWindowItems(ClientboundPackets1_16.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
registerSetSlot(ClientboundPackets1_16.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerTradeList(ClientboundPackets1_16.TRADE_LIST, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_16.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_16.ACKNOWLEDGE_PLAYER_DIGGING);
blockRewriter.registerBlockAction(ClientboundPackets1_16.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_16.BLOCK_CHANGE);
blockRewriter.registerMultiBlockChange(ClientboundPackets1_16.MULTI_BLOCK_CHANGE);
protocol.registerClientbound(ClientboundPackets1_16.ENTITY_EQUIPMENT, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int entityId = wrapper.passthrough(Type.VAR_INT);
List<EquipmentData> equipmentData = new ArrayList<>();
byte slot;
do {
slot = wrapper.read(Type.BYTE);
Item item = handleItemToClient(wrapper.read(Type.FLAT_VAR_INT_ITEM));
int rawSlot = slot & 0x7F;
equipmentData.add(new EquipmentData(rawSlot, item));
} while ((slot & 0xFFFFFF80) != 0);
// Send first data in the current packet
EquipmentData firstData = equipmentData.get(0);
wrapper.write(Type.VAR_INT, firstData.slot);
wrapper.write(Type.FLAT_VAR_INT_ITEM, firstData.item);
// If there are more items, send new packets for them
for (int i = 1; i < equipmentData.size(); i++) {
PacketWrapper equipmentPacket = wrapper.create(ClientboundPackets1_15.ENTITY_EQUIPMENT);
EquipmentData data = equipmentData.get(i);
equipmentPacket.write(Type.VAR_INT, entityId);
equipmentPacket.write(Type.VAR_INT, data.slot);
equipmentPacket.write(Type.FLAT_VAR_INT_ITEM, data.item);
equipmentPacket.send(Protocol1_15_2To1_16.class);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_16.UPDATE_LIGHT, new PacketRemapper() {
@Override
public void registerMap() {
// x
map(Type.VAR_INT);
// y
map(Type.VAR_INT);
map(Type.BOOLEAN, Type.NOTHING);
}
});
protocol.registerClientbound(ClientboundPackets1_16.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
Chunk chunk = wrapper.read(new Chunk1_16Type());
wrapper.write(new Chunk1_15Type(), chunk);
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null)
continue;
for (int j = 0; j < section.getPaletteSize(); j++) {
int old = section.getPaletteEntry(j);
section.setPaletteEntry(j, protocol.getMappingData().getNewBlockStateId(old));
}
}
CompoundTag heightMaps = chunk.getHeightMap();
for (Tag heightMapTag : heightMaps.values()) {
LongArrayTag heightMap = (LongArrayTag) heightMapTag;
int[] heightMapData = new int[256];
CompactArrayUtil.iterateCompactArrayWithPadding(9, heightMapData.length, heightMap.getValue(), (i, v) -> heightMapData[i] = v);
heightMap.setValue(CompactArrayUtil.createCompactArray(9, heightMapData.length, i -> heightMapData[i]));
}
if (chunk.isBiomeData()) {
for (int i = 0; i < 1024; i++) {
int biome = chunk.getBiomeData()[i];
switch(biome) {
// new nether biomes
case 170:
case 171:
case 172:
case 173:
chunk.getBiomeData()[i] = 8;
break;
}
}
}
if (chunk.getBlockEntities() == null)
return;
for (CompoundTag blockEntity : chunk.getBlockEntities()) {
handleBlockEntity(blockEntity);
}
});
}
});
blockRewriter.registerEffect(ClientboundPackets1_16.EFFECT, 1010, 2001);
registerSpawnParticle(ClientboundPackets1_16.SPAWN_PARTICLE, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE);
protocol.registerClientbound(ClientboundPackets1_16.WINDOW_PROPERTY, new PacketRemapper() {
@Override
public void registerMap() {
// Window id
map(Type.UNSIGNED_BYTE);
// Property
map(Type.SHORT);
// Value
map(Type.SHORT);
handler(wrapper -> {
short property = wrapper.get(Type.SHORT, 0);
if (property >= 4 && property <= 6) {
// Enchantment id
short enchantmentId = wrapper.get(Type.SHORT, 1);
if (enchantmentId > 11) {
// soul_speed
wrapper.set(Type.SHORT, 1, --enchantmentId);
} else if (enchantmentId == 11) {
wrapper.set(Type.SHORT, 1, (short) 9);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_16.MAP_DATA, new PacketRemapper() {
@Override
public void registerMap() {
// Map ID
map(Type.VAR_INT);
// Scale
map(Type.BYTE);
// Tracking Position
map(Type.BOOLEAN);
// Locked
map(Type.BOOLEAN);
handler(MapColorRewriter.getRewriteHandler(MapColorRewrites::getMappedColor));
}
});
protocol.registerClientbound(ClientboundPackets1_16.BLOCK_ENTITY_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
Position position = wrapper.passthrough(Type.POSITION1_14);
short action = wrapper.passthrough(Type.UNSIGNED_BYTE);
CompoundTag tag = wrapper.passthrough(Type.NBT);
handleBlockEntity(tag);
});
}
});
registerClickWindow(ServerboundPackets1_14.CLICK_WINDOW, Type.FLAT_VAR_INT_ITEM);
registerCreativeInvAction(ServerboundPackets1_14.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
protocol.registerServerbound(ServerboundPackets1_14.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
}
});
}
use of com.viaversion.viaversion.api.minecraft.Position in project ViaBackwards by ViaVersion.
the class EntityPackets1_14 method addTrackedEntity.
// TODO work the method into this class alone
@Override
protected void addTrackedEntity(PacketWrapper wrapper, int entityId, EntityType type) throws Exception {
super.addTrackedEntity(wrapper, entityId, type);
// Cache the position for every newly tracked entity
if (type == Entity1_14Types.PAINTING) {
final Position position = wrapper.get(Type.POSITION, 0);
positionHandler.cacheEntityPosition(wrapper, position.getX(), position.getY(), position.getZ(), true, false);
} else if (wrapper.getId() != ClientboundPackets1_14.JOIN_GAME.getId()) {
// ignore join game
positionHandler.cacheEntityPosition(wrapper, true, false);
}
}
use of com.viaversion.viaversion.api.minecraft.Position in project ViaBackwards by ViaVersion.
the class PlayerPackets1_14 method registerPackets.
@Override
protected void registerPackets() {
protocol.registerClientbound(ClientboundPackets1_14.SERVER_DIFFICULTY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
// Locked
map(Type.BOOLEAN, Type.NOTHING);
handler(wrapper -> {
byte difficulty = wrapper.get(Type.UNSIGNED_BYTE, 0).byteValue();
wrapper.user().get(DifficultyStorage.class).setDifficulty(difficulty);
});
}
});
protocol.registerClientbound(ClientboundPackets1_14.OPEN_SIGN_EDITOR, new // c
PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION1_14, Type.POSITION);
}
});
protocol.registerServerbound(ServerboundPackets1_13.QUERY_BLOCK_NBT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.POSITION, Type.POSITION1_14);
}
});
protocol.registerServerbound(ServerboundPackets1_13.PLAYER_DIGGING, new PacketRemapper() {
@Override
public void registerMap() {
// Action
map(Type.VAR_INT);
// Position
map(Type.POSITION, Type.POSITION1_14);
}
});
protocol.registerServerbound(ServerboundPackets1_13.RECIPE_BOOK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int type = wrapper.get(Type.VAR_INT, 0);
if (type == 0) {
wrapper.passthrough(Type.STRING);
} else if (type == 1) {
// Crafting Recipe Book Open
wrapper.passthrough(Type.BOOLEAN);
// Crafting Recipe Filter Active
wrapper.passthrough(Type.BOOLEAN);
// Smelting Recipe Book Open
wrapper.passthrough(Type.BOOLEAN);
// Smelting Recipe Filter Active
wrapper.passthrough(Type.BOOLEAN);
// Blast furnace/smoker data
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.BOOLEAN, false);
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_13.UPDATE_COMMAND_BLOCK, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION, Type.POSITION1_14);
}
});
protocol.registerServerbound(ServerboundPackets1_13.UPDATE_STRUCTURE_BLOCK, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION, Type.POSITION1_14);
}
});
protocol.registerServerbound(ServerboundPackets1_13.UPDATE_SIGN, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION, Type.POSITION1_14);
}
});
protocol.registerServerbound(ServerboundPackets1_13.PLAYER_BLOCK_PLACEMENT, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Position position = wrapper.read(Type.POSITION);
int face = wrapper.read(Type.VAR_INT);
int hand = wrapper.read(Type.VAR_INT);
float x = wrapper.read(Type.FLOAT);
float y = wrapper.read(Type.FLOAT);
float z = wrapper.read(Type.FLOAT);
wrapper.write(Type.VAR_INT, hand);
wrapper.write(Type.POSITION1_14, position);
wrapper.write(Type.VAR_INT, face);
wrapper.write(Type.FLOAT, x);
wrapper.write(Type.FLOAT, y);
wrapper.write(Type.FLOAT, z);
// Inside block
wrapper.write(Type.BOOLEAN, false);
}
});
}
});
}
use of com.viaversion.viaversion.api.minecraft.Position in project ViaBackwards by ViaVersion.
the class PlayerPacket1_13 method registerPackets.
@Override
protected void registerPackets() {
// Login Plugin Request
protocol.registerClientbound(State.LOGIN, 0x04, -1, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
packetWrapper.cancel();
packetWrapper.create(0x02, new // Plugin response
PacketHandler() {
@Override
public void handle(PacketWrapper newWrapper) throws Exception {
// Packet id
newWrapper.write(Type.VAR_INT, packetWrapper.read(Type.VAR_INT));
// Success
newWrapper.write(Type.BOOLEAN, false);
}
}).sendToServer(Protocol1_12_2To1_13.class);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String channel = wrapper.read(Type.STRING);
if (channel.equals("minecraft:trader_list")) {
wrapper.write(Type.STRING, "MC|TrList");
// Passthrough Window ID
wrapper.passthrough(Type.INT);
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
// Input Item
Item input = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, protocol.getItemRewriter().handleItemToClient(input));
// Output Item
Item output = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, protocol.getItemRewriter().handleItemToClient(output));
// Has second item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN);
if (secondItem) {
// Second Item
Item second = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, protocol.getItemRewriter().handleItemToClient(second));
}
// Trade disabled
wrapper.passthrough(Type.BOOLEAN);
// Number of tools uses
wrapper.passthrough(Type.INT);
// Maximum number of trade uses
wrapper.passthrough(Type.INT);
}
} else {
String oldChannel = InventoryPackets.getOldPluginChannelId(channel);
if (oldChannel == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring outgoing plugin message with channel: " + channel);
}
wrapper.cancel();
return;
}
wrapper.write(Type.STRING, oldChannel);
if (oldChannel.equals("REGISTER") || oldChannel.equals("UNREGISTER")) {
String[] channels = new String(wrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (String s : channels) {
String rewritten = InventoryPackets.getOldPluginChannelId(s);
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in outgoing REGISTER: " + s);
}
}
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
}
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.SPAWN_PARTICLE, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Particle ID
map(Type.INT);
// 1 - Long Distance
map(Type.BOOLEAN);
// 2 - X
map(Type.FLOAT);
// 3 - Y
map(Type.FLOAT);
// 4 - Z
map(Type.FLOAT);
// 5 - Offset X
map(Type.FLOAT);
// 6 - Offset Y
map(Type.FLOAT);
// 7 - Offset Z
map(Type.FLOAT);
// 8 - Particle Data
map(Type.FLOAT);
// 9 - Particle Count
map(Type.INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ParticleMapping.ParticleData old = ParticleMapping.getMapping(wrapper.get(Type.INT, 0));
wrapper.set(Type.INT, 0, old.getHistoryId());
int[] data = old.rewriteData(protocol, wrapper);
if (data != null) {
if (old.getHandler().isBlockHandler() && data[0] == 0) {
// Cancel air block particles
wrapper.cancel();
return;
}
for (int i : data) {
wrapper.write(Type.VAR_INT, i);
}
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.PLAYER_INFO, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
TabCompleteStorage storage = packetWrapper.user().get(TabCompleteStorage.class);
int action = packetWrapper.passthrough(Type.VAR_INT);
int nPlayers = packetWrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < nPlayers; i++) {
UUID uuid = packetWrapper.passthrough(Type.UUID);
if (action == 0) {
// Add
String name = packetWrapper.passthrough(Type.STRING);
storage.usernames().put(uuid, name);
int nProperties = packetWrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < nProperties; j++) {
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.STRING);
if (packetWrapper.passthrough(Type.BOOLEAN)) {
packetWrapper.passthrough(Type.STRING);
}
}
packetWrapper.passthrough(Type.VAR_INT);
packetWrapper.passthrough(Type.VAR_INT);
if (packetWrapper.passthrough(Type.BOOLEAN)) {
packetWrapper.passthrough(Type.COMPONENT);
}
} else if (action == 1) {
// Update Game Mode
packetWrapper.passthrough(Type.VAR_INT);
} else if (action == 2) {
// Update Ping
packetWrapper.passthrough(Type.VAR_INT);
} else if (action == 3) {
// Update Display Name
if (packetWrapper.passthrough(Type.BOOLEAN)) {
packetWrapper.passthrough(Type.COMPONENT);
}
} else if (action == 4) {
// Remove Player
storage.usernames().remove(uuid);
}
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.SCOREBOARD_OBJECTIVE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
map(Type.BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
byte mode = wrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) {
String value = wrapper.read(Type.COMPONENT).toString();
value = ChatRewriter.jsonToLegacyText(value);
if (value.length() > 32) {
value = value.substring(0, 32);
}
wrapper.write(Type.STRING, value);
int type = wrapper.read(Type.VAR_INT);
wrapper.write(Type.STRING, type == 1 ? "hearts" : "integer");
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.TEAMS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
map(Type.BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
byte action = wrapper.get(Type.BYTE, 0);
if (action == 0 || action == 2) {
String displayName = wrapper.read(Type.STRING);
displayName = ChatRewriter.jsonToLegacyText(displayName);
displayName = ChatUtil.removeUnusedColor(displayName, 'f');
if (displayName.length() > 32) {
displayName = displayName.substring(0, 32);
}
wrapper.write(Type.STRING, displayName);
byte flags = wrapper.read(Type.BYTE);
String nameTagVisibility = wrapper.read(Type.STRING);
String collisionRule = wrapper.read(Type.STRING);
int colour = wrapper.read(Type.VAR_INT);
if (colour == 21) {
colour = -1;
}
JsonElement prefixComponent = wrapper.read(Type.COMPONENT);
JsonElement suffixComponent = wrapper.read(Type.COMPONENT);
String prefix = prefixComponent == null || prefixComponent.isJsonNull() ? "" : ChatRewriter.jsonToLegacyText(prefixComponent.toString());
if (ViaBackwards.getConfig().addTeamColorTo1_13Prefix()) {
prefix += "§" + (colour > -1 && colour <= 15 ? Integer.toHexString(colour) : "r");
}
prefix = ChatUtil.removeUnusedColor(prefix, 'f', true);
if (prefix.length() > 16)
prefix = prefix.substring(0, 16);
if (prefix.endsWith("§"))
prefix = prefix.substring(0, prefix.length() - 1);
String suffix = suffixComponent == null || suffixComponent.isJsonNull() ? "" : ChatRewriter.jsonToLegacyText(suffixComponent.toString());
// Don't remove white coloring
suffix = ChatUtil.removeUnusedColor(suffix, '\0');
if (suffix.length() > 16)
suffix = suffix.substring(0, 16);
if (suffix.endsWith("§"))
suffix = suffix.substring(0, suffix.length() - 1);
wrapper.write(Type.STRING, prefix);
wrapper.write(Type.STRING, suffix);
wrapper.write(Type.BYTE, flags);
wrapper.write(Type.STRING, nameTagVisibility);
wrapper.write(Type.STRING, collisionRule);
wrapper.write(Type.BYTE, (byte) colour);
}
if (action == 0 || action == 3 || action == 4) {
// Entities
wrapper.passthrough(Type.STRING_ARRAY);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.DECLARE_COMMANDS, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
wrapper.cancel();
TabCompleteStorage storage = wrapper.user().get(TabCompleteStorage.class);
if (!storage.commands().isEmpty()) {
storage.commands().clear();
}
int size = wrapper.read(Type.VAR_INT);
boolean initialNodes = true;
for (int i = 0; i < size; i++) {
byte flags = wrapper.read(Type.BYTE);
// Children indices
wrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
if ((flags & 0x08) != 0) {
// Redirect node index
wrapper.read(Type.VAR_INT);
}
byte nodeType = (byte) (flags & 0x03);
if (initialNodes && nodeType == 2) {
initialNodes = false;
}
if (nodeType == 1 || nodeType == 2) {
// Literal/argument node
String name = wrapper.read(Type.STRING);
if (nodeType == 1 && initialNodes) {
storage.commands().add('/' + name);
}
}
if (nodeType == 2) {
// Argument node
commandRewriter.handleArgument(wrapper, wrapper.read(Type.STRING));
}
if ((flags & 0x10) != 0) {
// Suggestion type
wrapper.read(Type.STRING);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.TAB_COMPLETE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
TabCompleteStorage storage = wrapper.user().get(TabCompleteStorage.class);
if (storage.lastRequest() == null) {
wrapper.cancel();
return;
}
if (storage.lastId() != wrapper.read(Type.VAR_INT))
wrapper.cancel();
int start = wrapper.read(Type.VAR_INT);
int length = wrapper.read(Type.VAR_INT);
int lastRequestPartIndex = storage.lastRequest().lastIndexOf(' ') + 1;
// Client only replaces after space
if (lastRequestPartIndex != start)
wrapper.cancel();
if (length != storage.lastRequest().length() - lastRequestPartIndex) {
// We can't set the length in previous versions
wrapper.cancel();
}
int count = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < count; i++) {
String match = wrapper.read(Type.STRING);
wrapper.write(Type.STRING, (start == 0 && !storage.isLastAssumeCommand() ? "/" : "") + match);
// Ignore tooltip
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.STRING);
}
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_12_1.TAB_COMPLETE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
TabCompleteStorage storage = wrapper.user().get(TabCompleteStorage.class);
List<String> suggestions = new ArrayList<>();
String command = wrapper.read(Type.STRING);
boolean assumeCommand = wrapper.read(Type.BOOLEAN);
wrapper.read(Type.OPTIONAL_POSITION);
if (!assumeCommand && !command.startsWith("/")) {
// Complete usernames for non-commands
String buffer = command.substring(command.lastIndexOf(' ') + 1);
for (String value : storage.usernames().values()) {
if (startsWithIgnoreCase(value, buffer)) {
suggestions.add(value);
}
}
} else if (!storage.commands().isEmpty() && !command.contains(" ")) {
// Complete commands names with values from 'Declare Commands' packet
for (String value : storage.commands()) {
if (startsWithIgnoreCase(value, command)) {
suggestions.add(value);
}
}
}
if (!suggestions.isEmpty()) {
wrapper.cancel();
PacketWrapper response = wrapper.create(ClientboundPackets1_12_1.TAB_COMPLETE);
response.write(Type.VAR_INT, suggestions.size());
for (String value : suggestions) {
response.write(Type.STRING, value);
}
response.scheduleSend(Protocol1_12_2To1_13.class);
storage.setLastRequest(null);
return;
}
if (!assumeCommand && command.startsWith("/")) {
command = command.substring(1);
}
int id = ThreadLocalRandom.current().nextInt();
wrapper.write(Type.VAR_INT, id);
wrapper.write(Type.STRING, command);
storage.setLastId(id);
storage.setLastAssumeCommand(assumeCommand);
storage.setLastRequest(command);
});
}
});
protocol.registerServerbound(ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
String channel = wrapper.read(Type.STRING);
switch(channel) {
case "MC|BSign":
case "MC|BEdit":
wrapper.setId(0x0B);
Item book = wrapper.read(Type.ITEM);
wrapper.write(Type.FLAT_ITEM, protocol.getItemRewriter().handleItemToServer(book));
boolean signing = channel.equals("MC|BSign");
wrapper.write(Type.BOOLEAN, signing);
break;
case "MC|ItemName":
wrapper.setId(0x1C);
break;
case "MC|AdvCmd":
byte type = wrapper.read(Type.BYTE);
if (type == 0) {
// Information from https://wiki.vg/index.php?title=Plugin_channels&oldid=14089
// The Notchain client only uses this for command block minecarts and uses MC|AutoCmd for blocks, but the Notchian server still accepts it for either.
// Maybe older versions used this and we need to implement this? The issues is that we would have to save the command block types
wrapper.setId(0x22);
wrapper.cancel();
ViaBackwards.getPlatform().getLogger().warning("Client send MC|AdvCmd custom payload to update command block, weird!");
} else if (type == 1) {
wrapper.setId(0x23);
// Entity Id
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT));
// Command
wrapper.passthrough(Type.STRING);
// Track Output
wrapper.passthrough(Type.BOOLEAN);
} else {
wrapper.cancel();
}
break;
case "MC|AutoCmd":
{
wrapper.setId(0x22);
int x = wrapper.read(Type.INT);
int y = wrapper.read(Type.INT);
int z = wrapper.read(Type.INT);
wrapper.write(Type.POSITION, new Position(x, (short) y, z));
// Command
wrapper.passthrough(Type.STRING);
byte flags = 0;
// Track Output
if (wrapper.read(Type.BOOLEAN))
flags |= 0x01;
String mode = wrapper.read(Type.STRING);
int modeId = mode.equals("SEQUENCE") ? 0 : mode.equals("AUTO") ? 1 : 2;
wrapper.write(Type.VAR_INT, modeId);
// Is conditional
if (wrapper.read(Type.BOOLEAN))
flags |= 0x02;
// Automatic
if (wrapper.read(Type.BOOLEAN))
flags |= 0x04;
wrapper.write(Type.BYTE, flags);
break;
}
case "MC|Struct":
{
wrapper.setId(0x25);
int x = wrapper.read(Type.INT);
int y = wrapper.read(Type.INT);
int z = wrapper.read(Type.INT);
wrapper.write(Type.POSITION, new Position(x, (short) y, z));
wrapper.write(Type.VAR_INT, wrapper.read(Type.BYTE) - 1);
String mode = wrapper.read(Type.STRING);
int modeId = mode.equals("SAVE") ? 0 : mode.equals("LOAD") ? 1 : mode.equals("CORNER") ? 2 : 3;
wrapper.write(Type.VAR_INT, modeId);
// Name
wrapper.passthrough(Type.STRING);
// Offset X
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue());
// Offset Y
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue());
// Offset Z
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue());
// Size X
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue());
// Size Y
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue());
// Size Z
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue());
String mirror = wrapper.read(Type.STRING);
int mirrorId = mode.equals("NONE") ? 0 : mode.equals("LEFT_RIGHT") ? 1 : 2;
String rotation = wrapper.read(Type.STRING);
int rotationId = mode.equals("NONE") ? 0 : mode.equals("CLOCKWISE_90") ? 1 : mode.equals("CLOCKWISE_180") ? 2 : 3;
// Metadata
wrapper.passthrough(Type.STRING);
byte flags = 0;
// Ignore entities
if (wrapper.read(Type.BOOLEAN))
flags |= 0x01;
// Show air
if (wrapper.read(Type.BOOLEAN))
flags |= 0x02;
// Show bounding box
if (wrapper.read(Type.BOOLEAN))
flags |= 0x04;
// Integrity
wrapper.passthrough(Type.FLOAT);
// Seed
wrapper.passthrough(Type.VAR_LONG);
wrapper.write(Type.BYTE, flags);
break;
}
case "MC|Beacon":
wrapper.setId(0x20);
// Primary Effect
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT));
// Secondary Effect
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT));
break;
case "MC|TrSel":
wrapper.setId(0x1F);
// Slot
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT));
break;
case "MC|PickItem":
wrapper.setId(0x15);
break;
default:
String newChannel = InventoryPackets.getNewPluginChannelId(channel);
if (newChannel == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring incoming plugin message with channel: " + channel);
}
wrapper.cancel();
return;
}
wrapper.write(Type.STRING, newChannel);
if (newChannel.equals("minecraft:register") || newChannel.equals("minecraft:unregister")) {
String[] channels = new String(wrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (String s : channels) {
String rewritten = InventoryPackets.getNewPluginChannelId(s);
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in incoming REGISTER: " + s);
}
}
if (!rewrittenChannels.isEmpty()) {
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
} else {
wrapper.cancel();
return;
}
}
break;
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.STATISTICS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int size = wrapper.get(Type.VAR_INT, 0);
int newSize = size;
for (int i = 0; i < size; i++) {
int categoryId = wrapper.read(Type.VAR_INT);
int statisticId = wrapper.read(Type.VAR_INT);
String name = "";
// categories 0-7 (items, blocks, entities) - probably not feasible
switch(categoryId) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// remove value
wrapper.read(Type.VAR_INT);
newSize--;
continue;
case 8:
name = protocol.getMappingData().getStatisticMappings().get(statisticId);
if (name == null) {
wrapper.read(Type.VAR_INT);
newSize--;
continue;
}
break;
}
// string id
wrapper.write(Type.STRING, name);
// value
wrapper.passthrough(Type.VAR_INT);
}
if (newSize != size) {
wrapper.set(Type.VAR_INT, 0, newSize);
}
}
});
}
});
}
use of com.viaversion.viaversion.api.minecraft.Position in project ViaBackwards by ViaVersion.
the class BlockItemPackets1_13 method registerPackets.
@Override
protected void registerPackets() {
protocol.registerClientbound(ClientboundPackets1_13.COOLDOWN, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int itemId = wrapper.read(Type.VAR_INT);
int oldId = protocol.getMappingData().getItemMappings().get(itemId);
if (oldId != -1) {
Optional<String> eggEntityId = SpawnEggRewriter.getEntityId(oldId);
if (eggEntityId.isPresent()) {
itemId = 383 << 16;
} else {
itemId = (oldId >> 4) << 16 | oldId & 0xF;
}
}
wrapper.write(Type.VAR_INT, itemId);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_ACTION, new PacketRemapper() {
@Override
public void registerMap() {
// Location
map(Type.POSITION);
// Action Id
map(Type.UNSIGNED_BYTE);
// Action param
map(Type.UNSIGNED_BYTE);
// Block Id - /!\ NOT BLOCK STATE ID
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int blockId = wrapper.get(Type.VAR_INT, 0);
if (blockId == 73)
blockId = 25;
else if (blockId == 99)
blockId = 33;
else if (blockId == 92)
blockId = 29;
else if (blockId == 142)
blockId = 54;
else if (blockId == 305)
blockId = 146;
else if (blockId == 249)
blockId = 130;
else if (blockId == 257)
blockId = 138;
else if (blockId == 140)
blockId = 52;
else if (blockId == 472)
blockId = 209;
else if (blockId >= 483 && blockId <= 498)
blockId = blockId - 483 + 219;
wrapper.set(Type.VAR_INT, 0, blockId);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_ENTITY_DATA, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Position
map(Type.POSITION);
// 1 - Action
map(Type.UNSIGNED_BYTE);
// 2 - NBT Data
map(Type.NBT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
BackwardsBlockEntityProvider provider = Via.getManager().getProviders().get(BackwardsBlockEntityProvider.class);
// TODO conduit handling
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 5) {
wrapper.cancel();
}
wrapper.set(Type.NBT, 0, provider.transform(wrapper.user(), wrapper.get(Type.POSITION, 0), wrapper.get(Type.NBT, 0)));
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.UNLOAD_CHUNK, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int chunkMinX = wrapper.passthrough(Type.INT) << 4;
int chunkMinZ = wrapper.passthrough(Type.INT) << 4;
int chunkMaxX = chunkMinX + 15;
int chunkMaxZ = chunkMinZ + 15;
BackwardsBlockStorage blockStorage = wrapper.user().get(BackwardsBlockStorage.class);
blockStorage.getBlocks().entrySet().removeIf(entry -> {
Position position = entry.getKey();
return position.getX() >= chunkMinX && position.getZ() >= chunkMinZ && position.getX() <= chunkMaxX && position.getZ() <= chunkMaxZ;
});
}
});
}
});
// Block Change
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_CHANGE, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Position
map(Type.POSITION);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int blockState = wrapper.read(Type.VAR_INT);
Position position = wrapper.get(Type.POSITION, 0);
// Store blocks
BackwardsBlockStorage storage = wrapper.user().get(BackwardsBlockStorage.class);
storage.checkAndStore(position, blockState);
wrapper.write(Type.VAR_INT, protocol.getMappingData().getNewBlockStateId(blockState));
// Flower pot special treatment
flowerPotSpecialTreatment(wrapper.user(), blockState, position);
}
});
}
});
// Multi Block Change
protocol.registerClientbound(ClientboundPackets1_13.MULTI_BLOCK_CHANGE, new PacketRemapper() {
@Override
public void registerMap() {
// 0 - Chunk X
map(Type.INT);
// 1 - Chunk Z
map(Type.INT);
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
BackwardsBlockStorage storage = wrapper.user().get(BackwardsBlockStorage.class);
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
int chunkX = wrapper.get(Type.INT, 0);
int chunkZ = wrapper.get(Type.INT, 1);
int block = record.getBlockId();
Position position = new Position(record.getSectionX() + (chunkX * 16), record.getY(), record.getSectionZ() + (chunkZ * 16));
// Store if needed
storage.checkAndStore(position, block);
// Flower pot special treatment
flowerPotSpecialTreatment(wrapper.user(), block, position);
// Change to old id
record.setBlockId(protocol.getMappingData().getNewBlockStateId(block));
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.WINDOW_ITEMS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
map(Type.FLAT_ITEM_ARRAY, Type.ITEM_ARRAY);
handler(itemArrayHandler(Type.ITEM_ARRAY));
}
});
protocol.registerClientbound(ClientboundPackets1_13.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.FLAT_ITEM, Type.ITEM);
handler(itemToClientHandler(Type.ITEM));
}
});
protocol.registerClientbound(ClientboundPackets1_13.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type_old = new Chunk1_9_3_4Type(clientWorld);
Chunk1_13Type type = new Chunk1_13Type(clientWorld);
Chunk chunk = wrapper.read(type);
// Handle Block Entities before block rewrite
BackwardsBlockEntityProvider provider = Via.getManager().getProviders().get(BackwardsBlockEntityProvider.class);
BackwardsBlockStorage storage = wrapper.user().get(BackwardsBlockStorage.class);
for (CompoundTag tag : chunk.getBlockEntities()) {
Tag idTag = tag.get("id");
if (idTag == null)
continue;
String id = (String) idTag.getValue();
// Ignore if we don't handle it
if (!provider.isHandled(id))
continue;
int sectionIndex = ((NumberTag) tag.get("y")).asInt() >> 4;
if (sectionIndex < 0 || sectionIndex > 15) {
// 1.17 chunks
continue;
}
ChunkSection section = chunk.getSections()[sectionIndex];
int x = ((NumberTag) tag.get("x")).asInt();
int y = ((NumberTag) tag.get("y")).asInt();
int z = ((NumberTag) tag.get("z")).asInt();
Position position = new Position(x, (short) y, z);
int block = section.getFlatBlock(x & 0xF, y & 0xF, z & 0xF);
storage.checkAndStore(position, block);
provider.transform(wrapper.user(), position, tag);
}
// Rewrite new blocks to old blocks
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null) {
continue;
}
// Flower pots require a special treatment, they are no longer block entities :(
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
int block = section.getFlatBlock(x, y, z);
// Check if the block is a flower
if (FlowerPotHandler.isFlowah(block)) {
Position pos = new Position((x + (chunk.getX() << 4)), (short) (y + (i << 4)), (z + (chunk.getZ() << 4)));
// Store block
storage.checkAndStore(pos, block);
CompoundTag nbt = provider.transform(wrapper.user(), pos, "minecraft:flower_pot");
chunk.getBlockEntities().add(nbt);
}
}
}
}
for (int p = 0; p < section.getPaletteSize(); p++) {
int old = section.getPaletteEntry(p);
if (old != 0) {
int oldId = protocol.getMappingData().getNewBlockStateId(old);
section.setPaletteEntry(p, oldId);
}
}
}
if (chunk.isBiomeData()) {
for (int i = 0; i < 256; i++) {
int biome = chunk.getBiomeData()[i];
int newId = -1;
switch(biome) {
// end biomes
case 40:
case 41:
case 42:
case 43:
newId = 9;
break;
// deep ocean biomes
case 47:
case 48:
case 49:
newId = 24;
break;
case // deep frozen... let's just pick the frozen variant
50:
newId = 10;
break;
// the other new ocean biomes
case 44:
case 45:
case 46:
newId = 0;
break;
}
if (newId != -1) {
chunk.getBiomeData()[i] = newId;
}
}
}
wrapper.write(type_old, chunk);
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.EFFECT, new PacketRemapper() {
@Override
public void registerMap() {
// Effect Id
map(Type.INT);
// Location
map(Type.POSITION);
// Data
map(Type.INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int id = wrapper.get(Type.INT, 0);
int data = wrapper.get(Type.INT, 1);
if (id == 1010) {
// Play record
wrapper.set(Type.INT, 1, protocol.getMappingData().getItemMappings().get(data) >> 4);
} else if (id == 2001) {
// Block break + block break sound
data = protocol.getMappingData().getNewBlockStateId(data);
int blockId = data >> 4;
int blockData = data & 0xF;
wrapper.set(Type.INT, 1, (blockId & 0xFFF) | (blockData << 12));
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.MAP_DATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.BOOLEAN);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int iconCount = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < iconCount; i++) {
int type = wrapper.read(Type.VAR_INT);
byte x = wrapper.read(Type.BYTE);
byte z = wrapper.read(Type.BYTE);
byte direction = wrapper.read(Type.BYTE);
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.COMPONENT);
}
if (type > 9) {
wrapper.set(Type.VAR_INT, 1, wrapper.get(Type.VAR_INT, 1) - 1);
continue;
}
wrapper.write(Type.BYTE, (byte) ((type << 4) | (direction & 0x0F)));
wrapper.write(Type.BYTE, x);
wrapper.write(Type.BYTE, z);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_13.ENTITY_EQUIPMENT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.VAR_INT);
map(Type.FLAT_ITEM, Type.ITEM);
handler(itemToClientHandler(Type.ITEM));
}
});
protocol.registerClientbound(ClientboundPackets1_13.WINDOW_PROPERTY, new PacketRemapper() {
@Override
public void registerMap() {
// Window Id
map(Type.UNSIGNED_BYTE);
// Property
map(Type.SHORT);
// Value
map(Type.SHORT);
handler(wrapper -> {
short property = wrapper.get(Type.SHORT, 0);
// Enchantment table
if (property >= 4 && property <= 6) {
short oldId = wrapper.get(Type.SHORT, 1);
wrapper.set(Type.SHORT, 1, (short) protocol.getMappingData().getEnchantmentMappings().getNewId(oldId));
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_12_1.CREATIVE_INVENTORY_ACTION, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT);
map(Type.ITEM, Type.FLAT_ITEM);
handler(itemToServerHandler(Type.FLAT_ITEM));
}
});
protocol.registerServerbound(ServerboundPackets1_12_1.CLICK_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.BYTE);
map(Type.SHORT);
map(Type.VAR_INT);
map(Type.ITEM, Type.FLAT_ITEM);
handler(itemToServerHandler(Type.FLAT_ITEM));
}
});
}
Aggregations