ViaVersion/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java

738 lines
34 KiB
Java
Raw Normal View History

2018-07-18 19:10:43 +02:00
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets;
2018-12-15 12:13:05 +01:00
import com.github.steveice10.opennbt.conversion.ConverterRegistry;
import com.github.steveice10.opennbt.tag.builtin.*;
2018-07-02 16:36:03 +02:00
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
2018-07-15 14:26:26 +02:00
import com.google.common.io.BaseEncoding;
import us.myles.ViaVersion.api.PacketWrapper;
2018-07-29 13:14:17 +02:00
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
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_13to1_12_2.ChatRewriter;
2018-12-15 12:13:05 +01:00
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.BlockIdData;
2018-07-18 19:10:43 +02:00
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.SoundSource;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.SpawnEggRewriter;
2018-07-02 16:36:03 +02:00
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class InventoryPackets {
private static String NBT_TAG_NAME;
public static void register(Protocol protocol) {
NBT_TAG_NAME = "ViaVersion|" + protocol.getClass().getSimpleName();
/*
Outgoing packets
*/
// Set slot packet
protocol.registerOutgoing(State.PLAY, 0x16, 0x17, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM, Type.FLAT_ITEM); // 2 - Slot Value
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.FLAT_ITEM, 0);
toClient(stack);
}
});
}
});
// Window items packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x15, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.ITEM_ARRAY, Type.FLAT_ITEM_ARRAY); // 1 - Window Values
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item[] stacks = wrapper.get(Type.FLAT_ITEM_ARRAY, 0);
for (Item stack : stacks)
toClient(stack);
}
});
}
});
// Window property
protocol.registerOutgoing(State.PLAY, 0x15, 0x16, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Window id
map(Type.SHORT); // Property
map(Type.SHORT); // Value
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
short property = wrapper.get(Type.SHORT, 0);
if (property >= 4 && property <= 6) { // Enchantment id
wrapper.set(Type.SHORT, 1, (short) MappingData.enchantmentMappings.getNewEnchantment(
wrapper.get(Type.SHORT, 1)
));
}
}
});
}
});
// Plugin message Packet -> Trading
protocol.registerOutgoing(State.PLAY, 0x18, 0x19, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String channel = wrapper.get(Type.STRING, 0);
2018-01-07 17:28:50 +01:00
// Handle stopsound change TODO change location of this remap to other class?
if (channel.equalsIgnoreCase("MC|StopSound")) {
String originalSource = wrapper.read(Type.STRING);
String originalSound = wrapper.read(Type.STRING);
// Reset the packet
wrapper.clearPacket();
wrapper.setId(0x4C);
byte flags = 0;
wrapper.write(Type.BYTE, flags); // Placeholder
if (!originalSource.isEmpty()) {
flags |= 1;
Optional<SoundSource> finalSource = SoundSource.findBySource(originalSource);
if (!finalSource.isPresent()) {
if (!Via.getConfig().isSuppress1_13ConversionErrors() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().info("Could not handle unknown sound source " + originalSource + " falling back to default: master");
}
finalSource = Optional.of(SoundSource.MASTER);
}
wrapper.write(Type.VAR_INT, finalSource.get().getId());
}
if (!originalSound.isEmpty()) {
flags |= 2;
wrapper.write(Type.STRING, originalSound);
}
wrapper.set(Type.BYTE, 0, flags); // Update flags
2018-06-22 14:19:57 +02:00
return;
} else if (channel.equalsIgnoreCase("MC|TrList")) {
channel = "minecraft:trader_list";
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
// Input Item
2018-07-13 20:23:07 +02:00
Item input = wrapper.read(Type.ITEM);
2018-06-22 14:19:57 +02:00
InventoryPackets.toClient(input);
2018-07-13 20:23:07 +02:00
wrapper.write(Type.FLAT_ITEM, input);
// Output Item
2018-07-13 20:23:07 +02:00
Item output = wrapper.read(Type.ITEM);
2018-06-22 14:19:57 +02:00
InventoryPackets.toClient(output);
2018-07-13 20:23:07 +02:00
wrapper.write(Type.FLAT_ITEM, output);
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) {
// Second Item
2018-07-13 20:23:07 +02:00
Item second = wrapper.read(Type.ITEM);
2018-06-22 14:19:57 +02:00
InventoryPackets.toClient(second);
2018-07-13 20:23:07 +02:00
wrapper.write(Type.FLAT_ITEM, second);
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
}
2018-06-22 14:19:57 +02:00
} else {
2018-07-15 14:26:26 +02:00
channel = getNewPluginChannelId(channel);
2018-07-02 16:36:03 +02:00
if (channel == null) {
wrapper.cancel();
return;
} else if (channel.equals("minecraft:register") || channel.equals("minecraft:unregister")) {
String[] channels = new String(wrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (int i = 0; i < channels.length; i++) {
2018-07-15 14:26:26 +02:00
String rewritten = getNewPluginChannelId(channels[i]);
2018-07-29 13:14:17 +02:00
if (rewritten != null) {
2018-07-02 16:36:03 +02:00
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppress1_13ConversionErrors() || Via.getManager().isDebug()) {
2018-07-29 13:14:17 +02:00
Via.getPlatform().getLogger().warning("Ignoring plugin channel in REGISTER: " + channels[i]);
}
2018-07-02 16:36:03 +02:00
}
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
}
}
2018-06-22 14:19:57 +02:00
wrapper.set(Type.STRING, 0, channel);
}
2018-07-02 16:36:03 +02:00
// TODO Fix trading GUI
});
}
});
// Entity Equipment Packet
2018-07-11 15:13:36 +02:00
protocol.registerOutgoing(State.PLAY, 0x3F, 0x42, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.VAR_INT); // 1 - Slot ID
map(Type.ITEM, Type.FLAT_ITEM); // 2 - Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.FLAT_ITEM, 0);
toClient(stack);
}
});
}
});
/*
Incoming packets
*/
// Click window packet
2018-07-14 12:53:31 +02:00
protocol.registerIncoming(State.PLAY, 0x07, 0x08, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.FLAT_ITEM, Type.ITEM); // 5 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
toServer(item);
}
});
}
}
);
// Plugin message
2018-07-11 14:47:13 +02:00
protocol.registerIncoming(State.PLAY, 0x09, 0x0A, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String channel = wrapper.get(Type.STRING, 0);
2018-07-15 14:26:26 +02:00
channel = getOldPluginChannelId(channel);
if (channel == null) {
wrapper.cancel();
return;
} else if (channel.equals("REGISTER") || channel.equals("UNREGISTER")) {
String[] channels = new String(wrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (int i = 0; i < channels.length; i++) {
2018-07-15 14:26:26 +02:00
String rewritten = getOldPluginChannelId(channels[i]);
2018-07-29 13:14:17 +02:00
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppress1_13ConversionErrors() || Via.getManager().isDebug()) {
2018-07-29 13:14:17 +02:00
Via.getPlatform().getLogger().warning("Ignoring plugin channel in REGISTER: " + channels[i]);
}
}
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
}
wrapper.set(Type.STRING, 0, channel);
}
});
}
});
// Creative Inventory Action
2018-07-11 14:47:13 +02:00
protocol.registerIncoming(State.PLAY, 0x1B, 0x24, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT); // 0 - Slot
map(Type.FLAT_ITEM, Type.ITEM); // 1 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
toServer(item);
}
});
}
}
);
}
2018-04-08 17:02:46 +02:00
// TODO CLEANUP / SMARTER REWRITE SYSTEM
2018-07-02 16:36:03 +02:00
// TODO Rewrite identifiers
public static void toClient(Item item) {
if (item == null) return;
2018-03-20 18:21:37 +01:00
CompoundTag tag = item.getTag();
// Save original id
int originalId = (item.getId() << 16 | item.getData() & 0xFFFF);
2018-07-20 12:14:51 +02:00
int rawId = (item.getId() << 4 | item.getData() & 0xF);
2018-07-17 22:40:39 +02:00
// NBT Additions
2018-03-20 18:21:37 +01:00
if (isDamageable(item.getId())) {
2018-07-17 22:40:39 +02:00
if (tag == null) item.setTag(tag = new CompoundTag("tag"));
2018-03-20 18:21:37 +01:00
tag.put(new IntTag("Damage", item.getData()));
}
if (item.getId() == 358) { // map
2018-07-17 22:40:39 +02:00
if (tag == null) item.setTag(tag = new CompoundTag("tag"));
2018-03-20 18:21:37 +01:00
tag.put(new IntTag("map", item.getData()));
}
2018-07-17 22:40:39 +02:00
// NBT Changes
if (tag != null) {
// Invert shield color id
2018-07-18 20:23:46 +02:00
if (item.getId() == 442 || item.getId() == 425) {
2018-07-17 22:40:39 +02:00
if (tag.get("BlockEntityTag") instanceof CompoundTag) {
CompoundTag blockEntityTag = tag.get("BlockEntityTag");
if (blockEntityTag.get("Base") instanceof IntTag) {
IntTag base = blockEntityTag.get("Base");
base.setValue(15 - base.getValue());
}
2018-07-18 20:23:46 +02:00
if (blockEntityTag.get("Patterns") instanceof ListTag) {
for (Tag pattern : (ListTag) blockEntityTag.get("Patterns")) {
if (pattern instanceof CompoundTag) {
IntTag c = ((CompoundTag) pattern).get("Color");
c.setValue(15 - c.getValue()); // Invert color id
}
}
}
2018-03-20 18:21:37 +01:00
}
}
2018-07-17 22:40:39 +02:00
// Display Name now uses JSON
if (tag.get("display") instanceof CompoundTag) {
CompoundTag display = tag.get("display");
if (display.get("Name") instanceof StringTag) {
StringTag name = display.get("Name");
display.put(new StringTag(NBT_TAG_NAME + "|Name", name.getValue()));
2018-07-17 22:40:39 +02:00
name.setValue(
ChatRewriter.legacyTextToJson(
2018-07-17 22:40:39 +02:00
name.getValue()
)
2018-07-17 22:40:39 +02:00
);
}
}
2018-07-17 22:40:39 +02:00
// ench is now Enchantments and now uses identifiers
if (tag.get("ench") instanceof ListTag) {
ListTag ench = tag.get("ench");
ListTag enchantments = new ListTag("Enchantments", CompoundTag.class);
for (Tag enchEntry : ench) {
if (enchEntry instanceof CompoundTag) {
CompoundTag enchantmentEntry = new CompoundTag("");
2018-07-20 20:54:52 +02:00
short oldId = ((Number) ((CompoundTag) enchEntry).get("id").getValue()).shortValue();
2018-07-20 20:47:05 +02:00
String newId = MappingData.oldEnchantmentsIds.get(oldId);
2018-07-29 13:14:17 +02:00
if (newId == null) {
newId = "viaversion:legacy/" + oldId;
2018-07-20 20:47:05 +02:00
}
enchantmentEntry.put(new StringTag("id", newId));
2018-07-20 20:58:04 +02:00
enchantmentEntry.put(new ShortTag("lvl", ((Number) ((CompoundTag) enchEntry).get("lvl").getValue()).shortValue()));
2018-07-17 22:40:39 +02:00
enchantments.add(enchantmentEntry);
}
}
tag.remove("ench");
tag.put(enchantments);
}
2018-07-19 09:51:38 +02:00
if (tag.get("StoredEnchantments") instanceof ListTag) {
ListTag storedEnch = tag.get("StoredEnchantments");
ListTag newStoredEnch = new ListTag("StoredEnchantments", CompoundTag.class);
for (Tag enchEntry : storedEnch) {
if (enchEntry instanceof CompoundTag) {
CompoundTag enchantmentEntry = new CompoundTag("");
2018-07-20 20:54:52 +02:00
short oldId = ((Number) ((CompoundTag) enchEntry).get("id").getValue()).shortValue();
2018-07-20 20:47:05 +02:00
String newId = MappingData.oldEnchantmentsIds.get(oldId);
if (newId == null) {
2018-07-29 13:14:17 +02:00
newId = "viaversion:legacy/" + oldId;
2018-07-20 20:47:05 +02:00
}
2018-07-19 09:51:38 +02:00
enchantmentEntry.put(new StringTag("id",
2018-07-20 20:47:05 +02:00
newId
2018-07-19 09:51:38 +02:00
));
2018-07-20 20:58:04 +02:00
enchantmentEntry.put(new ShortTag("lvl", ((Number) ((CompoundTag) enchEntry).get("lvl").getValue()).shortValue()));
2018-07-19 09:51:38 +02:00
newStoredEnch.add(enchantmentEntry);
}
}
tag.remove("StoredEnchantments");
tag.put(newStoredEnch);
}
2018-12-15 12:13:05 +01:00
if (tag.get("CanPlaceOn") instanceof ListTag) {
ListTag old = tag.get("CanPlaceOn");
ListTag newCanPlaceOn = new ListTag("CanPlaceOn", StringTag.class);
tag.put(ConverterRegistry.convertToTag(NBT_TAG_NAME + "|CanPlaceOn", ConverterRegistry.convertToValue(old))); // There will be data losing
for (Tag oldTag : old) {
Object value = oldTag.getValue();
String[] newValues = BlockIdData.blockIdMapping.get(value instanceof String
? ((String) value).replace("minecraft:", "")
: null);
if (newValues != null) {
for (String newValue : newValues) {
newCanPlaceOn.add(new StringTag("", newValue));
}
} else {
newCanPlaceOn.add(oldTag);
}
}
tag.put(newCanPlaceOn);
}
if (tag.get("CanDestroy") instanceof ListTag) {
ListTag old = tag.get("CanDestroy");
ListTag newCanDestroy = new ListTag("CanDestroy", StringTag.class);
tag.put(ConverterRegistry.convertToTag(NBT_TAG_NAME + "|CanDestroy", ConverterRegistry.convertToValue(old))); // There will be data losing
for (Tag oldTag : old) {
Object value = oldTag.getValue();
String[] newValues = BlockIdData.blockIdMapping.get(value instanceof String
? ((String) value).replace("minecraft:", "")
: null);
if (newValues != null) {
for (String newValue : newValues) {
newCanDestroy.add(new StringTag("", newValue));
}
} else {
newCanDestroy.add(oldTag);
}
}
tag.put(newCanDestroy);
}
2018-07-20 12:14:51 +02:00
// Handle SpawnEggs
if (item.getId() == 383) {
if (tag.get("EntityTag") instanceof CompoundTag) {
CompoundTag entityTag = tag.get("EntityTag");
if (entityTag.get("id") instanceof StringTag) {
StringTag identifier = entityTag.get("id");
rawId = SpawnEggRewriter.getSpawnEggId(identifier.getValue());
if (rawId == -1) {
rawId = 25100288; // Bat fallback
} else {
entityTag.remove("id");
if (entityTag.isEmpty())
tag.remove("EntityTag");
}
} else {
// Fallback to bat
rawId = 25100288;
}
2018-04-08 17:02:46 +02:00
} else {
// Fallback to bat
rawId = 25100288;
}
2018-07-20 12:14:51 +02:00
}
if (tag.isEmpty()) {
item.setTag(tag = null);
2018-04-08 17:02:46 +02:00
}
}
if (!MappingData.oldToNewItems.containsKey(rawId)) {
2018-07-17 22:40:39 +02:00
if (!isDamageable(item.getId()) && item.getId() != 358) { // Map
if (tag == null) item.setTag(tag = new CompoundTag("tag"));
tag.put(new IntTag(NBT_TAG_NAME, originalId)); // Data will be lost, saving original id
}
if (item.getId() == 31 && item.getData() == 0) { // Shrub was removed
2018-07-17 22:51:31 +02:00
rawId = 32 << 4; // Dead Bush
2018-07-17 22:40:39 +02:00
} else if (MappingData.oldToNewItems.containsKey(rawId & ~0xF)) {
2018-04-20 00:39:30 +02:00
rawId &= ~0xF; // Remove data
} else {
if (!Via.getConfig().isSuppress1_13ConversionErrors() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Failed to get 1.13 item for " + item.getId());
}
rawId = 16; // Stone
}
}
item.setId(MappingData.oldToNewItems.get(rawId).shortValue());
item.setData((short) 0);
}
2018-07-29 13:14:17 +02:00
public static String getNewPluginChannelId(String old) {
switch (old) {
case "MC|TrList":
return "minecraft:trader_list";
case "MC|Brand":
return "minecraft:brand";
case "MC|BOpen":
return "minecraft:book_open";
case "MC|DebugPath":
return "minecraft:debug/paths";
case "MC|DebugNeighborsUpdate":
return "minecraft:debug/neighbors_update";
case "REGISTER":
return "minecraft:register";
case "UNREGISTER":
return "minecraft:unregister";
case "BungeeCord":
return "bungeecord:main";
case "WDL|INIT":
return "wdl:init";
case "WDL|CONTROL":
return "wdl:init";
case "WDL|REQUEST":
return "wdl:request";
default:
return old.matches("([0-9a-z_-]*:)?[0-9a-z_/.-]*") // Identifier regex
2018-07-29 13:14:17 +02:00
? old
: "viaversion:legacy/" + BaseEncoding.base32().lowerCase().withPadChar('-').encode(
old.getBytes(StandardCharsets.UTF_8));
}
}
public static void toServer(Item item) {
if (item == null) return;
2018-03-20 18:21:37 +01:00
Integer rawId = null;
boolean gotRawIdFromTag = false;
2018-03-20 18:21:37 +01:00
CompoundTag tag = item.getTag();
// Use tag to get original ID and data
2018-03-20 18:21:37 +01:00
if (tag != null) {
// Check for valid tag
if (tag.get(NBT_TAG_NAME) instanceof IntTag) {
rawId = (Integer) tag.get(NBT_TAG_NAME).getValue();
// Remove the tag
tag.remove(NBT_TAG_NAME);
gotRawIdFromTag = true;
}
}
2018-03-20 18:21:37 +01:00
if (rawId == null) {
2018-07-17 22:40:39 +02:00
Integer oldId = MappingData.oldToNewItems.inverse().get((int) item.getId());
if (oldId != null) {
// Handle spawn eggs
Optional<String> eggEntityId = SpawnEggRewriter.getEntityId(oldId);
if (eggEntityId.isPresent()) {
rawId = 383 << 16;
if (tag == null)
item.setTag(tag = new CompoundTag("tag"));
if (!tag.contains("EntityTag")) {
CompoundTag entityTag = new CompoundTag("EntityTag");
entityTag.put(new StringTag("id", eggEntityId.get()));
tag.put(entityTag);
2018-04-20 00:39:30 +02:00
}
} else {
rawId = (oldId >> 4) << 16 | oldId & 0xF;
2018-03-20 18:21:37 +01:00
}
}
}
2018-04-20 00:39:30 +02:00
if (rawId == null) {
if (!Via.getConfig().isSuppress1_13ConversionErrors() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Failed to get 1.12 item for " + item.getId());
}
2018-04-20 00:39:30 +02:00
rawId = 0x10000; // Stone
}
item.setId((short) (rawId >> 16));
item.setData((short) (rawId & 0xFFFF));
// NBT changes
2018-04-20 00:39:30 +02:00
if (tag != null) {
if (isDamageable(item.getId())) {
if (tag.get("Damage") instanceof IntTag) {
if (!gotRawIdFromTag)
item.setData((short) (int) tag.get("Damage").getValue());
tag.remove("Damage");
2018-03-20 18:21:37 +01:00
}
2018-04-20 00:39:30 +02:00
}
2018-04-20 00:39:30 +02:00
if (item.getId() == 358) { // map
if (tag.get("map") instanceof IntTag) {
if (!gotRawIdFromTag)
item.setData((short) (int) tag.get("map").getValue());
tag.remove("map");
2018-03-20 18:21:37 +01:00
}
2018-04-20 00:39:30 +02:00
}
2018-07-18 20:23:46 +02:00
if (item.getId() == 442 || item.getId() == 425) { // shield / banner
2018-04-20 00:39:30 +02:00
if (tag.get("BlockEntityTag") instanceof CompoundTag) {
CompoundTag blockEntityTag = tag.get("BlockEntityTag");
if (blockEntityTag.get("Base") instanceof IntTag) {
IntTag base = blockEntityTag.get("Base");
base.setValue(15 - base.getValue()); // invert color id
2018-03-20 18:21:37 +01:00
}
2018-07-18 20:23:46 +02:00
if (blockEntityTag.get("Patterns") instanceof ListTag) {
for (Tag pattern : (ListTag) blockEntityTag.get("Patterns")) {
if (pattern instanceof CompoundTag) {
IntTag c = ((CompoundTag) pattern).get("Color");
c.setValue(15 - c.getValue()); // Invert color id
}
}
}
2018-03-20 18:21:37 +01:00
}
}
// Display Name now uses JSON
if (tag.get("display") instanceof CompoundTag) {
CompoundTag display = tag.get("display");
if (((CompoundTag) tag.get("display")).get("Name") instanceof StringTag) {
StringTag name = display.get("Name");
StringTag via = display.get(NBT_TAG_NAME + "|Name");
name.setValue(
via != null ? via.getValue() : ChatRewriter.jsonTextToLegacy(
name.getValue()
)
);
display.remove(NBT_TAG_NAME + "|Name");
}
}
// ench is now Enchantments and now uses identifiers
if (tag.get("Enchantments") instanceof ListTag) {
ListTag enchantments = tag.get("Enchantments");
ListTag ench = new ListTag("ench", CompoundTag.class);
for (Tag enchantmentEntry : enchantments) {
if (enchantmentEntry instanceof CompoundTag) {
CompoundTag enchEntry = new CompoundTag("");
2018-07-20 20:47:05 +02:00
String newId = (String) ((CompoundTag) enchantmentEntry).get("id").getValue();
Short oldId = MappingData.oldEnchantmentsIds.inverse().get(newId);
2018-07-29 13:14:17 +02:00
if (oldId == null && newId.startsWith("viaversion:legacy/")) {
2018-07-20 20:47:05 +02:00
oldId = Short.valueOf(newId.substring(18));
}
enchEntry.put(
new ShortTag(
"id",
2018-07-20 20:47:05 +02:00
oldId
)
);
enchEntry.put(new ShortTag("lvl", (Short) ((CompoundTag) enchantmentEntry).get("lvl").getValue()));
ench.add(enchEntry);
}
}
2019-01-23 17:03:10 +01:00
tag.remove("Enchantments");
tag.put(ench);
}
2018-07-19 09:51:38 +02:00
if (tag.get("StoredEnchantments") instanceof ListTag) {
ListTag storedEnch = tag.get("StoredEnchantments");
ListTag newStoredEnch = new ListTag("StoredEnchantments", CompoundTag.class);
for (Tag enchantmentEntry : storedEnch) {
if (enchantmentEntry instanceof CompoundTag) {
2018-07-29 13:14:17 +02:00
CompoundTag enchEntry = new CompoundTag("");
String newId = (String) ((CompoundTag) enchantmentEntry).get("id").getValue();
2018-07-20 20:54:52 +02:00
Short oldId = MappingData.oldEnchantmentsIds.inverse().get(newId);
2018-07-29 13:14:17 +02:00
if (oldId == null && newId.startsWith("viaversion:legacy/")) {
2018-07-20 20:54:52 +02:00
oldId = Short.valueOf(newId.substring(18));
}
2018-07-19 09:51:38 +02:00
enchEntry.put(
new ShortTag(
"id",
2018-07-20 20:54:52 +02:00
oldId
2018-07-19 09:51:38 +02:00
)
);
enchEntry.put(new ShortTag("lvl", (Short) ((CompoundTag) enchantmentEntry).get("lvl").getValue()));
newStoredEnch.add(enchEntry);
}
}
tag.remove("StoredEnchantments");
tag.put(newStoredEnch);
}
2018-12-15 12:13:05 +01:00
if (tag.get(NBT_TAG_NAME + "|CanPlaceOn") instanceof ListTag) {
tag.put(ConverterRegistry.convertToTag(
"CanPlaceOn",
ConverterRegistry.convertToValue(tag.get(NBT_TAG_NAME + "|CanPlaceOn"))
));
tag.remove(NBT_TAG_NAME + "|CanPlaceOn");
} else if (tag.get("CanPlaceOn") instanceof ListTag) {
ListTag old = tag.get("CanPlaceOn");
ListTag newCanPlaceOn = new ListTag("CanPlaceOn", StringTag.class);
for (Tag oldTag : old) {
Object value = oldTag.getValue();
String[] newValues = BlockIdData.fallbackReverseMapping.get(value instanceof String
? ((String) value).replace("minecraft:", "")
: null);
if (newValues != null) {
for (String newValue : newValues) {
newCanPlaceOn.add(new StringTag("", newValue));
}
} else {
newCanPlaceOn.add(oldTag);
}
}
tag.put(newCanPlaceOn);
}
if (tag.get(NBT_TAG_NAME + "|CanDestroy") instanceof ListTag) {
tag.put(ConverterRegistry.convertToTag(
"CanDestroy",
ConverterRegistry.convertToValue(tag.get(NBT_TAG_NAME + "|CanDestroy"))
));
tag.remove(NBT_TAG_NAME + "|CanDestroy");
} else if (tag.get("CanDestroy") instanceof ListTag) {
ListTag old = tag.get("CanDestroy");
ListTag newCanDestroy = new ListTag("CanDestroy", StringTag.class);
for (Tag oldTag : old) {
Object value = oldTag.getValue();
String[] newValues = BlockIdData.fallbackReverseMapping.get(value instanceof String
? ((String) value).replace("minecraft:", "")
: null);
if (newValues != null) {
for (String newValue : newValues) {
newCanDestroy.add(new StringTag("", newValue));
}
} else {
newCanDestroy.add(oldTag);
}
}
tag.put(newCanDestroy);
}
2018-03-20 18:21:37 +01:00
}
}
2018-07-15 14:26:26 +02:00
public static String getOldPluginChannelId(String newId) {
switch (newId) {
case "minecraft:register":
2018-07-15 14:26:26 +02:00
return "REGISTER";
case "minecraft:unregister":
2018-07-15 14:26:26 +02:00
return "UNREGISTER";
case "minecraft:brand":
2018-07-15 14:26:26 +02:00
return "MC|Brand";
case "bungeecord:main":
return "BungeeCord";
2018-07-21 23:18:31 +02:00
case "wdl:init":
return "WDL|INIT";
case "wdl:control":
return "WDL|CONTROL";
case "wdl:request":
return "WDL|REQUEST";
default:
return newId.startsWith("viaversion:legacy/") // Our format :)
2018-07-15 14:26:26 +02:00
? new String(BaseEncoding.base32().lowerCase().withPadChar('-').decode(
newId.substring(18)), StandardCharsets.UTF_8)
: newId.startsWith("legacy:")
? newId.substring(7) // Rewrite BungeeCord's format. It will only prevent kicks, plugins will still be broken because of case-sensitivity *plays sad violin*
: newId.startsWith("bungeecord:legacy/")
? newId.substring(18)
2018-07-15 14:26:26 +02:00
: newId;
}
}
2018-07-29 13:14:17 +02:00
public static boolean isDamageable(int id) {
return id >= 256 && id <= 259 // iron shovel, pickaxe, axe, flint and steel
|| id == 261 // bow
|| id >= 267 && id <= 279 // iron sword, wooden+stone+diamond swords, shovels, pickaxes, axes
|| id >= 283 && id <= 286 // gold sword, shovel, pickaxe, axe
|| id >= 290 && id <= 294 // hoes
|| id >= 298 && id <= 317 // armors
|| id == 346 // fishing rod
|| id == 359 // shears
|| id == 398 // carrot on a stick
|| id == 442 // shield
|| id == 443; // elytra
}
}