mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2026-11-04 17:00:06 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fb3aa8c7a | ||
|
|
f175a903a3 | ||
|
|
7c80e37e3a | ||
|
|
ff61e1d897 | ||
|
|
d49272a41f | ||
|
|
bea6df1174 | ||
|
|
4ca84f6001 | ||
|
|
61c079af19 | ||
|
|
e0b9deb128 | ||
|
|
1d89bc7f95 | ||
|
|
28c18c33fa | ||
|
|
d08cb1b743 | ||
|
|
fb18f69a0b | ||
|
|
56e1d32aa0 | ||
|
|
d4aa5a2fb3 | ||
|
|
b54a87f465 | ||
|
|
5acfa9faf7 | ||
|
|
638f4cd19a | ||
|
|
baf12dd516 | ||
|
|
4b6b26fbba | ||
|
|
5c5784795d | ||
|
|
1f8e7515b1 | ||
|
|
3778698018 | ||
|
|
40dd2be139 | ||
|
|
edbe2c92ce | ||
|
|
b9ae1ef43e | ||
|
|
4631fd1977 | ||
|
|
3d25686745 | ||
|
|
18b5b2626a | ||
|
|
219ad4737a | ||
|
|
b9368ae80a | ||
|
|
03c80ccff8 | ||
|
|
f6aed5578f | ||
|
|
646de0b1af | ||
|
|
4e33a40ede | ||
|
|
21b0ac7a43 | ||
|
|
15d3944700 | ||
|
|
acd9a6f57c | ||
|
|
d5fe4e22b4 | ||
|
|
9f0c38915a | ||
|
|
bc7f081b3a | ||
|
|
46b6627f9f | ||
|
|
51cc1843ad | ||
|
|
98d1d2cb49 | ||
|
|
556560a0f3 | ||
|
|
be2534c6e6 | ||
|
|
d40d1bd232 | ||
|
|
6143f78ccf | ||
|
|
52cdebc3d3 | ||
|
|
cdccae95e0 | ||
|
|
b0c45e3ed3 | ||
|
|
3ba518650c | ||
|
|
5a303996a1 | ||
|
|
695534e8a8 | ||
|
|
16ba011243 | ||
|
|
0ea7271157 | ||
|
|
dc2b2f1407 | ||
|
|
85baefc69b | ||
|
|
41e0fdc20f | ||
|
|
5c328fba33 | ||
|
|
91b11878fb | ||
|
|
0ea5e07d63 | ||
|
|
152e4e77a8 | ||
|
|
cf20c6397d | ||
|
|
981672e2cf | ||
|
|
d10b600e72 | ||
|
|
de9cec36c7 | ||
|
|
6eb561607c | ||
|
|
db3e1f605a | ||
|
|
31583fc2d3 | ||
|
|
6096ce4eea | ||
|
|
873da12233 | ||
|
|
78191ea366 | ||
|
|
f8d7c5c193 | ||
|
|
bc9c979e7d | ||
|
|
d686a9ddf0 | ||
|
|
9dd610605f | ||
|
|
219e163ac2 | ||
|
|
925e7b4664 | ||
|
|
5a9f040af8 | ||
|
|
992ad7f35a | ||
|
|
bb93ac011c | ||
|
|
4070ea9f02 | ||
|
|
499efa1608 | ||
|
|
0196d9c83e | ||
|
|
4c316de042 | ||
|
|
8ee5d7e680 | ||
|
|
64c128d414 | ||
|
|
77d11fc593 | ||
|
|
2c72a09809 | ||
|
|
3dbd81da76 | ||
|
|
a0116c7ea7 | ||
|
|
fd5dadbe01 | ||
|
|
df87a02c38 | ||
|
|
bb293b3e5d | ||
|
|
ff03892b25 | ||
|
|
eb51306d82 | ||
|
|
81eb3362f3 | ||
|
|
7f06b03453 | ||
|
|
c16432de2a | ||
|
|
b162dbdff0 | ||
|
|
dfbe57e304 | ||
|
|
6f6dc2c641 | ||
|
|
06990ec0c9 | ||
|
|
351b42b5e5 | ||
|
|
20e3c832fb | ||
|
|
ec9c121da2 | ||
|
|
12c773edea | ||
|
|
97b411aa6d | ||
|
|
24f6c4f0fd | ||
|
|
9409c7d22a | ||
|
|
17d94a17f0 | ||
|
|
a1cb4d3691 | ||
|
|
1d5070a480 | ||
|
|
f612adbd0a | ||
|
|
6716beec5a | ||
|
|
d22b00e4a6 | ||
|
|
fe9ca49920 | ||
|
|
e1837dc578 | ||
|
|
66eead2927 | ||
|
|
937a2a2532 | ||
|
|
bee45ef9ef | ||
|
|
1946a65ab2 | ||
|
|
f594a946d4 |
No files matched your search
@@ -11,13 +11,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
@@ -12,19 +12,26 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
check-latest: true
|
||||
- name: Publish
|
||||
- name: Build
|
||||
run: ./gradlew build
|
||||
- name: Publish to Hangar
|
||||
env:
|
||||
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
|
||||
run: ./gradlew publishAllPublicationsToHangar --stacktrace
|
||||
continue-on-error: true
|
||||
- name: Publish to Modrinth
|
||||
env:
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
run: ./gradlew build modrinth publishAllPublicationsToHangar --stacktrace
|
||||
run: ./gradlew modrinth --stacktrace
|
||||
continue-on-error: true
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Update Gradle Wrapper
|
||||
|
||||
+19
-98
@@ -1,115 +1,36 @@
|
||||
### Java files ###
|
||||
*.class
|
||||
# Gradle
|
||||
|
||||
# Package Files
|
||||
#*.jar
|
||||
*.war
|
||||
*.ear
|
||||
.gradle/
|
||||
build/
|
||||
out/
|
||||
classes/
|
||||
.kotlin/
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
# Eclipse
|
||||
|
||||
*.launch
|
||||
|
||||
# Idea
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
# Ignore project files
|
||||
*.iml
|
||||
|
||||
# Ignore IDEA directory
|
||||
.idea/*
|
||||
.idea/
|
||||
!.idea/copyright/*
|
||||
!.idea/scopes/*
|
||||
|
||||
# Include the project's dictionary
|
||||
!.idea/dictionaries/
|
||||
!.idea/dictionaries/*
|
||||
|
||||
# File-based project format:
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
### Plugin-specific files: ###
|
||||
# IntelliJ
|
||||
/out/
|
||||
# VSCode
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.vscode/
|
||||
bin/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
# macOS
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
|
||||
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
.nb-gradle/
|
||||
|
||||
### MacOS ###
|
||||
.DS_Store
|
||||
|
||||
### Run Folder (ViaProxy) ###
|
||||
common/run/
|
||||
# Misc
|
||||
|
||||
run/
|
||||
@@ -8,7 +8,7 @@
|
||||
it works on any platform you can think of.**
|
||||
|
||||
The base ViaVersion jar runs on Paper and Velocity. We also have projects integrating ViaVersion to run
|
||||
on Fabric, Forge, Bungee, Sponge, or as a standalone proxy to join from basically any client version on
|
||||
on Fabric, Forge, Sponge, or as a standalone proxy to join from basically any client version on
|
||||
any server version from the past decade. **See [HERE](https://viaversion.com) for an overview of the different Via\* projects.**
|
||||
|
||||
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
|
||||
@@ -16,7 +16,7 @@ direct access to client/server state and more extensive API.
|
||||
|
||||
Supported Versions:
|
||||
|
||||

|
||||

|
||||
|
||||
**User Docs:** https://docs.viaversion.com
|
||||
|
||||
@@ -87,12 +87,10 @@ of the `build/libs` directory.
|
||||
|
||||
You need JDK 17 or newer to build ViaVersion.
|
||||
|
||||
|
||||
Mapping Files
|
||||
--------------
|
||||
Mapping files are generated and managed in our [Mappings repository](https://github.com/ViaVersion/Mappings). The generated mapping output is stored [here](./common/src/main/resources/assets/viaversion).
|
||||
|
||||
|
||||
Resources
|
||||
--------
|
||||
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a **security vulnerability**, please **do not** open a public issue. Instead, use one of the following **confidential contact methods**:
|
||||
|
||||
* **Email:** [security@viaversion.com](mailto:security@viaversion.com)
|
||||
* **Discord:** Join our [Discord server](https://discord.gg/viaversion) and visit the [#exploit-report](https://discord.com/channels/316206679014244363/1388847764137316485) channel for further instructions.
|
||||
|
||||
If your issue is **not security-related** (e.g., bug reports, feature requests, or usage questions), please use the [GitHub Issues page](https://github.com/ViaVersion/ViaVersion/issues) or contact us via the [Discord server](https://discord.gg/viaversion).
|
||||
@@ -123,7 +123,7 @@ public interface ViaAPI<T> {
|
||||
boolean isInjected(UUID uuid);
|
||||
|
||||
/**
|
||||
* Returns whether Via injected into this player connection. Note that this method may not work on
|
||||
* Returns the injected UserConnection if present. Note that this method may not work on
|
||||
* clientside implementations and is generally not recommended to be used. Use {@link ConnectionManager} instead.
|
||||
*
|
||||
* @param uuid uuid of the player
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.configuration;
|
||||
|
||||
public record RateLimitConfig(boolean enabled, int maxRate, String maxRateKickMessage, int warningRate, int maxWarnings,
|
||||
long trackingPeriodNanos, String warningKickMessage, String ratePlaceholder) {
|
||||
}
|
||||
+20
-7
@@ -147,6 +147,7 @@ public interface ViaVersionConfig extends Config {
|
||||
*
|
||||
* @return The number of packets a client can send per second.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
int getMaxPPS();
|
||||
|
||||
/**
|
||||
@@ -154,6 +155,7 @@ public interface ViaVersionConfig extends Config {
|
||||
*
|
||||
* @return Kick message, with colour codes using '&amp;'
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
String getMaxPPSKickMessage();
|
||||
|
||||
/**
|
||||
@@ -161,6 +163,7 @@ public interface ViaVersionConfig extends Config {
|
||||
*
|
||||
* @return Time in seconds that should be tracked for warnings
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
int getTrackingPeriod();
|
||||
|
||||
/**
|
||||
@@ -168,6 +171,7 @@ public interface ViaVersionConfig extends Config {
|
||||
*
|
||||
* @return The number of packets per second to count as a warning.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
int getWarningPPS();
|
||||
|
||||
/**
|
||||
@@ -175,6 +179,7 @@ public interface ViaVersionConfig extends Config {
|
||||
*
|
||||
* @return The number of packets a client can send per second.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
int getMaxWarnings();
|
||||
|
||||
/**
|
||||
@@ -182,8 +187,13 @@ public interface ViaVersionConfig extends Config {
|
||||
*
|
||||
* @return Kick message, with colour codes using '&amp;'
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
String getMaxWarningsKickMessage();
|
||||
|
||||
RateLimitConfig getPacketTrackerConfig();
|
||||
|
||||
RateLimitConfig getPacketSizeTrackerConfig();
|
||||
|
||||
/**
|
||||
* Send supported versions in the status response packet
|
||||
*
|
||||
@@ -233,13 +243,6 @@ public interface ViaVersionConfig extends Config {
|
||||
*/
|
||||
boolean isChunkBorderFix();
|
||||
|
||||
/**
|
||||
* Should we fix nbt array's in json chat messages for 1.12 clients
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_12NBTArrayFix();
|
||||
|
||||
/**
|
||||
* Should we make team colours based on the last colour in team prefix
|
||||
*
|
||||
@@ -270,6 +273,8 @@ public interface ViaVersionConfig extends Config {
|
||||
*/
|
||||
String getBlockedDisconnectMsg();
|
||||
|
||||
boolean logBlockedJoins();
|
||||
|
||||
/**
|
||||
* Get the message sent to players being kicked on reload.
|
||||
* Players are kicked to stop the server crashing
|
||||
@@ -485,4 +490,12 @@ public interface ViaVersionConfig extends Config {
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean fix1_21PlacementRotation();
|
||||
|
||||
/**
|
||||
* If enabled, cancel swing packets sent while having an inventory opened on 1.15.2 and below servers.
|
||||
* This can cause false positives with anti-cheat plugins.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean cancelSwingInInventory();
|
||||
}
|
||||
@@ -30,15 +30,6 @@ package com.viaversion.viaversion.api.connection;
|
||||
*/
|
||||
public interface StorableObject {
|
||||
|
||||
/**
|
||||
* Returns whether the object should be uncached on a server switch.
|
||||
*
|
||||
* @return whether the object should be uncached on a server switch
|
||||
*/
|
||||
default boolean clearOnServerSwitch() {
|
||||
return true;
|
||||
}
|
||||
|
||||
default void onRemove() {
|
||||
}
|
||||
}
|
||||
@@ -139,17 +139,7 @@ public interface UserConnection {
|
||||
/**
|
||||
* Clear stored objects, entity trackers and client worlds.
|
||||
*/
|
||||
default void clearStoredObjects() {
|
||||
clearStoredObjects(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear stored objects, entity trackers and client worlds.
|
||||
* If cleared for a proxy server switch, some stored objects and tracker data will be retained.
|
||||
*
|
||||
* @param isServerSwitch whether the clear is due to a server switch
|
||||
*/
|
||||
void clearStoredObjects(boolean isServerSwitch);
|
||||
void clearStoredObjects();
|
||||
|
||||
/**
|
||||
* Sends a raw packet to the connection on the current thread.
|
||||
@@ -204,9 +194,15 @@ public interface UserConnection {
|
||||
/**
|
||||
* Monitors serverbound packets and returns whether a packet can/should be processed.
|
||||
*
|
||||
* @param bytes the number of bytes in the packet
|
||||
* @return false if this packet should be cancelled
|
||||
*/
|
||||
boolean checkServerboundPacket();
|
||||
boolean checkServerboundPacket(int bytes);
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
default boolean checkServerboundPacket() {
|
||||
return checkServerboundPacket(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors clientbound packets and returns whether a packet can/should be processed.
|
||||
@@ -219,6 +215,11 @@ public interface UserConnection {
|
||||
* @see #checkClientboundPacket()
|
||||
* @see #checkServerboundPacket()
|
||||
*/
|
||||
default boolean checkIncomingPacket(final int bytes) {
|
||||
return isClientSide() ? checkClientboundPacket() : checkServerboundPacket(bytes);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
default boolean checkIncomingPacket() {
|
||||
return isClientSide() ? checkClientboundPacket() : checkServerboundPacket();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.data;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryType;
|
||||
import com.viaversion.viaversion.api.minecraft.TagData;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@@ -140,12 +141,14 @@ public interface MappingData {
|
||||
|
||||
@Nullable Mappings getBlockMappings();
|
||||
|
||||
@Nullable Mappings getBlockEntityMappings();
|
||||
@Nullable FullMappings getFullBlockMappings();
|
||||
|
||||
@Nullable Mappings getBlockStateMappings();
|
||||
|
||||
@Nullable Mappings getSoundMappings();
|
||||
|
||||
@Nullable FullMappings getFullSoundMappings();
|
||||
|
||||
@Nullable Mappings getStatisticsMappings();
|
||||
|
||||
@Nullable Mappings getMenuMappings();
|
||||
@@ -154,6 +157,8 @@ public interface MappingData {
|
||||
|
||||
@Nullable Mappings getPaintingMappings();
|
||||
|
||||
@Nullable FullMappings getBlockEntityMappings();
|
||||
|
||||
@Nullable FullMappings getAttributeMappings();
|
||||
|
||||
@Nullable FullMappings getEntityMappings();
|
||||
@@ -163,4 +168,26 @@ public interface MappingData {
|
||||
@Nullable FullMappings getRecipeSerializerMappings();
|
||||
|
||||
@Nullable FullMappings getDataComponentSerializerMappings();
|
||||
|
||||
default @Nullable FullMappings getFullMappings(final MappingType mappingType) {
|
||||
return switch (mappingType) {
|
||||
case ITEM -> getFullItemMappings();
|
||||
case SOUND -> getFullSoundMappings();
|
||||
case ENTITY -> getEntityMappings();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of block (not block state) ids that had their base type or properties changed.
|
||||
*
|
||||
* @return set of changed block ids, or null if not tracked/none are present
|
||||
*/
|
||||
@Nullable IntSet changedBlocks();
|
||||
|
||||
/**
|
||||
* Type of mappings. Currently only relevant for ops writing of generic holder classes and expanded when needed.
|
||||
*/
|
||||
enum MappingType {
|
||||
ITEM, SOUND, ENTITY
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryType;
|
||||
import com.viaversion.viaversion.api.minecraft.TagData;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
@@ -44,17 +46,21 @@ public class MappingDataBase implements MappingData {
|
||||
protected FullMappings recipeSerializerMappings;
|
||||
protected FullMappings itemDataSerializerMappings;
|
||||
protected FullMappings attributeMappings;
|
||||
protected FullMappings blockEntityMappings;
|
||||
protected ParticleMappings particleMappings;
|
||||
protected BiMappings itemMappings;
|
||||
protected BiMappings blockMappings;
|
||||
protected Mappings blockStateMappings;
|
||||
protected Mappings blockEntityMappings;
|
||||
protected Mappings soundMappings;
|
||||
protected Mappings statisticsMappings;
|
||||
protected Mappings enchantmentMappings;
|
||||
protected Mappings paintingMappings;
|
||||
protected Mappings menuMappings;
|
||||
protected Map<RegistryType, List<TagData>> tags;
|
||||
/**
|
||||
* Set of block ids that have had type or property changes.
|
||||
*/
|
||||
protected IntSet changedBlocks;
|
||||
|
||||
public MappingDataBase(final String unmappedVersion, final String mappedVersion) {
|
||||
this.unmappedVersion = unmappedVersion;
|
||||
@@ -68,10 +74,7 @@ public class MappingDataBase implements MappingData {
|
||||
}
|
||||
|
||||
final CompoundTag data = readMappingsFile("mappings-" + unmappedVersion + "to" + mappedVersion + ".nbt");
|
||||
blockMappings = loadBiMappings(data, "blocks");
|
||||
blockStateMappings = loadMappings(data, "blockstates");
|
||||
blockEntityMappings = loadMappings(data, "blockentities");
|
||||
soundMappings = loadMappings(data, "sounds");
|
||||
statisticsMappings = loadMappings(data, "statistics");
|
||||
menuMappings = loadMappings(data, "menus");
|
||||
enchantmentMappings = loadMappings(data, "enchantments");
|
||||
@@ -80,12 +83,16 @@ public class MappingDataBase implements MappingData {
|
||||
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
|
||||
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
|
||||
if (unmappedIdentifierData != null && mappedIdentifierData != null) {
|
||||
itemMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "items");
|
||||
itemMappings = loadFullOrBiMappings(data, unmappedIdentifierData, mappedIdentifierData, "items");
|
||||
blockMappings = loadFullOrBiMappings(data, unmappedIdentifierData, mappedIdentifierData, "blocks");
|
||||
soundMappings = loadFullOrBiMappings(data, unmappedIdentifierData, mappedIdentifierData, "sounds");
|
||||
|
||||
entityMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "entities");
|
||||
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
|
||||
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
|
||||
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
|
||||
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
|
||||
blockEntityMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "blockentities");
|
||||
|
||||
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
|
||||
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
|
||||
@@ -99,6 +106,8 @@ public class MappingDataBase implements MappingData {
|
||||
} else {
|
||||
// Might not have identifiers in older versions
|
||||
itemMappings = loadBiMappings(data, "items");
|
||||
blockMappings = loadBiMappings(data, "blocks");
|
||||
soundMappings = loadMappings(data, "sounds");
|
||||
}
|
||||
|
||||
final CompoundTag tagsTag = data.getCompoundTag("tags");
|
||||
@@ -109,6 +118,11 @@ public class MappingDataBase implements MappingData {
|
||||
loadTags(RegistryType.ENTITY, tagsTag);
|
||||
}
|
||||
|
||||
final IntArrayTag changedBlocks = data.getIntArrayTag("changed_blocks");
|
||||
if (changedBlocks != null) {
|
||||
this.changedBlocks = new IntOpenHashSet(changedBlocks.getValue());
|
||||
}
|
||||
|
||||
loadExtras(data);
|
||||
}
|
||||
|
||||
@@ -132,6 +146,11 @@ public class MappingDataBase implements MappingData {
|
||||
return MappingDataLoader.INSTANCE.loadMappings(data, key);
|
||||
}
|
||||
|
||||
protected @Nullable BiMappings loadFullOrBiMappings(final CompoundTag data, final CompoundTag unmappedIdentifiersTag, final CompoundTag mappedIdentifiersTag, final String key) {
|
||||
final FullMappings mappings = loadFullMappings(data, unmappedIdentifiersTag, mappedIdentifiersTag, key);
|
||||
return mappings != null ? mappings : loadBiMappings(data, key);
|
||||
}
|
||||
|
||||
protected @Nullable FullMappings loadFullMappings(final CompoundTag data, final CompoundTag unmappedIdentifiersTag, final CompoundTag mappedIdentifiersTag, final String key) {
|
||||
if (!unmappedIdentifiersTag.contains(key) || !mappedIdentifiersTag.contains(key)) {
|
||||
return null;
|
||||
@@ -208,8 +227,8 @@ public class MappingDataBase implements MappingData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOldSoundId(final int i) {
|
||||
return soundMappings.getNewIdOrDefault(i, 0);
|
||||
public int getOldSoundId(final int id) {
|
||||
return soundMappings.inverse().getNewIdOrDefault(id, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -224,8 +243,8 @@ public class MappingDataBase implements MappingData {
|
||||
|
||||
@Override
|
||||
public @Nullable FullMappings getFullItemMappings() {
|
||||
if (itemMappings instanceof FullMappings) {
|
||||
return (FullMappings) itemMappings;
|
||||
if (itemMappings instanceof FullMappings fullItemMappings) {
|
||||
return fullItemMappings;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -241,7 +260,15 @@ public class MappingDataBase implements MappingData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Mappings getBlockEntityMappings() {
|
||||
public @Nullable FullMappings getFullBlockMappings() {
|
||||
if (blockMappings instanceof FullMappings fullBlockMappings) {
|
||||
return fullBlockMappings;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FullMappings getBlockEntityMappings() {
|
||||
return blockEntityMappings;
|
||||
}
|
||||
|
||||
@@ -255,6 +282,14 @@ public class MappingDataBase implements MappingData {
|
||||
return soundMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FullMappings getFullSoundMappings() {
|
||||
if (soundMappings instanceof FullMappings fullSoundMappings) {
|
||||
return fullSoundMappings;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Mappings getStatisticsMappings() {
|
||||
return statisticsMappings;
|
||||
@@ -300,6 +335,11 @@ public class MappingDataBase implements MappingData {
|
||||
return recipeSerializerMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable IntSet changedBlocks() {
|
||||
return changedBlocks;
|
||||
}
|
||||
|
||||
protected Logger getLogger() {
|
||||
return Via.getPlatform().getLogger();
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public class MappingDataLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int mappedSize = tag.getIntTag("mappedSize").asInt();
|
||||
final int mappedSize = tag.getInt("mappedSize", -1);
|
||||
final byte strategy = tag.getByteTag("id").asByte();
|
||||
final V mappings;
|
||||
if (strategy == DIRECT_ID) {
|
||||
|
||||
@@ -82,6 +82,11 @@ public interface EntityTracker {
|
||||
*/
|
||||
void clearEntities();
|
||||
|
||||
/**
|
||||
* Clears all stored data, including entity types, entity data and client entity id.
|
||||
*/
|
||||
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.
|
||||
@@ -180,6 +185,20 @@ public interface EntityTracker {
|
||||
*/
|
||||
void setCurrentWorld(String currentWorld);
|
||||
|
||||
/**
|
||||
* Returns the id of the current dimension, or -1 if unset (i.e. before 1.20.5).
|
||||
*
|
||||
* @return id of the current dimension, or -1 if unset
|
||||
*/
|
||||
int currentDimensionId();
|
||||
|
||||
/**
|
||||
* Sets the id of the current dimension.
|
||||
*
|
||||
* @param currentDimensionId id of the current dimension
|
||||
*/
|
||||
void setCurrentDimensionId(int currentDimensionId);
|
||||
|
||||
int biomesSent();
|
||||
|
||||
void setBiomesSent(int biomesSent);
|
||||
|
||||
@@ -33,7 +33,6 @@ public enum BlockFace {
|
||||
TOP((byte) 0, (byte) 1, (byte) 0, EnumAxis.Y),
|
||||
BOTTOM((byte) 0, (byte) -1, (byte) 0, EnumAxis.Y);
|
||||
|
||||
public static final BlockFace[] HORIZONTAL = {NORTH, SOUTH, EAST, WEST};
|
||||
private static final Map<BlockFace, BlockFace> opposites = new EnumMap<>(BlockFace.class);
|
||||
|
||||
static {
|
||||
|
||||
@@ -29,7 +29,11 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record GameProfile(@Nullable String name, @Nullable UUID id, Property[] properties) {
|
||||
public record GameProfile(@Nullable String name, @Nullable UUID id, Property[] properties, boolean dynamic) {
|
||||
|
||||
public GameProfile(@Nullable final String name, @Nullable final UUID id, final Property[] properties) {
|
||||
this(name, id, properties, true);
|
||||
}
|
||||
|
||||
public GameProfile(@Nullable final String name, @Nullable final UUID id) {
|
||||
this(name, id, new Property[0]);
|
||||
|
||||
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface Holder<T> {
|
||||
|
||||
@@ -89,7 +90,18 @@ public interface Holder<T> {
|
||||
* @param rewriteFunction the function to rewrite the id
|
||||
* @return a new holder with the id rewritten, or self
|
||||
*/
|
||||
Holder<T> updateId(final Int2IntFunction rewriteFunction);
|
||||
default Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
return this.updateId(rewriteFunction, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new holder with the id rewritten using the given function, or self if this is a direct holder or the id did not change.
|
||||
*
|
||||
* @param rewriteFunction the function to rewrite the id
|
||||
* @param ifMissing a supplier that provides a new holder if the id is missing (i.e. -1)
|
||||
* @return a new holder with the id rewritten, or self
|
||||
*/
|
||||
Holder<T> updateId(Int2IntFunction rewriteFunction, Supplier<Holder<T>> ifMissing);
|
||||
|
||||
/**
|
||||
* Returns a new holder with the value rewritten using the given function, or self if this is an id holder or the value did not change.
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Set of ids that either holds a string tag key or an array of ids.
|
||||
@@ -32,7 +36,7 @@ public interface HolderSet {
|
||||
/**
|
||||
* Creates a new holder set for the given tag.
|
||||
*
|
||||
* @param tagKey the tag key
|
||||
* @param tagKey the tag key, not including '#'
|
||||
* @return a new holder set
|
||||
*/
|
||||
static HolderSet of(final String tagKey) {
|
||||
@@ -49,10 +53,29 @@ public interface HolderSet {
|
||||
return new HolderSetImpl.Ids(ids);
|
||||
}
|
||||
|
||||
static HolderSet fromTag(final Tag tag, final Function<String, Integer> mappingFunction) {
|
||||
if (tag instanceof StringTag stringTag) {
|
||||
if (stringTag.getValue().startsWith("#")) {
|
||||
return HolderSet.of(stringTag.getValue().substring(1));
|
||||
}
|
||||
|
||||
final int id = mappingFunction.apply(stringTag.getValue());
|
||||
return HolderSet.of(new int[]{id});
|
||||
} else if (tag instanceof ListTag<?> listTag) {
|
||||
final int[] ids = new int[listTag.size()];
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
final String value = ((StringTag) listTag.get(i)).getValue();
|
||||
ids[i] = mappingFunction.apply(value);
|
||||
}
|
||||
return HolderSet.of(ids);
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag key.
|
||||
* Gets the tag key, not including '#'.
|
||||
*
|
||||
* @return the tag key
|
||||
* @return the tag key without a '#'
|
||||
* @see #hasTagKey()
|
||||
*/
|
||||
String tagKey();
|
||||
|
||||
@@ -25,6 +25,7 @@ package com.viaversion.viaversion.api.minecraft;
|
||||
import com.google.common.base.Preconditions;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
record IdHolder<T>(int id) implements Holder<T> {
|
||||
|
||||
@@ -48,12 +49,15 @@ record IdHolder<T>(int id) implements Holder<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction, final Supplier<Holder<T>> ifMissing) {
|
||||
final int rewrittenId = rewriteFunction.applyAsInt(id);
|
||||
if (rewrittenId == id) {
|
||||
return this;
|
||||
}
|
||||
if (rewrittenId == -1) {
|
||||
if (ifMissing != null) {
|
||||
return ifMissing.get();
|
||||
}
|
||||
throw new IllegalArgumentException("Received invalid id in updateId");
|
||||
}
|
||||
return Holder.of(rewrittenId);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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 org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Profile that can be either dynamically filled by the client or is already static.
|
||||
* The additional fields are optional overrides.
|
||||
*/
|
||||
public record ResolvableProfile(GameProfile profile, @Nullable String bodyTexture, @Nullable String capeTexture,
|
||||
@Nullable String elytraTexture, @Nullable Integer modelType) {
|
||||
|
||||
public ResolvableProfile(final GameProfile profile) {
|
||||
this(profile, null, null, null, null);
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,21 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record SoundEvent(String identifier, @Nullable Float fixedRange) {
|
||||
|
||||
private static final Holder<SoundEvent> UNKNOWN = Holder.of(new SoundEvent("viaversion:unknown", 0F));
|
||||
|
||||
public SoundEvent withIdentifier(final String identifier) {
|
||||
return new SoundEvent(identifier, this.fixedRange);
|
||||
}
|
||||
|
||||
public static @Nullable Holder<SoundEvent> rewriteHolder(@Nullable final Holder<SoundEvent> holder, final Int2IntFunction soundRewriteFunction) {
|
||||
if (holder == null) {
|
||||
return null;
|
||||
}
|
||||
return holder.updateId(soundRewriteFunction, () -> UNKNOWN);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
record ValueHolder<T>(T value) implements Holder<T> {
|
||||
|
||||
@@ -43,7 +44,7 @@ record ValueHolder<T>(T value) implements Holder<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction, final Supplier<Holder<T>> ifMissing) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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;
|
||||
|
||||
public record Vector3d(double x, double y, double z) {
|
||||
|
||||
public static final Vector3d ZERO = new Vector3d(0, 0, 0);
|
||||
}
|
||||
@@ -45,6 +45,16 @@ public interface CodecContext {
|
||||
|
||||
Key dataComponentType(int id);
|
||||
|
||||
Key entity(int id);
|
||||
|
||||
Key blockEntity(int id);
|
||||
|
||||
Key sound(int id);
|
||||
|
||||
Key key(MappingData.MappingType mappingType, int id);
|
||||
|
||||
int id(MappingData.MappingType mappingType, String identifier);
|
||||
|
||||
static RegistryAccess of(final List<String> enchantments, final MappingData mappingData) {
|
||||
return new RegistryAccessImpl(enchantments, mappingData);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.codec;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DelegatingOps implements Ops {
|
||||
|
||||
private final Ops delegate;
|
||||
|
||||
public DelegatingOps(final Ops delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodecContext context() {
|
||||
return delegate.context();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(final byte b) {
|
||||
delegate.writeByte(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(final byte[] array) {
|
||||
delegate.writeBytes(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(final boolean b) {
|
||||
delegate.writeBoolean(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(final short s) {
|
||||
delegate.writeShort(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(final CharSequence sequence) {
|
||||
delegate.writeString(sequence);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(final int i) {
|
||||
delegate.writeInt(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(final long l) {
|
||||
delegate.writeLong(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(final float f) {
|
||||
delegate.writeFloat(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(final double d) {
|
||||
delegate.writeDouble(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInts(final int[] array) {
|
||||
delegate.writeInts(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLongs(final long[] array) {
|
||||
delegate.writeLongs(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeList(final Consumer<ListSerializer> consumer) {
|
||||
delegate.writeList(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMap(final Consumer<MapSerializer> consumer) {
|
||||
delegate.writeMap(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> void write(final Type<V> type, final V value) {
|
||||
delegate.write(type, value);
|
||||
}
|
||||
}
|
||||
@@ -129,5 +129,7 @@ public interface Ops {
|
||||
MapSerializer writeList(String key, Consumer<ListSerializer> consumer);
|
||||
|
||||
MapSerializer writeMap(String key, Consumer<MapSerializer> consumer);
|
||||
|
||||
<T> MapSerializer writeInlinedMap(Type<T> valueType, T value);
|
||||
}
|
||||
}
|
||||
+26
@@ -66,6 +66,32 @@ final class RegistryAccessImpl implements CodecContext.RegistryAccess {
|
||||
return key(mappingData.getDataComponentSerializerMappings(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key entity(final int id) {
|
||||
return key(mappingData.getEntityMappings(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key blockEntity(final int id) {
|
||||
return key(mappingData.getBlockEntityMappings(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key sound(final int id) {
|
||||
return key(mappingData.getFullSoundMappings(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key key(final MappingData.MappingType mappingType, final int id) {
|
||||
return key(mappingData.getFullMappings(mappingType), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id(final MappingData.MappingType mappingType, final String identifier) {
|
||||
final FullMappings mappings = mappingData.getFullMappings(mappingType);
|
||||
return mapped ? mappings.mappedId(identifier) : mappings.id(identifier);
|
||||
}
|
||||
|
||||
private Key key(final FullMappings mappings, final int id) {
|
||||
final String identifier = mapped ? mappings.mappedIdentifier(id) : mappings.identifier(id);
|
||||
return key(identifier, id);
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.codec;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ThrowingOps implements Ops {
|
||||
|
||||
@Override
|
||||
public CodecContext context() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(final byte b) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(final byte[] array) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(final boolean b) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(final short s) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(final CharSequence sequence) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(final int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(final long l) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(final float f) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(final double d) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInts(final int[] array) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLongs(final long[] array) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeList(final Consumer<ListSerializer> consumer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMap(final Consumer<MapSerializer> consumer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> void write(final Type<V> type, final V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -23,6 +23,7 @@
|
||||
package com.viaversion.viaversion.api.minecraft.data;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.util.ArrayUtil;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.Objects;
|
||||
@@ -102,7 +103,7 @@ final class FilledStructuredData<T> implements StructuredData<T> {
|
||||
public String toString() {
|
||||
return "FilledStructuredData{" +
|
||||
"key=" + key +
|
||||
", value=" + value +
|
||||
", value=" + ArrayUtil.toString(value) +
|
||||
", id=" + id +
|
||||
'}';
|
||||
}
|
||||
|
||||
+1
-1
@@ -241,7 +241,7 @@ public final class StructuredDataContainer implements Copyable {
|
||||
/**
|
||||
* Sets the lookup for serializer ids. Required to call most of the other methods.
|
||||
*
|
||||
* @param protocol protocol to retreive the id of the serializer from
|
||||
* @param protocol protocol to retrieve the id of the serializer from
|
||||
* @param mappedNames if the names are mapped (true if structures from the mapped version are added, false for the unmapped version)
|
||||
*/
|
||||
public void setIdLookup(final Protocol<?, ?, ?, ?> protocol, final boolean mappedNames) {
|
||||
|
||||
+24
-12
@@ -27,8 +27,8 @@ import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.EitherHolder;
|
||||
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
|
||||
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_2;
|
||||
@@ -39,12 +39,14 @@ import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_20_
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Bee;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.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.Consumable1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.CustomModelData1_21_4;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DebugStickState;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Enchantable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
||||
@@ -56,15 +58,19 @@ import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ItemModel;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
|
||||
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.PotDecorations;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
|
||||
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.SuspiciousStewEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.TooltipDisplay;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.TropicalFishPattern;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.EntityData;
|
||||
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.Weapon;
|
||||
@@ -95,10 +101,10 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Integer> DAMAGE = new StructuredDataKey<>("damage", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Unbreakable> UNBREAKABLE1_20_5 = new StructuredDataKey<>("unbreakable", Unbreakable.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.TAG);
|
||||
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
|
||||
public static final StructuredDataKey<Key> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.RESOURCE_LOCATION);
|
||||
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TAG, 256));
|
||||
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TEXT_COMPONENT_TAG);
|
||||
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);
|
||||
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TEXT_COMPONENT_TAG, 256));
|
||||
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", EnumTypes.RARITY);
|
||||
public static final StructuredDataKey<Enchantments> ENCHANTMENTS1_20_5 = new StructuredDataKey<>("enchantments", Enchantments.TYPE1_20_5);
|
||||
public static final StructuredDataKey<Enchantments> ENCHANTMENTS1_21_5 = new StructuredDataKey<>("enchantments", Enchantments.TYPE1_21_5);
|
||||
@@ -132,7 +138,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Equippable> EQUIPPABLE1_21_2 = new StructuredDataKey<>("equippable", Equippable.TYPE1_21_2);
|
||||
public static final StructuredDataKey<Equippable> EQUIPPABLE1_21_5 = new StructuredDataKey<>("equippable", Equippable.TYPE1_21_5);
|
||||
public static final StructuredDataKey<Equippable> EQUIPPABLE1_21_6 = new StructuredDataKey<>("equippable", Equippable.TYPE1_21_6);
|
||||
public static final StructuredDataKey<HolderSet> REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET);
|
||||
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.RESOURCE_LOCATION);
|
||||
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE);
|
||||
@@ -155,10 +161,12 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
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<CompoundTag> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<CompoundTag> ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
|
||||
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);
|
||||
public static final StructuredDataKey<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<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.TYPE);
|
||||
public static final StructuredDataKey<EitherHolder<Instrument1_21_2>> INSTRUMENT1_21_5 = new StructuredDataKey<>("instrument", Instrument1_21_2.EITHER_HOLDER_TYPE);
|
||||
@@ -171,14 +179,17 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<LodestoneTracker> LODESTONE_TRACKER = new StructuredDataKey<>("lodestone_tracker", LodestoneTracker.TYPE);
|
||||
public static final StructuredDataKey<FireworkExplosion> FIREWORK_EXPLOSION = new StructuredDataKey<>("firework_explosion", FireworkExplosion.TYPE);
|
||||
public static final StructuredDataKey<Fireworks> FIREWORKS = new StructuredDataKey<>("fireworks", Fireworks.TYPE);
|
||||
public static final StructuredDataKey<GameProfile> PROFILE = new StructuredDataKey<>("profile", Types.GAME_PROFILE);
|
||||
public static final StructuredDataKey<GameProfile> PROFILE1_20_5 = new StructuredDataKey<>("profile", Types.GAME_PROFILE);
|
||||
public static final StructuredDataKey<ResolvableProfile> PROFILE1_21_9 = new StructuredDataKey<>("profile", Types.RESOLVABLE_PROFILE);
|
||||
public static final StructuredDataKey<Key> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Types.RESOURCE_LOCATION);
|
||||
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<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[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
|
||||
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);
|
||||
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<Holder<SoundEvent>> BREAK_SOUND = new StructuredDataKey<>("break_sound", Types.SOUND_EVENT);
|
||||
|
||||
@@ -214,6 +225,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKeys1_21_2 V1_21_4 = VersionedTypes.V1_21_4.structuredDataKeys();
|
||||
public static final StructuredDataKeys1_21_5 V1_21_5 = VersionedTypes.V1_21_5.structuredDataKeys();
|
||||
public static final StructuredDataKeys1_21_5 V1_21_6 = VersionedTypes.V1_21_6.structuredDataKeys();
|
||||
public static final StructuredDataKeys1_21_5 V1_21_9 = VersionedTypes.V1_21_9.structuredDataKeys();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
+9
-7
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class EntityTypes1_10 {
|
||||
|
||||
@@ -143,7 +143,7 @@ public class EntityTypes1_10 {
|
||||
SPIDER(52, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(59, SPIDER);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<EntityType> TYPES;
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
@@ -184,7 +184,9 @@ public class EntityTypes1_10 {
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
final EntityType[] values = EntityType.values();
|
||||
TYPES = new Int2ObjectOpenHashMap<>(values.length);
|
||||
for (EntityType type : values) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
@@ -230,7 +232,7 @@ public class EntityTypes1_10 {
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final int data;
|
||||
@@ -238,7 +240,7 @@ public class EntityTypes1_10 {
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
|
||||
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +270,7 @@ public class EntityTypes1_10 {
|
||||
}
|
||||
|
||||
public static ObjectType findById(final int id, final int data) {
|
||||
final Map<Integer, ObjectType> types = TYPES.get(id);
|
||||
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
|
||||
if (types == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+9
-7
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class EntityTypes1_11 {
|
||||
|
||||
@@ -168,7 +168,7 @@ public class EntityTypes1_11 {
|
||||
EVOKER(34, ABSTRACT_MONSTER),
|
||||
VINDICATOR(36, ABSTRACT_MONSTER);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<EntityType> TYPES;
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
@@ -209,7 +209,9 @@ public class EntityTypes1_11 {
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
final EntityType[] values = EntityType.values();
|
||||
TYPES = new Int2ObjectOpenHashMap<>(values.length);
|
||||
for (EntityType type : values) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
@@ -257,7 +259,7 @@ public class EntityTypes1_11 {
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final int data;
|
||||
@@ -265,7 +267,7 @@ public class EntityTypes1_11 {
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
|
||||
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +297,7 @@ public class EntityTypes1_11 {
|
||||
}
|
||||
|
||||
public static ObjectType findById(final int id, final int data) {
|
||||
final Map<Integer, ObjectType> types = TYPES.get(id);
|
||||
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
|
||||
if (types == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+9
-7
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class EntityTypes1_12 {
|
||||
|
||||
@@ -174,7 +174,7 @@ public class EntityTypes1_12 {
|
||||
EVOKER(34, SPELLCASTER_ILLAGER),
|
||||
ILLUSIONER(37, SPELLCASTER_ILLAGER);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<EntityType> TYPES;
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
@@ -215,7 +215,9 @@ public class EntityTypes1_12 {
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
final EntityType[] values = EntityType.values();
|
||||
TYPES = new Int2ObjectOpenHashMap<>(values.length);
|
||||
for (EntityType type : values) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
@@ -263,7 +265,7 @@ public class EntityTypes1_12 {
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final int data;
|
||||
@@ -271,7 +273,7 @@ public class EntityTypes1_12 {
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
|
||||
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +303,7 @@ public class EntityTypes1_12 {
|
||||
}
|
||||
|
||||
public static ObjectType findById(final int id, final int data) {
|
||||
final Map<Integer, ObjectType> types = TYPES.get(id);
|
||||
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
|
||||
if (types == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+9
-7
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class EntityTypes1_13 {
|
||||
|
||||
@@ -185,7 +185,7 @@ public class EntityTypes1_13 {
|
||||
EVOKER(21, SPELLCASTER_ILLAGER),
|
||||
ILLUSIONER(31, SPELLCASTER_ILLAGER);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<EntityType> TYPES;
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
@@ -226,7 +226,9 @@ public class EntityTypes1_13 {
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
final EntityType[] values = EntityType.values();
|
||||
TYPES = new Int2ObjectOpenHashMap<>(values.length);
|
||||
for (EntityType type : values) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
@@ -275,7 +277,7 @@ public class EntityTypes1_13 {
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL),
|
||||
TRIDENT(94, EntityType.TRIDENT);
|
||||
|
||||
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final int data;
|
||||
@@ -283,7 +285,7 @@ public class EntityTypes1_13 {
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
|
||||
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +315,7 @@ public class EntityTypes1_13 {
|
||||
}
|
||||
|
||||
public static ObjectType findById(final int id, final int data) {
|
||||
final Map<Integer, ObjectType> types = TYPES.get(id);
|
||||
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
|
||||
if (types == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ public enum EntityTypes1_14 implements EntityType {
|
||||
|
||||
EntityTypes1_14(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_14(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ public enum EntityTypes1_15 implements EntityType {
|
||||
|
||||
EntityTypes1_15(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_15(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -218,7 +218,7 @@ public enum EntityTypes1_16 implements EntityType {
|
||||
|
||||
EntityTypes1_16(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_16(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ public enum EntityTypes1_16_2 implements EntityType {
|
||||
|
||||
EntityTypes1_16_2(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_16_2(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -227,7 +227,7 @@ public enum EntityTypes1_17 implements EntityType {
|
||||
|
||||
EntityTypes1_17(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_17(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ public enum EntityTypes1_19 implements EntityType {
|
||||
|
||||
EntityTypes1_19(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_19(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -233,7 +233,7 @@ public enum EntityTypes1_19_3 implements EntityType {
|
||||
|
||||
EntityTypes1_19_3(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_19_3(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -240,7 +240,7 @@ public enum EntityTypes1_19_4 implements EntityType {
|
||||
|
||||
EntityTypes1_19_4(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_19_4(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -242,7 +242,7 @@ public enum EntityTypes1_20_3 implements EntityType {
|
||||
|
||||
EntityTypes1_20_3(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_20_3(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -248,7 +248,7 @@ public enum EntityTypes1_20_5 implements EntityType {
|
||||
|
||||
EntityTypes1_20_5(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_20_5(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -272,7 +272,7 @@ public enum EntityTypes1_21_2 implements EntityType {
|
||||
|
||||
EntityTypes1_21_2(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_21_2(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+1
-1
@@ -271,7 +271,7 @@ public enum EntityTypes1_21_4 implements EntityType {
|
||||
|
||||
EntityTypes1_21_4(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_21_4(final EntityType parent, @Nullable final String identifier) {
|
||||
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.util.EntityTypeUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public enum EntityTypes1_21_9 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),
|
||||
|
||||
SLIME(MOB),
|
||||
MAGMA_CUBE(SLIME),
|
||||
|
||||
// Ambient mobs
|
||||
AMBIENT_CREATURE(MOB, null),
|
||||
BAT(AMBIENT_CREATURE),
|
||||
|
||||
// Flying mobs
|
||||
FLYING_MOB(MOB, null),
|
||||
GHAST(FLYING_MOB),
|
||||
PHANTOM(FLYING_MOB),
|
||||
|
||||
// Pathfinder mobs and its subclasses
|
||||
PATHFINDER_MOB(MOB, null),
|
||||
ALLAY(PATHFINDER_MOB),
|
||||
|
||||
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
|
||||
SNOW_GOLEM(ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(ABSTRACT_GOLEM),
|
||||
SHULKER(ABSTRACT_GOLEM),
|
||||
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_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),
|
||||
|
||||
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
|
||||
COW(ABSTRACT_COW),
|
||||
MOOSHROOM(ABSTRACT_COW),
|
||||
|
||||
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
|
||||
CAT(TAMABLE_ANIMAL),
|
||||
OCELOT(TAMABLE_ANIMAL),
|
||||
WOLF(TAMABLE_ANIMAL),
|
||||
PARROT(TAMABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
|
||||
HORSE(ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(ABSTRACT_HORSE),
|
||||
CAMEL(ABSTRACT_HORSE),
|
||||
|
||||
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
|
||||
DONKEY(ABSTRACT_CHESTED_HORSE),
|
||||
MULE(ABSTRACT_CHESTED_HORSE),
|
||||
LLAMA(ABSTRACT_CHESTED_HORSE),
|
||||
TRADER_LLAMA(LLAMA),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
|
||||
BLAZE(ABSTRACT_MONSTER),
|
||||
CREEPER(ABSTRACT_MONSTER),
|
||||
ENDERMITE(ABSTRACT_MONSTER),
|
||||
ENDERMAN(ABSTRACT_MONSTER),
|
||||
GIANT(ABSTRACT_MONSTER),
|
||||
SILVERFISH(ABSTRACT_MONSTER),
|
||||
VEX(ABSTRACT_MONSTER),
|
||||
WITHER(ABSTRACT_MONSTER),
|
||||
BREEZE(ABSTRACT_MONSTER),
|
||||
ZOGLIN(ABSTRACT_MONSTER),
|
||||
WARDEN(ABSTRACT_MONSTER),
|
||||
CREAKING(ABSTRACT_MONSTER),
|
||||
|
||||
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
|
||||
SKELETON(ABSTRACT_SKELETON),
|
||||
STRAY(ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(ABSTRACT_SKELETON),
|
||||
BOGGED(ABSTRACT_SKELETON),
|
||||
|
||||
ZOMBIE(ABSTRACT_MONSTER),
|
||||
DROWNED(ZOMBIE),
|
||||
HUSK(ZOMBIE),
|
||||
ZOMBIFIED_PIGLIN(ZOMBIE),
|
||||
ZOMBIE_VILLAGER(ZOMBIE),
|
||||
|
||||
GUARDIAN(ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(GUARDIAN),
|
||||
|
||||
SPIDER(ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(SPIDER),
|
||||
|
||||
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
|
||||
PIGLIN(ABSTRACT_PIGLIN),
|
||||
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
|
||||
|
||||
// Water mobs
|
||||
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
|
||||
DOLPHIN(AGEABLE_WATER_CREATURE),
|
||||
|
||||
SQUID(AGEABLE_WATER_CREATURE),
|
||||
GLOW_SQUID(SQUID),
|
||||
|
||||
WATER_ANIMAL(PATHFINDER_MOB, null),
|
||||
ABSTRACT_FISH(WATER_ANIMAL, null),
|
||||
PUFFERFISH(ABSTRACT_FISH),
|
||||
TADPOLE(ABSTRACT_FISH),
|
||||
|
||||
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
|
||||
COD(ABSTRACT_SCHOOLING_FISH),
|
||||
SALMON(ABSTRACT_SCHOOLING_FISH),
|
||||
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
|
||||
|
||||
// Raiders
|
||||
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
|
||||
WITCH(ABSTRACT_RAIDER),
|
||||
RAVAGER(ABSTRACT_RAIDER),
|
||||
|
||||
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
|
||||
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
|
||||
VINDICATOR(ABSTRACT_ILLAGER),
|
||||
PILLAGER(ABSTRACT_ILLAGER),
|
||||
EVOKER(SPELLCASTER_ILLAGER),
|
||||
ILLUSIONER(SPELLCASTER_ILLAGER);
|
||||
|
||||
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
|
||||
private final EntityType parent;
|
||||
private final String identifier;
|
||||
private int id = -1;
|
||||
|
||||
EntityTypes1_21_9(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_21_9(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);
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class EntityTypes1_8 {
|
||||
|
||||
@@ -135,7 +135,7 @@ public class EntityTypes1_8 {
|
||||
SPIDER(52, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(59, SPIDER);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<EntityType> TYPES;
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
@@ -176,7 +176,9 @@ public class EntityTypes1_8 {
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
final EntityType[] values = EntityType.values();
|
||||
TYPES = new Int2ObjectOpenHashMap<>(values.length);
|
||||
for (EntityType type : values) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
@@ -218,7 +220,7 @@ public class EntityTypes1_8 {
|
||||
ARMOR_STAND(78, EntityType.ARMOR_STAND),
|
||||
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK);
|
||||
|
||||
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final int data;
|
||||
@@ -226,7 +228,7 @@ public class EntityTypes1_8 {
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
|
||||
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +258,7 @@ public class EntityTypes1_8 {
|
||||
}
|
||||
|
||||
public static ObjectType findById(final int id, final int data) {
|
||||
final Map<Integer, ObjectType> types = TYPES.get(id);
|
||||
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
|
||||
if (types == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+9
-7
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class EntityTypes1_9 {
|
||||
|
||||
@@ -142,7 +142,7 @@ public class EntityTypes1_9 {
|
||||
SPIDER(52, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(59, SPIDER);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<EntityType> TYPES;
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
@@ -183,7 +183,9 @@ public class EntityTypes1_9 {
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
final EntityType[] values = EntityType.values();
|
||||
TYPES = new Int2ObjectOpenHashMap<>(values.length);
|
||||
for (EntityType type : values) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
@@ -229,7 +231,7 @@ public class EntityTypes1_9 {
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
|
||||
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final int data;
|
||||
@@ -237,7 +239,7 @@ public class EntityTypes1_9 {
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
|
||||
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +269,7 @@ public class EntityTypes1_9 {
|
||||
}
|
||||
|
||||
public static ObjectType findById(final int id, final int data) {
|
||||
final Map<Integer, ObjectType> types = TYPES.get(id);
|
||||
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
|
||||
if (types == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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 EntityDataTypes1_21_9 extends AbstractEntityDataTypes {
|
||||
|
||||
public final EntityDataType byteType = add(0, Types.BYTE);
|
||||
public final EntityDataType varIntType = add(1, Types.VAR_INT);
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
|
||||
public final EntityDataType optionalBlockPositionType = add(11, Types.OPTIONAL_POSITION_1_14);
|
||||
public final EntityDataType directionType = add(12, Types.VAR_INT);
|
||||
public final EntityDataType optionalUUIDType = add(13, Types.OPTIONAL_UUID);
|
||||
public final EntityDataType blockStateType = add(14, Types.VAR_INT);
|
||||
public final EntityDataType optionalBlockStateType = add(15, Types.VAR_INT);
|
||||
public final EntityDataType particleType;
|
||||
public final EntityDataType particlesType;
|
||||
public final EntityDataType villagerDatatType = 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 cowVariantType = add(22, Types.VAR_INT);
|
||||
public final EntityDataType wolfVariantType = add(23, Types.VAR_INT);
|
||||
public final EntityDataType wolfSoundVariantType = add(24, Types.VAR_INT);
|
||||
public final EntityDataType frogVariantType = add(25, Types.VAR_INT);
|
||||
public final EntityDataType pigVariantType = add(26, Types.VAR_INT);
|
||||
public final EntityDataType chickenVariantType = add(27, Types.VAR_INT);
|
||||
public final EntityDataType optionalGlobalPosition = add(28, Types.OPTIONAL_GLOBAL_POSITION);
|
||||
public final EntityDataType paintingVariantType = add(29, PaintingVariant.TYPE1_21_2);
|
||||
public final EntityDataType snifferState = add(30, Types.VAR_INT);
|
||||
public final EntityDataType armadilloState = add(31, Types.VAR_INT);
|
||||
public final EntityDataType copperGolemState = add(32, Types.VAR_INT);
|
||||
public final EntityDataType weatheringCopperState = add(33, Types.VAR_INT);
|
||||
public final EntityDataType vector3FType = add(34, Types.VECTOR3F);
|
||||
public final EntityDataType quaternionType = add(35, Types.QUATERNION);
|
||||
public final EntityDataType mannequinProfileType = add(36, Types.RESOLVABLE_PROFILE);
|
||||
|
||||
public EntityDataTypes1_21_9(final VersionedTypesHolder types) {
|
||||
super(37);
|
||||
this.itemType = add(7, types.item());
|
||||
this.particleType = add(16, types.particle());
|
||||
this.particlesType = add(17, types.particles());
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ package com.viaversion.viaversion.api.minecraft.item;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public interface Item extends ItemBase {
|
||||
|
||||
+25
-1
@@ -22,14 +22,21 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
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.util.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public record AttributeModifiers1_20_5(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable {
|
||||
public record AttributeModifiers1_20_5(AttributeModifier[] modifiers,
|
||||
boolean showInTooltip) implements Copyable, Rewritable {
|
||||
|
||||
public static final Type<AttributeModifiers1_20_5> TYPE = new Type<>(AttributeModifiers1_20_5.class) {
|
||||
@Override
|
||||
@@ -51,6 +58,23 @@ public record AttributeModifiers1_20_5(AttributeModifier[] modifiers, boolean sh
|
||||
return new AttributeModifiers1_20_5(Copyable.copy(modifiers), showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeModifiers1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
|
||||
if (mappings == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final List<AttributeModifier> modifiers = new ArrayList<>(this.modifiers.length);
|
||||
for (final AttributeModifier modifier : this.modifiers) {
|
||||
final int mappedId = clientbound ? mappings.getNewId(modifier.attribute()) : mappings.inverse().getNewId(modifier.attribute());
|
||||
if (mappedId != -1) {
|
||||
modifiers.add(new AttributeModifier(mappedId, modifier.modifier(), modifier.slotType()));
|
||||
}
|
||||
}
|
||||
return new AttributeModifiers1_20_5(modifiers.toArray(AttributeModifier[]::new), this.showInTooltip);
|
||||
}
|
||||
|
||||
public record AttributeModifier(int attribute, ModifierData modifier, int slotType) {
|
||||
|
||||
public static final Type<AttributeModifier> TYPE = new Type<>(AttributeModifier.class) {
|
||||
|
||||
+25
-2
@@ -23,16 +23,22 @@
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.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.util.Copyable;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable {
|
||||
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable, Rewritable {
|
||||
|
||||
public AttributeModifiers1_21(final AttributeModifier[] modifiers) {
|
||||
this(modifiers, true);
|
||||
@@ -101,6 +107,23 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
|
||||
return new AttributeModifiers1_21(Copyable.copy(modifiers), showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeModifiers1_21 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
|
||||
if (mappings == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final List<AttributeModifier> modifiers = new ArrayList<>(this.modifiers.length);
|
||||
for (final AttributeModifier modifier : this.modifiers) {
|
||||
final int mappedId = clientbound ? mappings.getNewId(modifier.attribute()) : mappings.inverse().getNewId(modifier.attribute());
|
||||
if (mappedId != -1) {
|
||||
modifiers.add(new AttributeModifier(mappedId, modifier.modifier(), modifier.slotType(), modifier.display()));
|
||||
}
|
||||
}
|
||||
return new AttributeModifiers1_21(modifiers.toArray(AttributeModifier[]::new), this.showInTooltip);
|
||||
}
|
||||
|
||||
public record AttributeModifier(int attribute, ModifierData modifier, int slotType, Display display) {
|
||||
private static final String[] EQUIPMENT_SLOT_GROUPS = {"any", "mainhand", "offhand", "hand", "feet", "legs", "chest", "head", "armor", "body", "saddle"};
|
||||
private static final String[] OPERATION = {"add_value", "add_multiplied_base", "add_multiplied_total"};
|
||||
@@ -173,7 +196,7 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
|
||||
map.writeMap("display", display -> {
|
||||
display.write("type", Types.STRING, Display.DISPLAY_TYPES[value.display.id()]);
|
||||
if (value.display instanceof final OverrideText overrideText) {
|
||||
display.write("value", Types.TAG, overrideText.component);
|
||||
display.write("value", Types.TEXT_COMPONENT_TAG, overrideText.component);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,20 +30,24 @@ import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record Bee(CompoundTag entityData, int ticksInHive, int minTicksInHive) implements Copyable {
|
||||
public record Bee(EntityData entityData, int ticksInHive, int minTicksInHive) implements Copyable {
|
||||
|
||||
public static final Type<Bee> TYPE = new Type<>(Bee.class) {
|
||||
public Bee(final CompoundTag entityData, final int ticksInHive, final int minTicksInHive) {
|
||||
this(new EntityData(-1, entityData), ticksInHive, minTicksInHive);
|
||||
}
|
||||
|
||||
public static final Type<Bee> TYPE1_20_5 = new Type<>(Bee.class) {
|
||||
@Override
|
||||
public Bee read(final ByteBuf buffer) {
|
||||
final CompoundTag entityData = Types.COMPOUND_TAG.read(buffer);
|
||||
final int ticksInHive = Types.VAR_INT.readPrimitive(buffer);
|
||||
final int minTicksInHive = Types.VAR_INT.readPrimitive(buffer);
|
||||
return new Bee(entityData, ticksInHive, minTicksInHive);
|
||||
return new Bee(new EntityData(-1, entityData), ticksInHive, minTicksInHive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Bee value) {
|
||||
Types.COMPOUND_TAG.write(buffer, value.entityData);
|
||||
Types.COMPOUND_TAG.write(buffer, value.entityData.tag());
|
||||
Types.VAR_INT.writePrimitive(buffer, value.ticksInHive);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.minTicksInHive);
|
||||
}
|
||||
@@ -51,12 +55,38 @@ public record Bee(CompoundTag entityData, int ticksInHive, int minTicksInHive) i
|
||||
@Override
|
||||
public void write(final Ops ops, final Bee value) {
|
||||
ops.writeMap(map -> map
|
||||
.writeOptional("entity_data", Types.COMPOUND_TAG, value.entityData, new CompoundTag())
|
||||
.writeOptional("entity_data", Types.COMPOUND_TAG, value.entityData.tag(), new CompoundTag())
|
||||
.write("ticks_in_hive", Types.INT, value.ticksInHive)
|
||||
.write("min_ticks_in_hive", Types.INT, value.minTicksInHive));
|
||||
}
|
||||
};
|
||||
public static final Type<Bee[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
public static final Type<Bee[]> ARRAY_TYPE1_20_5 = new ArrayType<>(TYPE1_20_5);
|
||||
|
||||
public static final Type<Bee> TYPE1_21_9 = new Type<>(Bee.class) {
|
||||
@Override
|
||||
public Bee read(final ByteBuf buffer) {
|
||||
final EntityData entityData = EntityData.TYPE.read(buffer);
|
||||
final int ticksInHive = Types.VAR_INT.readPrimitive(buffer);
|
||||
final int minTicksInHive = Types.VAR_INT.readPrimitive(buffer);
|
||||
return new Bee(entityData, ticksInHive, minTicksInHive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Bee value) {
|
||||
EntityData.TYPE.write(buffer, value.entityData);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.ticksInHive);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.minTicksInHive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Bee value) {
|
||||
ops.writeMap(map -> map
|
||||
.write("entity_data", EntityData.TYPE, value.entityData)
|
||||
.write("ticks_in_hive", Types.INT, value.ticksInHive)
|
||||
.write("min_ticks_in_hive", Types.INT, value.minTicksInHive));
|
||||
}
|
||||
};
|
||||
public static final Type<Bee[]> ARRAY_TYPE1_21_9 = new ArrayType<>(TYPE1_21_9);
|
||||
|
||||
@Override
|
||||
public Bee copy() {
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
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;
|
||||
|
||||
public record BlockEntityData(int type, CompoundTag tag) implements Rewritable {
|
||||
|
||||
public static final Type<BlockEntityData> TYPE = new Type<>(BlockEntityData.class) {
|
||||
@Override
|
||||
public BlockEntityData read(final ByteBuf buffer) {
|
||||
final int type = Types.VAR_INT.readPrimitive(buffer);
|
||||
final CompoundTag tag = Types.COMPOUND_TAG.read(buffer);
|
||||
return new BlockEntityData(type, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final BlockEntityData value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.type);
|
||||
Types.COMPOUND_TAG.write(buffer, value.tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final BlockEntityData data) {
|
||||
ops.writeMap(map -> map
|
||||
.write("id", Types.RESOURCE_LOCATION, ops.context().registryAccess().blockEntity(data.type))
|
||||
.writeInlinedMap(Types.COMPOUND_TAG, data.tag)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public BlockEntityData rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final int mappedType = protocol.getMappingData().getBlockEntityMappings().getNewId(type);
|
||||
// Empty mappings might be possible for removed block entities, set a dummy value in that case. Will be handled fine by server and client without losing data
|
||||
return new BlockEntityData(mappedType != -1 ? mappedType : 0, tag);
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -22,12 +22,15 @@
|
||||
*/
|
||||
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.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
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.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@@ -39,7 +42,7 @@ public record BlocksAttacks(
|
||||
@Nullable String bypassedByTag,
|
||||
@Nullable Holder<SoundEvent> blockSound,
|
||||
@Nullable Holder<SoundEvent> disableSound
|
||||
) {
|
||||
) implements Rewritable {
|
||||
|
||||
public static final Type<BlocksAttacks> TYPE = new Type<>(BlocksAttacks.class) {
|
||||
|
||||
@@ -67,6 +70,13 @@ public record BlocksAttacks(
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public BlocksAttacks rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean 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.bypassedByTag, blockSound, disableSound);
|
||||
}
|
||||
|
||||
public record DamageReduction(float horizontalBlockingAngle, @Nullable HolderSet type, float base, float factor) {
|
||||
|
||||
public static final Type<DamageReduction> TYPE = new Type<>(DamageReduction.class) {
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
|
||||
|
||||
@Override
|
||||
public Consumable1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> soundHolder = this.sound.updateId(Rewritable.soundRewriteFunction(protocol, 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);
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -44,6 +44,10 @@ public final class ContainterContents {
|
||||
ops.writeList(list -> {
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
final Item item = value[i];
|
||||
if (item.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int slot = i;
|
||||
list.writeMap(map -> map
|
||||
.write("slot", Types.INT, slot)
|
||||
|
||||
+2
-12
@@ -23,24 +23,14 @@
|
||||
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.util.Key;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record DamageResistant(Key typesTagKey) {
|
||||
|
||||
public static final Type<DamageResistant> TYPE = new Type<>(DamageResistant.class) {
|
||||
@Override
|
||||
public DamageResistant read(final ByteBuf buffer) {
|
||||
final Key typesTagKey = Types.RESOURCE_LOCATION.read(buffer);
|
||||
return new DamageResistant(typesTagKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final DamageResistant value) {
|
||||
Types.RESOURCE_LOCATION.write(buffer, value.typesTagKey());
|
||||
}
|
||||
public static final Type<DamageResistant> TYPE = new TransformingType<>(Types.RESOURCE_LOCATION, DamageResistant.class, DamageResistant::new, DamageResistant::typesTagKey) {
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final DamageResistant value) {
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
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.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
public record DebugStickState(CompoundTag tag) implements Rewritable, Copyable {
|
||||
|
||||
public static final Type<DebugStickState> TYPE = TransformingType.of(Types.COMPOUND_TAG, DebugStickState.class, DebugStickState::new, DebugStickState::tag);
|
||||
|
||||
@Override
|
||||
public DebugStickState rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
CompoundTag updatedTag = tag;
|
||||
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 protocol.getMappingData().changedBlocks().contains(blockId);
|
||||
});
|
||||
}
|
||||
return new DebugStickState(updatedTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebugStickState copy() {
|
||||
return new DebugStickState(tag.copy());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
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.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record EntityData(int type, CompoundTag tag) implements Rewritable, Copyable {
|
||||
|
||||
public static final Type<EntityData> TYPE = new Type<>(EntityData.class) {
|
||||
@Override
|
||||
public EntityData read(final ByteBuf buffer) {
|
||||
final int type = Types.VAR_INT.readPrimitive(buffer);
|
||||
final CompoundTag tag = Types.COMPOUND_TAG.read(buffer);
|
||||
return new EntityData(type, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final EntityData value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.type);
|
||||
Types.COMPOUND_TAG.write(buffer, value.tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final EntityData data) {
|
||||
ops.writeMap(map -> map
|
||||
.write("id", Types.RESOURCE_LOCATION, ops.context().registryAccess().entity(data.type))
|
||||
.writeInlinedMap(Types.COMPOUND_TAG, data.tag)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public EntityData rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final int mappedType = protocol.getMappingData().getEntityMappings().getNewId(type);
|
||||
return new EntityData(mappedType, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityData copy() {
|
||||
return new EntityData(type, tag.copy());
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,11 @@ public final class EnumTypes {
|
||||
public static final EnumType HORSE_VARIANT = new EnumType(Fallback.WRAP, "white", "creamy", "chestnut", "brown", "black", "gray", "dark_brown");
|
||||
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");
|
||||
// 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"));
|
||||
// Pretty much enums, but with a resource location
|
||||
public static final RegistryValueType VILLAGER_TYPE = new RegistryValueType("desert", "jungle", "plains", "savanna", "snow", "swamp", "taiga");
|
||||
public static final RegistryValueType POTION = new RegistryValueType("water", "mundane", "thick", "awkward", "night_vision", "long_night_vision", "invisibility", "long_invisibility", "leaping", "long_leaping", "strong_leaping", "fire_resistance", "long_fire_resistance", "swiftness", "long_swiftness", "strong_swiftness", "slowness", "long_slowness", "strong_slowness", "turtle_master", "long_turtle_master", "strong_turtle_master", "water_breathing", "long_water_breathing", "healing", "strong_healing", "harming", "strong_harming", "poison", "long_poison", "strong_poison", "regeneration", "long_regeneration", "strong_regeneration", "strength", "long_strength", "strong_strength", "weakness", "long_weakness", "luck", "slow_falling", "long_slow_falling", "wind_charged", "weaving", "oozing", "infested");
|
||||
public static final RegistryValueType MOB_EFFECT = new RegistryValueType("speed", "slowness", "haste", "mining_fatigue", "strength", "instant_health", "instant_damage", "jump_boost", "nausea", "regeneration", "resistance", "fire_resistance", "water_breathing", "invisibility", "blindness", "night_vision", "hunger", "weakness", "poison", "wither", "health_boost", "absorption", "saturation", "glowing", "levitation", "luck", "unluck", "slow_falling", "conduit_power", "dolphins_grace", "bad_omen", "hero_of_the_village", "darkness", "trial_omen", "raid_omen", "wind_charged", "weaving", "oozing", "infested");
|
||||
}
|
||||
+42
-3
@@ -23,12 +23,16 @@
|
||||
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.misc.HolderSetType;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@@ -101,6 +105,21 @@ public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Null
|
||||
buffer.writeBoolean(value.damageOnHurt());
|
||||
buffer.writeBoolean(value.equipOnInteract());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Equippable value) {
|
||||
final Holder<SoundEvent> defaultEquipSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "item.armor.equip_generic"));
|
||||
ops.writeMap(map -> map
|
||||
.write("slot", EnumTypes.EQUIPMENT_SLOT, value.equipmentSlot)
|
||||
.writeOptional("equip_sound", Types.SOUND_EVENT, value.soundEvent, defaultEquipSound)
|
||||
.writeOptional("asset_id", Types.RESOURCE_LOCATION, value.model != null ? Key.of(value.model) : null)
|
||||
.writeOptional("camera_overlay", Types.RESOURCE_LOCATION, value.cameraOverlay != null ? Key.of(value.cameraOverlay) : null)
|
||||
.writeOptional("allowed_entities", new HolderSetType(MappingData.MappingType.ENTITY), value.allowedEntities)
|
||||
.writeOptional("dispensable", Types.BOOLEAN, value.dispensable, true)
|
||||
.writeOptional("swappable", Types.BOOLEAN, value.swappable, true)
|
||||
.writeOptional("damage_on_hurt", Types.BOOLEAN, value.damageOnHurt, true)
|
||||
.writeOptional("equip_on_interact", Types.BOOLEAN, value.equipOnInteract, false));
|
||||
}
|
||||
};
|
||||
public static final Type<Equippable> TYPE1_21_6 = new Type<>(Equippable.class) {
|
||||
@Override
|
||||
@@ -133,12 +152,32 @@ public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Null
|
||||
buffer.writeBoolean(value.canBeSheared());
|
||||
Types.SOUND_EVENT.write(buffer, value.shearingSound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Equippable value) {
|
||||
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "item.armor.equip_generic"));
|
||||
final Holder<SoundEvent> defaultShearingSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "item.shears.snip"));
|
||||
ops.writeMap(map -> map
|
||||
.write("slot", EnumTypes.EQUIPMENT_SLOT, value.equipmentSlot)
|
||||
.writeOptional("equip_sound", Types.SOUND_EVENT, value.soundEvent, defaultSound)
|
||||
.writeOptional("asset_id", Types.RESOURCE_LOCATION, value.model != null ? Key.of(value.model) : null)
|
||||
.writeOptional("camera_overlay", Types.RESOURCE_LOCATION, value.cameraOverlay != null ? Key.of(value.cameraOverlay) : null)
|
||||
.writeOptional("allowed_entities", new HolderSetType(MappingData.MappingType.ENTITY), value.allowedEntities)
|
||||
.writeOptional("dispensable", Types.BOOLEAN, value.dispensable, true)
|
||||
.writeOptional("swappable", Types.BOOLEAN, value.swappable, true)
|
||||
.writeOptional("damage_on_hurt", Types.BOOLEAN, value.damageOnHurt, true)
|
||||
.writeOptional("equip_on_interact", Types.BOOLEAN, value.equipOnInteract, false)
|
||||
.writeOptional("can_be_sheared", Types.BOOLEAN, value.canBeSheared, false)
|
||||
.writeOptional("shearing_sound", Types.SOUND_EVENT, value.shearingSound, defaultShearingSound));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Equippable rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> shearingSound = this.shearingSound.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return soundEvent == this.soundEvent && shearingSound == this.shearingSound ? this : new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, canBeSheared, shearingSound);
|
||||
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> shearingSound = SoundEvent.rewriteHolder(this.shearingSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final HolderSet allowedEntities = this.allowedEntities != null ? this.allowedEntities.rewrite(Rewritable.entityRewriteFunction(protocol, clientbound)) : null;
|
||||
return soundEvent == this.soundEvent && shearingSound == this.shearingSound && allowedEntities == this.allowedEntities ? this
|
||||
: new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, canBeSheared, shearingSound);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -52,7 +52,7 @@ public record Instrument1_20_5(Holder<SoundEvent> soundEvent, int useDuration, f
|
||||
|
||||
@Override
|
||||
public Instrument1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return soundEvent == this.soundEvent ? this : new Instrument1_20_5(soundEvent, useDuration, range);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -59,7 +59,7 @@ public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration,
|
||||
|
||||
@Override
|
||||
public Instrument1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, 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, description);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.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.Key;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
public record ItemModel(Key key) implements Rewritable {
|
||||
|
||||
public static final Type<ItemModel> TYPE = TransformingType.of(Types.RESOURCE_LOCATION, ItemModel.class, ItemModel::new, ItemModel::key);
|
||||
|
||||
@Override
|
||||
public ItemModel rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
// This data specifically will often be used with Vanilla items, so the key should be rewritten
|
||||
final String type = key().toString();
|
||||
final String mappedType = Rewritable.rewriteItem(protocol, clientbound, type);
|
||||
return mappedType == null || type.equals(mappedType) ? this : new ItemModel(Key.of(mappedType));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -111,7 +111,7 @@ public record JukeboxPlayable(EitherHolder<JukeboxSong> song, boolean showInTool
|
||||
|
||||
@Override
|
||||
public JukeboxSong rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return soundEvent == this.soundEvent ? this : new JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
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.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
public record LockCode(CompoundTag tag) implements Rewritable, Copyable {
|
||||
|
||||
public static final Type<LockCode> TYPE = TransformingType.of(Types.COMPOUND_TAG, LockCode.class, LockCode::new, LockCode::tag);
|
||||
|
||||
@Override
|
||||
public LockCode rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
CompoundTag updatedTag = tag;
|
||||
if (clientbound && protocol.getComponentRewriter() != null) {
|
||||
// Just abuse the component rewriter and keep this one-way
|
||||
updatedTag = tag.copy();
|
||||
updatedTag.putString("id", "air");
|
||||
protocol.getComponentRewriter().handleShowItem(connection, updatedTag);
|
||||
updatedTag.remove("id");
|
||||
|
||||
final FullMappings mappings = protocol.getMappingData().getFullItemMappings();
|
||||
final Tag itemsTag = updatedTag.get("items");
|
||||
if (itemsTag != null) {
|
||||
final HolderSet items = HolderSet.fromTag(itemsTag, key -> mappings.id(key));
|
||||
items.rewrite(mappings::getNewId);
|
||||
updatedTag.put("items", toTag(items, mappings));
|
||||
}
|
||||
}
|
||||
return new LockCode(updatedTag);
|
||||
}
|
||||
|
||||
private Tag toTag(final HolderSet holderSet, final FullMappings mappings) {
|
||||
if (holderSet.hasTagKey()) {
|
||||
return new StringTag("#" + holderSet.tagKey());
|
||||
}
|
||||
|
||||
final int[] ids = holderSet.ids();
|
||||
if (ids.length == 1) {
|
||||
return new StringTag(mappings.mappedIdentifier(ids[0]));
|
||||
}
|
||||
|
||||
final ListTag<StringTag> listTag = new ListTag<>(StringTag.class);
|
||||
for (final int id : ids) {
|
||||
listTag.add(new StringTag(mappings.mappedIdentifier(id)));
|
||||
}
|
||||
return listTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockCode copy() {
|
||||
return new LockCode(tag.copy());
|
||||
}
|
||||
}
|
||||
+10
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
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.util.Copyable;
|
||||
@@ -85,6 +86,15 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
|
||||
Types.OPTIONAL_STRING.write(buffer, value.customName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final PotionContents value) {
|
||||
ops.writeMap(map -> map
|
||||
.writeOptional("potion", EnumTypes.POTION, value.potion)
|
||||
.writeOptional("custom_color", Types.INT, value.customColor)
|
||||
.writeOptional("custom_effects", PotionEffect.ARRAY_TYPE, value.customEffects, new PotionEffect[0])
|
||||
.writeOptional("custom_name", Types.STRING, value.customName));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
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.ArrayType;
|
||||
@@ -42,6 +43,13 @@ public record PotionEffect(int effect, PotionEffectData effectData) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.effect);
|
||||
PotionEffectData.TYPE.write(buffer, value.effectData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final PotionEffect value) {
|
||||
ops.writeMap(map -> map
|
||||
.write("id", EnumTypes.MOB_EFFECT, value.effect)
|
||||
.writeInlinedMap(PotionEffectData.TYPE, value.effectData));
|
||||
}
|
||||
};
|
||||
public static final Type<PotionEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
|
||||
|
||||
+12
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
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.Types;
|
||||
@@ -52,6 +53,17 @@ public record PotionEffectData(int amplifier, int duration, boolean ambient, boo
|
||||
buffer.writeBoolean(value.showIcon);
|
||||
OPTIONAL_TYPE.write(buffer, value.hiddenEffect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final PotionEffectData value) {
|
||||
ops.writeMap(map -> map
|
||||
.writeOptional("amplifier", Types.UNSIGNED_BYTE, (short) value.amplifier, (short) 0)
|
||||
.writeOptional("duration", Types.INT, value.duration, 0)
|
||||
.writeOptional("ambient", Types.BOOLEAN, value.ambient, false)
|
||||
.writeOptional("show_particles", Types.BOOLEAN, value.showParticles, true)
|
||||
.writeOptional("show_icon", Types.BOOLEAN, value.showIcon)
|
||||
.writeOptional("hidden_effect", TYPE, value.hiddenEffect));
|
||||
}
|
||||
};
|
||||
public static final Type<PotionEffectData> OPTIONAL_TYPE = new OptionalType<>(TYPE) {
|
||||
};
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.MappingType;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
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.api.type.types.misc.HolderSetType;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
public record Repairable(HolderSet items) implements Rewritable {
|
||||
|
||||
public static final Type<Repairable> TYPE = new TransformingType<>(Types.HOLDER_SET, Repairable.class, Repairable::new, Repairable::items) {
|
||||
@Override
|
||||
public void write(final Ops ops, final Repairable value) {
|
||||
ops.writeMap(map -> map.write("items", new HolderSetType(MappingType.ITEM), value.items));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Repairable rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final HolderSet items = this.items.rewrite(Rewritable.itemRewriteFunction(protocol, clientbound));
|
||||
return this.items == items ? this : new Repairable(items);
|
||||
}
|
||||
}
|
||||
@@ -100,9 +100,9 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
Preconditions.checkArgument(!initialized, "Protocol has already been initialized");
|
||||
initialized = true;
|
||||
|
||||
// Create logger if protocol does not have one
|
||||
if (getLogger() == null) {
|
||||
logger = new ProtocolLogger(getClass());
|
||||
// Create logger if the protocol doesn't have one
|
||||
if (logger == null) {
|
||||
logger = createLogger();
|
||||
}
|
||||
registerPackets();
|
||||
registerConfigurationChangeHandlers();
|
||||
@@ -128,6 +128,10 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
}
|
||||
}
|
||||
|
||||
protected ProtocolLogger createLogger() {
|
||||
return new ProtocolLogger(getClass());
|
||||
}
|
||||
|
||||
protected void registerConfigurationChangeHandlers() {
|
||||
// Register handlers for protocol state switching
|
||||
// Assuming ids will change too often, it is cleaner to register them here instead of the base protocols,
|
||||
@@ -139,7 +143,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
|
||||
final CU startConfigurationPacket = startConfigurationPacket();
|
||||
if (startConfigurationPacket != null) {
|
||||
appendClientbound(startConfigurationPacket, setServerStateHandler(State.CONFIGURATION));
|
||||
appendClientbound(startConfigurationPacket, startConfigurationHandler());
|
||||
}
|
||||
|
||||
final SU finishConfigurationPacket = serverboundFinishConfigurationPacket();
|
||||
@@ -476,6 +480,16 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
return wrapper -> wrapper.user().getProtocolInfo().setServerState(state);
|
||||
}
|
||||
|
||||
private PacketHandler startConfigurationHandler() {
|
||||
return setServerStateHandler(State.CONFIGURATION).then(wrapper -> {
|
||||
// Mimic client behaviour
|
||||
final EntityTracker tracker = wrapper.user().getEntityTracker(getClass());
|
||||
if (tracker != null) {
|
||||
tracker.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final PacketTypesProvider<CU, CM, SM, SU> getPacketTypesProvider() {
|
||||
return packetTypesProvider;
|
||||
|
||||
@@ -24,11 +24,15 @@ package com.viaversion.viaversion.api.protocol;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.Direction;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.exception.CancelException;
|
||||
import com.viaversion.viaversion.exception.InformativeException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public interface ProtocolPipeline extends SimpleProtocol {
|
||||
public interface ProtocolPipeline {
|
||||
|
||||
/**
|
||||
* Adds a protocol to the current pipeline.
|
||||
@@ -67,6 +71,15 @@ public interface ProtocolPipeline extends SimpleProtocol {
|
||||
@Deprecated
|
||||
@Nullable <P extends Protocol> P getProtocol(Class<P> pipeClass);
|
||||
|
||||
/**
|
||||
* Transform a packet using the protocols in this pipeline.
|
||||
*
|
||||
* @param direction The direction the packet is going in
|
||||
* @param state The current protocol state
|
||||
* @param packetWrapper The packet wrapper to transform
|
||||
*/
|
||||
void transform(Direction direction, State state, PacketWrapper packetWrapper) throws InformativeException, CancelException;
|
||||
|
||||
List<Protocol> pipes(@Nullable Class<? extends Protocol> protocolClass, boolean skipCurrentPipeline, Direction direction);
|
||||
|
||||
/**
|
||||
|
||||
+163
-96
@@ -23,152 +23,219 @@
|
||||
package com.viaversion.viaversion.api.protocol.packet;
|
||||
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.configuration.RateLimitConfig;
|
||||
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class PacketTracker {
|
||||
private final UserConnection connection;
|
||||
private static final long SECOND_NANOS = 1_000_000_000L;
|
||||
|
||||
private final RateTracker packetTracker = new RateTracker(5);
|
||||
private final RateTracker packetSizeTracker = new RateTracker(3);
|
||||
private long startTime = System.nanoTime();
|
||||
private boolean packetLimiterEnabled = true;
|
||||
private long sentPackets;
|
||||
private long receivedPackets;
|
||||
// Used for tracking pps
|
||||
private long startTime;
|
||||
private long intervalPackets;
|
||||
private long packetsPerSecond = -1L;
|
||||
// Used for handling warnings (over time)
|
||||
private int secondsObserved;
|
||||
private int warnings;
|
||||
private final UserConnection connection;
|
||||
private long sentPacketsTotal;
|
||||
private long receivedPacketsTotal;
|
||||
|
||||
public PacketTracker(UserConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for incrementing the number of packets sent to the client.
|
||||
* Increments the number of packets sent to the client.
|
||||
*/
|
||||
public void incrementSent() {
|
||||
this.sentPackets++;
|
||||
this.sentPacketsTotal++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for incrementing the number of packets received from the client.
|
||||
*
|
||||
* @return true if the interval has reset and can now be checked for the packets sent
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public boolean incrementReceived() {
|
||||
// handle stats
|
||||
long diff = System.currentTimeMillis() - startTime;
|
||||
if (diff >= 1000) {
|
||||
packetsPerSecond = intervalPackets;
|
||||
startTime = System.currentTimeMillis();
|
||||
intervalPackets = 1;
|
||||
return true;
|
||||
} else {
|
||||
intervalPackets++;
|
||||
}
|
||||
// increase total
|
||||
this.receivedPackets++;
|
||||
return false;
|
||||
return incrementReceived(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for packet flood with the packets sent in the last second.
|
||||
* ALWAYS check for {@link #incrementReceived()} before using this method.
|
||||
* Increments the number of packets received from the client.
|
||||
*
|
||||
* @return true if the packet should be cancelled
|
||||
* @see #incrementReceived()
|
||||
* @return true if the interval has reset
|
||||
*/
|
||||
public boolean exceedsMaxPPS() {
|
||||
if (connection.isClientSide()) return false; // Don't apply PPS limiting for client-side
|
||||
ViaVersionConfig conf = Via.getConfig();
|
||||
// Max PPS Checker
|
||||
if (conf.getMaxPPS() > 0 && packetsPerSecond >= conf.getMaxPPS()) {
|
||||
connection.disconnect(conf.getMaxPPSKickMessage().replace("%pps", Long.toString(packetsPerSecond)));
|
||||
return true; // don't send current packet
|
||||
}
|
||||
public boolean incrementReceived(int packetSize) {
|
||||
receivedPacketsTotal++;
|
||||
|
||||
// Tracking PPS Checker
|
||||
if (conf.getMaxWarnings() > 0 && conf.getTrackingPeriod() > 0) {
|
||||
if (secondsObserved > conf.getTrackingPeriod()) {
|
||||
// Reset
|
||||
warnings = 0;
|
||||
secondsObserved = 1;
|
||||
} else {
|
||||
secondsObserved++;
|
||||
if (packetsPerSecond >= conf.getWarningPPS()) {
|
||||
warnings++;
|
||||
}
|
||||
|
||||
if (warnings >= conf.getMaxWarnings()) {
|
||||
connection.disconnect(conf.getMaxWarningsKickMessage().replace("%pps", Long.toString(packetsPerSecond)));
|
||||
return true; // don't send current packet
|
||||
}
|
||||
ViaVersionConfig config = Via.getConfig();
|
||||
long currentTime = System.nanoTime();
|
||||
long elapsed = currentTime - startTime;
|
||||
if (elapsed < SECOND_NANOS) {
|
||||
// Add to current interval
|
||||
if (config.getPacketTrackerConfig().enabled()) {
|
||||
packetTracker.addIntervalValue(1);
|
||||
}
|
||||
if (config.getPacketSizeTrackerConfig().enabled()) {
|
||||
packetSizeTracker.addIntervalValue(packetSize);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
// Reset interval tracking
|
||||
if (config.getPacketTrackerConfig().enabled()) {
|
||||
packetTracker.updateRate(elapsed);
|
||||
packetTracker.addIntervalValue(1);
|
||||
}
|
||||
if (config.getPacketSizeTrackerConfig().enabled()) {
|
||||
packetSizeTracker.updateRate(elapsed);
|
||||
packetSizeTracker.addIntervalValue(packetSize);
|
||||
}
|
||||
startTime = currentTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean exceedsLimits() {
|
||||
if (connection.isClientSide()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ViaVersionConfig config = Via.getConfig();
|
||||
return packetTracker.exceedsLimit(connection, config.getPacketTrackerConfig())
|
||||
|| packetSizeTracker.exceedsLimit(connection, config.getPacketSizeTrackerConfig());
|
||||
}
|
||||
|
||||
public long getSentPackets() {
|
||||
return sentPackets;
|
||||
return sentPacketsTotal;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setSentPackets(long sentPackets) {
|
||||
this.sentPackets = sentPackets;
|
||||
this.sentPacketsTotal = sentPackets;
|
||||
}
|
||||
|
||||
public long getReceivedPackets() {
|
||||
return receivedPackets;
|
||||
return receivedPacketsTotal;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setReceivedPackets(long receivedPackets) {
|
||||
this.receivedPackets = receivedPackets;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
this.receivedPacketsTotal = receivedPackets;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public long getIntervalPackets() {
|
||||
return intervalPackets;
|
||||
return this.packetTracker.intervalValue;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setIntervalPackets(long intervalPackets) {
|
||||
this.intervalPackets = intervalPackets;
|
||||
this.packetTracker.intervalValue = Math.toIntExact(intervalPackets);
|
||||
}
|
||||
|
||||
public long getPacketsPerSecond() {
|
||||
return packetsPerSecond;
|
||||
}
|
||||
|
||||
public void setPacketsPerSecond(long packetsPerSecond) {
|
||||
this.packetsPerSecond = packetsPerSecond;
|
||||
}
|
||||
|
||||
public int getSecondsObserved() {
|
||||
return secondsObserved;
|
||||
}
|
||||
|
||||
public void setSecondsObserved(int secondsObserved) {
|
||||
this.secondsObserved = secondsObserved;
|
||||
}
|
||||
|
||||
public int getWarnings() {
|
||||
return warnings;
|
||||
}
|
||||
|
||||
public void setWarnings(int warnings) {
|
||||
this.warnings = warnings;
|
||||
public int getPacketsPerSecond() {
|
||||
return packetTracker.currentRate;
|
||||
}
|
||||
|
||||
public boolean isPacketLimiterEnabled() {
|
||||
return packetLimiterEnabled;
|
||||
ViaVersionConfig config = Via.getConfig();
|
||||
return packetLimiterEnabled && config.getPacketTrackerConfig().enabled() && config.getPacketSizeTrackerConfig().enabled();
|
||||
}
|
||||
|
||||
public void setPacketLimiterEnabled(boolean packetLimiterEnabled) {
|
||||
this.packetLimiterEnabled = packetLimiterEnabled;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setWarnings(int warnings) {
|
||||
this.packetTracker.warnings = warnings;
|
||||
}
|
||||
|
||||
private static final class RateTracker {
|
||||
private final int[] history;
|
||||
private int historyIndex;
|
||||
private int historyCount;
|
||||
private int currentRate = -1;
|
||||
|
||||
// Interval tracking
|
||||
int intervalValue;
|
||||
|
||||
// Warning system
|
||||
private long warningPeriodStart = System.nanoTime();
|
||||
private int warnings;
|
||||
|
||||
public RateTracker(int windowSize) {
|
||||
this.history = new int[windowSize];
|
||||
}
|
||||
|
||||
public void addIntervalValue(int value) {
|
||||
intervalValue += value;
|
||||
}
|
||||
|
||||
public void updateRate(long elapsedNanos) {
|
||||
// Update sliding window
|
||||
history[historyIndex] = (int) ((intervalValue * SECOND_NANOS) / elapsedNanos);
|
||||
historyIndex = (historyIndex + 1) % history.length;
|
||||
if (historyCount < history.length) {
|
||||
historyCount++;
|
||||
}
|
||||
|
||||
// Calculate smoothed average
|
||||
int sum = 0;
|
||||
for (int i = 0; i < historyCount; i++) {
|
||||
sum += history[i];
|
||||
}
|
||||
|
||||
currentRate = sum / historyCount;
|
||||
intervalValue = 0; // Reset
|
||||
}
|
||||
|
||||
public boolean exceedsLimit(UserConnection connection, RateLimitConfig limitConfig) {
|
||||
if (!limitConfig.enabled() || currentRate < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Immediate limit check
|
||||
if (limitConfig.maxRate() > 0 && currentRate >= limitConfig.maxRate()) {
|
||||
connection.disconnect(limitConfig.maxRateKickMessage().replace(limitConfig.ratePlaceholder(), Integer.toString(currentRate)));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Interval warnings
|
||||
if (limitConfig.maxWarnings() > 0 && limitConfig.trackingPeriodNanos() > 0 && limitConfig.warningRate() > 0) {
|
||||
return checkTrackedInterval(connection, limitConfig);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkTrackedInterval(UserConnection connection, RateLimitConfig config) {
|
||||
long currentTime = System.nanoTime();
|
||||
if (currentTime - warningPeriodStart >= config.trackingPeriodNanos()) {
|
||||
// Reset
|
||||
warnings = 0;
|
||||
warningPeriodStart = currentTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentRate >= config.warningRate() && ++warnings >= config.maxWarnings()) {
|
||||
connection.disconnect(config.warningKickMessage().replace(config.ratePlaceholder(), Integer.toString(currentRate)));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
intervalValue = 0;
|
||||
currentRate = -1;
|
||||
warnings = 0;
|
||||
warningPeriodStart = System.nanoTime();
|
||||
historyIndex = 0;
|
||||
historyCount = 0;
|
||||
Arrays.fill(history, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
sentPacketsTotal = 0;
|
||||
receivedPacketsTotal = 0;
|
||||
startTime = System.nanoTime();
|
||||
packetTracker.reset();
|
||||
packetSizeTracker.reset();
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
public static final ProtocolVersion v1_21_4 = register(769, "1.21.4");
|
||||
public static final ProtocolVersion v1_21_5 = register(770, "1.21.5");
|
||||
public static final ProtocolVersion v1_21_6 = register(771, "1.21.6");
|
||||
public static final ProtocolVersion v1_21_7 = register(772, "1.21.7-1.21.8", new SubVersionRange("1.21", 7, 8));
|
||||
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 unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
|
||||
|
||||
static {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package com.viaversion.viaversion.api.rewriter;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@@ -34,4 +35,6 @@ public interface ComponentRewriter {
|
||||
void processText(UserConnection connection, @Nullable JsonElement element);
|
||||
|
||||
JsonElement processText(UserConnection connection, @Nullable String json);
|
||||
|
||||
void handleShowItem(UserConnection connection, CompoundTag itemTag);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TransformingType<F, T> extends Type<T> {
|
||||
private final Type<F> from;
|
||||
private final Function<F, T> mapFunction;
|
||||
private final Function<T, F> reverseFunction;
|
||||
|
||||
protected TransformingType(
|
||||
final Type<F> from, final Class<T> outputClass,
|
||||
final Function<F, T> mapFunction, final Function<T, F> reverseFunction
|
||||
) {
|
||||
super(from.getTypeName(), outputClass);
|
||||
this.from = from;
|
||||
this.mapFunction = mapFunction;
|
||||
this.reverseFunction = reverseFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type that transforms the input to a separate output type.
|
||||
* Useful if you have wrapper classes of a single object.
|
||||
*
|
||||
* @param from type to map from
|
||||
* @param outputClass output class
|
||||
* @param mapFunction function to map from F to T
|
||||
* @param reverseFunction function to map from T to F
|
||||
* @param <F> from type
|
||||
* @param <T> to type
|
||||
* @return transforming type
|
||||
*/
|
||||
public static <F, T> Type<T> of(
|
||||
final Type<F> from, final Class<T> outputClass,
|
||||
final Function<F, T> mapFunction, final Function<T, F> reverseFunction
|
||||
) {
|
||||
return new TransformingType<>(from, outputClass, mapFunction, reverseFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(final ByteBuf buffer) {
|
||||
return mapFunction.apply(from.read(buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final T value) {
|
||||
from.write(buffer, reverseFunction.apply(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final T value) {
|
||||
from.write(ops, reverseFunction.apply(value));
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,10 @@ 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.ResolvableProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.Vector;
|
||||
import com.viaversion.viaversion.api.minecraft.Vector3d;
|
||||
import com.viaversion.viaversion.api.minecraft.Vector3f;
|
||||
import com.viaversion.viaversion.api.minecraft.VillagerData;
|
||||
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
|
||||
@@ -70,6 +72,7 @@ import com.viaversion.viaversion.api.type.types.ShortType;
|
||||
import com.viaversion.viaversion.api.type.types.StringType;
|
||||
import com.viaversion.viaversion.api.type.types.UUIDType;
|
||||
import com.viaversion.viaversion.api.type.types.UnsignedByteType;
|
||||
import com.viaversion.viaversion.api.type.types.UnsignedIntType;
|
||||
import com.viaversion.viaversion.api.type.types.UnsignedShortType;
|
||||
import com.viaversion.viaversion.api.type.types.VarIntArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.VarIntType;
|
||||
@@ -100,6 +103,7 @@ import com.viaversion.viaversion.api.type.types.math.BlockPositionType1_8;
|
||||
import com.viaversion.viaversion.api.type.types.math.ChunkPositionType;
|
||||
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.MovementVectorType;
|
||||
import com.viaversion.viaversion.api.type.types.math.QuaternionType;
|
||||
import com.viaversion.viaversion.api.type.types.math.Vector3fType;
|
||||
import com.viaversion.viaversion.api.type.types.math.VectorType;
|
||||
@@ -108,13 +112,16 @@ import com.viaversion.viaversion.api.type.types.misc.GameProfileType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.KeyType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.LengthPrefixedTagType;
|
||||
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.SoundEventType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ResolvableProfileType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.TagKeyType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.TagType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.TextComponentTagType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.VillagerDataType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
@@ -142,6 +149,7 @@ public final class Types {
|
||||
|
||||
public static final IntType INT = new IntType();
|
||||
public static final Type<int[]> INT_ARRAY_PRIMITIVE = new IntArrayType();
|
||||
public static final UnsignedIntType UNSIGNED_INT = new UnsignedIntType();
|
||||
|
||||
public static final FloatType FLOAT = new FloatType();
|
||||
public static final FloatType.OptionalFloatType OPTIONAL_FLOAT = new FloatType.OptionalFloatType();
|
||||
@@ -190,6 +198,7 @@ public final class Types {
|
||||
public static final Type<Vector> VECTOR = new VectorType();
|
||||
public static final Type<Vector3f> VECTOR3F = new Vector3fType();
|
||||
public static final Type<Quaternion> QUATERNION = new QuaternionType();
|
||||
public static final Type<Vector3d> MOVEMENT_VECTOR = new MovementVectorType();
|
||||
|
||||
public static final Type<CompoundTag> NAMED_COMPOUND_TAG = new NamedCompoundTagType();
|
||||
public static final Type<CompoundTag> OPTIONAL_NAMED_COMPOUND_TAG = new NamedCompoundTagType.OptionalNamedCompoundTagType();
|
||||
@@ -199,6 +208,8 @@ public final class Types {
|
||||
public static final Type<Tag> TAG = new TagType();
|
||||
public static final Type<Tag[]> TAG_ARRAY = new ArrayType<>(TAG);
|
||||
public static final Type<Tag> OPTIONAL_TAG = new TagType.OptionalTagType();
|
||||
public static final Type<Tag> TEXT_COMPONENT_TAG = new TextComponentTagType(); // only strictly needed for hashing
|
||||
public static final Type<Tag> CUSTOM_CLICK_ACTION_TAG = new LengthPrefixedTagType(65536);
|
||||
|
||||
public static final Type<GlobalBlockPosition> GLOBAL_POSITION = new GlobalBlockPositionType();
|
||||
public static final Type<GlobalBlockPosition> OPTIONAL_GLOBAL_POSITION = new GlobalBlockPositionType.OptionalGlobalPositionType();
|
||||
@@ -220,6 +231,7 @@ public final class Types {
|
||||
public static final Type<VillagerData> VILLAGER_DATA = new VillagerDataType();
|
||||
|
||||
public static final Type<GameProfile> GAME_PROFILE = new GameProfileType();
|
||||
public static final Type<ResolvableProfile> RESOLVABLE_PROFILE = new ResolvableProfileType();
|
||||
public static final Type<GameProfile.Property> PROFILE_PROPERTY = new ProfilePropertyType();
|
||||
public static final Type<GameProfile.Property[]> PROFILE_PROPERTY_ARRAY = new ArrayType<>(PROFILE_PROPERTY);
|
||||
public static final Type<ProfileKey> PROFILE_KEY = new ProfileKeyType();
|
||||
|
||||
@@ -41,4 +41,8 @@ public final class RegistryValueType extends VarIntType {
|
||||
public void write(final Ops ops, final Integer value) {
|
||||
Types.STRING.write(ops, names[value]);
|
||||
}
|
||||
|
||||
public String[] names() {
|
||||
return names;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.Type;
|
||||
import com.viaversion.viaversion.api.type.TypeConverter;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class UnsignedIntType extends Type<Long> implements TypeConverter<Long> {
|
||||
public static final long MAX_UNSIGNED_INT = 0xFFFFFFFFL;
|
||||
|
||||
public UnsignedIntType() {
|
||||
super(Long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long read(ByteBuf buffer) {
|
||||
return buffer.readUnsignedInt();
|
||||
}
|
||||
|
||||
public long readPrimitive(ByteBuf buffer) {
|
||||
return buffer.readUnsignedInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Long l) {
|
||||
buffer.writeInt(l.intValue());
|
||||
}
|
||||
|
||||
public void writePrimitive(ByteBuf buffer, long l) {
|
||||
buffer.writeInt((int) l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long from(Object o) {
|
||||
if (o instanceof Number number) {
|
||||
return number.longValue();
|
||||
} else if (o instanceof Boolean boo) {
|
||||
return boo ? 1L : 0L;
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
-1
@@ -25,7 +25,6 @@ package com.viaversion.viaversion.api.type.types.chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
-1
@@ -24,7 +24,6 @@ package com.viaversion.viaversion.api.type.types.item;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.item.ItemHasher;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.math;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.Vector3d;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.UnsignedIntType;
|
||||
import com.viaversion.viaversion.util.MathUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class MovementVectorType extends Type<Vector3d> {
|
||||
// Using 15 bits, steal short constants for it
|
||||
private static final double MAX_QUANTIZED_VALUE = Short.MAX_VALUE - 1;
|
||||
private static final int SCALE_BITS = 2; // first 2 bits for the scale
|
||||
private static final int SCALE_BITS_MASK = 3;
|
||||
private static final int CONTINUATION_FLAG = 1 << 2; // 3rd bit to indicate more scale data
|
||||
private static final double ABS_MAX_VALUE = (1L << Integer.SIZE + SCALE_BITS) - 1; // Unsigned int + the first two scale bits
|
||||
private static final double ABS_MIN_VALUE = 1 / MAX_QUANTIZED_VALUE;
|
||||
|
||||
public MovementVectorType() {
|
||||
super(Vector3d.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3d read(final ByteBuf buffer) {
|
||||
// Pack values back into a single long
|
||||
final int first = Types.UNSIGNED_BYTE.read(buffer);
|
||||
if (first == 0) {
|
||||
return Vector3d.ZERO;
|
||||
}
|
||||
|
||||
final int second = Types.UNSIGNED_BYTE.read(buffer);
|
||||
final long remaining = Types.UNSIGNED_INT.read(buffer);
|
||||
final long packed = remaining << 16 | second << 8 | first;
|
||||
|
||||
long scale = first & SCALE_BITS_MASK;
|
||||
if ((first & CONTINUATION_FLAG) != 0) {
|
||||
// Read the remaining bits and add them to the first two
|
||||
scale |= (Types.VAR_INT.readPrimitive(buffer) & UnsignedIntType.MAX_UNSIGNED_INT) << SCALE_BITS;
|
||||
}
|
||||
|
||||
// 15 bits for each part after removing the scale bits
|
||||
return new Vector3d(
|
||||
unpack(packed >> (0 + SCALE_BITS_MASK)) * scale,
|
||||
unpack(packed >> (15 + SCALE_BITS_MASK)) * scale,
|
||||
unpack(packed >> (30 + SCALE_BITS_MASK)) * scale
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Vector3d vec) {
|
||||
final double x = sanitize(vec.x());
|
||||
final double y = sanitize(vec.y());
|
||||
final double z = sanitize(vec.z());
|
||||
|
||||
final double maxPart = Math.max(Math.abs(x), Math.max(Math.abs(y), Math.abs(z)));
|
||||
if (maxPart < ABS_MIN_VALUE) {
|
||||
buffer.writeByte(0);
|
||||
return;
|
||||
}
|
||||
|
||||
final long scale = MathUtil.ceilLong(maxPart);
|
||||
final boolean scaleTooLargeForBits = (scale & SCALE_BITS_MASK) != scale;
|
||||
final long scaleBits = scaleTooLargeForBits ? (scale & SCALE_BITS_MASK) | CONTINUATION_FLAG : scale;
|
||||
final long packed = scaleBits
|
||||
| (pack(x / scale) << (0 + SCALE_BITS_MASK))
|
||||
| (pack(y / scale) << (15 + SCALE_BITS_MASK))
|
||||
| (pack(z / scale) << (30 + SCALE_BITS_MASK));
|
||||
|
||||
buffer.writeByte((byte) packed);
|
||||
buffer.writeByte((byte) (packed >> 8));
|
||||
buffer.writeInt((int) (packed >> 16));
|
||||
|
||||
if (scaleTooLargeForBits) {
|
||||
// First two bits have already been written
|
||||
Types.VAR_INT.writePrimitive(buffer, (int) (scale >> SCALE_BITS));
|
||||
}
|
||||
}
|
||||
|
||||
private double sanitize(final double value) {
|
||||
return Double.isNaN(value) ? 0 : MathUtil.clamp(value, -ABS_MAX_VALUE, ABS_MAX_VALUE);
|
||||
}
|
||||
|
||||
private long pack(final double value) {
|
||||
// Shift to [0, 1] and quantize to 15 bits
|
||||
final double shifted = (value * 0.5) + 0.5;
|
||||
return Math.round(shifted * MAX_QUANTIZED_VALUE);
|
||||
}
|
||||
|
||||
private double unpack(final long value) {
|
||||
// Normalize to [-1, 1]
|
||||
final double clamped = Math.min(value & Short.MAX_VALUE, MAX_QUANTIZED_VALUE);
|
||||
return (clamped * 2) / MAX_QUANTIZED_VALUE - 1;
|
||||
}
|
||||
}
|
||||
@@ -22,16 +22,27 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.misc;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.data.MappingDataBase;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
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.Types;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class HolderSetType extends Type<HolderSet> {
|
||||
|
||||
private final MappingDataBase.MappingType mappingType;
|
||||
|
||||
public HolderSetType() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public HolderSetType(final MappingDataBase.MappingType mappingType) {
|
||||
super(HolderSet.class);
|
||||
this.mappingType = mappingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,6 +74,28 @@ public class HolderSetType extends Type<HolderSet> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final HolderSet value) {
|
||||
if (value.hasTagKey()) {
|
||||
ops.write(Types.TAG_KEY, Key.of(value.tagKey()));
|
||||
} else {
|
||||
Preconditions.checkArgument(mappingType != null, "Cannot write HolderSet with direct ids without a mapping type");
|
||||
if (value.ids().length == 1) {
|
||||
// Single entries are inlined
|
||||
final Key key = ops.context().registryAccess().key(mappingType, value.ids()[0]);
|
||||
ops.write(Types.RESOURCE_LOCATION, key);
|
||||
return;
|
||||
}
|
||||
|
||||
ops.writeList(list -> {
|
||||
for (final int id : value.ids()) {
|
||||
final Key key = ops.context().registryAccess().key(mappingType, id);
|
||||
list.write(Types.RESOURCE_LOCATION, key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static final class OptionalHolderSetType extends OptionalType<HolderSet> {
|
||||
|
||||
public OptionalHolderSetType() {
|
||||
|
||||
@@ -22,16 +22,27 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.misc;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
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.util.Key;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public abstract class HolderType<T> extends Type<Holder<T>> {
|
||||
|
||||
private final MappingData.MappingType mappingType;
|
||||
|
||||
protected HolderType() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
protected HolderType(final MappingData.MappingType mappingType) {
|
||||
super(Holder.class);
|
||||
this.mappingType = mappingType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,6 +68,24 @@ public abstract class HolderType<T> extends Type<Holder<T>> {
|
||||
|
||||
public abstract void writeDirect(final ByteBuf buffer, final T object);
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Holder<T> value) {
|
||||
if (value.hasId()) {
|
||||
ops.write(Types.RESOURCE_LOCATION, identifier(ops, value.id()));
|
||||
} else {
|
||||
writeDirect(ops, value.value());
|
||||
}
|
||||
}
|
||||
|
||||
protected Key identifier(final Ops ops, final int id) {
|
||||
Preconditions.checkArgument(mappingType != null, "Mapping type is not defined for this HolderType");
|
||||
return ops.context().registryAccess().key(mappingType, id);
|
||||
}
|
||||
|
||||
public void writeDirect(final Ops ops, final T object) {
|
||||
throw new UnsupportedOperationException("Write operation not supported for type: " + getTypeName());
|
||||
}
|
||||
|
||||
public abstract static class OptionalHolderType<T> extends HolderType<T> {
|
||||
private final HolderType<T> type;
|
||||
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.misc;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public final class LengthPrefixedTagType extends Type<Tag> {
|
||||
|
||||
private final int maxLength;
|
||||
|
||||
public LengthPrefixedTagType(int maxLength) {
|
||||
super(Tag.class);
|
||||
this.maxLength = maxLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag read(final ByteBuf buffer) {
|
||||
final int length = Types.VAR_INT.readPrimitive(buffer);
|
||||
|
||||
Preconditions.checkArgument(length <= maxLength,
|
||||
"Cannot receive tag longer than %s bytes (got %s bytes)", maxLength, length);
|
||||
|
||||
return Types.TAG.read(buffer.readSlice(length));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Tag tag) {
|
||||
final ByteBuf tempBuf = buffer.alloc().buffer();
|
||||
try {
|
||||
Types.TAG.write(tempBuf, tag);
|
||||
|
||||
Preconditions.checkArgument(tempBuf.readableBytes() <= maxLength,
|
||||
"Cannot send tag longer than %s bytes (got %s bytes)", maxLength, tempBuf.readableBytes());
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, tempBuf.readableBytes());
|
||||
buffer.writeBytes(tempBuf);
|
||||
} finally {
|
||||
tempBuf.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,6 +160,13 @@ public class ParticleType extends DynamicType<Particle> {
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // Color
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Duration
|
||||
};
|
||||
public static final DataReader<Particle> POWER = (buf, particle) -> {
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf));
|
||||
};
|
||||
public static final DataReader<Particle> SPELL = (buf, particle) -> {
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // Color
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Power
|
||||
};
|
||||
|
||||
public static DataReader<Particle> item(Type<Item> item) {
|
||||
return (buf, particle) -> particle.add(item, item.read(buf));
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.misc;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
|
||||
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.util.Key;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ResolvableProfileType extends Type<ResolvableProfile> {
|
||||
|
||||
public ResolvableProfileType() {
|
||||
super(ResolvableProfile.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResolvableProfile read(final ByteBuf buffer) {
|
||||
final GameProfile profile;
|
||||
if (buffer.readBoolean()) {
|
||||
final UUID id = Types.UUID.read(buffer);
|
||||
final String name = Types.STRING.read(buffer);
|
||||
final GameProfile.Property[] properties = Types.PROFILE_PROPERTY_ARRAY.read(buffer);
|
||||
profile = new GameProfile(name, id, properties, false);
|
||||
} else {
|
||||
profile = Types.GAME_PROFILE.read(buffer);
|
||||
}
|
||||
|
||||
final String texture = Types.OPTIONAL_STRING.read(buffer);
|
||||
final String capeTexture = Types.OPTIONAL_STRING.read(buffer);
|
||||
final String elytraTexture = Types.OPTIONAL_STRING.read(buffer);
|
||||
final Boolean encodedModelType = Types.OPTIONAL_BOOLEAN.read(buffer); // ...
|
||||
final Integer modelType = encodedModelType != null ? (encodedModelType ? 0 : 1) : null;
|
||||
return new ResolvableProfile(profile, texture, capeTexture, elytraTexture, modelType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ResolvableProfile value) {
|
||||
final GameProfile profile = value.profile();
|
||||
if (!profile.dynamic()) {
|
||||
buffer.writeBoolean(true);
|
||||
Types.UUID.write(buffer, profile.id());
|
||||
Types.STRING.write(buffer, profile.name());
|
||||
Types.PROFILE_PROPERTY_ARRAY.write(buffer, profile.properties());
|
||||
} else {
|
||||
buffer.writeBoolean(false);
|
||||
Types.GAME_PROFILE.write(buffer, profile);
|
||||
}
|
||||
|
||||
Types.OPTIONAL_STRING.write(buffer, value.bodyTexture());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.capeTexture());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.elytraTexture());
|
||||
Types.OPTIONAL_BOOLEAN.write(buffer, value.modelType() != null ? value.modelType() == 0 : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final ResolvableProfile value) {
|
||||
final String modelType = value.modelType() != null ? (value.modelType() == 0 ? "slim" : "wide") : null;
|
||||
ops.writeMap(map -> map
|
||||
.writeInlinedMap(Types.GAME_PROFILE, value.profile())
|
||||
.writeOptional("texture", Types.RESOURCE_LOCATION, value.bodyTexture() != null ? Key.of(value.bodyTexture()) : null)
|
||||
.writeOptional("cape", Types.RESOURCE_LOCATION, value.capeTexture() != null ? Key.of(value.capeTexture()) : null)
|
||||
.writeOptional("elytra", Types.RESOURCE_LOCATION, value.elytraTexture() != null ? Key.of(value.elytraTexture()) : null)
|
||||
.writeOptional("model", Types.OPTIONAL_STRING, modelType)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -22,12 +22,19 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.misc;
|
||||
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public final class SoundEventType extends HolderType<SoundEvent> {
|
||||
|
||||
public SoundEventType() {
|
||||
super(MappingData.MappingType.SOUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent readDirect(final ByteBuf buffer) {
|
||||
final String resourceLocation = Types.STRING.read(buffer);
|
||||
@@ -41,6 +48,13 @@ public final class SoundEventType extends HolderType<SoundEvent> {
|
||||
Types.OPTIONAL_FLOAT.write(buffer, value.fixedRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final Ops ops, final SoundEvent object) {
|
||||
ops.writeMap(map -> map
|
||||
.write("sound_id", Types.RESOURCE_LOCATION, Key.of(object.identifier()))
|
||||
.writeOptional("range", Types.FLOAT, object.fixedRange()));
|
||||
}
|
||||
|
||||
public static final class OptionalSoundEventType extends OptionalHolderType<SoundEvent> {
|
||||
|
||||
public OptionalSoundEventType() {
|
||||
|
||||
@@ -105,13 +105,13 @@ public class TagType extends Type<Tag> {
|
||||
} else if (value instanceof CompoundTag compoundTag) {
|
||||
ops.writeMap(map -> {
|
||||
for (final Map.Entry<String, Tag> entry : compoundTag.entrySet()) {
|
||||
map.write(entry.getKey(), Types.TAG, entry.getValue());
|
||||
map.write(entry.getKey(), this, entry.getValue());
|
||||
}
|
||||
});
|
||||
} else if (value instanceof ListTag<?> listTag) {
|
||||
ops.writeList(list -> {
|
||||
for (final Tag tag : listTag) {
|
||||
list.write(Types.TAG, tag);
|
||||
list.write(this, tag);
|
||||
}
|
||||
});
|
||||
} else if (value instanceof IntArrayTag intArrayTag) {
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2025 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.misc;
|
||||
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Only strictly needed for hashing purposes for now.
|
||||
*/
|
||||
public class TextComponentTagType extends TagType {
|
||||
|
||||
private static final Set<String> BOOLEAN_KEYS = Set.of("bold", "italic", "underlined", "strikethrough", "obfuscated", "interpret");
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Tag value) {
|
||||
if (value instanceof final CompoundTag compoundTag) {
|
||||
ops.writeMap(map -> {
|
||||
for (final Map.Entry<String, Tag> entry : compoundTag.entrySet()) {
|
||||
write(map, entry.getKey(), entry.getValue());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
super.write(ops, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(final Ops.MapSerializer map, final String key, final Tag value) {
|
||||
// Better than fully parsing and re-serializing the component
|
||||
if (value instanceof final ByteTag byteTag && BOOLEAN_KEYS.contains(key)) {
|
||||
map.write(key, Types.BOOLEAN, byteTag.asBoolean());
|
||||
} else {
|
||||
map.write(key, this, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_5;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_9;
|
||||
|
||||
/**
|
||||
* Holds versioned accessors for highly volatile types, specifically around items and data components.
|
||||
@@ -44,4 +45,5 @@ public final class VersionedTypes {
|
||||
public static final Types1_20_5<StructuredDataKeys1_21_2, EntityDataTypes1_21_2> V1_21_4 = new Types1_20_5<>(StructuredDataKeys1_21_2::new, EntityDataTypes1_21_2::new);
|
||||
public static final Types1_20_5<StructuredDataKeys1_21_5, EntityDataTypes1_21_5> V1_21_5 = new Types1_20_5<>(StructuredDataKeys1_21_5::new, EntityDataTypes1_21_5::new);
|
||||
public static final Types1_20_5<StructuredDataKeys1_21_5, EntityDataTypes1_21_5> V1_21_6 = new Types1_20_5<>(StructuredDataKeys1_21_5::new, EntityDataTypes1_21_5::new);
|
||||
public static final Types1_20_5<StructuredDataKeys1_21_5, EntityDataTypes1_21_9> V1_21_9 = new Types1_20_5<>(StructuredDataKeys1_21_5::new, EntityDataTypes1_21_9::new);
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -76,4 +77,21 @@ public final class ArrayUtil {
|
||||
}
|
||||
return boxedArray;
|
||||
}
|
||||
|
||||
public static String toString(final Object o) {
|
||||
if (o == null || !o.getClass().isArray()) {
|
||||
return String.valueOf(o);
|
||||
}
|
||||
|
||||
final int length = Array.getLength(o);
|
||||
final StringBuilder builder = new StringBuilder("[");
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(Array.get(o, i));
|
||||
}
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@ package com.viaversion.viaversion.util;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.utils.JsonUtils;
|
||||
import java.util.Comparator;
|
||||
import net.lenni0451.mcstructs.text.utils.JsonUtils;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class GsonUtil {
|
||||
|
||||
@@ -124,7 +124,7 @@ public final class Key {
|
||||
}
|
||||
|
||||
public static boolean equals(final String firstIdentifier, final String secondIdentifier) {
|
||||
return of(firstIdentifier).equals(of(secondIdentifier));
|
||||
return firstIdentifier != null && secondIdentifier != null && of(firstIdentifier).equals(of(secondIdentifier));
|
||||
}
|
||||
|
||||
public static String namespaced(final String identifier) {
|
||||
|
||||
@@ -24,6 +24,22 @@ package com.viaversion.viaversion.util;
|
||||
|
||||
public final class MathUtil {
|
||||
|
||||
/**
|
||||
* Miniscule value below which positive floats are considered zero
|
||||
*/
|
||||
public static final float EPSILON = 1.0E-5F;
|
||||
|
||||
/**
|
||||
* Returns the ceiled integer value of the given float.
|
||||
*
|
||||
* @param value float value to ceil
|
||||
* @return ceiled integer value
|
||||
*/
|
||||
public static int ceil(final float value) {
|
||||
final int intValue = (int) value;
|
||||
return value > intValue ? intValue + 1 : intValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ceiled log to the base of 2 for the given number.
|
||||
*
|
||||
@@ -34,6 +50,11 @@ public final class MathUtil {
|
||||
return i > 0 ? 32 - Integer.numberOfLeadingZeros(i - 1) : 0;
|
||||
}
|
||||
|
||||
public static long ceilLong(final double d) {
|
||||
final long l = (long) d;
|
||||
return d > l ? l + 1 : l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clamped number within the given range.
|
||||
*
|
||||
@@ -48,4 +69,11 @@ public final class MathUtil {
|
||||
}
|
||||
return i > max ? max : i;
|
||||
}
|
||||
|
||||
public static double clamp(final double d, final double min, final double max) {
|
||||
if (d < min) {
|
||||
return min;
|
||||
}
|
||||
return d > max ? max : d;
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,12 @@ public interface Rewritable {
|
||||
|
||||
static Int2IntFunction soundRewriteFunction(final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
return protocol.getMappingData().getSoundMappings() == null ? Int2IntFunction.identity()
|
||||
: (clientbound ? protocol.getMappingData()::getNewSoundId : protocol.getMappingData()::getOldSoundId);
|
||||
: (clientbound ? protocol.getMappingData().getSoundMappings()::getNewId : protocol.getMappingData()::getOldSoundId);
|
||||
}
|
||||
|
||||
static Int2IntFunction entityRewriteFunction(final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
return protocol.getMappingData().getEntityMappings() == null ? Int2IntFunction.identity()
|
||||
: (clientbound ? protocol.getMappingData().getEntityMappings()::getNewId : protocol.getMappingData().getEntityMappings().inverse()::getNewId);
|
||||
}
|
||||
|
||||
static @Nullable String mappedIdentifier(final FullMappings mappings, final String identifier) {
|
||||
|
||||
Loaded 100 of 296 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user