Compare commits

...

120 Commits

Author SHA1 Message Date
Nassim Jahnke d28e7cd652
4.10.0 Release 2024-04-26 15:03:17 +02:00
Nassim Jahnke f20d99fcef
Add 1.20.6 to .5 version
We technically don't know whether that will stay true, but might as well now to prevent confusion, as it wouldn't have any consequences if it did change
2024-04-26 15:02:57 +02:00
Nassim Jahnke a1c182f291
Ignore invalid names in the data component for hover events as well 2024-04-26 10:01:29 +02:00
Nassim Jahnke 8e63fd635b
Ignore invalid names in player heads 2024-04-26 09:29:19 +02:00
FlorianMichael 676e62c71f
Fix via dump throwing an error on sponge 2024-04-25 22:44:42 +02:00
FlorianMichael f422e03348
Rename ranged protocol version names 2024-04-25 20:31:22 +02:00
Nassim Jahnke fdf735420f
Add enforce-secure-chat setting to determine what is sent to the client by default 2024-04-25 20:21:36 +02:00
Nassim Jahnke b13fbbe175
Fix various issues in hover events serialization 2024-04-25 10:34:24 +02:00
Nassim Jahnke 9dd3348510
Move appendClientbound/Serverbound methods to Protocol interface 2024-04-24 20:11:05 +02:00
Nassim Jahnke 0e97af29b4
Add warning on Bungee startup
Without more specific injection points as with Velocity, Via has started failing more and more on Bungee and maintaining the required hackfixes coming from that has shown time intensive
2024-04-24 19:56:09 +02:00
Nassim Jahnke 3dfcd6b9b9
Fix written book hover serialization 2024-04-24 15:47:56 +02:00
Nassim Jahnke 8df0c0ae2e
Catch component parsing exceptions separately instead of failing the entire item 2024-04-24 15:47:47 +02:00
Nassim Jahnke d2ca6a82be
Assume enforce secure chat as false by default
Setting it to true will result in chat validation errors on the client for other players without chat sessions or valid signatures
2024-04-24 10:26:35 +02:00
Nassim Jahnke 9654a613cd
Put combat kill through component rewriter 2024-04-24 10:15:53 +02:00
Nassim Jahnke c5e6fa7d0c
Fix trim material ids at tail 2024-04-24 10:11:22 +02:00
Nassim Jahnke b78f9d350b
Check for lore length, not component length 2024-04-23 23:53:24 +02:00
Nassim Jahnke ebbe1b6da2
Make backwards enchantment code more readable 2024-04-23 23:44:12 +02:00
Nassim Jahnke 3aed7cb949
Fix mending translation from getting the id from the wrong class 2024-04-23 19:56:17 +02:00
Nassim Jahnke e2f3dc7572
Limit enchantments to 0-255 2024-04-23 19:32:32 +02:00
Nassim Jahnke f2b9c42590
Remove snapshot version support 2024-04-23 17:01:46 +02:00
Nassim Jahnke 9894671274
Add back default method 2024-04-23 13:47:05 +02:00
Nassim Jahnke 71ab15b331
Serialize to 1.20.3 components in conversion
Aside from hover events, only reading of components changed and we need the 1.20.3 hover input. Hover events are already handled by us.
2024-04-23 13:39:15 +02:00
Nassim Jahnke 34bc5b9d36
Put item name and lore through component rewriter
An absolute classic moment where servers are putting hover events into not hoverable item names and lore
2024-04-23 13:07:05 +02:00
Nassim Jahnke d80fd46c2f
Update version references 2024-04-23 11:26:17 +02:00
Nassim Jahnke b47446d9f7
Merge branch 'refs/heads/dev' into preview 2024-04-23 10:59:45 +02:00
Nassim Jahnke a4adef3cec
Fix attribute slot handling 2024-04-22 23:57:55 +02:00
Nassim Jahnke f525ad98e7
Fix handling of sweeping 2024-04-22 16:24:13 +02:00
Nassim Jahnke bc0b4470f6
1.20.5-rc3 2024-04-22 16:20:09 +02:00
Nassim Jahnke d3d6d4f1cd
Fixes to hover event handling, some cleanup 2024-04-22 16:05:44 +02:00
Nassim Jahnke 5069b26c2f
Reuse previously sent enforces-secure-chat value 2024-04-22 16:05:40 +02:00
FlorianMichael 079671060c
Remove items from extra-identifiers-1.20.3 file 2024-04-22 07:13:03 +02:00
Nassim Jahnke 89cd8aec1d
Merge branch 'refs/heads/dev' into preview 2024-04-21 23:47:01 +02:00
Nassim Jahnke 5e4f25efeb
Merge branch 'refs/heads/dev' into preview
# Conflicts:
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java
#	common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java
#	common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java
2024-04-21 22:51:45 +02:00
Nassim Jahnke 73daac471c
Split up version data in dump 2024-04-21 21:55:59 +02:00
Nassim Jahnke f4e9225f85
Store item identifiers, make identifier files more compact via global table 2024-04-21 20:47:38 +02:00
FlorianMichael d7e66260de
Add 1.20.5 nbt->component conversion base
Has to be implemented into ViaBackwards yet and handlers are still missing
2024-04-21 14:53:25 +02:00
FlorianMichael dc6d581123
Update mcstructs and use new component serializer 2024-04-21 12:13:59 +02:00
FlorianMichael bd3f1206e6
[ci skip] document 1.9 metadata in MetaIndex 2024-04-21 11:35:10 +02:00
FlorianMichael b9e92e5c1f
Fix zombie metadata in 1.10->1.11 2024-04-21 11:24:20 +02:00
Gero 0acaed7c7a Use correct item type for 1.20.5 particle reading 2024-04-20 23:50:24 +02:00
FlorianMichael 3055a4277d
Use toString() method in ComponentUtil 2024-04-20 22:52:40 +02:00
Gero bcbe69d24c Fix ITEM_NAME component to tag conversion 2024-04-20 22:44:22 +02:00
Nassim Jahnke 949b3d712e
Fix illager metadata in 1.13->1.14 2024-04-20 13:36:00 +02:00
Nassim Jahnke 216dcb2931
Remove invalid zombified piglin data 2024-04-20 12:43:08 +02:00
Nassim Jahnke bff1536529
Fall back to keys without namespace in registry data 2024-04-20 12:06:39 +02:00
Nassim Jahnke b221e47eb7
Add creative mode range attributes if needed
Add the range argument either with or without modifiers depending on the gamemode to otherwise reset them
2024-04-19 21:35:41 +02:00
Nassim Jahnke 1be0605f51
Eat remaining particle data in spawn particle 2024-04-19 17:02:08 +02:00
Nassim Jahnke c75b4d8ef5
1.20.5-rc2 2024-04-19 15:38:35 +02:00
Gero e08c263ced Add missing dust_color_transition data remapping (changed in 24w03a) 2024-04-19 11:02:11 +02:00
Nassim Jahnke 1bb85b11e9
Merge branch 'refs/heads/dev' into preview 2024-04-19 10:11:05 +02:00
Nassim Jahnke 3520f99d5a
Remove empty items from various block entities 2024-04-19 09:56:24 +02:00
RaphiMC 7825a1e460
Handle show_entity type field 2024-04-18 23:11:19 +02:00
Nassim Jahnke 57b37457d6
Add spit damage type
The client depends on it
2024-04-18 20:12:38 +02:00
Nassim Jahnke f7aa1a516e
Fill wolf_food item tag 2024-04-18 18:58:29 +02:00
Nassim Jahnke b1468ac6d0
Update particle codec format
Was changed in 1.20.5-pre1
2024-04-18 18:36:22 +02:00
Nassim Jahnke 27b5fdb4ff
Merge branch 'refs/heads/dev' into preview
# Conflicts:
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13_1to1_13/metadata/MetadataRewriter1_13_1To1_13.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/metadata/MetadataRewriter1_14To1_13_2.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_15to1_14_4/metadata/MetadataRewriter1_15To1_14_4.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_16_2to1_16_1/metadata/MetadataRewriter1_16_2To1_16_1.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_16to1_15_2/metadata/MetadataRewriter1_16To1_15_2.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_17to1_16_4/packets/EntityPackets.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/packets/EntityPackets.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_19_3to1_19_1/packets/EntityPackets.java
#	common/src/main/java/com/viaversion/viaversion/protocols/protocol1_19to1_18_2/packets/EntityPackets.java
2024-04-18 16:17:05 +02:00
Nassim Jahnke 64f911ed4a
1.20.5-rc1 2024-04-18 15:47:44 +02:00
FlorianMichael 033d5ae49a
Handle removed item conversion in component rewriter 2024-04-17 22:39:08 +02:00
Nassim Jahnke 8cf9114403
1.20.5-pre4 2024-04-17 15:01:16 +02:00
Nassim Jahnke 13eec3c2ea
1.20.5-pre3 2024-04-16 15:36:02 +02:00
Nassim Jahnke 31ccd2ab9b
1.20.5-pre2 2024-04-15 17:14:23 +02:00
FlorianMichael 2be190d152
Some consistency cleanup 2024-04-13 22:32:56 +02:00
FlorianMichael 4e25549682
Handle legacy item hover events
Co-authored-by: RaphiMC <50594595+raphimc@users.noreply.github.com>
2024-04-13 21:01:34 +02:00
FlorianMichael 287678c12a
[ci skip] Add comments for conversion direction to classes 2024-04-13 20:58:38 +02:00
FlorianMichael 4343aa17fc
Add missing annotations to StatePropertyMatcher 2024-04-13 20:57:32 +02:00
FlorianMichael 970986bc59
Add component rewriter for 1.20.3->1.20.5 2024-04-13 20:56:54 +02:00
Nassim Jahnke ba4404fad6
1.20.5-pre1 2024-04-10 17:33:10 +02:00
Nassim Jahnke 99f29e2597
Prepare proper banner id tracking, small other fixes 2024-04-09 12:40:16 +02:00
EnZaXD 7932b79080
Explain backup tags (#1) 2024-04-08 16:59:33 +02:00
FlorianMichael 4b780b92ee
Fix armor trim conversion 2024-04-08 15:05:01 +02:00
Nassim Jahnke d04aaeb926
Handle color in area effect cloud 2024-04-08 14:21:11 +02:00
FlorianMichael 9f1ee27afc
Add missing checks in item id conversions 2024-04-08 13:36:58 +02:00
Nassim Jahnke 5f685884ff
Handle entity effect particle in spawn particle 2024-04-08 13:33:59 +02:00
FlorianMichael ba2e50cc88
Fix StructuredDataConverter#removeItemBackupTag 2024-04-08 13:31:13 +02:00
FlorianMichael 7b28683b6a
Add remaining data backup handling 2024-04-08 13:18:49 +02:00
Nassim Jahnke 510747a7cd
Replace empty items in recipes 2024-04-08 10:53:39 +02:00
Nassim Jahnke 8c5752bb4c
Update unsupported java version warning 2024-04-07 22:34:20 +02:00
Nassim Jahnke 33e2a1fc13
Send unsigned messages if possible
The server cannot guarantee that the last seen values are correct, so in order to avoid kicks from invalid signatures, we will just strip them if possible.
2024-04-07 22:05:14 +02:00
Nassim Jahnke dbe8a389ce
Update authors 2024-04-07 20:41:44 +02:00
Nassim Jahnke 83223c1520
Also handle ack in serverbound chat message 2024-04-07 20:35:07 +02:00
FlorianMichael 935077222e
Simplify code 2024-04-07 20:08:16 +02:00
FlorianMichael 8961660846
Fix chat command handling 2024-04-07 19:43:29 +02:00
Nassim Jahnke 1fe23e4aeb
Fix trade list handling 2024-04-07 13:36:02 +02:00
Nassim Jahnke 06394c1f74
Apply network limits 2024-04-07 11:41:57 +02:00
Nassim Jahnke 68c2af2795
Replace unknown sounds with direct value in registry data 2024-04-06 23:47:27 +02:00
Nassim Jahnke 35a00d0b95
Check for new outbound_config pipeline handler 2024-04-06 23:10:58 +02:00
Nassim Jahnke c2489c7a4c
Back up 1.20.5 data components in VB for creative clients 2024-04-06 21:26:44 +02:00
Nassim Jahnke c743c20334
Update wolf textures again, add utility methods 2024-04-06 21:26:44 +02:00
FlorianMichael 228689f181
Remove temporary goat horn fix 2024-04-06 21:26:44 +02:00
Nassim Jahnke 67e6e1a2e3
24w14a 2024-04-06 21:26:44 +02:00
Nassim Jahnke a2c1c52f51
24w13a 2024-04-06 21:26:44 +02:00
Nassim Jahnke fd4db24d44
Fix intangible projectile data reading 2024-04-06 21:26:43 +02:00
Nassim Jahnke 0b7fdd4c69
Update wild wolf texture field name 2024-04-06 21:26:43 +02:00
Nassim Jahnke 4849ca0745
Start working on 24w12a 2024-04-06 21:26:43 +02:00
Nassim Jahnke 60b782455d
Fix display tag setting and doubled item id rewriting 2024-04-06 21:26:43 +02:00
FlorianMichael 3fef71db2e
Added missing null checks for CONTAINER_LOOT handler 2024-04-06 21:26:43 +02:00
Nassim Jahnke 9ca02680c8
Fix enchantment level 2024-04-06 21:26:43 +02:00
FlorianMichael 5899886b42
Fixes 2024-04-06 21:26:42 +02:00
Nassim Jahnke c2567115d8
Fix various issues 2024-04-06 21:26:42 +02:00
Nassim Jahnke 4255876c22
Fix up block state handling, add PotDecorations wrapper 2024-04-06 21:26:42 +02:00
FlorianMichael 57a589924d
More structured data handling 2024-04-06 21:26:42 +02:00
Nassim Jahnke 936dcafc11
Make HolderSet an interface 2024-04-06 21:26:42 +02:00
Nassim Jahnke b6489b8343
Fix block predicate parsing 2024-04-06 21:26:41 +02:00
Nassim Jahnke bf11a0a7de
Start working on 24w11a 2024-04-06 21:26:41 +02:00
Nassim Jahnke 7d41706026
Rewrite block predicates the other way around as well 2024-04-06 21:26:41 +02:00
FlorianMichael 93f081dd84
Add even more backwards rewriters 2024-04-06 21:26:41 +02:00
Nassim Jahnke 3f82b150d2
Handle CanPlaceOn and CanDestroy tags 2024-04-06 21:26:39 +02:00
Nassim Jahnke 7a96498f6d
Some sanity checks, get item id by name fast 2024-04-06 21:26:17 +02:00
FlorianMichael 817febe605
Even more work! 2024-04-06 21:26:16 +02:00
Nassim Jahnke bb4a8b73e0
Small cleanup 2024-04-06 21:26:16 +02:00
Nassim Jahnke 8d3492ba30
Add more structured data -> nbt converters 2024-04-06 21:26:16 +02:00
Nassim Jahnke 658364b643
Add a few structured data -> nbt converters 2024-04-06 21:26:16 +02:00
Nassim Jahnke 666b204ebb
Prepare class for structured data->tag rewriting 2024-04-06 21:26:16 +02:00
Nassim Jahnke bfab9b0c11
Banner patterns and wolves 2024-04-06 21:26:15 +02:00
Nassim Jahnke 121f107ff3
More handled structures 2024-04-06 21:26:15 +02:00
Nassim Jahnke 426bd9aa99
More handled structures 2024-04-06 21:26:13 +02:00
Nassim Jahnke 7a66bb8e1c
More handled structures 2024-04-06 21:25:39 +02:00
Nassim Jahnke 329abcac7d
More handled structures 2024-04-06 21:25:08 +02:00
Nassim Jahnke 0961de898d
Handle books, among other things 2024-04-06 21:25:05 +02:00
Nassim Jahnke b4ee564aa2
24w10a, more item component work 2024-04-06 21:23:57 +02:00
152 changed files with 6306 additions and 728 deletions

View File

@ -10,4 +10,7 @@ ij_java_class_count_to_use_import_on_demand = 999999
ij_java_names_count_to_use_import_on_demand = 999999
ij_java_imports_layout = *,|,$*
ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
ij_java_generate_final_parameters = true
[{*.json,*.yml}]
indent_size = 2

View File

@ -55,10 +55,10 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_9 = register(107, "1.9");
public static final ProtocolVersion v1_9_1 = register(108, "1.9.1");
public static final ProtocolVersion v1_9_2 = register(109, "1.9.2");
public static final ProtocolVersion v1_9_3 = register(110, "1.9.3/4", new SubVersionRange("1.9", 3, 4));
public static final ProtocolVersion v1_9_3 = register(110, "1.9.3/1.9.4", new SubVersionRange("1.9", 3, 4));
public static final ProtocolVersion v1_10 = register(210, "1.10.x");
public static final ProtocolVersion v1_11 = register(315, "1.11");
public static final ProtocolVersion v1_11_1 = register(316, "1.11.1/2", new SubVersionRange("1.11", 1, 2));
public static final ProtocolVersion v1_11_1 = register(316, "1.11.1/1.11.2", new SubVersionRange("1.11", 1, 2));
public static final ProtocolVersion v1_12 = register(335, "1.12");
public static final ProtocolVersion v1_12_1 = register(338, "1.12.1");
public static final ProtocolVersion v1_12_2 = register(340, "1.12.2");
@ -77,18 +77,19 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_16_1 = register(736, "1.16.1");
public static final ProtocolVersion v1_16_2 = register(751, "1.16.2");
public static final ProtocolVersion v1_16_3 = register(753, "1.16.3");
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/5", new SubVersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/1.16.5", new SubVersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_17 = register(755, "1.17");
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new SubVersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18_2 = register(758, "1.18.2");
public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/2", new SubVersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/1.19.2", new SubVersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new SubVersionRange("1.20", 0, 1));
public static final ProtocolVersion v1_20_2 = register(764, "1.20.2");
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3");
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");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {

View File

@ -66,7 +66,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes
*/
default int apiVersion() {
return 25;
return 26;
}
/**

View File

@ -450,4 +450,11 @@ public interface ViaVersionConfig extends Config {
* @return true if enabled
*/
boolean translateOcelotToCat();
/**
* Returns the value of the "enforce secure chat" setting sent to 1.19+ clients on join.
*
* @return the value sent to 1.19+ clients on join
*/
boolean enforceSecureChat();
}

View File

@ -27,7 +27,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Mappings containing the full string identifier mappings.
*/
public interface FullMappings extends Mappings {
public interface FullMappings extends BiMappings {
/**
* Returns the unmapped integer id for the given identifier, or -1 if not found.

View File

@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.data;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
@ -37,6 +38,7 @@ public class FullMappingsBase implements FullMappings {
private final Mappings mappings;
public FullMappingsBase(final List<String> unmappedIdentifiers, final List<String> mappedIdentifiers, final Mappings mappings) {
Preconditions.checkNotNull(mappings, "Mappings cannot be null");
this.mappings = mappings;
this.stringToId = toInverseMap(unmappedIdentifiers);
this.mappedStringToId = toInverseMap(mappedIdentifiers);

View File

@ -89,8 +89,21 @@ public interface MappingData {
*/
@Nullable List<TagData> getTags(RegistryType type);
/**
* Returns item mappings.
*
* @return item mappings
*/
@Nullable BiMappings getItemMappings();
/**
* Returns item mappings if they also have identifier data present.
*
* @return item mappings if they also have identifier data present
* @see #getItemMappings()
*/
@Nullable FullMappings getFullItemMappings();
@Nullable ParticleMappings getParticleMappings();
@Nullable Mappings getBlockMappings();

View File

@ -24,8 +24,6 @@ package com.viaversion.viaversion.api.data;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.RegistryType;
@ -35,7 +33,6 @@ import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MappingDataBase implements MappingData {
@ -80,28 +77,29 @@ public class MappingDataBase implements MappingData {
enchantmentMappings = loadMappings(data, "enchantments");
paintingMappings = loadMappings(data, "paintings");
attributeMappings = loadMappings(data, "attributes");
itemMappings = loadBiMappings(data, "items");
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
if (unmappedIdentifierData != null && mappedIdentifierData != null) {
itemMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "items");
entityMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "entities");
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
final ListTag<StringTag> unmappedParticles = unmappedIdentifierData.getListTag("particles", StringTag.class);
final ListTag<StringTag> mappedParticles = mappedIdentifierData.getListTag("particles", StringTag.class);
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
if (unmappedParticles != null && mappedParticles != null) {
Mappings particleMappings = loadMappings(data, "particles");
if (particleMappings == null) {
particleMappings = new IdentityMappings(unmappedParticles.size(), mappedParticles.size());
}
final List<String> identifiers = unmappedParticles.stream().map(StringTag::getValue).collect(Collectors.toList());
final List<String> mappedIdentifiers = mappedParticles.stream().map(StringTag::getValue).collect(Collectors.toList());
this.particleMappings = new ParticleMappings(identifiers, mappedIdentifiers, particleMappings);
this.particleMappings = new ParticleMappings(unmappedParticles, mappedParticles, particleMappings);
}
} else {
// Might not have identifiers in older versions
itemMappings = loadBiMappings(data, "items");
}
final CompoundTag tagsTag = data.getCompoundTag("tags");
@ -114,6 +112,10 @@ public class MappingDataBase implements MappingData {
loadExtras(data);
}
protected @Nullable List<String> identifiersFromGlobalIds(final CompoundTag mappingsTag, final String key) {
return MappingDataLoader.INSTANCE.identifiersFromGlobalIds(mappingsTag, key);
}
protected @Nullable CompoundTag readMappingsFile(final String name) {
return MappingDataLoader.INSTANCE.loadNBT(name);
}
@ -194,6 +196,14 @@ public class MappingDataBase implements MappingData {
return itemMappings;
}
@Override
public @Nullable FullMappings getFullItemMappings() {
if (itemMappings instanceof FullMappings) {
return (FullMappings) itemMappings;
}
return null;
}
@Override
public @Nullable ParticleMappings getParticleMappings() {
return particleMappings;

View File

@ -28,6 +28,7 @@ import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.github.steveice10.opennbt.tag.io.NBTIO;
import com.github.steveice10.opennbt.tag.io.TagReader;
import com.google.common.annotations.Beta;
@ -40,13 +41,16 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.util.GsonUtil;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@ -54,14 +58,14 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class MappingDataLoader {
public static final MappingDataLoader INSTANCE = new MappingDataLoader(MappingDataLoader.class, "assets/viaversion/data/");
public static final TagReader<CompoundTag> MAPPINGS_READER = NBTIO.reader(CompoundTag.class).named();
private static final Map<String, String[]> GLOBAL_IDENTIFIER_INDEXES = new HashMap<>();
private static final byte DIRECT_ID = 0;
private static final byte SHIFTS_ID = 1;
private static final byte CHANGES_ID = 2;
private static final byte IDENTITY_ID = 3;
public static final MappingDataLoader INSTANCE = new MappingDataLoader(MappingDataLoader.class, "assets/viaversion/data/");
private final Map<String, CompoundTag> mappingsCache = new HashMap<>();
private final Class<?> dataLoaderClass;
private final String dataPath;
@ -72,6 +76,40 @@ public class MappingDataLoader {
this.dataPath = dataPath;
}
public static void loadGlobalIdentifiers() {
// Load in a file with all the identifiers we need, so that we don't need to duplicate them
// for every single new version with only a couple of changes in them.
final CompoundTag globalIdentifiers = INSTANCE.loadNBT("identifier-table.nbt");
for (final Map.Entry<String, Tag> entry : globalIdentifiers.entrySet()) {
//noinspection unchecked
final ListTag<StringTag> value = (ListTag<StringTag>) entry.getValue();
final String[] array = new String[value.size()];
for (int i = 0, size = value.size(); i < size; i++) {
array[i] = value.get(i).getValue();
}
GLOBAL_IDENTIFIER_INDEXES.put(entry.getKey(), array);
}
}
/**
* Returns the global id of the identifier in the registry.
*
* @param registry registry key
* @param globalId global id
* @return identifier
* @throws IllegalArgumentException if the registry key is invalid
*/
public @Nullable String identifierFromGlobalId(final String registry, final int globalId) {
final String[] array = GLOBAL_IDENTIFIER_INDEXES.get(registry);
if (array == null) {
throw new IllegalArgumentException("Unknown global identifier key: " + registry);
}
if (globalId < 0 || globalId >= array.length) {
throw new IllegalArgumentException("Unknown global identifier index: " + globalId);
}
return array[globalId];
}
public void clearCache() {
mappingsCache.clear();
cacheValid = false;
@ -146,7 +184,7 @@ public class MappingDataLoader {
return null;
}
try (final InputStream stream = resource) {
try (final InputStream stream = new BufferedInputStream(resource)) {
return MAPPINGS_READER.read(stream);
} catch (final IOException e) {
throw new RuntimeException(e);
@ -238,23 +276,32 @@ public class MappingDataLoader {
return mappingsSupplier.create(mappings, mappedSizeTag.asInt());
}
public FullMappings loadFullMappings(final CompoundTag mappingsTag, final CompoundTag unmappedIdentifiers, final CompoundTag mappedIdentifiers, final String key) {
final ListTag<StringTag> unmappedElements = unmappedIdentifiers.getListTag(key, StringTag.class);
final ListTag<StringTag> mappedElements = mappedIdentifiers.getListTag(key, StringTag.class);
if (unmappedElements == null || mappedElements == null) {
public FullMappings loadFullMappings(final CompoundTag mappingsTag, final CompoundTag unmappedIdentifiersTag, final CompoundTag mappedIdentifiersTag, final String key) {
if (!unmappedIdentifiersTag.contains(key) || !mappedIdentifiersTag.contains(key)) {
return null;
}
final List<String> unmappedIdentifiers = identifiersFromGlobalIds(unmappedIdentifiersTag, key);
final List<String> mappedIdentifiers = identifiersFromGlobalIds(mappedIdentifiersTag, key);
Mappings mappings = loadMappings(mappingsTag, key);
if (mappings == null) {
mappings = new IdentityMappings(unmappedElements.size(), mappedElements.size());
mappings = new IdentityMappings(unmappedIdentifiers.size(), mappedIdentifiers.size());
}
return new FullMappingsBase(
unmappedElements.stream().map(StringTag::getValue).collect(Collectors.toList()),
mappedElements.stream().map(StringTag::getValue).collect(Collectors.toList()),
mappings
);
return new FullMappingsBase(unmappedIdentifiers, mappedIdentifiers, mappings);
}
public @Nullable List<String> identifiersFromGlobalIds(final CompoundTag mappingsTag, final String key) {
final Mappings mappings = loadMappings(mappingsTag, key);
if (mappings == null) {
return null;
}
final List<String> identifiers = new ArrayList<>(mappings.size());
for (int i = 0; i < mappings.size(); i++) {
identifiers.add(identifierFromGlobalId(key, mappings.getNewId(i)));
}
return identifiers;
}
/**

View File

@ -84,10 +84,4 @@ public interface Mappings {
* @return mappings with keys and values swapped
*/
Mappings inverse();
@FunctionalInterface
interface MappingsSupplier<T extends Mappings> {
T supply(int[] mappings, int mappedIds);
}
}

View File

@ -35,6 +35,7 @@ public class ParticleMappings extends FullMappingsBase {
addBlockParticle("block");
addBlockParticle("falling_dust");
addBlockParticle("block_marker");
addBlockParticle("dust_pillar");
addItemParticle("item");
}

View File

@ -31,13 +31,13 @@ public final class GameProfile {
private final UUID id;
private final Property[] properties;
public GameProfile(final String name, @Nullable final UUID id, final Property[] properties) {
public GameProfile(@Nullable final String name, @Nullable final UUID id, final Property[] properties) {
this.name = name;
this.id = id;
this.properties = properties;
}
public String name() {
public @Nullable String name() {
return name;
}

View File

@ -22,21 +22,29 @@
*/
package com.viaversion.viaversion.api.minecraft;
import com.google.common.base.Preconditions;
public interface Holder<T> {
public final class Holder<T> {
private final T value;
private final int id;
public Holder(final int id) {
this.value = null;
this.id = id;
/**
* Returns an indirect id holder.
*
* @param id the id
* @param <T> the type of the value
* @return a new holder with the given id
* @throws IllegalArgumentException if the id is negative
*/
static <T> Holder<T> of(final int id) {
return new HolderImpl<>(id);
}
public Holder(final T value) {
this.value = value;
this.id = -1;
/**
* Returns a direct value holder.
*
* @param value the value
* @param <T> the type of the value
* @return a new direct holder
*/
static <T> Holder<T> of(final T value) {
return new HolderImpl<>(value);
}
/**
@ -45,9 +53,7 @@ public final class Holder<T> {
* @return true if the holder is direct
* @see #hasId()
*/
public boolean isDirect() {
return id == -1;
}
boolean isDirect();
/**
* Returns true if this holder has an id.
@ -55,16 +61,22 @@ public final class Holder<T> {
* @return true if this holder has an id
* @see #isDirect()
*/
public boolean hasId() {
return id != -1;
}
boolean hasId();
public T value() {
Preconditions.checkArgument(isDirect(), "Holder is not direct");
return value;
}
/**
* Returns the value of this holder.
*
* @return the value of this holder
* @throws IllegalArgumentException if this holder is not direct
* @see #isDirect()
*/
T value();
public int id() {
return id;
}
/**
* Returns the id of this holder, or -1 if this holder is direct.
*
* @return the id of this holder, or -1 if this holder is direct
* @see #hasId()
*/
int id();
}

View File

@ -0,0 +1,63 @@
/*
* 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 com.google.common.base.Preconditions;
final class HolderImpl<T> implements Holder<T> {
private final T value;
private final int id;
HolderImpl(final int id) {
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;
}
@Override
public boolean hasId() {
return id != -1;
}
@Override
public T value() {
Preconditions.checkArgument(isDirect(), "Holder is not direct");
return value;
}
@Override
public int id() {
return id;
}
}

View File

@ -22,15 +22,58 @@
*/
package com.viaversion.viaversion.api.minecraft;
import com.viaversion.viaversion.util.EitherImpl;
/**
* Set of ids that either holds a string tag key or an array of ids.
*/
public interface HolderSet {
public final class HolderSet extends EitherImpl<String, int[]> {
public HolderSet(final String tagKey) {
super(tagKey, null);
/**
* Creates a new holder set for the given tag.
*
* @param tagKey the tag key
* @return a new holder set
*/
static HolderSet of(final String tagKey) {
return new HolderSetImpl(tagKey);
}
public HolderSet(final int[] ids) {
super(null, ids);
/**
* Creates a new holder set for the given ids.
*
* @param ids the direct ids
* @return a new holder set
*/
static HolderSet of(final int[] ids) {
return new HolderSetImpl(ids);
}
/**
* Gets the tag key.
*
* @return the tag key
* @see #hasTagKey()
*/
String tagKey();
/**
* Returns whether this holder set has a tag key.
*
* @return true if this holder set has a tag key, false if it has direct ids
*/
boolean hasTagKey();
/**
* Gets the direct ids.
*
* @return direct ids
* @see #hasIds()
*/
int[] ids();
/**
* Returns whether this holder set has direct ids.
*
* @return true if this holder set has direct ids, false if it has a tag key
*/
boolean hasIds();
}

View File

@ -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;
import com.viaversion.viaversion.util.EitherImpl;
final class HolderSetImpl extends EitherImpl<String, int[]> implements HolderSet {
HolderSetImpl(final String tagKey) {
super(tagKey, null);
}
HolderSetImpl(final int[] ids) {
super(null, ids);
}
@Override
public String tagKey() {
return left();
}
@Override
public boolean hasTagKey() {
return isLeft();
}
@Override
public int[] ids() {
return right();
}
@Override
public boolean hasIds() {
return isRight();
}
}

View File

@ -73,6 +73,18 @@ public final class Particle implements IdHolder {
arguments.add(index, new ParticleData<>(type, value));
}
public <T> void set(final int index, final Type<T> type, final T value) {
arguments.set(index, new ParticleData<>(type, value));
}
@Override
public String toString() {
return "Particle{" +
"arguments=" + arguments +
", id=" + id +
'}';
}
public static final class ParticleData<T> {
private final Type<T> type;
private T value;

View File

@ -22,6 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft;
import java.util.Arrays;
public final class TagData {
private final String identifier;
private final int[] entries;
@ -38,4 +40,12 @@ public final class TagData {
public int[] entries() {
return entries;
}
@Override
public String toString() {
return "TagData{" +
"identifier='" + identifier + '\'' +
", entries=" + Arrays.toString(entries) +
'}';
}
}

View File

@ -67,4 +67,28 @@ final class EmptyStructuredData<T> implements StructuredData<T> {
public int id() {
return this.id;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final EmptyStructuredData<?> that = (EmptyStructuredData<?>) o;
if (id != that.id) return false;
return key.equals(that.key);
}
@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result + id;
return result;
}
@Override
public String toString() {
return "EmptyStructuredData{" +
"key=" + key +
", id=" + id +
'}';
}
}

View File

@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft.data;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import java.util.Objects;
final class FilledStructuredData<T> implements StructuredData<T> {
@ -72,4 +73,31 @@ final class FilledStructuredData<T> implements StructuredData<T> {
public int id() {
return id;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FilledStructuredData<?> that = (FilledStructuredData<?>) o;
if (id != that.id) return false;
if (!key.equals(that.key)) return false;
return Objects.equals(value, that.value);
}
@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result + (value != null ? value.hashCode() : 0);
result = 31 * result + id;
return result;
}
@Override
public String toString() {
return "FilledStructuredData{" +
"key=" + key +
", value=" + value +
", id=" + id +
'}';
}
}

View File

@ -25,8 +25,10 @@ package com.viaversion.viaversion.api.minecraft.data;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.Unit;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Map;
import java.util.function.Function;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class StructuredDataContainer {
@ -39,6 +41,13 @@ public final class StructuredDataContainer {
this.data = data;
}
public StructuredDataContainer(final StructuredData<?>[] dataArray) {
this(new Reference2ObjectOpenHashMap<>(dataArray.length));
for (final StructuredData<?> data : dataArray) {
add(data);
}
}
public StructuredDataContainer() {
this(new Reference2ObjectOpenHashMap<>());
}
@ -68,13 +77,37 @@ public final class StructuredDataContainer {
return data != null && data.isPresent() ? data : null;
}
public <T> void add(final StructuredDataKey<T> key, final T value) {
/**
* Returns structured data by id if not empty, or creates it.
*
* @param key serializer id
* @param mappingFunction function to create structured data if not present
* @param <T> data type
* @return structured data if not empty
*/
public <T> StructuredData<T> computeIfAbsent(final StructuredDataKey<T> key, final Function<StructuredDataKey<T>, T> mappingFunction) {
final StructuredData<T> data = this.getNonEmpty(key);
if (data != null) {
return data;
}
final int id = serializerId(key);
final StructuredData<T> empty = StructuredData.of(key, mappingFunction.apply(key), id);
this.data.put(key, empty);
return empty;
}
public <T> void set(final StructuredDataKey<T> key, final T value) {
final int id = serializerId(key);
if (id != -1) {
this.data.put(key, StructuredData.of(key, value, id));
}
}
public void set(final StructuredDataKey<Unit> key) {
this.set(key, Unit.INSTANCE);
}
public void addEmpty(final StructuredDataKey<?> key) {
// Empty optional to override the Minecraft default
this.data.put(key, StructuredData.empty(key, serializerId(key)));
@ -125,4 +158,15 @@ public final class StructuredDataContainer {
public Map<StructuredDataKey<?>, StructuredData<?>> data() {
return data;
}
private <T> void add(final StructuredData<T> data) {
set(data.key(), data.value());
}
@Override
public String toString() {
return "StructuredDataContainer{" +
"data=" + data +
'}';
}
}

View File

@ -30,17 +30,22 @@ 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;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers;
import com.viaversion.viaversion.api.minecraft.item.data.BannerPattern;
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.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
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.LodestoneTarget;
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;
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.WrittenBook;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
@ -49,21 +54,29 @@ import com.viaversion.viaversion.util.Unit;
public final class StructuredDataKey<T> {
public static final StructuredDataKey<CompoundTag> CUSTOM_DATA = new StructuredDataKey<>("custom_data", Type.COMPOUND_TAG);
public static final StructuredDataKey<Integer> MAX_STACK_SIZE = new StructuredDataKey<>("max_stack_size", Type.VAR_INT);
public static final StructuredDataKey<Integer> MAX_DAMAGE = new StructuredDataKey<>("max_damage", Type.VAR_INT);
public static final StructuredDataKey<Integer> DAMAGE = new StructuredDataKey<>("damage", Type.VAR_INT);
public static final StructuredDataKey<Boolean> UNBREAKABLE = new StructuredDataKey<>("unbreakable", Type.BOOLEAN);
public static final StructuredDataKey<Unbreakable> UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE);
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Type.TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Type.TAG);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", Type.TAG_ARRAY);
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Type.VAR_INT);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE);
public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON = new StructuredDataKey<>("can_place_on", AdventureModePredicate.TYPE);
public static final StructuredDataKey<AdventureModePredicate> CAN_BREAK = new StructuredDataKey<>("can_break", AdventureModePredicate.TYPE);
public static final StructuredDataKey<AttributeModifiers> ATTRIBUTE_MODIFIERS = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers.TYPE);
public static final StructuredDataKey<Integer> CUSTOM_MODEL_DATA = new StructuredDataKey<>("custom_model_data", Type.VAR_INT);
public static final StructuredDataKey<Unit> HIDE_ADDITIONAL_TOOLTIP = new StructuredDataKey<>("hide_additional_tooltip", Type.EMPTY);
public static final StructuredDataKey<Unit> HIDE_TOOLTIP = new StructuredDataKey<>("hide_tooltip", Type.EMPTY);
public static final StructuredDataKey<Integer> REPAIR_COST = new StructuredDataKey<>("repair_cost", Type.VAR_INT);
public static final StructuredDataKey<Unit> CREATIVE_SLOT_LOCK = new StructuredDataKey<>("creative_slot_lock", Type.EMPTY);
public static final StructuredDataKey<Boolean> ENCHANTMENT_GLINT_OVERRIDE = new StructuredDataKey<>("enchantment_glint_override", Type.BOOLEAN);
public static final StructuredDataKey<Unit> INTANGIBLE_PROJECTILE = new StructuredDataKey<>("intangible_projectile", Type.EMPTY);
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS = new StructuredDataKey<>("storded_enchantments", Enchantments.TYPE);
public static final StructuredDataKey<Tag> INTANGIBLE_PROJECTILE = new StructuredDataKey<>("intangible_projectile", Type.TAG); // Doesn't actually hold data
public static final StructuredDataKey<FoodProperties> FOOD = new StructuredDataKey<>("food", FoodProperties.TYPE);
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Type.EMPTY);
public static final StructuredDataKey<ToolProperties> TOOL = new StructuredDataKey<>("tool", ToolProperties.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", Type.INT);
public static final StructuredDataKey<Integer> MAP_ID = new StructuredDataKey<>("map_id", Type.VAR_INT);
@ -73,7 +86,7 @@ public final class StructuredDataKey<T> {
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<PotionContents> POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE);
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
public static final StructuredDataKey<String[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", Type.STRING_ARRAY);
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);
public static final StructuredDataKey<ArmorTrim> TRIM = new StructuredDataKey<>("trim", ArmorTrim.TYPE);
public static final StructuredDataKey<CompoundTag> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Type.COMPOUND_TAG);
@ -81,15 +94,16 @@ public final class StructuredDataKey<T> {
public static final StructuredDataKey<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Type.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Type.COMPOUND_TAG);
public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
public static final StructuredDataKey<String[]> RECIPES = new StructuredDataKey<>("recipes", Type.STRING_ARRAY);
public static final StructuredDataKey<LodestoneTarget> LODESTONE_TARGET = new StructuredDataKey<>("lodestone_target", LodestoneTarget.TYPE);
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Type.VAR_INT);
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Type.TAG);
public static final StructuredDataKey<LodestoneTracker> LODESTONE_TRACKER = new StructuredDataKey<>("lodestone_tracker", LodestoneTracker.TYPE);
public static final StructuredDataKey<FireworkExplosion> FIREWORK_EXPLOSION = new StructuredDataKey<>("firework_explosion", FireworkExplosion.TYPE);
public static final StructuredDataKey<Fireworks> FIREWORKS = new StructuredDataKey<>("fireworks", Fireworks.TYPE);
public static final StructuredDataKey<GameProfile> PROFILE = new StructuredDataKey<>("profile", Type.GAME_PROFILE);
public static final StructuredDataKey<String> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Type.STRING);
public static final StructuredDataKey<BannerPattern[]> BANNER_PATTERNS = new StructuredDataKey<>("banner_patterns", BannerPattern.ARRAY_TYPE);
public static final StructuredDataKey<BannerPatternLayer[]> BANNER_PATTERNS = new StructuredDataKey<>("banner_patterns", BannerPatternLayer.ARRAY_TYPE);
public static final StructuredDataKey<Integer> BASE_COLOR = new StructuredDataKey<>("base_color", Type.VAR_INT);
public static final StructuredDataKey<int[]> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", Type.VAR_INT_ARRAY_PRIMITIVE);
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
public static final StructuredDataKey<Item[]> CONTAINER = new StructuredDataKey<>("container", Types1_20_5.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);
@ -111,4 +125,12 @@ public final class StructuredDataKey<T> {
public String identifier() {
return identifier;
}
@Override
public String toString() {
return "StructuredDataKey{" +
"identifier='" + identifier + '\'' +
", type=" + type +
'}';
}
}

View File

@ -44,6 +44,7 @@ public enum EntityTypes1_20_5 implements EntityType {
TNT(ENTITY),
SHULKER_BULLET(ENTITY),
FISHING_BOBBER(ENTITY),
OMINOUS_ITEM_SPAWNER(ENTITY),
LIVINGENTITY(ENTITY, null),
ARMOR_STAND(LIVINGENTITY),

View File

@ -80,7 +80,8 @@ public interface Item {
*
* @return item tag
*/
@Nullable CompoundTag tag();
@Nullable
CompoundTag tag();
/**
* Sets the item compound tag.
@ -97,4 +98,13 @@ public interface Item {
* @return copy of the item
*/
Item copy();
/**
* Returns true if the item is empty.
*
* @return true if the item is empty
*/
default boolean isEmpty() {
return identifier() == 0 || amount() <= 0;
}
}

View File

@ -29,13 +29,13 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class StructuredItem implements Item {
private final StructuredDataContainer data;
private int identifier;
private byte amount;
private int amount;
public StructuredItem() {
this(0, (byte) 0, new StructuredDataContainer());
public StructuredItem(final int identifier, final int amount) {
this(identifier, amount, new StructuredDataContainer());
}
public StructuredItem(final int identifier, final byte amount, final StructuredDataContainer data) {
public StructuredItem(final int identifier, final int amount, final StructuredDataContainer data) {
this.identifier = identifier;
this.amount = amount;
this.data = data;
@ -58,10 +58,7 @@ public class StructuredItem implements Item {
@Override
public void setAmount(final int amount) {
if (amount > Byte.MAX_VALUE || amount < Byte.MIN_VALUE) {
throw new IllegalArgumentException("Invalid item amount: " + amount);
}
this.amount = (byte) amount;
this.amount = amount;
}
@Override
@ -101,4 +98,13 @@ public class StructuredItem implements Item {
result = 31 * result + amount;
return result;
}
@Override
public String toString() {
return "StructuredItem{" +
"data=" + data +
", identifier=" + identifier +
", amount=" + amount +
'}';
}
}

View File

@ -25,7 +25,6 @@ package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
// This goes DEEEP
public final class AdventureModePredicate {
public static final Type<AdventureModePredicate> TYPE = new Type<AdventureModePredicate>(AdventureModePredicate.class) {

View File

@ -41,19 +41,19 @@ public final class AttributeModifier {
public void write(final ByteBuf buffer, final AttributeModifier value) throws Exception {
Type.VAR_INT.writePrimitive(buffer, value.attribute);
ModifierData.TYPE.write(buffer, value.modifier);
Type.VAR_INT.writePrimitive(buffer, value.slot);
Type.VAR_INT.writePrimitive(buffer, value.slotType);
}
};
public static final Type<AttributeModifier[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final int attribute;
private final ModifierData modifier;
private final int slot;
private final int slotType;
public AttributeModifier(final int attribute, final ModifierData modifier, final int slot) {
public AttributeModifier(final int attribute, final ModifierData modifier, final int slotType) {
this.attribute = attribute;
this.modifier = modifier;
this.slot = slot;
this.slotType = slotType;
}
public int attribute() {
@ -64,7 +64,7 @@ public final class AttributeModifier {
return modifier;
}
public int slot() {
return slot;
public int slotType() {
return slotType;
}
}

View File

@ -23,40 +23,39 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf;
public final class BannerPattern {
public static final Type<BannerPattern> TYPE = new Type<BannerPattern>(BannerPattern.class) {
public static final HolderType<BannerPattern> TYPE = new HolderType<BannerPattern>() {
@Override
public BannerPattern read(final ByteBuf buffer) throws Exception {
final int pattern = Type.VAR_INT.readPrimitive(buffer);
final int color = Type.VAR_INT.readPrimitive(buffer);
return new BannerPattern(pattern, color);
public BannerPattern readDirect(final ByteBuf buffer) throws Exception {
final String assetId = Type.STRING.read(buffer);
final String translationKey = Type.STRING.read(buffer);
return new BannerPattern(assetId, translationKey);
}
@Override
public void write(final ByteBuf buffer, final BannerPattern value) throws Exception {
Type.VAR_INT.writePrimitive(buffer, value.pattern);
Type.VAR_INT.writePrimitive(buffer, value.color);
public void writeDirect(final ByteBuf buffer, final BannerPattern value) throws Exception {
Type.STRING.write(buffer, value.assetId);
Type.STRING.write(buffer, value.translationKey);
}
};
public static final Type<BannerPattern[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final int pattern;
private final int color;
private final String assetId;
private final String translationKey;
public BannerPattern(final int pattern, final int color) {
this.pattern = pattern;
this.color = color;
public BannerPattern(final String assetId, final String translationKey) {
this.assetId = assetId;
this.translationKey = translationKey;
}
public int pattern() {
return this.pattern;
public String assetId() {
return assetId;
}
public int color() {
return this.color;
public String translationKey() {
return translationKey;
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import io.netty.buffer.ByteBuf;
public final class BannerPatternLayer {
public static final Type<BannerPatternLayer> TYPE = new Type<BannerPatternLayer>(BannerPatternLayer.class) {
@Override
public BannerPatternLayer read(final ByteBuf buffer) throws Exception {
final Holder<BannerPattern> pattern = BannerPattern.TYPE.read(buffer);
final int color = Type.VAR_INT.readPrimitive(buffer);
return new BannerPatternLayer(pattern, color);
}
@Override
public void write(final ByteBuf buffer, final BannerPatternLayer value) throws Exception {
BannerPattern.TYPE.write(buffer, value.pattern);
Type.VAR_INT.writePrimitive(buffer, value.dyeColor);
}
};
public static final Type<BannerPatternLayer[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final Holder<BannerPattern> pattern;
private final int dyeColor;
public BannerPatternLayer(final Holder<BannerPattern> pattern, final int dyeColor) {
this.pattern = pattern;
this.dyeColor = dyeColor;
}
public Holder<BannerPattern> pattern() {
return pattern;
}
public int dyeColor() {
return dyeColor;
}
}

View File

@ -42,7 +42,7 @@ public final class BlockPredicate {
@Override
public void write(final ByteBuf buffer, final BlockPredicate value) throws Exception {
Type.OPTIONAL_HOLDER_SET.write(buffer, value.holders);
Type.OPTIONAL_HOLDER_SET.write(buffer, value.holderSet);
buffer.writeBoolean(value.propertyMatchers != null);
if (value.propertyMatchers != null) {
@ -54,18 +54,18 @@ public final class BlockPredicate {
};
public static final Type<BlockPredicate[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final HolderSet holders;
private final HolderSet holderSet;
private final StatePropertyMatcher[] propertyMatchers;
private final CompoundTag tag;
public BlockPredicate(@Nullable final HolderSet holders, final StatePropertyMatcher @Nullable [] propertyMatchers, @Nullable final CompoundTag tag) {
this.holders = holders;
public BlockPredicate(@Nullable final HolderSet holderSet, final StatePropertyMatcher @Nullable [] propertyMatchers, @Nullable final CompoundTag tag) {
this.holderSet = holderSet;
this.propertyMatchers = propertyMatchers;
this.tag = tag;
}
public @Nullable HolderSet predicates() {
return holders;
public @Nullable HolderSet holderSet() {
return holderSet;
}
public StatePropertyMatcher @Nullable [] propertyMatchers() {

View File

@ -62,6 +62,10 @@ public final class Enchantments {
this.showInTooltip = showInTooltip;
}
public Enchantments(final boolean showInTooltip) {
this(new Int2IntOpenHashMap(), showInTooltip);
}
public Int2IntMap enchantments() {
return enchantments;
}
@ -73,4 +77,20 @@ public final class Enchantments {
public boolean showInTooltip() {
return showInTooltip;
}
public void add(final int id, final int level) {
enchantments.put(id, level);
}
public void remove(final int id) {
enchantments.remove(id);
}
public void clear() {
enchantments.clear();
}
public int getLevel(final int id) {
return enchantments.getOrDefault(id, -1);
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class Filterable<T> {
private final T raw;
private final T filtered;
protected Filterable(final T raw, @Nullable final T filtered) {
this.raw = raw;
this.filtered = filtered;
}
public T raw() {
return raw;
}
public boolean isFiltered() {
return filtered != null;
}
public @Nullable T filtered() {
return filtered;
}
public T get() {
return filtered != null ? filtered : raw;
}
public abstract static class FilterableType<T, F extends Filterable<T>> extends Type<F> {
private final Type<T> elementType;
private final Type<T> optionalElementType;
protected FilterableType(final Type<T> elementType, final Type<T> optionalElementType, final Class<F> outputClass) {
super(outputClass);
this.elementType = elementType;
this.optionalElementType = optionalElementType;
}
@Override
public F read(final ByteBuf buffer) throws Exception {
final T raw = elementType.read(buffer);
final T filtered = optionalElementType.read(buffer);
return create(raw, filtered);
}
@Override
public void write(final ByteBuf buffer, final F value) throws Exception {
elementType.write(buffer, value.raw());
optionalElementType.write(buffer, value.filtered());
}
protected abstract F create(T raw, T filtered);
}
}

View File

@ -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.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class FilterableComponent extends Filterable<Tag> {
public static final Type<FilterableComponent> TYPE = new FilterableType<Tag, FilterableComponent>(Type.TAG, Type.OPTIONAL_TAG, FilterableComponent.class) {
@Override
protected FilterableComponent create(final Tag raw, final Tag filtered) {
return new FilterableComponent(raw, filtered);
}
};
public static final Type<FilterableComponent[]> ARRAY_TYPE = new ArrayType<>(FilterableComponent.TYPE);
public FilterableComponent(final Tag raw, @Nullable final Tag filtered) {
super(raw, filtered);
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.ArrayType;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class FilterableString extends Filterable<String> {
public static final Type<FilterableString> TYPE = new FilterableType<String, FilterableString>(Type.STRING, Type.OPTIONAL_STRING, FilterableString.class) {
@Override
protected FilterableString create(final String raw, final String filtered) {
return new FilterableString(raw, filtered);
}
};
public static final Type<FilterableString[]> ARRAY_TYPE = new ArrayType<>(TYPE);
public FilterableString(final String raw, @Nullable final String filtered) {
super(raw, filtered);
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.ArrayType;
import io.netty.buffer.ByteBuf;
public final class FoodEffect {
public static final Type<FoodEffect> TYPE = new Type<FoodEffect>(FoodEffect.class) {
@Override
public FoodEffect read(final ByteBuf buffer) throws Exception {
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) throws Exception {
PotionEffect.TYPE.write(buffer, value.effect);
buffer.writeFloat(value.probability);
}
};
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final PotionEffect effect;
private final float probability;
public FoodEffect(final PotionEffect effect, final float probability) {
this.effect = effect;
this.probability = probability;
}
public PotionEffect effect() {
return effect;
}
public float probability() {
return probability;
}
}

View File

@ -0,0 +1,84 @@
/*
* 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 io.netty.buffer.ByteBuf;
public final class FoodProperties {
public static final Type<FoodProperties> TYPE = new Type<FoodProperties>(FoodProperties.class) {
@Override
public FoodProperties read(final ByteBuf buffer) throws Exception {
final int nutrition = Type.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, possibleEffects);
}
@Override
public void write(final ByteBuf buffer, final FoodProperties value) throws Exception {
Type.VAR_INT.writePrimitive(buffer, value.nutrition);
buffer.writeFloat(value.saturationModifier);
buffer.writeBoolean(value.canAlwaysEat);
buffer.writeFloat(value.eatSeconds);
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
}
};
private final int nutrition;
private final float saturationModifier;
private final boolean canAlwaysEat;
private final float eatSeconds;
private final FoodEffect[] possibleEffects;
public FoodProperties(final int nutrition, final float saturationModifier, final boolean canAlwaysEat, final float eatSeconds, final FoodEffect[] possibleEffects) {
this.nutrition = nutrition;
this.saturationModifier = saturationModifier;
this.canAlwaysEat = canAlwaysEat;
this.eatSeconds = eatSeconds;
this.possibleEffects = possibleEffects;
}
public int nutrition() {
return nutrition;
}
public float saturationModifier() {
return saturationModifier;
}
public boolean canAlwaysEat() {
return canAlwaysEat;
}
public float eatSeconds() {
return eatSeconds;
}
public FoodEffect[] possibleEffects() {
return possibleEffects;
}
}

View File

@ -25,20 +25,21 @@ package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.GlobalPosition;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class LodestoneTarget {
public final class LodestoneTracker {
public static final Type<LodestoneTarget> TYPE = new Type<LodestoneTarget>(LodestoneTarget.class) {
public static final Type<LodestoneTracker> TYPE = new Type<LodestoneTracker>(LodestoneTracker.class) {
@Override
public LodestoneTarget read(final ByteBuf buffer) throws Exception {
final GlobalPosition position = Type.GLOBAL_POSITION.read(buffer);
public LodestoneTracker read(final ByteBuf buffer) throws Exception {
final GlobalPosition position = Type.OPTIONAL_GLOBAL_POSITION.read(buffer);
final boolean tracked = buffer.readBoolean();
return new LodestoneTarget(position, tracked);
return new LodestoneTracker(position, tracked);
}
@Override
public void write(final ByteBuf buffer, final LodestoneTarget value) throws Exception {
Type.GLOBAL_POSITION.write(buffer, value.position);
public void write(final ByteBuf buffer, final LodestoneTracker value) throws Exception {
Type.OPTIONAL_GLOBAL_POSITION.write(buffer, value.position);
buffer.writeBoolean(value.tracked);
}
};
@ -46,12 +47,12 @@ public final class LodestoneTarget {
private final GlobalPosition position;
private final boolean tracked;
public LodestoneTarget(final GlobalPosition position, final boolean tracked) {
public LodestoneTracker(@Nullable final GlobalPosition position, final boolean tracked) {
this.position = position;
this.tracked = tracked;
}
public GlobalPosition pos() {
public @Nullable GlobalPosition pos() {
return this.position;
}

View File

@ -0,0 +1,75 @@
/*
* 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 io.netty.buffer.ByteBuf;
public final class PotDecorations {
public static final Type<PotDecorations> TYPE = new Type<PotDecorations>(PotDecorations.class) {
@Override
public PotDecorations read(final ByteBuf buffer) throws Exception {
return new PotDecorations(Type.VAR_INT_ARRAY_PRIMITIVE.read(buffer));
}
@Override
public void write(final ByteBuf buffer, final PotDecorations value) throws Exception {
Type.VAR_INT_ARRAY_PRIMITIVE.write(buffer, value.itemIds());
}
};
private final int[] itemIds;
public PotDecorations(final int[] itemIds) {
this.itemIds = itemIds;
}
public PotDecorations(final int backItem, final int leftItem, final int rightItem, final int frontItem) {
this.itemIds = new int[]{backItem, leftItem, rightItem, frontItem};
}
public int[] itemIds() {
return itemIds;
}
public int backItem() {
return item(0);
}
public int leftItem() {
return item(1);
}
public int rightItem() {
return item(2);
}
public int frontItem() {
return item(3);
}
private int item(final int index) {
return index < 0 || index >= itemIds.length ? -1 : itemIds[index];
}
}

View File

@ -24,7 +24,6 @@ package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -60,7 +59,7 @@ public final class PotionEffectData {
private final boolean ambient;
private final boolean showParticles;
private final boolean showIcon;
private final PotionEffectData hiddenEffect; // RECURSIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVESIVE
private final PotionEffectData hiddenEffect;
public PotionEffectData(final int amplifier, final int duration, final boolean ambient, final boolean showParticles,
final boolean showIcon, @Nullable final PotionEffectData hiddenEffect) {

View File

@ -85,11 +85,11 @@ public final class StatePropertyMatcher {
this.maxValue = maxValue;
}
public String minValue() {
public @Nullable String minValue() {
return minValue;
}
public String maxValue() {
public @Nullable String maxValue() {
return maxValue;
}
}

View File

@ -0,0 +1,68 @@
/*
* 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 io.netty.buffer.ByteBuf;
public final class ToolProperties {
public static final Type<ToolProperties> TYPE = new Type<ToolProperties>(ToolProperties.class) {
@Override
public ToolProperties read(final ByteBuf buffer) throws Exception {
final ToolRule[] rules = ToolRule.ARRAY_TYPE.read(buffer);
final float defaultMiningSpeed = buffer.readFloat();
final int damagePerBlock = Type.VAR_INT.readPrimitive(buffer);
return new ToolProperties(rules, defaultMiningSpeed, damagePerBlock);
}
@Override
public void write(final ByteBuf buffer, final ToolProperties value) throws Exception {
ToolRule.ARRAY_TYPE.write(buffer, value.rules());
buffer.writeFloat(value.defaultMiningSpeed());
Type.VAR_INT.writePrimitive(buffer, value.damagePerBlock());
}
};
private final ToolRule[] rules;
private final float defaultMiningSpeed;
private final int damagePerBlock;
public ToolProperties(final ToolRule[] rules, final float defaultMiningSpeed, final int damagePerBlock) {
this.rules = rules;
this.defaultMiningSpeed = defaultMiningSpeed;
this.damagePerBlock = damagePerBlock;
}
public ToolRule[] rules() {
return rules;
}
public float defaultMiningSpeed() {
return defaultMiningSpeed;
}
public int damagePerBlock() {
return damagePerBlock;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.HolderSet;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class ToolRule {
public static final Type<ToolRule> TYPE = new Type<ToolRule>(ToolRule.class) {
@Override
public ToolRule read(final ByteBuf buffer) throws Exception {
final HolderSet blocks = Type.HOLDER_SET.read(buffer);
final Float speed = Type.OPTIONAL_FLOAT.read(buffer);
final Boolean correctForDrops = Type.OPTIONAL_BOOLEAN.read(buffer);
return new ToolRule(blocks, speed, correctForDrops);
}
@Override
public void write(final ByteBuf buffer, final ToolRule value) throws Exception {
Type.HOLDER_SET.write(buffer, value.blocks);
Type.OPTIONAL_FLOAT.write(buffer, value.speed);
Type.OPTIONAL_BOOLEAN.write(buffer, value.correctForDrops);
}
};
public static final Type<ToolRule[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final HolderSet blocks;
private final Float speed;
private final Boolean correctForDrops;
public ToolRule(final HolderSet blocks, @Nullable final Float speed, @Nullable final Boolean correctForDrops) {
this.blocks = blocks;
this.speed = speed;
this.correctForDrops = correctForDrops;
}
public HolderSet blocks() {
return blocks;
}
public @Nullable Float speed() {
return speed;
}
public @Nullable Boolean correctForDrops() {
return correctForDrops;
}
}

View File

@ -0,0 +1,51 @@
/*
* 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 io.netty.buffer.ByteBuf;
public final class Unbreakable {
public static final Type<Unbreakable> TYPE = new Type<Unbreakable>(Unbreakable.class) {
@Override
public Unbreakable read(final ByteBuf buffer) {
return new Unbreakable(buffer.readBoolean());
}
@Override
public void write(final ByteBuf buffer, final Unbreakable value) {
buffer.writeBoolean(value.showInTooltip());
}
};
private final boolean showInTooltip;
public Unbreakable(final boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
public boolean showInTooltip() {
return showInTooltip;
}
}

View File

@ -30,31 +30,31 @@ public final class WrittenBook {
public static final Type<WrittenBook> TYPE = new Type<WrittenBook>(WrittenBook.class) {
@Override
public WrittenBook read(final ByteBuf buffer) throws Exception {
final String title = Type.STRING.read(buffer);
final FilterableString title = FilterableString.TYPE.read(buffer);
final String author = Type.STRING.read(buffer);
final int generation = Type.VAR_INT.readPrimitive(buffer);
final String[] pages = Type.STRING_ARRAY.read(buffer);
final FilterableComponent[] pages = FilterableComponent.ARRAY_TYPE.read(buffer);
final boolean resolved = buffer.readBoolean();
return new WrittenBook(title, author, generation, pages, resolved);
}
@Override
public void write(final ByteBuf buffer, final WrittenBook value) throws Exception {
Type.STRING.write(buffer, value.title);
FilterableString.TYPE.write(buffer, value.title);
Type.STRING.write(buffer, value.author);
Type.VAR_INT.writePrimitive(buffer, value.generation);
Type.STRING_ARRAY.write(buffer, value.pages);
FilterableComponent.ARRAY_TYPE.write(buffer, value.pages);
buffer.writeBoolean(value.resolved);
}
};
private final String title;
private final FilterableString title;
private final String author;
private final int generation;
private final String[] pages;
private final FilterableComponent[] pages;
private final boolean resolved;
public WrittenBook(final String title, final String author, final int generation, final String[] pages, final boolean resolved) {
public WrittenBook(final FilterableString title, final String author, final int generation, final FilterableComponent[] pages, final boolean resolved) {
this.title = title;
this.author = author;
this.generation = generation;
@ -62,7 +62,7 @@ public final class WrittenBook {
this.resolved = resolved;
}
public String title() {
public FilterableString title() {
return title;
}
@ -74,7 +74,7 @@ public final class WrittenBook {
return generation;
}
public String[] pages() {
public FilterableComponent[] pages() {
return pages;
}

View File

@ -22,8 +22,10 @@
*/
package com.viaversion.viaversion.api.minecraft.metadata.types;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.type.Type;
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_20_5;
@ -47,20 +49,23 @@ public final class MetaTypes1_20_5 extends AbstractMetaTypes {
public final MetaType optionalBlockStateType = add(15, Type.VAR_INT);
public final MetaType nbtType = add(16, Type.COMPOUND_TAG);
public final MetaType particleType;
public final MetaType villagerDatatType = add(18, Type.VILLAGER_DATA);
public final MetaType optionalVarIntType = add(19, Type.OPTIONAL_VAR_INT);
public final MetaType poseType = add(20, Type.VAR_INT);
public final MetaType catVariantType = add(21, Type.VAR_INT);
public final MetaType frogVariantType = add(22, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(23, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType paintingVariantType = add(24, Type.VAR_INT);
public final MetaType snifferState = add(25, Type.VAR_INT);
public final MetaType armadilloState = add(26, Type.VAR_INT);
public final MetaType vectorType = add(27, Type.VECTOR3F);
public final MetaType quaternionType = add(28, Type.QUATERNION);
public final MetaType particlesType;
public final MetaType villagerDatatType = add(19, Type.VILLAGER_DATA);
public final MetaType optionalVarIntType = add(20, Type.OPTIONAL_VAR_INT);
public final MetaType poseType = add(21, Type.VAR_INT);
public final MetaType catVariantType = add(22, Type.VAR_INT);
public final MetaType wolfVariantType = add(23, Type.VAR_INT);
public final MetaType frogVariantType = add(24, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(25, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType paintingVariantType = add(26, Type.VAR_INT);
public final MetaType snifferState = add(27, Type.VAR_INT);
public final MetaType armadilloState = add(28, Type.VAR_INT);
public final MetaType vectorType = add(29, Type.VECTOR3F);
public final MetaType quaternionType = add(30, Type.QUATERNION);
public MetaTypes1_20_5(final ParticleType particleType) {
super(29);
public MetaTypes1_20_5(final ParticleType particleType, final ArrayType<Particle> particlesType) {
super(31);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
}
}

View File

@ -146,6 +146,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
@Override
public void appendClientbound(final CU type, final PacketHandler handler) {
final PacketMapping mapping = clientboundMappings.mappedPacket(type.state(), type.getId());
if (mapping != null) {
@ -155,6 +156,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
@Override
public void appendServerbound(final SU type, final PacketHandler handler) {
final PacketMapping mapping = serverboundMappings.mappedPacket(type.state(), type.getId());
if (mapping != null) {

View File

@ -36,8 +36,8 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.rewriter.Rewriter;
import com.viaversion.viaversion.api.rewriter.TagRewriter;
import com.viaversion.viaversion.api.type.Type;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@ -242,6 +242,28 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
*/
boolean hasRegisteredServerbound(State state, int unmappedPacketId);
/**
* Appends a clientbound packet type handler with another, as opposed to replacing it entirely.
* <p>
* Use {@link PacketWrapper#set(Type, int, Object)} to change individual parts, or call
* {@link PacketWrapper#resetReader()} to reset the reader index.
*
* @param type clientbound packet type
* @param handler packet handler
*/
void appendClientbound(CU type, PacketHandler handler);
/**
* Appends a serverbound packet type handler with another, as opposed to replacing it entirely.
* <p>
* Use {@link PacketWrapper#set(Type, int, Object)} to change individual parts, or call
* {@link PacketWrapper#resetReader()} to reset the reader index.
*
* @param type serverbound packet type
* @param handler packet handler
*/
void appendServerbound(SU type, PacketHandler handler);
/**
* Transform a packet using this protocol
*
@ -268,7 +290,8 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
* @return object if present, else null
*/
@Deprecated
@Nullable <T> T get(Class<T> objectClass);
@Nullable
<T> T get(Class<T> objectClass);
/**
* Caches an object, retrievable by using {@link #get(Class)}.

View File

@ -49,10 +49,10 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_9 = register(107, "1.9");
public static final ProtocolVersion v1_9_1 = register(108, "1.9.1");
public static final ProtocolVersion v1_9_2 = register(109, "1.9.2");
public static final ProtocolVersion v1_9_3 = register(110, "1.9.3/1.9.4", new SubVersionRange("1.9", 3, 4));
public static final ProtocolVersion v1_9_3 = register(110, "1.9.3-1.9.4", new SubVersionRange("1.9", 3, 4));
public static final ProtocolVersion v1_10 = register(210, "1.10.x", new SubVersionRange("1.10", 0, 2));
public static final ProtocolVersion v1_11 = register(315, "1.11");
public static final ProtocolVersion v1_11_1 = register(316, "1.11.1/1.11.2", new SubVersionRange("1.11", 1, 2));
public static final ProtocolVersion v1_11_1 = register(316, "1.11.1-1.11.2", new SubVersionRange("1.11", 1, 2));
public static final ProtocolVersion v1_12 = register(335, "1.12");
public static final ProtocolVersion v1_12_1 = register(338, "1.12.1");
public static final ProtocolVersion v1_12_2 = register(340, "1.12.2");
@ -71,19 +71,19 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_16_1 = register(736, "1.16.1");
public static final ProtocolVersion v1_16_2 = register(751, "1.16.2");
public static final ProtocolVersion v1_16_3 = register(753, "1.16.3");
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/1.16.5", new SubVersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4-1.16.5", new SubVersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_17 = register(755, "1.17");
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new SubVersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18 = register(757, "1.18-1.18.1", new SubVersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18_2 = register(758, "1.18.2");
public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/1.19.2", new SubVersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1-1.19.2", new SubVersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new SubVersionRange("1.20", 0, 1));
public static final ProtocolVersion v1_20 = register(763, "1.20-1.20.1", new SubVersionRange("1.20", 0, 1));
public static final ProtocolVersion v1_20_2 = register(764, "1.20.2");
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, 178, "1.20.5");
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 unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
public static ProtocolVersion register(int version, String name) {

View File

@ -128,6 +128,7 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<long[]> LONG_ARRAY_PRIMITIVE = new LongArrayType();
public static final BooleanType BOOLEAN = new BooleanType();
public static final BooleanType.OptionalBooleanType OPTIONAL_BOOLEAN = new BooleanType.OptionalBooleanType();
/* Other Types */
public static final Type<JsonElement> COMPONENT = new ComponentType();
@ -193,6 +194,7 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final BitSetType PROFILE_ACTIONS_ENUM = new BitSetType(6);
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);
public static final Type<RegistryEntry> REGISTRY_ENTRY = new RegistryEntryType();

View File

@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.type.types;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.TypeConverter;
import io.netty.buffer.ByteBuf;
@ -49,4 +50,12 @@ public class BooleanType extends Type<Boolean> implements TypeConverter<Boolean>
}
return (Boolean) o;
}
// Lol
public static final class OptionalBooleanType extends OptionalType<Boolean> {
public OptionalBooleanType() {
super(Type.BOOLEAN);
}
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.item;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
// Very similar to normal items (and just results in an item), except it allows non-positive amounts and has id/amount swapped because ???
public final class ItemCostType1_20_5 extends Type<Item> {
private final Type<StructuredData<?>[]> dataArrayType;
public ItemCostType1_20_5(final Type<StructuredData<?>[]> dataArrayType) {
super(Item.class);
this.dataArrayType = dataArrayType;
}
@Override
public Item read(final ByteBuf buffer) throws Exception {
final int id = Type.VAR_INT.readPrimitive(buffer);
final int amount = Type.VAR_INT.readPrimitive(buffer);
final StructuredData<?>[] dataArray = dataArrayType.read(buffer);
return new StructuredItem(id, amount, new StructuredDataContainer(dataArray));
}
@Override
public void write(final ByteBuf buffer, final Item object) throws Exception {
Type.VAR_INT.writePrimitive(buffer, object.identifier());
Type.VAR_INT.writePrimitive(buffer, object.amount());
dataArrayType.write(buffer, object.structuredData().data().values().toArray(new StructuredData[0]));
}
public static final class OptionalItemCostType extends OptionalType<Item> {
public OptionalItemCostType(final Type<Item> type) {
super(type);
}
}
}

View File

@ -45,7 +45,7 @@ public class ItemType1_20_5 extends Type<Item> {
@Override
public @Nullable Item read(final ByteBuf buffer) throws Exception {
final byte amount = buffer.readByte();
final int amount = Type.VAR_INT.readPrimitive(buffer);
if (amount <= 0) {
return null;
}
@ -66,14 +66,14 @@ public class ItemType1_20_5 extends Type<Item> {
for (int i = 0; i < valuesSize; i++) {
final StructuredData<?> value = dataType.read(buffer);
final StructuredDataKey<?> key = dataType.key(value.id());
Preconditions.checkNotNull(key, "No data component serializer found for $s", value);
Preconditions.checkNotNull(key, "No data component serializer found for %s", value);
map.put(key, value);
}
for (int i = 0; i < markersSize; i++) {
final int id = Type.VAR_INT.readPrimitive(buffer);
final StructuredDataKey<?> key = dataType.key(id);
Preconditions.checkNotNull(key, "No data component serializer found for empty id $s", id);
Preconditions.checkNotNull(key, "No data component serializer found for empty id %s", id);
map.put(key, StructuredData.empty(key, id));
}
return map;
@ -82,11 +82,11 @@ public class ItemType1_20_5 extends Type<Item> {
@Override
public void write(final ByteBuf buffer, @Nullable final Item object) throws Exception {
if (object == null) {
buffer.writeByte(0);
Type.VAR_INT.writePrimitive(buffer, 0);
return;
}
buffer.writeByte(object.amount());
Type.VAR_INT.writePrimitive(buffer, object.amount());
Type.VAR_INT.writePrimitive(buffer, object.identifier());
final Map<StructuredDataKey<?>, StructuredData<?>> data = object.structuredData().data();

View File

@ -22,19 +22,18 @@
*/
package com.viaversion.viaversion.api.type.types.item;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class StructuredDataType extends Type<StructuredData<?>> {
private final Int2ObjectMap<StructuredDataKey<?>> types = new Int2ObjectOpenHashMap<>();
private StructuredDataKey<?>[] types;
public StructuredDataType() {
super(StructuredData.class);
@ -48,16 +47,17 @@ public class StructuredDataType extends Type<StructuredData<?>> {
@Override
public StructuredData<?> read(final ByteBuf buffer) throws Exception {
Preconditions.checkNotNull(types, "StructuredDataType has not been initialized");
final int id = Type.VAR_INT.readPrimitive(buffer);
final StructuredDataKey<?> key = this.types.get(id);
if (key != null) {
return readData(buffer, key, id);
final StructuredDataKey<?> key = this.types[id];
if (key == null) {
throw new IllegalArgumentException("No data component serializer found for id " + id);
}
throw new IllegalArgumentException("No data component serializer found for id " + id);
return readData(buffer, key, id);
}
public @Nullable StructuredDataKey<?> key(final int id) {
return types.get(id);
return id >= 0 && id < types.length ? types[id] : null;
}
private <T> StructuredData<T> readData(final ByteBuf buffer, final StructuredDataKey<T> key, final int id) throws Exception {
@ -65,25 +65,24 @@ public class StructuredDataType extends Type<StructuredData<?>> {
}
public DataFiller filler(final Protocol<?, ?, ?, ?> protocol) {
return filler(protocol, true);
}
public DataFiller filler(final Protocol<?, ?, ?, ?> protocol, final boolean useMappedNames) {
return new DataFiller(protocol, useMappedNames);
return new DataFiller(protocol);
}
public final class DataFiller {
private final FullMappings mappings;
private final boolean useMappedNames;
private DataFiller(final Protocol<?, ?, ?, ?> protocol, final boolean useMappedNames) {
private DataFiller(final Protocol<?, ?, ?, ?> protocol) {
this.mappings = protocol.getMappingData().getDataComponentSerializerMappings();
this.useMappedNames = useMappedNames;
Preconditions.checkArgument(mappings != null, "No mappings found for protocol %s", protocol.getClass());
Preconditions.checkArgument(types == null, "StructuredDataType has already been initialized");
types = new StructuredDataKey[mappings.mappedSize()];
}
public DataFiller add(final StructuredDataKey<?> reader) {
types.put(useMappedNames ? mappings.mappedId(reader.identifier()) : mappings.id(reader.identifier()), reader);
final int id = mappings.mappedId(reader.identifier());
Preconditions.checkArgument(id != -1, "No mapped id found for %s", reader.identifier());
types[id] = reader;
return this;
}
}

View File

@ -34,7 +34,7 @@ public final class GameProfileType extends Type<GameProfile> {
@Override
public GameProfile read(final ByteBuf buffer) throws Exception {
final String name = Type.STRING.read(buffer);
final String name = Type.OPTIONAL_STRING.read(buffer);
final java.util.UUID id = Type.OPTIONAL_UUID.read(buffer);
final int propertyCount = Type.VAR_INT.readPrimitive(buffer);
final GameProfile.Property[] properties = new GameProfile.Property[propertyCount];
@ -49,7 +49,7 @@ public final class GameProfileType extends Type<GameProfile> {
@Override
public void write(final ByteBuf buffer, final GameProfile value) throws Exception {
Type.STRING.write(buffer, value.name());
Type.OPTIONAL_STRING.write(buffer, value.name());
Type.OPTIONAL_UUID.write(buffer, value.id());
Type.VAR_INT.writePrimitive(buffer, value.properties().length);
for (final GameProfile.Property property : value.properties()) {

View File

@ -38,23 +38,23 @@ public class HolderSetType extends Type<HolderSet> {
final int size = Type.VAR_INT.readPrimitive(buffer) - 1;
if (size == -1) {
final String tag = Type.STRING.read(buffer);
return new HolderSet(tag);
return HolderSet.of(tag);
}
final int[] values = new int[size];
for (int i = 0; i < size; i++) {
values[i] = Type.VAR_INT.readPrimitive(buffer);
}
return new HolderSet(values);
return HolderSet.of(values);
}
@Override
public void write(final ByteBuf buffer, final HolderSet object) throws Exception {
if (object.isLeft()) {
if (object.hasTagKey()) {
Type.VAR_INT.writePrimitive(buffer, 0);
Type.STRING.write(buffer, object.left());
Type.STRING.write(buffer, object.tagKey());
} else {
final int[] values = object.right();
final int[] values = object.ids();
Type.VAR_INT.writePrimitive(buffer, values.length + 1);
for (final int value : values) {
Type.VAR_INT.writePrimitive(buffer, value);

View File

@ -36,9 +36,9 @@ public abstract class HolderType<T> extends Type<Holder<T>> {
public Holder<T> read(final ByteBuf buffer) throws Exception {
final int id = Type.VAR_INT.readPrimitive(buffer) - 1; // Normalize id
if (id == -1) {
return new Holder<>(readDirect(buffer));
return Holder.of(readDirect(buffer));
}
return new Holder<>(id);
return Holder.of(id);
}
@Override

View File

@ -28,6 +28,7 @@ import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.util.Key;
import io.netty.buffer.ByteBuf;
@ -70,6 +71,7 @@ public class ParticleType extends DynamicType<Particle> {
public static final DataReader<Particle> ITEM1_13 = itemHandler(Type.ITEM1_13);
public static final DataReader<Particle> ITEM1_13_2 = itemHandler(Type.ITEM1_13_2);
public static final DataReader<Particle> ITEM1_20_2 = itemHandler(Type.ITEM1_20_2);
public static final DataReader<Particle> ITEM1_20_5 = itemHandler(Types1_20_5.ITEM);
public static final DataReader<Particle> DUST = (buf, particle) -> {
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Red 0-1
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Green 0-1
@ -80,7 +82,7 @@ public class ParticleType extends DynamicType<Particle> {
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Red 0-1
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Green 0-1
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Blue 0-1
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Scale 0.01-4
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Scale 0.01-4 (moved to the end as of 24w03a / 1.20.5)
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Red
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Green
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Blue
@ -135,5 +137,6 @@ public class ParticleType extends DynamicType<Particle> {
public static final DataReader<Particle> SHRIEK = (buf, particle) -> {
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Delay
};
public static final DataReader<Particle> COLOR = (buf, particle) -> particle.add(Type.INT, buf.readInt());
}
}

View File

@ -22,11 +22,14 @@
*/
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.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaTypes1_20_5;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
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.metadata.MetaListType;
@ -34,14 +37,19 @@ import com.viaversion.viaversion.api.type.types.metadata.MetadataType;
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_20_5 {
// Most of these are only safe to use after protocol loading
public static final ParticleType PARTICLE = new ParticleType();
public static final StructuredDataType STRUCTURED_DATA = new StructuredDataType();
public static final Type<StructuredData<?>[]> STRUCTURED_DATA_ARRAY = new ArrayType<>(STRUCTURED_DATA);
public static final Type<Item> ITEM = new ItemType1_20_5(STRUCTURED_DATA);
public static final Type<Item[]> ITEM_ARRAY = new ArrayType<>(ITEM);
public static final MetaTypes1_20_5 META_TYPES = new MetaTypes1_20_5(PARTICLE);
public static final Type<Item> ITEM_COST = new ItemCostType1_20_5(STRUCTURED_DATA_ARRAY);
public static final Type<Item> OPTIONAL_ITEM_COST = new ItemCostType1_20_5.OptionalItemCostType(ITEM_COST);
public static final ParticleType PARTICLE = new ParticleType();
public static final ArrayType<Particle> PARTICLES = new ArrayType<>(PARTICLE);
public static final MetaTypes1_20_5 META_TYPES = new MetaTypes1_20_5(PARTICLE, PARTICLES);
public static final Type<Metadata> METADATA = new MetadataType(META_TYPES);
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
}

View File

@ -34,13 +34,13 @@ public final class BukkitChannelInitializer extends ChannelInitializer<Channel>
public static final String VIA_DECODER = "via-decoder";
public static final String MINECRAFT_ENCODER = "encoder";
public static final String MINECRAFT_DECODER = "decoder";
public static final String MINECRAFT_OUTBOUND_CONFIG = "outbound_config";
public static final String MINECRAFT_COMPRESSOR = "compress";
public static final String MINECRAFT_DECOMPRESSOR = "decompress";
public static final Object COMPRESSION_ENABLED_EVENT = paperCompressionEnabledEvent();
private static final Method INIT_CHANNEL_METHOD;
private final ChannelInitializer<Channel> original;
static {
try {
INIT_CHANNEL_METHOD = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
@ -80,7 +80,8 @@ public final class BukkitChannelInitializer extends ChannelInitializer<Channel>
// Add our transformers
final ChannelPipeline pipeline = channel.pipeline();
pipeline.addBefore(MINECRAFT_ENCODER, VIA_ENCODER, new BukkitEncodeHandler(connection));
final String encoderName = pipeline.get(MINECRAFT_OUTBOUND_CONFIG) != null ? MINECRAFT_OUTBOUND_CONFIG : MINECRAFT_ENCODER;
pipeline.addBefore(encoderName, VIA_ENCODER, new BukkitEncodeHandler(connection));
pipeline.addBefore(MINECRAFT_DECODER, VIA_DECODER, new BukkitDecodeHandler(connection));
}

View File

@ -1,6 +1,6 @@
name: ViaVersion
main: com.viaversion.viaversion.ViaVersionPlugin
authors: [ _MylesC, creeper123123321, Gerrygames, kennytv, Matsv ]
authors: [ _MylesC, creeper123123321, Gerrygames, kennytv, Matsv, EnZaXD, RK_01 ]
version: ${version}
description: ${description}
api-version: 1.13

View File

@ -57,7 +57,7 @@ public class BungeePlugin extends Plugin implements ViaServerProxyPlatform<Proxi
@Override
public void onLoad() {
try {
ProtocolConstants.class.getField("MINECRAFT_1_19_4");
ProtocolConstants.class.getField("MINECRAFT_1_20_5");
} catch (NoSuchFieldException e) {
getLogger().warning(" / \\");
getLogger().warning(" / \\");
@ -68,6 +68,9 @@ public class BungeePlugin extends Plugin implements ViaServerProxyPlatform<Proxi
getLogger().warning("/_____________\\");
}
getLogger().warning("ViaVersion does not work as intended across many different server versions, especially the more recent ones. " +
"Consider moving Via plugins to your backend server or switching to Velocity.");
api = new BungeeViaAPI();
config = new BungeeViaConfig(getDataFolder());
BungeeCommandHandler commandHandler = new BungeeCommandHandler();

View File

@ -1,5 +1,5 @@
name: ViaVersion
main: com.viaversion.viaversion.BungeePlugin
description: ${description}
author: _MylesC, creeper123123321, Gerrygames, kennytv, Matsv
author: _MylesC, creeper123123321, Gerrygames, kennytv, Matsv, EnZaXD, RK_01
version: ${version}

View File

@ -21,6 +21,7 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.ViaManager;
import com.viaversion.viaversion.api.configuration.ConfigurationProvider;
import com.viaversion.viaversion.api.connection.ConnectionManager;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.debug.DebugHandler;
import com.viaversion.viaversion.api.platform.PlatformTask;
import com.viaversion.viaversion.api.platform.UnsupportedSoftware;
@ -93,6 +94,8 @@ public class ViaManagerImpl implements ViaManager {
loadServerProtocol();
}
MappingDataLoader.loadGlobalIdentifiers();
// Register protocols
protocolManager.registerProtocols();
@ -231,8 +234,8 @@ public class ViaManagerImpl implements ViaManager {
}
if (version < 17) {
platform.getLogger().warning("You are running an outdated Java version, please consider updating it to at least Java 17 (your version is " + javaVersion + "). "
+ "At some point in the future, ViaVersion will no longer be compatible with this version of Java.");
platform.getLogger().warning("You are running an outdated Java version, please update it to at least Java 17 (your version is " + javaVersion + ").");
platform.getLogger().warning("Starting with Minecraft 1.21, ViaVersion will no longer officially be compatible with this version of Java, only offering unsupported compatibility builds.");
}
}

View File

@ -22,14 +22,12 @@ import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.api.minecraft.WorldIdentifiers;
import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.protocol.version.VersionType;
import com.viaversion.viaversion.protocol.BlockedProtocolVersionsImpl;
import com.viaversion.viaversion.util.Config;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -89,6 +87,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
private WorldIdentifiers map1_16WorldNames;
private boolean cache1_17Light;
private boolean translateOcelotToCat;
private boolean enforceSecureChat;
protected AbstractViaConfig(final File configFile) {
super(configFile);
@ -157,6 +156,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
worlds.getOrDefault("end", WorldIdentifiers.END_DEFAULT));
cache1_17Light = getBoolean("cache-1_17-light", true);
translateOcelotToCat = getBoolean("translate-ocelot-to-cat", true);
enforceSecureChat = getBoolean("enforce-secure-chat", false);
}
private BlockedProtocolVersions loadBlockedProtocolVersions() {
@ -528,4 +528,9 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
public boolean translateOcelotToCat() {
return translateOcelotToCat;
}
@Override
public boolean enforceSecureChat() {
return enforceSecureChat;
}
}

View File

@ -17,25 +17,31 @@
*/
package com.viaversion.viaversion.dump;
import com.viaversion.viaversion.api.protocol.version.VersionType;
import java.util.Set;
public class VersionInfo {
private final String javaVersion;
private final String operatingSystem;
private final String serverProtocol;
private final Set<String> enabledProtocols;
private final VersionType versionType;
private final int serverProtocol;
private final String serverVersion;
private final Set<String> enabledVersions;
private final String platformName;
private final String platformVersion;
private final String pluginVersion;
private final String implementationVersion;
private final Set<String> subPlatforms;
public VersionInfo(String javaVersion, String operatingSystem, String serverProtocol, Set<String> enabledProtocols,
String platformName, String platformVersion, String pluginVersion, String implementationVersion, Set<String> subPlatforms) {
public VersionInfo(String javaVersion, String operatingSystem, VersionType versionType, int serverProtocol, String serverVersion,
Set<String> enabledVersions, String platformName, String platformVersion, String pluginVersion, String implementationVersion,
Set<String> subPlatforms) {
this.javaVersion = javaVersion;
this.operatingSystem = operatingSystem;
this.serverProtocol = serverProtocol;
this.enabledProtocols = enabledProtocols;
this.versionType = versionType;
this.serverVersion = serverVersion;
this.enabledVersions = enabledVersions;
this.platformName = platformName;
this.platformVersion = platformVersion;
this.pluginVersion = pluginVersion;
@ -51,12 +57,20 @@ public class VersionInfo {
return operatingSystem;
}
public String getServerProtocol() {
public VersionType getVersionType() {
return versionType;
}
public int getServerProtocol() {
return serverProtocol;
}
public Set<String> getEnabledProtocols() {
return enabledProtocols;
public String getServerVersion() {
return serverVersion;
}
public Set<String> getEnabledVersions() {
return enabledVersions;
}
public String getPlatformName() {

View File

@ -61,8 +61,6 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter<ClientboundPacket
event.cancel();
} else if (meta.id() == 15) {
meta.setId(14);
} else if (meta.id() == 14) {
meta.setId(15);
}
});
@ -110,7 +108,7 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter<ClientboundPacket
byte data = meta.value();
// Check invisible | Check small | Check if custom name is empty | Check if custom name visible is true
if ((data & 0x20) == 0x20 && ((byte) flags.getValue() & 0x01) == 0x01
&& !((String) customName.getValue()).isEmpty() && (boolean) customNameVisible.getValue()) {
&& !((String) customName.getValue()).isEmpty() && (boolean) customNameVisible.getValue()) {
EntityTracker1_11 tracker = tracker(event.user());
int entityId = event.entityId();
if (tracker.addHologram(entityId)) {

View File

@ -52,10 +52,7 @@ public class Protocol1_13_2To1_13_1 extends AbstractProtocol<ClientboundPackets1
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN))
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.OPTIONAL_STRING); // Parent
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {

View File

@ -521,10 +521,7 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN))
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.OPTIONAL_STRING); // Parent
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {

View File

@ -155,13 +155,17 @@ public class MetadataRewriter1_14To1_13_2 extends EntityRewriter<ClientboundPack
event.cancel(); // "Is swinging arms"
});
filter().type(EntityTypes1_14.ABSTRACT_ILLAGER_BASE).index(14).handler((event, meta) -> {
EntityTracker1_14 tracker = tracker(event.user());
int entityId = event.entityId();
tracker.setInsentientData(entityId, (byte) ((tracker.getInsentientData(entityId) & ~0x4)
filter().type(EntityTypes1_14.ABSTRACT_ILLAGER_BASE).handler((event, meta) -> {
if (event.index() == 14) {
EntityTracker1_14 tracker = tracker(event.user());
int entityId = event.entityId();
tracker.setInsentientData(entityId, (byte) ((tracker.getInsentientData(entityId) & ~0x4)
| (((Number) meta.getValue()).byteValue() != 0 ? 0x4 : 0))); // New attacking
event.createExtraMeta(new Metadata(13, Types1_14.META_TYPES.byteType, tracker.getInsentientData(entityId)));
event.cancel(); // "Has target (aggressive state)"
event.createExtraMeta(new Metadata(13, Types1_14.META_TYPES.byteType, tracker.getInsentientData(entityId)));
event.cancel(); // "Has target (aggressive state)"
} else if (event.index() > 14) {
meta.setId(meta.id() - 1);
}
});
filter().type(EntityTypes1_14.OCELOT).removeIndex(17); // variant

View File

@ -246,7 +246,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_13, Serve
if (display != null) {
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
if (lore != null) {
display.put(nbtTagName("Lore"), new ListTag<>(lore.copy().getValue())); // Save old lore
display.put(nbtTagName("Lore"), lore.copy()); // Save old lore
for (StringTag loreEntry : lore) {
String jsonText = ComponentUtil.legacyToJsonString(loreEntry.getValue(), true);
loreEntry.setValue(jsonText);
@ -270,7 +270,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_13, Serve
if (lore != null) {
Tag savedLore = display.remove(nbtTagName("Lore"));
if (savedLore instanceof ListTag) {
display.put("Lore", new ListTag<>(((ListTag<?>) savedLore).getValue()));
display.put("Lore", savedLore.copy());
} else {
for (StringTag loreEntry : lore) {
loreEntry.setValue(ComponentUtil.jsonToLegacy(loreEntry.getValue()));

View File

@ -21,6 +21,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.util.TagUtil;
import java.util.HashMap;
import java.util.Map;
@ -37,7 +38,7 @@ public class MappingData extends MappingDataBase {
dimensionRegistry = MappingDataLoader.INSTANCE.loadNBTFromFile("dimension-registry-1.16.2.nbt");
// Data of each dimension
final ListTag<CompoundTag> dimensions = dimensionRegistry.getCompoundTag("minecraft:dimension_type").getListTag("value", CompoundTag.class);
final ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(dimensionRegistry, "dimension_type");
for (final CompoundTag dimension : dimensions) {
// Copy with an empty name
final CompoundTag dimensionData = dimension.getCompoundTag("element").copy();

View File

@ -20,7 +20,6 @@ package com.viaversion.viaversion.protocols.protocol1_17to1_16_4.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_16_2;
@ -35,6 +34,7 @@ import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ClientboundPac
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ClientboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_16_4;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.TagUtil;
public final class EntityPackets extends EntityRewriter<ClientboundPackets1_16_2, Protocol1_17To1_16_4> {
@ -77,8 +77,8 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_16_2
map(Type.NAMED_COMPOUND_TAG); // Current dimension
handler(wrapper -> {
// Add new dimension fields
CompoundTag dimensionRegistry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0).getCompoundTag("minecraft:dimension_type");
ListTag<CompoundTag> dimensions = dimensionRegistry.getListTag("value", CompoundTag.class);
CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(registry, "dimension_type");
for (CompoundTag dimension : dimensions) {
CompoundTag dimensionCompound = dimension.getCompoundTag("element");
addNewDimensionData(dimensionCompound);

View File

@ -28,10 +28,10 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.TagUtil;
public final class Protocol1_18_2To1_18 extends AbstractProtocol<ClientboundPackets1_18, ClientboundPackets1_18, ServerboundPackets1_17, ServerboundPackets1_17> {
public Protocol1_18_2To1_18() {
super(ClientboundPackets1_18.class, ClientboundPackets1_18.class, ServerboundPackets1_17.class, ServerboundPackets1_17.class);
}
@ -70,8 +70,7 @@ public final class Protocol1_18_2To1_18 extends AbstractProtocol<ClientboundPack
map(Type.NAMED_COMPOUND_TAG); // Current dimension data
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final CompoundTag dimensionsHolder = registry.getCompoundTag("minecraft:dimension_type");
final ListTag<CompoundTag> dimensions = dimensionsHolder.getListTag("value", CompoundTag.class);
final ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(registry, "dimension_type");
for (final CompoundTag dimension : dimensions) {
addTagPrefix(dimension.getCompoundTag("element"));
}

View File

@ -45,6 +45,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.util.CipherUtil;
import com.viaversion.viaversion.util.Pair;
import com.viaversion.viaversion.util.TagUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -189,7 +190,7 @@ public final class Protocol1_19_1To1_19 extends AbstractProtocol<ClientboundPack
chatTypeStorage.clear();
final CompoundTag registry = wrapper.passthrough(Type.NAMED_COMPOUND_TAG);
final ListTag<CompoundTag> chatTypes = registry.getCompoundTag("minecraft:chat_type").getListTag("value", CompoundTag.class);
final ListTag<CompoundTag> chatTypes = TagUtil.getRegistryEntries(registry, "chat_type");
for (final CompoundTag chatType : chatTypes) {
final NumberTag idTag = chatType.getNumberTag("id");
chatTypeStorage.addChatType(idTag.asInt(), chatType);
@ -207,7 +208,7 @@ public final class Protocol1_19_1To1_19 extends AbstractProtocol<ClientboundPack
map(Type.OPTIONAL_COMPONENT); // Motd
map(Type.OPTIONAL_STRING); // Encoded icon
map(Type.BOOLEAN); // Previews chat
create(Type.BOOLEAN, false); // Enforces secure chat
create(Type.BOOLEAN, Via.getConfig().enforceSecureChat()); // Enforces secure chat
}
});

View File

@ -62,7 +62,6 @@ import java.util.concurrent.ThreadLocalRandom;
public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPackets1_19_1, ClientboundPackets1_19_3, ServerboundPackets1_19_1, ServerboundPackets1_19_3> {
public static final MappingData MAPPINGS = new MappingDataBase("1.19", "1.19.3");
private static final BitSetType ACKNOWLEDGED_BIT_SET_TYPE = new BitSetType(20);
private static final UUID ZERO_UUID = new UUID(0, 0);
private static final byte[] EMPTY_BYTES = new byte[0];
private final EntityPackets entityRewriter = new EntityPackets(this);
@ -95,13 +94,13 @@ public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPa
return;
}
wrapper.write(Type.SOUND_EVENT, new Holder<>(soundId));
wrapper.write(Type.SOUND_EVENT, Holder.of(soundId));
};
registerClientbound(ClientboundPackets1_19_1.ENTITY_SOUND, soundHandler);
registerClientbound(ClientboundPackets1_19_1.SOUND, soundHandler);
registerClientbound(ClientboundPackets1_19_1.NAMED_SOUND, ClientboundPackets1_19_3.SOUND, wrapper -> {
final String soundIdentifier = wrapper.read(Type.STRING);
wrapper.write(Type.SOUND_EVENT, new Holder<>(new SoundEvent(soundIdentifier, null)));
wrapper.write(Type.SOUND_EVENT, Holder.of(new SoundEvent(soundIdentifier, null)));
});
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_1.STATISTICS);
@ -246,7 +245,7 @@ public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPa
wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); // No last unacknowledged
});
read(Type.VAR_INT); // Offset
read(ACKNOWLEDGED_BIT_SET_TYPE); // Acknowledged
read(Type.ACKNOWLEDGED_BIT_SET); // Acknowledged
}
});
registerServerbound(ServerboundPackets1_19_3.CHAT_MESSAGE, new PacketHandlers() {
@ -282,7 +281,7 @@ public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPa
wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); // No last unacknowledged
});
read(Type.VAR_INT); // Offset
read(ACKNOWLEDGED_BIT_SET_TYPE); // Acknowledged
read(Type.ACKNOWLEDGED_BIT_SET); // Acknowledged
}
});

View File

@ -60,4 +60,11 @@ public final class ReceivedMessagesStorage implements StorableObject {
public void resetUnacknowledgedCount() {
unacknowledged = 0;
}
public void clear() {
this.size = 0;
this.unacknowledged = 0;
this.lastSignature = null;
Arrays.fill(this.signatures, null);
}
}

View File

@ -21,7 +21,6 @@ import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_19_4;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
@ -34,6 +33,7 @@ import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPac
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.Protocol1_19_4To1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.storage.PlayerVehicleTracker;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.TagUtil;
public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3, Protocol1_19_4To1_19_3> {
@ -63,8 +63,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
final CompoundTag damageTypeRegistry = protocol.getMappingData().damageTypesRegistry();
registry.put("minecraft:damage_type", damageTypeRegistry);
final CompoundTag biomeRegistry = registry.getCompoundTag("minecraft:worldgen/biome");
final ListTag<CompoundTag> biomes = biomeRegistry.getListTag("value", CompoundTag.class);
final ListTag<CompoundTag> biomes = TagUtil.getRegistryEntries(registry, "worldgen/biome");
for (final CompoundTag biomeTag : biomes) {
final CompoundTag biomeData = biomeTag.getCompoundTag("element");
final StringTag precipitation = biomeData.getStringTag("precipitation");
@ -227,7 +226,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
@Override
protected void registerRewrites() {
filter().mapMetaType(typeId -> Types1_19_4.META_TYPES.byId(typeId >= 14 ? typeId + 1 : typeId)); // Optional block state (and map block state=14 to optional block state)
registerMetaTypeHandler(Types1_19_4.META_TYPES.itemType, Types1_19_4.META_TYPES.blockStateType, Types1_19_4.META_TYPES.optionalBlockStateType, Types1_19_4.META_TYPES.particleType);
registerMetaTypeHandler(Types1_19_4.META_TYPES.itemType, Types1_19_4.META_TYPES.blockStateType, Types1_19_4.META_TYPES.optionalBlockStateType, Types1_19_4.META_TYPES.particleType, null);
filter().type(EntityTypes1_19_4.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value();

View File

@ -44,6 +44,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.Dimensio
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import com.viaversion.viaversion.util.TagUtil;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
@ -178,7 +179,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_18,
tag.put("minecraft:chat_type", protocol.getMappingData().chatRegistry());
// Cache a whole lot of data
final ListTag<CompoundTag> dimensions = tag.getCompoundTag("minecraft:dimension_type").getListTag("value", CompoundTag.class);
final ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(tag, "dimension_type");
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(dimensions.size());
final Map<CompoundTag, String> dimensionsMap = new HashMap<>(dimensions.size());
for (final CompoundTag dimension : dimensions) {

View File

@ -42,7 +42,7 @@ import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPac
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.util.PotionEffects;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.util.PotionEffects1_20_2;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.util.MathUtil;
@ -144,10 +144,7 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
final int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN))
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.OPTIONAL_STRING); // Parent
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {
@ -384,7 +381,8 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
final CompoundTag effectTag = (CompoundTag) tag;
final Tag idTag = effectTag.remove("Id");
if (idTag instanceof NumberTag) {
final String key = PotionEffects.idToKey(((NumberTag) idTag).asInt());
// Empty effect removed
final String key = PotionEffects1_20_2.idToKey(((NumberTag) idTag).asInt() - 1);
if (key != null) {
effectTag.put("id", new StringTag(key));
}
@ -415,8 +413,8 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
final CompoundTag effectTag = (CompoundTag) tag;
final Tag idTag = effectTag.remove("id");
if (idTag instanceof StringTag) {
final int id = PotionEffects.keyToId(((StringTag) idTag).getValue());
effectTag.put("Id", new IntTag(id));
final int id = PotionEffects1_20_2.keyToId(((StringTag) idTag).getValue());
effectTag.putInt("Id", id + 1); // Account for empty effect at id 0
}
renameTag(effectTag, "amplifier", "Amplifier");
@ -444,12 +442,12 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
final Tag primaryEffect = tag.remove("Primary");
if (primaryEffect instanceof NumberTag && ((NumberTag) primaryEffect).asInt() != 0) {
tag.put("primary_effect", new StringTag(PotionEffects.idToKeyOrLuck(((NumberTag) primaryEffect).asInt())));
tag.put("primary_effect", new StringTag(PotionEffects1_20_2.idToKeyOrLuck(((NumberTag) primaryEffect).asInt() - 1)));
}
final Tag secondaryEffect = tag.remove("Secondary");
if (secondaryEffect instanceof NumberTag && ((NumberTag) secondaryEffect).asInt() != 0) {
tag.put("secondary_effect", new StringTag(PotionEffects.idToKeyOrLuck(((NumberTag) secondaryEffect).asInt())));
tag.put("secondary_effect", new StringTag(PotionEffects1_20_2.idToKeyOrLuck(((NumberTag) secondaryEffect).asInt() - 1)));
}
return tag;
}

View File

@ -173,7 +173,7 @@ public final class EntityPacketRewriter1_20_2 extends EntityRewriter<Clientbound
@Override
protected void registerRewrites() {
filter().mapMetaType(Types1_20_2.META_TYPES::byId);
registerMetaTypeHandler(Types1_20_2.META_TYPES.itemType, Types1_20_2.META_TYPES.blockStateType, Types1_20_2.META_TYPES.optionalBlockStateType, Types1_20_2.META_TYPES.particleType);
registerMetaTypeHandler(Types1_20_2.META_TYPES.itemType, Types1_20_2.META_TYPES.blockStateType, Types1_20_2.META_TYPES.optionalBlockStateType, Types1_20_2.META_TYPES.particleType, null);
filter().type(EntityTypes1_19_4.DISPLAY).addIndex(10);

View File

@ -22,11 +22,10 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class PotionEffects {
public final class PotionEffects1_20_2 {
private static final Object2IntMap<String> KEY_TO_ID = new Object2IntOpenHashMap<>();
private static final String[] POTION_EFFECTS = {
"", // No effect
"speed",
"slowness",
"haste",
@ -63,18 +62,19 @@ public final class PotionEffects {
};
static {
for (int i = 1; i < POTION_EFFECTS.length; i++) {
for (int i = 0; i < POTION_EFFECTS.length; i++) {
final String effect = POTION_EFFECTS[i];
KEY_TO_ID.put(effect, i);
}
KEY_TO_ID.defaultReturnValue(-1);
}
public static @Nullable String idToKey(final int id) {
return id >= 1 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : null;
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : null;
}
public static String idToKeyOrLuck(final int id) {
return id >= 1 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
}
public static int keyToId(final String key) {

View File

@ -128,11 +128,7 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
final int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.STRING);
}
wrapper.passthrough(Type.OPTIONAL_STRING); // Parent
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {

View File

@ -148,7 +148,7 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
final CompoundTag tag = item.tag();
if (tag != null && item.identifier() == 1047) { // Written book
updatePages(tag, "pages");
updatePages(tag, "filtered_pages");
updatePages(tag, "filtered_pages"); // TODO This isn't a list
}
return super.handleItemToClient(connection, item);
}

View File

@ -133,8 +133,8 @@ public final class EntityPacketRewriter1_20_3 extends EntityRewriter<Clientbound
Types1_20_3.META_TYPES.itemType,
Types1_20_3.META_TYPES.blockStateType,
Types1_20_3.META_TYPES.optionalBlockStateType,
Types1_20_3.META_TYPES.particleType
);
Types1_20_3.META_TYPES.particleType,
null);
filter().type(EntityTypes1_20_3.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value();

View File

@ -18,12 +18,12 @@
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3;
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.ProfileKey;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
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;
@ -33,12 +33,14 @@ import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.CommandRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MappingData;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPacket1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPackets1_20_5;
@ -46,19 +48,27 @@ import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.Serverb
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.rewriter.BlockItemPacketRewriter1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.rewriter.ComponentRewriter1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.rewriter.EntityPacketRewriter1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.storage.AcknowledgedMessagesStorage;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import java.util.UUID;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPacket1_20_3, ClientboundPacket1_20_5, ServerboundPacket1_20_3, ServerboundPacket1_20_5> {
public static final MappingData MAPPINGS = new MappingDataBase("1.20.3", "1.20.5");
public static final MappingData MAPPINGS = new MappingData();
// Mojang will remove this in the next release, so if we were to set this to false,
// people would miss the changes and not fix their plugins before forcefully running into the errors then
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 TagRewriter<ClientboundPacket1_20_3> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter<ClientboundPacket1_20_3> componentRewriter = new ComponentRewriter1_20_5(this);
public Protocol1_20_5To1_20_3() {
super(ClientboundPacket1_20_3.class, ClientboundPacket1_20_5.class, ServerboundPacket1_20_3.class, ServerboundPacket1_20_5.class);
@ -77,6 +87,10 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
new StatisticsRewriter<>(this).register(ClientboundPackets1_20_3.STATISTICS);
componentRewriter.registerComponentPacket(ClientboundPackets1_20_3.SYSTEM_CHAT);
componentRewriter.registerComponentPacket(ClientboundPackets1_20_3.DISGUISED_CHAT);
componentRewriter.registerCombatKill1_20(ClientboundPackets1_20_3.COMBAT_KILL);
registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO, wrapper -> {
wrapper.passthrough(Type.STRING); // Server ID
wrapper.passthrough(Type.BYTE_ARRAY_PRIMITIVE); // Public key
@ -87,7 +101,125 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
registerClientbound(ClientboundPackets1_20_3.SERVER_DATA, wrapper -> {
wrapper.passthrough(Type.TAG); // MOTD
wrapper.passthrough(Type.OPTIONAL_BYTE_ARRAY_PRIMITIVE); // Icon
wrapper.read(Type.BOOLEAN); // Enforces secure chat - moved to join game
// Moved to join game
final boolean enforcesSecureChat = wrapper.read(Type.BOOLEAN);
final AcknowledgedMessagesStorage storage = wrapper.user().get(AcknowledgedMessagesStorage.class);
storage.setSecureChatEnforced(enforcesSecureChat);
if (enforcesSecureChat) {
// Only send the chat session to the server if we know that it is required
storage.sendQueuedChatSession(wrapper);
}
});
// Big problem with this update: Without access to the client, this cannot 100% predict the
// correct offset. This means we have to entirely discard client acknowledgements and fake them.
registerClientbound(ClientboundPackets1_20_3.PLAYER_CHAT, wrapper -> {
wrapper.passthrough(Type.UUID); // Sender
wrapper.passthrough(Type.VAR_INT); // Index
final byte[] signature = wrapper.passthrough(Type.OPTIONAL_SIGNATURE_BYTES);
if (signature == null) {
return;
}
// Mimic client behavior for acknowledgements
final AcknowledgedMessagesStorage storage = wrapper.user().get(AcknowledgedMessagesStorage.class);
if (storage.add(signature) && storage.offset() > 64) {
final PacketWrapper chatAck = wrapper.create(ServerboundPackets1_20_3.CHAT_ACK);
chatAck.write(Type.VAR_INT, storage.offset());
chatAck.sendToServer(Protocol1_20_5To1_20_3.class);
storage.clearOffset();
}
});
registerServerbound(ServerboundPackets1_20_5.CHAT_MESSAGE, wrapper -> {
wrapper.passthrough(Type.STRING); // Message
wrapper.passthrough(Type.LONG); // Timestamp
final AcknowledgedMessagesStorage storage = wrapper.user().get(AcknowledgedMessagesStorage.class);
final long salt = wrapper.read(Type.LONG);
final byte[] signature = wrapper.read(Type.OPTIONAL_SIGNATURE_BYTES);
if (storage.isSecureChatEnforced()) {
// Fake it till you make it
wrapper.write(Type.LONG, salt);
wrapper.write(Type.OPTIONAL_SIGNATURE_BYTES, signature);
} else {
// Go the safer route and strip the signature. No signature means no verification
wrapper.write(Type.LONG, 0L);
wrapper.write(Type.OPTIONAL_SIGNATURE_BYTES, null);
}
replaceChatAck(wrapper, storage);
});
registerServerbound(ServerboundPackets1_20_5.CHAT_COMMAND_SIGNED, ServerboundPackets1_20_3.CHAT_COMMAND, wrapper -> {
wrapper.passthrough(Type.STRING); // Command
wrapper.passthrough(Type.LONG); // Timestamp
// See above, strip signatures if we can to prevent verification of possibly bad signatures
final AcknowledgedMessagesStorage storage = wrapper.user().get(AcknowledgedMessagesStorage.class);
final long salt = wrapper.read(Type.LONG);
final int signatures = wrapper.read(Type.VAR_INT);
if (storage.isSecureChatEnforced()) {
wrapper.write(Type.LONG, salt);
wrapper.write(Type.VAR_INT, signatures);
for (int i = 0; i < signatures; i++) {
wrapper.passthrough(Type.STRING); // Argument name
wrapper.passthrough(Type.SIGNATURE_BYTES); // Signature
}
} else {
// Remove signatures
wrapper.write(Type.LONG, 0L);
wrapper.write(Type.VAR_INT, 0); // No signatures
for (int i = 0; i < signatures; i++) {
wrapper.read(Type.STRING); // Argument name
wrapper.read(Type.SIGNATURE_BYTES); // Signature
}
}
replaceChatAck(wrapper, storage);
});
registerServerbound(ServerboundPackets1_20_5.CHAT_COMMAND, wrapper -> {
wrapper.passthrough(Type.STRING); // Command
wrapper.write(Type.LONG, System.currentTimeMillis()); // Timestamp
wrapper.write(Type.LONG, 0L); // Salt
wrapper.write(Type.VAR_INT, 0); // No signatures
writeChatAck(wrapper, wrapper.user().get(AcknowledgedMessagesStorage.class));
});
registerServerbound(ServerboundPackets1_20_5.CHAT_SESSION_UPDATE, wrapper -> {
// Delay this until we know whether the server enforces secure chat
// The server sends this info in SERVER_DATA, but the client already sends this after receiving the game login
final AcknowledgedMessagesStorage storage = wrapper.user().get(AcknowledgedMessagesStorage.class);
if (storage.secureChatEnforced() != null && storage.secureChatEnforced()) {
// We already know that secure chat is enforced, let it through
return;
}
final UUID sessionId = wrapper.read(Type.UUID);
final ProfileKey profileKey = wrapper.read(Type.PROFILE_KEY);
storage.queueChatSession(sessionId, profileKey);
wrapper.cancel();
});
cancelServerbound(ServerboundPackets1_20_5.CHAT_ACK);
registerClientbound(ClientboundPackets1_20_3.START_CONFIGURATION, wrapper -> wrapper.user().put(new AcknowledgedMessagesStorage()));
new CommandRewriter1_19_4<>(this).registerDeclareCommands1_19(ClientboundPackets1_20_3.DECLARE_COMMANDS);
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
wrapper.passthrough(Type.UUID); // UUID
wrapper.passthrough(Type.STRING); // Name
final int properties = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < properties; i++) {
wrapper.passthrough(Type.STRING); // Name
wrapper.passthrough(Type.STRING); // Value
wrapper.passthrough(Type.OPTIONAL_STRING); // Signature
}
wrapper.write(Type.BOOLEAN, strictErrorHandling);
});
cancelServerbound(State.LOGIN, ServerboundLoginPackets.COOKIE_RESPONSE.getId());
@ -97,6 +229,18 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
cancelServerbound(ServerboundPackets1_20_5.DEBUG_SAMPLE_SUBSCRIPTION);
}
private void replaceChatAck(final PacketWrapper wrapper, final AcknowledgedMessagesStorage storage) throws Exception {
wrapper.read(Type.VAR_INT); // Offset
wrapper.read(Type.ACKNOWLEDGED_BIT_SET); // Acknowledged
writeChatAck(wrapper, storage);
}
private void writeChatAck(final PacketWrapper wrapper, final AcknowledgedMessagesStorage storage) {
wrapper.write(Type.VAR_INT, storage.offset());
wrapper.write(Type.ACKNOWLEDGED_BIT_SET, storage.toAck());
storage.clearOffset();
}
@Override
protected void onMappingDataLoaded() {
super.onMappingDataLoaded();
@ -106,60 +250,34 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("dust_pillar", ParticleType.Readers.BLOCK)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.ITEM1_20_2)
.reader("item", ParticleType.Readers.ITEM1_20_5)
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
.reader("shriek", ParticleType.Readers.SHRIEK)
.reader("entity_effect", ParticleType.Readers.COLOR);
Types1_20_5.STRUCTURED_DATA.filler(this)
.add(StructuredDataKey.CUSTOM_DATA)
.add(StructuredDataKey.DAMAGE)
.add(StructuredDataKey.UNBREAKABLE)
.add(StructuredDataKey.CUSTOM_NAME)
.add(StructuredDataKey.LORE)
.add(StructuredDataKey.ENCHANTMENTS)
.add(StructuredDataKey.CAN_PLACE_ON)
.add(StructuredDataKey.CAN_BREAK)
.add(StructuredDataKey.ATTRIBUTE_MODIFIERS)
.add(StructuredDataKey.CUSTOM_MODEL_DATA)
.add(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP)
.add(StructuredDataKey.REPAIR_COST)
.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_PROJECTILES)
.add(StructuredDataKey.BUNDLE_CONTENTS)
.add(StructuredDataKey.POTION_CONTENTS)
.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.RECIPES)
.add(StructuredDataKey.LODESTONE_TARGET)
.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)
.add(StructuredDataKey.CONTAINER)
.add(StructuredDataKey.BLOCK_STATE)
.add(StructuredDataKey.BEES)
.add(StructuredDataKey.LOCK)
.add(StructuredDataKey.CONTAINER_LOOT);
.add(StructuredDataKey.CUSTOM_DATA).add(StructuredDataKey.MAX_STACK_SIZE).add(StructuredDataKey.MAX_DAMAGE)
.add(StructuredDataKey.DAMAGE).add(StructuredDataKey.UNBREAKABLE).add(StructuredDataKey.RARITY)
.add(StructuredDataKey.HIDE_TOOLTIP).add(StructuredDataKey.FOOD).add(StructuredDataKey.FIRE_RESISTANT)
.add(StructuredDataKey.CUSTOM_NAME).add(StructuredDataKey.LORE).add(StructuredDataKey.ENCHANTMENTS)
.add(StructuredDataKey.CAN_PLACE_ON).add(StructuredDataKey.CAN_BREAK).add(StructuredDataKey.ATTRIBUTE_MODIFIERS)
.add(StructuredDataKey.CUSTOM_MODEL_DATA).add(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP).add(StructuredDataKey.REPAIR_COST)
.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_PROJECTILES).add(StructuredDataKey.BUNDLE_CONTENTS).add(StructuredDataKey.POTION_CONTENTS)
.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.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)
.add(StructuredDataKey.CONTAINER).add(StructuredDataKey.BLOCK_STATE).add(StructuredDataKey.BEES)
.add(StructuredDataKey.LOCK).add(StructuredDataKey.CONTAINER_LOOT).add(StructuredDataKey.TOOL)
.add(StructuredDataKey.ITEM_NAME).add(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER);
tagRewriter.addTag(RegistryType.ITEM, "minecraft:dyeable", 853, 854, 855, 856, 1120);
}
@ -167,6 +285,7 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_20_5.PLAYER));
connection.put(new AcknowledgedMessagesStorage());
}
@Override
@ -189,6 +308,10 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
return tagRewriter;
}
public ComponentRewriter<ClientboundPacket1_20_3> getComponentRewriter() {
return componentRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_20_3, ClientboundPacket1_20_5, ServerboundPacket1_20_3, ServerboundPacket1_20_5> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(

View File

@ -0,0 +1,43 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class ArmorMaterials1_20_5 {
private static final KeyMappings MATERIALS = new KeyMappings(
"leather",
"chainmail",
"iron",
"gold",
"diamond",
"turtle",
"netherite",
"armadillo"
);
public static @Nullable String idToKey(final int id) {
return MATERIALS.idToKey(id);
}
public static int keyToId(final String material) {
return MATERIALS.keyToId(material);
}
}

View File

@ -1,60 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.protocol1_20_5to1_20_3.data;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* String to/from int ID mappings for 1.20.3 attributes.
*/
public final class AttributeMappings {
private static final String[] ATTRIBUTES = {
"generic.armor",
"generic.armor_toughness",
"generic.attack_damage",
"generic.attack_knockback",
"generic.attack_speed",
"generic.flying_speed",
"generic.follow_range",
"horse.jump_strength",
"generic.knockback_resistance",
"generic.luck",
"generic.max_absorption",
"generic.max_health",
"generic.movement_speed",
"zombie.spawn_reinforcements"
};
private static final Object2IntMap<String> STRING_TO_ID = new Object2IntOpenHashMap<>();
static {
for (int i = 0; i < ATTRIBUTES.length; i++) {
STRING_TO_ID.put(ATTRIBUTES[i], i);
}
}
public static @Nullable String attribute(final int id) {
return id >= 0 && id < ATTRIBUTES.length ? ATTRIBUTES[id] : null;
}
public static int id(final String attribute) {
return STRING_TO_ID.getOrDefault(attribute, -1);
}
}

View File

@ -0,0 +1,61 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class Attributes1_20_5 {
private static final KeyMappings ATTRIBUTES = new KeyMappings(
"generic.armor",
"generic.armor_toughness",
"generic.attack_damage",
"generic.attack_knockback",
"generic.attack_speed",
"player.block_break_speed",
"player.block_interaction_range",
"player.entity_interaction_range",
"generic.fall_damage_multiplier",
"generic.flying_speed",
"generic.follow_range",
"generic.gravity",
"generic.jump_strength",
"generic.knockback_resistance",
"generic.luck",
"generic.max_absorption",
"generic.max_health",
"generic.movement_speed",
"generic.safe_fall_distance",
"generic.scale",
"zombie.spawn_reinforcements",
"generic.step_height"
);
public static @Nullable String idToKey(final int id) {
return ATTRIBUTES.idToKey(id);
}
public static int keyToId(String attribute) {
if (Key.stripMinecraftNamespace(attribute).equals("horse.jump_strength")) {
attribute = "generic.jump_strength";
}
return ATTRIBUTES.keyToId(attribute);
}
}

View File

@ -0,0 +1,142 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class BannerPatterns1_20_5 {
private static final KeyMappings PATTERNS = new KeyMappings(
"base",
"square_bottom_left",
"square_bottom_right",
"square_top_left",
"square_top_right",
"stripe_bottom",
"stripe_top",
"stripe_left",
"stripe_right",
"stripe_center",
"stripe_middle",
"stripe_downright",
"stripe_downleft",
"small_stripes",
"cross",
"straight_cross",
"triangle_bottom",
"triangle_top",
"triangles_bottom",
"triangles_top",
"diagonal_left",
"diagonal_up_right",
"diagonal_up_left",
"diagonal_right",
"circle",
"rhombus",
"half_vertical",
"half_horizontal",
"half_vertical_right",
"half_horizontal_bottom",
"border",
"curly_border",
"gradient",
"gradient_up",
"bricks",
"globe",
"creeper",
"skull",
"flower",
"mojang",
"piglin",
"flow",
"guster"
);
private static final Map<String, String> PATTERN_IDS = new HashMap<>();
static {
PATTERN_IDS.put("b", "base");
PATTERN_IDS.put("bl", "square_bottom_left");
PATTERN_IDS.put("br", "square_bottom_right");
PATTERN_IDS.put("tl", "square_top_left");
PATTERN_IDS.put("tr", "square_top_right");
PATTERN_IDS.put("bs", "stripe_bottom");
PATTERN_IDS.put("ts", "stripe_top");
PATTERN_IDS.put("ls", "stripe_left");
PATTERN_IDS.put("rs", "stripe_right");
PATTERN_IDS.put("cs", "stripe_center");
PATTERN_IDS.put("ms", "stripe_middle");
PATTERN_IDS.put("drs", "stripe_downright");
PATTERN_IDS.put("dls", "stripe_downleft");
PATTERN_IDS.put("ss", "small_stripes");
PATTERN_IDS.put("cr", "cross");
PATTERN_IDS.put("sc", "straight_cross");
PATTERN_IDS.put("bt", "triangle_bottom");
PATTERN_IDS.put("tt", "triangle_top");
PATTERN_IDS.put("bts", "triangles_bottom");
PATTERN_IDS.put("tts", "triangles_top");
PATTERN_IDS.put("ld", "diagonal_left");
PATTERN_IDS.put("rd", "diagonal_up_right");
PATTERN_IDS.put("lud", "diagonal_up_left");
PATTERN_IDS.put("rud", "diagonal_right");
PATTERN_IDS.put("mc", "circle");
PATTERN_IDS.put("mr", "rhombus");
PATTERN_IDS.put("vh", "half_vertical");
PATTERN_IDS.put("hh", "half_horizontal");
PATTERN_IDS.put("vhr", "half_vertical_right");
PATTERN_IDS.put("hhb", "half_horizontal_bottom");
PATTERN_IDS.put("bo", "border");
PATTERN_IDS.put("cbo", "curly_border");
PATTERN_IDS.put("gra", "gradient");
PATTERN_IDS.put("gru", "gradient_up");
PATTERN_IDS.put("bri", "bricks");
PATTERN_IDS.put("glb", "globe");
PATTERN_IDS.put("cre", "creeper");
PATTERN_IDS.put("sku", "skull");
PATTERN_IDS.put("flo", "flower");
PATTERN_IDS.put("moj", "mojang");
PATTERN_IDS.put("pig", "piglin");
}
public static @Nullable String idToKey(final int id) {
return PATTERNS.idToKey(id);
}
public static int keyToId(final String pattern) {
return PATTERNS.keyToId(pattern);
}
public static @Nullable String compactToFullId(final String compactId) {
return PATTERN_IDS.get(compactId);
}
public static @Nullable String fullIdToCompact(final String fullId) {
for (Map.Entry<String, String> entry : PATTERN_IDS.entrySet()) {
if (entry.getValue().equals(fullId)) {
return entry.getKey();
}
}
return null;
}
public static String[] keys() {
return PATTERNS.keys();
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.protocol1_20_5to1_20_3.data;
public final class DyeColors {
public static String colorById(final int id) {
switch (id) {
case 1:
return "orange";
case 2:
return "magenta";
case 3:
return "light_blue";
case 4:
return "yellow";
case 5:
return "lime";
case 6:
return "pink";
case 7:
return "gray";
case 8:
return "light_gray";
case 9:
return "cyan";
case 10:
return "purple";
case 11:
return "blue";
case 12:
return "brown";
case 13:
return "green";
case 14:
return "red";
case 15:
return "black";
default:
return "white";
}
}
}

View File

@ -17,14 +17,12 @@
*/
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class EnchantmentMappings {
public final class Enchantments1_20_5 {
public static final String[] ENCHANTMENTS = {
public static final KeyMappings ENCHANTMENTS = new KeyMappings(
"protection",
"fire_protection",
"feather_falling",
@ -44,7 +42,7 @@ public final class EnchantmentMappings {
"knockback",
"fire_aspect",
"looting",
"sweeping",
"sweeping_edge",
"efficiency",
"silk_touch",
"unbreaking",
@ -62,22 +60,18 @@ public final class EnchantmentMappings {
"multishot",
"quick_charge",
"piercing",
"density",
"breach",
"wind_burst",
"mending",
"vanishing_curse"
};
private static final Object2IntMap<String> STRING_TO_ID = new Object2IntOpenHashMap<>();
);
static {
for (int i = 0; i < ENCHANTMENTS.length; i++) {
STRING_TO_ID.put(ENCHANTMENTS[i], i);
}
public static @Nullable String idToKey(final int id) {
return ENCHANTMENTS.idToKey(id);
}
public static @Nullable String enchantment(final int id) {
return id >= 0 && id < ENCHANTMENTS.length ? ENCHANTMENTS[id] : null;
}
public static int id(final String attribute) {
return STRING_TO_ID.getOrDefault(Key.stripMinecraftNamespace(attribute), -1);
public static int keyToId(final String enchantment) {
return ENCHANTMENTS.keyToId(enchantment);
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class EquipmentSlots1_20_5 {
public static final KeyMappings SLOTS = new KeyMappings(
"any",
"mainhand",
"offhand",
"hand",
"feet",
"legs",
"chest",
"head",
"armor",
"body"
);
public static @Nullable String idToKey(final int id) {
return SLOTS.idToKey(id);
}
public static int keyToId(final String enchantment) {
return SLOTS.keyToId(enchantment);
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
// Same as 1.20.5
public final class Instruments1_20_3 {
private static final KeyMappings MAPPINGS = new KeyMappings(
"ponder_goat_horn",
"sing_goat_horn",
"seek_goat_horn",
"feel_goat_horn",
"admire_goat_horn",
"call_goat_horn",
"yearn_goat_horn",
"dream_goat_horn"
);
public static @Nullable String idToKey(final int id) {
return MAPPINGS.idToKey(id);
}
public static int keyToId(final String name) {
return MAPPINGS.keyToId(name);
}
}

View File

@ -17,9 +17,11 @@
*/
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
public final class MapDecorationMappings {
import com.viaversion.viaversion.util.KeyMappings;
private static final String[] MAP_DECORATIONS = {
public final class MapDecorations1_20_5 {
private static final KeyMappings MAP_DECORATIONS = new KeyMappings(
"player",
"frame",
"red_marker",
@ -53,10 +55,15 @@ public final class MapDecorationMappings {
"village_snowy",
"village_taiga",
"jungle_temple",
"swamp_hut"
};
"swamp_hut",
"trial_chambers"
);
public static String mapDecoration(final int index) {
return index < 0 || index >= MAP_DECORATIONS.length ? "player" : MAP_DECORATIONS[index];
public static String idToKey(final int index) {
return index < 0 || index >= MAP_DECORATIONS.size() ? "player" : MAP_DECORATIONS.idToKey(index);
}
public static int keyToId(final String key) {
return MAP_DECORATIONS.keyToId(key);
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.protocol1_20_5to1_20_3.data;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MappingData extends MappingDataBase {
private KeyMappings blocks;
private KeyMappings sounds;
public MappingData() {
super("1.20.3", "1.20.5");
}
@Override
protected void loadExtras(final CompoundTag data) {
super.loadExtras(data);
final CompoundTag extraMappings = MappingDataLoader.INSTANCE.loadNBT("extra-identifiers-1.20.3.nbt");
blocks = new KeyMappings(extraMappings.getListTag("blocks", StringTag.class));
sounds = new KeyMappings(extraMappings.getListTag("sounds", StringTag.class));
}
public int blockId(final String name) {
return blocks.keyToId(name);
}
public @Nullable String blockName(final int id) {
return blocks.idToKey(id);
}
public int soundId(final String name) {
return sounds.keyToId(name);
}
public @Nullable String soundName(final int id) {
return sounds.idToKey(id);
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class PotionEffects1_20_5 {
private static final Object2IntMap<String> KEY_TO_ID = new Object2IntOpenHashMap<>();
private static final String[] POTION_EFFECTS = {
"speed",
"slowness",
"haste",
"mining_fatigue",
"strength",
"instant_health",
"instant_damage",
"jump_boost",
"nausea",
"regeneration",
"resistance",
"fire_resistance",
"water_breathing",
"invisibility",
"blindness",
"night_vision",
"hunger",
"weakness",
"poison",
"wither",
"health_boost",
"absorption",
"saturation",
"glowing",
"levitation",
"luck",
"unluck",
"slow_falling",
"conduit_power",
"dolphins_grace",
"bad_omen",
"hero_of_the_village",
"darkness",
"trial_omen",
"raid_omen",
"wind_charged",
"weaving",
"oozing",
"infested"
};
static {
for (int i = 0; i < POTION_EFFECTS.length; i++) {
final String effect = POTION_EFFECTS[i];
KEY_TO_ID.put(effect, i);
}
KEY_TO_ID.defaultReturnValue(-1);
}
public static @Nullable String idToKey(final int id) {
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : null;
}
public static String idToKeyOrLuck(final int id) {
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
}
public static int keyToId(final String key) {
return KEY_TO_ID.getInt(Key.stripMinecraftNamespace(key));
}
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class Potions1_20_5 {
private static final KeyMappings POTIONS = new KeyMappings(
"water",
"mundane",
"thick",
"awkward",
"night_vision",
"long_night_vision",
"invisibility",
"long_invisibility",
"leaping",
"long_leaping",
"strong_leaping",
"fire_resistance",
"long_fire_resistance",
"swiftness",
"long_swiftness",
"strong_swiftness",
"slowness",
"long_slowness",
"strong_slowness",
"turtle_master",
"long_turtle_master",
"strong_turtle_master",
"water_breathing",
"long_water_breathing",
"healing",
"strong_healing",
"harming",
"strong_harming",
"poison",
"long_poison",
"strong_poison",
"regeneration",
"long_regeneration",
"strong_regeneration",
"strength",
"long_strength",
"strong_strength",
"weakness",
"long_weakness",
"luck",
"slow_falling",
"long_slow_falling",
"wind_charged",
"weaving",
"oozing",
"infested"
);
public static @Nullable String idToKey(final int id) {
return POTIONS.idToKey(id);
}
public static int keyToId(final String potion) {
return POTIONS.keyToId(potion);
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class TrimMaterials1_20_3 {
private static final KeyMappings MATERIALS = new KeyMappings(
"amethyst",
"copper",
"diamond",
"emerald",
"gold",
"iron",
"lapis",
"netherite",
"quartz",
"redstone"
);
public static @Nullable String idToKey(final int id) {
return MATERIALS.idToKey(id);
}
public static int keyToId(final String material) {
return MATERIALS.keyToId(material);
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.protocol1_20_5to1_20_3.data;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class TrimPatterns1_20_3 {
private static final KeyMappings PATTERNS = new KeyMappings(
"coast",
"dune",
"eye",
"host",
"raiser",
"rib",
"sentry",
"shaper",
"silence",
"snout",
"spire",
"tide",
"vex",
"ward",
"wayfinder",
"wild"
);
public static @Nullable String idToKey(final int id) {
return PATTERNS.idToKey(id);
}
public static int keyToId(final String pattern) {
return PATTERNS.keyToId(pattern);
}
}

View File

@ -27,14 +27,15 @@ public enum ClientboundConfigurationPackets1_20_5 implements ClientboundPacket1_
FINISH_CONFIGURATION, // 0x03
KEEP_ALIVE, // 0x04
PING, // 0x05
REGISTRY_DATA, // 0x06
RESOURCE_PACK_POP, // 0x07
RESOURCE_PACK_PUSH, // 0x08
STORE_COOKIE, // 0x09
TRANSFER, // 0x0A
UPDATE_ENABLED_FEATURES, // 0x0B
UPDATE_TAGS, // 0x0C
SELECT_KNOWN_PACKS; // 0x0D
RESET_CHAT, // 0x06
REGISTRY_DATA, // 0x07
RESOURCE_PACK_POP, // 0x08
RESOURCE_PACK_PUSH, // 0x09
STORE_COOKIE, // 0x0A
TRANSFER, // 0x0B
UPDATE_ENABLED_FEATURES, // 0x0C
UPDATE_TAGS, // 0x0D
SELECT_KNOWN_PACKS; // 0x0E
@Override
public int getId() {

Some files were not shown because too many files have changed in this diff Show More