Compare commits

..
6 Commits
Author SHA1 Message Date
NotAlexNoyle c09fa331c6 Exclude CODEOWNERS from language statistics 2026-10-28 08:31:40 -04:00
NotAlexNoyle 0088f657e7 Add CODEOWNERS (one staff approval) 2026-10-28 08:31:40 -04:00
NotAlexNoyle 0f95f7cbaf Merge branch 'ViaVersion:master' into master 2026-06-17 12:51:33 -04:00
NotAlexNoyle e607988751 Suppress jdk17 warning 2026-06-17 04:00:23 -04:00
NotAlexNoyle 1f6103aa9b Fix network protocol error on 1.21.5+ clients 2026-06-05 12:25:14 -04:00
NotAlexNoyle 00bb773c4a TrueOG fork patches
Cumulative customizations on top of upstream ViaVersion master:
- build.gradle.kts: enable Eclipse gradle plugin
- common/.../config.yml: TrueOG network 1.19.4 production config,
  disallow clients above 1.21.11, rely on Scoreboard-OG to hide
  scoreboard numbers, suppress warnings
- common/.../v1_19_4to1_20 EntityPacketRewriter1_20: cancel Purpur
  Rainglow non-vanilla GLOW_SQUID metadata (placeholder index, fixed
  in the follow-up commit)

Squashes: Add eclipse gradle plugin (47af35dfa), Use live TrueOG
Network 1.19.4/main config files (f44d281a8, 47e67a1b9), Suppress
warnings (17d367bd9), Rely on Scoreboard-OG to hide scoreboard
numbers (e69efcc39), Disallow clients above 1.21.11 (7cfbe8b94),
Bee anger field iterations (dd95e81c3, 38746d70e), Fix packets
(57f9f1016).
2026-06-05 12:25:09 -04:00
427 changed files with 30226 additions and 21480 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
-3
View File
@@ -1,5 +1,4 @@
version: 2
# Disabled for the time being, being done manually instead
updates:
- package-ecosystem: "github-actions"
cooldown:
@@ -7,11 +6,9 @@ updates:
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 0
- package-ecosystem: "gradle"
cooldown:
default-days: 7
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 0
+4 -4
View File
@@ -11,16 +11,16 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6.4.0
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-disabled: false
cache-provider: basic
- name: Set up JDK 17
uses: actions/setup-java@v6.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'temurin'
java-version: 17
@@ -30,7 +30,7 @@ jobs:
- name: Upload Artifacts to GitHub
# Only upload on the preview repository as there is no CI job for it.
if: ${{ github.repository == 'ViaVersion/ViaVersionDev' && github.ref_name == 'preview' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Artifacts
path: build/libs/
+4 -4
View File
@@ -16,16 +16,16 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6.4.0
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-disabled: false
cache-provider: basic
- name: Set up JDK 17
uses: actions/setup-java@v6.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'temurin'
java-version: 17
@@ -40,5 +40,5 @@ jobs:
- name: Publish to Modrinth
env:
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew publishMods --stacktrace
run: ./gradlew modrinth --stacktrace
continue-on-error: true
-2
View File
@@ -37,5 +37,3 @@ bin/
run/
AGENTS.override.md
.claude/
!.claude/CLAUDE.md
+8 -13
View File
@@ -14,23 +14,18 @@ or as [a standalone proxy](https://github.com/ViaVersion/ViaProxy) to join from
any server version from the past decade. **See [HERE](https://viaversion.com) for an overview of the different Via\*
projects.**
**Note:** While ViaVersion works reliably across all listed platforms, it has the highest performance and state accuracy on **Paper** servers and through **[ViaFabricPlus](https://github.com/ViaVersion/ViaFabricPlus)** on clients, since both offer more extensive APIs and direct access to client/server state.
Note that ViaVersion will be able to **run best on either Paper servers or
through [ViaFabricPlus](https://github.com/ViaVersion/ViaFabricPlus?tab=readme-ov-file#viafabricplus)** due to having
direct access to client/server state and more extensive API.
### Supported Versions
Supported Versions:
| Players joining with… | Install |
| :--- | :--- |
| **Newer** versions than the server | ViaVersion |
| **Older** versions than the server, down to 1.9 | ViaVersion + [ViaBackwards](https://github.com/ViaVersion/ViaBackwards) |
| **1.7.x – 1.8.x** | ViaVersion + [ViaBackwards](https://github.com/ViaVersion/ViaBackwards) + [ViaRewind](https://github.com/ViaVersion/ViaRewind) |
![Table (https://ci.viaversion.com/userContent/images/T.png)](https://ci.viaversion.com/userContent/images/T.png)
If you're stuck, try [this tool](https://viaversion.com/setup) to work out what plugins you need.
**User Docs:** [docs.viaversion.com](https://docs.viaversion.com)
Snapshot Support
----------
**User Docs:** https://docs.viaversion.com
Snapshot support
--------
**ViaVersion will only be released a few days *after* a Minecraft update** unless the protocol changes of the update
were trivial. If you want early-access, usually days or even weeks before the final release, you can subscribe to
either:
@@ -66,7 +66,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes
*/
default int apiVersion() {
return 27;
return 26;
}
/**
@@ -261,8 +261,6 @@ public interface ViaVersionConfig extends Config {
*/
boolean isChunkBorderFix();
boolean isMultiReddustColorFix();
/**
* Should we make team colours based on the last colour in team prefix
*
@@ -500,13 +498,6 @@ public interface ViaVersionConfig extends Config {
*/
boolean handleInvalidItemCount();
/**
* Backs up the original data of nested items (e.g. in containers or bundles) for 1.20.5+ clients on 1.20.4 and older servers.
*
* @return true if enabled
*/
boolean backupNestedItems();
/**
* Tries to cancel block break/place sounds sent by 1.8 servers to 1.9+ clients to prevent them from playing twice
*
@@ -515,7 +506,7 @@ public interface ViaVersionConfig extends Config {
boolean cancelBlockSounds();
/**
* Hides sidebar scoreboard numbers for 1.20.3+ clients on older server versions.
* Hides scoreboard numbers for 1.20.3+ clients on older server versions.
*
* @return true if enabled
*/
@@ -1,45 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.connection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.item.ItemHasher;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
/**
* Holds protocol-specific data. Protocols may extend the data wrapper to hold extra data.
*/
public interface ProtocolStorables {
EntityTracker entityTracker();
void setEntityTracker(EntityTracker tracker);
ClientWorld clientWorld();
void setClientWorld(ClientWorld clientWorld);
ItemHasher itemHasher();
void setItemHasher(ItemHasher itemHasher);
}
@@ -22,8 +22,6 @@
*/
package com.viaversion.viaversion.api.connection;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.item.ItemHasher;
@@ -38,18 +36,18 @@ import io.netty.channel.ChannelFuture;
import io.netty.handler.codec.CodecException;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface UserConnection {
/**
* Get an object from the storage. Useful where protocol instances aren't readily available.
* Get an object from the storage.
*
* @param objectClass The class of the object to get
* @param <T> The type of the class you want to get.
* @return The requested object
* @see #storables(Protocol)
*/
@Nullable <T extends StorableObject> T get(Class<T> objectClass);
@@ -71,56 +69,27 @@ public interface UserConnection {
@Nullable <T extends StorableObject> T remove(Class<T> objectClass);
/**
* Put an object into the stored objects based on class. Useful where protocol instances aren't readily available.
* Put an object into the stored objects based on class.
*
* @param object The object to store.
* @see #storables(Protocol)
*/
void put(StorableObject object);
/**
* Holds protocol-specific data. Where protocol instances aren't readily available, use {@link #put(StorableObject)}.
*
* @param protocol protocol
* @param <T> protocol-specific storables type
* @return protocol storables
* @throws IllegalArgumentException if the protocol does not have a valid return value for {@link Protocol#index()}
*/
<T extends ProtocolStorables> T storables(Protocol<?, ?, ?, ?> protocol);
/**
* Holds protocol-specific data. Prefer using {@link #storables(Protocol)} where possible.
*
* @param protocolClass protocol class
* @param <T> protocol-specific storables type
* @return protocol storables
* @throws IllegalArgumentException if the protocol does not have a valid return value for {@link Protocol#index()}
* @see #storables(Protocol)
*/
default <T extends ProtocolStorables> T storables(final Class<? extends Protocol> protocolClass) {
return storables(Via.getManager().getProtocolManager().getProtocol(protocolClass));
}
/**
* Returns a collection of entity trackers currently registered.
*
* @return collection of entity trackers currently registered
*/
@Deprecated(forRemoval = true)
Collection<EntityTracker> getEntityTrackers();
@Deprecated(forRemoval = true)
@Nullable <T extends EntityTracker> T getEntityTracker(Class<? extends Protocol> protocolClass);
/**
* Returns the entity tracker by the given protocol class if present.
*
* @param protocol protocol
* @param <T> entity tracker type
* @param protocolClass protocol class
* @param <T> entity tracker type
* @return entity tracker if present
* @see com.viaversion.viaversion.api.rewriter.EntityRewriter#tracker(UserConnection)
*/
@Nullable <T extends EntityTracker> T getEntityTracker(Protocol<?, ?, ?, ?> protocol);
@Nullable <T extends EntityTracker> T getEntityTracker(Class<? extends Protocol> protocolClass);
/**
* Adds an entity tracker to the user connection.
@@ -128,43 +97,34 @@ public interface UserConnection {
*
* @param protocolClass protocol class
* @param tracker entity tracker
* @deprecated use {@link #storables(Protocol)}
*/
@Deprecated(forRemoval = true)
void addEntityTracker(Class<? extends Protocol> protocolClass, EntityTracker tracker);
/**
* Returns the item hasher by the given class if present.
*
* @param protocol protocol
* @param <T> item hasher type
* @return item hasher if present
*/
@Nullable <T extends ItemHasher> T getItemHasher(Protocol<?, ?, ?, ?> protocol);
/**
* Adds an item hasher to the user connection.
*
* @param protocolClass protocol class
* @param itemHasher item hasher
* @deprecated use {@link #storables(Protocol)}
*/
@Deprecated(forRemoval = true)
void addItemHasher(Class<? extends Protocol> protocolClass, ItemHasher itemHasher);
@Deprecated(forRemoval = true)
/**
* Returns the item hasher by the given protocol class if present.
*
* @param protocolClass protocol class
* @param <T> item hasher type
* @return item hasher if present
*/
@Nullable <T extends ItemHasher> T getItemHasher(Class<? extends Protocol> protocolClass);
/**
* Returns the client world by the given class if present.
* Returns the client world by the given protocol class if present.
*
* @param protocolClass protocol class
* @param <T> client world type
* @return client world if present
* @deprecated use {@link #storables(Protocol)}
*/
@Nullable
@Deprecated(forRemoval = true)
<T extends ClientWorld> T getClientWorld(Class<? extends Protocol> protocolClass);
/**
@@ -174,7 +134,6 @@ public interface UserConnection {
* @param protocolClass protocol class
* @param clientWorld client world
*/
@Deprecated(forRemoval = true)
void addClientWorld(Class<? extends Protocol> protocolClass, ClientWorld clientWorld);
/**
@@ -406,10 +365,10 @@ public interface UserConnection {
}
/**
* Returns a newly generated token that will let a packet be passed through without
* Returns a newly generated uuid that will let a packet be passed through without
* transforming its contents if used together with {@link PacketWrapper#PASSTHROUGH_ID}.
*
* @return generated passthrough token
*/
long generatePassthroughToken();
UUID generatePassthroughToken();
}
@@ -22,29 +22,88 @@
*/
package com.viaversion.viaversion.api.data;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class FullIdentityMappings extends FullMappingsBase {
public class FullIdentityMappings implements FullMappings {
private static final String[] EMPTY_ARRAY = new String[0];
private final Object2IntMap<String> stringToId;
private final String[] idToString;
private final Mappings mappings;
public FullIdentityMappings(final IdentifiersPair identifiersPair, final Mappings mappings) {
this(toInverseMap(identifiersPair.unmapped()), identifiersPair.unmapped().stream().map(Key::of).toArray(Key[]::new), mappings);
Preconditions.checkNotNull(mappings, "Mappings cannot be null");
this.mappings = mappings;
this.stringToId = FullMappingsBase.toInverseMap(identifiersPair.unmapped());
this.idToString = identifiersPair.unmapped().toArray(EMPTY_ARRAY);
}
private FullIdentityMappings(final Object2IntMap<String> stringToId, final Key[] idToKey, final Mappings mappings) {
super(stringToId, stringToId, idToKey, idToKey, mappings);
private FullIdentityMappings(final Object2IntMap<String> stringToId, final String[] idToString, final Mappings mappings) {
this.stringToId = stringToId;
this.idToString = idToString;
this.mappings = mappings;
}
@Override
public int id(final String identifier) {
return stringToId.getInt(Key.stripMinecraftNamespace(identifier));
}
@Override
public int mappedId(final String mappedIdentifier) {
return id(mappedIdentifier);
}
@Override
public String identifier(final int id) {
if (id < 0 || id >= idToString.length) {
return null;
}
final String identifier = idToString[id];
return Key.namespaced(identifier);
}
@Override
public @Nullable String identifier(final String mappedIdentifier) {
return mappedIdentifier(mappedIdentifier);
final int mappedId = mappedId(mappedIdentifier);
if (mappedId == -1) {
return null;
}
final int id = mappings.inverse().getNewId(mappedId);
return id != -1 ? identifier(id) : null;
}
@Override
public @Nullable Key keyFromMappedKey(final String mappedIdentifier) {
return mappedKeyFromKey(mappedIdentifier);
public @Nullable String mappedIdentifier(final int mappedId) {
return identifier(mappedId);
}
@Override
public @Nullable String mappedIdentifier(final String identifier) {
return identifier(identifier);
}
@Override
public int getNewId(int id) {
return mappings.getNewId(id);
}
@Override
public void setNewId(int id, int mappedId) {
mappings.setNewId(id, mappedId);
}
@Override
public int size() {
return mappings.size();
}
@Override
public int mappedSize() {
return mappings.mappedSize();
}
@Override
@@ -58,7 +117,7 @@ public class FullIdentityMappings extends FullMappingsBase {
}
@Override
public FullIdentityMappings inverse() {
return new FullIdentityMappings(stringToId, idToKey, mappings.inverse());
public FullMappings inverse() {
return new FullIdentityMappings(stringToId, idToString, mappings.inverse());
}
}
@@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.data;
import com.viaversion.viaversion.util.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@@ -52,10 +51,7 @@ public interface FullMappings extends BiMappings {
* @param id unmapped id
* @return unmapped string identifier, or null if out of bounds
*/
default @Nullable String identifier(int id) {
final Key key = keyFromId(id);
return key != null ? key.toString() : null;
}
@Nullable String identifier(int id);
/**
* Returns the unmapped string identifier for the given mapped identifier.
@@ -63,10 +59,7 @@ public interface FullMappings extends BiMappings {
* @param mappedIdentifier mapped identifier
* @return unmapped string identifier, or null if not found
*/
default @Nullable String identifier(String mappedIdentifier) {
final Key key = keyFromMappedKey(mappedIdentifier);
return key != null ? key.toString() : null;
}
@Nullable String identifier(String mappedIdentifier);
/**
* Returns the mapped string identifier for the given mapped id.
@@ -74,10 +67,7 @@ public interface FullMappings extends BiMappings {
* @param mappedId mapped id
* @return mapped string identifier, or null if out of bounds
*/
default @Nullable String mappedIdentifier(int mappedId) {
final Key key = mappedKeyFromMappedId(mappedId);
return key != null ? key.toString() : null;
}
@Nullable String mappedIdentifier(int mappedId);
/**
* Returns the mapped string identifier for the given unmapped identifier.
@@ -85,42 +75,7 @@ public interface FullMappings extends BiMappings {
* @param identifier unmapped identifier
* @return mapped string identifier, or null if not found
*/
default @Nullable String mappedIdentifier(String identifier) {
final Key key = mappedKeyFromKey(identifier);
return key != null ? key.toString() : null;
}
/**
* Returns the unmapped key for the given mapped id.
*
* @param id unmapped id
* @return unmapped key, or null if out of bounds
*/
@Nullable Key keyFromId(int id);
/**
* Returns the unmapped key for the given mapped identifier.
*
* @param mappedIdentifier mapped identifier
* @return unmapped key, or null if not found
*/
@Nullable Key keyFromMappedKey(String mappedIdentifier);
/**
* Returns the mapped key for the given mapped id.
*
* @param mappedId mapped id
* @return mapped key, or null if out of bounds
*/
@Nullable Key mappedKeyFromMappedId(int mappedId);
/**
* Returns the mapped key for the given unmapped identifier.
*
* @param identifier unmapped identifier
* @return mapped key, or null if not found
*/
@Nullable Key mappedKeyFromKey(String identifier);
@Nullable String mappedIdentifier(String identifier);
/**
* Returns whether the int id mappings are identity mappings.
@@ -31,26 +31,27 @@ import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public class FullMappingsBase implements FullMappings {
protected final Object2IntMap<String> stringToId;
protected final Object2IntMap<String> mappedStringToId;
protected final Key[] idToKey;
protected final Key[] mappedIdToKey;
protected final Mappings mappings;
private static final String[] EMPTY_ARRAY = new String[0];
private final Object2IntMap<String> stringToId;
private final Object2IntMap<String> mappedStringToId;
private final String[] idToString;
private final String[] mappedIdToString;
private final Mappings mappings;
public FullMappingsBase(final IdentifiersPair identifiersPair, final Mappings mappings) {
Preconditions.checkNotNull(mappings, "Mappings cannot be null");
this.mappings = mappings;
this.stringToId = toInverseMap(identifiersPair.unmapped());
this.idToKey = identifiersPair.unmapped().stream().map(Key::of).toArray(Key[]::new);
this.idToString = identifiersPair.unmapped().toArray(EMPTY_ARRAY);
this.mappedStringToId = toInverseMap(identifiersPair.mapped());
this.mappedIdToKey = identifiersPair.mapped().stream().map(Key::of).toArray(Key[]::new);
this.mappedIdToString = identifiersPair.mapped().toArray(EMPTY_ARRAY);
}
protected FullMappingsBase(final Object2IntMap<String> stringToId, final Object2IntMap<String> mappedStringToId, final Key[] idToKey, final Key[] mappedIdToKey, final Mappings mappings) {
private FullMappingsBase(final Object2IntMap<String> stringToId, final Object2IntMap<String> mappedStringToId, final String[] idToString, final String[] mappedIdToString, final Mappings mappings) {
this.stringToId = stringToId;
this.mappedStringToId = mappedStringToId;
this.idToKey = idToKey;
this.mappedIdToKey = mappedIdToKey;
this.idToString = idToString;
this.mappedIdToString = mappedIdToString;
this.mappings = mappings;
}
@@ -78,43 +79,45 @@ public class FullMappingsBase implements FullMappings {
}
@Override
public @Nullable Key keyFromId(final int id) {
if (id < 0 || id >= idToKey.length) {
public String identifier(final int id) {
if (id < 0 || id >= idToString.length) {
return null;
}
return idToKey[id];
final String identifier = idToString[id];
return Key.namespaced(identifier);
}
@Override
public @Nullable Key keyFromMappedKey(final String mappedIdentifier) {
public @Nullable String identifier(final String mappedIdentifier) {
final int mappedId = mappedId(mappedIdentifier);
if (mappedId == -1) {
return null;
}
final int id = mappings.inverse().getNewId(mappedId);
return id != -1 ? keyFromId(id) : null;
return id != -1 ? identifier(id) : null;
}
@Override
public @Nullable Key mappedKeyFromMappedId(final int mappedId) {
if (mappedId < 0 || mappedId >= mappedIdToKey.length) {
public @Nullable String mappedIdentifier(final int mappedId) {
if (mappedId < 0 || mappedId >= mappedIdToString.length) {
return null;
}
return mappedIdToKey[mappedId];
final String identifier = mappedIdToString[mappedId];
return Key.namespaced(identifier);
}
@Override
public @Nullable Key mappedKeyFromKey(final String identifier) {
public @Nullable String mappedIdentifier(final String identifier) {
final int id = id(identifier);
if (id == -1) {
return null;
}
final int mappedId = mappings.getNewId(id);
return mappedId != -1 ? mappedKeyFromMappedId(mappedId) : null;
return mappedId != -1 ? mappedIdentifier(mappedId) : null;
}
@Override
@@ -144,6 +147,6 @@ public class FullMappingsBase implements FullMappings {
@Override
public FullMappings inverse() {
return new FullMappingsBase(mappedStringToId, stringToId, mappedIdToKey, idToKey, mappings.inverse());
return new FullMappingsBase(mappedStringToId, stringToId, mappedIdToString, idToString, mappings.inverse());
}
}
@@ -1,72 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.data;
import com.viaversion.nbt.tag.ByteArrayTag;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.function.IntConsumer;
/**
* Reads sets of non-negative ints stored as ranges, packed into a byte array of varints.
* Each range is stored as an offset and length pair. The offset is the start of the first range and the
* difference to the previous range's exclusive end; the length is the inclusive end minus the start.
*/
public final class IdRanges {
/**
* Returns the encoded id set as an int set.
*
* @param rangesTag tag with the encoded ranges
* @return decoded ids
*/
public static IntSet decode(final ByteArrayTag rangesTag) {
final IntSet ids = new IntOpenHashSet();
forEachId(rangesTag, ids::add);
return ids;
}
public static IntList decodeAsList(final ByteArrayTag rangesTag) {
final IntList ids = new IntArrayList();
forEachId(rangesTag, ids::add);
return ids;
}
public static void forEachId(final ByteArrayTag rangesTag, final IntConsumer consumer) {
final ByteBuf buf = Unpooled.wrappedBuffer(rangesTag.getValue());
int prevEnd = 0;
while (buf.isReadable()) {
final int start = prevEnd + Types.VAR_INT.readPrimitive(buf);
final int end = start + Types.VAR_INT.readPrimitive(buf);
for (int id = start; id <= end; id++) {
consumer.accept(id);
}
prevEnd = end + 1;
}
}
}
@@ -1,111 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.data;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Full mappings for versions where required identifiers hadn't yet followed the resource location format (i.e., pre-1.9.4 sounds).
*/
public class LegacyFullStringMappingsBase extends FullMappingsBase {
private final String[] idToString;
private final String[] mappedIdToString;
public LegacyFullStringMappingsBase(final IdentifiersPair identifiersPair, final Mappings mappings) {
super(toInverseMap(identifiersPair.unmapped()), toInverseMap(identifiersPair.mapped()), new Key[0], new Key[0], mappings);
this.idToString = identifiersPair.unmapped().toArray(new String[0]);
this.mappedIdToString = identifiersPair.mapped().toArray(new String[0]);
}
private LegacyFullStringMappingsBase(final Object2IntMap<String> stringToId, final Object2IntMap<String> mappedStringToId, final String[] idToKey, final String[] mappedIdToString, final Mappings mappings) {
super(stringToId, mappedStringToId, new Key[0], new Key[0], mappings);
this.idToString = idToKey;
this.mappedIdToString = mappedIdToString;
}
@Override
public String identifier(final int id) {
if (id < 0 || id >= idToString.length) {
return null;
}
return Key.namespaced(idToString[id]);
}
@Override
public @Nullable String identifier(final String mappedIdentifier) {
final int mappedId = mappedId(mappedIdentifier);
if (mappedId == -1) {
return null;
}
final int id = mappings.inverse().getNewId(mappedId);
return id != -1 ? identifier(id) : null;
}
@Override
public @Nullable String mappedIdentifier(final int mappedId) {
if (mappedId < 0 || mappedId >= mappedIdToString.length) {
return null;
}
return Key.namespaced(mappedIdToString[mappedId]);
}
@Override
public @Nullable String mappedIdentifier(final String identifier) {
final int id = id(identifier);
if (id == -1) {
return null;
}
final int mappedId = mappings.getNewId(id);
return mappedId != -1 ? mappedIdentifier(mappedId) : null;
}
@Override
public @Nullable Key keyFromId(final int id) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable Key keyFromMappedKey(final String mappedIdentifier) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable Key mappedKeyFromMappedId(final int mappedId) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable Key mappedKeyFromKey(final String identifier) {
throw new UnsupportedOperationException();
}
@Override
public FullMappings inverse() {
return new LegacyFullStringMappingsBase(mappedStringToId, stringToId, mappedIdToString, idToString, mappings.inverse());
}
}
@@ -29,7 +29,6 @@ import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface MappingData {
@@ -191,27 +190,15 @@ public interface MappingData {
*/
@Nullable IntSet changedBlocks();
default boolean hasBlockChanged(final int blockId) {
return changedBlocks() != null && changedBlocks().contains(blockId);
}
@Nullable Set<String> changedEnvironmentAttributes();
/**
* Type of mappings. Currently only relevant for ops writing of generic holder classes and expanded when needed.
*/
enum MappingType implements RegistryKey {
ITEM, BLOCK, SOUND, ENTITY_TYPE;
private final Key key;
MappingType() {
this.key = Key.of(name().toLowerCase(Locale.ROOT));
}
@Override
public Key registry() {
return this.key;
public Key key() {
return Key.of(name().toLowerCase(Locale.ROOT));
}
}
}
@@ -22,11 +22,8 @@
*/
package com.viaversion.viaversion.api.data;
import com.viaversion.nbt.tag.ByteArrayTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntArrayTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
@@ -38,9 +35,7 @@ import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MappingDataBase implements MappingData {
@@ -68,7 +63,6 @@ public class MappingDataBase implements MappingData {
* Set of block ids that have had type or property changes.
*/
protected IntSet changedBlocks;
protected Set<String> changedEnvironmentAttributes;
public MappingDataBase(final String unmappedVersion, final String mappedVersion) {
this.unmappedVersion = unmappedVersion;
@@ -124,7 +118,6 @@ public class MappingDataBase implements MappingData {
loadTags(RegistryType.ITEM, tagsTag);
loadTags(RegistryType.BLOCK, tagsTag);
loadTags(RegistryType.ENTITY, tagsTag);
loadTags(RegistryType.FLUID, tagsTag);
}
final IntArrayTag changedBlocks = data.getIntArrayTag("changed_blocks");
@@ -132,11 +125,6 @@ public class MappingDataBase implements MappingData {
this.changedBlocks = new IntOpenHashSet(changedBlocks.getValue());
}
final ListTag<StringTag> changedEnvironmentAttributes = data.getListTag("changed_environment_attributes", StringTag.class);
if (changedEnvironmentAttributes != null) {
this.changedEnvironmentAttributes = changedEnvironmentAttributes.stream().map(StringTag::getValue).collect(Collectors.toSet());
}
loadExtras(data);
}
@@ -179,10 +167,6 @@ public class MappingDataBase implements MappingData {
if (mappings == null) {
mappings = new IdentityMappings(identifiersPair.unmapped().size(), identifiersPair.mapped().size());
}
return createFullMappings(identifiersPair, mappings);
}
protected FullMappings createFullMappings(final IdentifiersPair identifiersPair, final Mappings mappings) {
return FullMappingsBase.of(identifiersPair, mappings);
}
@@ -199,14 +183,8 @@ public class MappingDataBase implements MappingData {
final List<TagData> tagsList = new ArrayList<>(tags.size());
for (final Map.Entry<String, Tag> entry : tag.entrySet()) {
final int[] entries;
if (entry.getValue() instanceof final ByteArrayTag rangesTag) {
entries = IdRanges.decodeAsList(rangesTag).toIntArray();
} else {
// Old format / if the values need to be sorted
entries = ((IntArrayTag) entry.getValue()).getValue();
}
tagsList.add(new TagData(entry.getKey(), entries));
final IntArrayTag entries = (IntArrayTag) entry.getValue();
tagsList.add(new TagData(entry.getKey(), entries.getValue()));
}
this.tags.put(type, tagsList);
@@ -371,11 +349,6 @@ public class MappingDataBase implements MappingData {
return changedBlocks;
}
@Override
public @Nullable Set<String> changedEnvironmentAttributes() {
return changedEnvironmentAttributes;
}
protected Logger getLogger() {
return Via.getPlatform().getLogger();
}
@@ -31,17 +31,13 @@ import com.google.gson.JsonSyntaxException;
import com.viaversion.nbt.io.NBTIO;
import com.viaversion.nbt.io.TagReader;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntArrayTag;
import com.viaversion.nbt.tag.IntTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.GsonUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.io.BufferedInputStream;
@@ -55,7 +51,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -64,16 +59,15 @@ 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 int VERSION = 2;
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;
private final Map<String, CompoundTag> mappingsCache = new ConcurrentHashMap<>();
private final Map<String, CompoundTag> mappingsCache = new HashMap<>();
private final Class<?> dataLoaderClass;
private final String dataPath;
private volatile boolean cacheValid = true;
private boolean cacheValid = true;
public MappingDataLoader(final Class<?> dataLoaderClass, final String dataPath) {
this.dataLoaderClass = dataLoaderClass;
@@ -110,14 +104,14 @@ public class MappingDataLoader {
throw new IllegalArgumentException("Unknown global identifier key: " + registry);
}
if (globalId < 0 || globalId >= array.length) {
throw new IllegalArgumentException("Unknown global identifier index: " + registry + "/" + globalId);
throw new IllegalArgumentException("Unknown global identifier index: " + globalId);
}
return array[globalId];
}
public void clearCache() {
cacheValid = false;
mappingsCache.clear();
cacheValid = false;
}
/**
@@ -166,14 +160,17 @@ public class MappingDataLoader {
return loadNBTFromFile(name);
}
if (cache) {
// Also blocks concurrent loaders of the same file until the first one has finished
return mappingsCache.computeIfAbsent(name, this::loadNBTFromFile);
CompoundTag data = mappingsCache.get(name);
if (data != null) {
return data;
}
// Still do a lookup, but don't store it
final CompoundTag data = mappingsCache.get(name);
return data != null ? data : loadNBTFromFile(name);
data = loadNBTFromFile(name);
if (cache && data != null) {
mappingsCache.put(name, data);
}
return data;
}
public @Nullable CompoundTag loadNBT(final String name) {
@@ -214,29 +211,15 @@ public class MappingDataLoader {
return null;
}
final int version = mappingsTag.getInt("version", -1);
if (version != VERSION) {
throw new IllegalArgumentException("Invalid version: " + version);
}
final int mappedSize = tag.getInt("mappedSize", -1);
final byte strategy = tag.getByteTag("id").asByte();
final V mappings;
if (strategy == DIRECT_ID) {
// Zigzag varints of the difference to the previous mapped id
final int size = tag.getIntTag("size").asInt();
final ByteBuf buf = Unpooled.wrappedBuffer(tag.getByteArrayTag("val").getValue());
final int[] values = new int[size];
int prev = 0;
for (int i = 0; i < size; i++) {
prev += readZigZagVarInt(buf);
values[i] = prev;
}
return IntArrayMappings.of(values, mappedSize);
final IntArrayTag valuesTag = tag.getIntArrayTag("val");
return IntArrayMappings.of(valuesTag.getValue(), mappedSize);
} else if (strategy == SHIFTS_ID) {
final ValuePairs pairs = readAtValuePairs(tag);
final int[] shiftsAt = pairs.first;
final int[] shiftsTo = pairs.second;
final int[] shiftsAt = tag.getIntArrayTag("at").getValue();
final int[] shiftsTo = tag.getIntArrayTag("to").getValue();
final int size = tag.getIntTag("size").asInt();
mappings = holderSupplier.get(size);
@@ -259,9 +242,8 @@ public class MappingDataLoader {
}
}
} else if (strategy == CHANGES_ID) {
final ValuePairs pairs = readAtValuePairs(tag);
final int[] changesAt = pairs.first;
final int[] values = pairs.second;
final int[] changesAt = tag.getIntArrayTag("at").getValue();
final int[] values = tag.getIntArrayTag("val").getValue();
final int size = tag.getIntTag("size").asInt();
final boolean fillBetween = tag.get("nofill") == null;
mappings = holderSupplier.get(size);
@@ -280,13 +262,6 @@ public class MappingDataLoader {
// Assign the changed value
addConsumer.addTo(mappings, changedId, values[i]);
}
// Fill the remainder
if (fillBetween && nextUnhandledId != size) {
for (int id = nextUnhandledId; id < size; id++) {
addConsumer.addTo(mappings, id, id);
}
}
} else if (strategy == IDENTITY_ID) {
final IntTag sizeTag = tag.getIntTag("size");
return new IdentityMappings(sizeTag.asInt(), mappedSize);
@@ -296,37 +271,6 @@ public class MappingDataLoader {
return mappingsSupplier.create(mappings, mappedSize);
}
/**
* Reads alternating id and value pairs from varints. The id as the difference to the previous id,
* the value as the zigzag difference to the previous value.
*
* @param tag tag to read the packed values from
* @return array of ids and array of values
*/
private static ValuePairs readAtValuePairs(final CompoundTag tag) {
final ByteBuf buf = Unpooled.wrappedBuffer(tag.getByteArrayTag("val").getValue());
final IntList at = new IntArrayList();
final IntList values = new IntArrayList();
int prevAt = -1;
int prevValue = 0;
while (buf.isReadable()) {
prevAt = prevAt + 1 + Types.VAR_INT.readPrimitive(buf);
prevValue += readZigZagVarInt(buf);
at.add(prevAt);
values.add(prevValue);
}
return new ValuePairs(at.toIntArray(), values.toIntArray());
}
private static int readZigZagVarInt(final ByteBuf buf) {
// https://lemire.me/blog/2022/11/25/making-all-your-integers-positive-with-zigzag-encoding/
// In short, using deltas to previous ids makes the numbers small, and using zigzag encoding means they're all positive.
// Being all positive means we can use varints to make most of the data much shorter than 8 bytes.
// All of that combined ends up having a decent effect when compressed in the jar file as well.
final int value = Types.VAR_INT.readPrimitive(buf);
return (value >>> 1) ^ -(value & 1);
}
public @Nullable List<String> identifiersFromGlobalIds(final CompoundTag mappingsTag, final String key) {
final Mappings mappings = loadMappings(mappingsTag, key);
return mappings != null ? identifiers(mappings, key) : null;
@@ -371,10 +315,6 @@ public class MappingDataLoader {
continue;
}
if (mappedGlobalId == -1) {
throw new IllegalArgumentException("Mapped global id -1 for unmapped global id: " + key + "/" + unmappedIdentifier + " (" + unmappedGlobalId + ")");
}
identity = false;
unmappedIdentifiers.add(unmappedIdentifier);
mappedIdentifiers.add(identifierFromGlobalId(key, mappedGlobalId));
@@ -383,9 +323,8 @@ public class MappingDataLoader {
}
private List<String> identifiers(final Mappings mappings, final String key) {
final int size = mappings.size();
final List<String> identifiers = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
final List<String> identifiers = new ArrayList<>(mappings.size());
for (int i = 0; i < mappings.size(); i++) {
final int globalId = mappings.getNewId(i);
identifiers.add(identifierFromGlobalId(key, globalId));
}
@@ -462,7 +401,4 @@ public class MappingDataLoader {
this(identifiers, identifiers, true);
}
}
private record ValuePairs(int[] first, int[] second) {
}
}
@@ -23,9 +23,7 @@
package com.viaversion.viaversion.api.data.entity;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.KeyMappings;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -45,9 +43,8 @@ public interface EntityTracker {
*
* @param id entity id
* @param type entity type
* @return tracked entity
*/
TrackedEntity addEntity(int id, EntityType type);
void addEntity(int id, EntityType type);
/**
* Returns whether the entity is currently tracked.
@@ -78,9 +75,8 @@ public interface EntityTracker {
* Untracks an entity.
*
* @param id entity id
* @return previously tracked entity
*/
@Nullable TrackedEntity removeEntity(int id);
void removeEntity(int id);
/**
* Clears stored entity types and data, only leaving behind the client entity.
@@ -92,6 +88,25 @@ public interface EntityTracker {
*/
void clear();
/**
* Returns the stored entity data if an entity with the id is tracked, else null.
* If no data has been initialized yet, it will be done and returned by this method.
*
* @param id entity id
* @return stored entity data if an entity with the id is tracked, else null
* @throws IllegalArgumentException if entity data storage has not been enabled via the implementation
*/
@Nullable StoredEntityData entityData(int id);
/**
* Returns stored entity data if it has previously been initialized by {@link #entityData(int)}, else null.
*
* @param id entity id
* @return stored entity data if it has previously been initialized by {@link #entityData(int)}
* @throws IllegalArgumentException if entity data storage has not been enabled via the implementation
*/
@Nullable StoredEntityData entityDataIfPresent(int id);
/**
* Returns whether the client entity id has been set.
*
@@ -189,24 +204,6 @@ public interface EntityTracker {
void setBiomesSent(int biomesSent);
/**
* Returns the cached chunk type for the current dimension if set.
*
* @param mapped whether to return the mapped chunk type
* @return cached chunk type
*/
@Nullable Type<Chunk> chunkType(boolean mapped);
/**
* Caches the chunk type for the current dimension.
* <p>
* Invalidates when the world section height or the number of biomes change.
*
* @param mapped whether to set the mapped chunk type
* @param chunkType chunk type
*/
void setChunkType(boolean mapped, @Nullable Type<Chunk> chunkType);
EntityType playerType();
@Nullable DimensionData dimensionData(String dimension);
@@ -20,34 +20,50 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.util;
package com.viaversion.viaversion.api.data.entity;
public final class NestingLimiter {
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import org.checkerframework.checker.nullness.qual.Nullable;
private static final ThreadLocal<int[]> STATE = ThreadLocal.withInitial(() -> new int[]{0, -1}); // Current depth, max depth
public interface StoredEntityData {
/**
* Sets the max depth for reads on the current thread.
* Returns the entity type of the stored entity.
*
* @param maxDepth max depth, or -1 for no limit
* @return the previous max depth, to be set again once done
* @return entity type
*/
public static int setMaxDepth(final int maxDepth) {
final int[] state = STATE.get();
final int previous = state[1];
state[1] = maxDepth;
return previous;
}
EntityType type();
public static void increment() {
final int[] state = STATE.get();
if (state[1] != -1 && state[0] >= state[1]) {
throw new IllegalArgumentException("Data is nested too deeply");
}
state[0]++;
}
/**
* Checks if the storage contains an object of the given type.
*
* @param objectClass object class to check
* @return whether an object of the given type is in the storage
*/
boolean has(Class<?> objectClass);
public static void decrement() {
STATE.get()[0]--;
}
/**
* Returns an object from the storage if present.
*
* @param objectClass class of the object to get
* @param <T> object type
* @return object if present
*/
@Nullable <T> T get(Class<T> objectClass);
/**
* Removes and returns an object from the storage if present.
*
* @param objectClass class of the object to remove
* @param <T> object type
* @return removed object if present
*/
@Nullable <T> T remove(Class<T> objectClass);
/**
* Stores an object based on its class.
*
* @param object object to store
*/
void put(Object object);
}
@@ -22,9 +22,7 @@
*/
package com.viaversion.viaversion.api.data.entity;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface TrackedEntity {
@@ -36,37 +34,18 @@ public interface TrackedEntity {
EntityType entityType();
/**
* Checks if the storage contains an object of the given type.
* Object to hold arbitrary additional data.
*
* @param objectClass object class to check
* @return whether an object of the given type is in the storage
* @return entity data
*/
boolean has(Class<? extends StorableObject> objectClass);
StoredEntityData data();
/**
* Returns an object from the storage if present.
* Returns whether the stored entity currently has any additional data.
*
* @param objectClass class of the object to get
* @param <T> object type
* @return object if present
* @return whether the stored entity currently has additional data
*/
@Nullable <T extends StorableObject> T get(Class<T> objectClass);
/**
* Removes and returns an object from the storage if present.
*
* @param objectClass class of the object to remove
* @param <T> object type
* @return removed object if present
*/
@Nullable <T extends StorableObject> T remove(Class<T> objectClass);
/**
* Stores an object based on its class.
*
* @param object object to store
*/
void put(StorableObject object);
boolean hasData();
/**
* Returns whether entity data has already been sent at least once for this entity.
@@ -79,8 +79,8 @@ public record PaintingVariant(int width, int height, String assetId, @Nullable T
.write("width", Types.INT, value.width())
.write("height", Types.INT, value.height())
.write("asset_id", Types.IDENTIFIER, Key.of(value.assetId()))
.writeOptional("title", Types.TEXT_COMPONENT_TAG, value.title())
.writeOptional("author", Types.TEXT_COMPONENT_TAG, value.author()));
.writeOptional("title", Types.TRUSTED_TAG, value.title())
.writeOptional("author", Types.TRUSTED_TAG, value.author()));
}
@Override
@@ -34,7 +34,7 @@ import com.viaversion.viaversion.util.Key;
*/
public interface RegistryKey {
Key registry();
Key key();
static RegistryKey of(final String key) {
return new SimpleRegistryKey(Key.of(key));
@@ -43,7 +43,7 @@ public enum RegistryType implements RegistryKey {
static {
for (RegistryType type : getValues()) {
MAP.put(type.identifier(), type);
MAP.put(type.identifier, type);
}
}
@@ -55,18 +55,18 @@ public enum RegistryType implements RegistryKey {
return MAP.get(identifier);
}
private final Key key;
private final String identifier;
RegistryType(final String identifier) {
this.key = Key.of(identifier);
this.identifier = identifier;
}
public String identifier() {
return key.path();
return identifier;
}
@Override
public Key registry() {
return this.key;
public Key key() {
return Key.of(identifier);
}
}
@@ -1,40 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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;
public final class ResolvableFloat extends EitherImpl<Float, String> {
private ResolvableFloat(final Float left, final String right) {
super(left, right);
}
public static ResolvableFloat of(final String value) {
return new ResolvableFloat(null, value);
}
public static ResolvableFloat of(final Float value) {
return new ResolvableFloat(value, null);
}
}
@@ -1,40 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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;
public final class ResolvableInt extends EitherImpl<Integer, String> {
private ResolvableInt(final Integer left, final String right) {
super(left, right);
}
public static ResolvableInt of(final String value) {
return new ResolvableInt(null, value);
}
public static ResolvableInt of(final Integer value) {
return new ResolvableInt(value, null);
}
}
@@ -24,10 +24,10 @@ package com.viaversion.viaversion.api.minecraft;
import com.viaversion.viaversion.util.Key;
record SimpleRegistryKey(Key registry) implements RegistryKey {
record SimpleRegistryKey(Key key) implements RegistryKey {
@Override
public String toString() {
return registry.toString();
return key.toString();
}
}
@@ -39,11 +39,4 @@ public record SoundEvent(String identifier, @Nullable Float fixedRange) {
}
return holder.updateId(soundRewriteFunction, () -> UNKNOWN);
}
public static @Nullable Holder<SoundEvent> rewriteOptionalHolder(@Nullable final Holder<SoundEvent> holder, final Int2IntFunction soundRewriteFunction) {
if (holder == null) {
return null;
}
return holder.updateId(soundRewriteFunction, () -> null);
}
}
@@ -22,9 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.chunks;
import com.viaversion.viaversion.util.CompactArrayUtil;
import java.util.function.IntConsumer;
import java.util.function.IntPredicate;
import java.util.function.IntUnaryOperator;
public interface DataPalette {
@@ -149,27 +146,6 @@ public interface DataPalette {
}
}
/**
* Runs over all section coordinate indices that match the given predicate.
*
* @param idPredicate predicate to test ids
* @param coordinateConsumer consumer to run over applicable coordinate indices (not ids!)
* @see #idAt(int)
*/
void forEachMatchingCoordinate(IntPredicate idPredicate, IntConsumer coordinateConsumer);
/**
* Packs the section values into a compact long array as used by the protocol.
*
* @param bitsPerValue bits used per value
* @param entries number of values
* @param rawIds whether to pack raw ids instead of palette indexes (direct palette)
* @return compact long array of the values
*/
default long[] createPackedValues(final int bitsPerValue, final int entries, final boolean rawIds) {
return CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, entries, rawIds ? this::idAt : this::paletteIndexAt);
}
/**
* Returns the size of the palette.
*
@@ -22,13 +22,9 @@
*/
package com.viaversion.viaversion.api.minecraft.chunks;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.util.CompactArrayUtil;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.function.IntConsumer;
import java.util.function.IntPredicate;
import java.util.function.IntUnaryOperator;
public final class DataPaletteImpl implements DataPalette {
@@ -36,8 +32,8 @@ public final class DataPaletteImpl implements DataPalette {
private static final int DEFAULT_INITIAL_SIZE = 16;
private final IntArrayList palette;
private final Int2IntMap inversePalette;
private final int sizeBits;
private Int2IntMap inversePalette;
private ChunkData values;
public DataPaletteImpl(final int valuesLength) {
@@ -47,30 +43,11 @@ public final class DataPaletteImpl implements DataPalette {
public DataPaletteImpl(final int valuesLength, final int initialSize) {
values = new SingleChunkData(valuesLength);
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
// Pre-size the palette array
// Pre-size the palette array/map
palette = new IntArrayList(initialSize);
}
private Int2IntMap inversePalette() {
// Lazily build the inverse palette. Most palettes never need it
if (inversePalette == null) {
inversePalette = new Int2IntOpenHashMap(palette.size());
inversePalette.defaultReturnValue(-1);
for (int i = 0; i < palette.size(); i++) {
inversePalette.put(palette.getInt(i), i);
}
}
return inversePalette;
}
private Int2IntMap emptyInversePalette() {
if (inversePalette == null) {
inversePalette = new Int2IntOpenHashMap(palette.size());
inversePalette.defaultReturnValue(-1);
} else {
inversePalette.clear();
}
return inversePalette;
// To get an initial table size of initialSize, need to scale it down by load factor.
inversePalette = new Int2IntOpenHashMap((int) (initialSize * Int2IntOpenHashMap.DEFAULT_LOAD_FACTOR));
inversePalette.defaultReturnValue(-1);
}
@Override
@@ -86,7 +63,7 @@ public final class DataPaletteImpl implements DataPalette {
@Override
public void setIdAt(final int sectionCoordinate, final int id) {
int index = inversePalette().get(id);
int index = inversePalette.get(id);
if (index == -1) {
index = palette.size();
palette.add(id);
@@ -106,38 +83,6 @@ public final class DataPaletteImpl implements DataPalette {
values.set(sectionCoordinate, index);
}
/**
* Stores palette indexes from a compact long array, replacing all current values.
* The data is kept packed unless written to; reads extract bits the slow way, since almost all work will use replaceIds or will only have a few reads.
* <p>
* Only valid for local palettes (bitsPerValue &lt;= 8).
*
* @param data compact long array
* @param bitsPerValue bits per value
* @param valuesPerLong packked values per long
*/
public void setPaletteIndexes(final long[] data, final int bitsPerValue, final int valuesPerLong) {
Preconditions.checkArgument(bitsPerValue <= 8, "Cannot pack global palette");
values = new PackedChunkData(data, bitsPerValue, valuesPerLong, values.size());
}
@Override
public long[] createPackedValues(final int bitsPerValue, final int entries, final boolean rawIds) {
if (rawIds) {
return CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, entries, this::idAt);
}
if (values instanceof final PackedChunkData packed && packed.bitsPerValue == bitsPerValue) {
// Values were never modified and the width still matches - write them back as-is
return packed.data;
}
final int valuesPerLong = (char) (64 / bitsPerValue);
final long[] data = new long[(entries + valuesPerLong - 1) / valuesPerLong];
values.packInto(data, bitsPerValue);
return data;
}
@Override
public int size() {
return palette.size();
@@ -151,7 +96,7 @@ public final class DataPaletteImpl implements DataPalette {
@Override
public void setIdByIndex(final int index, final int id) {
final int oldId = palette.set(index, id);
if (oldId == id || inversePalette == null) return;
if (oldId == id) return;
inversePalette.put(id, index);
if (inversePalette.get(oldId) == index) {
@@ -167,7 +112,7 @@ public final class DataPaletteImpl implements DataPalette {
@Override
public void replaceId(final int oldId, final int newId) {
final int index = inversePalette().remove(oldId);
final int index = inversePalette.remove(oldId);
if (index == -1) return;
inversePalette.put(newId, index);
@@ -185,12 +130,12 @@ public final class DataPaletteImpl implements DataPalette {
return;
}
inversePalette.clear();
int writeIndex = 0;
int[] indexRemap = null;
int firstCollision = 0;
final int[] palette = this.palette.elements();
final Int2IntMap inversePalette = emptyInversePalette();
for (int readIndex = 0; readIndex < oldSize; readIndex++) {
final int mappedId = mapper.applyAsInt(palette[readIndex]);
final int existingIndex = inversePalette.putIfAbsent(mappedId, writeIndex);
@@ -227,51 +172,14 @@ public final class DataPaletteImpl implements DataPalette {
@Override
public void addId(final int id) {
if (inversePalette != null) {
inversePalette.put(id, palette.size());
}
inversePalette.put(id, palette.size());
palette.add(id);
}
private static final ThreadLocal<boolean[]> MATCHING_INDEXES = ThreadLocal.withInitial(() -> new boolean[ChunkSection.SIZE]);
@Override
public void forEachMatchingCoordinate(final IntPredicate idPredicate, final IntConsumer coordinateConsumer) {
final int size = size();
if (size > ChunkSection.SIZE) { // Shouldn't ever happen normally, but is technically possible...
for (int idx = 0, len = this.values.size(); idx < len; idx++) {
if (idPredicate.test(idAt(idx))) {
coordinateConsumer.accept(idx);
}
}
return;
}
// Instead of going through every single coordinate value (4096 for block sections), check the palette ids first.
// Reuse a thread-local array for quick checking against palette indexes.
final boolean[] matching = MATCHING_INDEXES.get();
boolean any = false;
for (int i = 0; i < size; i++) {
final boolean match = idPredicate.test(idByIndex(i));
matching[i] = match;
any |= match;
}
if (!any) {
return;
}
for (int idx = 0, len = this.values.size(); idx < len; idx++) {
if (matching[paletteIndexAt(idx)]) {
coordinateConsumer.accept(idx);
}
}
}
@Override
public void clear() {
palette.clear();
inversePalette = null;
inversePalette.clear();
}
interface ChunkData {
@@ -280,11 +188,6 @@ public final class DataPaletteImpl implements DataPalette {
void set(int idx, int val);
int size();
/**
* Packs all values into the given compact long array.
*/
void packInto(long[] data, int bitsPerValue);
}
private final class SingleChunkData implements ChunkData {
@@ -312,11 +215,6 @@ public final class DataPaletteImpl implements DataPalette {
public int size() {
return size;
}
@Override
public void packInto(final long[] data, final int bitsPerValue) {
// All values are 0, nothing to write
}
}
private final class ByteChunkData implements ChunkData {
@@ -326,10 +224,6 @@ public final class DataPaletteImpl implements DataPalette {
this.data = new byte[size];
}
public ByteChunkData(byte[] data) {
this.data = data;
}
@Override
public int get(int idx) {
return data[idx] & 0xFF;
@@ -350,11 +244,6 @@ public final class DataPaletteImpl implements DataPalette {
public int size() {
return data.length;
}
@Override
public void packInto(final long[] out, final int bitsPerValue) {
CompactArrayUtil.packWithPadding(data, out, bitsPerValue);
}
}
private static final class ShortChunkData implements ChunkData {
@@ -381,63 +270,6 @@ public final class DataPaletteImpl implements DataPalette {
public int size() {
return data.length;
}
@Override
public void packInto(final long[] out, final int bitsPerValue) {
CompactArrayUtil.packWithPadding(data, out, bitsPerValue);
}
}
/**
* Raw chunk data as read from the buffer.
*/
private final class PackedChunkData implements ChunkData {
private final long[] data;
private final int bitsPerValue;
private final int valuesPerLong;
private final long maxEntryValue;
private final int size;
private PackedChunkData(final long[] data, final int bitsPerValue, final int valuesPerLong, final int size) {
this.data = data;
this.bitsPerValue = bitsPerValue;
this.valuesPerLong = valuesPerLong;
this.size = size;
this.maxEntryValue = (1L << bitsPerValue) - 1;
}
@Override
public int get(final int idx) {
// Called so rarely that the cheap storage outweighs the more complex getter
final int cellIndex = idx / valuesPerLong;
final int bitIndex = (idx - cellIndex * valuesPerLong) * bitsPerValue;
return (int) (data[cellIndex] >>> bitIndex & maxEntryValue);
}
@Override
public void set(final int idx, final int val) {
// First write access, actually read out for fast value access
final ChunkData byteChunkData = extractData();
values = byteChunkData;
byteChunkData.set(idx, val);
}
private ChunkData extractData() {
final byte[] unpackedData = new byte[size];
CompactArrayUtil.unpackWithPadding(this.data, unpackedData, bitsPerValue);
return new ByteChunkData(unpackedData);
}
@Override
public int size() {
return size;
}
@Override
public void packInto(final long[] out, final int newBitsPerValue) {
// Always called with bitsPerValue != newBitsPerValue, which should only really happen if the server sends an unncessarily high bit width,
// or if the number of ids shrunk in replaceIds. Rare enough to not need its own special method
extractData().packInto(out, newBitsPerValue);
}
}
}
@@ -38,8 +38,6 @@ public interface CodecContext {
UserConnection connection();
Protocol<?, ?, ?, ?> protocol();
interface RegistryAccess {
UserConnection connection();
@@ -58,9 +58,7 @@ public interface Ops {
void writeMap(Consumer<MapSerializer> consumer);
default <V> void write(final Type<V> type, final V value) {
type.write(this, value);
}
<V> void write(final Type<V> type, final V value);
interface ListSerializer {
@@ -39,8 +39,8 @@ final class RegistryAccessImpl implements CodecContext.RegistryAccess {
private final boolean mapped;
RegistryAccessImpl(final Protocol<?, ?, ?, ?> protocol, final UserConnection connection) {
this.mappingData = Preconditions.checkNotNull(protocol.getMappingData(), "No mapping data present for protocol");
this.entityTracker = Preconditions.checkNotNull(protocol.getEntityRewriter().tracker(connection), "Entity tracker has to be added first");
this.mappingData = Preconditions.checkNotNull(protocol.getMappingData());
this.entityTracker = Preconditions.checkNotNull(protocol.getEntityRewriter().tracker(connection));
this.connection = connection;
this.mapped = false;
}
@@ -102,16 +102,17 @@ final class RegistryAccessImpl implements CodecContext.RegistryAccess {
public Key registryKey(final String registry, final int id) {
final KeyMappings mappings = entityTracker.registryKeys(registry);
Preconditions.checkNotNull(mappings, "No registry mappings for registry: %s", registry);
return keyOrUnknown(mappings.key(id), id);
final String identifier = id >= 0 && id < mappings.size() ? mappings.idToKey(id) : null;
return key(identifier, id);
}
private Key key(final FullMappings mappings, final int id) {
final Key key = mapped ? mappings.mappedKeyFromMappedId(id) : mappings.keyFromId(id);
return keyOrUnknown(key, id);
final String identifier = mapped ? mappings.mappedIdentifier(id) : mappings.identifier(id);
return key(identifier, id);
}
private Key keyOrUnknown(@Nullable final Key key, final int id) {
return key != null ? key : Key.of("viaversion", "unknown/" + id);
private Key key(@Nullable final String identifier, final int id) {
return identifier != null ? Key.of(identifier) : Key.of("viaversion", "unknown/" + id);
}
@Override
@@ -270,7 +270,7 @@ public final class StructuredDataContainer implements Copyable {
@Override
public StructuredDataContainer copy() {
final Reference2ObjectOpenHashMap<StructuredDataKey<?>, StructuredData<?>> map = new Reference2ObjectOpenHashMap<>(data.size());
final Reference2ObjectOpenHashMap<StructuredDataKey<?>, StructuredData<?>> map = new Reference2ObjectOpenHashMap<>();
for (final StructuredData<?> value : data.values()) {
map.put(value.key(), value.copy());
}
@@ -30,15 +30,14 @@ import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.RegistryKey;
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_20_5;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_11;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_2;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_5;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrim1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrim26_3;
import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrimMaterial1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.trim.ArmorTrimMaterial26_3;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrimMaterial;
import com.viaversion.viaversion.api.minecraft.item.data.AttackRange;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21;
@@ -47,14 +46,11 @@ import com.viaversion.viaversion.api.minecraft.item.data.Bee;
import com.viaversion.viaversion.api.minecraft.item.data.BlockEntityData;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks;
import com.viaversion.viaversion.api.minecraft.item.data.BreakSound;
import com.viaversion.viaversion.api.minecraft.item.data.BrewingFuel;
import com.viaversion.viaversion.api.minecraft.item.data.Compostable;
import com.viaversion.viaversion.api.minecraft.item.data.consumable.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.CookingFuel;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.CustomModelData1_21_4;
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant26_1;
import com.viaversion.viaversion.api.minecraft.item.data.DamageType;
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
import com.viaversion.viaversion.api.minecraft.item.data.DebugStickState;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
@@ -75,14 +71,12 @@ import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable.Jukebox
import com.viaversion.viaversion.api.minecraft.item.data.KineticWeapon;
import com.viaversion.viaversion.api.minecraft.item.data.LockCode;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.MobVisibility;
import com.viaversion.viaversion.api.minecraft.item.data.PiercingWeapon;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations1_20_5;
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.ProvidesBannerPatterns;
import com.viaversion.viaversion.api.minecraft.item.data.trim.ProvidesTrimMaterial1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.ProvidesTrimMaterial;
import com.viaversion.viaversion.api.minecraft.item.data.Repairable;
import com.viaversion.viaversion.api.minecraft.item.data.SignText;
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
import com.viaversion.viaversion.api.minecraft.item.data.SwingAnimation;
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
@@ -91,7 +85,6 @@ import com.viaversion.viaversion.api.minecraft.item.data.TropicalFishPattern;
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.minecraft.item.data.UseEffects;
import com.viaversion.viaversion.api.minecraft.item.data.VillagerFood;
import com.viaversion.viaversion.api.minecraft.item.data.Weapon;
import com.viaversion.viaversion.api.minecraft.item.data.WritableBook;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
@@ -124,7 +117,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Unit> UNBREAKABLE1_21_5 = new StructuredDataKey<>("unbreakable", Types.EMPTY);
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TEXT_COMPONENT_TAG);
public static final StructuredDataKey<Float> MINIMUM_ATTACK_CHARGE = new StructuredDataKey<>("minimum_attack_charge", Types.FLOAT);
public static final StructuredDataKey<Either<Integer, String>> DAMAGE_TYPE1_21_11 = new StructuredDataKey<>("damage_type", new SynchronizedRegistryEitherType(RegistryKey.of("damage_type")));
public static final StructuredDataKey<DamageType> DAMAGE_TYPE1_21_11 = new StructuredDataKey<>("damage_type", DamageType.TYPE1_21_11);
public static final StructuredDataKey<Integer> DAMAGE_TYPE26_1 = new StructuredDataKey<>("damage_type", new SynchronizedRegistryValueType(RegistryKey.of("damage_type")));
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TEXT_COMPONENT_TAG);
public static final StructuredDataKey<ItemModel> ITEM_MODEL = new StructuredDataKey<>("item_model", ItemModel.TYPE);
@@ -151,10 +144,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_20_5);
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_21);
public static final StructuredDataKey<FoodProperties1_21_2> FOOD1_21_2 = new StructuredDataKey<>("food", FoodProperties1_21_2.TYPE);
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_2 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE1_21_2);
// 1.21.5-1.21.9 only, animation id 5 was still named spear
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_5 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE1_21_5);
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE26_3 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE26_3);
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_2 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE);
public static final StructuredDataKey<UseCooldown> USE_COOLDOWN = new StructuredDataKey<>("use_cooldown", UseCooldown.TYPE);
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY);
public static final StructuredDataKey<DamageResistant1_21_2> DAMAGE_RESISTANT1_21_2 = new StructuredDataKey<>("damage_resistant", DamageResistant1_21_2.TYPE);
@@ -170,18 +160,13 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Repairable> REPAIRABLE = new StructuredDataKey<>("repairable", Repairable.TYPE);
public static final StructuredDataKey<Unit> GLIDER = new StructuredDataKey<>("glider", Types.EMPTY);
public static final StructuredDataKey<Key> TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.IDENTIFIER);
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION1_21_2 = new StructuredDataKey<>("death_protection", DeathProtection.TYPE1_21_2);
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION26_3 = new StructuredDataKey<>("death_protection", DeathProtection.TYPE26_3);
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE);
public static final StructuredDataKey<BlocksAttacks> BLOCKS_ATTACKS1_21_5 = new StructuredDataKey<>("blocks_attacks", BlocksAttacks.TYPE1_21_5);
public static final StructuredDataKey<BlocksAttacks> BLOCKS_ATTACKS26_1 = new StructuredDataKey<>("blocks_attacks", BlocksAttacks.TYPE26_1);
public static final StructuredDataKey<PiercingWeapon> PIERCING_WEAPON = new StructuredDataKey<>("piercing_weapon", PiercingWeapon.TYPE);
public static final StructuredDataKey<KineticWeapon> KINETIC_WEAPON = new StructuredDataKey<>("kinetic_weapon", KineticWeapon.TYPE);
public static final StructuredDataKey<SwingAnimation> SWING_ANIMATION = new StructuredDataKey<>("swing_animation", SwingAnimation.TYPE);
public static final StructuredDataKey<SwingAnimation> ATTACK_ANIMATION = new StructuredDataKey<>("attack_animation", SwingAnimation.TYPE);
public static final StructuredDataKey<SwingAnimation> INTERACT_ANIMATION = new StructuredDataKey<>("interact_animation", SwingAnimation.TYPE);
public static final StructuredDataKey<Integer> ADDITIONAL_TRADE_COST = new StructuredDataKey<>("additional_trade_cost", Types.VAR_INT);
public static final StructuredDataKey<Integer> BLOCK_TRANSFORMER = new StructuredDataKey<>("block_transformer", new SynchronizedRegistryValueType(RegistryKey.of("block_transformer")));
public static final StructuredDataKey<VillagerFood> VILLAGER_FOOD = new StructuredDataKey<>("villager_food", VillagerFood.TYPE);
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS1_20_5 = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE1_20_5);
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS1_21_5 = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE1_21_5);
public static final StructuredDataKey<Integer> DYE = new StructuredDataKey<>("dye", EnumTypes.DYE_COLOR);
@@ -197,11 +182,10 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
public static final StructuredDataKey<WritableBook> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", WritableBook.TYPE);
public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE);
public static final StructuredDataKey<ArmorTrim1_20_5> TRIM1_20_5 = new StructuredDataKey<>("trim", ArmorTrim1_20_5.TYPE1_20_5);
public static final StructuredDataKey<ArmorTrim1_20_5> TRIM1_21_2 = new StructuredDataKey<>("trim", ArmorTrim1_20_5.TYPE1_21_2);
public static final StructuredDataKey<ArmorTrim1_20_5> TRIM1_21_4 = new StructuredDataKey<>("trim", ArmorTrim1_20_5.TYPE1_21_4);
public static final StructuredDataKey<ArmorTrim1_20_5> TRIM1_21_5 = new StructuredDataKey<>("trim", ArmorTrim1_20_5.TYPE1_21_5);
public static final StructuredDataKey<ArmorTrim26_3> TRIM26_3 = new StructuredDataKey<>("trim", ArmorTrim26_3.TYPE);
public static final StructuredDataKey<ArmorTrim> TRIM1_20_5 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_20_5);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_2 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_2);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_4 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_4);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_5 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_5);
public static final StructuredDataKey<DebugStickState> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", DebugStickState.TYPE);
public static final StructuredDataKey<CompoundTag> ENTITY_DATA1_20_5 = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<EntityData> ENTITY_DATA1_21_9 = new StructuredDataKey<>("entity_data", EntityData.TYPE);
@@ -209,13 +193,11 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA1_20_5 = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<BlockEntityData> BLOCK_ENTITY_DATA1_21_9 = new StructuredDataKey<>("block_entity_data", BlockEntityData.TYPE);
public static final StructuredDataKey<Holder<Instrument1_20_5>> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE1_21_2);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
public static final StructuredDataKey<EitherHolder<Instrument1_21_2>> INSTRUMENT1_21_5 = new StructuredDataKey<>("instrument", Instrument1_21_2.EITHER_HOLDER_TYPE);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT26_1 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE1_21_2);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT26_3 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE26_3);
public static final StructuredDataKey<ProvidesTrimMaterial1_20_5> PROVIDES_TRIM_MATERIAL1_21_5 = new StructuredDataKey<>("provides_trim_material", ProvidesTrimMaterial1_20_5.TYPE);
public static final StructuredDataKey<Holder<ArmorTrimMaterial1_20_5>> PROVIDES_TRIM_MATERIAL26_1 = new StructuredDataKey<>("provides_trim_material", ArmorTrimMaterial1_20_5.TYPE1_21_5);
public static final StructuredDataKey<Holder<ArmorTrimMaterial26_3>> PROVIDES_TRIM_MATERIAL26_3 = new StructuredDataKey<>("provides_trim_material", ArmorTrimMaterial26_3.TYPE);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT26_1 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
public static final StructuredDataKey<ProvidesTrimMaterial> PROVIDES_TRIM_MATERIAL1_21_5 = new StructuredDataKey<>("provides_trim_material", ProvidesTrimMaterial.TYPE);
public static final StructuredDataKey<Holder<ArmorTrimMaterial>> PROVIDES_TRIM_MATERIAL26_1 = new StructuredDataKey<>("provides_trim_material", ArmorTrimMaterial.TYPE1_21_5);
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT);
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE1_21 = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE1_21);
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE1_21_5 = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE1_21_5);
@@ -231,24 +213,14 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Key> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Types.IDENTIFIER);
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", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<PotDecorations1_20_5> POT_DECORATIONS1_20_5 = new StructuredDataKey<>("pot_decorations", PotDecorations1_20_5.TYPE);
// 26.3+ pot decorations are in their own key classes
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE);
public static final StructuredDataKey<Bee[]> BEES1_20_5 = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE1_20_5);
public static final StructuredDataKey<Bee[]> BEES1_21_9 = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE1_21_9);
public static final StructuredDataKey<Tag> LOCK1_20_5 = new StructuredDataKey<>("lock", Types.TAG);
public static final StructuredDataKey<LockCode> LOCK1_21_2 = new StructuredDataKey<>("lock", LockCode.TYPE);
public static final StructuredDataKey<CompoundTag> CONTAINER_LOOT = new StructuredDataKey<>("container_loot", Types.COMPOUND_TAG);
public static final StructuredDataKey<BreakSound> BREAK_SOUND = new StructuredDataKey<>("break_sound", BreakSound.TYPE);
public static final StructuredDataKey<Compostable> COMPOSTABLE = new StructuredDataKey<>("compostable", Compostable.TYPE);
public static final StructuredDataKey<CookingFuel> COOKING_FUEL = new StructuredDataKey<>("cooking_fuel", CookingFuel.TYPE);
public static final StructuredDataKey<BrewingFuel> BREWING_FUEL = new StructuredDataKey<>("brewing_fuel", BrewingFuel.TYPE);
public static final StructuredDataKey<MobVisibility> MOB_VISIBILITY = new StructuredDataKey<>("mob_visibility", MobVisibility.TYPE);
public static final StructuredDataKey<Integer> PROVIDES_POTTERY_PATTERN = new StructuredDataKey<>("provides_pottery_pattern", new SynchronizedRegistryValueType(RegistryKey.of("decorated_pot_pattern")));
public static final StructuredDataKey<SignText> SIGN_TEXT_FRONT = new StructuredDataKey<>("sign_text_front", SignText.TYPE);
public static final StructuredDataKey<SignText> SIGN_TEXT_BACK = new StructuredDataKey<>("sign_text_back", SignText.TYPE);
public static final StructuredDataKey<Unit> WAXED = new StructuredDataKey<>("waxed", Types.EMPTY);
public static final StructuredDataKey<Integer> CUSHION_COLOR = new StructuredDataKey<>("cushion/color", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<Holder<SoundEvent>> BREAK_SOUND = new StructuredDataKey<>("break_sound", Types.SOUND_EVENT);
public static final StructuredDataKey<Integer> VILLAGER_VARIANT = new StructuredDataKey<>("villager/variant", EnumTypes.VILLAGER_TYPE);
public static final StructuredDataKey<Integer> WOLF_VARIANT = new StructuredDataKey<>("wolf/variant", new SynchronizedRegistryValueType(RegistryKey.of("wolf_variant")));
@@ -33,9 +33,8 @@ public class StructuredDataKeys1_20_5 extends VersionedStructuredDataKeys {
public final StructuredDataKey<Item[]> bundleContents;
public StructuredDataKeys1_20_5(final VersionedTypesHolder types) {
// Also includes later vanilla limits
this.container = add("container", types.itemArray().withMaxLength(256));
this.chargedProjectiles = add("charged_projectiles", types.itemArray().withMaxLength(1024));
this.bundleContents = add("bundle_contents", types.itemArray().withMaxLength(1024));
this.container = add("container", types.itemArray());
this.chargedProjectiles = add("charged_projectiles", types.itemArray());
this.bundleContents = add("bundle_contents", types.itemArray());
}
}
@@ -36,8 +36,8 @@ public class StructuredDataKeys1_21_2 extends VersionedStructuredDataKeys {
public StructuredDataKeys1_21_2(final VersionedTypesHolder types) {
this.container = add("container", new ContainerContentsType(types.optionalItemTemplate()));
this.chargedProjectiles = add("charged_projectiles", types.itemTemplateArray().withMaxLength(1024));
this.bundleContents = add("bundle_contents", types.itemTemplateArray().withMaxLength(1024));
this.chargedProjectiles = add("charged_projectiles", types.itemTemplateArray());
this.bundleContents = add("bundle_contents", types.itemTemplateArray());
this.useRemainder = add("use_remainder", types.itemTemplate());
}
}
@@ -1,37 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.data.version;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public class StructuredDataKeys26_2 extends StructuredDataKeys1_21_11 {
public final StructuredDataKey<Item> sulfurCubeContent;
public StructuredDataKeys26_2(final VersionedTypesHolder types) {
super(types);
this.sulfurCubeContent = add("sulfur_cube_content", types.itemTemplate());
}
}
@@ -1,37 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.data.version;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations26_3;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public class StructuredDataKeys26_3 extends StructuredDataKeys26_2 {
public final StructuredDataKey<PotDecorations26_3> potDecorations;
public StructuredDataKeys26_3(final VersionedTypesHolder types) {
super(types);
this.potDecorations = add("pot_decorations", new PotDecorations26_3.PotDecorationsType(types.optionalItemTemplate()));
}
}
@@ -1,332 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes26_2 implements EntityType {
ENTITY(null, null),
AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(ENTITY),
EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(ENTITY),
ITEM(ENTITY),
TNT(ENTITY),
OMINOUS_ITEM_SPAWNER(ENTITY),
MARKER(ENTITY),
LIGHTNING_BOLT(ENTITY),
INTERACTION(ENTITY),
DISPLAY(ENTITY, null),
BLOCK_DISPLAY(DISPLAY),
ITEM_DISPLAY(DISPLAY),
TEXT_DISPLAY(DISPLAY),
// Hanging entities
HANGING_ENTITY(ENTITY, null),
LEASH_KNOT(HANGING_ENTITY),
PAINTING(HANGING_ENTITY),
ITEM_FRAME(HANGING_ENTITY),
GLOW_ITEM_FRAME(ITEM_FRAME),
// Projectiles
PROJECTILE(ENTITY, null),
ITEM_PROJECTILE(PROJECTILE, null),
SNOWBALL(ITEM_PROJECTILE),
ENDER_PEARL(ITEM_PROJECTILE),
EGG(ITEM_PROJECTILE),
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
FIREWORK_ROCKET(PROJECTILE),
LLAMA_SPIT(PROJECTILE),
SHULKER_BULLET(PROJECTILE),
FISHING_BOBBER(PROJECTILE),
WITHER_SKULL(PROJECTILE),
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
ABSTRACT_THROWN_POTION(ITEM_PROJECTILE, null),
SPLASH_POTION(ABSTRACT_THROWN_POTION),
LINGERING_POTION(ABSTRACT_THROWN_POTION),
ABSTRACT_ARROW(PROJECTILE, null),
ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(ABSTRACT_ARROW),
ABSTRACT_FIREBALL(ENTITY, null),
FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(ABSTRACT_FIREBALL),
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
// Vehicles
VEHICLE(ENTITY, null),
ABSTRACT_MINECART(VEHICLE, null),
MINECART(ABSTRACT_MINECART),
FURNACE_MINECART(ABSTRACT_MINECART),
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
TNT_MINECART(ABSTRACT_MINECART),
SPAWNER_MINECART(ABSTRACT_MINECART),
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
ABSTRACT_BOAT(VEHICLE, null),
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
ACACIA_BOAT(ABSTRACT_BOAT),
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
BAMBOO_RAFT(ABSTRACT_BOAT),
BIRCH_BOAT(ABSTRACT_BOAT),
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
CHERRY_BOAT(ABSTRACT_BOAT),
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
DARK_OAK_BOAT(ABSTRACT_BOAT),
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
JUNGLE_BOAT(ABSTRACT_BOAT),
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
MANGROVE_BOAT(ABSTRACT_BOAT),
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
OAK_BOAT(ABSTRACT_BOAT),
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
PALE_OAK_BOAT(ABSTRACT_BOAT),
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
SPRUCE_BOAT(ABSTRACT_BOAT),
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
// Living entities as a larger subclass
LIVING_ENTITY(ENTITY, null),
ARMOR_STAND(LIVING_ENTITY),
// Players
AVATAR(LIVING_ENTITY, null),
MANNEQUIN(AVATAR),
PLAYER(AVATAR),
// Mobs as a larger subclass
MOB(LIVING_ENTITY, null),
ENDER_DRAGON(MOB),
// Ambient mobs
AMBIENT_CREATURE(MOB, null),
BAT(AMBIENT_CREATURE),
// Flying mobs
FLYING_MOB(MOB, null),
GHAST(FLYING_MOB),
PHANTOM(FLYING_MOB),
// Pathfinder mobs and its subclasses
PATHFINDER_MOB(MOB, null),
ALLAY(PATHFINDER_MOB),
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
SNOW_GOLEM(ABSTRACT_GOLEM),
IRON_GOLEM(ABSTRACT_GOLEM),
SHULKER(ABSTRACT_GOLEM),
COPPER_GOLEM(ABSTRACT_GOLEM),
// Ageable mobs and (tamable) animals
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
VILLAGER(ABSTRACT_VILLAGER),
WANDERING_TRADER(ABSTRACT_VILLAGER),
ABSTRACT_CUBE_MOB(ABSTRACT_AGEABLE, null),
SLIME(ABSTRACT_CUBE_MOB),
MAGMA_CUBE(ABSTRACT_CUBE_MOB),
SULFUR_CUBE(ABSTRACT_CUBE_MOB),
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
AXOLOTL(ABSTRACT_ANIMAL),
CHICKEN(ABSTRACT_ANIMAL),
PANDA(ABSTRACT_ANIMAL),
PIG(ABSTRACT_ANIMAL),
POLAR_BEAR(ABSTRACT_ANIMAL),
RABBIT(ABSTRACT_ANIMAL),
SHEEP(ABSTRACT_ANIMAL),
BEE(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
FROG(ABSTRACT_ANIMAL),
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
HAPPY_GHAST(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
MOOSHROOM(ABSTRACT_COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
ABSTRACT_NAUTILUS(TAMABLE_ANIMAL, null),
NAUTILUS(ABSTRACT_NAUTILUS),
ZOMBIE_NAUTILUS(ABSTRACT_NAUTILUS),
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(ABSTRACT_HORSE),
CAMEL(ABSTRACT_HORSE),
CAMEL_HUSK(CAMEL),
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(ABSTRACT_CHESTED_HORSE),
MULE(ABSTRACT_CHESTED_HORSE),
LLAMA(ABSTRACT_CHESTED_HORSE),
TRADER_LLAMA(LLAMA),
// Monsters
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
BLAZE(ABSTRACT_MONSTER),
CREEPER(ABSTRACT_MONSTER),
ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(ABSTRACT_MONSTER),
GIANT(ABSTRACT_MONSTER),
SILVERFISH(ABSTRACT_MONSTER),
VEX(ABSTRACT_MONSTER),
WITHER(ABSTRACT_MONSTER),
BREEZE(ABSTRACT_MONSTER),
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
CREAKING(ABSTRACT_MONSTER),
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(ABSTRACT_SKELETON),
BOGGED(ABSTRACT_SKELETON),
PARCHED(ABSTRACT_SKELETON),
ZOMBIE(ABSTRACT_MONSTER),
DROWNED(ZOMBIE),
HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(ZOMBIE),
GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(GUARDIAN),
SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(SPIDER),
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
// Water mobs
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
DOLPHIN(AGEABLE_WATER_CREATURE),
SQUID(AGEABLE_WATER_CREATURE),
GLOW_SQUID(SQUID),
WATER_ANIMAL(PATHFINDER_MOB, null),
ABSTRACT_FISH(WATER_ANIMAL, null),
PUFFERFISH(ABSTRACT_FISH),
TADPOLE(ABSTRACT_FISH),
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
COD(ABSTRACT_SCHOOLING_FISH),
SALMON(ABSTRACT_SCHOOLING_FISH),
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
// Raiders
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
WITCH(ABSTRACT_RAIDER),
RAVAGER(ABSTRACT_RAIDER),
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
VINDICATOR(ABSTRACT_ILLAGER),
PILLAGER(ABSTRACT_ILLAGER),
EVOKER(SPELLCASTER_ILLAGER),
ILLUSIONER(SPELLCASTER_ILLAGER);
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final EntityType parent;
private final String identifier;
private int id = -1;
EntityTypes26_2(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes26_2(final EntityType parent, @Nullable final String identifier) {
this.parent = parent;
this.identifier = identifier;
}
@Override
public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
}
return id;
}
@Override
public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent;
}
@Override
public boolean isAbstractType() {
return identifier == null;
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
}
}
@@ -1,336 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes26_3 implements EntityType {
ENTITY(null, null),
AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(ENTITY),
EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(ENTITY),
ITEM(ENTITY),
TNT(ENTITY),
OMINOUS_ITEM_SPAWNER(ENTITY),
MARKER(ENTITY),
LIGHTNING_BOLT(ENTITY),
INTERACTION(ENTITY),
DISPLAY(ENTITY, null),
BLOCK_DISPLAY(DISPLAY),
ITEM_DISPLAY(DISPLAY),
TEXT_DISPLAY(DISPLAY),
// Hanging entities
HANGING_ENTITY(ENTITY, null),
LEASH_KNOT(HANGING_ENTITY),
PAINTING(HANGING_ENTITY),
ITEM_FRAME(HANGING_ENTITY),
GLOW_ITEM_FRAME(ITEM_FRAME),
CUSHION(ENTITY),
// Projectiles
PROJECTILE(ENTITY, null),
ITEM_PROJECTILE(PROJECTILE, null),
SNOWBALL(ITEM_PROJECTILE),
ENDER_PEARL(ITEM_PROJECTILE),
EGG(ITEM_PROJECTILE),
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
FIREWORK_ROCKET(PROJECTILE),
LLAMA_SPIT(PROJECTILE),
SHULKER_BULLET(PROJECTILE),
FISHING_BOBBER(PROJECTILE),
WITHER_SKULL(PROJECTILE),
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
ABSTRACT_THROWN_POTION(ITEM_PROJECTILE, null),
SPLASH_POTION(ABSTRACT_THROWN_POTION),
LINGERING_POTION(ABSTRACT_THROWN_POTION),
ABSTRACT_ARROW(PROJECTILE, null),
ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(ABSTRACT_ARROW),
ABSTRACT_FIREBALL(ENTITY, null),
FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(ABSTRACT_FIREBALL),
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
// Vehicles
VEHICLE(ENTITY, null),
ABSTRACT_MINECART(VEHICLE, null),
MINECART(ABSTRACT_MINECART),
FURNACE_MINECART(ABSTRACT_MINECART),
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
TNT_MINECART(ABSTRACT_MINECART),
SPAWNER_MINECART(ABSTRACT_MINECART),
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
ABSTRACT_BOAT(VEHICLE, null),
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
ACACIA_BOAT(ABSTRACT_BOAT),
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
BAMBOO_RAFT(ABSTRACT_BOAT),
BIRCH_BOAT(ABSTRACT_BOAT),
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
CHERRY_BOAT(ABSTRACT_BOAT),
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
DARK_OAK_BOAT(ABSTRACT_BOAT),
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
JUNGLE_BOAT(ABSTRACT_BOAT),
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
MANGROVE_BOAT(ABSTRACT_BOAT),
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
OAK_BOAT(ABSTRACT_BOAT),
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
PALE_OAK_BOAT(ABSTRACT_BOAT),
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
SPRUCE_BOAT(ABSTRACT_BOAT),
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
POPLAR_BOAT(ABSTRACT_BOAT),
POPLAR_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
// Living entities as a larger subclass
LIVING_ENTITY(ENTITY, null),
ARMOR_STAND(LIVING_ENTITY),
// Players
AVATAR(LIVING_ENTITY, null),
MANNEQUIN(AVATAR),
PLAYER(AVATAR),
// Mobs as a larger subclass
MOB(LIVING_ENTITY, null),
ENDER_DRAGON(MOB),
// Ambient mobs
AMBIENT_CREATURE(MOB, null),
BAT(AMBIENT_CREATURE),
// Flying mobs
FLYING_MOB(MOB, null),
GHAST(FLYING_MOB),
PHANTOM(FLYING_MOB),
// Pathfinder mobs and its subclasses
PATHFINDER_MOB(MOB, null),
ALLAY(PATHFINDER_MOB),
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
SNOW_GOLEM(ABSTRACT_GOLEM),
IRON_GOLEM(ABSTRACT_GOLEM),
SHULKER(ABSTRACT_GOLEM),
COPPER_GOLEM(ABSTRACT_GOLEM),
// Ageable mobs and (tamable) animals
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
VILLAGER(ABSTRACT_VILLAGER),
WANDERING_TRADER(ABSTRACT_VILLAGER),
ABSTRACT_CUBE_MOB(ABSTRACT_AGEABLE, null),
SLIME(ABSTRACT_CUBE_MOB),
MAGMA_CUBE(ABSTRACT_CUBE_MOB),
SULFUR_CUBE(ABSTRACT_CUBE_MOB),
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
AXOLOTL(ABSTRACT_ANIMAL),
CHICKEN(ABSTRACT_ANIMAL),
PANDA(ABSTRACT_ANIMAL),
PIG(ABSTRACT_ANIMAL),
POLAR_BEAR(ABSTRACT_ANIMAL),
RABBIT(ABSTRACT_ANIMAL),
SHEEP(ABSTRACT_ANIMAL),
BEE(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
FROG(ABSTRACT_ANIMAL),
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
HAPPY_GHAST(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
MOOSHROOM(ABSTRACT_COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
ABSTRACT_NAUTILUS(TAMABLE_ANIMAL, null),
NAUTILUS(ABSTRACT_NAUTILUS),
ZOMBIE_NAUTILUS(ABSTRACT_NAUTILUS),
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(ABSTRACT_HORSE),
CAMEL(ABSTRACT_HORSE),
CAMEL_HUSK(CAMEL),
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(ABSTRACT_CHESTED_HORSE),
MULE(ABSTRACT_CHESTED_HORSE),
LLAMA(ABSTRACT_CHESTED_HORSE),
TRADER_LLAMA(LLAMA),
// Monsters
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
BLAZE(ABSTRACT_MONSTER),
CREEPER(ABSTRACT_MONSTER),
ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(ABSTRACT_MONSTER),
GIANT(ABSTRACT_MONSTER),
SILVERFISH(ABSTRACT_MONSTER),
VEX(ABSTRACT_MONSTER),
WITHER(ABSTRACT_MONSTER),
BREEZE(ABSTRACT_MONSTER),
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
CREAKING(ABSTRACT_MONSTER),
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(ABSTRACT_SKELETON),
BOGGED(ABSTRACT_SKELETON),
PARCHED(ABSTRACT_SKELETON),
ZOMBIE(ABSTRACT_MONSTER),
DROWNED(ZOMBIE),
HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(ZOMBIE),
GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(GUARDIAN),
SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(SPIDER),
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
// Water mobs
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
DOLPHIN(AGEABLE_WATER_CREATURE),
SQUID(AGEABLE_WATER_CREATURE),
GLOW_SQUID(SQUID),
WATER_ANIMAL(PATHFINDER_MOB, null),
ABSTRACT_FISH(WATER_ANIMAL, null),
PUFFERFISH(ABSTRACT_FISH),
TADPOLE(ABSTRACT_FISH),
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
COD(ABSTRACT_SCHOOLING_FISH),
SALMON(ABSTRACT_SCHOOLING_FISH),
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
// Raiders
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
WITCH(ABSTRACT_RAIDER),
RAVAGER(ABSTRACT_RAIDER),
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
VINDICATOR(ABSTRACT_ILLAGER),
PILLAGER(ABSTRACT_ILLAGER),
EVOKER(SPELLCASTER_ILLAGER),
ILLUSIONER(SPELLCASTER_ILLAGER);
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final EntityType parent;
private final String identifier;
private int id = -1;
EntityTypes26_3(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes26_3(final EntityType parent, @Nullable final String identifier) {
this.parent = parent;
this.identifier = identifier;
}
@Override
public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
}
return id;
}
@Override
public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent;
}
@Override
public boolean isAbstractType() {
return identifier == null;
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
}
}
@@ -1,83 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entitydata.types;
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public final class EntityDataTypes26_3 extends AbstractEntityDataTypes {
public final EntityDataType byteType = add(0, Types.BYTE);
public final EntityDataType varIntType = add(1, Types.VAR_INT);
public final EntityDataType longType = add(2, Types.VAR_LONG);
public final EntityDataType floatType = add(3, Types.FLOAT);
public final EntityDataType stringType = add(4, Types.STRING);
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
public final EntityDataType itemType;
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
public final EntityDataType optionalBlockPositionType = add(11, Types.OPTIONAL_POSITION_1_14);
public final EntityDataType directionType = add(12, Types.VAR_INT);
public final EntityDataType optionalUUIDType = add(13, Types.OPTIONAL_UUID);
public final EntityDataType blockStateType = add(14, Types.VAR_INT);
public final EntityDataType optionalBlockStateType = add(15, Types.VAR_INT);
public final EntityDataType particleType;
public final EntityDataType particlesType;
public final EntityDataType villagerDataType = add(18, Types.VILLAGER_DATA);
public final EntityDataType optionalVarIntType = add(19, Types.OPTIONAL_VAR_INT);
public final EntityDataType poseType = add(20, Types.VAR_INT);
public final EntityDataType catVariantType = add(21, Types.VAR_INT);
public final EntityDataType catSoundVariant = add(22, Types.VAR_INT);
public final EntityDataType cowVariantType = add(23, Types.VAR_INT);
public final EntityDataType cowSoundVariant = add(24, Types.VAR_INT);
public final EntityDataType wolfVariantType = add(25, Types.VAR_INT);
public final EntityDataType wolfSoundVariantType = add(26, Types.VAR_INT);
public final EntityDataType frogVariantType = add(27, Types.VAR_INT);
public final EntityDataType pigVariantType = add(28, Types.VAR_INT);
public final EntityDataType pigSoundVariant = add(29, Types.VAR_INT);
public final EntityDataType chickenVariantType = add(30, Types.VAR_INT);
public final EntityDataType chickenSoundVariant = add(31, Types.VAR_INT);
public final EntityDataType zombieNautilusVariantType = add(32, Types.VAR_INT);
public final EntityDataType optionalGlobalPosition = add(33, Types.OPTIONAL_GLOBAL_POSITION);
public final EntityDataType paintingVariantType = add(34, PaintingVariant.TYPE1_21_2);
public final EntityDataType snifferState = add(35, Types.VAR_INT);
public final EntityDataType armadilloState = add(36, Types.VAR_INT);
public final EntityDataType copperGolemState = add(37, Types.VAR_INT);
public final EntityDataType weatheringCopperState = add(38, Types.VAR_INT);
public final EntityDataType vector3FType = add(39, Types.VECTOR3F);
public final EntityDataType quaternionType = add(40, Types.QUATERNION);
public final EntityDataType mannequinProfileType = add(41, Types.RESOLVABLE_PROFILE);
public final EntityDataType humanoidArmType = add(42, Types.VAR_INT);
public final EntityDataType dyeColorType = add(43, Types.VAR_INT);
public EntityDataTypes26_3(final VersionedTypesHolder types) {
super(44);
this.itemType = add(7, types.item());
this.particleType = add(16, types.particle());
this.particlesType = add(17, types.particles());
}
}
@@ -20,7 +20,7 @@
* 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.trim;
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
@@ -30,86 +30,86 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record ArmorTrim1_20_5(Holder<ArmorTrimMaterial1_20_5> material, Holder<ArmorTrimPattern> pattern,
boolean showInTooltip) implements Rewritable {
public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern,
boolean showInTooltip) implements Rewritable {
public ArmorTrim1_20_5(Holder<ArmorTrimMaterial1_20_5> material, Holder<ArmorTrimPattern> pattern) {
public ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern) {
this(material, pattern, true);
}
public static final Type<ArmorTrim1_20_5> TYPE1_20_5 = new Type<>(ArmorTrim1_20_5.class) {
public static final Type<ArmorTrim> TYPE1_20_5 = new Type<>(ArmorTrim.class) {
@Override
public ArmorTrim1_20_5 read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial1_20_5> material = ArmorTrimMaterial1_20_5.TYPE1_20_5.read(buffer);
public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_20_5.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE1_20_5.read(buffer);
final boolean showInTooltip = buffer.readBoolean();
return new ArmorTrim1_20_5(material, pattern, showInTooltip);
return new ArmorTrim(material, pattern, showInTooltip);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim1_20_5 value) {
ArmorTrimMaterial1_20_5.TYPE1_20_5.write(buffer, value.material);
public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE1_20_5.write(buffer, value.material);
ArmorTrimPattern.TYPE1_20_5.write(buffer, value.pattern);
buffer.writeBoolean(value.showInTooltip);
}
};
public static final Type<ArmorTrim1_20_5> TYPE1_21_2 = new Type<>(ArmorTrim1_20_5.class) {
public static final Type<ArmorTrim> TYPE1_21_2 = new Type<>(ArmorTrim.class) {
@Override
public ArmorTrim1_20_5 read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial1_20_5> material = ArmorTrimMaterial1_20_5.TYPE1_21_2.read(buffer);
public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_2.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE1_20_5.read(buffer);
final boolean showInTooltip = buffer.readBoolean();
return new ArmorTrim1_20_5(material, pattern, showInTooltip);
return new ArmorTrim(material, pattern, showInTooltip);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim1_20_5 value) {
ArmorTrimMaterial1_20_5.TYPE1_21_2.write(buffer, value.material);
public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE1_21_2.write(buffer, value.material);
ArmorTrimPattern.TYPE1_20_5.write(buffer, value.pattern);
buffer.writeBoolean(value.showInTooltip);
}
};
public static final Type<ArmorTrim1_20_5> TYPE1_21_4 = new Type<>(ArmorTrim1_20_5.class) {
public static final Type<ArmorTrim> TYPE1_21_4 = new Type<>(ArmorTrim.class) {
@Override
public ArmorTrim1_20_5 read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial1_20_5> material = ArmorTrimMaterial1_20_5.TYPE1_21_4.read(buffer);
public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_4.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE1_20_5.read(buffer);
final boolean showInTooltip = buffer.readBoolean();
return new ArmorTrim1_20_5(material, pattern, showInTooltip);
return new ArmorTrim(material, pattern, showInTooltip);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim1_20_5 value) {
ArmorTrimMaterial1_20_5.TYPE1_21_4.write(buffer, value.material);
public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE1_21_4.write(buffer, value.material);
ArmorTrimPattern.TYPE1_20_5.write(buffer, value.pattern);
buffer.writeBoolean(value.showInTooltip);
}
};
public static final Type<ArmorTrim1_20_5> TYPE1_21_5 = new Type<>(ArmorTrim1_20_5.class) {
public static final Type<ArmorTrim> TYPE1_21_5 = new Type<>(ArmorTrim.class) {
@Override
public ArmorTrim1_20_5 read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial1_20_5> material = ArmorTrimMaterial1_20_5.TYPE1_21_5.read(buffer);
public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_5.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE1_21_5.read(buffer);
return new ArmorTrim1_20_5(material, pattern);
return new ArmorTrim(material, pattern);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim1_20_5 value) {
ArmorTrimMaterial1_20_5.TYPE1_21_5.write(buffer, value.material);
public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE1_21_5.write(buffer, value.material);
ArmorTrimPattern.TYPE1_21_5.write(buffer, value.pattern);
}
@Override
public void write(final Ops ops, final ArmorTrim1_20_5 value) {
public void write(final Ops ops, final ArmorTrim value) {
ops.writeMap(map -> map
.write("material", ArmorTrimMaterial1_20_5.TYPE1_21_5, value.material)
.write("material", ArmorTrimMaterial.TYPE1_21_5, value.material)
.write("pattern", ArmorTrimPattern.TYPE1_21_5, value.pattern));
}
};
@Override
public ArmorTrim1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
Holder<ArmorTrimMaterial1_20_5> material = this.material;
public ArmorTrim rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
Holder<ArmorTrimMaterial> material = this.material;
if (material.isDirect()) {
material = Holder.of(material.value().rewrite(connection, protocol, clientbound));
}
@@ -118,6 +118,6 @@ public record ArmorTrim1_20_5(Holder<ArmorTrimMaterial1_20_5> material, Holder<A
if (pattern.isDirect()) {
pattern = Holder.of(pattern.value().rewrite(connection, protocol, clientbound));
}
return new ArmorTrim1_20_5(material, pattern, showInTooltip);
return new ArmorTrim(material, pattern, showInTooltip);
}
}
@@ -20,7 +20,7 @@
* 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.trim;
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
@@ -32,32 +32,32 @@ import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import java.util.HashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import java.util.Map;
public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemModelIndex,
Map<String, String> overrideArmorMaterials,
Tag description) implements Copyable, Rewritable {
public record ArmorTrimMaterial(String assetName, int itemId, float itemModelIndex,
Map<String, String> overrideArmorMaterials,
Tag description) implements Copyable, Rewritable {
public ArmorTrimMaterial1_20_5(final String assetName, final int itemId, final Map<String, String> overrideArmorMaterials, final Tag description) {
public ArmorTrimMaterial(final String assetName, final int itemId, final Map<String, String> overrideArmorMaterials, final Tag description) {
this(assetName, itemId, 0F, overrideArmorMaterials, description);
}
public ArmorTrimMaterial1_20_5(final String assetName, final Map<String, String> overrideArmorMaterials, final Tag description) {
public ArmorTrimMaterial(final String assetName, final Map<String, String> overrideArmorMaterials, final Tag description) {
this(assetName, 0, 0F, overrideArmorMaterials, description);
}
public static final HolderType<ArmorTrimMaterial1_20_5> TYPE1_20_5 = new HolderType<>() {
public static final HolderType<ArmorTrimMaterial> TYPE1_20_5 = new HolderType<>() {
// The override key is an int, but given we don't use it at all and that creating a new type is annoying,
// we'll just store it in the string map:tm:
@Override
public ArmorTrimMaterial1_20_5 readDirect(final ByteBuf buffer) {
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer);
final int item = Types.VAR_INT.readPrimitive(buffer);
final float itemModelIndex = buffer.readFloat();
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> overrideArmorMaterials = new HashMap<>();
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>();
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final int key = Types.VAR_INT.readPrimitive(buffer);
final String value = Types.STRING.read(buffer);
@@ -65,11 +65,11 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
}
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial1_20_5(assetName, item, itemModelIndex, overrideArmorMaterials, description);
return new ArmorTrimMaterial(assetName, item, itemModelIndex, overrideArmorMaterials, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial1_20_5 value) {
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
Types.STRING.write(buffer, value.assetName());
Types.VAR_INT.writePrimitive(buffer, value.itemId());
buffer.writeFloat(value.itemModelIndex());
@@ -83,15 +83,15 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
Types.TAG.write(buffer, value.description());
}
};
public static final HolderType<ArmorTrimMaterial1_20_5> TYPE1_21_2 = new HolderType<>() {
public static final HolderType<ArmorTrimMaterial> TYPE1_21_2 = new HolderType<>() {
@Override
public ArmorTrimMaterial1_20_5 readDirect(final ByteBuf buffer) {
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer);
final int item = Types.VAR_INT.readPrimitive(buffer);
final float itemModelIndex = buffer.readFloat();
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> overrideArmorMaterials = new HashMap<>();
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>();
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final String key = Types.STRING.read(buffer);
final String value = Types.STRING.read(buffer);
@@ -99,11 +99,11 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
}
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial1_20_5(assetName, item, itemModelIndex, overrideArmorMaterials, description);
return new ArmorTrimMaterial(assetName, item, itemModelIndex, overrideArmorMaterials, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial1_20_5 value) {
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
Types.STRING.write(buffer, value.assetName());
Types.VAR_INT.writePrimitive(buffer, value.itemId());
buffer.writeFloat(value.itemModelIndex());
@@ -117,14 +117,14 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
Types.TAG.write(buffer, value.description());
}
};
public static final HolderType<ArmorTrimMaterial1_20_5> TYPE1_21_4 = new HolderType<>() {
public static final HolderType<ArmorTrimMaterial> TYPE1_21_4 = new HolderType<>() {
@Override
public ArmorTrimMaterial1_20_5 readDirect(final ByteBuf buffer) {
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer);
final int item = Types.VAR_INT.readPrimitive(buffer);
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> overrideArmorMaterials = new HashMap<>();
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>();
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final String key = Types.STRING.read(buffer);
final String value = Types.STRING.read(buffer);
@@ -132,11 +132,11 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
}
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial1_20_5(assetName, item, overrideArmorMaterials, description);
return new ArmorTrimMaterial(assetName, item, overrideArmorMaterials, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial1_20_5 value) {
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
Types.STRING.write(buffer, value.assetName());
Types.VAR_INT.writePrimitive(buffer, value.itemId());
@@ -149,13 +149,13 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
Types.TAG.write(buffer, value.description());
}
};
public static final HolderType<ArmorTrimMaterial1_20_5> TYPE1_21_5 = new HolderType<>() {
public static final HolderType<ArmorTrimMaterial> TYPE1_21_5 = new HolderType<>() {
@Override
public ArmorTrimMaterial1_20_5 readDirect(final ByteBuf buffer) {
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer);
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> overrideArmorMaterials = new HashMap<>();
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>();
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final String key = Types.STRING.read(buffer);
final String value = Types.STRING.read(buffer);
@@ -163,11 +163,11 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
}
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial1_20_5(assetName, overrideArmorMaterials, description);
return new ArmorTrimMaterial(assetName, overrideArmorMaterials, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial1_20_5 value) {
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
Types.STRING.write(buffer, value.assetName());
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
@@ -180,7 +180,7 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
}
@Override
public void writeDirect(final Ops ops, final ArmorTrimMaterial1_20_5 object) {
public void writeDirect(final Ops ops, final ArmorTrimMaterial object) {
ops.writeMap(map -> {
map.write("asset_name", Types.STRING, object.assetName());
if (!object.overrideArmorMaterials.isEmpty()) {
@@ -201,12 +201,12 @@ public record ArmorTrimMaterial1_20_5(String assetName, int itemId, float itemMo
};
@Override
public ArmorTrimMaterial1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return new ArmorTrimMaterial1_20_5(assetName, Rewritable.rewriteItem(protocol, clientbound, itemId), itemModelIndex, overrideArmorMaterials, description);
public ArmorTrimMaterial rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return new ArmorTrimMaterial(assetName, Rewritable.rewriteItem(protocol, clientbound, itemId), itemModelIndex, overrideArmorMaterials, description);
}
@Override
public ArmorTrimMaterial1_20_5 copy() {
return new ArmorTrimMaterial1_20_5(assetName, itemId, itemModelIndex, new HashMap<>(overrideArmorMaterials), description);
public ArmorTrimMaterial copy() {
return new ArmorTrimMaterial(assetName, itemId, itemModelIndex, new Object2ObjectArrayMap<>(overrideArmorMaterials), description);
}
}
@@ -20,7 +20,7 @@
* 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.trim;
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
@@ -27,7 +27,7 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
import io.netty.buffer.ByteBuf;
import java.util.HashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Map;
public record BlockStateProperties(Map<String, String> properties) implements Copyable {
@@ -36,7 +36,7 @@ public record BlockStateProperties(Map<String, String> properties) implements Co
@Override
public BlockStateProperties read(final ByteBuf buffer) {
final int size = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> properties = new HashMap<>();
final Map<String, String> properties = new Object2ObjectOpenHashMap<>();
for (int i = 0; i < size; i++) {
properties.put(Types.STRING.read(buffer), Types.STRING.read(buffer));
}
@@ -64,6 +64,6 @@ public record BlockStateProperties(Map<String, String> properties) implements Co
@Override
public BlockStateProperties copy() {
return new BlockStateProperties(new HashMap<>(properties));
return new BlockStateProperties(new Object2ObjectOpenHashMap<>(properties));
}
}
@@ -130,8 +130,8 @@ public record BlocksAttacks(
@Override
public BlocksAttacks rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> blockSound = SoundEvent.rewriteOptionalHolder(this.blockSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> disableSound = SoundEvent.rewriteOptionalHolder(this.disableSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> blockSound = SoundEvent.rewriteHolder(this.blockSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> disableSound = SoundEvent.rewriteHolder(this.disableSound, Rewritable.soundRewriteFunction(protocol, clientbound));
return new BlocksAttacks(this.blockDelaySeconds, this.disableCooldownScale, this.damageReductions, this.itemDamage, this.bypassedBy, blockSound, disableSound);
}
@@ -1,43 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Rewritable;
public record BreakSound(Holder<SoundEvent> sound) implements Rewritable {
public static final Type<BreakSound> TYPE = TransformingType.of(Types.SOUND_EVENT, BreakSound.class, BreakSound::new, BreakSound::sound);
@Override
public BreakSound rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> sound = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
return this.sound == sound ? this : new BreakSound(sound);
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.ResolvableFloat;
import com.viaversion.viaversion.api.minecraft.ResolvableInt;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record BrewingFuel(ResolvableInt uses, ResolvableFloat speedMultiplier) {
public static final Type<BrewingFuel> TYPE = new Type<>(BrewingFuel.class) {
@Override
public BrewingFuel read(final ByteBuf buffer) {
final ResolvableInt uses = Types.RESOLVABLE_INT.read(buffer);
final ResolvableFloat speedMultiplier = Types.RESOLVABLE_FLOAT.read(buffer);
return new BrewingFuel(uses, speedMultiplier);
}
@Override
public void write(final ByteBuf buffer, final BrewingFuel value) {
Types.RESOLVABLE_INT.write(buffer, value.uses);
Types.RESOLVABLE_FLOAT.write(buffer, value.speedMultiplier);
}
@Override
public void write(final Ops ops, final BrewingFuel value) {
ops.writeMap(map -> map
.write("uses", Types.RESOLVABLE_INT, value.uses)
.write("speed_multiplier", Types.RESOLVABLE_FLOAT, value.speedMultiplier));
}
};
}
@@ -1,40 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.ResolvableInt;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
public record Compostable(ResolvableInt layers) {
public static final Type<Compostable> TYPE = new TransformingType<>(Types.RESOLVABLE_INT, Compostable.class, Compostable::new, Compostable::layers) {
@Override
public void write(final Ops ops, final Compostable value) {
ops.writeMap(map -> map.write("layers", Types.RESOLVABLE_INT, value.layers));
}
};
}
@@ -0,0 +1,200 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<SoundEvent> sound,
boolean hasConsumeParticles,
ConsumeEffect<?>[] consumeEffects) implements Copyable, Rewritable {
private static final HolderSetType REMOVE_EFFECTS_TYPE = new HolderSetType() {
@Override
public void write(final Ops ops, final HolderSet value) {
ops.writeMap(map -> map.write("effects", new HolderSetType(EnumTypes.MOB_EFFECT), value));
}
};
private static final Type<Float> TELEPORT_RANDOMLY_TYPE = new Type<>(Float.class) {
@Override
public void write(final ByteBuf buffer, final Float value) {
Types.FLOAT.writePrimitive(buffer, value);
}
@Override
public Float read(final ByteBuf buffer) {
return Types.FLOAT.readPrimitive(buffer);
}
@Override
public void write(final Ops ops, final Float value) {
ops.writeMap(map -> map.write("diameter", Types.FLOAT, 16F));
}
};
private static final HolderType<SoundEvent> PLAY_SOUND_TYPE = new HolderType<>(MappingData.MappingType.SOUND) {
@Override
public SoundEvent readDirect(final ByteBuf buffer) {
return Types.SOUND_EVENT.readDirect(buffer);
}
@Override
public void writeDirect(final ByteBuf buffer, final SoundEvent value) {
Types.SOUND_EVENT.writeDirect(buffer, value);
}
@Override
public void write(final Ops ops, final Holder<SoundEvent> value) {
ops.writeMap(map -> map.write("sound", Types.SOUND_EVENT, value));
}
};
public static final Type<?>[] EFFECT_TYPES = {
ApplyStatusEffects.TYPE,
REMOVE_EFFECTS_TYPE,
Types.EMPTY, // clear all effects
TELEPORT_RANDOMLY_TYPE,
PLAY_SOUND_TYPE
};
public static final Type<Consumable1_21_2> TYPE = new Type<>(Consumable1_21_2.class) {
@Override
public Consumable1_21_2 read(final ByteBuf buffer) {
final float consumeSeconds = buffer.readFloat();
final int animationType = Types.VAR_INT.readPrimitive(buffer);
final Holder<SoundEvent> sound = Types.SOUND_EVENT.read(buffer);
final boolean hasConsumeParticles = buffer.readBoolean();
final ConsumeEffect<?>[] consumeEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, consumeEffects);
}
@Override
public void write(final ByteBuf buffer, final Consumable1_21_2 value) {
buffer.writeFloat(value.consumeSeconds);
Types.VAR_INT.writePrimitive(buffer, value.animationType);
Types.SOUND_EVENT.write(buffer, value.sound);
buffer.writeBoolean(value.hasConsumeParticles);
ConsumeEffect.ARRAY_TYPE.write(buffer, value.consumeEffects);
}
@Override
public void write(final Ops ops, final Consumable1_21_2 value) {
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "entity.generic.eat"));
ops.writeMap(map -> map
.writeOptional("consume_seconds", Types.FLOAT, value.consumeSeconds, 1.6F)
.writeOptional("animation", EnumTypes.ITEM_USE_ANIMATION, value.animationType, 1)
.writeOptional("sound", Types.SOUND_EVENT, value.sound, defaultSound)
.writeOptional("has_consume_particles", Types.BOOLEAN, value.hasConsumeParticles, true)
.writeOptional("consume_effects", ConsumeEffect.ARRAY_TYPE, value.consumeEffects, new ConsumeEffect<?>[0]));
}
};
public record ConsumeEffect<T>(int id, Type<T> type, T value) {
public static final Type<ConsumeEffect<?>> TYPE = new Type<>(ConsumeEffect.class) {
@Override
public ConsumeEffect<?> read(final ByteBuf buffer) {
// Oh no...
final int effectType = Types.VAR_INT.readPrimitive(buffer);
final Type<?> type = EFFECT_TYPES[effectType];
final Object value = type.read(buffer);
return ConsumeEffect.of(effectType, type, value);
}
@Override
public void write(final ByteBuf buffer, final ConsumeEffect<?> value) {
Types.VAR_INT.writePrimitive(buffer, value.id);
value.writeValue(buffer);
}
@Override
public void write(final Ops ops, final ConsumeEffect<?> value) {
writeGeneric(ops, value);
}
private <E> void writeGeneric(final Ops ops, final ConsumeEffect<E> value) {
ops.writeMap(map -> map
.write("type", EnumTypes.CONSUME_EFFECT, value.id)
.writeInlinedMap(value.type, value.value));
}
};
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE = new ArrayType<>(TYPE);
static <T> ConsumeEffect<T> of(final int id, final Type<T> type, final Object value) {
//noinspection unchecked
return new ConsumeEffect<>(id, type, (T) value);
}
void writeValue(final ByteBuf buf) {
this.type.write(buf, this.value);
}
}
public record ApplyStatusEffects(PotionEffect[] effects, float probability) {
public static final Type<ApplyStatusEffects> TYPE = new Type<>(ApplyStatusEffects.class) {
@Override
public ApplyStatusEffects read(final ByteBuf buffer) {
final PotionEffect[] effects = PotionEffect.ARRAY_TYPE.read(buffer);
final float probability = buffer.readFloat();
return new ApplyStatusEffects(effects, probability);
}
@Override
public void write(final ByteBuf buffer, final ApplyStatusEffects value) {
PotionEffect.ARRAY_TYPE.write(buffer, value.effects);
buffer.writeFloat(value.probability);
}
@Override
public void write(final Ops ops, final ApplyStatusEffects value) {
ops.writeMap(map -> map
.write("effects", PotionEffect.ARRAY_TYPE, value.effects)
.writeOptional("probability", Types.FLOAT, value.probability, 1F));
}
};
}
@Override
public Consumable1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundHolder = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundHolder == this.sound ? this : new Consumable1_21_2(consumeSeconds, animationType, soundHolder, hasConsumeParticles, consumeEffects);
}
@Override
public Consumable1_21_2 copy() {
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, Copyable.copy(consumeEffects));
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.ResolvableFloat;
import com.viaversion.viaversion.api.minecraft.ResolvableInt;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record CookingFuel(ResolvableInt burnTime, ResolvableFloat speedMultiplier) {
public static final Type<CookingFuel> TYPE = new Type<>(CookingFuel.class) {
@Override
public CookingFuel read(final ByteBuf buffer) {
final ResolvableInt burnTime = Types.RESOLVABLE_INT.read(buffer);
final ResolvableFloat speedMultiplier = Types.RESOLVABLE_FLOAT.read(buffer);
return new CookingFuel(burnTime, speedMultiplier);
}
@Override
public void write(final ByteBuf buffer, final CookingFuel value) {
Types.RESOLVABLE_INT.write(buffer, value.burnTime);
Types.RESOLVABLE_FLOAT.write(buffer, value.speedMultiplier);
}
@Override
public void write(final Ops ops, final CookingFuel value) {
ops.writeMap(map -> map
.write("burn_time", Types.RESOLVABLE_INT, value.burnTime)
.write("speed_multiplier", Types.RESOLVABLE_FLOAT, value.speedMultiplier));
}
};
}
@@ -23,12 +23,10 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.RegistryKey;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
public record DamageResistant26_1(HolderSet types) {
@@ -36,7 +34,7 @@ public record DamageResistant26_1(HolderSet types) {
@Override
public void write(final Ops ops, final DamageResistant26_1 value) {
ops.writeMap(map -> map.write("types", new HolderSetType(RegistryKey.of("damage_type")), value.types));
ops.writeMap(map -> map.write("types", Types.HOLDER_SET, value.types));
}
};
}
@@ -22,18 +22,18 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.EitherType;
import com.viaversion.viaversion.util.Either;
public record VillagerFood(int nutrition) {
/**
* 1.21.11-only damage type.
*
* @param id registry int or string id
*/
public record DamageType(Either<Integer, String> id) {
public static final Type<VillagerFood> TYPE = new TransformingType<>(Types.VAR_INT, VillagerFood.class, VillagerFood::new, VillagerFood::nutrition) {
@Override
public void write(final Ops ops, final VillagerFood value) {
ops.writeMap(map -> map.write("nutrition", Types.VAR_INT, value.nutrition));
}
};
public static final Type<DamageType> TYPE1_21_11 = TransformingType.of(new EitherType<>(Types.VAR_INT, Types.STRING), DamageType.class, DamageType::new, DamageType::id);
}
@@ -22,35 +22,20 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.minecraft.item.data.consumable.ConsumeEffect;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2.ConsumeEffect;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
public record DeathProtection(ConsumeEffect<?>[] deathEffects) implements Copyable, Rewritable {
public record DeathProtection(ConsumeEffect<?>[] deathEffects) implements Copyable {
public static final Type<DeathProtection> TYPE1_21_2 = new TransformingType<>(ConsumeEffect.ARRAY_TYPE1_21_2, DeathProtection.class, DeathProtection::new, DeathProtection::deathEffects) {
public static final Type<DeathProtection> TYPE = new TransformingType<>(ConsumeEffect.ARRAY_TYPE, DeathProtection.class, DeathProtection::new, DeathProtection::deathEffects) {
@Override
public void write(final Ops ops, final DeathProtection value) {
ops.writeMap(map -> map.writeOptional("death_effects", ConsumeEffect.ARRAY_TYPE1_21_2, value.deathEffects, new ConsumeEffect<?>[0]));
ops.writeMap(map -> map.write("death_effects", ConsumeEffect.ARRAY_TYPE, value.deathEffects));
}
};
public static final Type<DeathProtection> TYPE26_3 = new TransformingType<>(ConsumeEffect.ARRAY_TYPE26_3, DeathProtection.class, DeathProtection::new, DeathProtection::deathEffects) {
@Override
public void write(final Ops ops, final DeathProtection value) {
ops.writeMap(map -> map.writeOptional("death_effects", ConsumeEffect.ARRAY_TYPE26_3, value.deathEffects, new ConsumeEffect<?>[0]));
}
};
@Override
public DeathProtection rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final ConsumeEffect<?>[] deathEffects = ConsumeEffect.rewrite(this.deathEffects, connection, protocol, clientbound);
return deathEffects == this.deathEffects ? this : new DeathProtection(deathEffects);
}
@Override
public DeathProtection copy() {
@@ -38,12 +38,12 @@ public record DebugStickState(CompoundTag tag) implements Rewritable, Copyable {
@Override
public DebugStickState rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
CompoundTag updatedTag = tag;
if (protocol.getMappingData() != null && protocol.getMappingData().changedBlocks() != null) {
if (clientbound && protocol.getMappingData() != null && protocol.getMappingData().changedBlocks() != null) {
updatedTag = tag.copy();
// Anything beyond this isn't worth the disk space/handling
updatedTag.entrySet().removeIf(entry -> {
final int blockId = protocol.getMappingData().getFullBlockMappings().id(entry.getKey());
return blockId == -1 || protocol.getMappingData().changedBlocks().contains(blockId);
return protocol.getMappingData().changedBlocks().contains(blockId);
});
}
return new DebugStickState(updatedTag);
@@ -27,7 +27,6 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Limit;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
@@ -42,7 +41,7 @@ public record Enchantments(Int2IntMap enchantments, boolean showInTooltip) imple
@Override
public Enchantments read(final ByteBuf buffer) {
final Int2IntMap enchantments = new Int2IntOpenHashMap();
final int size = Limit.max(Types.VAR_INT.readPrimitive(buffer), 256);
final int size = Types.VAR_INT.readPrimitive(buffer);
for (int i = 0; i < size; i++) {
final int id = Types.VAR_INT.readPrimitive(buffer);
final int level = Types.VAR_INT.readPrimitive(buffer);
@@ -66,7 +65,7 @@ public record Enchantments(Int2IntMap enchantments, boolean showInTooltip) imple
@Override
public Enchantments read(final ByteBuf buffer) {
final Int2IntMap enchantments = new Int2IntOpenHashMap();
final int size = Limit.max(Types.VAR_INT.readPrimitive(buffer), 256);
final int size = Types.VAR_INT.readPrimitive(buffer);
for (int i = 0; i < size; i++) {
final int id = Types.VAR_INT.readPrimitive(buffer);
final int level = Types.VAR_INT.readPrimitive(buffer);
@@ -46,8 +46,7 @@ public final class EnumTypes {
public static final EnumType LLAMA_VARIANT = new EnumType(Fallback.CLAMP, "creamy", "white", "brown", "gray");
public static final EnumType AXOLOTL_VARIANT = new EnumType("lucy", "wild", "gold", "cyan", "blue");
public static final EnumType EQUIPMENT_SLOT = new EnumType("mainhand", "feet", "legs", "chest", "head", "offhand", "body", "saddle");
public static final EnumType SWING_ANIMATION1_21_11 = new EnumType("none", "whack", "stab");
public static final EnumType ITEM_USE_ANIMATION1_21_5 = new EnumType("none", "eat", "drink", "block", "bow", "spear", "crossbow", "spyglass", "toot_horn", "brush", "bundle");
public static final EnumType SWING_ANIMATION = new EnumType("none", "whack", "stab");
public static final EnumType ITEM_USE_ANIMATION = new EnumType("none", "eat", "drink", "block", "bow", "trident", "crossbow", "spyglass", "toot_horn", "brush", "bundle", "spear");
// Enums with non-ordinal ids
public static final FakeEnumType RABBIT_VARIANT = new FakeEnumType(List.of("brown", "white", "black", "white_splotched", "gold", "salt"), of(99, "evil"));
@@ -34,7 +34,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public final class FilterableComponent extends Filterable<Tag> implements Copyable, Rewritable {
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TEXT_COMPONENT_TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
@Override
protected FilterableComponent create(final Tag raw, final Tag filtered) {
return new FilterableComponent(raw, filtered);
@@ -37,13 +37,9 @@ import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration, float range,
int durabilityDamage, Tag description) implements Copyable, Rewritable {
Tag description) implements Copyable, Rewritable {
public Instrument1_21_2(final Holder<SoundEvent> soundEvent, final float useDuration, final float range, final Tag description) {
this(soundEvent, useDuration, range, 0, description);
}
public static final HolderType<Instrument1_21_2> TYPE1_21_2 = new HolderType<>() {
public static final HolderType<Instrument1_21_2> TYPE = new HolderType<>() {
@Override
public Instrument1_21_2 readDirect(final ByteBuf buffer) {
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
@@ -67,44 +63,7 @@ public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration,
.write("sound_event", Types.SOUND_EVENT, value.soundEvent())
.write("use_duration", Types.FLOAT, value.useDuration())
.write("range", Types.FLOAT, value.range())
.write("description", Types.TEXT_COMPONENT_TAG, value.description()));
}
@Override
protected Key identifier(final Ops ops, final int id) {
return ops.context().registryAccess().registryKey("instrument", id);
}
};
public static final EitherHolderType<Instrument1_21_2> EITHER_HOLDER_TYPE = new EitherHolderType<>(TYPE1_21_2);
public static final HolderType<Instrument1_21_2> TYPE26_3 = new HolderType<>() {
@Override
public Instrument1_21_2 readDirect(final ByteBuf buffer) {
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final float useDuration = Types.FLOAT.readPrimitive(buffer);
final float range = Types.FLOAT.readPrimitive(buffer);
final int durabilityDamage = Types.VAR_INT.readPrimitive(buffer);
final Tag description = Types.TAG.read(buffer);
return new Instrument1_21_2(soundEvent, useDuration, range, durabilityDamage, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final Instrument1_21_2 value) {
Types.SOUND_EVENT.write(buffer, value.soundEvent());
Types.FLOAT.writePrimitive(buffer, value.useDuration());
Types.FLOAT.writePrimitive(buffer, value.range());
Types.VAR_INT.writePrimitive(buffer, value.durabilityDamage());
Types.TAG.write(buffer, value.description());
}
@Override
public void writeDirect(final Ops ops, final Instrument1_21_2 value) {
ops.writeMap(map -> map
.write("sound_event", Types.SOUND_EVENT, value.soundEvent())
.write("use_duration", Types.FLOAT, value.useDuration())
.write("range", Types.FLOAT, value.range())
.writeOptional("durability_damage", Types.VAR_INT, value.durabilityDamage(), 0)
.write("description", Types.TEXT_COMPONENT_TAG, value.description()));
.write("description", Types.TAG, value.description()));
}
@Override
@@ -112,15 +71,16 @@ public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration,
return ops.context().registryAccess().registryKey("instrument", id);
}
};
public static final EitherHolderType<Instrument1_21_2> EITHER_HOLDER_TYPE = new EitherHolderType<>(TYPE);
@Override
public Instrument1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundEvent == this.soundEvent ? this : new Instrument1_21_2(soundEvent, useDuration, range, durabilityDamage, description);
return soundEvent == this.soundEvent ? this : new Instrument1_21_2(soundEvent, useDuration, range, description);
}
@Override
public Instrument1_21_2 copy() {
return new Instrument1_21_2(soundEvent, useDuration, range, durabilityDamage, description.copy());
return new Instrument1_21_2(soundEvent, useDuration, range, description.copy());
}
}
@@ -22,22 +22,19 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record KineticWeapon(int contactCooldownTicks, int delayTicks, @Nullable Condition dismountConditions,
@Nullable Condition knockbackConditions, @Nullable Condition damageConditions,
float forwardMovement, float damageMultiplier,
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) implements Rewritable {
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) {
public static final Type<KineticWeapon> TYPE = new Type<>(KineticWeapon.class) {
@Override
@@ -83,13 +80,6 @@ public record KineticWeapon(int contactCooldownTicks, int delayTicks, @Nullable
}
};
@Override
public KineticWeapon rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> sound = SoundEvent.rewriteOptionalHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> hitSound = SoundEvent.rewriteOptionalHolder(this.hitSound, Rewritable.soundRewriteFunction(protocol, clientbound));
return sound == this.sound && hitSound == this.hitSound ? this : new KineticWeapon(contactCooldownTicks, delayTicks, dismountConditions, knockbackConditions, damageConditions, forwardMovement, damageMultiplier, sound, hitSound);
}
public record Condition(int maxDurationTicks, float minSpeed, float minRelativeSpeed) {
public static final Type<Condition> TYPE = new Type<>(Condition.class) {
@@ -1,56 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.data.MappingData;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
import io.netty.buffer.ByteBuf;
public record MobVisibility(HolderSet targetingEntityTypes, float visibility) {
public static final Type<MobVisibility> TYPE = new Type<>(MobVisibility.class) {
@Override
public MobVisibility read(final ByteBuf buffer) {
final HolderSet targetingEntityTypes = Types.HOLDER_SET.read(buffer);
final float visibility = Types.FLOAT.readPrimitive(buffer);
return new MobVisibility(targetingEntityTypes, visibility);
}
@Override
public void write(final ByteBuf buffer, final MobVisibility value) {
Types.HOLDER_SET.write(buffer, value.targetingEntityTypes);
Types.FLOAT.writePrimitive(buffer, value.visibility);
}
@Override
public void write(final Ops ops, final MobVisibility value) {
ops.writeMap(map -> map
.write("targeting_entity_types", new HolderSetType(MappingData.MappingType.ENTITY_TYPE), value.targetingEntityTypes)
.write("visibility", Types.FLOAT, value.visibility));
}
};
}
@@ -22,19 +22,16 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record PiercingWeapon(boolean dealsKnockback, boolean dismounts,
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) implements Rewritable {
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) {
public static final Type<PiercingWeapon> TYPE = new Type<>(PiercingWeapon.class) {
@Override
@@ -64,11 +61,4 @@ public record PiercingWeapon(boolean dealsKnockback, boolean dismounts,
);
}
};
@Override
public PiercingWeapon rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> sound = SoundEvent.rewriteOptionalHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> hitSound = SoundEvent.rewriteOptionalHolder(this.hitSound, Rewritable.soundRewriteFunction(protocol, clientbound));
return sound == this.sound && hitSound == this.hitSound ? this : new PiercingWeapon(dealsKnockback, dismounts, sound, hitSound);
}
}
@@ -29,25 +29,22 @@ import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Rewritable;
public record PotDecorations1_20_5(int[] itemIds) implements Copyable, Rewritable {
public record PotDecorations(int[] itemIds) implements Copyable, Rewritable {
private static final Key BRICK = Key.ofPath("brick");
public static final Type<PotDecorations1_20_5> TYPE = new TransformingType<>(Types.VAR_INT_ARRAY_PRIMITIVE, PotDecorations1_20_5.class, PotDecorations1_20_5::new, PotDecorations1_20_5::itemIds) {
public static final Type<PotDecorations> TYPE = new TransformingType<>(Types.VAR_INT_ARRAY_PRIMITIVE, PotDecorations.class, PotDecorations::new, PotDecorations::itemIds) {
@Override
public void write(final Ops ops, final PotDecorations1_20_5 value) {
// Vanilla always encodes all 4 sides, filling missing ones with bricks
public void write(final Ops ops, final PotDecorations value) {
ops.writeList(list -> {
for (int i = 0; i < 4; i++) {
list.write(Types.IDENTIFIER, i < value.itemIds.length ? ops.context().registryAccess().item(value.itemIds[i]) : BRICK);
for (final int itemId : value.itemIds) {
list.write(Types.IDENTIFIER, ops.context().registryAccess().item(itemId));
}
});
}
};
public PotDecorations1_20_5(final int backItem, final int leftItem, final int rightItem, final int frontItem) {
public PotDecorations(final int backItem, final int leftItem, final int rightItem, final int frontItem) {
this(new int[]{backItem, leftItem, rightItem, frontItem});
}
@@ -72,16 +69,16 @@ public record PotDecorations1_20_5(int[] itemIds) implements Copyable, Rewritabl
}
@Override
public PotDecorations1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
public PotDecorations rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final int[] newItems = new int[itemIds.length];
for (int i = 0; i < itemIds.length; i++) {
newItems[i] = Rewritable.rewriteItem(protocol, clientbound, itemIds[i]);
}
return new PotDecorations1_20_5(newItems);
return new PotDecorations(newItems);
}
@Override
public PotDecorations1_20_5 copy() {
return new PotDecorations1_20_5(Copyable.copy(itemIds));
public PotDecorations copy() {
return new PotDecorations(Copyable.copy(itemIds));
}
}
@@ -1,96 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
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.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
import static com.viaversion.viaversion.util.Rewritable.rewriteItem;
public record PotDecorations26_3(@Nullable Item back, @Nullable Item left, @Nullable Item right,
@Nullable Item front) implements Copyable, Rewritable {
public static final class PotDecorationsType extends Type<PotDecorations26_3> {
private final Type<Item> itemTemplateType;
public PotDecorationsType(final Type<Item> itemTemplateType) {
super(PotDecorations26_3.class);
this.itemTemplateType = itemTemplateType;
}
@Override
public void write(final ByteBuf buffer, final PotDecorations26_3 value) {
itemTemplateType.write(buffer, value.back());
itemTemplateType.write(buffer, value.left());
itemTemplateType.write(buffer, value.right());
itemTemplateType.write(buffer, value.front());
}
@Override
public PotDecorations26_3 read(final ByteBuf buffer) {
final Item back = itemTemplateType.read(buffer);
final Item left = itemTemplateType.read(buffer);
final Item right = itemTemplateType.read(buffer);
final Item front = itemTemplateType.read(buffer);
return new PotDecorations26_3(back, left, right, front);
}
@Override
public void write(final Ops ops, final PotDecorations26_3 value) {
ops.writeMap(map -> map
.writeOptional("back", itemTemplateType, value.back())
.writeOptional("left", itemTemplateType, value.left())
.writeOptional("right", itemTemplateType, value.right())
.writeOptional("front", itemTemplateType, value.front())
);
}
}
@Override
public PotDecorations26_3 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return new PotDecorations26_3(
rewriteItem(connection, protocol, clientbound, back),
rewriteItem(connection, protocol, clientbound, left),
rewriteItem(connection, protocol, clientbound, right),
rewriteItem(connection, protocol, clientbound, front)
);
}
@Override
public PotDecorations26_3 copy() {
return new PotDecorations26_3(
back == null ? null : back.copy(),
left == null ? null : left.copy(),
right == null ? null : right.copy(),
front == null ? null : front.copy()
);
}
}
@@ -40,7 +40,7 @@ public record PotionEffectData(int amplifier, int duration, boolean ambient, boo
final boolean ambient = buffer.readBoolean();
final boolean showParticles = buffer.readBoolean();
final boolean showIcon = buffer.readBoolean();
final PotionEffectData hiddenEffect = OPTIONAL_TYPE.readTrackingDepth(buffer);
final PotionEffectData hiddenEffect = OPTIONAL_TYPE.read(buffer);
return new PotionEffectData(amplifier, duration, ambient, showParticles, showIcon, hiddenEffect);
}
@@ -20,7 +20,7 @@
* 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.trim;
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.EitherHolder;
@@ -32,34 +32,34 @@ import com.viaversion.viaversion.api.type.types.misc.EitherHolderType;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record ProvidesTrimMaterial1_20_5(EitherHolder<ArmorTrimMaterial1_20_5> material) implements Rewritable {
public record ProvidesTrimMaterial(EitherHolder<ArmorTrimMaterial> material) implements Rewritable {
public static final Type<ProvidesTrimMaterial1_20_5> TYPE = new Type<>(ProvidesTrimMaterial1_20_5.class) {
public static final Type<ProvidesTrimMaterial> TYPE = new Type<>(ProvidesTrimMaterial.class) {
@Override
public ProvidesTrimMaterial1_20_5 read(final ByteBuf buffer) {
final EitherHolder<ArmorTrimMaterial1_20_5> position = EitherHolderType.read(buffer, ArmorTrimMaterial1_20_5.TYPE1_21_5);
return new ProvidesTrimMaterial1_20_5(position);
public ProvidesTrimMaterial read(final ByteBuf buffer) {
final EitherHolder<ArmorTrimMaterial> position = EitherHolderType.read(buffer, ArmorTrimMaterial.TYPE1_21_5);
return new ProvidesTrimMaterial(position);
}
@Override
public void write(final ByteBuf buffer, final ProvidesTrimMaterial1_20_5 value) {
EitherHolderType.write(buffer, value.material, ArmorTrimMaterial1_20_5.TYPE1_21_5);
public void write(final ByteBuf buffer, final ProvidesTrimMaterial value) {
EitherHolderType.write(buffer, value.material, ArmorTrimMaterial.TYPE1_21_5);
}
@Override
public void write(final Ops ops, final ProvidesTrimMaterial1_20_5 value) {
EitherHolderType.write(ops, value.material, ArmorTrimMaterial1_20_5.TYPE1_21_5);
public void write(final Ops ops, final ProvidesTrimMaterial value) {
EitherHolderType.write(ops, value.material, ArmorTrimMaterial.TYPE1_21_5);
}
};
@Override
public ProvidesTrimMaterial1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
public ProvidesTrimMaterial rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
if (material.hasKey() || material.holder().hasId()) {
return this;
}
final ArmorTrimMaterial1_20_5 trimMaterial = material.holder().value();
return new ProvidesTrimMaterial1_20_5(EitherHolder.of(Holder.of(trimMaterial.rewrite(connection, protocol, clientbound))));
final ArmorTrimMaterial trimMaterial = material.holder().value();
return new ProvidesTrimMaterial(EitherHolder.of(Holder.of(trimMaterial.rewrite(connection, protocol, clientbound))));
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record SignText(Tag[] messages, Tag @Nullable [] filteredMessages, int color, boolean hasGlowingText) {
public static final Type<SignText> TYPE = new Type<>(SignText.class) {
@Override
public SignText read(final ByteBuf buffer) {
final Tag[] messages = Types.SIGN_TEXT.read(buffer);
final Tag[] filteredMessages = Types.OPTIONAL_SIGN_TEXT.read(buffer);
final int color = Types.VAR_INT.readPrimitive(buffer);
final boolean hasGlowingText = buffer.readBoolean();
return new SignText(messages, filteredMessages, color, hasGlowingText);
}
@Override
public void write(final ByteBuf buffer, final SignText value) {
Types.SIGN_TEXT.write(buffer, value.messages);
Types.OPTIONAL_SIGN_TEXT.write(buffer, value.filteredMessages);
Types.VAR_INT.writePrimitive(buffer, value.color);
Types.BOOLEAN.write(buffer, value.hasGlowingText);
}
@Override
public void write(final Ops ops, final SignText value) {
ops.writeMap(map -> map
.write("messages", Types.TEXT_COMPONENT_TAG_ARRAY, value.messages)
.writeOptional("filtered_messages", Types.TEXT_COMPONENT_TAG_ARRAY, value.filteredMessages)
.write("color", EnumTypes.DYE_COLOR, value.color)
.write("has_glowing_text", Types.BOOLEAN, value.hasGlowingText));
}
};
}
@@ -29,17 +29,9 @@ import io.netty.buffer.ByteBuf;
public record SwingAnimation(int type, int duration) {
public static final Type<SwingAnimation> TYPE = new SwingAnimationType(EnumTypes.SWING_ANIMATION1_21_11.idFromName("whack"));
private static class SwingAnimationType extends Type<SwingAnimation> {
private final int defaultType;
public SwingAnimationType(final int defaultType) {
super(SwingAnimation.class);
this.defaultType = defaultType;
}
private static final int DEFAULT_TYPE = EnumTypes.SWING_ANIMATION.idFromName("whack");
public static final Type<SwingAnimation> TYPE = new Type<>(SwingAnimation.class) {
@Override
public SwingAnimation read(final ByteBuf buffer) {
final int type = Types.VAR_INT.readPrimitive(buffer);
@@ -56,8 +48,9 @@ public record SwingAnimation(int type, int duration) {
@Override
public void write(final Ops ops, final SwingAnimation value) {
ops.writeMap(map -> map
.writeOptional("type", EnumTypes.SWING_ANIMATION1_21_11, value.type, this.defaultType)
.writeOptional("duration", Types.INT, value.duration, 6));
.writeOptional("type", EnumTypes.SWING_ANIMATION, value.type, DEFAULT_TYPE)
.writeOptional("duration", Types.INT, value.duration, 6)
);
}
}
};
}
@@ -28,7 +28,6 @@ import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Limit;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
@@ -43,7 +42,7 @@ public record TooltipDisplay(boolean hideTooltip,
public TooltipDisplay read(final ByteBuf buffer) {
final boolean hideTooltip = buffer.readBoolean();
final IntSortedSet hiddenComponents = new IntLinkedOpenHashSet();
final int size = Limit.max(Types.VAR_INT.readPrimitive(buffer), 256);
final int size = Types.VAR_INT.readPrimitive(buffer);
for (int i = 0; i < size; i++) {
hiddenComponents.add(Types.VAR_INT.readPrimitive(buffer));
}
@@ -1,54 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.consumable;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record ApplyStatusEffects(PotionEffect[] effects, float probability) {
public static final Type<ApplyStatusEffects> TYPE = new Type<>(ApplyStatusEffects.class) {
@Override
public ApplyStatusEffects read(final ByteBuf buffer) {
final PotionEffect[] effects = PotionEffect.ARRAY_TYPE.read(buffer);
final float probability = buffer.readFloat();
return new ApplyStatusEffects(effects, probability);
}
@Override
public void write(final ByteBuf buffer, final ApplyStatusEffects value) {
PotionEffect.ARRAY_TYPE.write(buffer, value.effects);
buffer.writeFloat(value.probability);
}
@Override
public void write(final Ops ops, final ApplyStatusEffects value) {
ops.writeMap(map -> map
.write("effects", PotionEffect.ARRAY_TYPE, value.effects)
.writeOptional("probability", Types.FLOAT, value.probability, 1F));
}
};
}
@@ -1,101 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.consumable;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.minecraft.item.data.EnumTypes;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.EnumType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<SoundEvent> sound,
boolean hasConsumeParticles,
ConsumeEffect<?>[] consumeEffects) implements Copyable, Rewritable {
public static final Type<Consumable1_21_2> TYPE1_21_2 = new ConsumableType(ConsumeEffect.ARRAY_TYPE1_21_2, EnumTypes.ITEM_USE_ANIMATION);
public static final Type<Consumable1_21_2> TYPE1_21_5 = new ConsumableType(ConsumeEffect.ARRAY_TYPE1_21_2, EnumTypes.ITEM_USE_ANIMATION1_21_5);
public static final Type<Consumable1_21_2> TYPE26_3 = new ConsumableType(ConsumeEffect.ARRAY_TYPE26_3, EnumTypes.ITEM_USE_ANIMATION);
private static final class ConsumableType extends Type<Consumable1_21_2> {
private final Type<ConsumeEffect<?>[]> consumeEffectType;
private final EnumType animationType;
private ConsumableType(final Type<ConsumeEffect<?>[]> consumeEffectType, final EnumType animationType) {
super(Consumable1_21_2.class);
this.consumeEffectType = consumeEffectType;
this.animationType = animationType;
}
@Override
public Consumable1_21_2 read(final ByteBuf buffer) {
final float consumeSeconds = buffer.readFloat();
final int animationType = Types.VAR_INT.readPrimitive(buffer);
final Holder<SoundEvent> sound = Types.SOUND_EVENT.read(buffer);
final boolean hasConsumeParticles = buffer.readBoolean();
final ConsumeEffect<?>[] consumeEffects = consumeEffectType.read(buffer);
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, consumeEffects);
}
@Override
public void write(final ByteBuf buffer, final Consumable1_21_2 value) {
buffer.writeFloat(value.consumeSeconds);
Types.VAR_INT.writePrimitive(buffer, value.animationType);
Types.SOUND_EVENT.write(buffer, value.sound);
buffer.writeBoolean(value.hasConsumeParticles);
consumeEffectType.write(buffer, value.consumeEffects);
}
@Override
public void write(final Ops ops, final Consumable1_21_2 value) {
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "entity.generic.eat"));
ops.writeMap(map -> map
.writeOptional("consume_seconds", Types.FLOAT, value.consumeSeconds, 1.6F)
.writeOptional("animation", animationType, value.animationType, 1)
.writeOptional("sound", Types.SOUND_EVENT, value.sound, defaultSound)
.writeOptional("has_consume_particles", Types.BOOLEAN, value.hasConsumeParticles, true)
.writeOptional("on_consume_effects", consumeEffectType, value.consumeEffects, new ConsumeEffect<?>[0]));
}
}
@Override
public Consumable1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundHolder = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
final ConsumeEffect<?>[] consumeEffects = ConsumeEffect.rewrite(this.consumeEffects, connection, protocol, clientbound);
return soundHolder == this.sound && consumeEffects == this.consumeEffects ? this
: new Consumable1_21_2(consumeSeconds, animationType, soundHolder, hasConsumeParticles, consumeEffects);
}
@Override
public Consumable1_21_2 copy() {
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, Copyable.copy(consumeEffects));
}
}
@@ -1,194 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.consumable;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.minecraft.item.data.EnumTypes;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record ConsumeEffect<T>(int id, Type<T> type, T value) implements Rewritable {
private static final HolderSetType REMOVE_EFFECTS_TYPE = new HolderSetType() {
@Override
public void write(final Ops ops, final HolderSet value) {
ops.writeMap(map -> map.write("effects", new HolderSetType(EnumTypes.MOB_EFFECT), value));
}
};
public static final Type<Float> TELEPORT_RANDOMLY_TYPE1_21_2 = new Type<>(Float.class) {
@Override
public void write(final ByteBuf buffer, final Float value) {
Types.FLOAT.writePrimitive(buffer, value);
}
@Override
public Float read(final ByteBuf buffer) {
return Types.FLOAT.readPrimitive(buffer);
}
@Override
public void write(final Ops ops, final Float value) {
ops.writeMap(map -> map.writeOptional("diameter", Types.FLOAT, value, 16F));
}
};
public static final Type<TeleportRandomlyConsumeEffect> TELEPORT_RANDOMLY_TYPE26_3 = new Type<>(TeleportRandomlyConsumeEffect.class) {
@Override
public void write(final ByteBuf buffer, final TeleportRandomlyConsumeEffect value) {
Types.FLOAT.writePrimitive(buffer, value.diameter());
Types.BOOLEAN.write(buffer, value.directionalParticles());
}
@Override
public TeleportRandomlyConsumeEffect read(final ByteBuf buffer) {
final float diameter = Types.FLOAT.readPrimitive(buffer);
final boolean directionalParticles = Types.BOOLEAN.read(buffer);
return new TeleportRandomlyConsumeEffect(diameter, directionalParticles);
}
@Override
public void write(final Ops ops, final TeleportRandomlyConsumeEffect value) {
ops.writeMap(map -> map
.writeOptional("diameter", Types.FLOAT, value.diameter(), 16F)
.writeOptional("directional_particles", Types.BOOLEAN, value.directionalParticles(), true)
);
}
};
private static final HolderType<SoundEvent> PLAY_SOUND_TYPE = new HolderType<>(MappingData.MappingType.SOUND) {
@Override
public SoundEvent readDirect(final ByteBuf buffer) {
return Types.SOUND_EVENT.readDirect(buffer);
}
@Override
public void writeDirect(final ByteBuf buffer, final SoundEvent value) {
Types.SOUND_EVENT.writeDirect(buffer, value);
}
@Override
public void write(final Ops ops, final Holder<SoundEvent> value) {
ops.writeMap(map -> map.write("sound", Types.SOUND_EVENT, value));
}
};
public static final Type<?>[] EFFECT_TYPES1_21_2 = {
ApplyStatusEffects.TYPE,
REMOVE_EFFECTS_TYPE,
Types.EMPTY, // clear all effects
TELEPORT_RANDOMLY_TYPE1_21_2,
PLAY_SOUND_TYPE
};
public static final Type<?>[] EFFECT_TYPES26_3 = {
ApplyStatusEffects.TYPE,
REMOVE_EFFECTS_TYPE,
Types.EMPTY, // clear all effects
TELEPORT_RANDOMLY_TYPE26_3,
PLAY_SOUND_TYPE
};
public static final Type<ConsumeEffect<?>> TYPE1_21_2 = new ConsumeEffectType(EFFECT_TYPES1_21_2);
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE1_21_2 = new ArrayType<>(TYPE1_21_2);
public static final Type<ConsumeEffect<?>> TYPE26_3 = new ConsumeEffectType(EFFECT_TYPES26_3);
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE26_3 = new ArrayType<>(TYPE26_3);
static <T> ConsumeEffect<T> of(final int id, final Type<T> type, final Object value) {
//noinspection unchecked
return new ConsumeEffect<>(id, type, (T) value);
}
@Override
public ConsumeEffect<T> rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
if (this.type != PLAY_SOUND_TYPE) {
return this;
}
//noinspection unchecked
final Holder<SoundEvent> sound = (Holder<SoundEvent>) this.value;
final Holder<SoundEvent> rewrittenSound = SoundEvent.rewriteHolder(sound, Rewritable.soundRewriteFunction(protocol, clientbound));
return rewrittenSound == sound ? this : ConsumeEffect.of(this.id, this.type, rewrittenSound);
}
public static ConsumeEffect<?>[] rewrite(final ConsumeEffect<?>[] effects, final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
ConsumeEffect<?>[] rewrittenEffects = effects;
for (int i = 0; i < effects.length; i++) {
final ConsumeEffect<?> rewrittenEffect = effects[i].rewrite(connection, protocol, clientbound);
if (rewrittenEffect != effects[i]) {
if (rewrittenEffects == effects) {
rewrittenEffects = effects.clone();
}
rewrittenEffects[i] = rewrittenEffect;
}
}
return rewrittenEffects;
}
void writeValue(final ByteBuf buf) {
this.type.write(buf, this.value);
}
private static final class ConsumeEffectType extends Type<ConsumeEffect<?>> {
private final Type<?>[] types;
private ConsumeEffectType(final Type<?>[] types) {
super(ConsumeEffect.class);
this.types = types;
}
@Override
public ConsumeEffect<?> read(final ByteBuf buffer) {
// Oh no...
final int effectType = Types.VAR_INT.readPrimitive(buffer);
final Type<?> type = types[effectType];
final Object value = type.read(buffer);
return ConsumeEffect.of(effectType, type, value);
}
@Override
public void write(final ByteBuf buffer, final ConsumeEffect<?> value) {
Types.VAR_INT.writePrimitive(buffer, value.id);
value.writeValue(buffer);
}
@Override
public void write(final Ops ops, final ConsumeEffect<?> value) {
writeGeneric(ops, value);
}
private <E> void writeGeneric(final Ops ops, final ConsumeEffect<E> value) {
ops.writeMap(map -> map
.write("type", EnumTypes.CONSUME_EFFECT, value.id)
.writeInlinedMap(value.type, value.value));
}
}
}
@@ -1,26 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.consumable;
public record TeleportRandomlyConsumeEffect(float diameter, boolean directionalParticles) {
}
@@ -1,66 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.trim;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record ArmorTrim26_3(Holder<ArmorTrimMaterial26_3> material,
Holder<ArmorTrimPattern> pattern) implements Rewritable {
public static final Type<ArmorTrim26_3> TYPE = new Type<>(ArmorTrim26_3.class) {
@Override
public ArmorTrim26_3 read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial26_3> material = ArmorTrimMaterial26_3.TYPE.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE1_21_5.read(buffer);
return new ArmorTrim26_3(material, pattern);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim26_3 value) {
ArmorTrimMaterial26_3.TYPE.write(buffer, value.material);
ArmorTrimPattern.TYPE1_21_5.write(buffer, value.pattern);
}
@Override
public void write(final Ops ops, final ArmorTrim26_3 value) {
ops.writeMap(map -> map
.write("material", ArmorTrimMaterial26_3.TYPE, value.material)
.write("pattern", ArmorTrimPattern.TYPE1_21_5, value.pattern));
}
};
@Override
public ArmorTrim26_3 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
Holder<ArmorTrimPattern> pattern = this.pattern;
if (pattern.isDirect()) {
pattern = Holder.of(pattern.value().rewrite(connection, protocol, clientbound));
}
return new ArmorTrim26_3(material, pattern);
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.trim;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import com.viaversion.viaversion.util.Key;
import io.netty.buffer.ByteBuf;
public record ArmorTrimMaterial26_3(String paletteId, Tag description) {
public static final HolderType<ArmorTrimMaterial26_3> TYPE = new HolderType<>() {
@Override
public ArmorTrimMaterial26_3 readDirect(final ByteBuf buffer) {
final String paletteId = Types.STRING.read(buffer);
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial26_3(paletteId, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial26_3 value) {
Types.STRING.write(buffer, value.paletteId());
Types.TAG.write(buffer, value.description());
}
@Override
public void writeDirect(final Ops ops, final ArmorTrimMaterial26_3 object) {
ops.writeMap(map -> {
map.write("palette_id", Types.IDENTIFIER, Key.of(object.paletteId()));
map.write("description", Types.TEXT_COMPONENT_TAG, object.description());
});
}
@Override
protected Key identifier(final Ops ops, final int id) {
return ops.context().registryAccess().registryKey("trim_material", id);
}
};
}
@@ -23,7 +23,6 @@
package com.viaversion.viaversion.api.protocol;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.connection.ProtocolStorables;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
@@ -34,7 +33,6 @@ import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
@@ -60,22 +58,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
*/
public interface Protocol<CU extends ClientboundPacketType, CM extends ClientboundPacketType, SM extends ServerboundPacketType, SU extends ServerboundPacketType> {
/**
* Returns the server protocol version for this protocol,
* or null if not set (e.g. for base protocols).
*
* @return the server protocol version
*/
@Nullable ProtocolVersion getServerVersion();
/**
* Returns the client protocol version for this protocol,
* or null if not set (e.g. for base protocols).
*
* @return the client protocol version for this protocol
*/
@Nullable ProtocolVersion getClientVersion();
default void registerClientbound(State state, ClientboundPacketType packetType, @Nullable PacketHandler handler) {
Preconditions.checkArgument(packetType.state() == state);
registerClientbound(state, packetType.getId(), packetType.getId(), handler, false);
@@ -478,15 +460,6 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
return false;
}
/**
* Returns the index assigned to this protocol during registration.
*
* @return protocol index, or -1 if not yet registered
*/
int index();
ProtocolStorables createStorables();
/**
* Marks this protocol as dependent on another. Before being initialized, it will wait for the dependency's completion.
*
@@ -318,12 +318,4 @@ public interface ProtocolManager {
* @return whether the mappings have been loaded
*/
boolean hasLoadedMappings();
/**
* Returns the number of registered protocols.
* Used to size per-connection protocol data arrays.
*
* @return number of registered protocols
*/
int registeredProtocolCount();
}
@@ -165,7 +165,7 @@ public class PacketTracker {
// Warning system
private long warningPeriodStart = System.nanoTime();
private long lastWarning = warningPeriodStart - SECOND_NANOS;
private long lastWarning = Long.MIN_VALUE;
private int warnings;
public RateTracker(int windowSize) {
@@ -28,11 +28,5 @@ public enum State {
STATUS,
LOGIN,
CONFIGURATION,
PLAY;
private static final int STATES_COUNT = values().length;
public static int statesCount() {
return STATES_COUNT;
}
PLAY
}
@@ -27,7 +27,7 @@ import java.util.Arrays;
import org.checkerframework.checker.nullness.qual.Nullable;
final class PacketArrayMappings implements PacketMappings {
private final PacketMapping[][] packets = new PacketMapping[State.statesCount()][];
private final PacketMapping[][] packets = new PacketMapping[State.values().length][];
@Override
public @Nullable PacketMapping mappedPacket(final State state, final int unmappedId) {
@@ -94,8 +94,6 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_21_9 = register(773, "1.21.9-1.21.10", new SubVersionRange("1.21", 9, 10));
public static final ProtocolVersion v1_21_11 = register(774, "1.21.11");
public static final ProtocolVersion v26_1 = register(775, "26.1-26.1.2", new SubVersionRange("26.1", 0, 2));
public static final ProtocolVersion v26_2 = register(776, "26.2");
public static final ProtocolVersion v26_3 = register(777, "26.3");
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
static {
@@ -87,6 +87,6 @@ public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter
* @return entity tracker
*/
default <E extends EntityTracker> E tracker(UserConnection connection) {
return connection.getEntityTracker(protocol());
return connection.getEntityTracker(protocol().getClass());
}
}
@@ -36,8 +36,6 @@ public interface RegistryDataRewriter {
void updateDialog(UserConnection connection, CompoundTag tag);
boolean updateBlockStateProvider(CompoundTag tag);
/**
* Sends registries that had additional entries configured, but weren't sent by the server at all
* by the time finish_configuration was sent to the client.
@@ -23,8 +23,6 @@
package com.viaversion.viaversion.api.type;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.util.NestingLimiter;
import io.netty.buffer.ByteBuf;
/**
* Type for buffer reading and writing.
@@ -65,22 +63,6 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T>, Cod
return typeName != null && !typeName.isEmpty() ? typeName : this.getClass().getName();
}
/**
* Reads a value and counts it towards the nesting depth limit of the current thread, to be used by recursive types.
*
* @param buffer buffer to read from
* @return read value
* @see NestingLimiter
*/
public T readTrackingDepth(final ByteBuf buffer) {
NestingLimiter.increment();
try {
return read(buffer);
} finally {
NestingLimiter.decrement();
}
}
@Override
public void write(Ops ops, T value) {
throw new UnsupportedOperationException("Write operation not supported for type: " + getTypeName());
@@ -36,8 +36,6 @@ import com.viaversion.viaversion.api.minecraft.PlayerMessageSignature;
import com.viaversion.viaversion.api.minecraft.ProfileKey;
import com.viaversion.viaversion.api.minecraft.Quaternion;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.ResolvableFloat;
import com.viaversion.viaversion.api.minecraft.ResolvableInt;
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.Vector;
@@ -60,7 +58,6 @@ import com.viaversion.viaversion.api.type.types.ByteType;
import com.viaversion.viaversion.api.type.types.ComponentType;
import com.viaversion.viaversion.api.type.types.DoubleType;
import com.viaversion.viaversion.api.type.types.EmptyType;
import com.viaversion.viaversion.api.type.types.FixedLengthArrayType;
import com.viaversion.viaversion.api.type.types.FloatArrayType;
import com.viaversion.viaversion.api.type.types.FloatType;
import com.viaversion.viaversion.api.type.types.IntArrayType;
@@ -108,7 +105,6 @@ import com.viaversion.viaversion.api.type.types.math.EulerAngleType;
import com.viaversion.viaversion.api.type.types.math.GlobalBlockPositionType;
import com.viaversion.viaversion.api.type.types.math.LowPrecisionVectorType;
import com.viaversion.viaversion.api.type.types.math.QuaternionType;
import com.viaversion.viaversion.api.type.types.math.Vector3dType;
import com.viaversion.viaversion.api.type.types.math.Vector3fType;
import com.viaversion.viaversion.api.type.types.math.VectorType;
import com.viaversion.viaversion.api.type.types.misc.CompoundTagHolderType;
@@ -122,8 +118,6 @@ import com.viaversion.viaversion.api.type.types.misc.NamedCompoundTagType;
import com.viaversion.viaversion.api.type.types.misc.PlayerMessageSignatureType;
import com.viaversion.viaversion.api.type.types.misc.ProfileKeyType;
import com.viaversion.viaversion.api.type.types.misc.ProfilePropertyType;
import com.viaversion.viaversion.api.type.types.misc.ResolvableFloatType;
import com.viaversion.viaversion.api.type.types.misc.ResolvableIntType;
import com.viaversion.viaversion.api.type.types.misc.ResolvableProfileType;
import com.viaversion.viaversion.api.type.types.misc.SoundEventType;
import com.viaversion.viaversion.api.type.types.misc.TagKeyType;
@@ -185,13 +179,10 @@ public final class Types {
public static final Type<UUID[]> UUID_ARRAY = new ArrayType<>(Types.UUID);
public static final VarIntType VAR_INT = new VarIntType();
public static final OptionalVarIntType OPTIONAL_VAR_INT = new OptionalVarIntType(); // compact
public static final OptionalType<Integer> BOOL_OPTIONAL_VAR_INT = new VarIntType.OptionalVarIntType(); // regular boolean prefixed
public static final OptionalVarIntType OPTIONAL_VAR_INT = new OptionalVarIntType();
public static final Type<int[]> VAR_INT_ARRAY_PRIMITIVE = new VarIntArrayType();
public static final VarLongType VAR_LONG = new VarLongType();
public static final BitSetType BIT_SET = new BitSetType(); // Generic length
/* MC Types */
public static final Type<byte[]> SERVERBOUND_CUSTOM_PAYLOAD_DATA = new RemainingBytesType(Short.MAX_VALUE);
@@ -200,9 +191,6 @@ public final class Types {
public static final Type<Key[]> IDENTIFIER_ARRAY = new ArrayType<>(IDENTIFIER);
public static final Type<Key> TAG_KEY = new TagKeyType();
public static final Type<ResolvableFloat> RESOLVABLE_FLOAT = new ResolvableFloatType();
public static final Type<ResolvableInt> RESOLVABLE_INT = new ResolvableIntType();
public static final Type<BlockPosition> BLOCK_POSITION1_8 = new BlockPositionType1_8();
public static final Type<BlockPosition> OPTIONAL_POSITION1_8 = new BlockPositionType1_8.OptionalBlockPositionType();
public static final Type<BlockPosition> BLOCK_POSITION1_14 = new BlockPositionType1_14();
@@ -210,7 +198,6 @@ public final class Types {
public static final Type<EulerAngle> ROTATIONS = new EulerAngleType();
public static final Type<Vector> VECTOR = new VectorType();
public static final Type<Vector3f> VECTOR3F = new Vector3fType();
public static final Type<Vector3d> VECTOR3D = new Vector3dType();
public static final Type<Quaternion> QUATERNION = new QuaternionType();
public static final Type<Vector3d> LOW_PRECISION_VECTOR = new LowPrecisionVectorType();
@Deprecated(forRemoval = true)
@@ -227,11 +214,7 @@ public final class Types {
public static final Type<Tag[]> TAG_ARRAY = new ArrayType<>(TAG);
public static final Type<Tag> OPTIONAL_TAG = TagType.OptionalTagType.type();
public static final Type<Tag> TEXT_COMPONENT_TAG = new TextComponentTagType(); // only strictly needed for hashing
public static final Type<Tag[]> TEXT_COMPONENT_TAG_ARRAY = new ArrayType<>(Types.TEXT_COMPONENT_TAG);
public static final Type<Tag> CUSTOM_CLICK_ACTION_TAG = new LengthPrefixedTagType(65536);
public static final FixedLengthArrayType<Tag> SIGN_TEXT = new FixedLengthArrayType<>(TAG, 4);
public static final Type<Tag[]> OPTIONAL_SIGN_TEXT = SIGN_TEXT.new OptionalFixedLengthArrayType();
public static final Type<Tag> TRUSTED_TAG = new TagType(false);
public static final Type<Tag> TRUSTED_OPTIONAL_TAG = TagType.OptionalTagType.trustedType();
@@ -296,7 +279,6 @@ public final class Types {
public static final Type<List<EntityData>> ENTITY_DATA_LIST1_9 = new EntityDataListType(ENTITY_DATA1_9);
public static final Type<List<EntityData>> ENTITY_DATA_LIST1_12 = new EntityDataListType(ENTITY_DATA1_12);
// No longer used past 1.20.2
public static final Type<Item> ITEM1_8 = new ItemType1_8();
public static final Type<Item> ITEM1_13 = new ItemType1_13();
@@ -31,8 +31,7 @@ import java.util.ArrayList;
import java.util.List;
public class ArrayType<T> extends Type<T[]> {
private static final int MAX_PRESIZED_LENGTH = 128;
protected final Type<T> elementType;
private final Type<T> elementType;
private final int maxLength;
public ArrayType(Type<T> type) {
@@ -46,12 +45,6 @@ public class ArrayType<T> extends Type<T[]> {
this.maxLength = maxLength;
}
private ArrayType(Class<? super T[]> outputClass, Type<T> type, int maxLength) {
super(type.getTypeName() + " Array", outputClass);
this.elementType = type;
this.maxLength = maxLength;
}
public static Class<?> getArrayClass(Class<?> componentType) {
// Should only happen once per class init.
return Array.newInstance(componentType, 0).getClass();
@@ -64,10 +57,10 @@ public class ArrayType<T> extends Type<T[]> {
throw new IllegalArgumentException("Array length " + amount + " is longer than maximum " + maxLength);
}
return amount <= MAX_PRESIZED_LENGTH ? readArray(buffer, amount) : readList(buffer, amount);
return amount < Short.MAX_VALUE ? readArray(buffer, amount) : readList(buffer, amount);
}
protected T[] readArray(ByteBuf buffer, int length) {
private T[] readArray(ByteBuf buffer, int length) {
T[] array = createArray(length);
for (int i = 0; i < length; i++) {
array[i] = elementType.read(buffer);
@@ -108,18 +101,4 @@ public class ArrayType<T> extends Type<T[]> {
}
});
}
public ArrayType<T> withMaxLength(final int maxLength) {
return new ArrayType<>(this.getOutputClass(), this.elementType, maxLength);
}
static int checkLength(final int length, final int elementBytes, final int readable) {
if (length < 0) {
throw new IllegalArgumentException("Length " + length + " is negative");
}
if ((long) length * elementBytes > readable) {
throw new IllegalArgumentException("Length " + length + " is larger than readable bytes");
}
return length;
}
}
@@ -24,7 +24,6 @@ package com.viaversion.viaversion.api.type.types;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import java.util.Arrays;
import java.util.BitSet;
@@ -40,31 +39,17 @@ public class BitSetType extends Type<BitSet> {
this.bytesLength = (int) Math.ceil(length / 8D);
}
public BitSetType() {
super(BitSet.class);
this.length = -1;
this.bytesLength = -1;
}
@Override
public BitSet read(ByteBuf buffer) {
if (this.length != -1) {
final byte[] bytes = new byte[bytesLength];
buffer.readBytes(bytes);
return BitSet.valueOf(bytes);
} else {
return BitSet.valueOf(Types.BYTE_ARRAY_PRIMITIVE.read(buffer));
}
final byte[] bytes = new byte[bytesLength];
buffer.readBytes(bytes);
return BitSet.valueOf(bytes);
}
@Override
public void write(ByteBuf buffer, BitSet object) {
if (this.length != -1) {
Preconditions.checkArgument(object.length() <= length, "BitSet of length %s larger than max length %s", object.length(), length);
final byte[] bytes = object.toByteArray();
buffer.writeBytes(bytes.length == bytesLength ? bytes : Arrays.copyOf(bytes, bytesLength));
} else {
Types.BYTE_ARRAY_PRIMITIVE.write(buffer, object.toByteArray());
}
Preconditions.checkArgument(object.length() <= length, "BitSet of length %s larger than max length %s", object.length(), length);
final byte[] bytes = object.toByteArray();
buffer.writeBytes(bytes.length == bytesLength ? bytes : Arrays.copyOf(bytes, bytesLength));
}
}
@@ -57,7 +57,7 @@ public class BooleanArrayType extends Type<boolean[]> {
@Override
public boolean[] read(final ByteBuf buffer) {
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is larger than readable bytes");
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
final boolean[] array = new boolean[length];
for (int i = 0; i < length; i++) {
array[i] = buffer.readBoolean();
@@ -32,30 +32,15 @@ import io.netty.buffer.ByteBuf;
public class ByteArrayType extends Type<byte[]> {
private final int length;
private final int maxLength;
public ByteArrayType(final int length) {
this(length, -1);
super(byte[].class);
this.length = length;
}
public ByteArrayType() {
this(-1, -1);
}
private ByteArrayType(final int length, final int maxLength) {
super(byte[].class);
this.length = length;
this.maxLength = maxLength;
}
/**
* Returns a length-prefixed byte array type that rejects arrays longer than the given maximum.
*
* @param maxLength maximum array length
* @return length-prefixed byte array type with the given maximum length
*/
public static ByteArrayType withMaxLength(final int maxLength) {
return new ByteArrayType(-1, maxLength);
this.length = -1;
}
@Override
@@ -63,7 +48,6 @@ public class ByteArrayType extends Type<byte[]> {
if (this.length != -1) {
Preconditions.checkArgument(length == object.length, "Length does not match expected length");
} else {
checkMaxLength(object.length);
Types.VAR_INT.writePrimitive(buffer, object.length);
}
buffer.writeBytes(object);
@@ -71,20 +55,13 @@ public class ByteArrayType extends Type<byte[]> {
@Override
public byte[] read(final ByteBuf buffer) {
final int length = this.length == -1 ? checkMaxLength(Types.VAR_INT.readPrimitive(buffer)) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is larger than readable bytes");
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
final byte[] array = new byte[length];
buffer.readBytes(array);
return array;
}
private int checkMaxLength(final int length) {
if (maxLength != -1 && length > maxLength) {
throw new IllegalArgumentException("Byte array length " + length + " is longer than maximum " + maxLength);
}
return length;
}
@Override
public void write(final Ops ops, final byte[] value) {
ops.writeBytes(value);
@@ -76,16 +76,4 @@ public final class EnumType extends VarIntType {
public enum Fallback {
ZERO, WRAP, CLAMP
}
public final class EnumArrayType extends VarIntArrayType {
@Override
public void write(final Ops ops, final int[] value) {
ops.writeList(list -> {
for (final int ordinal : value) {
list.write(Types.STRING, nameFromId(ordinal));
}
});
}
}
}
@@ -1,56 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class FixedLengthArrayType<T> extends ArrayType<T> {
private final int length;
public FixedLengthArrayType(final Type<T> type, final int length) {
super(type);
this.length = length;
}
@Override
public T[] read(final ByteBuf buffer) {
return readArray(buffer, this.length);
}
@Override
public void write(final ByteBuf buffer, final T[] object) {
for (final T o : object) {
elementType.write(buffer, o);
}
}
public final class OptionalFixedLengthArrayType extends OptionalType<T[]> {
public OptionalFixedLengthArrayType() {
super(FixedLengthArrayType.this);
}
}
}
@@ -27,8 +27,6 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import static com.viaversion.viaversion.api.type.types.ArrayType.checkLength;
public class FloatArrayType extends Type<float[]> {
private final int length;
@@ -57,7 +55,8 @@ public class FloatArrayType extends Type<float[]> {
@Override
public float[] read(final ByteBuf buffer) {
final int length = checkLength(this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length, Float.BYTES, buffer.readableBytes());
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
final float[] array = new float[length];
for (int i = 0; i < length; i++) {
array[i] = buffer.readFloat();
@@ -28,8 +28,6 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import static com.viaversion.viaversion.api.type.types.ArrayType.checkLength;
public class IntArrayType extends Type<int[]> {
private final int length;
@@ -58,7 +56,8 @@ public class IntArrayType extends Type<int[]> {
@Override
public int[] read(final ByteBuf buffer) {
final int length = checkLength(this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length, Integer.BYTES, buffer.readableBytes());
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
final int[] array = new int[length];
for (int i = 0; i < length; i++) {
array[i] = buffer.readInt();
@@ -28,8 +28,6 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import static com.viaversion.viaversion.api.type.types.ArrayType.checkLength;
public class LongArrayType extends Type<long[]> {
private final int length;
@@ -45,7 +43,8 @@ public class LongArrayType extends Type<long[]> {
@Override
public long[] read(final ByteBuf buffer) {
final int length = checkLength(this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length, Long.BYTES, buffer.readableBytes());
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
return readFixedLength(buffer, length);
}
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.type.types;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
@@ -34,7 +35,6 @@ public class StringType extends Type<String> {
private static final int MAX_CHAR_UTF_8_LENGTH = Character.toString(Character.MAX_VALUE)
.getBytes(StandardCharsets.UTF_8).length;
private final int maxLength;
private final int maxByteLength;
public StringType() {
this(Short.MAX_VALUE);
@@ -43,22 +43,21 @@ public class StringType extends Type<String> {
public StringType(int maxLength) {
super(String.class);
this.maxLength = maxLength;
this.maxByteLength = maxLength * MAX_CHAR_UTF_8_LENGTH;
}
@Override
public String read(ByteBuf buffer) {
int len = Types.VAR_INT.readPrimitive(buffer);
if (len > maxByteLength) {
throw new IllegalArgumentException("Cannot receive string longer than " + maxLength + " * " + MAX_CHAR_UTF_8_LENGTH + " bytes (got " + len + " bytes)");
}
Preconditions.checkArgument(len <= maxLength * MAX_CHAR_UTF_8_LENGTH,
"Cannot receive string longer than " + maxLength + " * " + MAX_CHAR_UTF_8_LENGTH + " bytes (got %s bytes)", len);
String string = buffer.toString(buffer.readerIndex(), len, StandardCharsets.UTF_8);
buffer.skipBytes(len);
if (string.length() > maxLength) {
throw new IllegalArgumentException("Cannot receive string longer than " + maxLength + " characters (got " + string.length() + ")");
}
Preconditions.checkArgument(string.length() <= maxLength,
"Cannot receive string longer than " + maxLength + " characters (got %s bytes)", string.length());
return string;
}
@@ -23,7 +23,6 @@
package com.viaversion.viaversion.api.type.types;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.TypeConverter;
import com.viaversion.viaversion.api.type.Types;
@@ -109,11 +108,4 @@ public class VarIntType extends Type<Integer> implements TypeConverter<Integer>
public static int varIntLength(final int value) {
return VAR_INT_LENGTHS[Integer.numberOfLeadingZeros(value)];
}
public static final class OptionalVarIntType extends OptionalType<Integer> {
public OptionalVarIntType() {
super(Types.VAR_INT);
}
}
}
@@ -83,11 +83,8 @@ public class PaletteType1_18 extends PaletteTypeBase {
final int valuesPerLong = (char) (64 / bitsPerValue);
final int expectedLength = (type.size() + valuesPerLong - 1) / valuesPerLong;
if (values.length == expectedLength) {
if (bitsPerValue == globalPaletteBits) {
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.size(), values, palette::setIdAt);
} else {
palette.setPaletteIndexes(values, bitsPerValue, valuesPerLong);
}
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.size(), values,
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt);
}
}
@@ -123,7 +120,11 @@ public class PaletteType1_18 extends PaletteTypeBase {
return;
}
final long[] values = palette.createPackedValues(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits);
final long[] values = CompactArrayUtil.createCompactArrayWithPadding(
bitsPerValue,
type.size(),
bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt
);
Types.LONG_ARRAY_PRIMITIVE.write(buffer, values);
}
@@ -46,11 +46,12 @@ public final class PaletteType1_21_5 extends PaletteType1_18 {
final int expectedLength = (type.size() + valuesPerLong - 1) / valuesPerLong;
final long[] values = LongArrayType.readFixedLength(buffer, expectedLength);
if (values.length != 0) {
if (bitsPerValue == globalPaletteBits) {
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.size(), values, palette::setIdAt);
} else {
palette.setPaletteIndexes(values, bitsPerValue, valuesPerLong);
}
CompactArrayUtil.iterateCompactArrayWithPadding(
bitsPerValue,
type.size(),
values,
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt
);
}
}
@@ -60,7 +61,11 @@ public final class PaletteType1_21_5 extends PaletteType1_18 {
return;
}
final long[] values = palette.createPackedValues(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits);
final long[] values = CompactArrayUtil.createCompactArrayWithPadding(
bitsPerValue,
type.size(),
bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt
);
LongArrayType.writeFixedLength(buffer, values);
}
Loaded 100 of 427 files, more files were not shown because too many files have changed in this diff. Show more