mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2026-11-04 17:00:06 -05:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4be33cbe2c | ||
|
|
e813796d9a | ||
|
|
271b6e7ff7 | ||
|
|
7bf4a30075 | ||
|
|
414e978829 | ||
|
|
637a81e569 | ||
|
|
b4023127f6 | ||
|
|
46a61058dd | ||
|
|
66b90a5b2a | ||
|
|
8f03d6bcef | ||
|
|
e1809674fd | ||
|
|
4d8b0d1f54 | ||
|
|
d1a0c58f5f | ||
|
|
724460d2e7 | ||
|
|
f2e3f53486 | ||
|
|
7190e365e4 |
No files matched your search
@@ -26,6 +26,8 @@ import com.viaversion.nbt.tag.ByteArrayTag;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.util.function.IntConsumer;
|
||||
@@ -49,6 +51,12 @@ public final class IdRanges {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public static IntList decodeAsList(final ByteArrayTag rangesTag) {
|
||||
final IntList ids = new IntArrayList();
|
||||
forEachId(rangesTag, ids::add);
|
||||
return ids;
|
||||
}
|
||||
|
||||
public static void forEachId(final ByteArrayTag rangesTag, final IntConsumer consumer) {
|
||||
final ByteBuf buf = Unpooled.wrappedBuffer(rangesTag.getValue());
|
||||
int prevEnd = 0;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.data;
|
||||
|
||||
import com.viaversion.nbt.tag.ByteArrayTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntArrayTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
@@ -198,8 +199,14 @@ public class MappingDataBase implements MappingData {
|
||||
|
||||
final List<TagData> tagsList = new ArrayList<>(tags.size());
|
||||
for (final Map.Entry<String, Tag> entry : tag.entrySet()) {
|
||||
final IntArrayTag entries = (IntArrayTag) entry.getValue();
|
||||
tagsList.add(new TagData(entry.getKey(), entries.getValue()));
|
||||
final int[] entries;
|
||||
if (entry.getValue() instanceof final ByteArrayTag rangesTag) {
|
||||
entries = IdRanges.decodeAsList(rangesTag).toIntArray();
|
||||
} else {
|
||||
// Old format / if the values need to be sorted
|
||||
entries = ((IntArrayTag) entry.getValue()).getValue();
|
||||
}
|
||||
tagsList.add(new TagData(entry.getKey(), entries));
|
||||
}
|
||||
|
||||
this.tags.put(type, tagsList);
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class FilterableComponent extends Filterable<Tag> implements Copyable, Rewritable {
|
||||
|
||||
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
|
||||
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TEXT_COMPONENT_TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
|
||||
@Override
|
||||
protected FilterableComponent create(final Tag raw, final Tag filtered) {
|
||||
return new FilterableComponent(raw, filtered);
|
||||
|
||||
+2
-2
@@ -34,7 +34,6 @@ import io.netty.buffer.ByteBuf;
|
||||
// Very similar to normal items (and just results in an item), except it allows non-positive amounts and has id/amount swapped because ???
|
||||
public final class ItemCostType1_20_5 extends Type<Item> {
|
||||
|
||||
private static final StructuredData<?>[] EMPTY_DATA_ARRAY = new StructuredData[0];
|
||||
private final Type<StructuredData<?>[]> dataArrayType;
|
||||
|
||||
public ItemCostType1_20_5(final Type<StructuredData<?>[]> dataArrayType) {
|
||||
@@ -54,7 +53,8 @@ public final class ItemCostType1_20_5 extends Type<Item> {
|
||||
public void write(final ByteBuf buffer, final Item object) {
|
||||
Types.VAR_INT.writePrimitive(buffer, object.identifier());
|
||||
Types.VAR_INT.writePrimitive(buffer, object.amount());
|
||||
dataArrayType.write(buffer, object.dataContainer().data().values().toArray(EMPTY_DATA_ARRAY));
|
||||
// Item costs are exact-match predicates without removal markers, so empty data can't be written
|
||||
dataArrayType.write(buffer, object.dataContainer().data().values().stream().filter(StructuredData::isPresent).toArray(StructuredData[]::new));
|
||||
}
|
||||
|
||||
public static final class OptionalItemCostType extends OptionalType<Item> {
|
||||
|
||||
+2
@@ -51,6 +51,7 @@ import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter.ComponentRew
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter.EntityPacketRewriter1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter.ItemPacketRewriter1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage.NonceStorage1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage.PlayerHealthStorage;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage.ReceivedMessagesStorage;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ServerboundPackets1_19_1;
|
||||
@@ -380,6 +381,7 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
|
||||
@Override
|
||||
public void init(final UserConnection user) {
|
||||
user.put(new ReceivedMessagesStorage());
|
||||
user.put(new PlayerHealthStorage());
|
||||
addEntityTracker(user, new EntityTrackerBase(user, EntityTypes1_19_3.PLAYER));
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -28,6 +28,7 @@ import com.viaversion.viaversion.api.type.types.version.Types1_19;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.Protocol1_19_1To1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ClientboundPackets1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage.PlayerHealthStorage;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
import java.util.BitSet;
|
||||
@@ -75,6 +76,13 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_1.SET_HEALTH, wrapper -> {
|
||||
final float health = wrapper.passthrough(Types.FLOAT);
|
||||
final int food = wrapper.passthrough(Types.VAR_INT);
|
||||
final float saturation = wrapper.passthrough(Types.FLOAT);
|
||||
wrapper.user().get(PlayerHealthStorage.class).update(health, food, saturation);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_1.RESPAWN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
@@ -94,6 +102,18 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
|
||||
}
|
||||
wrapper.write(Types.BYTE, keepDataMask);
|
||||
});
|
||||
handler(wrapper -> {
|
||||
final PlayerHealthStorage healthStorage = wrapper.user().get(PlayerHealthStorage.class);
|
||||
if (healthStorage.dead()) {
|
||||
// The client takes over the entity data of the dead player, its health of 0 would instantly re-open the death screen
|
||||
final PacketWrapper setHealth = wrapper.create(ClientboundPackets1_19_3.SET_HEALTH);
|
||||
setHealth.write(Types.FLOAT, 20F); // Overwritten by the server right after the respawn
|
||||
setHealth.write(Types.VAR_INT, healthStorage.food());
|
||||
setHealth.write(Types.FLOAT, healthStorage.saturation());
|
||||
setHealth.send(Protocol1_19_1To1_19_3.class);
|
||||
healthStorage.setDead(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+22
-9
@@ -15,22 +15,35 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v26_2to26_3.storage;
|
||||
package com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
|
||||
public final class LastMovement implements StorableObject {
|
||||
private long lastMovementTime;
|
||||
public final class PlayerHealthStorage implements StorableObject {
|
||||
|
||||
public LastMovement(final long lastMovementTime) {
|
||||
this.lastMovementTime = lastMovementTime;
|
||||
private boolean dead;
|
||||
private int food;
|
||||
private float saturation;
|
||||
|
||||
public void update(final float health, final int food, final float saturation) {
|
||||
this.dead = health <= 0;
|
||||
this.food = food;
|
||||
this.saturation = saturation;
|
||||
}
|
||||
|
||||
public long lastMovementTime() {
|
||||
return lastMovementTime;
|
||||
public boolean dead() {
|
||||
return this.dead;
|
||||
}
|
||||
|
||||
public void setLastMovementTime(final long lastMovementTime) {
|
||||
this.lastMovementTime = lastMovementTime;
|
||||
public void setDead(final boolean dead) {
|
||||
this.dead = dead;
|
||||
}
|
||||
|
||||
public int food() {
|
||||
return this.food;
|
||||
}
|
||||
|
||||
public float saturation() {
|
||||
return this.saturation;
|
||||
}
|
||||
}
|
||||
+26
-1
@@ -24,6 +24,7 @@ import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ChatType;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
@@ -139,6 +140,29 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
final double accelerationPower = Math.sqrt(xPower * xPower + yPower * yPower + zPower * zPower);
|
||||
wrapper.write(Types.DOUBLE, accelerationPower);
|
||||
});
|
||||
|
||||
// Servers up to 1.20.6 resend the win game event with a value of 0 to players that already saw the credits,
|
||||
// telling the client to skip the end poem and to confirm the credits right away.
|
||||
// 1.21+ clients ignore the value and always open the full end poem screen instead
|
||||
appendClientbound(ClientboundPackets1_20_5.GAME_EVENT, wrapper -> {
|
||||
wrapper.resetReader();
|
||||
final short event = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
if (event != 4) { // Win game
|
||||
return;
|
||||
}
|
||||
|
||||
final float value = wrapper.passthrough(Types.FLOAT);
|
||||
if (value >= 0.5F) { // Rounded by clients, meaning the end poem is being shown for the first time
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.cancel();
|
||||
|
||||
// The server only teleports the player out of the end once the client confirms the credits being over
|
||||
final PacketWrapper clientCommandPacket = wrapper.create(ServerboundPackets1_20_5.CLIENT_COMMAND);
|
||||
clientCommandPacket.write(Types.VAR_INT, 0); // Perform respawn
|
||||
clientCommandPacket.sendToServer(Protocol1_20_5To1_21.class);
|
||||
});
|
||||
}
|
||||
|
||||
public static String mapAttributeUUID(final UUID uuid, final String name) {
|
||||
@@ -191,9 +215,10 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
tagRewriter.addEmptyTags(RegistryType.ENTITY, "minecraft:can_turn_in_boats", "minecraft:deflects_projectiles", "minecraft:immune_to_infested",
|
||||
"minecraft:immune_to_oozing", "minecraft:no_anger_from_wind_charge");
|
||||
tagRewriter.addTag(RegistryType.ENCHANTMENT, "minecraft:curse", 10, 41); // Binding and vanishing curse
|
||||
tagRewriter.addTag(RegistryType.ENCHANTMENT, "minecraft:prevents_decorated_pot_shattering", 21); // Silk touch
|
||||
// Add other enchantment tags empty
|
||||
tagRewriter.addEmptyTags(RegistryType.ENCHANTMENT, "double_trade_price", "in_enchanting_table", "non_treasure", "on_mob_spawn_equipment", "on_random_loot",
|
||||
"on_traded_equipment", "prevents_bee_spawns_when_mining", "prevents_decorated_pot_shattering", "prevents_ice_melting", "prevents_infested_spawns", "smelts_loot",
|
||||
"on_traded_equipment", "prevents_bee_spawns_when_mining", "prevents_ice_melting", "prevents_infested_spawns", "smelts_loot",
|
||||
"tooltip_order", "tradeable", "treasure", "exclusive_set/armor", "exclusive_set/boots", "exclusive_set/bow", "exclusive_set/crossbow", "exclusive_set/damage",
|
||||
"exclusive_set/mining", "exclusive_set/riptide");
|
||||
}
|
||||
|
||||
+4
@@ -22,6 +22,7 @@ import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.data.MappingDataBase;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryType;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_4;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_5;
|
||||
@@ -191,6 +192,9 @@ public final class Protocol1_21_4To1_21_5 extends AbstractProtocol<ClientboundPa
|
||||
StructuredDataKey.PAINTING_VARIANT, StructuredDataKey.LLAMA_VARIANT, StructuredDataKey.AXOLOTL_VARIANT, StructuredDataKey.CAT_VARIANT,
|
||||
StructuredDataKey.CAT_COLLAR, StructuredDataKey.SHEEP_COLOR, StructuredDataKey.SHULKER_COLOR, StructuredDataKey.PROVIDES_TRIM_MATERIAL1_21_5,
|
||||
StructuredDataKey.BREAK_SOUND, StructuredDataKey.COW_VARIANT, StructuredDataKey.CHICKEN_VARIANT1_21_5, StructuredDataKey.WOLF_SOUND_VARIANT);
|
||||
|
||||
tagRewriter.renameTag(RegistryType.BLOCK, "dead_bush_may_place_on", "dry_vegetation_may_place_on");
|
||||
|
||||
super.onMappingDataLoaded();
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -21,6 +21,7 @@ import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.data.MappingDataBase;
|
||||
import com.viaversion.viaversion.api.minecraft.GameMode;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryType;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
@@ -141,6 +142,9 @@ public final class Protocol1_21_5To1_21_6 extends AbstractProtocol<ClientboundPa
|
||||
StructuredDataKey.PAINTING_VARIANT, StructuredDataKey.LLAMA_VARIANT, StructuredDataKey.AXOLOTL_VARIANT, StructuredDataKey.CAT_VARIANT,
|
||||
StructuredDataKey.CAT_COLLAR, StructuredDataKey.SHEEP_COLOR, StructuredDataKey.SHULKER_COLOR, StructuredDataKey.PROVIDES_TRIM_MATERIAL1_21_5,
|
||||
StructuredDataKey.BREAK_SOUND, StructuredDataKey.COW_VARIANT, StructuredDataKey.CHICKEN_VARIANT1_21_5, StructuredDataKey.WOLF_SOUND_VARIANT);
|
||||
|
||||
tagRewriter.renameTag(RegistryType.BLOCK, "plays_ambient_desert_block_sounds", "triggers_ambient_desert_dry_vegetation_block_sounds");
|
||||
|
||||
super.onMappingDataLoaded();
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -216,6 +216,11 @@ public class SpawnPacketRewriter1_9 {
|
||||
int entityID = wrapper.get(Types.VAR_INT, 0);
|
||||
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(protocol);
|
||||
tracker.handleEntityData(entityID, entityDataList);
|
||||
|
||||
// dragon default phase on 1.9+ is 10 (hovering), so we set it to match the only phase 1.8 had, which was 0 (circling)
|
||||
if (tracker.entityType(entityID) == EntityTypes1_9.EntityType.ENDER_DRAGON) {
|
||||
entityDataList.add(new EntityData(11, EntityDataTypes1_9.VAR_INT, 0)); // 11 = dragon phase id
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
+43
-1
@@ -21,8 +21,10 @@ import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryType;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys26_2;
|
||||
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys26_3;
|
||||
@@ -62,7 +64,6 @@ import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.NBTComponentRewriter;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
@@ -70,6 +71,10 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
public final class Protocol26_2To26_3 extends AbstractProtocol<ClientboundPacket26_1, ClientboundPacket26_3, ServerboundPacket26_1, ServerboundPacket26_3> {
|
||||
|
||||
public static final MappingData26_3 MAPPINGS = new MappingData26_3();
|
||||
private static final int SPLASH_POTION_SOUND = 1053;
|
||||
private static final int INSTANT_SPLASH_POTION_SOUND = 1054;
|
||||
private static final int SPLASH_POTION_PARTICLES = 2002;
|
||||
private static final int INSTANT_SPLASH_POTION_PARTICLES = 2007;
|
||||
private static final String[] POT_PATTERNS = {
|
||||
"angler",
|
||||
"archer",
|
||||
@@ -172,6 +177,40 @@ public final class Protocol26_2To26_3 extends AbstractProtocol<ClientboundPacket
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG)); // Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Target Name
|
||||
});
|
||||
|
||||
// 26.3 plays the potion splash sound through its own level event, older clients played it together with the particles
|
||||
appendClientbound(ClientboundPackets26_1.LEVEL_EVENT, wrapper -> {
|
||||
final int id = wrapper.get(Types.INT, 0);
|
||||
final BlockPosition position = wrapper.get(Types.BLOCK_POSITION1_14, 0);
|
||||
final int soundId;
|
||||
if (id == SPLASH_POTION_PARTICLES) {
|
||||
soundId = SPLASH_POTION_SOUND;
|
||||
} else if (id == INSTANT_SPLASH_POTION_PARTICLES) {
|
||||
soundId = INSTANT_SPLASH_POTION_SOUND;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
final PacketWrapper soundPacket = wrapper.create(ClientboundPackets26_3.LEVEL_EVENT);
|
||||
soundPacket.write(Types.INT, soundId);
|
||||
soundPacket.write(Types.BLOCK_POSITION1_14, position);
|
||||
soundPacket.write(Types.INT, 0); // Data
|
||||
soundPacket.write(Types.BOOLEAN, false); // Global
|
||||
soundPacket.scheduleSend(Protocol26_2To26_3.class);
|
||||
});
|
||||
|
||||
// 26.3 reads the items the brewing stand slots accept from the server, older clients have them hardcoded
|
||||
appendClientbound(ClientboundPackets26_1.UPDATE_RECIPES, wrapper -> {
|
||||
wrapper.resetReader();
|
||||
final int size = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.VAR_INT, size + 2);
|
||||
|
||||
// Copies, as later protocols rewrite the ids in place
|
||||
wrapper.write(Types.STRING, "minecraft:brewing_input");
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, MAPPINGS.brewingInputIds().clone());
|
||||
wrapper.write(Types.STRING, "minecraft:brewing_reagent");
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, MAPPINGS.brewingReagentIds().clone());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -209,6 +248,9 @@ public final class Protocol26_2To26_3 extends AbstractProtocol<ClientboundPacket
|
||||
StructuredDataKey.PROVIDES_POTTERY_PATTERN, StructuredDataKey.BLOCK_TRANSFORMER, StructuredDataKey.COMPOSTABLE, StructuredDataKey.VILLAGER_FOOD,
|
||||
StructuredDataKey.COOKING_FUEL, StructuredDataKey.BREWING_FUEL, StructuredDataKey.MOB_VISIBILITY, StructuredDataKey.SIGN_TEXT_BACK, StructuredDataKey.SIGN_TEXT_FRONT,
|
||||
StructuredDataKey.WAXED, StructuredDataKey.CUSHION_COLOR, StructuredDataKey.ATTACK_ANIMATION, StructuredDataKey.INTERACT_ANIMATION);
|
||||
|
||||
tagRewriter.renameTag(RegistryType.BLOCK, "convertable_to_mud", "convertible_to_mud");
|
||||
|
||||
super.onMappingDataLoaded();
|
||||
}
|
||||
|
||||
|
||||
+56
@@ -20,10 +20,44 @@ package com.viaversion.viaversion.protocols.v26_2to26_3.data;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.data.MappingDataBase;
|
||||
import com.viaversion.viaversion.api.data.MappingDataLoader;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
public final class MappingData26_3 extends MappingDataBase {
|
||||
|
||||
private static final String[] BREWING_INPUTS = {
|
||||
"potion",
|
||||
"splash_potion",
|
||||
"lingering_potion",
|
||||
"glass_bottle"
|
||||
};
|
||||
private static final String[] BREWING_REAGENTS = {
|
||||
"blaze_powder",
|
||||
"breeze_rod",
|
||||
"cobweb",
|
||||
"dragon_breath",
|
||||
"fermented_spider_eye",
|
||||
"ghast_tear",
|
||||
"glistering_melon_slice",
|
||||
"glowstone_dust",
|
||||
"golden_carrot",
|
||||
"gunpowder",
|
||||
"magma_cream",
|
||||
"nether_wart",
|
||||
"phantom_membrane",
|
||||
"pufferfish",
|
||||
"rabbit_foot",
|
||||
"redstone",
|
||||
"slime_block",
|
||||
"spider_eye",
|
||||
"stone",
|
||||
"sugar",
|
||||
"turtle_helmet"
|
||||
};
|
||||
|
||||
private CompoundTag blockTransformerRegistry;
|
||||
private int[] brewingInputIds;
|
||||
private int[] brewingReagentIds;
|
||||
|
||||
public MappingData26_3() {
|
||||
super("26.2", "26.3");
|
||||
@@ -32,9 +66,31 @@ public final class MappingData26_3 extends MappingDataBase {
|
||||
@Override
|
||||
protected void loadExtras(final CompoundTag data) {
|
||||
blockTransformerRegistry = MappingDataLoader.INSTANCE.loadNBTFromFile("block-transformer-registry-26.3.nbt");
|
||||
|
||||
brewingInputIds = itemIds(BREWING_INPUTS);
|
||||
brewingReagentIds = itemIds(BREWING_REAGENTS);
|
||||
}
|
||||
|
||||
private int[] itemIds(final String[] identifiers) {
|
||||
final IntList ids = new IntArrayList(identifiers.length);
|
||||
for (final String identifier : identifiers) {
|
||||
final int id = getFullItemMappings().mappedId(identifier);
|
||||
if (id != -1) {
|
||||
ids.add(id);
|
||||
}
|
||||
}
|
||||
return ids.toIntArray();
|
||||
}
|
||||
|
||||
public CompoundTag blockTransformerRegistry() {
|
||||
return blockTransformerRegistry;
|
||||
}
|
||||
|
||||
public int[] brewingInputIds() {
|
||||
return brewingInputIds;
|
||||
}
|
||||
|
||||
public int[] brewingReagentIds() {
|
||||
return brewingReagentIds;
|
||||
}
|
||||
}
|
||||
+21
@@ -36,6 +36,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrim26_3;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrimMaterial1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrimMaterial26_3;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPacket26_1;
|
||||
@@ -201,6 +202,10 @@ public final class BlockItemPacketRewriter26_3 extends StructuredItemRewriter<Cl
|
||||
@Override
|
||||
protected void handleItemDataComponentsToClient(final UserConnection connection, final Item item, final StructuredDataContainer container) {
|
||||
upgradeData(container);
|
||||
|
||||
// Add data components to fix issues in older protocols
|
||||
appendItemDataFixComponents(connection, item, container);
|
||||
|
||||
super.handleItemDataComponentsToClient(connection, item, container);
|
||||
}
|
||||
|
||||
@@ -210,6 +215,22 @@ public final class BlockItemPacketRewriter26_3 extends StructuredItemRewriter<Cl
|
||||
super.handleItemDataComponentsToServer(connection, item, container);
|
||||
}
|
||||
|
||||
private void appendItemDataFixComponents(final UserConnection connection, final Item item, final StructuredDataContainer container) {
|
||||
final ProtocolVersion serverVersion = connection.getProtocolInfo().serverProtocolVersion();
|
||||
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_12_2)) {
|
||||
// Axes only started stripping logs in 1.13
|
||||
if (item.identifier() == 1043 || item.identifier() == 1033 || item.identifier() == 1053 || item.identifier() == 1058 || item.identifier() == 1048 || item.identifier() == 1038 || item.identifier() == 1028) {
|
||||
container.setEmpty(StructuredDataKey.BLOCK_TRANSFORMER);
|
||||
}
|
||||
}
|
||||
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
// Shovels only started creating dirt paths in 1.9
|
||||
if (item.identifier() == 1036 || item.identifier() == 1046 || item.identifier() == 1041 || item.identifier() == 1026 || item.identifier() == 1056 || item.identifier() == 1031 || item.identifier() == 1051) {
|
||||
container.setEmpty(StructuredDataKey.BLOCK_TRANSFORMER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void upgradeData(final StructuredDataContainer container) {
|
||||
container.remove(StructuredDataKey.MAP_COLOR);
|
||||
|
||||
|
||||
+11
-33
@@ -17,8 +17,6 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v26_2to26_3.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes26_3;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes26_3;
|
||||
@@ -32,13 +30,14 @@ import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ServerboundPack
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.Protocol26_2To26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.packet.ClientboundPackets26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.packet.ServerboundPackets26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.storage.LastMovement;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
|
||||
public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPacket26_1, Protocol26_2To26_3> {
|
||||
|
||||
private static final int SINGLE_STEP = 1 << 1;
|
||||
private static final int MAX_TICK_OFFSET = 5;
|
||||
// All entities that care about steps use 3 steps in 26.2. 26.3 still lerps every tick within each step, so this
|
||||
// is equivalent
|
||||
private static final int INTERPOLATION_STEP_TICKS = 3;
|
||||
private static final int MAIN_HAND = 0;
|
||||
private static final int OFF_HAND = 1;
|
||||
private static final int CHANGE_DESTROY_DIRECTION_ACTION = 1;
|
||||
@@ -51,20 +50,20 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets26_1.MOVE_ENTITY_POS, wrapper -> {
|
||||
final int entityId = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.passthrough(Types.VAR_INT); // Entity id
|
||||
final short xa = wrapper.read(Types.SHORT);
|
||||
final short ya = wrapper.read(Types.SHORT);
|
||||
final short za = wrapper.read(Types.SHORT);
|
||||
final boolean onGround = wrapper.read(Types.BOOLEAN);
|
||||
wrapper.write(Types.VAR_INT, (onGround ? 1 : 0) | SINGLE_STEP); // Only the first bit set, otherwise empty = no step count
|
||||
wrapper.write(Types.VAR_INT, tickOffset(wrapper.user(), entityId));
|
||||
wrapper.write(Types.VAR_INT, INTERPOLATION_STEP_TICKS);
|
||||
wrapper.write(Types.SHORT, xa);
|
||||
wrapper.write(Types.SHORT, ya);
|
||||
wrapper.write(Types.SHORT, za);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets26_1.MOVE_ENTITY_POS_ROT, wrapper -> {
|
||||
final int entityId = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.passthrough(Types.VAR_INT); // Entity id
|
||||
final short xa = wrapper.read(Types.SHORT);
|
||||
final short ya = wrapper.read(Types.SHORT);
|
||||
final short za = wrapper.read(Types.SHORT);
|
||||
@@ -72,7 +71,7 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
|
||||
final byte xRot = wrapper.read(Types.BYTE);
|
||||
final boolean onGround = wrapper.read(Types.BOOLEAN);
|
||||
wrapper.write(Types.VAR_INT, (onGround ? 1 : 0) | SINGLE_STEP); // Only the first bit set, otherwise empty = no extra steps
|
||||
wrapper.write(Types.VAR_INT, tickOffset(wrapper.user(), entityId));
|
||||
wrapper.write(Types.VAR_INT, INTERPOLATION_STEP_TICKS);
|
||||
wrapper.write(Types.SHORT, xa);
|
||||
wrapper.write(Types.SHORT, ya);
|
||||
wrapper.write(Types.SHORT, za);
|
||||
@@ -92,10 +91,13 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
|
||||
protocol.registerClientbound(ClientboundPackets26_1.ENTITY_POSITION_SYNC, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Entity ID
|
||||
|
||||
wrapper.write(Types.VAR_INT, 0); // Linear
|
||||
wrapper.write(Types.VAR_INT, 1); // Stepped
|
||||
wrapper.write(Types.VAR_INT, 1); // 1 step
|
||||
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
wrapper.write(Types.VAR_INT, INTERPOLATION_STEP_TICKS);
|
||||
|
||||
wrapper.read(Types.DOUBLE); // Delta x
|
||||
wrapper.read(Types.DOUBLE); // Delta y
|
||||
@@ -177,30 +179,6 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
|
||||
wrapper.write(Types.OPTIONAL_VAR_INT, previousGamemode == -1 ? null : (int) previousGamemode);
|
||||
}
|
||||
|
||||
// To make the stepped interpolation handler work properly, the offset has to match the server's actual updateInterval (e.g. 2 for players).
|
||||
// An offset that's too small makes the client snap, a too large one makes it queue up steps and fall behind - this makes it match the actual rate.
|
||||
// Estimate it from the time between move packets; errors cancel out across consecutive packets as the timestamps telescope.
|
||||
private int tickOffset(final UserConnection connection, final int entityId) {
|
||||
final TrackedEntity entity = tracker(connection).entity(entityId);
|
||||
if (entity == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
final long now = System.nanoTime();
|
||||
final LastMovement timestamp = entity.get(LastMovement.class);
|
||||
if (timestamp == null) {
|
||||
entity.put(new LastMovement(now));
|
||||
return 1;
|
||||
}
|
||||
|
||||
final long deltaMillis = (now - timestamp.lastMovementTime()) / 1_000_000L;
|
||||
timestamp.setLastMovementTime(now);
|
||||
if (deltaMillis > MAX_TICK_OFFSET * 50L) {
|
||||
return 1; // No recent movement. Don't stretch the first step of a new movement burst
|
||||
}
|
||||
return (int) Math.max(1, (deltaMillis + 25) / 50); // Round to the nearest tick count
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
final EntityDataTypes26_3 entityDataTypes = protocol.mappedTypes().entityDataTypes();
|
||||
|
||||
@@ -86,8 +86,10 @@ public class RegistryDataRewriter implements com.viaversion.viaversion.api.rewri
|
||||
|
||||
switch (key) {
|
||||
case "enchantment" -> updateEnchantments(connection, entries);
|
||||
case "trim_material" -> updateTrimMaterials(entries);
|
||||
case "jukebox_song" -> updateJukeboxSongs(entries);
|
||||
case "trim_material" -> updateTrimMaterials(connection, entries);
|
||||
case "jukebox_song" -> updateJukeboxSongs(connection, entries);
|
||||
case "trim_pattern", "instrument" -> updateTextComponents(connection, entries, "description");
|
||||
case "painting_variant" -> updateTextComponents(connection, entries, "title", "author");
|
||||
case "worldgen/biome" -> updateBiomes(entries);
|
||||
case "worldgen/block_state_provider" -> updateBlockStateProviders(entries);
|
||||
case "dimension_type" -> updateDimensionTypes(entries);
|
||||
@@ -291,6 +293,18 @@ public class RegistryDataRewriter implements com.viaversion.viaversion.api.rewri
|
||||
updateTextComponent(connection, tag, "tooltip");
|
||||
}
|
||||
|
||||
protected void updateTextComponents(final UserConnection connection, final RegistryEntry[] entries, final String... keys) {
|
||||
for (final RegistryEntry entry : entries) {
|
||||
if (!(entry.tag() instanceof final CompoundTag tag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (final String key : keys) {
|
||||
updateTextComponent(connection, tag, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateTextComponent(final UserConnection connection, @Nullable final CompoundTag tag, final String key) {
|
||||
if (tag != null && protocol.getComponentRewriter() != null) {
|
||||
protocol.getComponentRewriter().processTag(connection, tag.get(key));
|
||||
@@ -333,6 +347,7 @@ public class RegistryDataRewriter implements com.viaversion.viaversion.api.rewri
|
||||
}
|
||||
|
||||
final CompoundTag tag = (CompoundTag) entry.tag();
|
||||
updateTextComponent(connection, tag, "description");
|
||||
if (!Mappings.isFullIdentity(protocol.getMappingData().getFullItemMappings())) {
|
||||
updateItemList(tag.getListTag("supported_items", StringTag.class));
|
||||
updateItemList(tag.getListTag("primary_items", StringTag.class));
|
||||
@@ -365,7 +380,8 @@ public class RegistryDataRewriter implements com.viaversion.viaversion.api.rewri
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTrimMaterials(final RegistryEntry[] entries) {
|
||||
public void updateTrimMaterials(final UserConnection connection, final RegistryEntry[] entries) {
|
||||
updateTextComponents(connection, entries, "description");
|
||||
if (Mappings.isFullIdentity(protocol.getMappingData().getFullItemMappings())) {
|
||||
return;
|
||||
}
|
||||
@@ -384,7 +400,8 @@ public class RegistryDataRewriter implements com.viaversion.viaversion.api.rewri
|
||||
}
|
||||
}
|
||||
|
||||
public void updateJukeboxSongs(final RegistryEntry[] entries) {
|
||||
public void updateJukeboxSongs(final UserConnection connection, final RegistryEntry[] entries) {
|
||||
updateTextComponents(connection, entries, "description");
|
||||
// can be overridden
|
||||
}
|
||||
|
||||
@@ -454,6 +471,14 @@ public class RegistryDataRewriter implements com.viaversion.viaversion.api.rewri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tag dripstoneParticle = TagUtil.getNamespacedTag(tag, "visual/default_dripstone_particle");
|
||||
if (dripstoneParticle instanceof CompoundTag modifierTag && modifierTag.contains("argument")) {
|
||||
dripstoneParticle = modifierTag.get("argument");
|
||||
}
|
||||
if (dripstoneParticle instanceof CompoundTag particle) {
|
||||
handleParticleData(particle);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNestedEffect(final CompoundTag effectsTag) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
-2
@@ -1,10 +1,10 @@
|
||||
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
|
||||
projectVersion=5.12.0
|
||||
projectVersion=5.12.1-SNAPSHOT
|
||||
|
||||
# Smile emoji (note that modrinth may not have added the version on release yet)
|
||||
mcVersions=26.3, 26.2, 26.1.2, 26.1.1, 26.1, 1.21.11, 1.21.10, 1.21.9, 1.21.8, 1.21.7, 1.21.6, 1.21.5, 1.21.4, 1.21.3, 1.21.2, 1.21.1, 1.21, 1.20.6, 1.20.5, 1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
|
||||
mcVersionRange=1.8-26.3
|
||||
velocityVersion=3.4-3.5
|
||||
velocityVersion=3.4-4.2.0
|
||||
|
||||
# Gradle properties
|
||||
org.gradle.daemon=true
|
||||
|
||||
+14
-3
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.velocity.listeners;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||
@@ -24,6 +26,7 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.viaversion.viaversion.VelocityPlugin;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.ConnectionManager;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.connection.ConnectionDetails;
|
||||
|
||||
@@ -32,9 +35,17 @@ public class ConnectionDetailsListener {
|
||||
|
||||
@Subscribe
|
||||
public void onPostServerJoin(final ServerPostConnectEvent event) {
|
||||
final UserConnection connection = Via.getManager().getConnectionManager().getClientConnection(event.getPlayer().getUniqueId());
|
||||
if (connection != null) {
|
||||
ConnectionDetails.sendConnectionDetails(connection, ConnectionDetails.PROXY_CHANNEL);
|
||||
ConnectionManager manager = Via.getManager().getConnectionManager();
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
|
||||
UserConnection frontend = manager.getServerConnection(uuid);
|
||||
if (frontend != null) {
|
||||
ConnectionDetails.sendPlayerDetails(frontend, ConnectionDetails.PROXY_CHANNEL);
|
||||
}
|
||||
|
||||
UserConnection backend = manager.getClientConnection(uuid);
|
||||
if (backend != null) {
|
||||
ConnectionDetails.sendServerDetails(backend, ConnectionDetails.PROXY_CHANNEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user