Compare commits

...
106 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
Nassim Jahnke f880adced2 5.1.0 Release 2024-10-25 09:24:29 +02:00
Nassim Jahnke fc07601f24 Fix glow squid index shift 2024-10-24 16:55:24 +02:00
Nassim Jahnke ecb241c187 Exclude error prone annotations
Recently added to gson, can be safely excluded
2024-10-24 12:50:36 +02:00
Nassim Jahnke 46040b1f5d Mark fallback return value in getProtocol as unknown 2024-10-23 17:04:54 +02:00
FlorianMichael 54daa11ce4 Fix ProtocolVersion#isKnown javadoc to make difference with isRegistered more clear 2024-10-23 17:02:45 +02:00
RaphiMC c556420870 Add option to construct ChunkSectionLightImpl without block light 2024-10-23 16:42:21 +02:00
FlorianMichael 84d928ebe7 Update version ranges in gradle.properties 2024-10-23 16:25:52 +02:00
FlorianMichael fa6eab5cc3 1.21.3 2024-10-23 15:42:16 +02:00
FlorianMichael 94b26a903c Check for suppress conversion warnings option in ComponentUtil functions 2024-10-22 22:31:17 +02:00
Nassim Jahnke c242456c30 Remove snapshot version 2024-10-22 17:02:14 +02:00
Nassim Jahnke 8391e9d924 Fix consumable writing 2024-10-22 13:23:06 +02:00
RK_01 f5aac9b1ab Convert all data from food component (#13) 2024-10-22 13:21:44 +02:00
RK_01 a6850392e1 Add failsafe handling to ACCEPT_TELEPORTATION packet order fix (#12) 2024-10-22 13:03:43 +02:00
RK_01 2b37178482 Fix ACCEPT_TELEPORTATION packet order (#11) 2024-10-22 11:13:45 +02:00
Nassim Jahnke 82199d9f39 1.21.2-rc2 2024-10-21 18:36:50 +02:00
FlorianMichael c2d2c6d067 Explain SerializerVersion terminology 2024-10-19 14:50:09 +02:00
FlorianMichael 4066a7b5b6 Mark serializer versions in ComponentRewriter as nullable 2024-10-19 14:43:43 +02:00
Nassim Jahnke 4a7624fef4 Update profile actions enum type 2024-10-19 13:18:14 +02:00
EnZaXD e38b3f3824 Add new PROFILE_ACTIONS_ENUM type in Types for 1.21.2+ 2024-10-19 11:45:51 +02:00
Nassim Jahnke 4573035aab 1.21.2-rc1 2024-10-17 15:28:15 +02:00
Nassim Jahnke 393a5ee973 1.21.2-pre5 2024-10-16 16:06:39 +02:00
Nassim Jahnke 080dc18165 1.21.2-pre4 2024-10-15 15:08:36 +02:00
Nassim Jahnke 6fd421d36e Fix finish configuration state change 2024-10-15 15:08:36 +02:00
Nassim Jahnke 84bd1d0782 Use recipe inputs from old recipe packet 2024-10-15 15:08:36 +02:00
Nassim Jahnke cff2303c62 1.21.2-pre3 2024-10-15 15:08:36 +02:00
Nassim Jahnke f5733c2cb8 They fixed the typo 2024-10-15 15:08:36 +02:00
Nassim Jahnke 21fec0e263 1.21.2-pre2 2024-10-15 15:08:36 +02:00
RK_01 093acc519e Fix CONTAINER_SET_SLOT translation (#9) 2024-10-15 15:08:35 +02:00
RK_01 886be3161e Fix EXPLODE knockback check and affected blocks (#8) 2024-10-15 15:08:35 +02:00
RK_01 dc7b708556 Fix PLAYER_POSITION delta movement (#7) 2024-10-15 15:08:35 +02:00
Nassim Jahnke e82f28c1ac Rewrite particles 2024-10-15 15:08:35 +02:00
Nassim Jahnke 7c7239a70d 1.21.2-pre1 2024-10-15 15:08:35 +02:00
Nassim Jahnke 3e3dad9e33 Show notification on recipe add 2024-10-15 15:08:35 +02:00
Nassim Jahnke 4871977681 Fix recipe removal array index 2024-10-15 15:08:34 +02:00
Nassim Jahnke 0a56e57aec Send stonecutter recipes 2024-10-15 15:08:34 +02:00
Nassim Jahnke a6ff477b8a Implement clientbound ghost recipe, fix null recipe groups 2024-10-15 15:08:34 +02:00
Nassim Jahnke ddad0384f3 Make recipes mostly work again 2024-10-15 15:08:34 +02:00
Nassim Jahnke aabe47f8bc Start working on recipe rewriting 2024-10-15 15:08:34 +02:00
Nassim Jahnke 354a5f1b75 Update packet id comments 2024-10-15 15:08:34 +02:00
Nassim Jahnke f58afd434d WIP 24w40a 2024-10-15 15:08:34 +02:00
Nassim Jahnke 57d5652cd5 Remove SetWrapper, moved to addon 2024-10-15 15:08:33 +02:00
Nassim Jahnke 25b521dfcf Rewrite lock nbt 2024-10-15 15:08:33 +02:00
Nassim Jahnke ce655d0679 Use absolute day time value 2024-10-15 15:08:33 +02:00
Nassim Jahnke e4e8297a82 24w39a 2024-10-15 15:08:33 +02:00
Nassim Jahnke 8357fd01aa Update attributes in item hover events 2024-10-15 15:08:33 +02:00
Nassim Jahnke 12b420d3e7 Send instrument registry, handle duration change from ticks to seconds 2024-10-15 15:08:33 +02:00
Nassim Jahnke db20bc0ae4 24w38a 2024-10-15 15:08:33 +02:00
Nassim Jahnke 2a2afa3821 Register component rewriter 2024-10-15 15:08:32 +02:00
Nassim Jahnke f0b2d9aafe 24w37a 2024-10-15 15:08:32 +02:00
Nassim Jahnke cd427a2a39 Don't use -1 to indicate no vehicle 2024-10-15 15:08:32 +02:00
Nassim Jahnke 75537d3f85 Cancel player input if not in a vehicle, fix shift/sprint input 2024-10-15 15:08:32 +02:00
Nassim Jahnke a88e2f3fb5 Set impulse to 0.98 instead of 1 as per vanilla value 2024-10-15 15:08:32 +02:00
Nassim Jahnke 8a41e7add6 Remove new item data from serverbound items 2024-10-15 15:08:32 +02:00
Nassim Jahnke 9c35228287 24w36a 2024-10-15 15:08:32 +02:00
Nassim Jahnke f9ec6b9d03 Split holder implementation 2024-10-15 15:08:31 +02:00
Nassim Jahnke 22d396d909 Add item hover event handling 2024-10-15 15:08:31 +02:00
Nassim Jahnke 39b28e21ca 24w35a, including missed change from 33a 2024-10-15 15:08:31 +02:00
Nassim Jahnke 0488cb7fbe Fix item type in 1.21.2 entity data 2024-10-15 15:08:31 +02:00
Nassim Jahnke ec4aa0637e 24w34a 2024-10-15 15:08:31 +02:00
Nassim Jahnke ffc5584b1c Null check component rewriter 2024-10-15 15:08:31 +02:00
Nassim Jahnke 45c6cfedb0 Update mappings 2024-10-15 15:08:30 +02:00
Nassim Jahnke c150e50636 Store attribute mappings in full 2024-10-15 15:08:30 +02:00
Nassim Jahnke 16e32a62e5 Bump version to 5.1.0-SNAPSHOT 2024-10-15 15:08:27 +02:00
Nassim Jahnke 1d18f2e45e Fix container id conversion and itemrewriter explosion method 2024-10-15 15:08:20 +02:00
Nassim Jahnke e46b38e58a Remove outdated todos 2024-10-15 15:08:20 +02:00
Nassim Jahnke 033741d292 WIP 24w33a 2024-10-15 15:08:20 +02:00
Nassim Jahnke 7a3ef1e0b7 5.0.5 Release 2024-10-15 10:44:03 +02:00
Nassim Jahnke 5be41ed3e9 Use stripped key in tag getting
Fixes #4182
2024-10-14 21:35:10 +02:00
143 changed files with 5497 additions and 954 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/
+3 -1
View File
@@ -19,7 +19,9 @@ dependencies {
api(libs.vianbt) {
exclude("it.unimi.dsi", "fastutil")
}
api(libs.gson)
api(libs.gson) {
exclude("com.google.errorprone", "error_prone_annotations")
}
implementation(rootProject.libs.text) {
exclude("com.google.code.gson", "gson")
exclude("com.viaversion", "nbt")
@@ -53,6 +53,14 @@ public interface FullMappings extends BiMappings {
*/
@Nullable String identifier(int id);
/**
* Returns the unmapped string identifier for the given mapped identifier.
*
* @param mappedIdentifier mapped identifier
* @return unmapped string identifier, or null if not found
*/
@Nullable String identifier(String mappedIdentifier);
/**
* Returns the mapped string identifier for the given mapped id.
*
@@ -83,6 +83,17 @@ public class FullMappingsBase implements FullMappings {
return Key.namespaced(identifier);
}
@Override
public @Nullable String identifier(final String mappedIdentifier) {
final int mappedId = mappedId(mappedIdentifier);
if (mappedId == -1) {
return null;
}
final int id = mappings.inverse().getNewId(mappedId);
return id != -1 ? identifier(id) : null;
}
@Override
public String mappedIdentifier(final int mappedId) {
if (mappedId < 0 || mappedId >= mappedIdToString.length) {
@@ -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);
/**
@@ -126,10 +152,10 @@ public interface MappingData {
@Nullable Mappings getEnchantmentMappings();
@Nullable Mappings getAttributeMappings();
@Nullable Mappings getPaintingMappings();
@Nullable FullMappings getAttributeMappings();
@Nullable FullMappings getEntityMappings();
@Nullable FullMappings getArgumentTypeMappings();
@@ -43,10 +43,10 @@ public class MappingDataBase implements MappingData {
protected FullMappings entityMappings;
protected FullMappings recipeSerializerMappings;
protected FullMappings itemDataSerializerMappings;
protected FullMappings attributeMappings;
protected ParticleMappings particleMappings;
protected BiMappings itemMappings;
protected BiMappings blockMappings;
protected BiMappings attributeMappings;
protected Mappings blockStateMappings;
protected Mappings blockEntityMappings;
protected Mappings soundMappings;
@@ -76,8 +76,6 @@ public class MappingDataBase implements MappingData {
menuMappings = loadMappings(data, "menus");
enchantmentMappings = loadMappings(data, "enchantments");
paintingMappings = loadMappings(data, "paintings");
attributeMappings = loadBiMappings(data, "attributes");
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
@@ -87,6 +85,7 @@ public class MappingDataBase implements MappingData {
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
@@ -180,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
@@ -272,7 +271,7 @@ public class MappingDataBase implements MappingData {
}
@Override
public @Nullable Mappings getAttributeMappings() {
public @Nullable FullMappings getAttributeMappings() {
return attributeMappings;
}
@@ -36,6 +36,7 @@ public class ParticleMappings extends FullMappingsBase {
addBlockParticle("falling_dust");
addBlockParticle("block_marker");
addBlockParticle("dust_pillar");
addBlockParticle("block_crumble");
addItemParticle("item");
}
@@ -78,7 +78,7 @@ public interface DebugHandler {
/**
* Returns whether packets should be logged after being transformed.
* Set to true by default.
* Set to false by default.
*
* @return whether packets should be logged after being transformed
*/
@@ -35,7 +35,7 @@ public interface Holder<T> {
* @throws IllegalArgumentException if the id is negative
*/
static <T> Holder<T> of(final int id) {
return new HolderImpl<>(id);
return new IdHolder<>(id);
}
/**
@@ -46,7 +46,7 @@ public interface Holder<T> {
* @return a new direct holder
*/
static <T> Holder<T> of(final T value) {
return new HolderImpl<>(value);
return new ValueHolder<>(value);
}
/**
@@ -36,7 +36,7 @@ public interface HolderSet {
* @return a new holder set
*/
static HolderSet of(final String tagKey) {
return new HolderSetImpl(tagKey);
return new HolderSetImpl.Tag(tagKey);
}
/**
@@ -46,7 +46,7 @@ public interface HolderSet {
* @return a new holder set
*/
static HolderSet of(final int[] ids) {
return new HolderSetImpl(ids);
return new HolderSetImpl.Ids(ids);
}
/**
@@ -22,50 +22,63 @@
*/
package com.viaversion.viaversion.api.minecraft;
import com.viaversion.viaversion.util.EitherImpl;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.Arrays;
final class HolderSetImpl extends EitherImpl<String, int[]> implements HolderSet {
final class HolderSetImpl {
HolderSetImpl(final String tagKey) {
super(tagKey, null);
}
record Tag(String tagKey) implements HolderSet {
@Override
public boolean hasTagKey() {
return true;
}
HolderSetImpl(final int[] ids) {
super(null, ids);
}
@Override
public int[] ids() {
throw new IllegalArgumentException("This holder set has a tag key");
}
@Override
public String tagKey() {
return left();
}
@Override
public boolean hasIds() {
return false;
}
@Override
public boolean hasTagKey() {
return isLeft();
}
@Override
public int[] ids() {
return right();
}
@Override
public boolean hasIds() {
return isRight();
}
@Override
public HolderSet rewrite(final Int2IntFunction idRewriter) {
if (hasTagKey()) {
@Override
public HolderSet rewrite(final Int2IntFunction idRewriter) {
return this;
}
}
final int[] ids = ids();
final int[] mappedIds = new int[ids.length];
for (int i = 0; i < mappedIds.length; i++) {
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
record Ids(int[] ids) implements HolderSet {
@Override
public boolean hasTagKey() {
return false;
}
@Override
public String tagKey() {
throw new IllegalArgumentException("This holder set has direct ids");
}
@Override
public boolean hasIds() {
return true;
}
@Override
public HolderSet rewrite(final Int2IntFunction idRewriter) {
final int[] mappedIds = new int[ids.length];
for (int i = 0; i < mappedIds.length; i++) {
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
}
return new Ids(mappedIds);
}
@Override
public String toString() {
return "Ids{" +
"ids=" + Arrays.toString(ids) +
'}';
}
return new HolderSetImpl(mappedIds);
}
}
@@ -25,49 +25,29 @@ package com.viaversion.viaversion.api.minecraft;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
final class HolderImpl<T> implements Holder<T> {
record IdHolder<T>(int id) implements Holder<T> {
private final T value;
private final int id;
HolderImpl(final int id) {
IdHolder {
Preconditions.checkArgument(id >= 0, "id cannot be negative");
this.value = null;
this.id = id;
}
HolderImpl(final T value) {
this.value = value;
this.id = -1;
}
@Override
public boolean isDirect() {
return id == -1;
return false;
}
@Override
public boolean hasId() {
return id != -1;
return true;
}
@Override
public T value() {
Preconditions.checkArgument(isDirect(), "Holder is not direct");
return value;
}
@Override
public int id() {
return id;
throw new IllegalArgumentException("Holder is not direct");
}
@Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
if (isDirect()) {
return this;
}
final int rewrittenId = rewriteFunction.applyAsInt(id);
if (rewrittenId == id) {
return this;
@@ -77,12 +57,4 @@ final class HolderImpl<T> implements Holder<T> {
}
return Holder.of(rewrittenId);
}
@Override
public String toString() {
return "HolderImpl{" +
"value=" + value +
", id=" + id +
'}';
}
}
@@ -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());
}
};
}
@@ -36,4 +36,8 @@ public record RegistryEntry(String key, @Nullable Tag tag) {
public RegistryEntry withKey(final String key) {
return new RegistryEntry(key, tag != null ? tag.copy() : null);
}
public RegistryEntry copy() {
return new RegistryEntry(key, tag != null ? tag.copy() : null);
}
}
@@ -0,0 +1,48 @@
/*
* 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;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
record ValueHolder<T>(T value) implements Holder<T> {
@Override
public boolean isDirect() {
return true;
}
@Override
public boolean hasId() {
return false;
}
@Override
public int id() {
return -1;
}
@Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
return this;
}
}
@@ -37,14 +37,14 @@ public class ChunkSectionImpl implements ChunkSection {
public ChunkSectionImpl(final boolean holdsLight) {
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
if (holdsLight) {
this.light = new ChunkSectionLightImpl();
this.light = ChunkSectionLightImpl.createWithBlockLight();
}
}
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
if (holdsLight) {
this.light = new ChunkSectionLightImpl();
this.light = ChunkSectionLightImpl.createWithBlockLight();
}
}
@@ -35,7 +35,7 @@ public interface ChunkSectionLight {
/**
* Returns whether the section has sky light.
*
* @return true if skylight is present
* @return true if sky light is present
*/
boolean hasSkyLight();
@@ -43,7 +43,7 @@ public interface ChunkSectionLight {
* Returns whether the section has block light.
* This returns true unless specifically set to null.
*
* @return true if skylight is present
* @return true if block light is present
*/
boolean hasBlockLight();
@@ -30,9 +30,17 @@ public class ChunkSectionLightImpl implements ChunkSectionLight {
private NibbleArray blockLight;
private NibbleArray skyLight;
public ChunkSectionLightImpl() {
// Block light is always written
this.blockLight = new NibbleArray(ChunkSection.SIZE);
protected ChunkSectionLightImpl() {
}
public static ChunkSectionLight createWithBlockLight() {
final ChunkSectionLightImpl light = new ChunkSectionLightImpl();
light.blockLight = new NibbleArray(ChunkSection.SIZE);
return light;
}
public static ChunkSectionLight createEmpty() {
return new ChunkSectionLightImpl();
}
@Override
@@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.GameProfile;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
@@ -34,13 +35,19 @@ import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21;
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
import com.viaversion.viaversion.api.minecraft.item.data.Bee;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
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.DeathProtection;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.Equippable;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
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.JukeboxPlayable;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
@@ -48,11 +55,13 @@ import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
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.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.util.Unit;
public record StructuredDataKey<T>(String identifier, Type<T> type) {
@@ -64,6 +73,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Unbreakable> UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE);
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
public static final StructuredDataKey<String> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.STRING);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", Types.TAG_ARRAY);
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE);
@@ -78,10 +88,21 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Unit> CREATIVE_SLOT_LOCK = new StructuredDataKey<>("creative_slot_lock", Types.EMPTY);
public static final StructuredDataKey<Boolean> ENCHANTMENT_GLINT_OVERRIDE = new StructuredDataKey<>("enchantment_glint_override", Types.BOOLEAN);
public static final StructuredDataKey<Tag> INTANGIBLE_PROJECTILE = new StructuredDataKey<>("intangible_projectile", Types.TAG); // Doesn't actually hold data
public static final StructuredDataKey<FoodProperties> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties.TYPE1_20_5);
public static final StructuredDataKey<FoodProperties> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties.TYPE1_21);
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_20_5);
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_21);
public static final StructuredDataKey<FoodProperties1_21_2> FOOD1_21_2 = new StructuredDataKey<>("food", FoodProperties1_21_2.TYPE);
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_2 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE);
public static final StructuredDataKey<Item> USE_REMAINDER = new StructuredDataKey<>("use_remainder", Types1_21_2.ITEM);
public static final StructuredDataKey<UseCooldown> USE_COOLDOWN = new StructuredDataKey<>("use_cooldown", UseCooldown.TYPE);
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY);
public static final StructuredDataKey<DamageResistant> DAMAGE_RESISTANT = new StructuredDataKey<>("damage_resistant", DamageResistant.TYPE);
public static final StructuredDataKey<ToolProperties> TOOL = new StructuredDataKey<>("tool", ToolProperties.TYPE);
public static final StructuredDataKey<Integer> ENCHANTABLE = new StructuredDataKey<>("enchantable", Types.VAR_INT);
public static final StructuredDataKey<Equippable> EQUIPPABLE = new StructuredDataKey<>("equippable", Equippable.TYPE);
public static final StructuredDataKey<HolderSet> REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET);
public static final StructuredDataKey<Unit> GLIDER = new StructuredDataKey<>("glider", Types.EMPTY);
public static final StructuredDataKey<String> TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.STRING);
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE);
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE);
public static final StructuredDataKey<DyedColor> DYED_COLOR = new StructuredDataKey<>("dyed_color", DyedColor.TYPE);
public static final StructuredDataKey<Integer> MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT);
@@ -90,9 +111,12 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Integer> MAP_POST_PROCESSING = new StructuredDataKey<>("map_post_processing", Types.VAR_INT);
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_20_5 = new StructuredDataKey<>("charged_projectiles", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21 = new StructuredDataKey<>("charged_projectiles", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21_2 = new StructuredDataKey<>("charged_projectiles", Types1_21_2.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_20_5 = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21 = new StructuredDataKey<>("bundle_contents", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<PotionContents> POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE);
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21_2 = new StructuredDataKey<>("bundle_contents", Types1_21_2.ITEM_ARRAY);
public static final StructuredDataKey<PotionContents> POTION_CONTENTS1_20_5 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_20_5);
public static final StructuredDataKey<PotionContents> POTION_CONTENTS1_21_2 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_21_2);
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
public static final StructuredDataKey<FilterableString[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", FilterableString.ARRAY_TYPE);
public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE);
@@ -101,7 +125,8 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<CompoundTag> ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
public static final StructuredDataKey<Holder<Instrument1_20_5>> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT);
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE);
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG);
@@ -115,6 +140,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
public static final StructuredDataKey<Item[]> CONTAINER1_20_5 = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CONTAINER1_21 = new StructuredDataKey<>("container", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CONTAINER1_21_2 = new StructuredDataKey<>("container", Types1_21_2.ITEM_ARRAY);
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE);
public static final StructuredDataKey<Bee[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);
@@ -0,0 +1,314 @@
/*
* 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.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_21_2 implements EntityType {
ENTITY(null, null),
AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(ENTITY),
EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(ENTITY),
ITEM(ENTITY),
TNT(ENTITY),
OMINOUS_ITEM_SPAWNER(ENTITY),
MARKER(ENTITY),
LIGHTNING_BOLT(ENTITY),
INTERACTION(ENTITY),
DISPLAY(ENTITY, null),
BLOCK_DISPLAY(DISPLAY),
ITEM_DISPLAY(DISPLAY),
TEXT_DISPLAY(DISPLAY),
// Hanging entities
HANGING_ENTITY(ENTITY, null),
LEASH_KNOT(HANGING_ENTITY),
PAINTING(HANGING_ENTITY),
ITEM_FRAME(HANGING_ENTITY),
GLOW_ITEM_FRAME(ITEM_FRAME),
// Projectiles
PROJECTILE(ENTITY, null),
ITEM_PROJECTILE(PROJECTILE, null),
SNOWBALL(ITEM_PROJECTILE),
ENDER_PEARL(ITEM_PROJECTILE),
EGG(ITEM_PROJECTILE),
POTION(ITEM_PROJECTILE),
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
FIREWORK_ROCKET(PROJECTILE),
LLAMA_SPIT(PROJECTILE),
SHULKER_BULLET(PROJECTILE),
FISHING_BOBBER(PROJECTILE),
WITHER_SKULL(PROJECTILE),
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
ABSTRACT_ARROW(PROJECTILE, null),
ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(ABSTRACT_ARROW),
ABSTRACT_FIREBALL(ENTITY, null),
FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(ABSTRACT_FIREBALL),
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
// Vehicles
VEHICLE(ENTITY, null),
ABSTRACT_MINECART(VEHICLE, null),
MINECART(ABSTRACT_MINECART),
FURNACE_MINECART(ABSTRACT_MINECART),
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
TNT_MINECART(ABSTRACT_MINECART),
SPAWNER_MINECART(ABSTRACT_MINECART),
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
ABSTRACT_BOAT(VEHICLE, null),
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
ACACIA_BOAT(ABSTRACT_BOAT),
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
BAMBOO_RAFT(ABSTRACT_BOAT),
BIRCH_BOAT(ABSTRACT_BOAT),
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
CHERRY_BOAT(ABSTRACT_BOAT),
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
DARK_OAK_BOAT(ABSTRACT_BOAT),
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
JUNGLE_BOAT(ABSTRACT_BOAT),
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
MANGROVE_BOAT(ABSTRACT_BOAT),
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
OAK_BOAT(ABSTRACT_BOAT),
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
PALE_OAK_BOAT(ABSTRACT_BOAT),
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
SPRUCE_BOAT(ABSTRACT_BOAT),
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
// Living entities as a larger subclass
LIVING_ENTITY(ENTITY, null),
ARMOR_STAND(LIVING_ENTITY),
PLAYER(LIVING_ENTITY),
// Mobs as a larger subclass
MOB(LIVING_ENTITY, null),
ENDER_DRAGON(MOB),
SLIME(MOB),
MAGMA_CUBE(SLIME),
// Ambient mobs
AMBIENT_CREATURE(MOB, null),
BAT(AMBIENT_CREATURE),
// Flying mobs
FLYING_MOB(MOB, null),
GHAST(FLYING_MOB),
PHANTOM(FLYING_MOB),
// Pathfinder mobs and its subclasses
PATHFINDER_MOB(MOB, null),
ALLAY(PATHFINDER_MOB),
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
SNOW_GOLEM(ABSTRACT_GOLEM),
IRON_GOLEM(ABSTRACT_GOLEM),
SHULKER(ABSTRACT_GOLEM),
// Ageable mobs and (tamable) animals
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
VILLAGER(ABSTRACT_VILLAGER),
WANDERING_TRADER(ABSTRACT_VILLAGER),
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
AXOLOTL(ABSTRACT_ANIMAL),
CHICKEN(ABSTRACT_ANIMAL),
PANDA(ABSTRACT_ANIMAL),
PIG(ABSTRACT_ANIMAL),
POLAR_BEAR(ABSTRACT_ANIMAL),
RABBIT(ABSTRACT_ANIMAL),
SHEEP(ABSTRACT_ANIMAL),
BEE(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
FROG(ABSTRACT_ANIMAL),
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(ABSTRACT_HORSE),
CAMEL(ABSTRACT_HORSE),
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(ABSTRACT_CHESTED_HORSE),
MULE(ABSTRACT_CHESTED_HORSE),
LLAMA(ABSTRACT_CHESTED_HORSE),
TRADER_LLAMA(LLAMA),
// Monsters
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
BLAZE(ABSTRACT_MONSTER),
CREEPER(ABSTRACT_MONSTER),
ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(ABSTRACT_MONSTER),
GIANT(ABSTRACT_MONSTER),
SILVERFISH(ABSTRACT_MONSTER),
VEX(ABSTRACT_MONSTER),
WITHER(ABSTRACT_MONSTER),
BREEZE(ABSTRACT_MONSTER),
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
CREAKING(ABSTRACT_MONSTER),
CREAKING_TRANSIENT(CREAKING),
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(ABSTRACT_SKELETON),
BOGGED(ABSTRACT_SKELETON),
ZOMBIE(ABSTRACT_MONSTER),
DROWNED(ZOMBIE),
HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(ZOMBIE),
GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(GUARDIAN),
SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(SPIDER),
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
// Water mobs
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
DOLPHIN(AGEABLE_WATER_CREATURE),
SQUID(AGEABLE_WATER_CREATURE),
GLOW_SQUID(SQUID),
WATER_ANIMAL(PATHFINDER_MOB, null),
ABSTRACT_FISH(WATER_ANIMAL, null),
PUFFERFISH(ABSTRACT_FISH),
TADPOLE(ABSTRACT_FISH),
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
COD(ABSTRACT_SCHOOLING_FISH),
SALMON(ABSTRACT_SCHOOLING_FISH),
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
// Raiders
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
WITCH(ABSTRACT_RAIDER),
RAVAGER(ABSTRACT_RAIDER),
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
VINDICATOR(ABSTRACT_ILLAGER),
PILLAGER(ABSTRACT_ILLAGER),
EVOKER(SPELLCASTER_ILLAGER),
ILLUSIONER(SPELLCASTER_ILLAGER);
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final EntityType parent;
private final String identifier;
private int id = -1;
EntityTypes1_21_2(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_2(final EntityType parent, @Nullable final String identifier) {
this.parent = parent;
this.identifier = identifier;
}
@Override
public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
}
return id;
}
@Override
public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent;
}
@Override
public boolean isAbstractType() {
return identifier == null;
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
}
}
@@ -26,10 +26,11 @@ 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.ArrayType;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
@@ -40,7 +41,7 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
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 = add(7, Types1_21.ITEM);
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);
@@ -59,14 +60,15 @@ 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);
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
public EntityDataTypes1_21(final ParticleType particleType, final ArrayType<Particle> particlesType) {
public EntityDataTypes1_21(final Type<Item> itemType, final ParticleType particleType, final ArrayType<Particle> particlesType) {
super(31);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
}
@@ -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);
}
}
@@ -0,0 +1,111 @@
/*
* 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.item.data;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import io.netty.buffer.ByteBuf;
public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<SoundEvent> sound,
boolean hasConsumeParticles, ConsumeEffect<?>[] consumeEffects) {
public static final Type<?>[] EFFECT_TYPES = {
ApplyStatusEffects.TYPE,
Types.HOLDER_SET, // remove effects
Types.EMPTY, // clear all effects
Types.FLOAT, // teleport randomly
Types.SOUND_EVENT // play sound
};
public static final Type<Consumable1_21_2> TYPE = new Type<>(Consumable1_21_2.class) {
@Override
public Consumable1_21_2 read(final ByteBuf buffer) {
final float consumeSeconds = buffer.readFloat();
final int animationType = Types.VAR_INT.readPrimitive(buffer);
final Holder<SoundEvent> sound = Types.SOUND_EVENT.read(buffer);
final boolean hasConsumeParticles = buffer.readBoolean();
final ConsumeEffect<?>[] consumeEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, consumeEffects);
}
@Override
public void write(final ByteBuf buffer, final Consumable1_21_2 value) {
buffer.writeFloat(value.consumeSeconds);
Types.VAR_INT.writePrimitive(buffer, value.animationType);
Types.SOUND_EVENT.write(buffer, value.sound);
buffer.writeBoolean(value.hasConsumeParticles);
ConsumeEffect.ARRAY_TYPE.write(buffer, value.consumeEffects);
}
};
public record ConsumeEffect<T>(int id, Type<T> type, T value) {
public static final Type<ConsumeEffect<?>> TYPE = new Type<>(ConsumeEffect.class) {
@Override
public ConsumeEffect<?> read(final ByteBuf buffer) {
// Oh no...
final int effectType = Types.VAR_INT.readPrimitive(buffer);
final Type<?> type = EFFECT_TYPES[effectType];
final Object value = type.read(buffer);
return ConsumeEffect.of(effectType, type, value);
}
@Override
public void write(final ByteBuf buffer, final ConsumeEffect<?> value) {
Types.VAR_INT.writePrimitive(buffer, value.id);
value.writeValue(buffer);
}
};
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE = new ArrayType<>(TYPE);
static <T> ConsumeEffect<T> of(final int id, final Type<T> type, final Object value) {
//noinspection unchecked
return new ConsumeEffect<>(id, type, (T) value);
}
void writeValue(final ByteBuf buf) {
this.type.write(buf, this.value);
}
}
public record ApplyStatusEffects(PotionEffect[] effects, float probability) {
public static final Type<ApplyStatusEffects> TYPE = new Type<>(ApplyStatusEffects.class) {
@Override
public ApplyStatusEffects read(final ByteBuf buffer) {
final PotionEffect[] effects = PotionEffect.ARRAY_TYPE.read(buffer);
final float probability = buffer.readFloat();
return new ApplyStatusEffects(effects, probability);
}
@Override
public void write(final ByteBuf buffer, final ApplyStatusEffects value) {
PotionEffect.ARRAY_TYPE.write(buffer, value.effects);
buffer.writeFloat(value.probability);
}
};
}
}
@@ -0,0 +1,43 @@
/*
* 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.item.data;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record DamageResistant(String typesTagKey) {
public static final Type<DamageResistant> TYPE = new Type<>(DamageResistant.class) {
@Override
public DamageResistant read(final ByteBuf buffer) {
final String typesTagKey = Types.STRING.read(buffer);
return new DamageResistant(typesTagKey);
}
@Override
public void write(final ByteBuf buffer, final DamageResistant value) {
Types.STRING.write(buffer, value.typesTagKey());
}
};
}
@@ -22,26 +22,23 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2.ConsumeEffect;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record FoodEffect(PotionEffect effect, float probability) {
public record DeathProtection(ConsumeEffect<?>[] deathEffects) {
public static final Type<FoodEffect> TYPE = new Type<>(FoodEffect.class) {
public static final Type<DeathProtection> TYPE = new Type<>(DeathProtection.class) {
@Override
public FoodEffect read(final ByteBuf buffer) {
final PotionEffect effect = PotionEffect.TYPE.read(buffer);
final float probability = buffer.readFloat();
return new FoodEffect(effect, probability);
public DeathProtection read(final ByteBuf buffer) {
final ConsumeEffect<?>[] deathEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
return new DeathProtection(deathEffects);
}
@Override
public void write(final ByteBuf buffer, final FoodEffect value) {
PotionEffect.TYPE.write(buffer, value.effect);
buffer.writeFloat(value.probability);
public void write(final ByteBuf buffer, final DeathProtection value) {
ConsumeEffect.ARRAY_TYPE.write(buffer, value.deathEffects);
}
};
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
}
@@ -0,0 +1,69 @@
/*
* 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.item.data;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import org.checkerframework.checker.nullness.qual.Nullable;
public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Nullable String model,
@Nullable String cameraOverlay, @Nullable HolderSet allowedEntities, boolean dispensable,
boolean swappable, boolean damageOnHurt) {
public static final Type<Equippable> TYPE = new Type<>(Equippable.class) {
@Override
public Equippable read(final ByteBuf buffer) {
final int equipmentSlot = Types.VAR_INT.readPrimitive(buffer);
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final String model = Types.OPTIONAL_STRING.read(buffer);
final String cameraOverlay = Types.OPTIONAL_STRING.read(buffer);
final HolderSet allowedEntities = Types.HOLDER_SET.read(buffer);
final boolean dispensable = buffer.readBoolean();
final boolean swappable = buffer.readBoolean();
final boolean damageOnHurt = buffer.readBoolean();
return new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
}
@Override
public void write(final ByteBuf buffer, final Equippable value) {
Types.VAR_INT.writePrimitive(buffer, value.equipmentSlot());
Types.SOUND_EVENT.write(buffer, value.soundEvent());
Types.OPTIONAL_STRING.write(buffer, value.model());
Types.OPTIONAL_STRING.write(buffer, value.cameraOverlay());
Types.HOLDER_SET.write(buffer, value.allowedEntities());
buffer.writeBoolean(value.dispensable());
buffer.writeBoolean(value.swappable());
buffer.writeBoolean(value.damageOnHurt());
}
};
public Equippable rewrite(final Int2IntFunction soundIdRewriter) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriter);
return soundEvent == this.soundEvent ? this : new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
}
}
@@ -25,25 +25,26 @@ package com.viaversion.viaversion.api.minecraft.item.data;
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.ArrayType;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import io.netty.buffer.ByteBuf;
public record FoodProperties(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
Item usingConvertsTo, FoodEffect[] possibleEffects) {
public record FoodProperties1_20_5(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
Item usingConvertsTo, FoodEffect[] possibleEffects) {
public static final Type<FoodProperties> TYPE1_20_5 = new Type<>(FoodProperties.class) {
public static final Type<FoodProperties1_20_5> TYPE1_20_5 = new Type<>(FoodProperties1_20_5.class) {
@Override
public FoodProperties read(final ByteBuf buffer) {
public FoodProperties1_20_5 read(final ByteBuf buffer) {
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
final float saturationModifier = buffer.readFloat();
final boolean canAlwaysEat = buffer.readBoolean();
final float eatSeconds = buffer.readFloat();
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer);
return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, null, possibleEffects);
return new FoodProperties1_20_5(nutrition, saturationModifier, canAlwaysEat, eatSeconds, null, possibleEffects);
}
@Override
public void write(final ByteBuf buffer, final FoodProperties value) {
public void write(final ByteBuf buffer, final FoodProperties1_20_5 value) {
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
buffer.writeFloat(value.saturationModifier);
buffer.writeBoolean(value.canAlwaysEat);
@@ -51,20 +52,20 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
}
};
public static final Type<FoodProperties> TYPE1_21 = new Type<FoodProperties>(FoodProperties.class) {
public static final Type<FoodProperties1_20_5> TYPE1_21 = new Type<>(FoodProperties1_20_5.class) {
@Override
public FoodProperties read(final ByteBuf buffer) {
public FoodProperties1_20_5 read(final ByteBuf buffer) {
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
final float saturationModifier = buffer.readFloat();
final boolean canAlwaysEat = buffer.readBoolean();
final float eatSeconds = buffer.readFloat();
final Item usingConvertsTo = Types1_21.OPTIONAL_ITEM.read(buffer);
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer);
return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, usingConvertsTo, possibleEffects);
return new FoodProperties1_20_5(nutrition, saturationModifier, canAlwaysEat, eatSeconds, usingConvertsTo, possibleEffects);
}
@Override
public void write(final ByteBuf buffer, final FoodProperties value) {
public void write(final ByteBuf buffer, final FoodProperties1_20_5 value) {
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
buffer.writeFloat(value.saturationModifier);
buffer.writeBoolean(value.canAlwaysEat);
@@ -73,4 +74,23 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
}
};
public record FoodEffect(PotionEffect effect, float probability) {
public static final Type<FoodEffect> TYPE = new Type<>(FoodEffect.class) {
@Override
public FoodEffect read(final ByteBuf buffer) {
final PotionEffect effect = PotionEffect.TYPE.read(buffer);
final float probability = buffer.readFloat();
return new FoodEffect(effect, probability);
}
@Override
public void write(final ByteBuf buffer, final FoodEffect value) {
PotionEffect.TYPE.write(buffer, value.effect);
buffer.writeFloat(value.probability);
}
};
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
}
}
@@ -0,0 +1,47 @@
/*
* 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.item.data;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record FoodProperties1_21_2(int nutrition, float saturationModifier, boolean canAlwaysEat) {
public static final Type<FoodProperties1_21_2> TYPE = new Type<>(FoodProperties1_21_2.class) {
@Override
public FoodProperties1_21_2 read(final ByteBuf buffer) {
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
final float saturationModifier = buffer.readFloat();
final boolean canAlwaysEat = buffer.readBoolean();
return new FoodProperties1_21_2(nutrition, saturationModifier, canAlwaysEat);
}
@Override
public void write(final ByteBuf buffer, final FoodProperties1_21_2 value) {
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
buffer.writeFloat(value.saturationModifier);
buffer.writeBoolean(value.canAlwaysEat);
}
};
}
@@ -29,27 +29,27 @@ import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record Instrument(Holder<SoundEvent> soundEvent, int useDuration, float range) {
public record Instrument1_20_5(Holder<SoundEvent> soundEvent, int useDuration, float range) {
public static final HolderType<Instrument> TYPE = new HolderType<>() {
public static final HolderType<Instrument1_20_5> TYPE = new HolderType<>() {
@Override
public Instrument readDirect(final ByteBuf buffer) {
public Instrument1_20_5 readDirect(final ByteBuf buffer) {
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final int useDuration = Types.VAR_INT.readPrimitive(buffer);
final float range = buffer.readFloat();
return new Instrument(soundEvent, useDuration, range);
final float range = Types.FLOAT.readPrimitive(buffer);
return new Instrument1_20_5(soundEvent, useDuration, range);
}
@Override
public void writeDirect(final ByteBuf buffer, final Instrument value) {
public void writeDirect(final ByteBuf buffer, final Instrument1_20_5 value) {
Types.SOUND_EVENT.write(buffer, value.soundEvent());
Types.VAR_INT.writePrimitive(buffer, value.useDuration());
buffer.writeFloat(value.range());
Types.FLOAT.writePrimitive(buffer, value.range());
}
};
public Instrument rewrite(final Int2IntFunction soundIdRewriteFunction) {
public Instrument1_20_5 rewrite(final Int2IntFunction soundIdRewriteFunction) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
return soundEvent == this.soundEvent ? this : new Instrument(soundEvent, useDuration, range);
return soundEvent == this.soundEvent ? this : new Instrument1_20_5(soundEvent, useDuration, range);
}
}
@@ -0,0 +1,58 @@
/*
* 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.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration, float range, Tag description) {
public static final HolderType<Instrument1_21_2> TYPE = new HolderType<>() {
@Override
public Instrument1_21_2 readDirect(final ByteBuf buffer) {
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final float useDuration = Types.FLOAT.readPrimitive(buffer);
final float range = Types.FLOAT.readPrimitive(buffer);
final Tag description = Types.TAG.read(buffer);
return new Instrument1_21_2(soundEvent, useDuration, range, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final Instrument1_21_2 value) {
Types.SOUND_EVENT.write(buffer, value.soundEvent());
Types.FLOAT.writePrimitive(buffer, value.useDuration());
Types.FLOAT.writePrimitive(buffer, value.range());
Types.TAG.write(buffer, value.description());
}
};
public Instrument1_21_2 rewrite(final Int2IntFunction soundIdRewriteFunction) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
return soundEvent == this.soundEvent ? this : new Instrument1_21_2(soundEvent, useDuration, range, description);
}
}
@@ -27,15 +27,20 @@ import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects) {
public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects,
@Nullable String customName) {
public static final Type<PotionContents> TYPE = new Type<>(PotionContents.class) {
public PotionContents(final @Nullable Integer potion, final @Nullable Integer customColor, final PotionEffect[] customEffects) {
this(potion, customColor, customEffects, null);
}
public static final Type<PotionContents> TYPE1_20_5 = new Type<>(PotionContents.class) {
@Override
public PotionContents read(final ByteBuf buffer) {
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
return new PotionContents(potion, customColor, customEffects);
return new PotionContents(potion, customColor, customEffects, null);
}
@Override
@@ -53,4 +58,31 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
}
};
public static final Type<PotionContents> TYPE1_21_2 = new Type<>(PotionContents.class) {
@Override
public PotionContents read(final ByteBuf buffer) {
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
final String customName = Types.OPTIONAL_STRING.read(buffer);
return new PotionContents(potion, customColor, customEffects, customName);
}
@Override
public void write(final ByteBuf buffer, final PotionContents value) {
buffer.writeBoolean(value.potion != null);
if (value.potion != null) {
Types.VAR_INT.writePrimitive(buffer, value.potion);
}
buffer.writeBoolean(value.customColor != null);
if (value.customColor != null) {
buffer.writeInt(value.customColor);
}
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
Types.OPTIONAL_STRING.write(buffer, value.customName);
}
};
}
@@ -0,0 +1,56 @@
/*
* 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.item.data;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import java.util.function.Function;
import org.checkerframework.checker.nullness.qual.Nullable;
public record UseCooldown(float seconds, @Nullable String cooldownGroup) {
public static final Type<UseCooldown> TYPE = new Type<>(UseCooldown.class) {
@Override
public UseCooldown read(final ByteBuf buffer) {
final float seconds = buffer.readFloat();
final String cooldownGroup = Types.OPTIONAL_STRING.read(buffer);
return new UseCooldown(seconds, cooldownGroup);
}
@Override
public void write(final ByteBuf buffer, final UseCooldown value) {
buffer.writeFloat(value.seconds());
Types.OPTIONAL_STRING.write(buffer, value.cooldownGroup());
}
};
public UseCooldown rewrite(final Function<String, String> idRewriter) {
if (cooldownGroup == null) {
return this;
}
final String mappedCooldownGroup = idRewriter.apply(cooldownGroup);
return new UseCooldown(seconds, mappedCooldownGroup);
}
}
@@ -198,6 +198,14 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
public void registerFinishConfiguration(final CU packetType, final PacketHandler handler) {
registerClientbound(packetType, wrapper -> {
// TODO Temporary solution to handle the finish configuration packet already having changed our tracked protocol state in a previous handler
wrapper.user().getProtocolInfo().setServerState(State.CONFIGURATION);
handler.handle(wrapper);
});
}
@Override
public final void loadMappingData() {
getMappingData().load();
@@ -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.
*
@@ -43,7 +43,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>();
public static final ProtocolVersion v1_7_2 = register(4, "1.7.2-1.7.5", new SubVersionRange("1.7", 2, 5));
@Deprecated(forRemoval=true) public static final ProtocolVersion v1_7_1 = v1_7_2;
@Deprecated(forRemoval = true)
public static final ProtocolVersion v1_7_1 = v1_7_2;
public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new SubVersionRange("1.7", 6, 10));
public static final ProtocolVersion v1_8 = register(47, "1.8.x", new SubVersionRange("1.8", 0, 9));
public static final ProtocolVersion v1_9 = register(107, "1.9");
@@ -85,8 +86,13 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4));
public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6));
public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1));
public static final ProtocolVersion v1_21_2 = register(768, "1.21.2-1.21.3", new SubVersionRange("1.21", 2, 3));
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
static {
unknown.known = false;
}
public static ProtocolVersion register(int version, String name) {
return register(version, -1, name);
}
@@ -150,7 +156,11 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
return protocolVersion;
}
}
return new ProtocolVersion(VersionType.SPECIAL, version, -1, "Unknown (" + version + ")", null);
// Will be made nullable instead in the future...
final ProtocolVersion unknown = new ProtocolVersion(versionType, version, -1, "Unknown (" + version + ")", null);
unknown.known = false;
return unknown;
}
public static @NonNull ProtocolVersion getProtocol(final int version) {
@@ -201,6 +211,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
private final int snapshotVersion;
private final String name;
private final Set<String> includedVersions;
@Deprecated // Remove when getProtocol is made nullable
private boolean known = true;
/**
* Constructs a new ProtocolVersion instance.
@@ -285,12 +297,12 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
}
/**
* Returns whether the protocol is set. Should only be unknown for unregistered protocols returned by {@link #getProtocol(int)}.
* Returns whether the protocol version is {@link #unknown}. For checking if the protocol version is registered, use {@link #isRegistered(VersionType, int)}
*
* @return true if the protocol is set
* @return true if the protocol version is unknown
*/
public boolean isKnown() {
return version != -1;
return known;
}
/**
@@ -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.
*
@@ -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);
}
@@ -189,7 +189,9 @@ public final class Types {
public static final Type<PlayerMessageSignature> OPTIONAL_PLAYER_MESSAGE_SIGNATURE = new PlayerMessageSignatureType.OptionalPlayerMessageSignatureType();
public static final Type<PlayerMessageSignature[]> PLAYER_MESSAGE_SIGNATURE_ARRAY = new ArrayType<>(PLAYER_MESSAGE_SIGNATURE);
public static final BitSetType PROFILE_ACTIONS_ENUM = new BitSetType(6);
public static final BitSetType PROFILE_ACTIONS_ENUM1_19_3 = new BitSetType(6);
public static final BitSetType PROFILE_ACTIONS_ENUM1_21_2 = new BitSetType(7);
public static final ByteArrayType SIGNATURE_BYTES = new ByteArrayType(256);
public static final BitSetType ACKNOWLEDGED_BIT_SET = new BitSetType(20);
public static final ByteArrayType.OptionalByteArrayType OPTIONAL_SIGNATURE_BYTES = new ByteArrayType.OptionalByteArrayType(256);
@@ -36,11 +36,19 @@ public class IntType extends Type<Integer> implements TypeConverter<Integer> {
return buffer.readInt();
}
public int readPrimitive(ByteBuf buffer) {
return buffer.readInt();
}
@Override
public void write(ByteBuf buffer, Integer object) {
buffer.writeInt(object);
}
public void writePrimitive(ByteBuf buffer, int object) {
buffer.writeInt(object);
}
@Override
public Integer from(Object o) {
if (o instanceof Number number) {
@@ -87,5 +87,12 @@ public class StructuredDataType extends Type<StructuredData<?>> {
types[id] = key;
return this;
}
public DataFiller add(final StructuredDataKey<?>... keys) {
for (final StructuredDataKey<?> key : keys) {
add(key);
}
return this;
}
}
}
@@ -77,6 +77,10 @@ public class ParticleType extends DynamicType<Particle> {
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Blue 0-1
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4
};
public static final DataReader<Particle> DUST1_21_2 = (buf, particle) -> {
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // RGB
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4
};
public static final DataReader<Particle> DUST_TRANSITION = (buf, particle) -> {
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Red 0-1
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green 0-1
@@ -86,6 +90,11 @@ public class ParticleType extends DynamicType<Particle> {
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Blue
};
public static final DataReader<Particle> DUST_TRANSITION1_21_2 = (buf, particle) -> {
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // From RGB
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // To RGB
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4
};
public static final DataReader<Particle> VIBRATION = (buf, particle) -> {
particle.add(Types.BLOCK_POSITION1_14, Types.BLOCK_POSITION1_14.read(buf)); // From block pos
@@ -136,7 +145,15 @@ public class ParticleType extends DynamicType<Particle> {
public static final DataReader<Particle> SHRIEK = (buf, particle) -> {
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Delay
};
public static final DataReader<Particle> COLOR = (buf, particle) -> particle.add(Types.INT, buf.readInt());
public static final DataReader<Particle> COLOR = (buf, particle) -> {
particle.add(Types.INT, Types.INT.readPrimitive(buf));
};
public static final DataReader<Particle> TRAIL = (buf, particle) -> {
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
};
public static DataReader<Particle> item(Type<Item> item) {
return (buf, particle) -> particle.add(item, item.read(buf));
@@ -50,7 +50,7 @@ public final class Types1_21 {
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(PARTICLE, PARTICLES);
public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(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);
}
@@ -0,0 +1,55 @@
/*
* 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.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_2;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType;
import com.viaversion.viaversion.api.type.types.item.ItemCostType1_20_5;
import com.viaversion.viaversion.api.type.types.item.ItemType1_20_5;
import com.viaversion.viaversion.api.type.types.item.StructuredDataType;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import java.util.List;
// Most of these are only safe to use after protocol loading
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[]> 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 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()
}
}
@@ -76,6 +76,7 @@ import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.Protocol1_20_3To1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.Protocol1_9_1To1_9_3;
import com.viaversion.viaversion.protocols.v1_9_3to1_10.Protocol1_9_3To1_10;
@@ -192,6 +193,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_20_3);
registerProtocol(new Protocol1_20_5To1_21(), ProtocolVersion.v1_21, ProtocolVersion.v1_20_5);
registerProtocol(new Protocol1_21To1_21_2(), ProtocolVersion.v1_21_2, ProtocolVersion.v1_21);
}
@Override
@@ -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,11 +23,14 @@ import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
public enum ClientboundLoginPackets implements BaseClientboundPacket {
LOGIN_DISCONNECT, // 0x00
HELLO, // 0x01
GAME_PROFILE, // 0x02
LOGIN_FINISHED, // 0x02
LOGIN_COMPRESSION, // 0x03
CUSTOM_QUERY, // 0x04
COOKIE_REQUEST; // 0x05
@Deprecated(forRemoval = true)
public static final ClientboundLoginPackets GAME_PROFILE = LOGIN_FINISHED;
@Override
public final int getId() {
return ordinal();
@@ -128,7 +128,7 @@ public class ClientboundBaseProtocol1_7 extends AbstractProtocol<BaseClientbound
});
// Track player name/uuid and setup connection + track state
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
registerClientbound(ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
final ProtocolInfo info = wrapper.user().getProtocolInfo();
if (info.serverProtocolVersion().olderThan(ProtocolVersion.v1_16)) {
@@ -19,12 +19,12 @@ package com.viaversion.viaversion.protocols.template;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
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.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
);*/
}
@@ -57,21 +56,22 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
// Registers item id changes
// Other places using item ids are: Entity data, tags, statistics, effect
// registerOpenWindow(ClientboundPackets1_21.OPEN_WINDOW); - If a new container type was added
registerCooldown(ClientboundPackets1_21.COOLDOWN);
registerSetContent1_17_1(ClientboundPackets1_21.CONTAINER_SET_CONTENT);
registerSetSlot1_17_1(ClientboundPackets1_21.CONTAINER_SET_SLOT);
// registerOpenScreen(ClientboundPackets1_21.OPEN_SCREEN); If a new container type was added; also remove from the component rewriter registration
//protocol.registerClientbound(ClientboundPackets1_21_2.SET_CURSOR_ITEM, this::passthroughClientboundItem);
registerCooldown1_21_2(ClientboundPackets1_21.COOLDOWN);
registerSetContent1_21_2(ClientboundPackets1_21.CONTAINER_SET_CONTENT);
registerSetSlot1_21_2(ClientboundPackets1_21.CONTAINER_SET_SLOT);
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT);
registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK);
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);
registerExplosion(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES);
final RecipeDisplayRewriter<ClientboundPacket1_21> recipeRewriter = new RecipeDisplayRewriter<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21.UPDATE_RECIPES);
//recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21.PLACE_GHOST_RECIPE);
// OR do this if serialization of recipes changed and override the relevant method
// Add new serializers to RecipeRewriter, or extend the last one for changes
// new RecipeRewriter1_20_3<ClientboundPacket1_21>(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES);
// Add new serializers to RecipeDisplayRewriter, or extend the last one for changes
}
}
@@ -0,0 +1,46 @@
/*
* 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.template;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.util.SerializerVersion;
public final class ComponentRewriter1_99 extends ComponentRewriter<ClientboundPacket1_21> {
public ComponentRewriter1_99(final Protocol1_99To_98 protocol) {
super(protocol, ReadType.NBT);
}
@Override
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
super.handleShowItem(connection, itemTag, componentsTag);
if (componentsTag == null) {
return;
}
// Remove or update data from componentsTag
}
@Override
protected SerializerVersion inputSerializerVersion() {
return SerializerVersion.V1_20_5;
}
}
@@ -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 -> {
@@ -24,6 +24,8 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
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;
@@ -32,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;
@@ -43,13 +46,16 @@ 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);
public Protocol1_99To_98() {
// Passing the class types into the super constructor is needed for automatic packet type id remapping, but can otherwise be omitted
@@ -63,6 +69,24 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
// If needed for item or component changes
componentRewriter.registerOpenScreen(ClientboundPackets1_21.OPEN_SCREEN);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_ACTION_BAR_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_TITLE_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_SUBTITLE_TEXT);
componentRewriter.registerBossEvent(ClientboundPackets1_21.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_21.TAB_LIST);
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21.PLAYER_COMBAT_KILL);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SYSTEM_CHAT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISGUISED_CHAT);
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);
@@ -90,16 +114,20 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
// EntityTypes1_20_5.initialize(this);
// Uncomment if a new particle was added = ids shifted; requires a new Types_ class copied from the last
/*Types1_21.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.ITEM1_20_2)
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);*/
/*Types1_21_2.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.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)
.reader("shriek", ParticleType.Readers.SHRIEK)
.reader("entity_effect", ParticleType.Readers.COLOR)
.reader("trail", ParticleType.Readers.TRAIL)
.reader("item", ParticleType.Readers.item(itemRewriter.mappedItemType()));*/
super.onMappingDataLoaded(); // Calls load methods on rewriters. Last in case the rewriters access the above filled data
}
@@ -127,11 +155,21 @@ 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;
}
@Override
public ComponentRewriter getComponentRewriter() {
return componentRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_21, ClientboundPacket1_21, ServerboundPacket1_20_5, ServerboundPacket1_20_5> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
@@ -353,7 +353,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
registerClientbound(ClientboundPackets1_12_1.PLACE_GHOST_RECIPE, new PacketHandlers() {
@Override
public void register() {
map(Types.BYTE);
map(Types.UNSIGNED_BYTE);
handler(wrapper -> wrapper.write(Types.STRING, "viaversion:legacy/" + wrapper.read(Types.VAR_INT)));
}
});
@@ -594,7 +594,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
registerServerbound(ServerboundPackets1_13.PLACE_RECIPE, new PacketHandlers() {
@Override
public void register() {
map(Types.BYTE); // Window id
map(Types.UNSIGNED_BYTE); // Window id
handler(wrapper -> {
String s = wrapper.read(Types.STRING);
@@ -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,11 +79,12 @@ 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);
// Login Success
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
// Transform string to a uuid
UUID uuid = UUID.fromString(wrapper.read(Types.STRING));
wrapper.write(Types.UUID, uuid);
@@ -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() {
@@ -232,7 +234,7 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
cancelServerbound(ServerboundPackets1_19.CHAT_PREVIEW);
// Login changes
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, new PacketHandlers() {
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, new PacketHandlers() {
@Override
public void register() {
map(Types.UUID); // UUID
@@ -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);
}
});
}
});
@@ -116,7 +122,7 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
set.set(action == 1 ? action + 1 : action + 2);
}
wrapper.write(Types.PROFILE_ACTIONS_ENUM, set);
wrapper.write(Types.PROFILE_ACTIONS_ENUM1_19_3, set);
final int entries = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < entries; i++) {
wrapper.passthrough(Types.UUID); // UUID
@@ -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 -> {
@@ -50,8 +50,7 @@ public class RecipeRewriter1_19_3<C extends ClientboundPacketType> extends Recip
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
handleIngredients(wrapper);
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
}
@Override
@@ -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);
@@ -268,7 +270,7 @@ public final class Protocol1_20_2To1_20_3 extends AbstractProtocol<ClientboundPa
}
});
registerClientbound(ClientboundPackets1_20_2.PLAYER_INFO_UPDATE, wrapper -> {
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM);
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM1_19_3);
final int entries = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < entries; i++) {
wrapper.passthrough(Types.UUID);
@@ -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));
}
});
@@ -64,4 +64,4 @@ public class RecipeRewriter1_20_3<C extends ClientboundPacketType> extends Recip
protected Type<Item[]> mappedItemArrayType() {
return protocol.getItemRewriter().mappedItemArrayType();
}
}
}
@@ -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);
@@ -211,7 +213,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
new CommandRewriter1_19_4<>(this).registerDeclareCommands1_19(ClientboundPackets1_20_3.COMMANDS);
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
wrapper.passthrough(Types.UUID); // UUID
wrapper.passthrough(Types.STRING); // Name
@@ -272,10 +274,10 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
.add(StructuredDataKey.CREATIVE_SLOT_LOCK).add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE).add(StructuredDataKey.INTANGIBLE_PROJECTILE)
.add(StructuredDataKey.STORED_ENCHANTMENTS).add(StructuredDataKey.DYED_COLOR).add(StructuredDataKey.MAP_COLOR)
.add(StructuredDataKey.MAP_ID).add(StructuredDataKey.MAP_DECORATIONS).add(StructuredDataKey.MAP_POST_PROCESSING)
.add(StructuredDataKey.CHARGED_PROJECTILES1_20_5).add(StructuredDataKey.BUNDLE_CONTENTS1_20_5).add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.CHARGED_PROJECTILES1_20_5).add(StructuredDataKey.BUNDLE_CONTENTS1_20_5).add(StructuredDataKey.POTION_CONTENTS1_20_5)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_20_5)
.add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS)
@@ -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;
@@ -18,8 +18,9 @@
package com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
public enum ServerboundConfigurationPackets1_20_5 implements ServerboundPacket1_20_5 {
public enum ServerboundConfigurationPackets1_20_5 implements ServerboundPacket1_20_5, ServerboundPacket1_21_2 {
CLIENT_INFORMATION, // 0x00
COOKIE_RESPONSE, // 0x01
@@ -60,9 +60,9 @@ import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5.FoodEffect;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
@@ -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);
@@ -536,7 +536,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
if (instrument != null) {
final int id = Instruments1_20_3.keyToId(instrument);
if (id != -1) {
data.set(StructuredDataKey.INSTRUMENT, Holder.of(id));
data.set(StructuredDataKey.INSTRUMENT1_20_5, Holder.of(id));
}
}
@@ -628,7 +628,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_8)) {
if (item.identifier() == 814 || item.identifier() == 819 || item.identifier() == 824 || item.identifier() == 829 || item.identifier() == 834) { // swords
// Make sword "eatable" to enable clientside instant blocking on 1.8. Consume time is set really high, so the eating animation doesn't play
item.dataContainer().set(StructuredDataKey.FOOD1_20_5, new FoodProperties(0, 0F, true, 3600, null, new FoodEffect[0]));
item.dataContainer().set(StructuredDataKey.FOOD1_20_5, new FoodProperties1_20_5(0, 0F, true, 3600, null, new FoodEffect[0]));
}
}
}
@@ -727,7 +727,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
soundEvent = Holder.of(instrument.getInt("sound_event"));
}
data.set(StructuredDataKey.INSTRUMENT, Holder.of(new Instrument(soundEvent, useDuration, range)));
data.set(StructuredDataKey.INSTRUMENT1_20_5, Holder.of(new Instrument1_20_5(soundEvent, useDuration, range)));
}
private void restoreFoodFromBackup(final CompoundTag food, final StructuredDataContainer data) {
@@ -756,7 +756,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
effect.getFloat("probability")
));
}
data.set(StructuredDataKey.FOOD1_20_5, new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, null, possibleEffects.toArray(new FoodEffect[0])));
data.set(StructuredDataKey.FOOD1_20_5, new FoodProperties1_20_5(nutrition, saturation, canAlwaysEat, eatSeconds, null, possibleEffects.toArray(new FoodEffect[0])));
}
private void restoreToolFromBackup(final CompoundTag tool, final StructuredDataContainer data) {
@@ -965,7 +965,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
}
if (potionId != null || customPotionColorTag != null || potionEffects != null) {
data.set(StructuredDataKey.POTION_CONTENTS, new PotionContents(
data.set(StructuredDataKey.POTION_CONTENTS1_20_5, new PotionContents(
potionId,
customPotionColorTag != null ? customPotionColorTag.asInt() : null,
potionEffects != null ? potionEffects : new PotionEffect[0]
@@ -55,9 +55,9 @@ import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5.FoodEffect;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
@@ -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
@@ -144,7 +144,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
registerEmpty(StructuredDataKey.MAP_POST_PROCESSING);
register(StructuredDataKey.CHARGED_PROJECTILES1_20_5, this::convertChargedProjectiles);
register(StructuredDataKey.BUNDLE_CONTENTS1_20_5, this::convertBundleContents);
register(StructuredDataKey.POTION_CONTENTS, this::convertPotionContents);
register(StructuredDataKey.POTION_CONTENTS1_20_5, this::convertPotionContents);
register(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, this::convertSuspiciousStewEffects);
register(StructuredDataKey.WRITABLE_BOOK_CONTENT, this::convertWritableBookContent);
register(StructuredDataKey.WRITTEN_BOOK_CONTENT, this::convertWrittenBookContent);
@@ -153,7 +153,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
register(StructuredDataKey.ENTITY_DATA, this::convertEntityData);
register(StructuredDataKey.BUCKET_ENTITY_DATA, this::convertBucketEntityData);
register(StructuredDataKey.BLOCK_ENTITY_DATA, this::convertBlockEntityData);
register(StructuredDataKey.INSTRUMENT, this::convertInstrument);
register(StructuredDataKey.INSTRUMENT1_20_5, this::convertInstrument);
register(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, this::convertOminousBottleAmplifier);
register(StructuredDataKey.RECIPES, this::convertRecipes);
register(StructuredDataKey.LODESTONE_TRACKER, this::convertLodestoneTracker);
@@ -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;
@@ -502,7 +501,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
return convertUnit();
}
protected CompoundTag convertFood(final FoodProperties value) {
protected CompoundTag convertFood(final FoodProperties1_20_5 value) {
final CompoundTag tag = new CompoundTag();
tag.put("nutrition", convertNonNegativeInt(value.nutrition()));
tag.putFloat("saturation", value.saturationModifier());
@@ -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()) {
@@ -745,12 +750,12 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
return convertNbtWithId(value);
}
protected Tag convertInstrument(final Holder<Instrument> value) {
protected Tag convertInstrument(final Holder<Instrument1_20_5> value) {
if (value.hasId()) {
return new StringTag(Instruments1_20_3.idToKey(value.id()));
}
final Instrument instrument = value.value();
final Instrument1_20_5 instrument = value.value();
final CompoundTag tag = new CompoundTag();
final Holder<SoundEvent> sound = instrument.soundEvent();
if (sound.hasId()) {
@@ -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));
}
}
}
}
@@ -44,8 +44,8 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5.FoodEffect;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData;
import com.viaversion.viaversion.api.minecraft.item.data.StatePropertyMatcher;
@@ -278,12 +278,12 @@ public final class StructuredDataConverter {
}
profileTag.put("Properties", propertiesTag);
});
register(StructuredDataKey.INSTRUMENT, (data, tag) -> {
register(StructuredDataKey.INSTRUMENT1_20_5, (data, tag) -> {
// Can't do anything with direct values
if (!data.hasId()) {
if (backupInconvertibleData) {
final CompoundTag backupTag = new CompoundTag();
final Instrument instrument = data.value();
final Instrument1_20_5 instrument = data.value();
if (instrument.soundEvent().hasId()) {
backupTag.putInt("sound_event", instrument.soundEvent().id());
} else {
@@ -398,7 +398,7 @@ public final class StructuredDataConverter {
enchantmentsTag.add(invalidEnchantment);
});
register(StructuredDataKey.POTION_CONTENTS, (data, tag) -> {
register(StructuredDataKey.POTION_CONTENTS1_20_5, (data, tag) -> {
if (data.potion() != null) {
final String potion = Potions1_20_5.idToKey(data.potion()); // Include 1.20.5 names
if (potion != null) {
@@ -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
@@ -201,10 +207,10 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
.add(StructuredDataKey.CREATIVE_SLOT_LOCK).add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE).add(StructuredDataKey.INTANGIBLE_PROJECTILE)
.add(StructuredDataKey.STORED_ENCHANTMENTS).add(StructuredDataKey.DYED_COLOR).add(StructuredDataKey.MAP_COLOR)
.add(StructuredDataKey.MAP_ID).add(StructuredDataKey.MAP_DECORATIONS).add(StructuredDataKey.MAP_POST_PROCESSING)
.add(StructuredDataKey.CHARGED_PROJECTILES1_21).add(StructuredDataKey.BUNDLE_CONTENTS1_21).add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.CHARGED_PROJECTILES1_21).add(StructuredDataKey.BUNDLE_CONTENTS1_21).add(StructuredDataKey.POTION_CONTENTS1_20_5)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_20_5)
.add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS)
@@ -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;
@@ -18,8 +18,9 @@
package com.viaversion.viaversion.protocols.v1_20_5to1_21.packet;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
public enum ClientboundConfigurationPackets1_21 implements ClientboundPacket1_21 {
public enum ClientboundConfigurationPackets1_21 implements ClientboundPacket1_21, ClientboundPacket1_21_2 {
COOKIE_REQUEST, // 0x00
CUSTOM_PAYLOAD, // 0x01
@@ -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,21 +66,8 @@ 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;
}
@Override
protected SerializerVersion outputSerializerVersion() {
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,22 +54,15 @@ 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.registerClientbound(ClientboundConfigurationPackets1_20_5.FINISH_CONFIGURATION, wrapper -> {
protocol.registerFinishConfiguration(ClientboundConfigurationPackets1_20_5.FINISH_CONFIGURATION, wrapper -> {
// Add new registries
final PacketWrapper paintingRegistryPacket = wrapper.create(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA);
paintingRegistryPacket.write(Types.STRING, "minecraft:painting_variant");
@@ -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() {
@@ -144,7 +148,7 @@ public final class Protocol1_20To1_20_2 extends AbstractProtocol<ClientboundPack
// We need to wait for it send the login ack before actually sending the play login,
// hence packets are added to a queue. With the data from the login packet, we sent what is needed
// during the configuration phase before finally transitioning to the play state with the client as well.
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
wrapper.user().get(ConfigurationState.class).setBridgePhase(BridgePhase.PROFILE_SENT);
wrapper.user().getProtocolInfo().setServerState(State.PLAY);
});
@@ -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
@@ -0,0 +1,280 @@
/*
* 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;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
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;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
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;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
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.protocols.v1_21to1_21_2.packet.ClientboundPacket1_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.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;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import java.util.BitSet;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPacket1_21, ClientboundPacket1_21_2, ServerboundPacket1_20_5, ServerboundPacket1_21_2> {
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);
public Protocol1_21To1_21_2() {
super(ClientboundPacket1_21.class, ClientboundPacket1_21_2.class, ServerboundPacket1_20_5.class, ServerboundPacket1_21_2.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
componentRewriter.registerOpenScreen(ClientboundPackets1_21.OPEN_SCREEN);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_ACTION_BAR_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_TITLE_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_SUBTITLE_TEXT);
componentRewriter.registerBossEvent(ClientboundPackets1_21.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_21.TAB_LIST);
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21.PLAYER_COMBAT_KILL);
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SYSTEM_CHAT);
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);
new StatisticsRewriter<>(this).register(ClientboundPackets1_21.AWARD_STATS);
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21.UPDATE_ATTRIBUTES);
registerServerbound(ServerboundPackets1_21_2.CLIENT_INFORMATION, this::clientInformation);
registerServerbound(ServerboundConfigurationPackets1_20_5.CLIENT_INFORMATION, this::clientInformation);
cancelServerbound(ServerboundPackets1_21_2.BUNDLE_ITEM_SELECTED);
cancelServerbound(ServerboundPackets1_21_2.CLIENT_TICK_END);
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
wrapper.passthrough(Types.UUID); // UUID
wrapper.passthrough(Types.STRING); // Name
final int properties = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < properties; i++) {
wrapper.passthrough(Types.STRING); // Name
wrapper.passthrough(Types.STRING); // Value
wrapper.passthrough(Types.OPTIONAL_STRING); // Signature
}
wrapper.read(Types.BOOLEAN); // Strict error handling
});
registerClientbound(ClientboundPackets1_21.SET_TIME, wrapper -> {
wrapper.passthrough(Types.LONG); // Game time
long dayTime = wrapper.read(Types.LONG);
boolean doDaylightCycle = true;
if (dayTime < 0) {
dayTime = -dayTime;
doDaylightCycle = false;
}
wrapper.write(Types.LONG, dayTime);
wrapper.write(Types.BOOLEAN, doDaylightCycle);
});
registerClientbound(ClientboundPackets1_21.PLAYER_INFO_UPDATE, wrapper -> {
final BitSet actions = wrapper.passthroughAndMap(Types.PROFILE_ACTIONS_ENUM1_19_3, Types.PROFILE_ACTIONS_ENUM1_21_2);
if (!actions.get(5)) { // Update display name
return;
}
final int entries = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < entries; i++) {
wrapper.passthrough(Types.UUID);
if (actions.get(0)) {
wrapper.passthrough(Types.STRING); // Player Name
final int properties = wrapper.passthrough(Types.VAR_INT);
for (int j = 0; j < properties; j++) {
wrapper.passthrough(Types.STRING); // Name
wrapper.passthrough(Types.STRING); // Value
wrapper.passthrough(Types.OPTIONAL_STRING); // Signature
}
}
if (actions.get(1) && wrapper.passthrough(Types.BOOLEAN)) {
wrapper.passthrough(Types.UUID); // Session UUID
wrapper.passthrough(Types.PROFILE_KEY);
}
if (actions.get(2)) {
wrapper.passthrough(Types.VAR_INT); // Gamemode
}
if (actions.get(3)) {
wrapper.passthrough(Types.BOOLEAN); // Listed
}
if (actions.get(4)) {
wrapper.passthrough(Types.VAR_INT); // Latency
}
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
}
});
registerClientbound(ClientboundPackets1_21.BUNDLE_DELIMITER, wrapper -> wrapper.user().get(BundleStateTracker.class).toggleBundling());
registerServerbound(ServerboundPackets1_21_2.PONG, wrapper -> {
final int id = wrapper.passthrough(Types.INT); // id
if (wrapper.user().get(PlayerPositionStorage.class).checkPong(id)) {
wrapper.cancel();
}
});
}
private void clientInformation(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Locale
wrapper.passthrough(Types.BYTE); // View distance
wrapper.passthrough(Types.VAR_INT); // Chat visibility
wrapper.passthrough(Types.BOOLEAN); // Chat colors
wrapper.passthrough(Types.UNSIGNED_BYTE); // Skin parts
wrapper.passthrough(Types.VAR_INT); // Main hand
wrapper.passthrough(Types.BOOLEAN); // Text filtering enabled
wrapper.passthrough(Types.BOOLEAN); // Allow listing
wrapper.read(Types.VAR_INT); // Particle status
}
@Override
protected void onMappingDataLoaded() {
EntityTypes1_21_2.initialize(this);
Types1_21_2.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.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)
.reader("shriek", ParticleType.Readers.SHRIEK)
.reader("entity_effect", ParticleType.Readers.COLOR)
.reader("trail", ParticleType.Readers.TRAIL)
.reader("item", ParticleType.Readers.item(Types1_21_2.ITEM));
Types1_21_2.STRUCTURED_DATA.filler(this).add(StructuredDataKey.CUSTOM_DATA, StructuredDataKey.MAX_STACK_SIZE, StructuredDataKey.MAX_DAMAGE,
StructuredDataKey.UNBREAKABLE, StructuredDataKey.RARITY, StructuredDataKey.HIDE_TOOLTIP, StructuredDataKey.DAMAGE_RESISTANT,
StructuredDataKey.CUSTOM_NAME, StructuredDataKey.LORE, StructuredDataKey.ENCHANTMENTS, StructuredDataKey.CAN_PLACE_ON,
StructuredDataKey.CAN_BREAK, StructuredDataKey.CUSTOM_MODEL_DATA, StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP,
StructuredDataKey.REPAIR_COST, StructuredDataKey.CREATIVE_SLOT_LOCK, StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE,
StructuredDataKey.INTANGIBLE_PROJECTILE, StructuredDataKey.STORED_ENCHANTMENTS, StructuredDataKey.DYED_COLOR,
StructuredDataKey.MAP_COLOR, StructuredDataKey.MAP_ID, StructuredDataKey.MAP_DECORATIONS, StructuredDataKey.MAP_POST_PROCESSING,
StructuredDataKey.POTION_CONTENTS1_21_2, StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, StructuredDataKey.WRITABLE_BOOK_CONTENT,
StructuredDataKey.WRITTEN_BOOK_CONTENT, StructuredDataKey.TRIM, StructuredDataKey.DEBUG_STICK_STATE, StructuredDataKey.ENTITY_DATA,
StructuredDataKey.BUCKET_ENTITY_DATA, StructuredDataKey.BLOCK_ENTITY_DATA, StructuredDataKey.INSTRUMENT1_21_2,
StructuredDataKey.RECIPES, StructuredDataKey.LODESTONE_TRACKER, StructuredDataKey.FIREWORK_EXPLOSION, StructuredDataKey.FIREWORKS,
StructuredDataKey.PROFILE, StructuredDataKey.NOTE_BLOCK_SOUND, StructuredDataKey.BANNER_PATTERNS, StructuredDataKey.BASE_COLOR,
StructuredDataKey.POT_DECORATIONS, StructuredDataKey.BLOCK_STATE, StructuredDataKey.BEES, StructuredDataKey.LOCK,
StructuredDataKey.CONTAINER_LOOT, StructuredDataKey.TOOL, StructuredDataKey.ITEM_NAME, StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER,
StructuredDataKey.FOOD1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE, StructuredDataKey.ATTRIBUTE_MODIFIERS1_21,
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_2,
StructuredDataKey.USE_COOLDOWN, StructuredDataKey.DAMAGE, StructuredDataKey.EQUIPPABLE, StructuredDataKey.ITEM_MODEL,
StructuredDataKey.GLIDER, StructuredDataKey.TOOLTIP_STYLE, StructuredDataKey.DEATH_PROTECTION,
// Volatile thanks to containing item
StructuredDataKey.CHARGED_PROJECTILES1_21_2, StructuredDataKey.BUNDLE_CONTENTS1_21_2, StructuredDataKey.CONTAINER1_21_2, StructuredDataKey.USE_REMAINDER);
super.onMappingDataLoaded();
}
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTracker1_21_2(connection));
connection.put(new BundleStateTracker());
connection.put(new PlayerPositionStorage());
connection.put(new ChunkLoadTracker());
connection.put(new GroundFlagTracker());
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
@Override
public EntityPacketRewriter1_21_2 getEntityRewriter() {
return entityRewriter;
}
@Override
public BlockItemPacketRewriter1_21_2 getItemRewriter() {
return itemRewriter;
}
@Override
public ParticleRewriter1_21_2 getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21> getTagRewriter() {
return tagRewriter;
}
@Override
public ComponentRewriter getComponentRewriter() {
return componentRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_21, ClientboundPacket1_21_2, ServerboundPacket1_20_5, ServerboundPacket1_21_2> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class),
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class),
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class)
);
}
}
Loaded 100 of 143 files, more files were not shown because too many files have changed in this diff. Show more