Compare commits

...
38 Commits
Author SHA1 Message Date
Nassim Jahnke d0815baac7 5.1.1 Release 2024-11-01 19:00:29 +01:00
EnZaXD bc6ad16d40 Properly remove custom_data component if we created it in 1.20.5+ protocols (#4229) 2024-11-01 18:50:54 +01:00
EnZaXD 33aecef7b3 Handle custom name in block entities in 1.12->1.13 (#4232)
Fixes https://github.com/ViaVersion/ViaFabricPlus/issues/592
2024-11-01 18:18:31 +01:00
Nassim Jahnke b7d37b16ae Correctly convert lock code to json instead
The normal codec doesn't serialize components to nbt, but to json strings in a string tag...
2024-10-31 20:01:36 +01:00
FlorianMichael 2b840abfef Check if blank, not empty 2024-10-31 19:31:34 +01:00
Valaphee The MeerkatandFlorianMichael bc4ad7faa3 Remove empty lock item components in 1.21->1.21.2 (#4228)
* Fix protocol error when an empty lock is sent

* Cleanup code

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2024-10-31 19:27:49 +01:00
EnZaXD f08a412db5 Drop idle packets where only horizontal collision changed in 1.21->1.21.2 (#4220) 2024-10-31 10:22:57 +01:00
Nassim Jahnke dcf050a604 Remove unneeded optional item type from Types1_21_2
Was only used in food properties up until 1.21.2 (luckily)
2024-10-31 09:57:04 +01:00
Nassim Jahnke 1f8d1339f5 Fix painting entity data in 1.21->1.21.2
Fixes #4227
2024-10-31 09:38:24 +01:00
Nassim Jahnke 5278f8ba65 Remove enchantments with level 0 in 1.21->1.21.2 2024-10-30 21:40:15 +01:00
RK_01 8fdae33333 Add auto start option to runViaProxy task (#4225) 2024-10-30 20:48:31 +01:00
RK_01 4054e83ffe Skip ViaProxy update check in runViaProxy gradle task (#4224) 2024-10-30 19:40:05 +01:00
RK_01 10f2cad8fd Change the consume animation of swords to block (#4223) 2024-10-30 18:21:00 +01:00
Nassim Jahnke 74b9eb9f45 Fix boat entity type check
As per usual plugins sending data for untracked entities
Fixes #4222
2024-10-30 16:47:34 +01:00
EnZaXD dde599c128 Fix boat colors not visible in 1.21->1.21.2 (#4200) 2024-10-30 10:42:27 +01:00
EnZaXD af8cbaf439 Add item fixes to component rewriter in 1.21.x protocols as well (#4217)
Adds the rarity fix in 1.20.5->1.21 and the item/custom name fix in 1.21->1.21.2 to the component rewriters / chat items.
2024-10-30 10:31:45 +01:00
Nassim Jahnke ad83d01fad Creaking transient extends creaking 2024-10-30 10:18:18 +01:00
EnZaXD 7eb3632144 Fix written_book_content and potion_contents data to tag conversion (#4218) 2024-10-30 09:40:39 +01:00
EnZaXD 1ac668d9f2 Add URL of ViaProxy to runViaProxy task (#4215) 2024-10-30 09:39:15 +01:00
EnZaXD f5033342c9 Use correct tag name for 1.21->1.21.2 item name fix (#4214) 2024-10-29 14:55:28 +01:00
RK_01 a0c0b7eff2 Add gradle task to quickly test/debug code changes (#4211) 2024-10-29 14:00:55 +01:00
Nassim Jahnke 7985b39ed5 Fix trail particle reading 2024-10-29 13:32:54 +01:00
Nassim Jahnke f26e370a49 Handle 1.21.2 block_crumble particle 2024-10-29 13:15:40 +01:00
RK_01 cb0c301baf Fix 1.21.1 -> 1.21.2 chunk loading edge case (#4212)
Will usually happen on 1.8 servers or older
2024-10-29 12:51:47 +01:00
RK_01 3858a83972 Small code cleanup (#4213) 2024-10-29 12:50:36 +01:00
EnZaXD 82ff0bae49 Fix item_name<->default name priority for items in 1.21->1.21.2 (#4208) 2024-10-29 11:56:23 +01:00
Nassim Jahnke ee16d7af28 Fix two area effect cloud item particle issues 2024-10-28 12:10:36 +01:00
Nassim Jahnke f914d57678 Small cleanup 2024-10-28 11:23:27 +01:00
EnZaXDandNassim Jahnke c13b40a373 Add ParticleRewriter base (#4203)
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2024-10-28 11:23:02 +01:00
Nassim Jahnke d60a37f7e6 Flatten some PacketHandlers in rewriters 2024-10-27 23:07:13 +01:00
Nassim Jahnke 3caaed00dc Write enabled features as string array 2024-10-27 16:02:37 +01:00
Nassim Jahnke f56bfbebb5 Update some deps 2024-10-27 14:59:46 +01:00
EnZaXD 3eec520ebd Send enable features packet after the play login packet in 1.19.1->1.19.3 (#4205) 2024-10-27 08:42:03 +01:00
Nassim Jahnke df69f1f344 Fix InformativeException value shuffling 2024-10-26 18:55:32 +02:00
EnZaXD 009b6c810c Fix and add missing javadocs in MappingData interface (#4202) 2024-10-26 18:55:08 +02:00
EnZaXD 65b76d53ef Fix MappingDataBase#getOldBlockId implementation (#4201) 2024-10-26 17:24:34 +02:00
Nassim Jahnke 7be7139241 Handle entity type changes in show_entity hover events
Fixes #4199
2024-10-25 20:45:42 +02:00
Nassim Jahnke 9bc943ea67 Bump version to 5.1.1-SNAPSHOT 2024-10-25 20:34:55 +02:00
81 changed files with 1718 additions and 682 deletions

No files matched your search

+4 -1
View File
@@ -109,4 +109,7 @@ nb-configuration.xml
.nb-gradle/
### MacOS ###
.DS_Store
.DS_Store
### Run Folder (ViaProxy) ###
common/run/
@@ -35,56 +35,82 @@ public interface MappingData {
void load();
/**
* Returns the mapped block state id, or -1 if unmapped.
* Returns the mapped block state id, or 0 if unmapped.
*
* @param id unmapped block state id
* @return mapped block state id, or -1 if unmapped
* @return mapped block state id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold block state mappings
*/
int getNewBlockStateId(int id);
/**
* Returns the mapped block id, or -1 if unmapped.
* Returns the mapped block id, or 0 if unmapped.
*
* @param id unmapped block id
* @return mapped block id, or -1 if unmapped
* @return mapped block id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold block mappings
*/
int getNewBlockId(int id);
/**
* Returns the backwards mapped block id, or 1 if unmapped.
*
* @param id mapped block id
* @return backwards mapped block id, or 1 if unmapped
*/
int getOldBlockId(int id);
/**
* Returns the mapped item id, or -1 if unmapped.
* Returns the mapped item id, or 0 if unmapped.
*
* @param id unmapped item id
* @return mapped item id, or -1 if unmapped
* @return mapped item id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold item mappings
*/
int getNewItemId(int id);
/**
* Returns the backwards mapped item id, or -1 if unmapped.
* Returns the backwards mapped item id, or 1 if unmapped.
*
* @param id mapped item id
* @return backwards mapped item id, or -1 if unmapped
* @return backwards mapped item id, or 1 if unmapped
* @throws NullPointerException if this mappingdata does not hold item mappings
*/
int getOldItemId(int id);
/**
* Returns the mapped particle id, or -1 if unmapped.
* Returns the mapped particle id, or 0 if unmapped.
*
* @param id unmapped particle id
* @return mapped particle id, or -1 if unmapped
* @return mapped particle id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold particle mappings
*/
int getNewParticleId(int id);
/**
* Returns the mapped attribute id, or 0 if unmapped.
*
* @param id unmapped attribute id
* @return mapped attribute id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold attribute mappings
*/
int getNewAttributeId(int id);
/**
* Returns the mapped sound id, or 0 if unmapped.
*
* @param id unmapped sound id
* @return mapped sound id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold sound mappings
*/
int getNewSoundId(int id);
/**
* Returns the backwards mapped sound id, or 1 if unmapped.
*
* @param i mapped sound id
* @return backwards mapped sound id, or 1 if unmapped
*/
int getOldSoundId(int i);
/**
@@ -179,7 +179,7 @@ public class MappingDataBase implements MappingData {
@Override
public int getOldBlockId(final int id) {
return blockMappings.getNewIdOrDefault(id, 1);
return blockMappings.inverse().getNewIdOrDefault(id, 1);
}
@Override
@@ -36,6 +36,7 @@ public class ParticleMappings extends FullMappingsBase {
addBlockParticle("falling_dust");
addBlockParticle("block_marker");
addBlockParticle("dust_pillar");
addBlockParticle("block_crumble");
addItemParticle("item");
}
@@ -22,13 +22,19 @@
*/
package com.viaversion.viaversion.api.minecraft;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record PaintingVariant(int width, int height, String assetId) {
public record PaintingVariant(int width, int height, String assetId, @Nullable Tag title, @Nullable Tag author) {
public static HolderType<PaintingVariant> TYPE = new HolderType<>() {
public PaintingVariant(final int width, final int height, final String assetId) {
this(width, height, assetId, null, null);
}
public static HolderType<PaintingVariant> TYPE1_21 = new HolderType<>() {
@Override
public PaintingVariant readDirect(final ByteBuf buffer) {
final int width = Types.VAR_INT.readPrimitive(buffer);
@@ -44,4 +50,24 @@ public record PaintingVariant(int width, int height, String assetId) {
Types.STRING.write(buffer, variant.assetId());
}
};
public static HolderType<PaintingVariant> TYPE1_21_2 = new HolderType<>() {
@Override
public PaintingVariant readDirect(final ByteBuf buffer) {
final int width = Types.VAR_INT.readPrimitive(buffer);
final int height = Types.VAR_INT.readPrimitive(buffer);
final String assetId = Types.STRING.read(buffer);
final Tag title = Types.OPTIONAL_TAG.read(buffer);
final Tag author = Types.OPTIONAL_TAG.read(buffer);
return new PaintingVariant(width, height, assetId, title, author);
}
@Override
public void writeDirect(final ByteBuf buffer, final PaintingVariant variant) {
Types.VAR_INT.writePrimitive(buffer, variant.width());
Types.VAR_INT.writePrimitive(buffer, variant.height());
Types.STRING.write(buffer, variant.assetId());
Types.OPTIONAL_TAG.write(buffer, variant.title());
Types.OPTIONAL_TAG.write(buffer, variant.author());
}
};
}
@@ -212,7 +212,7 @@ public enum EntityTypes1_21_2 implements EntityType {
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
CREAKING(ABSTRACT_MONSTER),
CREAKING_TRANSIENT(ABSTRACT_MONSTER),
CREAKING_TRANSIENT(CREAKING),
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
@@ -60,7 +60,7 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE);
public final EntityDataType frogVariantType = add(24, Types.VAR_INT);
public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION);
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE);
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE1_21);
public final EntityDataType snifferState = add(27, Types.VAR_INT);
public final EntityDataType armadilloState = add(28, Types.VAR_INT);
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
@@ -0,0 +1,74 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entitydata.types;
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.WolfVariant;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
public final class EntityDataTypes1_21_2 extends AbstractEntityDataTypes {
public final EntityDataType byteType = add(0, Types.BYTE);
public final EntityDataType varIntType = add(1, Types.VAR_INT);
public final EntityDataType longType = add(2, Types.VAR_LONG);
public final EntityDataType floatType = add(3, Types.FLOAT);
public final EntityDataType stringType = add(4, Types.STRING);
public final EntityDataType componentType = add(5, Types.TAG);
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
public final EntityDataType itemType;
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
public final EntityDataType optionalBlockPositionType = add(11, Types.OPTIONAL_POSITION_1_14);
public final EntityDataType directionType = add(12, Types.VAR_INT);
public final EntityDataType optionalUUIDType = add(13, Types.OPTIONAL_UUID);
public final EntityDataType blockStateType = add(14, Types.VAR_INT);
public final EntityDataType optionalBlockStateType = add(15, Types.VAR_INT);
public final EntityDataType compoundTagType = add(16, Types.COMPOUND_TAG);
public final EntityDataType particleType;
public final EntityDataType particlesType;
public final EntityDataType villagerDatatType = add(19, Types.VILLAGER_DATA);
public final EntityDataType optionalVarIntType = add(20, Types.OPTIONAL_VAR_INT);
public final EntityDataType poseType = add(21, Types.VAR_INT);
public final EntityDataType catVariantType = add(22, Types.VAR_INT);
public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE);
public final EntityDataType frogVariantType = add(24, Types.VAR_INT);
public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION);
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE1_21_2);
public final EntityDataType snifferState = add(27, Types.VAR_INT);
public final EntityDataType armadilloState = add(28, Types.VAR_INT);
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
public EntityDataTypes1_21_2(final Type<Item> itemType, final ParticleType particleType, final Type<Particle[]> particlesType) {
super(31);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
}
}
@@ -36,6 +36,7 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.rewriter.ParticleRewriter;
import com.viaversion.viaversion.api.rewriter.TagRewriter;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
@@ -374,6 +375,15 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
return null;
}
/**
* Returns the protocol's particle rewriter if present.
*
* @return particle rewriter
*/
default @Nullable ParticleRewriter getParticleRewriter() {
return null;
}
/**
* Returns the protocol's tag rewriter if present.
*
@@ -58,6 +58,14 @@ public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter
*/
int newEntityId(int id);
/**
* Returns the mapped entity (or the same if it has not changed).
*
* @param identifier unmapped entity identifier
* @return mapped entity identifier
*/
String mappedEntityIdentifier(String identifier);
/**
* Handles and transforms entity data of an entity.
*
@@ -23,7 +23,6 @@
package com.viaversion.viaversion.api.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
@@ -51,8 +50,6 @@ public interface ItemRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter<T
@Nullable
Item handleItemToServer(UserConnection connection, @Nullable Item item);
void rewriteParticle(UserConnection connection, Particle particle);
/**
* Returns the item type of the current protocol.
*
@@ -0,0 +1,27 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.api.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
public interface ParticleRewriter {
void rewriteParticle(UserConnection connection, Particle particle);
}
@@ -149,9 +149,9 @@ public class ParticleType extends DynamicType<Particle> {
particle.add(Types.INT, Types.INT.readPrimitive(buf));
};
public static final DataReader<Particle> TRAIL = (buf, particle) -> {
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target X
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target Y
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target Z
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target X
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target Y
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target Z
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // Color
};
@@ -25,7 +25,7 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_2;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
@@ -43,14 +43,13 @@ public final class Types1_21_2 {
public static final StructuredDataType STRUCTURED_DATA = new StructuredDataType();
public static final Type<StructuredData<?>[]> STRUCTURED_DATA_ARRAY = new ArrayType<>(STRUCTURED_DATA);
public static final ItemType1_20_5 ITEM = new ItemType1_20_5(STRUCTURED_DATA);
public static final Type<Item> OPTIONAL_ITEM = ITEM.new OptionalItemType(); // Optional as in boolean prefixed, not via the amount
public static final Type<Item[]> ITEM_ARRAY = new ArrayType<>(ITEM);
public static final Type<Item> ITEM_COST = new ItemCostType1_20_5(STRUCTURED_DATA_ARRAY);
public static final Type<Item> OPTIONAL_ITEM_COST = new ItemCostType1_20_5.OptionalItemCostType(ITEM_COST);
public static final ParticleType PARTICLE = new ParticleType();
public static final ArrayType<Particle> PARTICLES = new ArrayType<>(PARTICLE);
public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(ITEM, PARTICLE, PARTICLES);
public static final Type<Particle[]> PARTICLES = new ArrayType<>(PARTICLE);
public static final EntityDataTypes1_21_2 ENTITY_DATA_TYPES = new EntityDataTypes1_21_2(ITEM, PARTICLE, PARTICLES);
public static final Type<EntityData> ENTITY_DATA = new EntityDataType(ENTITY_DATA_TYPES);
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
}
@@ -22,11 +22,12 @@
*/
package com.viaversion.viaversion.exception;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public class InformativeException extends RuntimeException {
private final Map<String, Object> info = new HashMap<>();
private final List<DataEntry> dataEntries = new ArrayList<>();
private boolean shouldBePrinted = true;
private int sources;
@@ -34,8 +35,8 @@ public class InformativeException extends RuntimeException {
super(cause);
}
public InformativeException set(String key, Object value) {
info.put(key, value);
public InformativeException set(String key, @Nullable Object value) {
dataEntries.add(new DataEntry(key, value));
return this;
}
@@ -59,11 +60,11 @@ public class InformativeException extends RuntimeException {
public String getMessage() {
StringBuilder builder = new StringBuilder("Please report this on the Via support Discord or open an issue on the relevant GitHub repository\n");
boolean first = true;
for (Map.Entry<String, Object> entry : info.entrySet()) {
for (DataEntry entry : dataEntries) {
if (!first) {
builder.append(", ");
}
builder.append(entry.getKey()).append(": ").append(entry.getValue());
builder.append(entry.name()).append(": ").append(entry.value());
first = false;
}
return builder.toString();
@@ -74,4 +75,7 @@ public class InformativeException extends RuntimeException {
// Don't record this stack
return this;
}
private record DataEntry(String name, @Nullable Object value) {
}
}
+29
View File
@@ -18,3 +18,32 @@ java {
tasks.named<Jar>("sourcesJar") {
from(project(":viaversion-api").sourceSets.main.get().allSource)
}
// Task to quickly test/debug code changes using https://github.com/ViaVersion/ViaProxy
// For further instructions see the ViaProxy repository README
tasks.register<JavaExec>("runViaProxy") {
dependsOn(tasks.shadowJar)
val viaProxyConfiguration = configurations.create("viaProxy")
viaProxyConfiguration.dependencies.add(dependencies.create(rootProject.libs.viaProxy.get().copy().setTransitive(false)))
mainClass.set("net.raphimc.viaproxy.ViaProxy")
classpath = viaProxyConfiguration
workingDir = file("run")
jvmArgs = listOf("-DskipUpdateCheck")
if (System.getProperty("viaproxy.gui.autoStart") != null) {
jvmArgs("-Dviaproxy.gui.autoStart")
}
doFirst {
val jarsDir = file("$workingDir/jars")
jarsDir.mkdirs()
file("$jarsDir/${project.name}.jar").writeBytes(tasks.shadowJar.get().archiveFile.get().asFile.readBytes())
}
doLast {
file("$workingDir/jars/${project.name}.jar").delete()
file("$workingDir/logs").deleteRecursively()
}
}
@@ -243,11 +243,11 @@ public class PacketWrapperImpl implements PacketWrapper {
private InformativeException createInformativeException(final Exception cause, final Type<?> type, final int index) {
return new InformativeException(cause)
.set("Packet Type", this.packetType)
.set("Index", index)
.set("Type", type.getTypeName())
.set("Packet ID", this.id)
.set("Packet Type", this.packetType)
.set("Data", this.packetValues);
.set("Data", this.packetValues)
.set("Packet ID", this.id);
}
@Override
@@ -23,8 +23,8 @@ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
// To replace if needed:
@@ -37,8 +37,7 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
super(protocol, Types1_21.ITEM, Types1_21.ITEM_ARRAY);
/*super(protocol,
Types1_OLD.ITEM, Types1_OLD.ITEM_ARRAY, Types1_21.ITEM, Types1_21.ITEM_ARRAY,
Types1_OLD.ITEM_COST, Types1_OLD.OPTIONAL_ITEM_COST, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST,
Types1_OLD.PARTICLE, Types1_21.PARTICLE
Types1_OLD.ITEM_COST, Types1_OLD.OPTIONAL_ITEM_COST, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST
);*/
}
@@ -67,8 +66,6 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
registerContainerClick1_21_2(ServerboundPackets1_20_5.CONTAINER_CLICK);
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT);
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
registerExplosion1_21_2(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
final RecipeDisplayRewriter<ClientboundPacket1_21> recipeRewriter = new RecipeDisplayRewriter<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21.UPDATE_RECIPES);
@@ -17,17 +17,15 @@
*/
package com.viaversion.viaversion.protocols.template;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
// Replace if needed
// Types1_OLD
@@ -45,29 +43,25 @@ final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_2
registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA, /*Types1_OLD_ENTITY_DATA_LIST, */Types1_21.ENTITY_DATA_LIST); // Specify old and new entity data list if changed
registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> {
final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
final RegistryEntry[] entries = wrapper.passthrough(Types.REGISTRY_ENTRY_ARRAY);
handleRegistryData1_20_5(wrapper.user(), registryKey, entries); // Caches dimensions to access data like height later and tracks the amount of biomes sent for chunk data
});
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // Entity id
map(Types.BOOLEAN); // Hardcore
map(Types.STRING_ARRAY); // World List
map(Types.VAR_INT); // Max players
map(Types.VAR_INT); // View distance
map(Types.VAR_INT); // Simulation distance
map(Types.BOOLEAN); // Reduced debug info
map(Types.BOOLEAN); // Show death screen
map(Types.BOOLEAN); // Limited crafting
map(Types.VAR_INT); // Dimension id
map(Types.STRING); // World
handler(worldDataTrackerHandlerByKey1_20_5(3)); // Tracks world height and name for chunk data and entity (un)tracking
handler(playerTrackerHandler());
}
protocol.registerClientbound(ClientboundPackets1_21.LOGIN, wrapper -> {
final int entityId = wrapper.passthrough(Types.INT); // Entity id
wrapper.passthrough(Types.BOOLEAN); // Hardcore
wrapper.passthrough(Types.STRING_ARRAY); // World List
wrapper.passthrough(Types.VAR_INT); // Max players
wrapper.passthrough(Types.VAR_INT); // View distance
wrapper.passthrough(Types.VAR_INT); // Simulation distance
wrapper.passthrough(Types.BOOLEAN); // Reduced debug info
wrapper.passthrough(Types.BOOLEAN); // Show death screen
wrapper.passthrough(Types.BOOLEAN); // Limited crafting
final int dimensionId = wrapper.passthrough(Types.VAR_INT);
final String world = wrapper.passthrough(Types.STRING);
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
trackPlayer(wrapper.user(), entityId);
});
protocol.registerClientbound(ClientboundPackets1_21.RESPAWN, wrapper -> {
@@ -25,6 +25,7 @@ import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
@@ -33,6 +34,7 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfi
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -44,12 +46,14 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
// ClientboundPacket1_21
// ServerboundPacket1_20_5
// EntityTypes1_20_5 (MAPPED type)
// Types1_21_2.PARTICLE
// 1.99, 1.98
final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, ClientboundPacket1_21, ServerboundPacket1_20_5, ServerboundPacket1_20_5> {
public static final MappingData MAPPINGS = new MappingDataBase("1.98", "1.99");
private final EntityPacketRewriter1_99 entityRewriter = new EntityPacketRewriter1_99(this);
private final BlockItemPacketRewriter1_99 itemRewriter = new BlockItemPacketRewriter1_99(this);
private final ParticleRewriter<ClientboundPacket1_21> particleRewriter = new ParticleRewriter<>(this, /*Types1_OLD.PARTICLE,*/ Types1_21_2.PARTICLE);
private final TagRewriter<ClientboundPacket1_21> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter1_99 componentRewriter = new ComponentRewriter1_99(this);
@@ -79,6 +83,10 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
componentRewriter.registerPlayerInfoUpdate1_21_2(ClientboundPackets1_21.PLAYER_INFO_UPDATE);
componentRewriter.registerPing();
// If needed for any particle, item, or block changes. Extend ParticleRewriter for particle serializer changes
particleRewriter.registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
particleRewriter.registerExplode1_21_2(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
final SoundRewriter<ClientboundPacket1_21> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY);
@@ -109,9 +117,10 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
/*Types1_21_2.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST1_21_2)
.reader("dust_pillar", ParticleType.Readers.BLOCK)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("block_crumble", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST1_21_2)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION1_21_2)
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
@@ -146,6 +155,11 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21> getTagRewriter() {
return tagRewriter;
@@ -33,6 +33,7 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.FlowerPotHandler;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.SkullHandler;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.SpawnerHandler;
import com.viaversion.viaversion.util.ComponentUtil;
import java.util.HashMap;
import java.util.Map;
@@ -46,6 +47,21 @@ public class BlockEntityProvider implements Provider {
handlers.put("minecraft:skull", new SkullHandler());
handlers.put("minecraft:mob_spawner", new SpawnerHandler());
handlers.put("minecraft:command_block", new CommandBlockHandler());
final BlockEntityHandler customNameHandler = (user, tag) -> {
final StringTag name = tag.getStringTag("CustomName");
if (name != null) {
name.setValue(ComponentUtil.legacyToJsonString(name.getValue()));
}
return -1;
};
handlers.put("minecraft:chest", customNameHandler);
handlers.put("minecraft:dispenser", customNameHandler);
handlers.put("minecraft:dropper", customNameHandler);
handlers.put("minecraft:enchanting_table", customNameHandler);
handlers.put("minecraft:furnace", customNameHandler);
handlers.put("minecraft:hopper", customNameHandler);
handlers.put("minecraft:shulker_box", customNameHandler);
}
/**
@@ -22,12 +22,12 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.BlockEntityProvider;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class FlowerPotHandler implements BlockEntityProvider.BlockEntityHandler {
// Object -> string (id without namespace) or byte (numeric id)
private static final Map<Pair<?, Byte>, Integer> flowers = new ConcurrentHashMap<>();
private static final Map<Pair<?, Byte>, Integer> flowers = new HashMap<>();
static {
register("air", (byte) 0, (byte) 0, 5265);
@@ -17,7 +17,10 @@
*/
package com.viaversion.viaversion.protocols.v1_13_1to1_13_2.rewriter;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
@@ -30,8 +33,16 @@ public class EntityPacketRewriter1_13_2 {
public static void register(Protocol1_13_1To1_13_2 protocol) {
final PacketHandler dataTypeHandler = wrapper -> {
for (EntityData data : wrapper.get(Types1_13_2.ENTITY_DATA_LIST, 0)) {
data.setDataType(Types1_13_2.ENTITY_DATA_TYPES.byId(data.dataType().typeId()));
for (final EntityData data : wrapper.get(Types1_13_2.ENTITY_DATA_LIST, 0)) {
final EntityDataType dataType = Types1_13_2.ENTITY_DATA_TYPES.byId(data.dataType().typeId());
if (dataType == Types1_13_2.ENTITY_DATA_TYPES.particleType) {
final Particle particle = data.value();
if (particle.id() == 27) {
final Item item = particle.<Item>getArgument(0).getValue();
particle.set(0, Types.ITEM1_13_2, item);
}
}
data.setDataType(dataType);
}
};
@@ -23,15 +23,16 @@ import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_13_2;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.ComponentRewriter1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.data.MappingData1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.ComponentRewriter1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.EntityPacketRewriter1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.ItemPacketRewriter1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.PlayerPacketRewriter1_14;
@@ -39,6 +40,7 @@ import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.WorldPacketRew
import com.viaversion.viaversion.protocols.v1_13_2to1_14.storage.EntityTracker1_14;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -49,6 +51,7 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
public static final MappingData1_14 MAPPINGS = new MappingData1_14();
private final EntityPacketRewriter1_14 entityRewriter = new EntityPacketRewriter1_14(this);
private final ItemPacketRewriter1_14 itemRewriter = new ItemPacketRewriter1_14(this);
private final ParticleRewriter<ClientboundPackets1_13> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_13> tagRewriter = new TagRewriter<>(this);
public Protocol1_13_2To1_14() {
@@ -65,6 +68,8 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
new SoundRewriter<>(this).registerSound(ClientboundPackets1_13.SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_13.AWARD_STATS);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_13.LEVEL_PARTICLES, Types.FLOAT);
ComponentRewriter<ClientboundPackets1_13> componentRewriter = new ComponentRewriter1_14<>(this);
componentRewriter.registerComponentPacket(ClientboundPackets1_13.CHAT);
@@ -139,6 +144,11 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_13> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_13> getTagRewriter() {
return tagRewriter;
@@ -206,8 +206,6 @@ public class ItemPacketRewriter1_14 extends ItemRewriter<ClientboundPackets1_13,
});
registerSetCreativeModeSlot(ServerboundPackets1_14.SET_CREATIVE_MODE_SLOT);
registerLevelParticles(ClientboundPackets1_13.LEVEL_PARTICLES, Types.FLOAT);
}
@Override
@@ -35,6 +35,7 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPacke
import com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter.EntityPacketRewriter1_13_1;
import com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter.ItemPacketRewriter1_13_1;
import com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter.WorldPacketRewriter1_13_1;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -43,6 +44,7 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_1
public static final MappingData MAPPINGS = new MappingDataBase("1.13", "1.13.2");
private final EntityPacketRewriter1_13_1 entityRewriter = new EntityPacketRewriter1_13_1(this);
private final ItemPacketRewriter1_13_1 itemRewriter = new ItemPacketRewriter1_13_1(this);
private final ParticleRewriter<ClientboundPackets1_13> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_13> tagRewriter = new TagRewriter<>(this);
public Protocol1_13To1_13_1() {
@@ -128,6 +130,8 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_1
});
tagRewriter.register(ClientboundPackets1_13.UPDATE_TAGS, RegistryType.ITEM);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_13.LEVEL_PARTICLES, Types.FLOAT);
new StatisticsRewriter<>(this).register(ClientboundPackets1_13.AWARD_STATS);
}
@@ -152,6 +156,11 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_13> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_13> getTagRewriter() {
return tagRewriter;
@@ -97,7 +97,5 @@ public class ItemPacketRewriter1_13_1 extends ItemRewriter<ClientboundPackets1_1
registerContainerClick(ServerboundPackets1_13.CONTAINER_CLICK);
registerSetCreativeModeSlot(ServerboundPackets1_13.SET_CREATIVE_MODE_SLOT);
registerLevelParticles(ClientboundPackets1_13.LEVEL_PARTICLES, Types.FLOAT);
}
}
@@ -31,6 +31,7 @@ import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPacke
import com.viaversion.viaversion.protocols.v1_14_4to1_15.rewriter.EntityPacketRewriter1_15;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.rewriter.ItemPacketRewriter1_15;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.rewriter.WorldPacketRewriter1_15;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -40,6 +41,7 @@ public class Protocol1_14_4To1_15 extends AbstractProtocol<ClientboundPackets1_1
public static final MappingData MAPPINGS = new MappingDataBase("1.14", "1.15");
private final EntityPacketRewriter1_15 entityRewriter = new EntityPacketRewriter1_15(this);
private final ItemPacketRewriter1_15 itemRewriter = new ItemPacketRewriter1_15(this);
private final ParticleRewriter<ClientboundPackets1_14_4> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_14_4> tagRewriter = new TagRewriter<>(this);
public Protocol1_14_4To1_15() {
@@ -95,8 +97,13 @@ public class Protocol1_14_4To1_15 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_14_4> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_14_4> getTagRewriter() {
return tagRewriter;
}
}
}
@@ -47,6 +47,7 @@ import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.EntityPacketRe
import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.ItemPacketRewriter1_16;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.WorldPacketRewriter1_16;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.storage.InventoryTracker1_16;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -63,6 +64,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
public static final MappingData MAPPINGS = new MappingDataBase("1.15", "1.16");
private final EntityPacketRewriter1_16 entityRewriter = new EntityPacketRewriter1_16(this);
private final ItemPacketRewriter1_16 itemRewriter = new ItemPacketRewriter1_16(this);
private final ParticleRewriter<ClientboundPackets1_15> particleRewriter = new ParticleRewriter<>(this);
private final ComponentRewriter1_16 componentRewriter = new ComponentRewriter1_16(this);
private final TagRewriter<ClientboundPackets1_15> tagRewriter = new TagRewriter<>(this);
@@ -77,6 +79,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
WorldPacketRewriter1_16.register(this);
tagRewriter.register(ClientboundPackets1_15.UPDATE_TAGS, RegistryType.ENTITY);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_15.LEVEL_PARTICLES, Types.DOUBLE);
new StatisticsRewriter<>(this).register(ClientboundPackets1_15.AWARD_STATS);
@@ -255,6 +258,11 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_15> getParticleRewriter() {
return particleRewriter;
}
public ComponentRewriter1_16 getComponentRewriter() {
return componentRewriter;
}
@@ -136,8 +136,6 @@ public class ItemPacketRewriter1_16 extends ItemRewriter<ClientboundPackets1_15,
});
protocol.registerServerbound(ServerboundPackets1_16.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)));
registerLevelParticles(ClientboundPackets1_15.LEVEL_PARTICLES, Types.DOUBLE);
}
@Override
@@ -31,6 +31,7 @@ import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.EntityPacketRewriter1_16_2;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.ItemPacketRewriter1_16_2;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.WorldPacketRewriter1_16_2;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -40,6 +41,7 @@ public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1
public static final MappingData1_16_2 MAPPINGS = new MappingData1_16_2();
private final EntityPacketRewriter1_16_2 entityRewriter = new EntityPacketRewriter1_16_2(this);
private final ItemPacketRewriter1_16_2 itemRewriter = new ItemPacketRewriter1_16_2(this);
private final ParticleRewriter<ClientboundPackets1_16> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_16> tagRewriter = new TagRewriter<>(this);
public Protocol1_16_1To1_16_2() {
@@ -53,6 +55,7 @@ public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1
WorldPacketRewriter1_16_2.register(this);
tagRewriter.register(ClientboundPackets1_16.UPDATE_TAGS, RegistryType.ENTITY);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_16.LEVEL_PARTICLES, Types.DOUBLE);
new StatisticsRewriter<>(this).register(ClientboundPackets1_16.AWARD_STATS);
@@ -111,8 +114,13 @@ public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_16> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_16> getTagRewriter() {
return tagRewriter;
}
}
}
@@ -57,7 +57,5 @@ public class ItemPacketRewriter1_16_2 extends ItemRewriter<ClientboundPackets1_1
registerContainerClick(ServerboundPackets1_16_2.CONTAINER_CLICK);
registerSetCreativeModeSlot(ServerboundPackets1_16_2.SET_CREATIVE_MODE_SLOT);
protocol.registerServerbound(ServerboundPackets1_16_2.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)));
registerLevelParticles(ClientboundPackets1_16.LEVEL_PARTICLES, Types.DOUBLE);
}
}
@@ -37,6 +37,7 @@ import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPacke
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.EntityPacketRewriter1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.ItemPacketRewriter1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.WorldPacketRewriter1_17;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -46,6 +47,7 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
public static final MappingData MAPPINGS = new MappingDataBase("1.16.2", "1.17");
private final EntityPacketRewriter1_17 entityRewriter = new EntityPacketRewriter1_17(this);
private final ItemPacketRewriter1_17 itemRewriter = new ItemPacketRewriter1_17(this);
private final ParticleRewriter<ClientboundPackets1_16_2> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_16_2> tagRewriter = new TagRewriter<>(this);
public Protocol1_16_4To1_17() {
@@ -86,6 +88,8 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
soundRewriter.registerSound(ClientboundPackets1_16_2.SOUND);
soundRewriter.registerSound(ClientboundPackets1_16_2.SOUND_ENTITY);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_16_2.LEVEL_PARTICLES, Types.DOUBLE);
registerClientbound(ClientboundPackets1_16_2.RESOURCE_PACK, wrapper -> {
wrapper.passthrough(Types.STRING);
wrapper.passthrough(Types.STRING);
@@ -208,6 +212,11 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_16_2> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_16_2> getTagRewriter() {
return tagRewriter;
@@ -46,7 +46,6 @@ public final class ItemPacketRewriter1_17 extends ItemRewriter<ClientboundPacket
registerSetSlot(ClientboundPackets1_16_2.CONTAINER_SET_SLOT);
registerAdvancements(ClientboundPackets1_16_2.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_16_2.SET_EQUIPMENT);
registerLevelParticles(ClientboundPackets1_16_2.LEVEL_PARTICLES, Types.DOUBLE);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_16_2.UPDATE_RECIPES);
@@ -35,6 +35,7 @@ import com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter.ItemPacketRewr
import com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter.WorldPacketRewriter1_18;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.storage.ChunkLightStorage;
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -46,6 +47,7 @@ public final class Protocol1_17_1To1_18 extends AbstractProtocol<ClientboundPack
public static final ProtocolLogger LOGGER = new ProtocolLogger(Protocol1_17_1To1_18.class);
private final EntityPacketRewriter1_18 entityRewriter = new EntityPacketRewriter1_18(this);
private final ItemPacketRewriter1_18 itemRewriter = new ItemPacketRewriter1_18(this);
private final ParticleRewriter<ClientboundPackets1_17_1> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_17_1> tagRewriter = new TagRewriter<>(this);
public Protocol1_17_1To1_18() {
@@ -123,8 +125,13 @@ public final class Protocol1_17_1To1_18 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_17_1> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_17_1> getTagRewriter() {
return tagRewriter;
}
}
}
@@ -90,7 +90,7 @@ public final class EntityPacketRewriter1_18 extends EntityRewriter<ClientboundPa
} else if (particle.id() == 3) { // Light block
particle.add(Types.VAR_INT, 7786); // Light block state
} else {
rewriteParticle(event.user(), particle);
protocol.getParticleRewriter().rewriteParticle(event.user(), particle);
}
});
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocols.v1_17_1to1_18.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -30,27 +31,27 @@ public final class ChunkLightStorage implements StorableObject {
private final Set<Long> loadedChunks = new HashSet<>();
public void storeLight(final int x, final int z, final ChunkLight chunkLight) {
lightPackets.put(getChunkSectionIndex(x, z), chunkLight);
lightPackets.put(ChunkPosition.chunkKey(x, z), chunkLight);
}
public @Nullable ChunkLight removeLight(final int x, final int z) {
return lightPackets.remove(getChunkSectionIndex(x, z));
return lightPackets.remove(ChunkPosition.chunkKey(x, z));
}
public @Nullable ChunkLight getLight(final int x, final int z) {
return lightPackets.get(getChunkSectionIndex(x, z));
return lightPackets.get(ChunkPosition.chunkKey(x, z));
}
public boolean addLoadedChunk(final int x, final int z) {
return loadedChunks.add(getChunkSectionIndex(x, z));
return loadedChunks.add(ChunkPosition.chunkKey(x, z));
}
public boolean isLoaded(final int x, final int z) {
return loadedChunks.contains(getChunkSectionIndex(x, z));
return loadedChunks.contains(ChunkPosition.chunkKey(x, z));
}
public void clear(final int x, final int z) {
final long index = getChunkSectionIndex(x, z);
final long index = ChunkPosition.chunkKey(x, z);
lightPackets.remove(index);
loadedChunks.remove(index);
}
@@ -60,10 +61,6 @@ public final class ChunkLightStorage implements StorableObject {
lightPackets.clear();
}
private long getChunkSectionIndex(final int x, final int z) {
return ((x & 0x3FFFFFFL) << 38) | (z & 0x3FFFFFFL);
}
public record ChunkLight(boolean trustEdges, long[] skyLightMask, long[] blockLightMask,
long[] emptySkyLightMask, long[] emptyBlockLightMask,
byte[][] skyLight, byte[][] blockLight) {
@@ -45,6 +45,7 @@ import com.viaversion.viaversion.protocols.v1_18_2to1_19.storage.DimensionRegist
import com.viaversion.viaversion.protocols.v1_18_2to1_19.storage.NonceStorage1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.storage.SequenceStorage;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -57,6 +58,7 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
public static final MappingData1_19 MAPPINGS = new MappingData1_19();
private final EntityPacketRewriter1_19 entityRewriter = new EntityPacketRewriter1_19(this);
private final ItemPacketRewriter1_19 itemRewriter = new ItemPacketRewriter1_19(this);
private final ParticleRewriter<ClientboundPackets1_18> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_18> tagRewriter = new TagRewriter<>(this);
public Protocol1_18_2To1_19() {
@@ -347,6 +349,11 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_18> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_18> getTagRewriter() {
return tagRewriter;
@@ -331,7 +331,7 @@ public final class EntityPacketRewriter1_19 extends EntityRewriter<ClientboundPa
}
}
rewriteParticle(event.user(), particle);
protocol.getParticleRewriter().rewriteParticle(event.user(), particle);
});
registerEntityDataTypeHandler(Types1_19.ENTITY_DATA_TYPES.itemType, Types1_19.ENTITY_DATA_TYPES.optionalBlockStateType, null);
@@ -349,4 +349,4 @@ public final class EntityPacketRewriter1_19 extends EntityRewriter<ClientboundPa
public EntityType typeFromId(final int type) {
return EntityTypes1_19.getTypeFromId(type);
}
}
}
@@ -69,7 +69,7 @@ public final class ItemPacketRewriter1_19 extends ItemRewriter<ClientboundPacket
}
}
});
handler(levelParticlesHandler(Types.VAR_INT));
handler(protocol.getParticleRewriter().levelParticlesHandler1_13(Types.VAR_INT));
}
});
@@ -52,6 +52,7 @@ import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage.ReceivedMessa
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;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
@@ -68,6 +69,7 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
private static final byte[] EMPTY_BYTES = new byte[0];
private final EntityPacketRewriter1_19_3 entityRewriter = new EntityPacketRewriter1_19_3(this);
private final ItemPacketRewriter1_19_3 itemRewriter = new ItemPacketRewriter1_19_3(this);
private final ParticleRewriter<ClientboundPackets1_19_1> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_19_1> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_1To1_19_3() {
@@ -78,6 +80,8 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
protected void registerPackets() {
tagRewriter.registerGeneric(ClientboundPackets1_19_1.UPDATE_TAGS);
particleRewriter.registerLevelParticles1_19(ClientboundPackets1_19_1.LEVEL_PARTICLES);
entityRewriter.register();
itemRewriter.register();
@@ -380,6 +384,11 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_19_1> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_1> getTagRewriter() {
return tagRewriter;
@@ -22,6 +22,7 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_19_3;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_19;
import com.viaversion.viaversion.api.type.types.version.Types1_19_3;
@@ -62,11 +63,16 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
handler(worldDataTrackerHandlerByKey());
handler(playerTrackerHandler());
handler(wrapper -> {
// Also enable vanilla features
// Also enable vanilla features (set by default in later versions, but keeping it explicit is nicer)
final PacketWrapper enableFeaturesPacket = wrapper.create(ClientboundPackets1_19_3.UPDATE_ENABLED_FEATURES);
enableFeaturesPacket.write(Types.VAR_INT, 1);
enableFeaturesPacket.write(Types.STRING, "minecraft:vanilla");
enableFeaturesPacket.scheduleSend(Protocol1_19_1To1_19_3.class);
enableFeaturesPacket.write(Types.STRING_ARRAY, new String[]{"minecraft:vanilla"});
if (wrapper.user().getProtocolInfo().protocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_2)) {
// Make sure it's included in the configuration packets
enableFeaturesPacket.send(Protocol1_19_1To1_19_3.class);
} else {
enableFeaturesPacket.scheduleSend(Protocol1_19_1To1_19_3.class);
}
});
}
});
@@ -56,7 +56,6 @@ public final class ItemPacketRewriter1_19_3 extends ItemRewriter<ClientboundPack
registerMerchantOffers1_19(ClientboundPackets1_19_1.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_19_3.SET_CREATIVE_MODE_SLOT);
registerContainerSetData(ClientboundPackets1_19_1.CONTAINER_SET_DATA);
registerLevelParticles1_19(ClientboundPackets1_19_1.LEVEL_PARTICLES);
final RecipeRewriter<ClientboundPackets1_19_1> recipeRewriter = new RecipeRewriter<>(protocol);
protocol.registerClientbound(ClientboundPackets1_19_1.UPDATE_RECIPES, wrapper -> {
@@ -22,7 +22,6 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_19_4;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_19_4;
@@ -36,6 +35,7 @@ import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter.EntityPacket
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter.ItemPacketRewriter1_19_4;
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.storage.PlayerVehicleTracker;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -48,6 +48,7 @@ public final class Protocol1_19_3To1_19_4 extends AbstractProtocol<ClientboundPa
public static final MappingData1_19_4 MAPPINGS = new MappingData1_19_4();
private final EntityPacketRewriter1_19_4 entityRewriter = new EntityPacketRewriter1_19_4(this);
private final ItemPacketRewriter1_19_4 itemRewriter = new ItemPacketRewriter1_19_4(this);
private final ParticleRewriter<ClientboundPackets1_19_3> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_19_3> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_3To1_19_4() {
@@ -59,6 +60,8 @@ public final class Protocol1_19_3To1_19_4 extends AbstractProtocol<ClientboundPa
super.registerPackets();
tagRewriter.registerGeneric(ClientboundPackets1_19_3.UPDATE_TAGS);
particleRewriter.registerLevelParticles1_19(ClientboundPackets1_19_3.LEVEL_PARTICLES);
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_3.AWARD_STATS);
final SoundRewriter<ClientboundPackets1_19_3> soundRewriter = new SoundRewriter<>(this);
@@ -133,6 +136,11 @@ public final class Protocol1_19_3To1_19_4 extends AbstractProtocol<ClientboundPa
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_19_3> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_3> getTagRewriter() {
return tagRewriter;
@@ -19,7 +19,6 @@ package com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_18;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ClientboundPackets1_19_3;
@@ -91,7 +90,6 @@ public final class ItemPacketRewriter1_19_4 extends ItemRewriter<ClientboundPack
registerSetEquipment(ClientboundPackets1_19_3.SET_EQUIPMENT);
registerMerchantOffers1_19(ClientboundPackets1_19_3.MERCHANT_OFFERS);
registerContainerSetData(ClientboundPackets1_19_3.CONTAINER_SET_DATA);
registerLevelParticles1_19(ClientboundPackets1_19_3.LEVEL_PARTICLES);
registerSetCreativeModeSlot(ServerboundPackets1_19_4.SET_CREATIVE_MODE_SLOT);
registerContainerClick1_17_1(ServerboundPackets1_19_4.CONTAINER_CLICK);
@@ -103,4 +101,4 @@ public final class ItemPacketRewriter1_19_4 extends ItemRewriter<ClientboundPack
}
}.register(ClientboundPackets1_19_3.UPDATE_RECIPES);
}
}
}
@@ -31,6 +31,7 @@ import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPac
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4;
import com.viaversion.viaversion.protocols.v1_19_4to1_20.rewriter.EntityPacketRewriter1_20;
import com.viaversion.viaversion.protocols.v1_19_4to1_20.rewriter.ItemPacketRewriter1_20;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -40,6 +41,7 @@ public final class Protocol1_19_4To1_20 extends AbstractProtocol<ClientboundPack
public static final MappingData MAPPINGS = new MappingDataBase("1.19.4", "1.20");
private final EntityPacketRewriter1_20 entityRewriter = new EntityPacketRewriter1_20(this);
private final ItemPacketRewriter1_20 itemRewriter = new ItemPacketRewriter1_20(this);
private final ParticleRewriter<ClientboundPackets1_19_4> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_4To1_20() {
@@ -51,6 +53,7 @@ public final class Protocol1_19_4To1_20 extends AbstractProtocol<ClientboundPack
super.registerPackets();
tagRewriter.registerGeneric(ClientboundPackets1_19_4.UPDATE_TAGS);
particleRewriter.registerLevelParticles1_19(ClientboundPackets1_19_4.LEVEL_PARTICLES);
final SoundRewriter<ClientboundPackets1_19_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_19_4.SOUND);
@@ -108,8 +111,13 @@ public final class Protocol1_19_4To1_20 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_19_4> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_4> getTagRewriter() {
return tagRewriter;
}
}
}
@@ -59,7 +59,6 @@ public final class ItemPacketRewriter1_20 extends ItemRewriter<ClientboundPacket
registerMerchantOffers1_19(ClientboundPackets1_19_4.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_19_4.SET_CREATIVE_MODE_SLOT);
registerContainerSetData(ClientboundPackets1_19_4.CONTAINER_SET_DATA);
registerLevelParticles1_19(ClientboundPackets1_19_4.LEVEL_PARTICLES);
protocol.registerClientbound(ClientboundPackets1_19_4.UPDATE_ADVANCEMENTS, wrapper -> {
wrapper.passthrough(Types.BOOLEAN); // Reset/clear
@@ -193,4 +192,4 @@ public final class ItemPacketRewriter1_20 extends ItemRewriter<ClientboundPacket
frontText.put("has_glowing_text", glowing);
}
}
}
}
@@ -47,6 +47,7 @@ import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPacke
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPacket1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -61,6 +62,7 @@ public final class Protocol1_20_2To1_20_3 extends AbstractProtocol<ClientboundPa
public static final MappingData MAPPINGS = new MappingDataBase("1.20.2", "1.20.3");
private final BlockItemPacketRewriter1_20_3 itemRewriter = new BlockItemPacketRewriter1_20_3(this);
private final ParticleRewriter<ClientboundPacket1_20_2> particleRewriter = new ParticleRewriter<>(this);
private final EntityPacketRewriter1_20_3 entityRewriter = new EntityPacketRewriter1_20_3(this);
private final TagRewriter<ClientboundPacket1_20_2> tagRewriter = new TagRewriter<>(this);
@@ -381,6 +383,11 @@ public final class Protocol1_20_2To1_20_3 extends AbstractProtocol<ClientboundPa
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_20_2> getParticleRewriter() {
return particleRewriter;
}
@Override
public EntityPacketRewriter1_20_3 getEntityRewriter() {
return entityRewriter;
@@ -91,7 +91,7 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
wrapper.write(Types.VAR_INT, resourceLocation.equals("block") ? 0 : 1);
}
});
handler(levelParticlesHandler(Types.VAR_INT));
handler(protocol.getParticleRewriter().levelParticlesHandler1_13(Types.VAR_INT));
}
});
@@ -49,6 +49,7 @@ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.rewriter.BlockItemPacketRewriter1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.rewriter.ComponentRewriter1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.rewriter.EntityPacketRewriter1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.rewriter.ParticleRewriter1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.storage.AcknowledgedMessagesStorage;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.storage.ArmorTrimStorage;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundConfigurationPackets1_20_2;
@@ -71,6 +72,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
public static boolean strictErrorHandling = System.getProperty("viaversion.strict-error-handling1_20_5", "true").equalsIgnoreCase("true");
private final EntityPacketRewriter1_20_5 entityRewriter = new EntityPacketRewriter1_20_5(this);
private final BlockItemPacketRewriter1_20_5 itemRewriter = new BlockItemPacketRewriter1_20_5(this);
private final ParticleRewriter1_20_5 particleRewriter = new ParticleRewriter1_20_5(this);
private final TagRewriter<ClientboundPacket1_20_3> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter1_20_5<ClientboundPacket1_20_3> componentRewriter = new ComponentRewriter1_20_5<>(this, Types1_20_5.STRUCTURED_DATA);
@@ -318,6 +320,11 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
return itemRewriter;
}
@Override
public ParticleRewriter1_20_5 getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_20_3> getTagRewriter() {
return tagRewriter;
@@ -306,8 +306,8 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
final Particle smallExplosionParticle = wrapper.passthroughAndMap(Types1_20_3.PARTICLE, Types1_20_5.PARTICLE);
final Particle largeExplosionParticle = wrapper.passthroughAndMap(Types1_20_3.PARTICLE, Types1_20_5.PARTICLE);
rewriteParticle(wrapper.user(), smallExplosionParticle);
rewriteParticle(wrapper.user(), largeExplosionParticle);
protocol.getParticleRewriter().rewriteParticle(wrapper.user(), smallExplosionParticle);
protocol.getParticleRewriter().rewriteParticle(wrapper.user(), largeExplosionParticle);
final String sound = wrapper.read(Types.STRING);
final Float range = wrapper.read(Types.OPTIONAL_FLOAT);
@@ -102,8 +102,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends ComponentRewriter<C> {
private final Map<StructuredDataKey<?>, ConverterPair<?>> converters = new Reference2ObjectOpenHashMap<>();
private final StructuredDataType structuredDataType;
protected final Map<StructuredDataKey<?>, ConverterPair<?>> converters = new Reference2ObjectOpenHashMap<>();
protected final StructuredDataType structuredDataType;
/**
* @param protocol protocol
@@ -327,7 +327,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
return readFromTag(key, id, tag);
}
private <T> StructuredData<T> readFromTag(final StructuredDataKey<T> key, final int id, final Tag tag) {
protected <T> StructuredData<T> readFromTag(final StructuredDataKey<T> key, final int id, final Tag tag) {
final TagConverter<T> converter = tagConverter(key);
Preconditions.checkNotNull(converter, "No converter found for: %s", key);
return StructuredData.of(key, converter.convert(tag), id);
@@ -338,7 +338,6 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
}
// ---------------------------------------------------------------------------------------
// Conversion methods, can be overridden in future protocols to handle new changes
protected CompoundTag convertCustomData(final CompoundTag value) {
return value;
@@ -601,8 +600,15 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
if (value.customColor() != null) {
tag.putInt("custom_color", value.customColor());
}
final ListTag<CompoundTag> customEffects = new ListTag<>(CompoundTag.class);
for (final PotionEffect effect : value.customEffects()) {
convertPotionEffect(tag, effect);
final CompoundTag effectTag = new CompoundTag();
convertPotionEffect(effectTag, effect);
customEffects.add(effectTag);
}
tag.put("custom_effects", customEffects);
if (value.customName() != null) {
tag.putString("custom_name", value.customName());
}
return tag;
}
@@ -645,15 +651,14 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
protected CompoundTag convertWrittenBookContent(final WrittenBook value) {
final CompoundTag tag = new CompoundTag();
convertFilterableString(tag, value.title(), 32);
tag.putString("author", value.author());
if (value.generation() != 0) {
tag.put("generation", convertIntRange(value.generation(), 0, 3));
}
final CompoundTag title = new CompoundTag();
convertFilterableString(title, value.title(), 32);
tag.put("title", title);
tag.putString("author", value.author());
if (value.generation() != 0) {
tag.put("generation", convertIntRange(value.generation(), 0, 3));
}
final ListTag<CompoundTag> pagesTag = new ListTag<>(CompoundTag.class);
for (final FilterableComponent page : value.pages()) {
@@ -1123,17 +1128,17 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
// ---------------------------------------------------------------------------------------
private int checkIntRange(final int min, final int max, final int value) {
protected int checkIntRange(final int min, final int max, final int value) {
Preconditions.checkArgument(value >= min && value <= max, "Value out of range: " + value);
return value;
}
private float checkFloatRange(final float min, final float max, final float value) {
protected float checkFloatRange(final float min, final float max, final float value) {
Preconditions.checkArgument(value >= min && value <= max, "Value out of range: " + value);
return value;
}
private String checkStringRange(final int min, final int max, final String value) {
protected String checkStringRange(final int min, final int max, final String value) {
final int length = value.length();
Preconditions.checkArgument(length >= min && length <= max, "Value out of range: " + value);
return value;
@@ -547,14 +547,6 @@ public final class EntityPacketRewriter1_20_5 extends EntityRewriter<Clientbound
}
}
@Override
public void rewriteParticle(final UserConnection connection, final Particle particle) {
super.rewriteParticle(connection, particle);
if (particle.id() == protocol.getMappingData().getParticleMappings().mappedId("entity_effect")) {
particle.add(Types.INT, 0); // Default color, changed in the area effect handler
}
}
@Override
public void onMappingDataLoaded() {
mapTypes();
@@ -0,0 +1,50 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.v1_20_3to1_20_5.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPacket1_20_3;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
public final class ParticleRewriter1_20_5 extends ParticleRewriter<ClientboundPacket1_20_3> {
public ParticleRewriter1_20_5(final Protocol<ClientboundPacket1_20_3, ?, ?, ?> protocol) {
super(protocol);
}
@Override
public void rewriteParticle(final UserConnection connection, final Particle particle) {
super.rewriteParticle(connection, particle);
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (particle.id() == particleMappings.mappedId("entity_effect")) {
particle.add(Types.INT, 0); // Default color, changed in the area effect handler
} else if (particle.id() == particleMappings.mappedId("item")) {
final Particle.ParticleData<Item> data = particle.getArgument(0);
if (data.getValue().isEmpty()) {
data.setValue(new StructuredItem(1, 1));
}
}
}
}
@@ -28,6 +28,7 @@ import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvide
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundConfigurationPackets1_20_5;
@@ -47,6 +48,7 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter.EntityPacketRe
import com.viaversion.viaversion.protocols.v1_20_5to1_21.storage.EfficiencyAttributeStorage;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.storage.OnGroundTracker;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -62,6 +64,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
public static final MappingData1_21 MAPPINGS = new MappingData1_21();
private final EntityPacketRewriter1_21 entityRewriter = new EntityPacketRewriter1_21(this);
private final BlockItemPacketRewriter1_21 itemRewriter = new BlockItemPacketRewriter1_21(this);
private final ParticleRewriter<ClientboundPacket1_20_5> particleRewriter = new ParticleRewriter<>(this, Types1_20_5.PARTICLE, Types1_21.PARTICLE);
private final TagRewriter<ClientboundPacket1_20_5> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter<ClientboundPacket1_20_5> componentRewriter = new ComponentRewriter1_21(this);
@@ -92,6 +95,9 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_20_5.PLAYER_COMBAT_KILL);
componentRewriter.registerComponentPacket(ClientboundPackets1_20_5.SYSTEM_CHAT);
particleRewriter.registerLevelParticles1_20_5(ClientboundPackets1_20_5.LEVEL_PARTICLES);
particleRewriter.registerExplode1_20_5(ClientboundPackets1_20_5.EXPLODE); // Rewrites the included sound and particles
registerClientbound(ClientboundPackets1_20_5.DISGUISED_CHAT, wrapper -> {
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Message
@@ -246,6 +252,11 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_20_5> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_20_5> getTagRewriter() {
return tagRewriter;
@@ -52,8 +52,7 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
public BlockItemPacketRewriter1_21(final Protocol1_20_5To1_21 protocol) {
super(protocol,
Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY, Types1_21.ITEM, Types1_21.ITEM_ARRAY,
Types1_20_5.ITEM_COST, Types1_20_5.OPTIONAL_ITEM_COST, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST,
Types1_20_5.PARTICLE, Types1_21.PARTICLE
Types1_20_5.ITEM_COST, Types1_20_5.OPTIONAL_ITEM_COST, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST
);
}
@@ -74,8 +73,6 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK);
registerMerchantOffers1_20_5(ClientboundPackets1_20_5.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT);
registerLevelParticles1_20_5(ClientboundPackets1_20_5.LEVEL_PARTICLES);
registerExplosion(ClientboundPackets1_20_5.EXPLODE); // Rewrites the included sound and particles
protocol.registerClientbound(ClientboundPackets1_20_5.HORSE_SCREEN_OPEN, wrapper -> {
wrapper.passthrough(Types.UNSIGNED_BYTE); // Container id
@@ -139,14 +136,13 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
super.handleItemToClient(connection, item);
updateItemData(item);
final StructuredDataContainer dataContainer = item.dataContainer();
if (dataContainer.has(StructuredDataKey.RARITY)) {
final StructuredDataContainer data = item.dataContainer();
if (data.has(StructuredDataKey.RARITY)) {
return item;
}
// Change rarity of trident and piglin banner pattern
if (item.identifier() == 1188 || item.identifier() == 1200) {
dataContainer.set(StructuredDataKey.RARITY, 0); // Common
data.set(StructuredDataKey.RARITY, 0); // Common
saveTag(createCustomTag(item), new ByteTag(true), "rarity");
}
return item;
@@ -177,7 +173,16 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
super.handleItemToServer(connection, item);
downgradeItemData(item);
resetRarityValues(item, nbtTagName("rarity"));
final StructuredDataContainer data = item.dataContainer();
final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
return item;
}
if (customData.remove(nbtTagName("rarity")) != null) {
data.remove(StructuredDataKey.RARITY);
removeCustomTag(data, customData);
}
return item;
}
@@ -209,21 +214,6 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
});
}
public static void resetRarityValues(final Item item, final String tagName) {
final StructuredDataContainer dataContainer = item.dataContainer();
final CompoundTag customData = dataContainer.get(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
return;
}
if (customData.remove(tagName) != null) {
dataContainer.remove(StructuredDataKey.RARITY);
if (customData.isEmpty()) {
dataContainer.remove(StructuredDataKey.CUSTOM_DATA);
}
}
}
private int itemToJubeboxSong(final int id) {
String identifier = Protocol1_20_5To1_21.MAPPINGS.getFullItemMappings().identifier(id);
if (!identifier.contains("music_disc_")) {
@@ -19,10 +19,12 @@ package com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPacket1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.SerializerVersion;
import com.viaversion.viaversion.util.TagUtil;
import com.viaversion.viaversion.util.UUIDUtil;
@@ -34,8 +36,24 @@ public final class ComponentRewriter1_21 extends ComponentRewriter<ClientboundPa
super(protocol, ReadType.NBT);
}
private void convertAttributeModifiersComponent(final CompoundTag tag) {
final CompoundTag attributeModifiers = TagUtil.getNamespacedCompoundTag(tag, "minecraft:attribute_modifiers");
@Override
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, CompoundTag componentsTag) {
super.handleShowItem(connection, itemTag, componentsTag);
final String identifier = Key.stripMinecraftNamespace(itemTag.getString("id"));
if (identifier.equals("trident") || identifier.equals("piglin_banner_pattern")) {
if (componentsTag == null) {
itemTag.put("components", componentsTag = new CompoundTag());
}
if (!TagUtil.containsNamespaced(componentsTag, "rarity")) {
componentsTag.put("minecraft:rarity", new StringTag("common"));
}
}
if (componentsTag == null) {
return;
}
final CompoundTag attributeModifiers = TagUtil.getNamespacedCompoundTag(componentsTag, "attribute_modifiers");
if (attributeModifiers == null) {
return;
}
@@ -48,14 +66,6 @@ public final class ComponentRewriter1_21 extends ComponentRewriter<ClientboundPa
}
}
@Override
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
super.handleShowItem(connection, itemTag, componentsTag);
if (componentsTag != null) {
convertAttributeModifiersComponent(componentsTag);
}
}
@Override
protected SerializerVersion inputSerializerVersion() {
return SerializerVersion.V1_20_5;
@@ -40,8 +40,7 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.data.Paintings1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.storage.EfficiencyAttributeStorage;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.storage.OnGroundTracker;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.ArrayUtil;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
public final class EntityPacketRewriter1_21 extends EntityRewriter<ClientboundPacket1_20_5, Protocol1_20_5To1_21> {
@@ -55,20 +54,13 @@ public final class EntityPacketRewriter1_21 extends EntityRewriter<ClientboundPa
registerSetEntityData(ClientboundPackets1_20_5.SET_ENTITY_DATA, Types1_20_5.ENTITY_DATA_LIST, Types1_21.ENTITY_DATA_LIST);
registerRemoveEntities(ClientboundPackets1_20_5.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA, wrapper -> {
final String type = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
final RegistryEntry[] entries = wrapper.passthrough(Types.REGISTRY_ENTRY_ARRAY);
if (type.equals("damage_type")) {
// Add required damage type
final CompoundTag campfireDamageType = new CompoundTag();
campfireDamageType.putString("scaling", "when_caused_by_living_non_player");
campfireDamageType.putString("message_id", "inFire");
campfireDamageType.putFloat("exhaustion", 0.1F);
wrapper.set(Types.REGISTRY_ENTRY_ARRAY, 0, ArrayUtil.add(entries, new RegistryEntry("minecraft:campfire", campfireDamageType)));
} else {
handleRegistryData1_20_5(wrapper.user(), type, entries);
}
});
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
final CompoundTag campfireDamageType = new CompoundTag();
campfireDamageType.putString("scaling", "when_caused_by_living_non_player");
campfireDamageType.putString("message_id", "inFire");
campfireDamageType.putFloat("exhaustion", 0.1F);
registryDataRewriter.addEntries("damage_type", new RegistryEntry("minecraft:campfire", campfireDamageType));
protocol.registerClientbound(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA, registryDataRewriter::handle);
protocol.registerFinishConfiguration(ClientboundConfigurationPackets1_20_5.FINISH_CONFIGURATION, wrapper -> {
// Add new registries
@@ -53,6 +53,7 @@ import com.viaversion.viaversion.protocols.v1_20to1_20_2.storage.ConfigurationSt
import com.viaversion.viaversion.protocols.v1_20to1_20_2.storage.ConfigurationState.BridgePhase;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.storage.LastResourcePack;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.storage.LastTags;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.Key;
@@ -64,6 +65,7 @@ public final class Protocol1_20To1_20_2 extends AbstractProtocol<ClientboundPack
public static final MappingData MAPPINGS = new MappingDataBase("1.20", "1.20.2");
private final EntityPacketRewriter1_20_2 entityPacketRewriter = new EntityPacketRewriter1_20_2(this);
private final BlockItemPacketRewriter1_20_2 itemPacketRewriter = new BlockItemPacketRewriter1_20_2(this);
private final ParticleRewriter<ClientboundPackets1_19_4> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
public Protocol1_20To1_20_2() {
@@ -79,6 +81,8 @@ public final class Protocol1_20To1_20_2 extends AbstractProtocol<ClientboundPack
soundRewriter.registerSound1_19_3(ClientboundPackets1_19_4.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_19_4.SOUND_ENTITY);
particleRewriter.registerLevelParticles1_19(ClientboundPackets1_19_4.LEVEL_PARTICLES);
registerClientbound(ClientboundPackets1_19_4.CUSTOM_PAYLOAD, new PacketHandlers() {
@Override
protected void register() {
@@ -377,6 +381,11 @@ public final class Protocol1_20To1_20_2 extends AbstractProtocol<ClientboundPack
return itemPacketRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_19_4> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_4> getTagRewriter() {
return tagRewriter;
@@ -24,13 +24,13 @@ import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
@@ -39,8 +39,8 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter.RecipeRewriter1_19_4;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.data.PotionEffects1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.util.MathUtil;
@@ -65,7 +65,6 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
registerContainerClick1_17_1(ServerboundPackets1_20_2.CONTAINER_CLICK);
registerMerchantOffers1_19(ClientboundPackets1_19_4.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_20_2.SET_CREATIVE_MODE_SLOT);
registerLevelParticles1_19(ClientboundPackets1_19_4.LEVEL_PARTICLES);
protocol.registerServerbound(ServerboundPackets1_20_2.SET_BEACON, wrapper -> {
// Effects start at 1 before 1.20.2
@@ -31,7 +31,6 @@ import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
@@ -46,7 +45,11 @@ import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacke
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.ComponentRewriter1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.EntityPacketRewriter1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.ParticleRewriter1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.BundleStateTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ChunkLoadTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.EntityTracker1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.GroundFlagTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.PlayerPositionStorage;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
@@ -61,6 +64,7 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
public static final MappingData MAPPINGS = new MappingDataBase("1.21", "1.21.2");
private final EntityPacketRewriter1_21_2 entityRewriter = new EntityPacketRewriter1_21_2(this);
private final BlockItemPacketRewriter1_21_2 itemRewriter = new BlockItemPacketRewriter1_21_2(this);
private final ParticleRewriter1_21_2 particleRewriter = new ParticleRewriter1_21_2(this);
private final TagRewriter<ClientboundPacket1_21> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter1_21_2 componentRewriter = new ComponentRewriter1_21_2(this);
@@ -87,6 +91,8 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISGUISED_CHAT);
componentRewriter.registerPing();
particleRewriter.registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
final SoundRewriter<ClientboundPacket1_21> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY);
@@ -189,9 +195,10 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
Types1_21_2.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST1_21_2)
.reader("dust_pillar", ParticleType.Readers.BLOCK)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("block_crumble", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST1_21_2)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION1_21_2)
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
@@ -224,9 +231,11 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_2.PLAYER));
addEntityTracker(connection, new EntityTracker1_21_2(connection));
connection.put(new BundleStateTracker());
connection.put(new PlayerPositionStorage());
connection.put(new ChunkLoadTracker());
connection.put(new GroundFlagTracker());
}
@Override
@@ -244,6 +253,11 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public ParticleRewriter1_21_2 getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21> getTagRewriter() {
return tagRewriter;
@@ -17,27 +17,37 @@
*/
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
import com.viaversion.nbt.tag.ByteTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntArrayTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
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.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
@@ -48,14 +58,21 @@ import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.BundleStateTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ChunkLoadTracker;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.SerializerVersion;
import com.viaversion.viaversion.util.TagUtil;
import com.viaversion.viaversion.util.Unit;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -70,8 +87,7 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
public BlockItemPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) {
super(protocol,
Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_21_2.ITEM, Types1_21_2.ITEM_ARRAY,
Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_21_2.ITEM_COST, Types1_21_2.OPTIONAL_ITEM_COST,
Types1_21.PARTICLE, Types1_21_2.PARTICLE
Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_21_2.ITEM_COST, Types1_21_2.OPTIONAL_ITEM_COST
);
}
@@ -82,14 +98,12 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
blockRewriter.registerBlockUpdate(ClientboundPackets1_21.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21.BLOCK_ENTITY_DATA);
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT);
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_21_2.SET_CREATIVE_MODE_SLOT);
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
protocol.registerClientbound(ClientboundPackets1_21.COOLDOWN, wrapper -> {
final MappingData mappingData = protocol.getMappingData();
@@ -217,10 +231,10 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
final Particle smallExplosionParticle = wrapper.read(Types1_21.PARTICLE);
final Particle largeExplosionParticle = wrapper.read(Types1_21.PARTICLE);
if (power >= 2.0F && blockInteractionMode != 0) {
rewriteParticle(wrapper.user(), largeExplosionParticle);
protocol.getParticleRewriter().rewriteParticle(wrapper.user(), largeExplosionParticle);
wrapper.write(Types1_21_2.PARTICLE, largeExplosionParticle);
} else {
rewriteParticle(wrapper.user(), smallExplosionParticle);
protocol.getParticleRewriter().rewriteParticle(wrapper.user(), smallExplosionParticle);
wrapper.write(Types1_21_2.PARTICLE, smallExplosionParticle);
}
@@ -344,6 +358,50 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
wrapper.write(Types.BOOLEAN, state == RECIPE_INIT); // Replace
});
protocol.registerClientbound(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, wrapper -> {
final Chunk chunk = blockRewriter.handleChunk1_19(wrapper, ChunkType1_20_2::new);
final Mappings blockEntityMappings = protocol.getMappingData().getBlockEntityMappings();
if (blockEntityMappings != null) {
final List<BlockEntity> blockEntities = chunk.blockEntities();
for (int i = 0; i < blockEntities.size(); i++) {
final BlockEntity blockEntity = blockEntities.get(i);
final int id = blockEntity.typeId();
final int mappedId = blockEntityMappings.getNewIdOrDefault(id, id);
if (id != mappedId) {
blockEntities.set(i, blockEntity.withTypeId(mappedId));
}
}
}
final ChunkLoadTracker chunkLoadTracker = wrapper.user().get(ChunkLoadTracker.class);
if (chunkLoadTracker.isChunkLoaded(chunk.getX(), chunk.getZ())) {
// Unload the old chunk, so the new one can be loaded without graphical glitches
// Bundling it prevents the client from falling through the world during the chunk swap
final boolean isBundling = wrapper.user().get(BundleStateTracker.class).isBundling();
if (!isBundling) {
final PacketWrapper bundleStart = wrapper.create(ClientboundPackets1_21_2.BUNDLE_DELIMITER);
bundleStart.send(Protocol1_21To1_21_2.class);
}
final PacketWrapper forgetLevelChunk = wrapper.create(ClientboundPackets1_21_2.FORGET_LEVEL_CHUNK);
forgetLevelChunk.write(Types.CHUNK_POSITION, new ChunkPosition(chunk.getX(), chunk.getZ()));
forgetLevelChunk.send(Protocol1_21To1_21_2.class);
wrapper.send(Protocol1_21To1_21_2.class);
wrapper.cancel();
if (!isBundling) {
final PacketWrapper bundleEnd = wrapper.create(ClientboundPackets1_21_2.BUNDLE_DELIMITER);
bundleEnd.send(Protocol1_21To1_21_2.class);
}
} else {
chunkLoadTracker.addChunk(chunk.getX(), chunk.getZ());
}
});
protocol.registerClientbound(ClientboundPackets1_21.FORGET_LEVEL_CHUNK, wrapper -> {
final ChunkPosition chunkPosition = wrapper.passthrough(Types.CHUNK_POSITION);
wrapper.user().get(ChunkLoadTracker.class).removeChunk(chunkPosition.chunkX(), chunkPosition.chunkZ());
});
}
private void convertServerboundRecipeDisplayId(final PacketWrapper wrapper) {
@@ -357,38 +415,95 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
wrapper.write(Types.STRING, recipe.identifier());
}
@Override
public void rewriteParticle(final UserConnection connection, final Particle particle) {
super.rewriteParticle(connection, particle);
final String identifier = protocol.getMappingData().getParticleMappings().mappedIdentifier(particle.id());
if (identifier.equals("minecraft:dust_color_transition")) {
floatsToARGB(particle, 0);
floatsToARGB(particle, 1);
} else if (identifier.equals("minecraft:dust")) {
floatsToARGB(particle, 0);
}
}
private void floatsToARGB(final Particle particle, final int fromIndex) {
final Particle.ParticleData<Float> r = particle.removeArgument(fromIndex);
final Particle.ParticleData<Float> g = particle.removeArgument(fromIndex);
final Particle.ParticleData<Float> b = particle.removeArgument(fromIndex);
final int rgb = 255 << 24 | (int) (r.getValue() * 255) << 16 | (int) (g.getValue() * 255) << 8 | (int) (b.getValue() * 255);
particle.add(fromIndex, Types.INT, rgb);
}
@Override
public Item handleItemToClient(final UserConnection connection, final Item item) {
if (item.isEmpty()) {
return item;
}
super.handleItemToClient(connection, item);
updateItemData(item);
// Add data components to fix issues in older protocols
appendItemDataFixComponents(connection, item);
final StructuredDataContainer data = item.dataContainer();
final Enchantments enchantments = data.get(StructuredDataKey.ENCHANTMENTS);
if (enchantments != null && enchantments.size() != 0) {
// Level 0 is no longer allowed
final IntList enchantmentIds = new IntArrayList();
enchantments.enchantments().int2IntEntrySet().removeIf(entry -> {
if (entry.getIntValue() == 0) {
enchantmentIds.add(entry.getIntKey());
return true;
}
return false;
});
if (!enchantmentIds.isEmpty()) {
final IntArrayTag enchantmentIdsTag = new IntArrayTag(enchantmentIds.toIntArray());
saveTag(createCustomTag(item), enchantmentIdsTag, "0_enchants");
}
if (enchantments.size() == 0 && !data.has(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE)) {
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true);
saveTag(createCustomTag(item), new ByteTag(true), "remove_glint");
}
}
// Item name is now overridden by custom implemented display names (compass, player head, potion, shield, tipped arrow)
final int identifier = item.identifier();
if (identifier == 952 || identifier == 1147 || identifier == 1039 || identifier == 1203 || identifier == 1200 || identifier == 1204 || identifier == 1202) {
final Tag itemName = data.get(StructuredDataKey.ITEM_NAME);
if (itemName != null && !data.has(StructuredDataKey.CUSTOM_NAME)) {
final CompoundTag name = new CompoundTag();
name.putBoolean("italic", false);
name.putString("text", "");
name.put("extra", new ListTag<>(Collections.singletonList(itemName)));
data.set(StructuredDataKey.CUSTOM_NAME, name);
saveTag(createCustomTag(item), new ByteTag(true), "remove_custom_name");
}
}
return item;
}
@Override
public Item handleItemToServer(final UserConnection connection, final Item item) {
if (item.isEmpty()) {
return item;
}
super.handleItemToServer(connection, item);
downgradeItemData(item);
final StructuredDataContainer dataContainer = item.dataContainer();
final CompoundTag customData = dataContainer.get(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
return item;
}
if (customData.remove(nbtTagName("remove_custom_name")) != null) {
dataContainer.remove(StructuredDataKey.CUSTOM_NAME);
removeCustomTag(dataContainer, customData);
}
final IntArrayTag emptyEnchantments = customData.getIntArrayTag(nbtTagName("0_enchants"));
if (emptyEnchantments != null) {
Enchantments enchantments = dataContainer.get(StructuredDataKey.ENCHANTMENTS);
if (enchantments == null) {
enchantments = new Enchantments(true);
dataContainer.set(StructuredDataKey.ENCHANTMENTS, enchantments);
}
for (final int enchantmentId : emptyEnchantments.getValue()) {
enchantments.enchantments().put(enchantmentId, 0);
}
customData.remove(nbtTagName("0_enchants"));
if (customData.remove(nbtTagName("remove_glint")) != null) {
dataContainer.remove(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE);
}
removeCustomTag(dataContainer, customData);
}
return item;
}
@@ -406,6 +521,17 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
wrapper.write(Types.UNSIGNED_BYTE, (short) containerId);
}
private void appendItemDataFixComponents(final UserConnection connection, final Item item) {
final ProtocolVersion serverVersion = connection.getProtocolInfo().serverProtocolVersion();
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_8) && item.dataContainer().hasValue(StructuredDataKey.CONSUMABLE1_21_2)) {
if (item.identifier() == 840 || item.identifier() == 845 || item.identifier() == 850 || item.identifier() == 855 || item.identifier() == 860) { // swords
// Change the consume animation of swords to block
final Consumable1_21_2 consumable = item.dataContainer().get(StructuredDataKey.CONSUMABLE1_21_2);
item.dataContainer().set(StructuredDataKey.CONSUMABLE1_21_2, new Consumable1_21_2(consumable.consumeSeconds(), 3, consumable.sound(), consumable.hasConsumeParticles(), consumable.consumeEffects()));
}
}
}
public static void updateItemData(final Item item) {
final StructuredDataContainer dataContainer = item.dataContainer();
dataContainer.replace(StructuredDataKey.INSTRUMENT1_20_5, StructuredDataKey.INSTRUMENT1_21_2, instrument -> {
@@ -423,6 +549,7 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
final Consumable1_21_2.ApplyStatusEffects applyStatusEffects = new Consumable1_21_2.ApplyStatusEffects(new PotionEffect[]{effect.effect()}, effect.probability());
consumeEffects[i] = new Consumable1_21_2.ConsumeEffect<>(0 /* add status effect */, Consumable1_21_2.ApplyStatusEffects.TYPE, applyStatusEffects);
}
dataContainer.set(StructuredDataKey.CONSUMABLE1_21_2, new Consumable1_21_2(food.eatSeconds(), 1 /* eat */, sound, true, consumeEffects));
if (food.usingConvertsTo() != null) {
dataContainer.set(StructuredDataKey.USE_REMAINDER, food.usingConvertsTo());
@@ -434,11 +561,13 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21, StructuredDataKey.BUNDLE_CONTENTS1_21_2);
dataContainer.replaceKey(StructuredDataKey.POTION_CONTENTS1_20_5, StructuredDataKey.POTION_CONTENTS1_21_2);
dataContainer.replace(StructuredDataKey.FIRE_RESISTANT, StructuredDataKey.DAMAGE_RESISTANT, fireResistant -> new DamageResistant("minecraft:is_fire"));
dataContainer.replace(StructuredDataKey.LOCK, lock -> {
dataContainer.replace(StructuredDataKey.LOCK, tag -> {
final String lock = ((StringTag) tag).getValue();
final CompoundTag predicateTag = new CompoundTag();
final CompoundTag itemComponentsTag = new CompoundTag();
predicateTag.put("components", itemComponentsTag);
itemComponentsTag.put("custom_name", lock);
// As json here...
itemComponentsTag.putString("custom_name", ComponentUtil.plainToJson(lock).toString());
return predicateTag;
});
}
@@ -449,7 +578,9 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
final CompoundTag predicateTag = (CompoundTag) lock;
final CompoundTag itemComponentsTag = predicateTag.getCompoundTag("components");
if (itemComponentsTag != null) {
return TagUtil.getNamespacedStringTag(itemComponentsTag, "custom_name");
// Back from json in the string tag to plain text
final StringTag customName = TagUtil.getNamespacedStringTag(itemComponentsTag, "custom_name");
return new StringTag(SerializerVersion.V1_20_5.toComponent(customName.getValue()).asUnformattedString());
}
return null;
});
@@ -19,7 +19,9 @@ package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.NumberTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
@@ -27,6 +29,7 @@ import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.util.SerializerVersion;
import com.viaversion.viaversion.util.TagUtil;
import java.util.Collections;
import java.util.Iterator;
public final class ComponentRewriter1_21_2 extends ComponentRewriter<ClientboundPacket1_21> {
@@ -60,8 +63,35 @@ public final class ComponentRewriter1_21_2 extends ComponentRewriter<Clientbound
food.remove("effects");
}
final CompoundTag enchantments = TagUtil.getNamespacedCompoundTag(componentsTag, "enchantments");
if (enchantments != null) {
final CompoundTag levels = enchantments.getCompoundTag("levels");
levels.entrySet().removeIf(entry -> ((NumberTag) entry.getValue()).asInt() == 0);
}
TagUtil.removeNamespaced(componentsTag, "fire_resistant");
TagUtil.removeNamespaced(componentsTag, "lock");
final StringTag customName = TagUtil.getNamespacedStringTag(componentsTag, "custom_name");
final StringTag itemName = TagUtil.getNamespacedStringTag(componentsTag, "item_name");
if (customName != null || itemName == null) {
return;
}
final int identifier = protocol.getMappingData().getFullItemMappings().mappedId(itemTag.getString("id"));
if (identifier == 952 || identifier == 1147 || identifier == 1039 || identifier == 1203 || identifier == 1200 || identifier == 1204 || identifier == 1202) {
final var input = inputSerializerVersion();
final var output = outputSerializerVersion();
final CompoundTag name = new CompoundTag();
name.putBoolean("italic", false);
name.putString("text", "");
final Tag nameTag = input.toTag(input.toComponent(itemName.getValue()));
name.put("extra", new ListTag<>(Collections.singletonList(nameTag)));
componentsTag.put("minecraft:custom_name", new StringTag(output.toString(output.toComponent(name))));
}
}
public static void convertAttributes(final CompoundTag componentsTag, final FullMappings mappings) {
@@ -18,9 +18,13 @@
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
@@ -33,10 +37,15 @@ import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.BundleStateTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ChunkLoadTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ClientVehicleStorage;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.EntityTracker1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.GroundFlagTracker;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.PlayerPositionStorage;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
public final class EntityPacketRewriter1_21_2 extends EntityRewriter<ClientboundPacket1_21, Protocol1_21To1_21_2> {
@@ -63,6 +72,32 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA, Types1_21.ENTITY_DATA_LIST, Types1_21_2.ENTITY_DATA_LIST);
registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES);
protocol.appendClientbound(ClientboundPackets1_21.ADD_ENTITY, wrapper -> {
final int entityType = wrapper.get(Types.VAR_INT, 1);
final EntityType type = typeFromId(entityType);
if (type == null || !type.isOrHasParent(EntityTypes1_21_2.ABSTRACT_BOAT)) {
return;
}
final int entityId = wrapper.get(Types.VAR_INT, 0);
final UUID uuid = wrapper.get(Types.UUID, 0);
final double x = wrapper.get(Types.DOUBLE, 0);
final double y = wrapper.get(Types.DOUBLE, 1);
final double z = wrapper.get(Types.DOUBLE, 2);
final float pitch = wrapper.get(Types.BYTE, 0) * 256.0F / 360.0F;
final float yaw = wrapper.get(Types.BYTE, 1) * 256.0F / 360.0F;
final int data = wrapper.get(Types.VAR_INT, 2);
final EntityTracker1_21_2 tracker = tracker(wrapper.user());
final EntityTracker1_21_2.BoatEntity entity = tracker.trackBoatEntity(entityId, uuid, data);
entity.setPosition(x, y, z);
entity.setRotation(yaw, pitch);
});
protocol.registerFinishConfiguration(ClientboundConfigurationPackets1_21.FINISH_CONFIGURATION, wrapper -> {
final PacketWrapper instrumentsPacket = wrapper.create(ClientboundConfigurationPackets1_21.REGISTRY_DATA);
instrumentsPacket.write(Types.STRING, "minecraft:instrument");
@@ -121,8 +156,15 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
wrapper.passthrough(Types.VAR_INT); // Portal cooldown
wrapper.write(Types.VAR_INT, 64); // Sea level
final EntityTracker entityTracker = tracker(wrapper.user());
if (entityTracker.currentWorld() != null && !entityTracker.currentWorld().equals(world)) {
wrapper.user().get(ChunkLoadTracker.class).clear();
}
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
wrapper.user().put(new GroundFlagTracker());
wrapper.user().remove(ClientVehicleStorage.class);
});
@@ -185,6 +227,12 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
wrapper.user().remove(ClientVehicleStorage.class);
}
final EntityTracker1_21_2 tracker = tracker(wrapper.user());
final EntityTracker1_21_2.BoatEntity entity = tracker.trackedBoatEntity(vehicleId);
if (entity != null) {
entity.setPassengers(passengerIds);
}
final int clientEntityId = tracker(wrapper.user()).clientEntityId();
for (final int passenger : passengerIds) {
if (passenger == clientEntityId) {
@@ -235,11 +283,11 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
});
protocol.registerClientbound(ClientboundPackets1_21.TELEPORT_ENTITY, ClientboundPackets1_21_2.ENTITY_POSITION_SYNC, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
final int entityId = wrapper.passthrough(Types.VAR_INT); // Entity ID
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
final double x = wrapper.passthrough(Types.DOUBLE); // X
final double y = wrapper.passthrough(Types.DOUBLE); // Y
final double z = wrapper.passthrough(Types.DOUBLE); // Z
// Unused...
wrapper.write(Types.DOUBLE, 0D); // Delta movement X
@@ -247,17 +295,28 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
wrapper.write(Types.DOUBLE, 0D); // Delta movement Z
// Unpack y and x rot
final byte yaw = wrapper.read(Types.BYTE);
final byte pitch = wrapper.read(Types.BYTE);
wrapper.write(Types.FLOAT, yaw * 360F / 256F);
wrapper.write(Types.FLOAT, pitch * 360F / 256F);
final float yaw = wrapper.read(Types.BYTE) * 360F / 256F;
final float pitch = wrapper.read(Types.BYTE) * 360F / 256F;
wrapper.write(Types.FLOAT, yaw);
wrapper.write(Types.FLOAT, pitch);
final EntityTracker1_21_2 tracker = tracker(wrapper.user());
final EntityTracker1_21_2.BoatEntity trackedEntity = tracker.trackedBoatEntity(entityId);
if (trackedEntity == null) {
return;
}
trackedEntity.setPosition(x, y, z);
trackedEntity.setRotation(yaw, pitch);
});
protocol.registerClientbound(ClientboundPackets1_21.MOVE_ENTITY_POS, wrapper -> storeEntityPositionRotation(wrapper, true, false));
protocol.registerClientbound(ClientboundPackets1_21.MOVE_ENTITY_POS_ROT, wrapper -> storeEntityPositionRotation(wrapper, true, true));
protocol.registerClientbound(ClientboundPackets1_21.MOVE_ENTITY_ROT, wrapper -> storeEntityPositionRotation(wrapper, false, true));
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
readOnGround(wrapper);
handleOnGround(wrapper);
});
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS_ROT, wrapper -> {
final double x = wrapper.passthrough(Types.DOUBLE); // X
@@ -265,7 +324,7 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
final double z = wrapper.passthrough(Types.DOUBLE); // Z
final float yaw = wrapper.passthrough(Types.FLOAT); // Yaw
final float pitch = wrapper.passthrough(Types.FLOAT); // Pitch
readOnGround(wrapper);
handleOnGround(wrapper);
final PlayerPositionStorage playerPositionStorage = wrapper.user().get(PlayerPositionStorage.class);
if (playerPositionStorage.checkCaptureNextPlayerPositionPacket()) {
@@ -278,9 +337,19 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_ROT, wrapper -> {
wrapper.passthrough(Types.FLOAT); // Yaw
wrapper.passthrough(Types.FLOAT); // Pitch
readOnGround(wrapper);
handleOnGround(wrapper);
});
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, wrapper -> {
final GroundFlagTracker tracker = wrapper.user().get(GroundFlagTracker.class);
final boolean prevOnGround = tracker.onGround();
final boolean prevHorizontalCollision = tracker.horizontalCollision();
handleOnGround(wrapper);
if (prevOnGround == tracker.onGround() && prevHorizontalCollision != tracker.horizontalCollision()) {
// Newer clients will send idle packets even though the on ground state didn't change, ignore them
wrapper.cancel();
}
});
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, this::readOnGround);
protocol.registerServerbound(ServerboundPackets1_21_2.ACCEPT_TELEPORTATION, wrapper -> {
final PlayerPositionStorage playerPositionStorage = wrapper.user().get(PlayerPositionStorage.class);
if (playerPositionStorage.checkHasPlayerPosition()) {
@@ -313,9 +382,33 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
return registryDataRewriter;
}
private void readOnGround(final PacketWrapper wrapper) {
private void handleOnGround(final PacketWrapper wrapper) {
final GroundFlagTracker tracker = wrapper.user().get(GroundFlagTracker.class);
final short data = wrapper.read(Types.UNSIGNED_BYTE);
wrapper.write(Types.BOOLEAN, (data & 1) != 0); // On ground, ignoring horizontal collision data
wrapper.write(Types.BOOLEAN, tracker.setOnGround((data & 1) != 0)); // Ignoring horizontal collision data
tracker.setHorizontalCollision((data & 2) != 0);
}
private void storeEntityPositionRotation(final PacketWrapper wrapper, final boolean position, final boolean rotation) {
final int entityId = wrapper.passthrough(Types.VAR_INT); // Entity id
final EntityTracker1_21_2 tracker = tracker(wrapper.user());
final EntityTracker1_21_2.BoatEntity trackedEntity = tracker.trackedBoatEntity(entityId);
if (trackedEntity == null) {
return;
}
if (position) {
final double x = wrapper.passthrough(Types.SHORT) / 4096.0; // Delta X
final double y = wrapper.passthrough(Types.SHORT) / 4096.0; // Delta Y
final double z = wrapper.passthrough(Types.SHORT) / 4096.0; // Delta Z
trackedEntity.setPosition(trackedEntity.x() + x, trackedEntity.y() + y, trackedEntity.z() + z);
}
if (rotation) {
final float yaw = wrapper.passthrough(Types.BYTE) * 360.0F / 256.0F;
final float pitch = wrapper.passthrough(Types.BYTE) * 360.0F / 256.0F;
trackedEntity.setRotation(yaw, pitch);
}
}
@Override
@@ -333,7 +426,84 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
);
registerBlockStateHandler(EntityTypes1_21_2.ABSTRACT_MINECART, 11);
filter().type(EntityTypes1_21_2.ABSTRACT_BOAT).removeIndex(11); // Goodbye boat type
filter().type(EntityTypes1_21_2.ABSTRACT_BOAT).handler((event, data) -> {
final int dataIndex = event.index();
// Boat type - now set as own entity type
// Idea is to remove the old entity, then add a new one and re-apply entity data and passengers
if (dataIndex > 11) {
event.setIndex(dataIndex - 1);
return;
}
if (dataIndex != 11) {
return;
}
event.cancel();
final EntityTracker1_21_2 tracker = tracker(event.user());
final EntityTracker1_21_2.BoatEntity entity = tracker.trackedBoatEntity(event.entityId());
if (entity == null) {
return;
}
final boolean isBundling = event.user().get(BundleStateTracker.class).isBundling();
if (!isBundling) {
final PacketWrapper bundleStart = PacketWrapper.create(ClientboundPackets1_21_2.BUNDLE_DELIMITER, event.user());
bundleStart.send(Protocol1_21To1_21_2.class);
}
// Remove old entity
final PacketWrapper removeEntityPacket = PacketWrapper.create(ClientboundPackets1_21_2.REMOVE_ENTITIES, event.user());
removeEntityPacket.write(Types.VAR_INT_ARRAY_PRIMITIVE, new int[] { event.entityId() });
removeEntityPacket.send(Protocol1_21To1_21_2.class);
// Detect correct boat entity type from entity data
final int boatType = (int) data.getValue();
EntityType entityType;
if (tracker.entityType(event.entityId()).isOrHasParent(EntityTypes1_21_2.ABSTRACT_CHEST_BOAT)) {
entityType = entityTypeFromChestBoatType(boatType);
} else {
entityType = entityTypeFromBoatType(boatType);
}
// Spawn new entity
final PacketWrapper spawnEntityPacket = PacketWrapper.create(ClientboundPackets1_21_2.ADD_ENTITY, event.user());
spawnEntityPacket.write(Types.VAR_INT, event.entityId()); // Entity ID
spawnEntityPacket.write(Types.UUID, entity.uuid()); // Entity UUID
spawnEntityPacket.write(Types.VAR_INT, entityType.getId()); // Entity type
spawnEntityPacket.write(Types.DOUBLE, entity.x()); // X
spawnEntityPacket.write(Types.DOUBLE, entity.y()); // Y
spawnEntityPacket.write(Types.DOUBLE, entity.z()); // Z
spawnEntityPacket.write(Types.BYTE, (byte) Math.floor(entity.pitch() * 256.0F / 360.0F)); // Pitch
spawnEntityPacket.write(Types.BYTE, (byte) Math.floor(entity.yaw() * 256.0F / 360.0F)); // Yaw
spawnEntityPacket.write(Types.BYTE, (byte) 0); // Head yaw
spawnEntityPacket.write(Types.VAR_INT, entity.data()); // Data
spawnEntityPacket.write(Types.SHORT, (short) 0); // Velocity X
spawnEntityPacket.write(Types.SHORT, (short) 0); // Velocity Y
spawnEntityPacket.write(Types.SHORT, (short) 0); // Velocity Z
spawnEntityPacket.send(Protocol1_21To1_21_2.class);
// Update tracked entity in storage with new entity type
tracker.updateBoatType(event.entityId(), entityType);
// Re-apply entity data previously set
final PacketWrapper setEntityDataPacket = PacketWrapper.create(ClientboundPackets1_21_2.SET_ENTITY_DATA, event.user());
setEntityDataPacket.write(Types.VAR_INT, event.entityId());
setEntityDataPacket.write(Types1_21_2.ENTITY_DATA_LIST, entity.entityData());
setEntityDataPacket.send(Protocol1_21To1_21_2.class);
// Re-attach all passengers
if (entity.passengers() != null) {
final PacketWrapper setPassengersPacket = PacketWrapper.create(ClientboundPackets1_21_2.SET_PASSENGERS, event.user());
setPassengersPacket.write(Types.VAR_INT, event.entityId());
setPassengersPacket.write(Types.VAR_INT_ARRAY_PRIMITIVE, entity.passengers());
setPassengersPacket.send(Protocol1_21To1_21_2.class);
}
if (!isBundling) {
final PacketWrapper bundleEnd = PacketWrapper.create(ClientboundPackets1_21_2.BUNDLE_DELIMITER, event.user());
bundleEnd.send(Protocol1_21To1_21_2.class);
}
});
filter().type(EntityTypes1_21_2.SALMON).addIndex(17); // Data type
filter().type(EntityTypes1_21_2.AGEABLE_WATER_CREATURE).addIndex(16); // Baby
@@ -341,6 +511,76 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
filter().type(EntityTypes1_21_2.ABSTRACT_ARROW).addIndex(10); // In ground
}
@Override
public void handleEntityData(final int entityId, final List<EntityData> dataList, final UserConnection connection) {
super.handleEntityData(entityId, dataList, connection);
final EntityTracker1_21_2 tracker = tracker(connection);
final EntityType entityType = tracker.entityType(entityId);
if (entityType == null || !entityType.isOrHasParent(EntityTypes1_21_2.ABSTRACT_BOAT)) {
return;
}
final List<EntityData> entityData = tracker.trackedBoatEntity(entityId).entityData();
entityData.removeIf(first -> dataList.stream().anyMatch(second -> first.id() == second.id()));
for (final EntityData data : dataList) {
final Object value = data.value();
if (value instanceof Item item) {
entityData.add(new EntityData(data.id(), data.dataType(), item.copy()));
} else {
entityData.add(new EntityData(data.id(), data.dataType(), value));
}
}
}
private EntityType entityTypeFromBoatType(final int boatType) {
if (boatType == 0) {
return EntityTypes1_21_2.OAK_BOAT;
} else if (boatType == 1) {
return EntityTypes1_21_2.SPRUCE_BOAT;
} else if (boatType == 2) {
return EntityTypes1_21_2.BIRCH_BOAT;
} else if (boatType == 3) {
return EntityTypes1_21_2.JUNGLE_BOAT;
} else if (boatType == 4) {
return EntityTypes1_21_2.ACACIA_BOAT;
} else if (boatType == 5) {
return EntityTypes1_21_2.CHERRY_BOAT;
} else if (boatType == 6) {
return EntityTypes1_21_2.DARK_OAK_BOAT;
} else if (boatType == 7) {
return EntityTypes1_21_2.MANGROVE_BOAT;
} else if (boatType == 8) {
return EntityTypes1_21_2.BAMBOO_RAFT;
} else {
return EntityTypes1_21_2.OAK_BOAT; // Fallback
}
}
private EntityType entityTypeFromChestBoatType(final int chestBoatType) {
if (chestBoatType == 0) {
return EntityTypes1_21_2.OAK_CHEST_BOAT;
} else if (chestBoatType == 1) {
return EntityTypes1_21_2.SPRUCE_CHEST_BOAT;
} else if (chestBoatType == 2) {
return EntityTypes1_21_2.BIRCH_CHEST_BOAT;
} else if (chestBoatType == 3) {
return EntityTypes1_21_2.JUNGLE_CHEST_BOAT;
} else if (chestBoatType == 4) {
return EntityTypes1_21_2.ACACIA_CHEST_BOAT;
} else if (chestBoatType == 5) {
return EntityTypes1_21_2.CHERRY_CHEST_BOAT;
} else if (chestBoatType == 6) {
return EntityTypes1_21_2.DARK_OAK_CHEST_BOAT;
} else if (chestBoatType == 7) {
return EntityTypes1_21_2.MANGROVE_CHEST_BOAT;
} else if (chestBoatType == 8) {
return EntityTypes1_21_2.BAMBOO_CHEST_RAFT;
} else {
return EntityTypes1_21_2.OAK_CHEST_BOAT; // Fallback
}
}
@Override
public EntityType typeFromId(final int type) {
return EntityTypes1_21_2.getTypeFromId(type);
@@ -0,0 +1,55 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.v1_21to1_21_2.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
public final class ParticleRewriter1_21_2 extends ParticleRewriter<ClientboundPacket1_21> {
public ParticleRewriter1_21_2(final Protocol<ClientboundPacket1_21, ?, ?, ?> protocol) {
super(protocol, Types1_21.PARTICLE, Types1_21_2.PARTICLE);
}
private void floatsToARGB(final Particle particle, final int fromIndex) {
final Particle.ParticleData<Float> r = particle.removeArgument(fromIndex);
final Particle.ParticleData<Float> g = particle.removeArgument(fromIndex);
final Particle.ParticleData<Float> b = particle.removeArgument(fromIndex);
final int rgb = 255 << 24 | (int) (r.getValue() * 255) << 16 | (int) (g.getValue() * 255) << 8 | (int) (b.getValue() * 255);
particle.add(fromIndex, Types.INT, rgb);
}
@Override
public void rewriteParticle(final UserConnection connection, final Particle particle) {
super.rewriteParticle(connection, particle);
final String identifier = protocol.getMappingData().getParticleMappings().mappedIdentifier(particle.id());
if (identifier.equals("minecraft:dust_color_transition")) {
floatsToARGB(particle, 0);
floatsToARGB(particle, 1);
} else if (identifier.equals("minecraft:dust")) {
floatsToARGB(particle, 0);
}
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.v1_21to1_21_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import java.util.HashSet;
import java.util.Set;
public class ChunkLoadTracker implements StorableObject {
private final Set<Long> loadedChunks = new HashSet<>();
public void addChunk(final int x, final int z) {
this.loadedChunks.add(ChunkPosition.chunkKey(x, z));
}
public void removeChunk(final int x, final int z) {
this.loadedChunks.remove(ChunkPosition.chunkKey(x, z));
}
public boolean isChunkLoaded(final int x, final int z) {
return this.loadedChunks.contains(ChunkPosition.chunkKey(x, z));
}
public void clear() {
this.loadedChunks.clear();
}
}
@@ -0,0 +1,135 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.v1_21to1_21_2.storage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public final class EntityTracker1_21_2 extends EntityTrackerBase {
private final Int2ObjectMap<BoatEntity> boats = new Int2ObjectOpenHashMap<>();
public EntityTracker1_21_2(final UserConnection connection) {
super(connection, EntityTypes1_21_2.PLAYER);
}
public BoatEntity trackBoatEntity(final int entityId, final UUID uuid, final int data) {
final BoatEntity entity = new BoatEntity(uuid, data);
boats.put(entityId, entity);
return entity;
}
public BoatEntity trackedBoatEntity(final int entityId) {
return boats.get(entityId);
}
@Override
public void removeEntity(final int id) {
super.removeEntity(id);
boats.remove(id);
}
public void updateBoatType(final int entityId, final EntityType type) {
final BoatEntity entity = boats.get(entityId);
removeEntity(entityId);
boats.put(entityId, entity);
addEntity(entityId, type);
}
public static class BoatEntity {
private final List<EntityData> entityData = new ArrayList<>();
private final UUID uuid;
private final int data;
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
private int[] passengers;
public BoatEntity(final UUID uuid, final int data) {
this.uuid = uuid;
this.data = data;
}
public void setPosition(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void setRotation(final float yaw, final float pitch) {
this.yaw = yaw;
this.pitch = pitch;
}
public void setPassengers(final int[] passengers) {
this.passengers = passengers;
}
public UUID uuid() {
return uuid;
}
public int data() {
return data;
}
public double x() {
return x;
}
public double y() {
return y;
}
public double z() {
return z;
}
public float yaw() {
return yaw;
}
public float pitch() {
return pitch;
}
public List<EntityData> entityData() {
return entityData;
}
public int[] passengers() {
return passengers;
}
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.v1_21to1_21_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public final class GroundFlagTracker implements StorableObject {
private boolean onGround;
private boolean horizontalCollision;
public boolean onGround() {
return this.onGround;
}
public boolean setOnGround(boolean onGround) {
return this.onGround = onGround;
}
public boolean horizontalCollision() {
return this.horizontalCollision;
}
public void setHorizontalCollision(boolean horizontalCollision) {
this.horizontalCollision = horizontalCollision;
}
}
@@ -21,8 +21,8 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.BlockFace;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import com.viaversion.viaversion.api.minecraft.chunks.BaseChunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
@@ -133,7 +133,7 @@ public class WorldPacketRewriter1_9 {
ClientWorld1_9 clientWorld = wrapper.user().getClientWorld(Protocol1_8To1_9.class);
Chunk chunk = wrapper.read(ChunkType1_8.forEnvironment(clientWorld.getEnvironment()));
long chunkHash = ClientWorld1_9.toLong(chunk.getX(), chunk.getZ());
long chunkHash = ChunkPosition.chunkKey(chunk.getX(), chunk.getZ());
// Check if the chunk should be handled as an unload packet
if (chunk.isFullChunk() && chunk.getBitmask() == 0) {
@@ -152,7 +152,7 @@ public class WorldPacketRewriter1_9 {
for (BlockFace face : BlockFace.HORIZONTAL) {
int chunkX = chunk.getX() + face.modX();
int chunkZ = chunk.getZ() + face.modZ();
if (!clientWorld.getLoadedChunks().contains(ClientWorld1_9.toLong(chunkX, chunkZ))) {
if (!clientWorld.getLoadedChunks().contains(ChunkPosition.chunkKey(chunkX, chunkZ))) {
PacketWrapper unloadChunk = wrapper.create(ClientboundPackets1_9.FORGET_LEVEL_CHUNK);
unloadChunk.write(Types.INT, chunkX);
unloadChunk.write(Types.INT, chunkZ);
@@ -171,7 +171,7 @@ public class WorldPacketRewriter1_9 {
for (BlockFace face : BlockFace.HORIZONTAL) {
int chunkX = chunk.getX() + face.modX();
int chunkZ = chunk.getZ() + face.modZ();
if (!clientWorld.getLoadedChunks().contains(ClientWorld1_9.toLong(chunkX, chunkZ))) {
if (!clientWorld.getLoadedChunks().contains(ChunkPosition.chunkKey(chunkX, chunkZ))) {
PacketWrapper emptyChunk = wrapper.create(ClientboundPackets1_9.LEVEL_CHUNK);
Chunk c = new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], new int[256], new ArrayList<>());
emptyChunk.write(chunkType, c);
@@ -194,14 +194,14 @@ public class WorldPacketRewriter1_9 {
chunkData.write(chunkType, chunk);
chunkData.send(Protocol1_8To1_9.class);
clientWorld.getLoadedChunks().add(ClientWorld1_9.toLong(chunk.getX(), chunk.getZ()));
clientWorld.getLoadedChunks().add(ChunkPosition.chunkKey(chunk.getX(), chunk.getZ()));
// Send empty chunks surrounding the loaded chunk to force 1.9+ clients to render the new chunk
if (Via.getConfig().isChunkBorderFix()) {
for (BlockFace face : BlockFace.HORIZONTAL) {
int chunkX = chunk.getX() + face.modX();
int chunkZ = chunk.getZ() + face.modZ();
if (!clientWorld.getLoadedChunks().contains(ClientWorld1_9.toLong(chunkX, chunkZ))) {
if (!clientWorld.getLoadedChunks().contains(ChunkPosition.chunkKey(chunkX, chunkZ))) {
PacketWrapper emptyChunk = wrapper.create(ClientboundPackets1_9.LEVEL_CHUNK);
Chunk c = new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], new int[256], new ArrayList<>());
emptyChunk.write(chunkType, c);
@@ -17,16 +17,13 @@
*/
package com.viaversion.viaversion.protocols.v1_8to1_9.storage;
import com.google.common.collect.Sets;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import java.util.HashSet;
import java.util.Set;
public class ClientWorld1_9 extends ClientWorld {
private final Set<Long> loadedChunks = Sets.newConcurrentHashSet();
public static long toLong(int msw, int lsw) {
return ((long) msw << 32) + lsw + 2147483648L;
}
private final Set<Long> loadedChunks = new HashSet<>();
public Set<Long> getLoadedChunks() {
return loadedChunks;
@@ -22,12 +22,12 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
public class CommandBlockStorage implements StorableObject {
private final Map<Pair<Integer, Integer>, Map<BlockPosition, CompoundTag>> storedCommandBlocks = new ConcurrentHashMap<>();
private final Map<Pair<Integer, Integer>, Map<BlockPosition, CompoundTag>> storedCommandBlocks = new HashMap<>();
private boolean permissions;
public void unloadChunk(int x, int z) {
@@ -39,7 +39,7 @@ public class CommandBlockStorage implements StorableObject {
Pair<Integer, Integer> chunkPos = getChunkCoords(position);
if (!storedCommandBlocks.containsKey(chunkPos)) {
storedCommandBlocks.put(chunkPos, new ConcurrentHashMap<>());
storedCommandBlocks.put(chunkPos, new HashMap<>());
}
Map<BlockPosition, CompoundTag> blocks = storedCommandBlocks.get(chunkPos);
@@ -35,7 +35,6 @@ import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.MathUtil;
@@ -68,83 +67,61 @@ public class BlockRewriter<C extends ClientboundPacketType> {
}
public void registerBlockEvent(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(positionType); // Location
map(Types.UNSIGNED_BYTE); // Action id
map(Types.UNSIGNED_BYTE); // Action param
map(Types.VAR_INT); // Block id - /!\ NOT BLOCK STATE
handler(wrapper -> {
if (protocol.getMappingData().getBlockMappings() == null) {
return;
}
if (protocol.getMappingData().getBlockMappings() == null) {
return;
}
int id = wrapper.get(Types.VAR_INT, 0);
int mappedId = protocol.getMappingData().getNewBlockId(id);
if (mappedId == -1) {
// Block (action) has been removed
wrapper.cancel();
return;
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(positionType); // Location
wrapper.passthrough(Types.UNSIGNED_BYTE); // Action id
wrapper.passthrough(Types.UNSIGNED_BYTE); // Action param
final int blockId = wrapper.passthrough(Types.VAR_INT);
final int mappedId = protocol.getMappingData().getNewBlockId(blockId);
if (mappedId == -1) {
wrapper.cancel();
return;
}
wrapper.set(Types.VAR_INT, 0, mappedId);
});
if (blockId != mappedId) {
wrapper.set(Types.VAR_INT, 0, mappedId);
}
});
}
public void registerBlockUpdate(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(positionType);
map(Types.VAR_INT);
handler(wrapper -> wrapper.set(Types.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(wrapper.get(Types.VAR_INT, 0))));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(positionType);
final int blockId = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(blockId));
});
}
public void registerChunkBlocksUpdate(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // 0 - Chunk X
map(Types.INT); // 1 - Chunk Z
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.passthrough(Types.BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.INT); // Chunk X
wrapper.passthrough(Types.INT); // Chunk Z
for (BlockChangeRecord record : wrapper.passthrough(Types.BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
public void registerSectionBlocksUpdate(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.LONG); // Chunk position
map(Types.BOOLEAN); // Suppress light updates
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.passthrough(Types.VAR_LONG_BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.LONG); // Chunk position
wrapper.passthrough(Types.BOOLEAN); // Suppress light updates
for (BlockChangeRecord record : wrapper.passthrough(Types.VAR_LONG_BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
public void registerSectionBlocksUpdate1_20(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.LONG); // Chunk position
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.passthrough(Types.VAR_LONG_BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.LONG); // Chunk position
for (BlockChangeRecord record : wrapper.passthrough(Types.VAR_LONG_BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
@@ -33,7 +33,6 @@ import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.util.ComponentUtil;
@@ -66,17 +65,11 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
}
public void registerBossEvent(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UUID);
map(Types.VAR_INT);
handler(wrapper -> {
final int action = wrapper.get(Types.VAR_INT, 0);
if (action == 0 || action == 3) {
passthroughAndProcess(wrapper);
}
});
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.UUID);
final int action = wrapper.passthrough(Types.VAR_INT);
if (action == 0 || action == 3) {
passthroughAndProcess(wrapper);
}
});
}
@@ -112,24 +105,18 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
}
public void registerLegacyOpenWindow(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Id
map(Types.STRING); // Window Type
handler(wrapper -> processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT)));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.UNSIGNED_BYTE); // Id
wrapper.passthrough(Types.STRING); // Window Type
processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
});
}
public void registerOpenScreen(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Id
map(Types.VAR_INT); // Window Type
handler(wrapper -> passthroughAndProcess(wrapper));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Id
wrapper.passthrough(Types.VAR_INT); // Window Type
passthroughAndProcess(wrapper);
});
}
@@ -222,23 +209,17 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
}
public void registerPlayerCombatKill(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Player ID
map(Types.INT); // Killer ID
handler(wrapper -> processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT)));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Player ID
wrapper.passthrough(Types.INT); // Killer ID
processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
});
}
public void registerPlayerCombatKill1_20(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Player ID
handler(wrapper -> passthroughAndProcess(wrapper));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Player ID
passthroughAndProcess(wrapper);
});
}
@@ -390,6 +371,11 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
final CompoundTag contents = hoverEventTag.getCompoundTag("contents");
if (contents != null) {
processTag(connection, contents.get("name"));
final StringTag typeTag = contents.getStringTag("type");
if (typeTag != null && protocol.getEntityRewriter() != null) {
typeTag.setValue(protocol.getEntityRewriter().mappedEntityIdentifier(typeTag.getValue()));
}
}
} else if (action.equals("show_item")) {
convertLegacyContents(hoverEventTag);
@@ -399,7 +385,6 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
return;
}
// Until they're properly parsed
final CompoundTag componentsTag = contentsTag.getCompoundTag("components");
handleShowItem(connection, contentsTag, componentsTag);
if (componentsTag != null) {
@@ -24,19 +24,19 @@ import com.viaversion.nbt.tag.NumberTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.data.Int2IntMapMappings;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.rewriter.RewriterBase;
@@ -49,7 +49,6 @@ import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEventImpl;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.TagUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -60,7 +59,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class EntityRewriter<C extends ClientboundPacketType, T extends Protocol<C, ?, ?, ?>>
extends RewriterBase<T> implements com.viaversion.viaversion.api.rewriter.EntityRewriter<T> {
private static final EntityData[] EMPTY_ARRAY = new EntityData[0];
protected final List<EntityDataFilter> entityDataFilters = new ArrayList<>();
protected final boolean trackMappedType;
protected Mappings typeMappings;
@@ -156,6 +154,17 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
return typeMappings != null ? typeMappings.getNewIdOrDefault(id, id) : id;
}
@Override
public String mappedEntityIdentifier(final String identifier) {
if (typeMappings instanceof final FullMappings fullMappings) {
final String mappedIdentifier = fullMappings.mappedIdentifier(identifier);
if (mappedIdentifier != null) {
return mappedIdentifier;
}
}
return identifier;
}
/**
* Maps an entity type.
*
@@ -226,11 +235,11 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
data.setValue(protocol.getMappingData().getNewBlockStateId(value));
}
} else if (type == particleType) {
rewriteParticle(event.user(), data.value());
protocol.getParticleRewriter().rewriteParticle(event.user(), data.value());
} else if (type == particlesType) {
final Particle[] particles = data.value();
for (final Particle particle : particles) {
rewriteParticle(event.user(), particle);
protocol.getParticleRewriter().rewriteParticle(event.user(), particle);
}
} else if (type == componentType || type == optionalComponentType) {
if (protocol.getComponentRewriter() != null) {
@@ -249,14 +258,11 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
}
public void registerTracker(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // 0 - Entity ID
map(Types.UUID); // 1 - Entity UUID
map(Types.VAR_INT); // 2 - Entity Type
handler(trackerHandler());
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
wrapper.passthrough(Types.UUID); // Entity UUID
wrapper.passthrough(Types.VAR_INT); // Entity Type
trackerHandler().handle(wrapper);
});
}
@@ -264,15 +270,15 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // 0 - Entity id
map(Types.UUID); // 1 - Entity UUID
map(Types.VAR_INT); // 2 - Entity Type
map(Types.DOUBLE); // 3 - X
map(Types.DOUBLE); // 4 - Y
map(Types.DOUBLE); // 5 - Z
map(Types.BYTE); // 6 - Pitch
map(Types.BYTE); // 7 - Yaw
map(Types.INT); // 8 - Data
map(Types.VAR_INT); // Entity id
map(Types.UUID); // Entity UUID
map(Types.VAR_INT); // Entity Type
map(Types.DOUBLE); // X
map(Types.DOUBLE); // Y
map(Types.DOUBLE); // Z
map(Types.BYTE); // Pitch
map(Types.BYTE); // Yaw
map(Types.INT); // Data
handler(trackerHandler());
handler(wrapper -> {
int entityId = wrapper.get(Types.VAR_INT, 0);
@@ -286,31 +292,22 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
}
public void registerTrackerWithData1_19(C packetType, EntityType fallingBlockType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Entity id
map(Types.UUID); // Entity UUID
map(Types.VAR_INT); // Entity type
map(Types.DOUBLE); // X
map(Types.DOUBLE); // Y
map(Types.DOUBLE); // Z
map(Types.BYTE); // Pitch
map(Types.BYTE); // Yaw
map(Types.BYTE); // Head yaw
map(Types.VAR_INT); // Data
handler(trackerHandler());
handler(wrapper -> {
if (protocol.getMappingData() == null) {
return;
}
protocol.registerClientbound(packetType, wrapper -> {
final int entityId = wrapper.passthrough(Types.VAR_INT);
wrapper.passthrough(Types.UUID); // Entity UUID
final int entityTypeId = wrapper.passthrough(Types.VAR_INT);
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.BYTE); // Pitch
wrapper.passthrough(Types.BYTE); // Yaw
wrapper.passthrough(Types.BYTE); // Head yaw
final int data = wrapper.passthrough(Types.VAR_INT);
int entityId = wrapper.get(Types.VAR_INT, 0);
EntityType entityType = tracker(wrapper.user()).entityType(entityId);
if (entityType == fallingBlockType) {
wrapper.set(Types.VAR_INT, 2, protocol.getMappingData().getNewBlockStateId(wrapper.get(Types.VAR_INT, 2)));
}
});
final EntityType entityType = trackAndRewrite(wrapper, entityTypeId, entityId);
if (protocol.getMappingData() != null && entityType == fallingBlockType) {
final int mappedBlockStateId = protocol.getMappingData().getNewBlockStateId(data);
wrapper.set(Types.VAR_INT, 2, mappedBlockStateId);
}
});
}
@@ -377,12 +374,13 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
}
public PacketHandler playerTrackerHandler() {
return wrapper -> {
final EntityTracker tracker = tracker(wrapper.user());
final int entityId = wrapper.get(Types.INT, 0);
tracker.setClientEntityId(entityId);
tracker.addEntity(entityId, tracker.playerType());
};
return wrapper -> trackPlayer(wrapper.user(), wrapper.get(Types.INT, 0));
}
public void trackPlayer(final UserConnection connection, final int entityId) {
final EntityTracker tracker = tracker(connection);
tracker.setClientEntityId(entityId);
tracker.addEntity(entityId, tracker.playerType());
}
/**
@@ -505,21 +503,15 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
tracker(connection).setDimensions(dimensionDataMap);
}
public void handleRegistryData1_20_5(final UserConnection connection, final String registryKey, final RegistryEntry[] entries) {
if (registryKey.equals("worldgen/biome")) {
tracker(connection).setBiomesSent(entries.length);
} else if (registryKey.equals("dimension_type")) {
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(entries.length);
for (int i = 0; i < entries.length; i++) {
final RegistryEntry entry = entries[i];
final String key = Key.stripMinecraftNamespace(entry.key());
final DimensionData dimensionData = entry.tag() != null
? new DimensionDataImpl(i, (CompoundTag) entry.tag())
: DimensionDataImpl.withDefaultsFor(key, i);
dimensionDataMap.put(key, dimensionData);
}
tracker(connection).setDimensions(dimensionDataMap);
public EntityType trackAndRewrite(final PacketWrapper wrapper, final int typeId, final int entityId) {
final int mappedTypeId = newEntityId(typeId);
if (mappedTypeId != typeId) {
wrapper.set(Types.VAR_INT, 1, mappedTypeId);
}
final EntityType entityType = typeFromId(trackMappedType ? mappedTypeId : typeId);
tracker(wrapper.user()).addEntity(entityId, entityType);
return entityType;
}
// ---------------------------------------------------------------------------
@@ -535,16 +527,7 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
return wrapper -> {
int entityId = wrapper.get(Types.VAR_INT, 0);
int type = wrapper.get(Types.VAR_INT, 1);
int newType = newEntityId(type);
if (newType != type) {
wrapper.set(Types.VAR_INT, 1, newType);
}
EntityType entType = typeFromId(trackMappedType ? newType : type);
// Register Type ID
tracker(wrapper.user()).addEntity(entityId, entType);
trackAndRewrite(wrapper, type, entityId);
if (dataType != null) {
handleEntityData(entityId, wrapper.get(dataType, 0), wrapper.user());
}
@@ -581,30 +564,6 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
// ---------------------------------------------------------------------------
public RegistryEntry[] addRegistryEntries(final RegistryEntry[] entries, final RegistryEntry... toAdd) {
final int length = entries.length;
final RegistryEntry[] newEntries = Arrays.copyOf(entries, length + toAdd.length);
System.arraycopy(toAdd, 0, newEntries, length, toAdd.length);
return newEntries;
}
public void rewriteParticle(UserConnection connection, Particle particle) {
if (protocol.getItemRewriter() != null) {
protocol.getItemRewriter().rewriteParticle(connection, particle);
return;
}
// Dupe parts of the logic if no item rewriter is available
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
int id = particle.id();
if (mappings.isBlockParticle(id)) {
Particle.ParticleData<Integer> data = particle.getArgument(0);
data.setValue(protocol.getMappingData().getNewBlockStateId(data.getValue()));
}
particle.setId(protocol.getMappingData().getNewParticleId(id));
}
private void logException(Exception e, @Nullable EntityType type, List<EntityData> entityDataList, EntityData entityData) {
if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) {
protocol.getLogger().severe("An error occurred in entity data handler " + this.getClass().getSimpleName()
@@ -22,14 +22,11 @@ import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.rewriter.RewriterBase;
@@ -47,14 +44,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
private final Type<Item> mappedItemCostType;
private final Type<Item> optionalItemCostType;
private final Type<Item> mappedOptionalItemCostType;
private final Type<Particle> particleType;
private final Type<Particle> mappedParticleType;
public ItemRewriter(
T protocol,
Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType,
Type<Item> itemCostType, Type<Item> optionalItemCostType, Type<Item> mappedItemCostType, Type<Item> mappedOptionalItemCostType,
Type<Particle> particleType, Type<Particle> mappedParticleType
Type<Item> itemCostType, Type<Item> optionalItemCostType, Type<Item> mappedItemCostType, Type<Item> mappedOptionalItemCostType
) {
super(protocol);
this.itemType = itemType;
@@ -65,12 +59,10 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
this.mappedItemCostType = mappedItemCostType;
this.optionalItemCostType = optionalItemCostType;
this.mappedOptionalItemCostType = mappedOptionalItemCostType;
this.particleType = particleType;
this.mappedParticleType = mappedParticleType;
}
public ItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType) {
this(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, null, null, null, null, null, null);
this(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, null, null, null, null);
}
public ItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType) {
@@ -145,13 +137,10 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
}
public void registerSetSlot(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Container id
map(Types.SHORT); // Slot id
handler(wrapper -> passthroughClientboundItem(wrapper));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.UNSIGNED_BYTE); // Container id
wrapper.passthrough(Types.SHORT); // Slot id
passthroughClientboundItem(wrapper);
});
}
@@ -174,56 +163,42 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
// Sub 1.16
public void registerSetEquippedItem(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Entity ID
map(Types.VAR_INT); // Slot ID
handler(wrapper -> passthroughClientboundItem(wrapper));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
wrapper.passthrough(Types.VAR_INT); // Slot ID
passthroughClientboundItem(wrapper);
});
}
// 1.16+
public void registerSetEquipment(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // 0 - Entity ID
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
handler(wrapper -> {
byte slot;
do {
slot = wrapper.passthrough(Types.BYTE);
// & 0x7F into an extra variable if slot is needed
passthroughClientboundItem(wrapper);
} while (slot < 0);
});
}
byte slot;
do {
slot = wrapper.passthrough(Types.BYTE);
// & 0x7F into an extra variable if slot is needed
passthroughClientboundItem(wrapper);
} while (slot < 0);
});
}
public void registerSetCreativeModeSlot(S packetType) {
protocol.registerServerbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.SHORT); // 0 - Slot
handler(wrapper -> passthroughServerboundItem(wrapper));
}
protocol.registerServerbound(packetType, wrapper -> {
wrapper.passthrough(Types.SHORT); // Slot
passthroughServerboundItem(wrapper);
});
}
public void registerContainerClick(S packetType) {
protocol.registerServerbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // 0 - Container ID
map(Types.SHORT); // 1 - Slot
map(Types.BYTE); // 2 - Button
map(Types.SHORT); // 3 - Action number
map(Types.VAR_INT); // 4 - Mode
handler(wrapper -> passthroughServerboundItem(wrapper));
}
protocol.registerServerbound(packetType, wrapper -> {
wrapper.passthrough(Types.UNSIGNED_BYTE); // Container ID
wrapper.passthrough(Types.SHORT); // Slot
wrapper.passthrough(Types.BYTE); // Button
wrapper.passthrough(Types.SHORT); // Action number
wrapper.passthrough(Types.VAR_INT); // Mode
passthroughServerboundItem(wrapper);
});
}
@@ -460,155 +435,20 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
// Pre 1.21 for enchantments
public void registerContainerSetData(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Container id
handler(wrapper -> {
Mappings mappings = protocol.getMappingData().getEnchantmentMappings();
if (mappings == null) {
return;
}
short property = wrapper.passthrough(Types.SHORT);
if (property >= 4 && property <= 6) { // Enchantment id
short enchantmentId = (short) mappings.getNewId(wrapper.read(Types.SHORT));
wrapper.write(Types.SHORT, enchantmentId);
}
});
}
});
}
// Not the very best place for this, but has to stay here until *everything* is abstracted
public void registerLevelParticles(C packetType, Type<?> coordType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // 0 - Particle ID
map(Types.BOOLEAN); // 1 - Long Distance
map(coordType); // 2 - X
map(coordType); // 3 - Y
map(coordType); // 4 - Z
map(Types.FLOAT); // 5 - Offset X
map(Types.FLOAT); // 6 - Offset Y
map(Types.FLOAT); // 7 - Offset Z
map(Types.FLOAT); // 8 - Particle Data
map(Types.INT); // 9 - Particle Count
handler(levelParticlesHandler());
}
});
}
public void registerLevelParticles1_19(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // 0 - Particle ID
map(Types.BOOLEAN); // 1 - Long Distance
map(Types.DOUBLE); // 2 - X
map(Types.DOUBLE); // 3 - Y
map(Types.DOUBLE); // 4 - Z
map(Types.FLOAT); // 5 - Offset X
map(Types.FLOAT); // 6 - Offset Y
map(Types.FLOAT); // 7 - Offset Z
map(Types.FLOAT); // 8 - Particle Data
map(Types.INT); // 9 - Particle Count
handler(levelParticlesHandler(Types.VAR_INT));
}
});
}
public void registerLevelParticles1_20_5(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.BOOLEAN); // Long Distance
map(Types.DOUBLE); // X
map(Types.DOUBLE); // Y
map(Types.DOUBLE); // Z
map(Types.FLOAT); // Offset X
map(Types.FLOAT); // Offset Y
map(Types.FLOAT); // Offset Z
map(Types.FLOAT); // Particle Data
map(Types.INT); // Particle Count
handler(wrapper -> {
final Particle particle = wrapper.passthroughAndMap(particleType, mappedParticleType);
rewriteParticle(wrapper.user(), particle);
});
}
});
}
public void registerExplosion(C packetType) {
final SoundRewriter<C> soundRewriter = new SoundRewriter<>(protocol);
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.FLOAT); // Power
final int blocks = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < blocks; i++) {
wrapper.passthrough(Types.BYTE); // Relative X
wrapper.passthrough(Types.BYTE); // Relative Y
wrapper.passthrough(Types.BYTE); // Relative Z
}
wrapper.passthrough(Types.FLOAT); // Knockback X
wrapper.passthrough(Types.FLOAT); // Knockback Y
wrapper.passthrough(Types.FLOAT); // Knockback Z
wrapper.passthrough(Types.VAR_INT); // Block interaction type
wrapper.passthrough(Types.UNSIGNED_BYTE); // Container id
final Particle smallExplosionParticle = wrapper.passthroughAndMap(particleType, mappedParticleType);
final Particle largeExplosionParticle = wrapper.passthroughAndMap(particleType, mappedParticleType);
rewriteParticle(wrapper.user(), smallExplosionParticle);
rewriteParticle(wrapper.user(), largeExplosionParticle);
soundRewriter.soundHolderHandler().handle(wrapper);
});
}
public void registerExplosion1_21_2(C packetType) {
final SoundRewriter<C> soundRewriter = new SoundRewriter<>(protocol);
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.DOUBLE); // Knockback X
wrapper.passthrough(Types.DOUBLE); // Knockback Y
wrapper.passthrough(Types.DOUBLE); // Knockback Z
final Particle explosionParticle = wrapper.read(particleType);
wrapper.write(mappedParticleType, explosionParticle);
rewriteParticle(wrapper.user(), explosionParticle);
soundRewriter.soundHolderHandler().handle(wrapper);
});
}
public PacketHandler levelParticlesHandler() {
return levelParticlesHandler(Types.INT);
}
public PacketHandler levelParticlesHandler(Type<Integer> idType) {
return wrapper -> {
int id = wrapper.get(idType, 0);
if (id == -1) {
Mappings mappings = protocol.getMappingData().getEnchantmentMappings();
if (mappings == null) {
return;
}
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
if (mappings.isBlockParticle(id)) {
int data = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(data));
} else if (mappings.isItemParticle(id)) {
passthroughClientboundItem(wrapper);
short property = wrapper.passthrough(Types.SHORT);
if (property >= 4 && property <= 6) { // Enchantment id
short enchantmentId = (short) mappings.getNewId(wrapper.read(Types.SHORT));
wrapper.write(Types.SHORT, enchantmentId);
}
int mappedId = protocol.getMappingData().getNewParticleId(id);
if (mappedId != id) {
wrapper.set(idType, 0, mappedId);
}
};
});
}
protected void passthroughClientboundItem(final PacketWrapper wrapper) {
@@ -621,27 +461,6 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
wrapper.write(itemType, item);
}
@Override
public void rewriteParticle(UserConnection connection, Particle particle) {
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
int id = particle.id();
if (mappings.isBlockParticle(id)) {
Particle.ParticleData<Integer> data = particle.getArgument(0);
data.setValue(protocol.getMappingData().getNewBlockStateId(data.getValue()));
} else if (mappings.isItemParticle(id)) {
Particle.ParticleData<Item> data = particle.getArgument(0);
Item item = handleItemToClient(connection, data.getValue());
if (mappedItemType() != null && itemType() != mappedItemType()) {
// Replace the type
particle.set(0, mappedItemType(), item);
} else {
data.setValue(item);
}
}
particle.setId(protocol.getMappingData().getNewParticleId(id));
}
protected @Nullable String mappedIdentifier(final FullMappings mappings, final String identifier) {
// Check if the original exists before mapping
if (mappings.id(identifier) == -1) {
@@ -0,0 +1,199 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
public class ParticleRewriter<C extends ClientboundPacketType> implements com.viaversion.viaversion.api.rewriter.ParticleRewriter {
protected final Protocol<C, ?, ?, ?> protocol;
private final Type<Particle> particleType;
private final Type<Particle> mappedParticleType;
public ParticleRewriter(final Protocol<C, ?, ?, ?> protocol) {
this(protocol, null);
}
public ParticleRewriter(final Protocol<C, ?, ?, ?> protocol, final Type<Particle> particleType) {
this.protocol = protocol;
this.particleType = particleType;
this.mappedParticleType = particleType;
}
public ParticleRewriter(final Protocol<C, ?, ?, ?> protocol, final Type<Particle> particleType, final Type<Particle> mappedParticleType) {
this.protocol = protocol;
this.particleType = particleType;
this.mappedParticleType = mappedParticleType;
}
public void registerLevelParticles1_13(C packetType, Type<?> coordType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // 0 - Particle ID
map(Types.BOOLEAN); // 1 - Long Distance
map(coordType); // 2 - X
map(coordType); // 3 - Y
map(coordType); // 4 - Z
map(Types.FLOAT); // 5 - Offset X
map(Types.FLOAT); // 6 - Offset Y
map(Types.FLOAT); // 7 - Offset Z
map(Types.FLOAT); // 8 - Particle Data
map(Types.INT); // 9 - Particle Count
handler(levelParticlesHandler1_13(Types.INT));
}
});
}
public void registerLevelParticles1_19(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // 0 - Particle ID
map(Types.BOOLEAN); // 1 - Long Distance
map(Types.DOUBLE); // 2 - X
map(Types.DOUBLE); // 3 - Y
map(Types.DOUBLE); // 4 - Z
map(Types.FLOAT); // 5 - Offset X
map(Types.FLOAT); // 6 - Offset Y
map(Types.FLOAT); // 7 - Offset Z
map(Types.FLOAT); // 8 - Particle Data
map(Types.INT); // 9 - Particle Count
handler(levelParticlesHandler1_13(Types.VAR_INT));
}
});
}
public PacketHandler levelParticlesHandler1_13(Type<Integer> idType) {
return wrapper -> {
int id = wrapper.get(idType, 0);
if (id == -1) {
return;
}
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
if (mappings.isBlockParticle(id)) {
int data = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(data));
} else if (mappings.isItemParticle(id)) {
ItemRewriter<?> itemRewriter = protocol.getItemRewriter();
final Item item = wrapper.read(itemRewriter.itemType());
wrapper.write(itemRewriter.mappedItemType(), itemRewriter.handleItemToClient(wrapper.user(), item));
}
int mappedId = protocol.getMappingData().getNewParticleId(id);
if (mappedId != id) {
wrapper.set(idType, 0, mappedId);
}
};
}
public void registerLevelParticles1_20_5(final C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.BOOLEAN); // Long Distance
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.FLOAT); // Offset X
wrapper.passthrough(Types.FLOAT); // Offset Y
wrapper.passthrough(Types.FLOAT); // Offset Z
wrapper.passthrough(Types.FLOAT); // Particle Data
wrapper.passthrough(Types.INT); // Particle Count
final Particle particle = wrapper.passthroughAndMap(particleType, mappedParticleType);
rewriteParticle(wrapper.user(), particle);
});
}
public void registerExplode1_20_5(final C packetType) {
final SoundRewriter<C> soundRewriter = new SoundRewriter<>(protocol);
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.FLOAT); // Power
final int blocks = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < blocks; i++) {
wrapper.passthrough(Types.BYTE); // Relative X
wrapper.passthrough(Types.BYTE); // Relative Y
wrapper.passthrough(Types.BYTE); // Relative Z
}
wrapper.passthrough(Types.FLOAT); // Knockback X
wrapper.passthrough(Types.FLOAT); // Knockback Y
wrapper.passthrough(Types.FLOAT); // Knockback Z
wrapper.passthrough(Types.VAR_INT); // Block interaction type
final Particle smallExplosionParticle = wrapper.passthroughAndMap(particleType, mappedParticleType);
final Particle largeExplosionParticle = wrapper.passthroughAndMap(particleType, mappedParticleType);
rewriteParticle(wrapper.user(), smallExplosionParticle);
rewriteParticle(wrapper.user(), largeExplosionParticle);
soundRewriter.soundHolderHandler().handle(wrapper);
});
}
public void registerExplode1_21_2(final C packetType) {
final SoundRewriter<C> soundRewriter = new SoundRewriter<>(protocol);
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.DOUBLE); // Knockback X
wrapper.passthrough(Types.DOUBLE); // Knockback Y
wrapper.passthrough(Types.DOUBLE); // Knockback Z
final Particle explosionParticle = wrapper.read(particleType);
wrapper.write(mappedParticleType, explosionParticle);
rewriteParticle(wrapper.user(), explosionParticle);
soundRewriter.soundHolderHandler().handle(wrapper);
});
}
@Override
public void rewriteParticle(final UserConnection connection, final Particle particle) {
final ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
final ItemRewriter<?> itemRewriter = protocol.getItemRewriter();
final int id = particle.id();
if (mappings.isBlockParticle(id)) {
final Particle.ParticleData<Integer> data = particle.getArgument(0);
data.setValue(protocol.getMappingData().getNewBlockStateId(data.getValue()));
} else if (mappings.isItemParticle(id) && itemRewriter != null) {
final Particle.ParticleData<Item> data = particle.getArgument(0);
final Item item = itemRewriter.handleItemToClient(connection, data.getValue());
if (itemRewriter.mappedItemType() != null && itemRewriter.itemType() != itemRewriter.mappedItemType()) {
// Replace the type
particle.set(0, itemRewriter.mappedItemType(), item);
} else {
data.setValue(item);
}
}
particle.setId(protocol.getMappingData().getNewParticleId(id));
}
}
@@ -22,7 +22,6 @@ import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
public class SoundRewriter<C extends ClientboundPacketType> {
@@ -40,12 +39,9 @@ public class SoundRewriter<C extends ClientboundPacketType> {
}
public void registerSound(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Sound id
handler(getSoundHandler());
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Sound id
getSoundHandler().handle(wrapper);
});
}
@@ -23,7 +23,6 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
@@ -42,13 +41,14 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class StructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends Protocol<C, ?, ?, S>> extends ItemRewriter<C, S, T> {
public static final String MARKER_KEY = "VV|custom_data";
public StructuredItemRewriter(
T protocol,
Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType,
Type<Item> itemCostType, Type<Item> optionalItemCostType, Type<Item> mappedItemCostType, Type<Item> mappedOptionalItemCostType,
Type<Particle> particleType, Type<Particle> mappedParticleType
Type<Item> itemCostType, Type<Item> optionalItemCostType, Type<Item> mappedItemCostType, Type<Item> mappedOptionalItemCostType
) {
super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, itemCostType, optionalItemCostType, mappedItemCostType, mappedOptionalItemCostType, particleType, mappedParticleType);
super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, itemCostType, optionalItemCostType, mappedItemCostType, mappedOptionalItemCostType);
}
public StructuredItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType) {
@@ -207,15 +207,18 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
// Remove custom name
if (customData.remove(nbtTagName("added_custom_name")) != null) {
data.remove(StructuredDataKey.CUSTOM_NAME);
removeCustomTag(data, customData);
} else {
final Tag customName = removeBackupTag(customData, "custom_name");
if (customName != null) {
data.set(StructuredDataKey.CUSTOM_NAME, customName);
removeCustomTag(data, customData);
}
final Tag itemName = removeBackupTag(customData, "item_name");
if (itemName != null) {
data.set(StructuredDataKey.ITEM_NAME, itemName);
removeCustomTag(data, customData);
}
}
}
@@ -225,6 +228,7 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
customData = new CompoundTag();
customData.putBoolean(MARKER_KEY, true);
data.set(StructuredDataKey.CUSTOM_DATA, customData);
}
return customData;
@@ -241,6 +245,13 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
return customData.remove(nbtTagName(tagName));
}
protected void removeCustomTag(final StructuredDataContainer data, final CompoundTag customData) {
// Only remove if we initially added it and only the marker is left
if (customData.contains(MARKER_KEY) && customData.size() == 1) {
data.remove(StructuredDataKey.CUSTOM_DATA);
}
}
@FunctionalInterface
private interface ItemHandler {
@@ -17,8 +17,10 @@
*/
package com.viaversion.viaversion.util;
import com.viaversion.nbt.tag.ByteTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.NumberTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import java.util.Map;
@@ -60,6 +62,10 @@ public final class TagUtil {
return tag.remove(Key.namespaced(key)) != null || tag.remove(Key.stripMinecraftNamespace(key)) != null;
}
public static boolean containsNamespaced(final CompoundTag tag, final String key) {
return tag.contains(Key.namespaced(key)) || tag.contains(Key.stripMinecraftNamespace(key));
}
public static @Nullable CompoundTag getNamespacedCompoundTag(final CompoundTag tag, final String key) {
final CompoundTag compoundTag = tag.getCompoundTag(Key.namespaced(key));
return compoundTag != null ? compoundTag : tag.getCompoundTag(Key.stripMinecraftNamespace(key));
@@ -75,6 +81,11 @@ public final class TagUtil {
return stringTag != null ? stringTag : tag.getStringTag(Key.stripMinecraftNamespace(key));
}
public static @Nullable NumberTag getNamespacedNumberTag(final CompoundTag tag, final String key) {
final NumberTag numberTag = tag.getNumberTag(Key.namespaced(key));
return numberTag != null ? numberTag : tag.getNumberTag(Key.stripMinecraftNamespace(key));
}
public static Tag handleDeep(final Tag tag, final TagUpdater consumer) {
return handleDeep(null, tag, consumer);
}
+2 -2
View File
@@ -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.1.0
projectVersion=5.1.1
# Smile emoji
mcVersions=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-1.21.3
velocityVersion=3.3
velocityVersion=3.4
# Gradle properties
org.gradle.daemon=true
+6 -5
View File
@@ -3,23 +3,23 @@ metadata.format.version = "1.1"
[versions]
gson = "2.11.0"
fastutil = "8.5.14"
fastutil = "8.5.15"
vianbt = "5.0.1"
mcstructs = "5-2.5.4-SNAPSHOT"
mcstructs = "5-2.5.4"
# Common provided
netty = "4.0.20.Final"
guava = "17.0"
snakeYaml = "2.2"
junit = "5.11.2"
checkerQual = "3.48.0"
junit = "5.11.3"
checkerQual = "3.48.1"
# Platforms
paper = "1.20.4-R0.1-SNAPSHOT"
legacyBukkit = "1.8.8-R0.1-SNAPSHOT"
velocity = "3.1.1"
viaProxy = "3.3.5-SNAPSHOT"
[libraries]
@@ -40,6 +40,7 @@ checkerQual = { group = "org.checkerframework", name = "checker-qual", version.r
paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" }
legacyBukkit = { group = "org.bukkit", name = "bukkit", version.ref = "legacyBukkit" }
velocity = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" }
viaProxy = { group = "net.raphimc", name = "ViaProxy", version.ref = "viaProxy" }
[bundles]