Rewrite block/item/entity ids in statistics

Still todo: Rewrite change in category ids in various versions
This commit is contained in:
KennyTV 2020-08-12 22:14:50 +02:00
parent e45c82ee87
commit 0ec1116a9e
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
7 changed files with 154 additions and 35 deletions

View File

@ -1,6 +1,6 @@
package us.myles.ViaVersion.api.rewriters;
public enum TagType {
public enum RegistryType {
BLOCK,
ITEM,

View File

@ -0,0 +1,104 @@
package us.myles.ViaVersion.api.rewriters;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
public class StatisticsRewriter {
private final Protocol protocol;
private final IdRewriteFunction blockRewriter;
private final IdRewriteFunction itemRewriter;
private final IdRewriteFunction entityRewriter;
private final IdRewriteFunction categoryIdRewriter;
public StatisticsRewriter(Protocol protocol,
@Nullable IdRewriteFunction blockRewriter, @Nullable IdRewriteFunction itemRewriter, @Nullable IdRewriteFunction entityRewriter,
@Nullable IdRewriteFunction categoryIdRewriter) {
this.protocol = protocol;
this.blockRewriter = blockRewriter;
this.itemRewriter = itemRewriter;
this.entityRewriter = entityRewriter;
this.categoryIdRewriter = categoryIdRewriter;
}
public StatisticsRewriter(Protocol protocol, @Nullable IdRewriteFunction blockRewriter, @Nullable IdRewriteFunction itemRewriter, @Nullable IdRewriteFunction entityRewriter) {
this(protocol, blockRewriter, itemRewriter, entityRewriter, null);
}
public void register(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, 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++) {
int categoryId = wrapper.read(Type.VAR_INT);
int statisticId = wrapper.read(Type.VAR_INT);
int value = wrapper.read(Type.VAR_INT);
// Rewrite category id
if (categoryIdRewriter != null) {
categoryId = categoryIdRewriter.rewrite(categoryId);
if (categoryId == -1) {
// Remove entry
newSize--;
continue;
}
}
wrapper.write(Type.VAR_INT, categoryId);
RegistryType type = getRegistryTypeForStatistic(categoryId);
IdRewriteFunction statisticsRewriter;
// Rewrite the block/item/entity id
if (type != null && (statisticsRewriter = getRewriter(type)) != null) {
wrapper.write(Type.VAR_INT, statisticsRewriter.rewrite(statisticId));
} else {
wrapper.write(Type.VAR_INT, statisticId);
}
wrapper.write(Type.VAR_INT, value);
}
if (newSize != size) {
wrapper.set(Type.VAR_INT, 0, newSize);
}
});
}
});
}
@Nullable
protected IdRewriteFunction getRewriter(RegistryType type) {
switch (type) {
case BLOCK:
return blockRewriter;
case ITEM:
return itemRewriter;
case ENTITY:
return entityRewriter;
}
throw new IllegalArgumentException("Unknown registry type in statistics packet: " + type);
}
@Nullable
public RegistryType getRegistryTypeForStatistic(int statisticsId) {
switch (statisticsId) {
case 0:
return RegistryType.BLOCK;
case 1:
case 2:
case 3:
case 4:
case 5:
return RegistryType.ITEM;
case 6:
case 7:
return RegistryType.ENTITY;
default:
return null;
}
}
}

View File

@ -32,18 +32,18 @@ public class TagRewriter {
/**
* Adds an empty tag (since the client crashes if a checked tag is not registered.)
*/
public void addEmptyTag(TagType tagType, String id) {
public void addEmptyTag(RegistryType tagType, String id) {
getNewTags(tagType).add(new TagData(id, EMPTY_ARRAY));
}
public void addEmptyTags(TagType tagType, String... ids) {
public void addEmptyTags(RegistryType tagType, String... ids) {
List<TagData> tagList = getNewTags(tagType);
for (String id : ids) {
tagList.add(new TagData(id, EMPTY_ARRAY));
}
}
public void addTag(TagType tagType, String id, int... oldIds) {
public void addTag(RegistryType tagType, String id, int... oldIds) {
List<TagData> newTags = getNewTags(tagType);
IdRewriteFunction rewriteFunction = getRewriter(tagType);
for (int i = 0; i < oldIds.length; i++) {
@ -108,7 +108,7 @@ public class TagRewriter {
}
}
private List<TagData> getNewTags(TagType tagType) {
private List<TagData> getNewTags(RegistryType tagType) {
switch (tagType) {
case BLOCK:
return newBlockTags;
@ -122,7 +122,7 @@ public class TagRewriter {
}
}
private IdRewriteFunction getRewriter(TagType tagType) {
private IdRewriteFunction getRewriter(RegistryType tagType) {
switch (tagType) {
case BLOCK:
return blockRewriter;

View File

@ -8,6 +8,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
@ -29,7 +30,7 @@ public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, Clien
@Override
protected void registerPackets() {
new MetadataRewriter1_14To1_13_2(this);
MetadataRewriter1_14To1_13_2 metadataRewriter = new MetadataRewriter1_14To1_13_2(this);
InventoryPackets.register(this);
EntityPackets.register(this);
@ -37,6 +38,8 @@ public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, Clien
PlayerPackets.register(this);
new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id)).registerSound(ClientboundPackets1_13.SOUND);
new StatisticsRewriter(this, Protocol1_14To1_13_2::getNewBlockId,
InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId).register(ClientboundPackets1_13.STATISTICS);
ComponentRewriter componentRewriter = new ComponentRewriter1_14(this);
componentRewriter.registerChatMessage(ClientboundPackets1_13.CHAT_MESSAGE);

View File

@ -4,9 +4,10 @@ import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.RegistryType;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.rewriters.TagRewriter;
import us.myles.ViaVersion.api.rewriters.TagType;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
@ -28,7 +29,7 @@ public class Protocol1_15To1_14_4 extends Protocol<ClientboundPackets1_14, Clien
@Override
protected void registerPackets() {
new MetadataRewriter1_15To1_14_4(this);
MetadataRewriter1_15To1_14_4 metadataRewriter = new MetadataRewriter1_15To1_14_4(this);
EntityPackets.register(this);
PlayerPackets.register(this);
@ -39,6 +40,9 @@ public class Protocol1_15To1_14_4 extends Protocol<ClientboundPackets1_14, Clien
soundRewriter.registerSound(ClientboundPackets1_14.ENTITY_SOUND); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14.SOUND);
new StatisticsRewriter(this, Protocol1_15To1_14_4::getNewBlockId,
InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId).register(ClientboundPackets1_14.STATISTICS);
registerIncoming(ServerboundPackets1_14.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
@ -59,7 +63,7 @@ public class Protocol1_15To1_14_4 extends Protocol<ClientboundPackets1_14, Clien
for (int i = 0; i < 17; i++) {
shulkerBoxes[i] = shulkerBoxOffset + i;
}
tagRewriter.addTag(TagType.BLOCK, "minecraft:shulker_boxes", shulkerBoxes);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:shulker_boxes", shulkerBoxes);
}
public static int getNewBlockStateId(int id) {

View File

@ -4,9 +4,10 @@ import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.RegistryType;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.rewriters.TagRewriter;
import us.myles.ViaVersion.api.rewriters.TagType;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.metadata.MetadataRewriter1_16_2To1_16_1;
@ -36,6 +37,9 @@ public class Protocol1_16_2To1_16_1 extends Protocol<ClientboundPackets1_16, Cli
tagRewriter = new TagRewriter(this, Protocol1_16_2To1_16_1::getNewBlockId, InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId);
tagRewriter.register(ClientboundPackets1_16.TAGS);
new StatisticsRewriter(this, Protocol1_16_2To1_16_1::getNewBlockId, InventoryPackets::getNewItemId,
metadataRewriter::getNewEntityId).register(ClientboundPackets1_16.STATISTICS);
SoundRewriter soundRewriter = new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id));
soundRewriter.registerSound(ClientboundPackets1_16.SOUND);
soundRewriter.registerSound(ClientboundPackets1_16.ENTITY_SOUND);
@ -76,14 +80,14 @@ public class Protocol1_16_2To1_16_1 extends Protocol<ClientboundPackets1_16, Cli
protected void loadMappingData() {
MappingData.init();
tagRewriter.addTag(TagType.ITEM, "minecraft:stone_crafting_materials", 14, 962);
tagRewriter.addEmptyTag(TagType.BLOCK, "minecraft:mushroom_grow_block");
tagRewriter.addTag(RegistryType.ITEM, "minecraft:stone_crafting_materials", 14, 962);
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:mushroom_grow_block");
// The client now wants ALL (previous) tags to be sent, sooooo :>
tagRewriter.addEmptyTags(TagType.ITEM, "minecraft:soul_fire_base_blocks", "minecraft:furnace_materials", "minecraft:crimson_stems",
tagRewriter.addEmptyTags(RegistryType.ITEM, "minecraft:soul_fire_base_blocks", "minecraft:furnace_materials", "minecraft:crimson_stems",
"minecraft:gold_ores", "minecraft:piglin_loved", "minecraft:piglin_repellents", "minecraft:creeper_drop_music_discs",
"minecraft:logs_that_burn", "minecraft:stone_tool_materials", "minecraft:warped_stems");
tagRewriter.addEmptyTags(TagType.BLOCK, "minecraft:infiniburn_nether", "minecraft:crimson_stems",
tagRewriter.addEmptyTags(RegistryType.BLOCK, "minecraft:infiniburn_nether", "minecraft:crimson_stems",
"minecraft:wither_summon_base_blocks", "minecraft:infiniburn_overworld", "minecraft:piglin_repellents",
"minecraft:hoglin_repellents", "minecraft:prevent_mob_spawning_inside", "minecraft:wart_blocks",
"minecraft:stone_pressure_plates", "minecraft:nylium", "minecraft:gold_ores", "minecraft:pressure_plates",

View File

@ -9,9 +9,10 @@ import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.api.rewriters.RegistryType;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.rewriters.TagRewriter;
import us.myles.ViaVersion.api.rewriters.TagType;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
@ -50,6 +51,9 @@ public class Protocol1_16To1_15_2 extends Protocol<ClientboundPackets1_15, Clien
tagRewriter = new TagRewriter(this, Protocol1_16To1_15_2::getNewBlockId, InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId);
tagRewriter.register(ClientboundPackets1_15.TAGS);
new StatisticsRewriter(this, Protocol1_16To1_15_2::getNewBlockId, InventoryPackets::getNewItemId,
metadataRewriter::getNewEntityId).register(ClientboundPackets1_15.STATISTICS);
// Login Success
registerOutgoing(State.LOGIN, 0x02, 0x02, new PacketRemapper() {
@Override
@ -219,32 +223,32 @@ public class Protocol1_16To1_15_2 extends Protocol<ClientboundPackets1_15, Clien
wallPostOverrideTag[arrayIndex++] = i;
}
tagRewriter.addTag(TagType.BLOCK, "minecraft:wall_post_override", wallPostOverrideTag);
tagRewriter.addTag(TagType.BLOCK, "minecraft:beacon_base_blocks", 133, 134, 148, 265);
tagRewriter.addTag(TagType.BLOCK, "minecraft:climbable", 160, 241, 658);
tagRewriter.addTag(TagType.BLOCK, "minecraft:fire", 142);
tagRewriter.addTag(TagType.BLOCK, "minecraft:campfires", 679);
tagRewriter.addTag(TagType.BLOCK, "minecraft:fence_gates", 242, 467, 468, 469, 470, 471);
tagRewriter.addTag(TagType.BLOCK, "minecraft:unstable_bottom_center", 242, 467, 468, 469, 470, 471);
tagRewriter.addTag(TagType.BLOCK, "minecraft:wooden_trapdoors", 193, 194, 195, 196, 197, 198);
tagRewriter.addTag(TagType.ITEM, "minecraft:wooden_trapdoors", 215, 216, 217, 218, 219, 220);
tagRewriter.addTag(TagType.ITEM, "minecraft:beacon_payment_items", 529, 530, 531, 760);
tagRewriter.addTag(TagType.ENTITY, "minecraft:impact_projectiles", 2, 72, 71, 37, 69, 79, 83, 15, 93);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:wall_post_override", wallPostOverrideTag);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:beacon_base_blocks", 133, 134, 148, 265);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:climbable", 160, 241, 658);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:fire", 142);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:campfires", 679);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:fence_gates", 242, 467, 468, 469, 470, 471);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:unstable_bottom_center", 242, 467, 468, 469, 470, 471);
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:wooden_trapdoors", 193, 194, 195, 196, 197, 198);
tagRewriter.addTag(RegistryType.ITEM, "minecraft:wooden_trapdoors", 215, 216, 217, 218, 219, 220);
tagRewriter.addTag(RegistryType.ITEM, "minecraft:beacon_payment_items", 529, 530, 531, 760);
tagRewriter.addTag(RegistryType.ENTITY, "minecraft:impact_projectiles", 2, 72, 71, 37, 69, 79, 83, 15, 93);
// The client crashes if we don't send all tags it may use
tagRewriter.addEmptyTag(TagType.BLOCK, "minecraft:guarded_by_piglins");
tagRewriter.addEmptyTag(TagType.BLOCK, "minecraft:soul_speed_blocks");
tagRewriter.addEmptyTag(TagType.BLOCK, "minecraft:soul_fire_base_blocks");
tagRewriter.addEmptyTag(TagType.BLOCK, "minecraft:non_flammable_wood");
tagRewriter.addEmptyTag(TagType.ITEM, "minecraft:non_flammable_wood");
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:guarded_by_piglins");
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:soul_speed_blocks");
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:soul_fire_base_blocks");
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:non_flammable_wood");
tagRewriter.addEmptyTag(RegistryType.ITEM, "minecraft:non_flammable_wood");
// The rest of not accessed tags added in older versions; #1830
tagRewriter.addEmptyTags(TagType.BLOCK, "minecraft:bamboo_plantable_on", "minecraft:beds", "minecraft:bee_growables",
tagRewriter.addEmptyTags(RegistryType.BLOCK, "minecraft:bamboo_plantable_on", "minecraft:beds", "minecraft:bee_growables",
"minecraft:beehives", "minecraft:coral_plants", "minecraft:crops", "minecraft:dragon_immune", "minecraft:flowers",
"minecraft:portals", "minecraft:shulker_boxes", "minecraft:small_flowers", "minecraft:tall_flowers", "minecraft:trapdoors",
"minecraft:underwater_bonemeals", "minecraft:wither_immune", "minecraft:wooden_fences", "minecraft:wooden_trapdoors");
tagRewriter.addEmptyTags(TagType.ENTITY, "minecraft:arrows", "minecraft:beehive_inhabitors", "minecraft:raiders", "minecraft:skeletons");
tagRewriter.addEmptyTags(TagType.ITEM, "minecraft:beds", "minecraft:coals", "minecraft:fences", "minecraft:flowers",
tagRewriter.addEmptyTags(RegistryType.ENTITY, "minecraft:arrows", "minecraft:beehive_inhabitors", "minecraft:raiders", "minecraft:skeletons");
tagRewriter.addEmptyTags(RegistryType.ITEM, "minecraft:beds", "minecraft:coals", "minecraft:fences", "minecraft:flowers",
"minecraft:lectern_books", "minecraft:music_discs", "minecraft:small_flowers", "minecraft:tall_flowers", "minecraft:trapdoors", "minecraft:walls", "minecraft:wooden_fences");
}