Compare commits
319
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28bceecb1a | ||
|
|
488a6b6919 | ||
|
|
3cd01978df | ||
|
|
0c4dbbe0bb | ||
|
|
1750131831 | ||
|
|
5ac7aaccb7 | ||
|
|
ae60e2f28d | ||
|
|
17a73dff82 | ||
|
|
5e9d213082 | ||
|
|
210b0a6f0e | ||
|
|
f0f87b26d7 | ||
|
|
45a55a81c7 | ||
|
|
b2ec9eab50 | ||
|
|
2f08f0d58c | ||
|
|
d3f92ce9b8 | ||
|
|
cfa20ba418 | ||
|
|
de6ac47a2f | ||
|
|
b41733bdf6 | ||
|
|
8f8bc55bd0 | ||
|
|
81d92a728d | ||
|
|
68666d2d44 | ||
|
|
e539375143 | ||
|
|
0acec719b1 | ||
|
|
93e92ffc82 | ||
|
|
82c55b1d78 | ||
|
|
dd660a2de0 | ||
|
|
96c12ef483 | ||
|
|
1653de70c8 | ||
|
|
b57265e64f | ||
|
|
9d4af84872 | ||
|
|
40665782e7 | ||
|
|
2d663db53f | ||
|
|
896c6accfb | ||
|
|
1785677901 | ||
|
|
e32205ddaf | ||
|
|
f93c64d6aa | ||
|
|
b5eb568515 | ||
|
|
7897fca5be | ||
|
|
3ba86741f9 | ||
|
|
5515011644 | ||
|
|
f59e2a2de4 | ||
|
|
88c103c0a5 | ||
|
|
5772ee4a93 | ||
|
|
c525575d37 | ||
|
|
b8a170873d | ||
|
|
04e936d487 | ||
|
|
6553fc9ae9 | ||
|
|
ddbe8ef0fb | ||
|
|
8e4da81022 | ||
|
|
1620fc35f5 | ||
|
|
e878d77959 | ||
|
|
deab6a0cac | ||
|
|
77f0826ec8 | ||
|
|
76db43cab3 | ||
|
|
f0eab71644 | ||
|
|
e9985adafc | ||
|
|
157a1fe249 | ||
|
|
d48d0a21db | ||
|
|
908078becb | ||
|
|
d0815baac7 | ||
|
|
bc6ad16d40 | ||
|
|
33aecef7b3 | ||
|
|
b7d37b16ae | ||
|
|
2b840abfef | ||
|
|
bc4ad7faa3 | ||
|
|
f08a412db5 | ||
|
|
dcf050a604 | ||
|
|
1f8d1339f5 | ||
|
|
5278f8ba65 | ||
|
|
8fdae33333 | ||
|
|
4054e83ffe | ||
|
|
10f2cad8fd | ||
|
|
74b9eb9f45 | ||
|
|
dde599c128 | ||
|
|
af8cbaf439 | ||
|
|
ad83d01fad | ||
|
|
7eb3632144 | ||
|
|
1ac668d9f2 | ||
|
|
f5033342c9 | ||
|
|
a0c0b7eff2 | ||
|
|
7985b39ed5 | ||
|
|
f26e370a49 | ||
|
|
cb0c301baf | ||
|
|
3858a83972 | ||
|
|
82ff0bae49 | ||
|
|
ee16d7af28 | ||
|
|
f914d57678 | ||
|
|
c13b40a373 | ||
|
|
d60a37f7e6 | ||
|
|
3caaed00dc | ||
|
|
f56bfbebb5 | ||
|
|
3eec520ebd | ||
|
|
df69f1f344 | ||
|
|
009b6c810c | ||
|
|
65b76d53ef | ||
|
|
7be7139241 | ||
|
|
9bc943ea67 | ||
|
|
f880adced2 | ||
|
|
fc07601f24 | ||
|
|
ecb241c187 | ||
|
|
46040b1f5d | ||
|
|
54daa11ce4 | ||
|
|
c556420870 | ||
|
|
84d928ebe7 | ||
|
|
fa6eab5cc3 | ||
|
|
94b26a903c | ||
|
|
c242456c30 | ||
|
|
8391e9d924 | ||
|
|
f5aac9b1ab | ||
|
|
a6850392e1 | ||
|
|
2b37178482 | ||
|
|
82199d9f39 | ||
|
|
c2d2c6d067 | ||
|
|
4066a7b5b6 | ||
|
|
4a7624fef4 | ||
|
|
e38b3f3824 | ||
|
|
4573035aab | ||
|
|
393a5ee973 | ||
|
|
080dc18165 | ||
|
|
6fd421d36e | ||
|
|
84bd1d0782 | ||
|
|
cff2303c62 | ||
|
|
f5733c2cb8 | ||
|
|
21fec0e263 | ||
|
|
093acc519e | ||
|
|
886be3161e | ||
|
|
dc7b708556 | ||
|
|
e82f28c1ac | ||
|
|
7c7239a70d | ||
|
|
3e3dad9e33 | ||
|
|
4871977681 | ||
|
|
0a56e57aec | ||
|
|
a6ff477b8a | ||
|
|
ddad0384f3 | ||
|
|
aabe47f8bc | ||
|
|
354a5f1b75 | ||
|
|
f58afd434d | ||
|
|
57d5652cd5 | ||
|
|
25b521dfcf | ||
|
|
ce655d0679 | ||
|
|
e4e8297a82 | ||
|
|
8357fd01aa | ||
|
|
12b420d3e7 | ||
|
|
db20bc0ae4 | ||
|
|
2a2afa3821 | ||
|
|
f0b2d9aafe | ||
|
|
cd427a2a39 | ||
|
|
75537d3f85 | ||
|
|
a88e2f3fb5 | ||
|
|
8a41e7add6 | ||
|
|
9c35228287 | ||
|
|
f9ec6b9d03 | ||
|
|
22d396d909 | ||
|
|
39b28e21ca | ||
|
|
0488cb7fbe | ||
|
|
ec4aa0637e | ||
|
|
ffc5584b1c | ||
|
|
45c6cfedb0 | ||
|
|
c150e50636 | ||
|
|
16e32a62e5 | ||
|
|
1d18f2e45e | ||
|
|
e46b38e58a | ||
|
|
033741d292 | ||
|
|
7a3ef1e0b7 | ||
|
|
5be41ed3e9 | ||
|
|
83e44641d0 | ||
|
|
50084c112d | ||
|
|
81682f4921 | ||
|
|
1c339e8b54 | ||
|
|
1a9cda0579 | ||
|
|
6ad9a71907 | ||
|
|
9f24576ba7 | ||
|
|
8661bbc1fc | ||
|
|
0b5fa37f96 | ||
|
|
dab32bafa1 | ||
|
|
9e5c541f79 | ||
|
|
9674c617ca | ||
|
|
9df1704357 | ||
|
|
c0821de2e2 | ||
|
|
c358c39027 | ||
|
|
451b3a2637 | ||
|
|
619eecacf8 | ||
|
|
6bae039d52 | ||
|
|
b321029886 | ||
|
|
5287d4fb4f | ||
|
|
a0a2794291 | ||
|
|
9e354e956e | ||
|
|
27033e9096 | ||
|
|
e436bbe375 | ||
|
|
050a1dbacb | ||
|
|
ae1838d78a | ||
|
|
7235485802 | ||
|
|
fcb472347e | ||
|
|
e0ce8cc715 | ||
|
|
ebc0e61be8 | ||
|
|
95581a6fa5 | ||
|
|
d0b49009e5 | ||
|
|
369b076cad | ||
|
|
6555bcda74 | ||
|
|
e537dbb024 | ||
|
|
f92dbb655d | ||
|
|
0b2dac9056 | ||
|
|
7cd5514b90 | ||
|
|
5017d4bbb3 | ||
|
|
32e51b52aa | ||
|
|
4f66fd793b | ||
|
|
2a71612aea | ||
|
|
a993a08b8d | ||
|
|
a9c947517c | ||
|
|
2841bf3040 | ||
|
|
7edddda36e | ||
|
|
33de12ceb1 | ||
|
|
f8eb57cdbb | ||
|
|
b2d523f5c0 | ||
|
|
b586b0d361 | ||
|
|
c6381e7f4d | ||
|
|
10ee7e1930 | ||
|
|
78abf8be00 | ||
|
|
1dde24bb68 | ||
|
|
bc57512ca2 | ||
|
|
6ad3beca76 | ||
|
|
9d75125e41 | ||
|
|
8ce4112e86 | ||
|
|
7d542d5667 | ||
|
|
7d6599b90e | ||
|
|
1b03e24160 | ||
|
|
fcd91bb855 | ||
|
|
bda4ea9fd0 | ||
|
|
cbd26ce9d9 | ||
|
|
8d53f4aa5a | ||
|
|
1438f1f68d | ||
|
|
61fcf6f895 | ||
|
|
736834441d | ||
|
|
3f5417be97 | ||
|
|
cc1c88001f | ||
|
|
274f98c24e | ||
|
|
f39b466ac0 | ||
|
|
aa22ca1d56 | ||
|
|
802e868b2e | ||
|
|
02442a9775 | ||
|
|
5349de91c5 | ||
|
|
a8ef3c890a | ||
|
|
b556e6528a | ||
|
|
434b32cad8 | ||
|
|
60b3ba6bb7 | ||
|
|
864beef341 | ||
|
|
7b21df2c12 | ||
|
|
462a10363c | ||
|
|
040f85659d | ||
|
|
48d5aaf8fa | ||
|
|
41b0d95d70 | ||
|
|
b599399c48 | ||
|
|
721e27eb39 | ||
|
|
c9d6fbfcd0 | ||
|
|
b1f64fd081 | ||
|
|
2b508567db | ||
|
|
24d0ae7607 | ||
|
|
40a44d5dc5 | ||
|
|
b5a06181d4 | ||
|
|
35fa7e78a0 | ||
|
|
7f4faab4ab | ||
|
|
3906b47654 | ||
|
|
1476adb281 | ||
|
|
6fb072120b | ||
|
|
f2f0be0581 | ||
|
|
5ec30ef18a | ||
|
|
0915afe43b | ||
|
|
87b041bf3a | ||
|
|
275b09bdbb | ||
|
|
cc87c02020 | ||
|
|
a45985ed58 | ||
|
|
92dedfb950 | ||
|
|
6bbcf7d784 | ||
|
|
465a2354c0 | ||
|
|
c59c15d6f3 | ||
|
|
20f7738f08 | ||
|
|
323f0fa087 | ||
|
|
3138d667a6 | ||
|
|
365040f59d | ||
|
|
303d9ecf51 | ||
|
|
463381b84e | ||
|
|
7fef96d77e | ||
|
|
17358120cd | ||
|
|
e6da77cf47 | ||
|
|
dc503cd613 | ||
|
|
8aa2f4be46 | ||
|
|
c5dc5b2bf8 | ||
|
|
f4d6659760 | ||
|
|
bfbb80f708 | ||
|
|
248da118a9 | ||
|
|
a987882132 | ||
|
|
bca25d4744 | ||
|
|
2417ffe483 | ||
|
|
8606e5d663 | ||
|
|
5a0ca55b97 | ||
|
|
ceb1cffb00 | ||
|
|
1ff3035bc0 | ||
|
|
1f221ea828 | ||
|
|
dd1fad2dd7 | ||
|
|
245f7e24e4 | ||
|
|
9d3db4cf97 | ||
|
|
b67ebecce8 | ||
|
|
d03207289e | ||
|
|
64497b305a | ||
|
|
f5b3799db9 | ||
|
|
00fedc7656 | ||
|
|
05aa05c5b4 | ||
|
|
5243c1800e | ||
|
|
77d702bc9b | ||
|
|
c098e24c4f | ||
|
|
3d083cf463 | ||
|
|
2ab62a8f4f | ||
|
|
296f42086f | ||
|
|
e9f547f7ba | ||
|
|
b7f388b9ee | ||
|
|
824ff375d4 | ||
|
|
8bec05ed38 | ||
|
|
b367caa4b2 | ||
|
|
1c281abf65 |
No files matched your search
+2
-2
@@ -2,7 +2,7 @@
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
insert_final_newline = true
|
||||
tab_width = 4
|
||||
|
||||
[*.java]
|
||||
@@ -13,4 +13,4 @@ ij_java_generate_final_locals = true
|
||||
ij_java_generate_final_parameters = true
|
||||
|
||||
[{*.json,*.yml}]
|
||||
indent_size = 2
|
||||
indent_size = 2
|
||||
@@ -1,2 +1,3 @@
|
||||
github: kennytv
|
||||
patreon: kennytv
|
||||
custom: ['https://florianmichael.de/donate']
|
||||
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -7,13 +7,13 @@ jobs:
|
||||
# Only run on PRs if the source branch is on a different repo. We do not need to run everything twice.
|
||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
@@ -8,12 +8,12 @@ on:
|
||||
jobs:
|
||||
publish:
|
||||
if: github.repository_owner == 'ViaVersion'
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
name: Update Gradle Wrapper
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * 0"
|
||||
|
||||
jobs:
|
||||
update-gradle-wrapper:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Update Gradle Wrapper
|
||||
uses: gradle-update/update-gradle-wrapper-action@v2
|
||||
+4
-1
@@ -109,4 +109,7 @@ nb-configuration.xml
|
||||
.nb-gradle/
|
||||
|
||||
### MacOS ###
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
|
||||
### Run Folder (ViaProxy) ###
|
||||
common/run/
|
||||
@@ -1,7 +1,7 @@
|
||||
# ViaVersion
|
||||
|
||||
[](https://viaversion.com)
|
||||
[](https://github.com/ViaVersion/ViaVersion/actions)
|
||||
[](https://github.com/ViaVersion/ViaVersion/actions)
|
||||
[](https://viaversion.com/discord)
|
||||
|
||||
**Allows the connection of higher client versions to lower server versions -
|
||||
@@ -9,14 +9,24 @@ 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
|
||||
any server version from the past decade. **See [HERE](https://github.com/ViaVersion) for an overview of the different Via\* projects.**
|
||||
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
|
||||
direct access to client/server state and more extensive API.
|
||||
|
||||
Supported Versions:
|
||||
|
||||

|
||||

|
||||
|
||||
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/
|
||||
|
||||
Snapshot support
|
||||
--------
|
||||
**ViaVersion will only be released a few days *after* a Minecraft update** unless the protocol changes of the update were trivial. If you want early-access, usually days or even weeks before the final release, you can subscribe to either:
|
||||
- [GitHub Sponsors](https://github.com/sponsors/kennytv/sponsorships?sponsor=kennytv&tier_id=385613&preview=false) (preferred option. Use the `/verify` command on this Discord after), or alternatively
|
||||
- [Patreon](https://www.patreon.com/kennytv/membership) (see the highest tier and make sure to link Patreon to your Discord account under Settings->Connections)
|
||||
This also includes access to a private repository with the code, which will be pushed to the public repository after the given delay on a Minecraft update.
|
||||
|
||||
Releases/Dev Builds
|
||||
--------
|
||||
You can find official releases in the following places:
|
||||
@@ -67,6 +77,8 @@ dependencies {
|
||||
If you need access to the existing protocol or platform implementations, use the parent artifact `viaversion`.
|
||||
Please note the [differences in licensing](#license).
|
||||
|
||||
Note: If you want to make your own platform implementation of ViaVersion (and additional addons),
|
||||
you can use the [ViaLoader](https://github.com/ViaVersion/ViaLoader) project.
|
||||
|
||||
Building
|
||||
--------
|
||||
@@ -78,7 +90,7 @@ 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).
|
||||
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
|
||||
@@ -91,7 +103,7 @@ Resources
|
||||
|
||||
License
|
||||
--------
|
||||
The entirety of the [API directory](api) (including the legacy API directory) is licensed under the MIT License;
|
||||
The entirety of the [API directory](api) is licensed under the MIT License;
|
||||
see [licenses/MIT.md](licenses/MIT.md) for
|
||||
details.
|
||||
|
||||
|
||||
@@ -19,13 +19,15 @@ dependencies {
|
||||
api(libs.vianbt) {
|
||||
exclude("it.unimi.dsi", "fastutil")
|
||||
}
|
||||
api(libs.gson)
|
||||
api(libs.gson) {
|
||||
exclude("com.google.errorprone", "error_prone_annotations")
|
||||
}
|
||||
implementation(rootProject.libs.text) {
|
||||
exclude("com.google.code.gson", "gson")
|
||||
exclude("com.viaversion", "nbt")
|
||||
}
|
||||
api(libs.snakeYaml)
|
||||
|
||||
compileOnlyApi(libs.snakeYaml)
|
||||
compileOnlyApi(libs.netty)
|
||||
compileOnlyApi(libs.guava)
|
||||
compileOnlyApi(libs.checkerQual)
|
||||
|
||||
@@ -140,6 +140,13 @@ public interface ViaManager {
|
||||
*/
|
||||
void addEnableListener(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Adds a runnable to be executed when ViaVersion has finished its init after the full server load.
|
||||
*
|
||||
* @param runnable runnable to be executed
|
||||
*/
|
||||
void addPostEnableListener(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Returns whether the manager has been initialized (and protocols have been loaded).
|
||||
*
|
||||
|
||||
+31
-9
@@ -67,9 +67,9 @@ public interface ViaVersionConfig extends Config {
|
||||
boolean isShowNewDeathMessages();
|
||||
|
||||
/**
|
||||
* Get if metadata errors will be suppressed
|
||||
* Get if entity data errors will be suppressed
|
||||
*
|
||||
* @return true if metadata errors suppression is enabled
|
||||
* @return true if entity data errors suppression is enabled
|
||||
*/
|
||||
boolean isSuppressMetadataErrors();
|
||||
|
||||
@@ -292,13 +292,6 @@ public interface ViaVersionConfig extends Config {
|
||||
*/
|
||||
boolean isDisable1_13AutoComplete();
|
||||
|
||||
/**
|
||||
* Tries to minimize cooldown animation.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isMinimizeCooldown();
|
||||
|
||||
/**
|
||||
* Enable the serverside blockconnections for 1.13+ clients
|
||||
*
|
||||
@@ -464,4 +457,33 @@ public interface ViaVersionConfig extends Config {
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean handleInvalidItemCount();
|
||||
|
||||
/**
|
||||
* Tries to cancel block break/place sounds sent by 1.8 servers to 1.9+ clients to prevent them from playing twice
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean cancelBlockSounds();
|
||||
|
||||
/**
|
||||
* Hides scoreboard numbers for 1.20.3+ clients on older server versions.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean hideScoreboardNumbers();
|
||||
|
||||
/**
|
||||
* Fixes 1.21+ clients on 1.20.5 servers placing water/lava buckets at the wrong location when moving fast.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean fix1_21PlacementRotation();
|
||||
|
||||
/**
|
||||
* If enabled, 1.20.5+ clients will have sword blocking mechanics on 1.8 servers using the consumable item component.
|
||||
* Note that you won't be able to see the blocking in first person if the client is older than 1.21.4.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean swordBlockingViaConsumable();
|
||||
}
|
||||
@@ -29,6 +29,11 @@ public abstract class StoredObject implements StorableObject {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public UserConnection user() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public UserConnection getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.connection;
|
||||
|
||||
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
|
||||
import com.viaversion.viaversion.api.data.entity.EntityTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketTracker;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
@@ -99,14 +100,33 @@ public interface UserConnection {
|
||||
void addEntityTracker(Class<? extends Protocol> protocolClass, EntityTracker tracker);
|
||||
|
||||
/**
|
||||
* Clear stored objects and entity trackers.
|
||||
* Returns the client world by the given protocol class if present.
|
||||
*
|
||||
* @param protocolClass protocol class
|
||||
* @param <T> client world type
|
||||
* @return client world if present
|
||||
*/
|
||||
@Nullable
|
||||
<T extends ClientWorld> T getClientWorld(Class<? extends Protocol> protocolClass);
|
||||
|
||||
/**
|
||||
* Adds a client world to the user connection.
|
||||
* Does not override existing client worlds.
|
||||
*
|
||||
* @param protocolClass protocol class
|
||||
* @param clientWorld client world
|
||||
*/
|
||||
void addClientWorld(Class<? extends Protocol> protocolClass, ClientWorld clientWorld);
|
||||
|
||||
/**
|
||||
* Clear stored objects, entity trackers and client worlds.
|
||||
*/
|
||||
default void clearStoredObjects() {
|
||||
clearStoredObjects(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear stored objects and entity trackers.
|
||||
* 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
|
||||
|
||||
@@ -53,6 +53,14 @@ public interface FullMappings extends BiMappings {
|
||||
*/
|
||||
@Nullable String identifier(int id);
|
||||
|
||||
/**
|
||||
* Returns the unmapped string identifier for the given mapped identifier.
|
||||
*
|
||||
* @param mappedIdentifier mapped identifier
|
||||
* @return unmapped string identifier, or null if not found
|
||||
*/
|
||||
@Nullable String identifier(String mappedIdentifier);
|
||||
|
||||
/**
|
||||
* Returns the mapped string identifier for the given mapped id.
|
||||
*
|
||||
|
||||
@@ -84,7 +84,18 @@ public class FullMappingsBase implements FullMappings {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mappedIdentifier(final int mappedId) {
|
||||
public @Nullable String identifier(final String mappedIdentifier) {
|
||||
final int mappedId = mappedId(mappedIdentifier);
|
||||
if (mappedId == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int id = mappings.inverse().getNewId(mappedId);
|
||||
return id != -1 ? identifier(id) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String mappedIdentifier(final int mappedId) {
|
||||
if (mappedId < 0 || mappedId >= mappedIdToString.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -35,54 +35,84 @@ public interface MappingData {
|
||||
void load();
|
||||
|
||||
/**
|
||||
* Returns the mapped block state id, or -1 if unmapped.
|
||||
* Returns the mapped block state id, or 0 if unmapped.
|
||||
*
|
||||
* @param id unmapped block state id
|
||||
* @return mapped block state id, or -1 if unmapped
|
||||
* @return mapped block state id, or 0 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold block state mappings
|
||||
*/
|
||||
int getNewBlockStateId(int id);
|
||||
|
||||
/**
|
||||
* Returns the mapped block id, or -1 if unmapped.
|
||||
* Returns the mapped block id, or 0 if unmapped.
|
||||
*
|
||||
* @param id unmapped block id
|
||||
* @return mapped block id, or -1 if unmapped
|
||||
* @return mapped block id, or 0 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold block mappings
|
||||
*/
|
||||
int getNewBlockId(int id);
|
||||
|
||||
/**
|
||||
* Returns the backwards mapped block id, or 1 if unmapped.
|
||||
*
|
||||
* @param id mapped block id
|
||||
* @return backwards mapped block id, or 1 if unmapped
|
||||
*/
|
||||
int getOldBlockId(int id);
|
||||
|
||||
/**
|
||||
* Returns the mapped item id, or -1 if unmapped.
|
||||
* Returns the mapped item id, or 0 if unmapped.
|
||||
*
|
||||
* @param id unmapped item id
|
||||
* @return mapped item id, or -1 if unmapped
|
||||
* @return mapped item id, or 0 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold item mappings
|
||||
*/
|
||||
int getNewItemId(int id);
|
||||
|
||||
/**
|
||||
* Returns the backwards mapped item id, or -1 if unmapped.
|
||||
* Returns the backwards mapped item id, or 1 if unmapped.
|
||||
*
|
||||
* @param id mapped item id
|
||||
* @return backwards mapped item id, or -1 if unmapped
|
||||
* @return backwards mapped item id, or 1 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold item mappings
|
||||
*/
|
||||
int getOldItemId(int id);
|
||||
|
||||
/**
|
||||
* Returns the mapped particle id, or -1 if unmapped.
|
||||
* Returns the mapped particle id, or 0 if unmapped.
|
||||
*
|
||||
* @param id unmapped particle id
|
||||
* @return mapped particle id, or -1 if unmapped
|
||||
* @return mapped particle id, or 0 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold particle mappings
|
||||
*/
|
||||
int getNewParticleId(int id);
|
||||
|
||||
/**
|
||||
* Returns the mapped attribute id, or 0 if unmapped.
|
||||
*
|
||||
* @param id unmapped attribute id
|
||||
* @return mapped attribute id, or 0 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold attribute mappings
|
||||
*/
|
||||
int getNewAttributeId(int id);
|
||||
|
||||
/**
|
||||
* Returns the mapped sound id, or 0 if unmapped.
|
||||
*
|
||||
* @param id unmapped sound id
|
||||
* @return mapped sound id, or 0 if unmapped
|
||||
* @throws NullPointerException if this mappingdata does not hold sound mappings
|
||||
*/
|
||||
int getNewSoundId(int id);
|
||||
|
||||
/**
|
||||
* Returns the backwards mapped sound id, or 1 if unmapped.
|
||||
*
|
||||
* @param i mapped sound id
|
||||
* @return backwards mapped sound id, or 1 if unmapped
|
||||
*/
|
||||
int getOldSoundId(int i);
|
||||
|
||||
/**
|
||||
* Returns a list of tags to send if present.
|
||||
*
|
||||
@@ -122,10 +152,10 @@ public interface MappingData {
|
||||
|
||||
@Nullable Mappings getEnchantmentMappings();
|
||||
|
||||
@Nullable Mappings getAttributeMappings();
|
||||
|
||||
@Nullable Mappings getPaintingMappings();
|
||||
|
||||
@Nullable FullMappings getAttributeMappings();
|
||||
|
||||
@Nullable FullMappings getEntityMappings();
|
||||
|
||||
@Nullable FullMappings getArgumentTypeMappings();
|
||||
|
||||
@@ -43,6 +43,7 @@ public class MappingDataBase implements MappingData {
|
||||
protected FullMappings entityMappings;
|
||||
protected FullMappings recipeSerializerMappings;
|
||||
protected FullMappings itemDataSerializerMappings;
|
||||
protected FullMappings attributeMappings;
|
||||
protected ParticleMappings particleMappings;
|
||||
protected BiMappings itemMappings;
|
||||
protected BiMappings blockMappings;
|
||||
@@ -53,7 +54,6 @@ public class MappingDataBase implements MappingData {
|
||||
protected Mappings enchantmentMappings;
|
||||
protected Mappings paintingMappings;
|
||||
protected Mappings menuMappings;
|
||||
protected Mappings attributeMappings;
|
||||
protected Map<RegistryType, List<TagData>> tags;
|
||||
|
||||
public MappingDataBase(final String unmappedVersion, final String mappedVersion) {
|
||||
@@ -76,8 +76,6 @@ public class MappingDataBase implements MappingData {
|
||||
menuMappings = loadMappings(data, "menus");
|
||||
enchantmentMappings = loadMappings(data, "enchantments");
|
||||
paintingMappings = loadMappings(data, "paintings");
|
||||
attributeMappings = loadMappings(data, "attributes");
|
||||
|
||||
|
||||
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
|
||||
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
|
||||
@@ -87,6 +85,7 @@ public class MappingDataBase implements MappingData {
|
||||
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
|
||||
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
|
||||
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
|
||||
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
|
||||
|
||||
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
|
||||
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
|
||||
@@ -180,7 +179,7 @@ public class MappingDataBase implements MappingData {
|
||||
|
||||
@Override
|
||||
public int getOldBlockId(final int id) {
|
||||
return blockMappings.getNewIdOrDefault(id, 1);
|
||||
return blockMappings.inverse().getNewIdOrDefault(id, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -203,6 +202,16 @@ public class MappingDataBase implements MappingData {
|
||||
return checkValidity(id, attributeMappings.getNewId(id), "attributes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewSoundId(final int id) {
|
||||
return checkValidity(id, soundMappings.getNewId(id), "sound");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOldSoundId(final int i) {
|
||||
return soundMappings.getNewIdOrDefault(i, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<TagData> getTags(final RegistryType type) {
|
||||
return tags != null ? tags.get(type) : null;
|
||||
@@ -262,7 +271,7 @@ public class MappingDataBase implements MappingData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Mappings getAttributeMappings() {
|
||||
public @Nullable FullMappings getAttributeMappings() {
|
||||
return attributeMappings;
|
||||
}
|
||||
|
||||
@@ -315,4 +324,4 @@ public class MappingDataBase implements MappingData {
|
||||
|
||||
protected void loadExtras(final CompoundTag data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.viaversion.nbt.io.NBTIO;
|
||||
import com.viaversion.nbt.io.TagReader;
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntArrayTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
@@ -211,68 +210,64 @@ public class MappingDataLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ByteTag serializationStragetyTag = tag.getUnchecked("id");
|
||||
final IntTag mappedSizeTag = tag.getUnchecked("mappedSize");
|
||||
final byte strategy = serializationStragetyTag.asByte();
|
||||
final int mappedSize = tag.getIntTag("mappedSize").asInt();
|
||||
final byte strategy = tag.getByteTag("id").asByte();
|
||||
final V mappings;
|
||||
if (strategy == DIRECT_ID) {
|
||||
final IntArrayTag valuesTag = tag.getIntArrayTag("val");
|
||||
return IntArrayMappings.of(valuesTag.getValue(), mappedSizeTag.asInt());
|
||||
return IntArrayMappings.of(valuesTag.getValue(), mappedSize);
|
||||
} else if (strategy == SHIFTS_ID) {
|
||||
final IntArrayTag shiftsAtTag = tag.getIntArrayTag("at");
|
||||
final IntArrayTag shiftsTag = tag.getIntArrayTag("to");
|
||||
final IntTag sizeTag = tag.getUnchecked("size");
|
||||
final int[] shiftsAt = shiftsAtTag.getValue();
|
||||
final int[] shiftsTo = shiftsTag.getValue();
|
||||
final int size = sizeTag.asInt();
|
||||
final int[] shiftsAt = tag.getIntArrayTag("at").getValue();
|
||||
final int[] shiftsTo = tag.getIntArrayTag("to").getValue();
|
||||
final int size = tag.getIntTag("size").asInt();
|
||||
mappings = holderSupplier.get(size);
|
||||
|
||||
// Handle values until first shift
|
||||
if (shiftsAt[0] != 0) {
|
||||
// Add identity values before the first shift
|
||||
final int to = shiftsAt[0];
|
||||
for (int id = 0; id < to; id++) {
|
||||
addConsumer.addTo(mappings, id, id);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle shifts
|
||||
// Read shifts
|
||||
for (int i = 0; i < shiftsAt.length; i++) {
|
||||
final boolean isLast = i == shiftsAt.length - 1;
|
||||
final int from = shiftsAt[i];
|
||||
final int to = i == shiftsAt.length - 1 ? size : shiftsAt[i + 1];
|
||||
final int to = isLast ? size : shiftsAt[i + 1];
|
||||
int mappedId = shiftsTo[i];
|
||||
for (int id = from; id < to; id++) {
|
||||
addConsumer.addTo(mappings, id, mappedId++);
|
||||
}
|
||||
}
|
||||
} else if (strategy == CHANGES_ID) {
|
||||
final IntArrayTag changesAtTag = tag.getIntArrayTag("at");
|
||||
final IntArrayTag valuesTag = tag.getIntArrayTag("val");
|
||||
final IntTag sizeTag = tag.getUnchecked("size");
|
||||
final int[] changesAt = tag.getIntArrayTag("at").getValue();
|
||||
final int[] values = tag.getIntArrayTag("val").getValue();
|
||||
final int size = tag.getIntTag("size").asInt();
|
||||
final boolean fillBetween = tag.get("nofill") == null;
|
||||
final int[] changesAt = changesAtTag.getValue();
|
||||
final int[] values = valuesTag.getValue();
|
||||
mappings = holderSupplier.get(sizeTag.asInt());
|
||||
mappings = holderSupplier.get(size);
|
||||
|
||||
int nextUnhandledId = 0;
|
||||
for (int i = 0; i < changesAt.length; i++) {
|
||||
final int id = changesAt[i];
|
||||
final int changedId = changesAt[i];
|
||||
if (fillBetween) {
|
||||
// Fill from after the last change to before this change with unchanged ids
|
||||
final int previousId = i != 0 ? changesAt[i - 1] + 1 : 0;
|
||||
for (int identity = previousId; identity < id; identity++) {
|
||||
addConsumer.addTo(mappings, identity, identity);
|
||||
for (int id = nextUnhandledId; id < changedId; id++) {
|
||||
addConsumer.addTo(mappings, id, id);
|
||||
}
|
||||
nextUnhandledId = changedId + 1;
|
||||
}
|
||||
|
||||
// Assign the changed value
|
||||
addConsumer.addTo(mappings, id, values[i]);
|
||||
addConsumer.addTo(mappings, changedId, values[i]);
|
||||
}
|
||||
} else if (strategy == IDENTITY_ID) {
|
||||
final IntTag sizeTag = tag.getUnchecked("size");
|
||||
return new IdentityMappings(sizeTag.asInt(), mappedSizeTag.asInt());
|
||||
final IntTag sizeTag = tag.getIntTag("size");
|
||||
return new IdentityMappings(sizeTag.asInt(), mappedSize);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown serialization strategy: " + strategy);
|
||||
}
|
||||
return mappingsSupplier.create(mappings, mappedSizeTag.asInt());
|
||||
return mappingsSupplier.create(mappings, mappedSize);
|
||||
}
|
||||
|
||||
public @Nullable List<String> identifiersFromGlobalIds(final CompoundTag mappingsTag, final String key) {
|
||||
@@ -295,7 +290,7 @@ public class MappingDataLoader {
|
||||
* @return map with indexes hashed by their id value
|
||||
*/
|
||||
public Object2IntMap<String> indexedObjectToMap(final JsonObject object) {
|
||||
final Object2IntMap<String> map = new Object2IntOpenHashMap<>(object.size(), .99F);
|
||||
final Object2IntMap<String> map = new Object2IntOpenHashMap<>(object.size());
|
||||
map.defaultReturnValue(-1);
|
||||
for (final Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
map.put(entry.getValue().getAsString(), Integer.parseInt(entry.getKey()));
|
||||
@@ -310,7 +305,7 @@ public class MappingDataLoader {
|
||||
* @return map with indexes hashed by their id value
|
||||
*/
|
||||
public Object2IntMap<String> arrayToMap(final JsonArray array) {
|
||||
final Object2IntMap<String> map = new Object2IntOpenHashMap<>(array.size(), .99F);
|
||||
final Object2IntMap<String> map = new Object2IntOpenHashMap<>(array.size());
|
||||
map.defaultReturnValue(-1);
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
map.put(array.get(i).getAsString(), i);
|
||||
|
||||
@@ -36,6 +36,7 @@ public class ParticleMappings extends FullMappingsBase {
|
||||
addBlockParticle("falling_dust");
|
||||
addBlockParticle("block_marker");
|
||||
addBlockParticle("dust_pillar");
|
||||
addBlockParticle("block_crumble");
|
||||
addItemParticle("item");
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public interface EntityTracker {
|
||||
void removeEntity(int id);
|
||||
|
||||
/**
|
||||
* Clears stored entity types and data.
|
||||
* Clears stored entity types and data, only leaving behind the client entity.
|
||||
*/
|
||||
void clearEntities();
|
||||
|
||||
@@ -102,11 +102,19 @@ public interface EntityTracker {
|
||||
@Nullable StoredEntityData entityDataIfPresent(int id);
|
||||
|
||||
/**
|
||||
* Returns the client entity id or -1 if unset.
|
||||
* Returns whether the client entity id has been set.
|
||||
*
|
||||
* @return client entity id or -1 if unset
|
||||
* @return whether the client entity id has been set
|
||||
*/
|
||||
int clientEntityId();
|
||||
boolean hasClientEntityId();
|
||||
|
||||
/**
|
||||
* Returns the client entity id. Should be wrapped around {@link #hasClientEntityId()}.
|
||||
*
|
||||
* @return client entity id
|
||||
* @throws IllegalStateException if the client entity id has not been set
|
||||
*/
|
||||
int clientEntityId() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Sets the client entity id.
|
||||
@@ -169,12 +177,4 @@ public interface EntityTracker {
|
||||
@Nullable DimensionData dimensionData(int dimensionId);
|
||||
|
||||
void setDimensions(Map<String, DimensionData> dimensions);
|
||||
|
||||
/**
|
||||
* Adds the client player entity to the tracker.
|
||||
* If the client entity has not been set yet, this will return false.
|
||||
*
|
||||
* @return whether the client has been tracked
|
||||
*/
|
||||
boolean trackClientEntity();
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public interface DebugHandler {
|
||||
|
||||
/**
|
||||
* Returns whether packets should be logged after being transformed.
|
||||
* Set to true by default.
|
||||
* Set to false by default.
|
||||
*
|
||||
* @return whether packets should be logged after being transformed
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,13 @@ public class BlockPosition {
|
||||
return new BlockPosition(x + face.modX(), y + face.modY(), z + face.modZ());
|
||||
}
|
||||
|
||||
public double distanceFromCenterSquared(final double x, final double y, final double z) {
|
||||
final double dx = this.x + 0.5 - x;
|
||||
final double dy = this.y + 0.5 - y;
|
||||
final double dz = this.z + 0.5 - z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
public int x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,17 @@ public final class ChunkPosition {
|
||||
return (long) chunkX & 0xffffffffL | ((long) chunkZ & 0xffffffffL) << 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a long key for the given block coordinates.
|
||||
*
|
||||
* @param x the block X coordinate
|
||||
* @param z the block Z coordinate
|
||||
* @return the chunk key
|
||||
*/
|
||||
public static long chunkKeyForBlock(final int x, final int z) {
|
||||
return chunkKey(x >> 4, z >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -23,13 +23,12 @@
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Stored up until 1.14 to be used in chunk sending.
|
||||
*/
|
||||
public class ClientWorld implements StorableObject {
|
||||
private Environment environment;
|
||||
private Environment environment = Environment.NORMAL;
|
||||
|
||||
public ClientWorld() {
|
||||
}
|
||||
@@ -38,11 +37,20 @@ public class ClientWorld implements StorableObject {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public @Nullable Environment getEnvironment() {
|
||||
public Environment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
public void setEnvironment(final int environmentId) {
|
||||
/**
|
||||
* Sets the environment of the world and returns whether the environment was changed.
|
||||
*
|
||||
* @param environmentId the id of the environment to set
|
||||
* @return whether the environment was changed
|
||||
*/
|
||||
public boolean setEnvironment(final int environmentId) {
|
||||
final int previousEnvironmentId = environment.id();
|
||||
this.environment = Environment.getEnvironmentById(environmentId);
|
||||
|
||||
return previousEnvironmentId != environmentId;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
public enum GameMode {
|
||||
|
||||
NOT_SET(""),
|
||||
SURVIVAL("Survival Mode"),
|
||||
CREATIVE("Creative Mode"),
|
||||
ADVENTURE("Adventure Mode"),
|
||||
@@ -41,11 +42,11 @@ public enum GameMode {
|
||||
|
||||
public static GameMode getById(int id) {
|
||||
return switch (id) {
|
||||
case 0 -> SURVIVAL;
|
||||
case -1 -> NOT_SET;
|
||||
case 1 -> CREATIVE;
|
||||
case 2 -> ADVENTURE;
|
||||
case 3 -> SPECTATOR;
|
||||
default -> throw new IllegalArgumentException("Unknown gamemode id: " + id);
|
||||
default /*0*/ -> SURVIVAL;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public interface Holder<T> {
|
||||
|
||||
/**
|
||||
@@ -33,7 +35,7 @@ public interface Holder<T> {
|
||||
* @throws IllegalArgumentException if the id is negative
|
||||
*/
|
||||
static <T> Holder<T> of(final int id) {
|
||||
return new HolderImpl<>(id);
|
||||
return new IdHolder<>(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +46,7 @@ public interface Holder<T> {
|
||||
* @return a new direct holder
|
||||
*/
|
||||
static <T> Holder<T> of(final T value) {
|
||||
return new HolderImpl<>(value);
|
||||
return new ValueHolder<>(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,4 +81,12 @@ public interface Holder<T> {
|
||||
* @see #hasId()
|
||||
*/
|
||||
int id();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return a new holder with the id rewritten, or self
|
||||
*/
|
||||
Holder<T> updateId(final Int2IntFunction rewriteFunction);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public interface HolderSet {
|
||||
* @return a new holder set
|
||||
*/
|
||||
static HolderSet of(final String tagKey) {
|
||||
return new HolderSetImpl(tagKey);
|
||||
return new HolderSetImpl.Tag(tagKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ public interface HolderSet {
|
||||
* @return a new holder set
|
||||
*/
|
||||
static HolderSet of(final int[] ids) {
|
||||
return new HolderSetImpl(ids);
|
||||
return new HolderSetImpl.Ids(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,50 +22,63 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.viaversion.viaversion.util.EitherImpl;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.Arrays;
|
||||
|
||||
final class HolderSetImpl extends EitherImpl<String, int[]> implements HolderSet {
|
||||
final class HolderSetImpl {
|
||||
|
||||
HolderSetImpl(final String tagKey) {
|
||||
super(tagKey, null);
|
||||
}
|
||||
record Tag(String tagKey) implements HolderSet {
|
||||
@Override
|
||||
public boolean hasTagKey() {
|
||||
return true;
|
||||
}
|
||||
|
||||
HolderSetImpl(final int[] ids) {
|
||||
super(null, ids);
|
||||
}
|
||||
@Override
|
||||
public int[] ids() {
|
||||
throw new IllegalArgumentException("This holder set has a tag key");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tagKey() {
|
||||
return left();
|
||||
}
|
||||
@Override
|
||||
public boolean hasIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTagKey() {
|
||||
return isLeft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] ids() {
|
||||
return right();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIds() {
|
||||
return isRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderSet rewrite(final Int2IntFunction idRewriter) {
|
||||
if (hasTagKey()) {
|
||||
@Override
|
||||
public HolderSet rewrite(final Int2IntFunction idRewriter) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
final int[] ids = ids();
|
||||
final int[] mappedIds = new int[ids.length];
|
||||
for (int i = 0; i < mappedIds.length; i++) {
|
||||
mappedIds[i] = idRewriter.apply(ids[i]);
|
||||
record Ids(int[] ids) implements HolderSet {
|
||||
@Override
|
||||
public boolean hasTagKey() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tagKey() {
|
||||
throw new IllegalArgumentException("This holder set has direct ids");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderSet rewrite(final Int2IntFunction idRewriter) {
|
||||
final int[] mappedIds = new int[ids.length];
|
||||
for (int i = 0; i < mappedIds.length; i++) {
|
||||
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
|
||||
}
|
||||
return new Ids(mappedIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Ids{" +
|
||||
"ids=" + Arrays.toString(ids) +
|
||||
'}';
|
||||
}
|
||||
return new HolderSetImpl(mappedIds);
|
||||
}
|
||||
}
|
||||
+15
-26
@@ -23,49 +23,38 @@
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
final class HolderImpl<T> implements Holder<T> {
|
||||
record IdHolder<T>(int id) implements Holder<T> {
|
||||
|
||||
private final T value;
|
||||
private final int id;
|
||||
|
||||
HolderImpl(final int id) {
|
||||
IdHolder {
|
||||
Preconditions.checkArgument(id >= 0, "id cannot be negative");
|
||||
this.value = null;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
HolderImpl(final T value) {
|
||||
this.value = value;
|
||||
this.id = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
return id == -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasId() {
|
||||
return id != -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T value() {
|
||||
Preconditions.checkArgument(isDirect(), "Holder is not direct");
|
||||
return value;
|
||||
throw new IllegalArgumentException("Holder is not direct");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HolderImpl{" +
|
||||
"value=" + value +
|
||||
", id=" + id +
|
||||
'}';
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
final int rewrittenId = rewriteFunction.applyAsInt(id);
|
||||
if (rewrittenId == id) {
|
||||
return this;
|
||||
}
|
||||
if (rewrittenId == -1) {
|
||||
throw new IllegalArgumentException("Received invalid id in updateId");
|
||||
}
|
||||
return Holder.of(rewrittenId);
|
||||
}
|
||||
}
|
||||
@@ -22,13 +22,19 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record PaintingVariant(int width, int height, String assetId) {
|
||||
public record PaintingVariant(int width, int height, String assetId, @Nullable Tag title, @Nullable Tag author) {
|
||||
|
||||
public static HolderType<PaintingVariant> TYPE = new HolderType<>() {
|
||||
public PaintingVariant(final int width, final int height, final String assetId) {
|
||||
this(width, height, assetId, null, null);
|
||||
}
|
||||
|
||||
public static HolderType<PaintingVariant> TYPE1_21 = new HolderType<>() {
|
||||
@Override
|
||||
public PaintingVariant readDirect(final ByteBuf buffer) {
|
||||
final int width = Types.VAR_INT.readPrimitive(buffer);
|
||||
@@ -44,4 +50,24 @@ public record PaintingVariant(int width, int height, String assetId) {
|
||||
Types.STRING.write(buffer, variant.assetId());
|
||||
}
|
||||
};
|
||||
public static HolderType<PaintingVariant> TYPE1_21_2 = new HolderType<>() {
|
||||
@Override
|
||||
public PaintingVariant readDirect(final ByteBuf buffer) {
|
||||
final int width = Types.VAR_INT.readPrimitive(buffer);
|
||||
final int height = Types.VAR_INT.readPrimitive(buffer);
|
||||
final String assetId = Types.STRING.read(buffer);
|
||||
final Tag title = Types.OPTIONAL_TAG.read(buffer);
|
||||
final Tag author = Types.OPTIONAL_TAG.read(buffer);
|
||||
return new PaintingVariant(width, height, assetId, title, author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final PaintingVariant variant) {
|
||||
Types.VAR_INT.writePrimitive(buffer, variant.width());
|
||||
Types.VAR_INT.writePrimitive(buffer, variant.height());
|
||||
Types.STRING.write(buffer, variant.assetId());
|
||||
Types.OPTIONAL_TAG.write(buffer, variant.title());
|
||||
Types.OPTIONAL_TAG.write(buffer, variant.author());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.util.IdHolder;
|
||||
@@ -72,6 +73,14 @@ public final class Particle implements IdHolder {
|
||||
arguments.set(index, new ParticleData<>(type, value));
|
||||
}
|
||||
|
||||
public Particle copy() {
|
||||
final Particle particle = new Particle(id);
|
||||
for (ParticleData<?> argument : arguments) {
|
||||
particle.arguments.add(argument.copy());
|
||||
}
|
||||
return particle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Particle{" +
|
||||
@@ -109,6 +118,14 @@ public final class Particle implements IdHolder {
|
||||
wrapper.write(type, value);
|
||||
}
|
||||
|
||||
public ParticleData<T> copy() {
|
||||
if (value instanceof Item item) {
|
||||
return new ParticleData<>(type, (T) item.copy());
|
||||
} else {
|
||||
return new ParticleData<>(type, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParticleData{" +
|
||||
|
||||
@@ -25,9 +25,19 @@ package com.viaversion.viaversion.api.minecraft;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an entry in a registry.
|
||||
*
|
||||
* @param key key of the registry entry
|
||||
* @param tag data of the registry entry, or null if the client should use its default
|
||||
*/
|
||||
public record RegistryEntry(String key, @Nullable Tag tag) {
|
||||
|
||||
public RegistryEntry withKey(final String key) {
|
||||
return new RegistryEntry(key, tag != null ? tag.copy() : null);
|
||||
}
|
||||
|
||||
public RegistryEntry copy() {
|
||||
return new RegistryEntry(key, tag != null ? tag.copy() : null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
record ValueHolder<T>(T value) implements Holder<T> {
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasId() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -37,14 +37,14 @@ public class ChunkSectionImpl implements ChunkSection {
|
||||
public ChunkSectionImpl(final boolean holdsLight) {
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
this.light = ChunkSectionLightImpl.createWithBlockLight();
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
this.light = ChunkSectionLightImpl.createWithBlockLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ public interface ChunkSectionLight {
|
||||
/**
|
||||
* Returns whether the section has sky light.
|
||||
*
|
||||
* @return true if skylight is present
|
||||
* @return true if sky light is present
|
||||
*/
|
||||
boolean hasSkyLight();
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface ChunkSectionLight {
|
||||
* Returns whether the section has block light.
|
||||
* This returns true unless specifically set to null.
|
||||
*
|
||||
* @return true if skylight is present
|
||||
* @return true if block light is present
|
||||
*/
|
||||
boolean hasBlockLight();
|
||||
|
||||
|
||||
+11
-3
@@ -30,9 +30,17 @@ public class ChunkSectionLightImpl implements ChunkSectionLight {
|
||||
private NibbleArray blockLight;
|
||||
private NibbleArray skyLight;
|
||||
|
||||
public ChunkSectionLightImpl() {
|
||||
// Block light is always written
|
||||
this.blockLight = new NibbleArray(ChunkSection.SIZE);
|
||||
protected ChunkSectionLightImpl() {
|
||||
}
|
||||
|
||||
public static ChunkSectionLight createWithBlockLight() {
|
||||
final ChunkSectionLightImpl light = new ChunkSectionLightImpl();
|
||||
light.blockLight = new NibbleArray(ChunkSection.SIZE);
|
||||
return light;
|
||||
}
|
||||
|
||||
public static ChunkSectionLight createEmpty() {
|
||||
return new ChunkSectionLightImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,16 +52,14 @@ public interface StructuredData<T> extends IdHolder {
|
||||
return new EmptyStructuredData<>(key, id);
|
||||
}
|
||||
|
||||
void setValue(final T value);
|
||||
@Nullable T value();
|
||||
|
||||
void write(final ByteBuf buffer);
|
||||
void setValue(final T value);
|
||||
|
||||
void setId(final int id);
|
||||
|
||||
StructuredDataKey<T> key();
|
||||
|
||||
@Nullable T value();
|
||||
|
||||
/**
|
||||
* Returns whether the structured data is present. Even if true, the value may be null.
|
||||
*
|
||||
@@ -77,4 +75,6 @@ public interface StructuredData<T> extends IdHolder {
|
||||
* @return true if the structured data is empty
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
void write(final ByteBuf buffer);
|
||||
}
|
||||
+129
-72
@@ -33,6 +33,26 @@ import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Loosely represents Minecraft's data component patch, but may also be used for an item's full data components.
|
||||
* <p>
|
||||
* The most commonly used methods will ignore empty data (aka empty overrides that remove item defaults) since those will rarely be needed.
|
||||
* These are:
|
||||
* <ul>
|
||||
* <li>{@link #get(StructuredDataKey)}</li>
|
||||
* <li>{@link #set(StructuredDataKey, Object)}</li>
|
||||
* <li>{@link #set(StructuredDataKey)}</li>
|
||||
* <li>{@link #getNonEmptyData(StructuredDataKey)}</li>
|
||||
* <li>{@link #hasValue(StructuredDataKey)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* To interact with empty patches specifically, use:
|
||||
* <ul>
|
||||
* <li>{@link #setEmpty(StructuredDataKey)}</li>
|
||||
* <li>{@link #hasEmpty(StructuredDataKey)}</li>
|
||||
* </ul>
|
||||
* Other methods (e.g. {@link #getData(StructuredDataKey)} and {@link #has(StructuredDataKey)}) will handle both empty and non-empty data.
|
||||
*/
|
||||
public final class StructuredDataContainer {
|
||||
|
||||
private final Map<StructuredDataKey<?>, StructuredData<?>> data;
|
||||
@@ -55,66 +75,45 @@ public final class StructuredDataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns structured data by id if present.
|
||||
* Returns the non-empty value by id if present.
|
||||
*
|
||||
* @param key serializer id
|
||||
* @param <T> data type
|
||||
* @return structured data
|
||||
* @see #hasEmpty(StructuredDataKey)
|
||||
*/
|
||||
public @Nullable <T> T get(final StructuredDataKey<T> key) {
|
||||
final StructuredData<?> data = this.data.get(key);
|
||||
if (data == null || data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
//noinspection unchecked
|
||||
return ((StructuredData<T>) data).value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns structured data by id if present, either empty or non-empty.
|
||||
*
|
||||
* @param key serializer id
|
||||
* @param <T> data type
|
||||
* @return structured data
|
||||
*/
|
||||
public @Nullable <T> StructuredData<T> get(final StructuredDataKey<T> key) {
|
||||
public @Nullable <T> StructuredData<T> getData(final StructuredDataKey<T> key) {
|
||||
//noinspection unchecked
|
||||
return (StructuredData<T>) this.data.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns structured data by id if not empty.
|
||||
* Returns non-empty structured data by id if present.
|
||||
*
|
||||
* @param key serializer id
|
||||
* @param <T> data type
|
||||
* @return structured data if not empty
|
||||
* @return non-empty structured data
|
||||
*/
|
||||
public @Nullable <T> StructuredData<T> getNonEmpty(final StructuredDataKey<T> key) {
|
||||
public @Nullable <T> StructuredData<T> getNonEmptyData(final StructuredDataKey<T> key) {
|
||||
final StructuredData<?> data = this.data.get(key);
|
||||
//noinspection unchecked
|
||||
final StructuredData<T> data = (StructuredData<T>) this.data.get(key);
|
||||
return data != null && data.isPresent() ? data : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns structured data by id if not empty, or creates it.
|
||||
*
|
||||
* @param key serializer id
|
||||
* @param mappingFunction function to create structured data if not present
|
||||
* @param <T> data type
|
||||
* @return structured data if not empty
|
||||
*/
|
||||
public <T> StructuredData<T> computeIfAbsent(final StructuredDataKey<T> key, final Function<StructuredDataKey<T>, T> mappingFunction) {
|
||||
final StructuredData<T> data = this.getNonEmpty(key);
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
|
||||
final int id = serializerId(key);
|
||||
final StructuredData<T> empty = StructuredData.of(key, mappingFunction.apply(key), id);
|
||||
this.data.put(key, empty);
|
||||
return empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates and returns the structured data by id if not empty.
|
||||
*
|
||||
* @param key serializer id
|
||||
* @param mappingFunction function to update existing data
|
||||
* @param <T> data type
|
||||
* @return updated structured data if not empty
|
||||
*/
|
||||
public <T> @Nullable StructuredData<T> updateIfPresent(final StructuredDataKey<T> key, final Function<T, T> mappingFunction) {
|
||||
final StructuredData<T> data = this.getNonEmpty(key);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
data.setValue(mappingFunction.apply(data.value()));
|
||||
return data;
|
||||
return data != null && data.isPresent() ? (StructuredData<T>) data : null;
|
||||
}
|
||||
|
||||
public <T> void set(final StructuredDataKey<T> key, final T value) {
|
||||
@@ -124,49 +123,105 @@ public final class StructuredDataContainer {
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void replaceKey(final StructuredDataKey<T> key, final StructuredDataKey<T> toKey) {
|
||||
replace(key, toKey, Function.identity());
|
||||
}
|
||||
|
||||
public <T, V> void replace(final StructuredDataKey<T> key, final StructuredDataKey<V> toKey, final Function<T, V> valueMapper) {
|
||||
final StructuredData<T> data = remove(key);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.isPresent()) {
|
||||
set(toKey, valueMapper.apply(data.value()));
|
||||
} else {
|
||||
addEmpty(toKey);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(final StructuredDataKey<Unit> key) {
|
||||
this.set(key, Unit.INSTANCE);
|
||||
}
|
||||
|
||||
public void addEmpty(final StructuredDataKey<?> key) {
|
||||
public void setEmpty(final StructuredDataKey<?> key) {
|
||||
// Empty optional to override the Minecraft default
|
||||
this.data.put(key, StructuredData.empty(key, serializerId(key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and returns structured data by the given key.
|
||||
* Updates the structured data by id if not empty.
|
||||
*
|
||||
* @param key serializer key
|
||||
* @param <T> data type
|
||||
* @return removed structured data
|
||||
* @param key serializer id
|
||||
* @param valueMapper function to update existing data
|
||||
* @param <T> data type
|
||||
*/
|
||||
public @Nullable <T> StructuredData<T> remove(final StructuredDataKey<T> key) {
|
||||
final StructuredData<?> data = this.data.remove(key);
|
||||
//noinspection unchecked
|
||||
return data != null ? (StructuredData<T>) data : null;
|
||||
public <T> void replace(final StructuredDataKey<T> key, final Function<T, @Nullable T> valueMapper) {
|
||||
final StructuredData<T> data = this.getNonEmptyData(key);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final T replacement = valueMapper.apply(data.value());
|
||||
if (replacement != null) {
|
||||
data.setValue(replacement);
|
||||
} else {
|
||||
this.data.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(final StructuredDataKey<?> key) {
|
||||
public <T> void replaceKey(final StructuredDataKey<T> key, final StructuredDataKey<T> toKey) {
|
||||
replace(key, toKey, Function.identity());
|
||||
}
|
||||
|
||||
public <T, V> void replace(final StructuredDataKey<T> key, final StructuredDataKey<V> toKey, final Function<T, @Nullable V> valueMapper) {
|
||||
final StructuredData<?> data = this.data.remove(key);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.isPresent()) {
|
||||
//noinspection unchecked
|
||||
final T value = (T) data.value();
|
||||
final V replacement = valueMapper.apply(value);
|
||||
if (replacement != null) {
|
||||
set(toKey, replacement);
|
||||
}
|
||||
} else {
|
||||
// Also replace the key for empty data
|
||||
setEmpty(toKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes data by the given key.
|
||||
*
|
||||
* @param key data key
|
||||
* @see #replace(StructuredDataKey, Function)
|
||||
* @see #replace(StructuredDataKey, StructuredDataKey, Function)
|
||||
* @see #replaceKey(StructuredDataKey, StructuredDataKey)
|
||||
*/
|
||||
public void remove(final StructuredDataKey<?> key) {
|
||||
this.data.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is data for the given key, either empty or non-empty.
|
||||
*
|
||||
* @param key data key
|
||||
* @return whether there data for the given key
|
||||
* @see #hasEmpty(StructuredDataKey)
|
||||
* @see #hasValue(StructuredDataKey)
|
||||
*/
|
||||
public boolean has(final StructuredDataKey<?> key) {
|
||||
return this.data.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is non-empty data for the given key.
|
||||
*
|
||||
* @param key data key
|
||||
* @return whether there is non-empty data for the given key
|
||||
*/
|
||||
public boolean hasValue(final StructuredDataKey<?> key) {
|
||||
final StructuredData<?> data = this.data.get(key);
|
||||
return data != null && data.isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the structured data has an empty patch/override.
|
||||
*
|
||||
* @param key serializer id
|
||||
* @return whether the structured data has an empty patch/override
|
||||
*/
|
||||
public boolean hasEmpty(final StructuredDataKey<?> key) {
|
||||
final StructuredData<?> data = this.data.get(key);
|
||||
return data != null && data.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lookup for serializer ids. Required to call most of the other methods.
|
||||
*
|
||||
@@ -212,6 +267,8 @@ public final class StructuredDataContainer {
|
||||
public String toString() {
|
||||
return "StructuredDataContainer{" +
|
||||
"data=" + data +
|
||||
", lookup=" + lookup +
|
||||
", mappedNames=" + mappedNames +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+45
-9
@@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
|
||||
@@ -34,13 +35,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.BlockStateProperties;
|
||||
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.DyedColor;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Equippable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
|
||||
@@ -48,11 +56,15 @@ import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_4;
|
||||
import com.viaversion.viaversion.util.Unit;
|
||||
|
||||
public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
@@ -64,24 +76,38 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Unbreakable> UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE);
|
||||
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG);
|
||||
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
|
||||
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", Types.TAG_ARRAY);
|
||||
public static final StructuredDataKey<String> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.STRING);
|
||||
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TAG, 256));
|
||||
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE);
|
||||
public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON = new StructuredDataKey<>("can_place_on", AdventureModePredicate.TYPE);
|
||||
public static final StructuredDataKey<AdventureModePredicate> CAN_BREAK = new StructuredDataKey<>("can_break", AdventureModePredicate.TYPE);
|
||||
public static final StructuredDataKey<AttributeModifiers1_20_5> ATTRIBUTE_MODIFIERS1_20_5 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_20_5.TYPE);
|
||||
public static final StructuredDataKey<AttributeModifiers1_21> ATTRIBUTE_MODIFIERS1_21 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_21.TYPE);
|
||||
public static final StructuredDataKey<Integer> CUSTOM_MODEL_DATA = new StructuredDataKey<>("custom_model_data", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Integer> CUSTOM_MODEL_DATA1_20_5 = new StructuredDataKey<>("custom_model_data", Types.VAR_INT);
|
||||
public static final StructuredDataKey<CustomModelData1_21_4> CUSTOM_MODEL_DATA1_21_4 = new StructuredDataKey<>("custom_model_data", CustomModelData1_21_4.TYPE);
|
||||
public static final StructuredDataKey<Unit> HIDE_ADDITIONAL_TOOLTIP = new StructuredDataKey<>("hide_additional_tooltip", Types.EMPTY);
|
||||
public static final StructuredDataKey<Unit> HIDE_TOOLTIP = new StructuredDataKey<>("hide_tooltip", Types.EMPTY);
|
||||
public static final StructuredDataKey<Integer> REPAIR_COST = new StructuredDataKey<>("repair_cost", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Unit> CREATIVE_SLOT_LOCK = new StructuredDataKey<>("creative_slot_lock", Types.EMPTY);
|
||||
public static final StructuredDataKey<Boolean> ENCHANTMENT_GLINT_OVERRIDE = new StructuredDataKey<>("enchantment_glint_override", Types.BOOLEAN);
|
||||
public static final StructuredDataKey<Tag> INTANGIBLE_PROJECTILE = new StructuredDataKey<>("intangible_projectile", Types.TAG); // Doesn't actually hold data
|
||||
public static final StructuredDataKey<FoodProperties> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties.TYPE1_20_5);
|
||||
public static final StructuredDataKey<FoodProperties> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties.TYPE1_21);
|
||||
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_20_5);
|
||||
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_21);
|
||||
public static final StructuredDataKey<FoodProperties1_21_2> FOOD1_21_2 = new StructuredDataKey<>("food", FoodProperties1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_2 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Item> USE_REMAINDER1_21_2 = new StructuredDataKey<>("use_remainder", Types1_21_2.ITEM);
|
||||
public static final StructuredDataKey<Item> USE_REMAINDER1_21_4 = new StructuredDataKey<>("use_remainder", Types1_21_4.ITEM);
|
||||
public static final StructuredDataKey<UseCooldown> USE_COOLDOWN = new StructuredDataKey<>("use_cooldown", UseCooldown.TYPE);
|
||||
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY);
|
||||
public static final StructuredDataKey<DamageResistant> DAMAGE_RESISTANT = new StructuredDataKey<>("damage_resistant", DamageResistant.TYPE);
|
||||
public static final StructuredDataKey<ToolProperties> TOOL = new StructuredDataKey<>("tool", ToolProperties.TYPE);
|
||||
public static final StructuredDataKey<Integer> ENCHANTABLE = new StructuredDataKey<>("enchantable", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Equippable> EQUIPPABLE = new StructuredDataKey<>("equippable", Equippable.TYPE);
|
||||
public static final StructuredDataKey<HolderSet> REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET);
|
||||
public static final StructuredDataKey<Unit> GLIDER = new StructuredDataKey<>("glider", Types.EMPTY);
|
||||
public static final StructuredDataKey<String> TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.STRING);
|
||||
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE);
|
||||
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE);
|
||||
public static final StructuredDataKey<DyedColor> DYED_COLOR = new StructuredDataKey<>("dyed_color", DyedColor.TYPE);
|
||||
public static final StructuredDataKey<Integer> MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT);
|
||||
@@ -90,18 +116,26 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Integer> MAP_POST_PROCESSING = new StructuredDataKey<>("map_post_processing", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_20_5 = new StructuredDataKey<>("charged_projectiles", Types1_20_5.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21 = new StructuredDataKey<>("charged_projectiles", Types1_21.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21_2 = new StructuredDataKey<>("charged_projectiles", Types1_21_2.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21_4 = new StructuredDataKey<>("charged_projectiles", Types1_21_4.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_20_5 = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21 = new StructuredDataKey<>("bundle_contents", Types1_21.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<PotionContents> POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21_2 = new StructuredDataKey<>("bundle_contents", Types1_21_2.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21_4 = new StructuredDataKey<>("bundle_contents", Types1_21_4.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<PotionContents> POTION_CONTENTS1_20_5 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_20_5);
|
||||
public static final StructuredDataKey<PotionContents> POTION_CONTENTS1_21_2 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_21_2);
|
||||
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
|
||||
public static final StructuredDataKey<FilterableString[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", FilterableString.ARRAY_TYPE);
|
||||
public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE);
|
||||
public static final StructuredDataKey<ArmorTrim> TRIM = new StructuredDataKey<>("trim", ArmorTrim.TYPE);
|
||||
public static final StructuredDataKey<ArmorTrim> TRIM1_20_5 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_20_5);
|
||||
public static final StructuredDataKey<ArmorTrim> TRIM1_21_2 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_2);
|
||||
public static final StructuredDataKey<ArmorTrim> TRIM1_21_4 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_4);
|
||||
public static final StructuredDataKey<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<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
|
||||
public static final StructuredDataKey<Holder<Instrument1_20_5>> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE);
|
||||
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT);
|
||||
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE);
|
||||
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG);
|
||||
@@ -115,6 +149,8 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_20_5 = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_21 = new StructuredDataKey<>("container", Types1_21.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_21_2 = new StructuredDataKey<>("container", new ArrayType<>(Types1_21_2.ITEM, 256));
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_21_4 = new StructuredDataKey<>("container", Types1_21_4.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE);
|
||||
public static final StructuredDataKey<Bee[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
|
||||
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public class EntityTypes1_12 {
|
||||
|
||||
LIVING_ENTITY_BASE(ENTITY),
|
||||
ARMOR_STAND(30, LIVING_ENTITY_BASE),
|
||||
PLAYER(ENTITY), // Needed for entity (un)tracking
|
||||
PLAYER(LIVING_ENTITY_BASE), // Needed for entity (un)tracking
|
||||
|
||||
// Living entities as a larger subclass
|
||||
LIVING_ENTITY(LIVING_ENTITY_BASE),
|
||||
|
||||
+5
-4
@@ -51,11 +51,12 @@ public enum EntityTypes1_14 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+5
-4
@@ -51,11 +51,12 @@ public enum EntityTypes1_15 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -51,11 +51,12 @@ public enum EntityTypes1_16 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -51,11 +51,12 @@ public enum EntityTypes1_16_2 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -53,11 +53,12 @@ public enum EntityTypes1_17 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -53,11 +53,12 @@ public enum EntityTypes1_19 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -53,11 +53,12 @@ public enum EntityTypes1_19_3 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -59,11 +59,12 @@ public enum EntityTypes1_19_4 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+6
-5
@@ -59,11 +59,12 @@ public enum EntityTypes1_20_3 implements EntityType {
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+7
-6
@@ -59,12 +59,13 @@ public enum EntityTypes1_20_5 implements EntityType {
|
||||
GLOW_ITEM_FRAME(ITEM_FRAME),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null), // Not actually its own abstract type, but useful for categorizing
|
||||
SNOWBALL(PROJECTILE),
|
||||
ENDER_PEARL(PROJECTILE),
|
||||
EGG(PROJECTILE),
|
||||
POTION(PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(PROJECTILE),
|
||||
PROJECTILE(ENTITY, null),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
|
||||
+314
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.util.EntityTypeUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public enum EntityTypes1_21_2 implements EntityType {
|
||||
|
||||
ENTITY(null, null),
|
||||
|
||||
AREA_EFFECT_CLOUD(ENTITY),
|
||||
END_CRYSTAL(ENTITY),
|
||||
EVOKER_FANGS(ENTITY),
|
||||
EXPERIENCE_ORB(ENTITY),
|
||||
EYE_OF_ENDER(ENTITY),
|
||||
FALLING_BLOCK(ENTITY),
|
||||
ITEM(ENTITY),
|
||||
TNT(ENTITY),
|
||||
OMINOUS_ITEM_SPAWNER(ENTITY),
|
||||
MARKER(ENTITY),
|
||||
LIGHTNING_BOLT(ENTITY),
|
||||
INTERACTION(ENTITY),
|
||||
|
||||
DISPLAY(ENTITY, null),
|
||||
BLOCK_DISPLAY(DISPLAY),
|
||||
ITEM_DISPLAY(DISPLAY),
|
||||
TEXT_DISPLAY(DISPLAY),
|
||||
|
||||
// Hanging entities
|
||||
HANGING_ENTITY(ENTITY, null),
|
||||
LEASH_KNOT(HANGING_ENTITY),
|
||||
PAINTING(HANGING_ENTITY),
|
||||
ITEM_FRAME(HANGING_ENTITY),
|
||||
GLOW_ITEM_FRAME(ITEM_FRAME),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
FISHING_BOBBER(PROJECTILE),
|
||||
WITHER_SKULL(PROJECTILE),
|
||||
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
|
||||
|
||||
ABSTRACT_ARROW(PROJECTILE, null),
|
||||
ARROW(ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(ABSTRACT_ARROW),
|
||||
TRIDENT(ABSTRACT_ARROW),
|
||||
|
||||
ABSTRACT_FIREBALL(ENTITY, null),
|
||||
FIREBALL(ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(ABSTRACT_FIREBALL),
|
||||
|
||||
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
|
||||
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
|
||||
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
|
||||
|
||||
// Vehicles
|
||||
VEHICLE(ENTITY, null),
|
||||
|
||||
ABSTRACT_MINECART(VEHICLE, null),
|
||||
MINECART(ABSTRACT_MINECART),
|
||||
FURNACE_MINECART(ABSTRACT_MINECART),
|
||||
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
|
||||
TNT_MINECART(ABSTRACT_MINECART),
|
||||
SPAWNER_MINECART(ABSTRACT_MINECART),
|
||||
|
||||
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
|
||||
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
|
||||
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
|
||||
|
||||
ABSTRACT_BOAT(VEHICLE, null),
|
||||
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
|
||||
ACACIA_BOAT(ABSTRACT_BOAT),
|
||||
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
|
||||
BAMBOO_RAFT(ABSTRACT_BOAT),
|
||||
BIRCH_BOAT(ABSTRACT_BOAT),
|
||||
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
CHERRY_BOAT(ABSTRACT_BOAT),
|
||||
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
DARK_OAK_BOAT(ABSTRACT_BOAT),
|
||||
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
JUNGLE_BOAT(ABSTRACT_BOAT),
|
||||
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
MANGROVE_BOAT(ABSTRACT_BOAT),
|
||||
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
OAK_BOAT(ABSTRACT_BOAT),
|
||||
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
PALE_OAK_BOAT(ABSTRACT_BOAT),
|
||||
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
SPRUCE_BOAT(ABSTRACT_BOAT),
|
||||
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
|
||||
// Living entities as a larger subclass
|
||||
LIVING_ENTITY(ENTITY, null),
|
||||
ARMOR_STAND(LIVING_ENTITY),
|
||||
PLAYER(LIVING_ENTITY),
|
||||
|
||||
// Mobs as a larger subclass
|
||||
MOB(LIVING_ENTITY, null),
|
||||
ENDER_DRAGON(MOB),
|
||||
|
||||
SLIME(MOB),
|
||||
MAGMA_CUBE(SLIME),
|
||||
|
||||
// Ambient mobs
|
||||
AMBIENT_CREATURE(MOB, null),
|
||||
BAT(AMBIENT_CREATURE),
|
||||
|
||||
// Flying mobs
|
||||
FLYING_MOB(MOB, null),
|
||||
GHAST(FLYING_MOB),
|
||||
PHANTOM(FLYING_MOB),
|
||||
|
||||
// Pathfinder mobs and its subclasses
|
||||
PATHFINDER_MOB(MOB, null),
|
||||
ALLAY(PATHFINDER_MOB),
|
||||
|
||||
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
|
||||
SNOW_GOLEM(ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(ABSTRACT_GOLEM),
|
||||
SHULKER(ABSTRACT_GOLEM),
|
||||
|
||||
// Ageable mobs and (tamable) animals
|
||||
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
|
||||
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
|
||||
VILLAGER(ABSTRACT_VILLAGER),
|
||||
WANDERING_TRADER(ABSTRACT_VILLAGER),
|
||||
|
||||
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
|
||||
AXOLOTL(ABSTRACT_ANIMAL),
|
||||
CHICKEN(ABSTRACT_ANIMAL),
|
||||
PANDA(ABSTRACT_ANIMAL),
|
||||
PIG(ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(ABSTRACT_ANIMAL),
|
||||
RABBIT(ABSTRACT_ANIMAL),
|
||||
SHEEP(ABSTRACT_ANIMAL),
|
||||
BEE(ABSTRACT_ANIMAL),
|
||||
TURTLE(ABSTRACT_ANIMAL),
|
||||
FOX(ABSTRACT_ANIMAL),
|
||||
FROG(ABSTRACT_ANIMAL),
|
||||
GOAT(ABSTRACT_ANIMAL),
|
||||
HOGLIN(ABSTRACT_ANIMAL),
|
||||
STRIDER(ABSTRACT_ANIMAL),
|
||||
SNIFFER(ABSTRACT_ANIMAL),
|
||||
ARMADILLO(ABSTRACT_ANIMAL),
|
||||
|
||||
COW(ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(COW),
|
||||
|
||||
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
|
||||
CAT(TAMABLE_ANIMAL),
|
||||
OCELOT(TAMABLE_ANIMAL),
|
||||
WOLF(TAMABLE_ANIMAL),
|
||||
PARROT(TAMABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
|
||||
HORSE(ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(ABSTRACT_HORSE),
|
||||
CAMEL(ABSTRACT_HORSE),
|
||||
|
||||
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
|
||||
DONKEY(ABSTRACT_CHESTED_HORSE),
|
||||
MULE(ABSTRACT_CHESTED_HORSE),
|
||||
LLAMA(ABSTRACT_CHESTED_HORSE),
|
||||
TRADER_LLAMA(LLAMA),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
|
||||
BLAZE(ABSTRACT_MONSTER),
|
||||
CREEPER(ABSTRACT_MONSTER),
|
||||
ENDERMITE(ABSTRACT_MONSTER),
|
||||
ENDERMAN(ABSTRACT_MONSTER),
|
||||
GIANT(ABSTRACT_MONSTER),
|
||||
SILVERFISH(ABSTRACT_MONSTER),
|
||||
VEX(ABSTRACT_MONSTER),
|
||||
WITHER(ABSTRACT_MONSTER),
|
||||
BREEZE(ABSTRACT_MONSTER),
|
||||
ZOGLIN(ABSTRACT_MONSTER),
|
||||
WARDEN(ABSTRACT_MONSTER),
|
||||
CREAKING(ABSTRACT_MONSTER),
|
||||
CREAKING_TRANSIENT(CREAKING),
|
||||
|
||||
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
|
||||
SKELETON(ABSTRACT_SKELETON),
|
||||
STRAY(ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(ABSTRACT_SKELETON),
|
||||
BOGGED(ABSTRACT_SKELETON),
|
||||
|
||||
ZOMBIE(ABSTRACT_MONSTER),
|
||||
DROWNED(ZOMBIE),
|
||||
HUSK(ZOMBIE),
|
||||
ZOMBIFIED_PIGLIN(ZOMBIE),
|
||||
ZOMBIE_VILLAGER(ZOMBIE),
|
||||
|
||||
GUARDIAN(ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(GUARDIAN),
|
||||
|
||||
SPIDER(ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(SPIDER),
|
||||
|
||||
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
|
||||
PIGLIN(ABSTRACT_PIGLIN),
|
||||
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
|
||||
|
||||
// Water mobs
|
||||
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
|
||||
DOLPHIN(AGEABLE_WATER_CREATURE),
|
||||
|
||||
SQUID(AGEABLE_WATER_CREATURE),
|
||||
GLOW_SQUID(SQUID),
|
||||
|
||||
WATER_ANIMAL(PATHFINDER_MOB, null),
|
||||
ABSTRACT_FISH(WATER_ANIMAL, null),
|
||||
PUFFERFISH(ABSTRACT_FISH),
|
||||
TADPOLE(ABSTRACT_FISH),
|
||||
|
||||
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
|
||||
COD(ABSTRACT_SCHOOLING_FISH),
|
||||
SALMON(ABSTRACT_SCHOOLING_FISH),
|
||||
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
|
||||
|
||||
// Raiders
|
||||
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
|
||||
WITCH(ABSTRACT_RAIDER),
|
||||
RAVAGER(ABSTRACT_RAIDER),
|
||||
|
||||
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
|
||||
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
|
||||
VINDICATOR(ABSTRACT_ILLAGER),
|
||||
PILLAGER(ABSTRACT_ILLAGER),
|
||||
EVOKER(SPELLCASTER_ILLAGER),
|
||||
ILLUSIONER(SPELLCASTER_ILLAGER);
|
||||
|
||||
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
|
||||
private final EntityType parent;
|
||||
private final String identifier;
|
||||
private int id = -1;
|
||||
|
||||
EntityTypes1_21_2(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_21_2(final EntityType parent, @Nullable final String identifier) {
|
||||
this.parent = parent;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
if (id == -1) {
|
||||
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String identifier() {
|
||||
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstractType() {
|
||||
return identifier == null;
|
||||
}
|
||||
|
||||
public static EntityType getTypeFromId(final int typeId) {
|
||||
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
|
||||
}
|
||||
|
||||
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
|
||||
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
|
||||
}
|
||||
}
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entities;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.util.EntityTypeUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public enum EntityTypes1_21_4 implements EntityType {
|
||||
|
||||
ENTITY(null, null),
|
||||
|
||||
AREA_EFFECT_CLOUD(ENTITY),
|
||||
END_CRYSTAL(ENTITY),
|
||||
EVOKER_FANGS(ENTITY),
|
||||
EXPERIENCE_ORB(ENTITY),
|
||||
EYE_OF_ENDER(ENTITY),
|
||||
FALLING_BLOCK(ENTITY),
|
||||
ITEM(ENTITY),
|
||||
TNT(ENTITY),
|
||||
OMINOUS_ITEM_SPAWNER(ENTITY),
|
||||
MARKER(ENTITY),
|
||||
LIGHTNING_BOLT(ENTITY),
|
||||
INTERACTION(ENTITY),
|
||||
|
||||
DISPLAY(ENTITY, null),
|
||||
BLOCK_DISPLAY(DISPLAY),
|
||||
ITEM_DISPLAY(DISPLAY),
|
||||
TEXT_DISPLAY(DISPLAY),
|
||||
|
||||
// Hanging entities
|
||||
HANGING_ENTITY(ENTITY, null),
|
||||
LEASH_KNOT(HANGING_ENTITY),
|
||||
PAINTING(HANGING_ENTITY),
|
||||
ITEM_FRAME(HANGING_ENTITY),
|
||||
GLOW_ITEM_FRAME(ITEM_FRAME),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
FISHING_BOBBER(PROJECTILE),
|
||||
WITHER_SKULL(PROJECTILE),
|
||||
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
|
||||
|
||||
ABSTRACT_ARROW(PROJECTILE, null),
|
||||
ARROW(ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(ABSTRACT_ARROW),
|
||||
TRIDENT(ABSTRACT_ARROW),
|
||||
|
||||
ABSTRACT_FIREBALL(ENTITY, null),
|
||||
FIREBALL(ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(ABSTRACT_FIREBALL),
|
||||
|
||||
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
|
||||
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
|
||||
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
|
||||
|
||||
// Vehicles
|
||||
VEHICLE(ENTITY, null),
|
||||
|
||||
ABSTRACT_MINECART(VEHICLE, null),
|
||||
MINECART(ABSTRACT_MINECART),
|
||||
FURNACE_MINECART(ABSTRACT_MINECART),
|
||||
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
|
||||
TNT_MINECART(ABSTRACT_MINECART),
|
||||
SPAWNER_MINECART(ABSTRACT_MINECART),
|
||||
|
||||
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
|
||||
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
|
||||
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
|
||||
|
||||
ABSTRACT_BOAT(VEHICLE, null),
|
||||
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
|
||||
ACACIA_BOAT(ABSTRACT_BOAT),
|
||||
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
|
||||
BAMBOO_RAFT(ABSTRACT_BOAT),
|
||||
BIRCH_BOAT(ABSTRACT_BOAT),
|
||||
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
CHERRY_BOAT(ABSTRACT_BOAT),
|
||||
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
DARK_OAK_BOAT(ABSTRACT_BOAT),
|
||||
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
JUNGLE_BOAT(ABSTRACT_BOAT),
|
||||
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
MANGROVE_BOAT(ABSTRACT_BOAT),
|
||||
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
OAK_BOAT(ABSTRACT_BOAT),
|
||||
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
PALE_OAK_BOAT(ABSTRACT_BOAT),
|
||||
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
SPRUCE_BOAT(ABSTRACT_BOAT),
|
||||
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
|
||||
// Living entities as a larger subclass
|
||||
LIVING_ENTITY(ENTITY, null),
|
||||
ARMOR_STAND(LIVING_ENTITY),
|
||||
PLAYER(LIVING_ENTITY),
|
||||
|
||||
// Mobs as a larger subclass
|
||||
MOB(LIVING_ENTITY, null),
|
||||
ENDER_DRAGON(MOB),
|
||||
|
||||
SLIME(MOB),
|
||||
MAGMA_CUBE(SLIME),
|
||||
|
||||
// Ambient mobs
|
||||
AMBIENT_CREATURE(MOB, null),
|
||||
BAT(AMBIENT_CREATURE),
|
||||
|
||||
// Flying mobs
|
||||
FLYING_MOB(MOB, null),
|
||||
GHAST(FLYING_MOB),
|
||||
PHANTOM(FLYING_MOB),
|
||||
|
||||
// Pathfinder mobs and its subclasses
|
||||
PATHFINDER_MOB(MOB, null),
|
||||
ALLAY(PATHFINDER_MOB),
|
||||
|
||||
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
|
||||
SNOW_GOLEM(ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(ABSTRACT_GOLEM),
|
||||
SHULKER(ABSTRACT_GOLEM),
|
||||
|
||||
// Ageable mobs and (tamable) animals
|
||||
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
|
||||
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
|
||||
VILLAGER(ABSTRACT_VILLAGER),
|
||||
WANDERING_TRADER(ABSTRACT_VILLAGER),
|
||||
|
||||
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
|
||||
AXOLOTL(ABSTRACT_ANIMAL),
|
||||
CHICKEN(ABSTRACT_ANIMAL),
|
||||
PANDA(ABSTRACT_ANIMAL),
|
||||
PIG(ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(ABSTRACT_ANIMAL),
|
||||
RABBIT(ABSTRACT_ANIMAL),
|
||||
SHEEP(ABSTRACT_ANIMAL),
|
||||
BEE(ABSTRACT_ANIMAL),
|
||||
TURTLE(ABSTRACT_ANIMAL),
|
||||
FOX(ABSTRACT_ANIMAL),
|
||||
FROG(ABSTRACT_ANIMAL),
|
||||
GOAT(ABSTRACT_ANIMAL),
|
||||
HOGLIN(ABSTRACT_ANIMAL),
|
||||
STRIDER(ABSTRACT_ANIMAL),
|
||||
SNIFFER(ABSTRACT_ANIMAL),
|
||||
ARMADILLO(ABSTRACT_ANIMAL),
|
||||
|
||||
COW(ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(COW),
|
||||
|
||||
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
|
||||
CAT(TAMABLE_ANIMAL),
|
||||
OCELOT(TAMABLE_ANIMAL),
|
||||
WOLF(TAMABLE_ANIMAL),
|
||||
PARROT(TAMABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
|
||||
HORSE(ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(ABSTRACT_HORSE),
|
||||
CAMEL(ABSTRACT_HORSE),
|
||||
|
||||
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
|
||||
DONKEY(ABSTRACT_CHESTED_HORSE),
|
||||
MULE(ABSTRACT_CHESTED_HORSE),
|
||||
LLAMA(ABSTRACT_CHESTED_HORSE),
|
||||
TRADER_LLAMA(LLAMA),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
|
||||
BLAZE(ABSTRACT_MONSTER),
|
||||
CREEPER(ABSTRACT_MONSTER),
|
||||
ENDERMITE(ABSTRACT_MONSTER),
|
||||
ENDERMAN(ABSTRACT_MONSTER),
|
||||
GIANT(ABSTRACT_MONSTER),
|
||||
SILVERFISH(ABSTRACT_MONSTER),
|
||||
VEX(ABSTRACT_MONSTER),
|
||||
WITHER(ABSTRACT_MONSTER),
|
||||
BREEZE(ABSTRACT_MONSTER),
|
||||
ZOGLIN(ABSTRACT_MONSTER),
|
||||
WARDEN(ABSTRACT_MONSTER),
|
||||
CREAKING(ABSTRACT_MONSTER),
|
||||
|
||||
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_4(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_21_4(final EntityType parent, @Nullable final String identifier) {
|
||||
this.parent = parent;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
if (id == -1) {
|
||||
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String identifier() {
|
||||
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstractType() {
|
||||
return identifier == null;
|
||||
}
|
||||
|
||||
public static EntityType getTypeFromId(final int typeId) {
|
||||
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
|
||||
}
|
||||
|
||||
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
|
||||
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -93,7 +93,7 @@ public class EntityTypes1_8 {
|
||||
|
||||
LIVING_ENTITY_BASE(ENTITY),
|
||||
ARMOR_STAND(30, LIVING_ENTITY_BASE),
|
||||
PLAYER(LIVING_ENTITY_BASE), // Needed for entity (un)tracking and metadata indexing
|
||||
PLAYER(LIVING_ENTITY_BASE), // Needed for entity (un)tracking and entity data indexing
|
||||
|
||||
// Living entities as a larger subclass
|
||||
LIVING_ENTITY(48, LIVING_ENTITY_BASE),
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class EntityTypes1_9 {
|
||||
|
||||
LIVING_ENTITY_BASE(ENTITY),
|
||||
ARMOR_STAND(30, LIVING_ENTITY_BASE),
|
||||
PLAYER(ENTITY), // Needed for entity (un)tracking
|
||||
PLAYER(LIVING_ENTITY_BASE), // Needed for entity (un)tracking
|
||||
|
||||
// Living entities as a larger subclass
|
||||
LIVING_ENTITY(48, LIVING_ENTITY_BASE),
|
||||
|
||||
+36
-36
@@ -28,21 +28,21 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class EntityData {
|
||||
private int id;
|
||||
private EntityDataType metaType;
|
||||
private EntityDataType dataType;
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Creates a new metadata instance.
|
||||
* Creates a new entity data instance.
|
||||
*
|
||||
* @param id metadata index
|
||||
* @param metaType metadata type
|
||||
* @param id data index
|
||||
* @param dataType data type
|
||||
* @param value value if present
|
||||
* @throws IllegalArgumentException if the value and metaType are incompatible
|
||||
* @throws IllegalArgumentException if the value and dataType are incompatible
|
||||
*/
|
||||
public EntityData(int id, EntityDataType metaType, @Nullable Object value) {
|
||||
public EntityData(int id, EntityDataType dataType, @Nullable Object value) {
|
||||
this.id = id;
|
||||
this.metaType = metaType;
|
||||
this.value = checkValue(metaType, value);
|
||||
this.dataType = dataType;
|
||||
this.value = checkValue(dataType, value);
|
||||
}
|
||||
|
||||
public int id() {
|
||||
@@ -54,19 +54,19 @@ public final class EntityData {
|
||||
}
|
||||
|
||||
public EntityDataType dataType() {
|
||||
return metaType;
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the metadata type if compatible with the current value.
|
||||
* Sets the entity data type if compatible with the current value.
|
||||
*
|
||||
* @param metaType metadata type
|
||||
* @throws IllegalArgumentException if the metadata type and current value are incompatible
|
||||
* @param dataType entity data type
|
||||
* @throws IllegalArgumentException if the entity data type and current value are incompatible
|
||||
* @see #setTypeAndValue(EntityDataType, Object)
|
||||
*/
|
||||
public void setDataType(EntityDataType metaType) {
|
||||
checkValue(metaType, this.value);
|
||||
this.metaType = metaType;
|
||||
public void setDataType(EntityDataType dataType) {
|
||||
checkValue(dataType, this.value);
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public @Nullable <T> T value() {
|
||||
@@ -78,32 +78,32 @@ public final class EntityData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the metadata value if compatible with the current meta type.
|
||||
* Sets the entity data value if compatible with the current data type.
|
||||
*
|
||||
* @param value value
|
||||
* @throws IllegalArgumentException if the value and current metaType are incompatible
|
||||
* @throws IllegalArgumentException if the value and current dataType are incompatible
|
||||
* @see #setTypeAndValue(EntityDataType, Object)
|
||||
*/
|
||||
public void setValue(@Nullable Object value) {
|
||||
this.value = checkValue(this.metaType, value);
|
||||
this.value = checkValue(this.dataType, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets metadata type and value.
|
||||
* Sets entity data type and value.
|
||||
*
|
||||
* @param metaType metadata type
|
||||
* @param dataType entity data type
|
||||
* @param value value
|
||||
* @throws IllegalArgumentException if the value and metaType are incompatible
|
||||
* @throws IllegalArgumentException if the value and dataType are incompatible
|
||||
*/
|
||||
public void setTypeAndValue(EntityDataType metaType, @Nullable Object value) {
|
||||
this.value = checkValue(metaType, value);
|
||||
this.metaType = metaType;
|
||||
public void setTypeAndValue(EntityDataType dataType, @Nullable Object value) {
|
||||
this.value = checkValue(dataType, value);
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
private Object checkValue(EntityDataType metaType, @Nullable Object value) {
|
||||
Preconditions.checkNotNull(metaType);
|
||||
if (value != null && !metaType.type().getOutputClass().isAssignableFrom(value.getClass())) {
|
||||
throw new IllegalArgumentException("Metadata value and metaType are incompatible. Type=" + metaType
|
||||
private Object checkValue(EntityDataType dataType, @Nullable Object value) {
|
||||
Preconditions.checkNotNull(dataType);
|
||||
if (value != null && !dataType.type().getOutputClass().isAssignableFrom(value.getClass())) {
|
||||
throw new IllegalArgumentException("Entity data value and dataType are incompatible. Type=" + dataType
|
||||
+ ", value=" + value + " (" + value.getClass().getSimpleName() + ")");
|
||||
}
|
||||
return value;
|
||||
@@ -111,32 +111,32 @@ public final class EntityData {
|
||||
|
||||
@Deprecated
|
||||
public void setDataTypeUnsafe(EntityDataType type) {
|
||||
this.metaType = type;
|
||||
this.dataType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
EntityData metadata = (EntityData) o;
|
||||
if (id != metadata.id) return false;
|
||||
if (metaType != metadata.metaType) return false;
|
||||
return Objects.equals(value, metadata.value);
|
||||
EntityData entityData = (EntityData) o;
|
||||
if (id != entityData.id) return false;
|
||||
if (dataType != entityData.dataType) return false;
|
||||
return Objects.equals(value, entityData.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = id;
|
||||
result = 31 * result + metaType.hashCode();
|
||||
result = 31 * result + dataType.hashCode();
|
||||
result = 31 * result + (value != null ? value.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Metadata{" +
|
||||
return "EntityData{" +
|
||||
"id=" + id +
|
||||
", metaType=" + metaType +
|
||||
", dataType=" + dataType +
|
||||
", value=" + value +
|
||||
'}';
|
||||
}
|
||||
|
||||
+5
-5
@@ -35,7 +35,7 @@ public interface EntityDataType {
|
||||
Type type();
|
||||
|
||||
/**
|
||||
* Get type id from the specific MetaDataType
|
||||
* Get type id from the specific EntityDataType
|
||||
*
|
||||
* @return Type id as an integer
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ public interface EntityDataType {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EntityDataType{" +
|
||||
return "EntityDataTypeImpl{" +
|
||||
"typeId=" + typeId +
|
||||
", type=" + type +
|
||||
'}';
|
||||
@@ -77,9 +77,9 @@ public interface EntityDataType {
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final EntityDataTypeImpl metaType = (EntityDataTypeImpl) o;
|
||||
if (typeId != metaType.typeId) return false;
|
||||
return type.equals(metaType.type);
|
||||
final EntityDataTypeImpl dataType = (EntityDataTypeImpl) o;
|
||||
if (typeId != dataType.typeId) return false;
|
||||
return type.equals(dataType.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-3
@@ -44,8 +44,8 @@ public abstract class AbstractEntityDataTypes implements EntityDataTypes {
|
||||
}
|
||||
|
||||
protected EntityDataType add(final int typeId, final Type<?> type) {
|
||||
final EntityDataType metaType = EntityDataType.create(typeId, type);
|
||||
values[typeId] = metaType;
|
||||
return metaType;
|
||||
final EntityDataType dataType = EntityDataType.create(typeId, type);
|
||||
values[typeId] = dataType;
|
||||
return dataType;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -27,18 +27,18 @@ import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
|
||||
public interface EntityDataTypes {
|
||||
|
||||
/**
|
||||
* Returns the meta type by the given id.
|
||||
* Returns the data type by the given id.
|
||||
*
|
||||
* @param id type id
|
||||
* @return meta type by id
|
||||
* @return data type by id
|
||||
* @throws IndexOutOfBoundsException if id is out of bounds
|
||||
*/
|
||||
EntityDataType byId(int id);
|
||||
|
||||
/**
|
||||
* Returns an array of meta types.
|
||||
* Returns an array of data types.
|
||||
*
|
||||
* @return array of meta types
|
||||
* @return array of data types
|
||||
*/
|
||||
EntityDataType[] values();
|
||||
}
|
||||
+6
-4
@@ -26,10 +26,11 @@ import com.viaversion.viaversion.api.minecraft.PaintingVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.WolfVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
|
||||
public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
|
||||
@@ -40,7 +41,7 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType itemType = add(7, Types1_21.ITEM);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
|
||||
@@ -59,14 +60,15 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE);
|
||||
public final EntityDataType frogVariantType = add(24, Types.VAR_INT);
|
||||
public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION);
|
||||
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE);
|
||||
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE1_21);
|
||||
public final EntityDataType snifferState = add(27, Types.VAR_INT);
|
||||
public final EntityDataType armadilloState = add(28, Types.VAR_INT);
|
||||
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
|
||||
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
|
||||
|
||||
public EntityDataTypes1_21(final ParticleType particleType, final ArrayType<Particle> particlesType) {
|
||||
public EntityDataTypes1_21(final Type<Item> itemType, final ParticleType particleType, final ArrayType<Particle> particlesType) {
|
||||
super(31);
|
||||
this.itemType = add(7, itemType);
|
||||
this.particleType = add(17, particleType);
|
||||
this.particlesType = add(18, particlesType);
|
||||
}
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.entitydata.types;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.WolfVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
|
||||
|
||||
public final class EntityDataTypes1_21_2 extends AbstractEntityDataTypes {
|
||||
|
||||
public final EntityDataType byteType = add(0, Types.BYTE);
|
||||
public final EntityDataType varIntType = add(1, Types.VAR_INT);
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
|
||||
public final EntityDataType optionalBlockPositionType = add(11, Types.OPTIONAL_POSITION_1_14);
|
||||
public final EntityDataType directionType = add(12, Types.VAR_INT);
|
||||
public final EntityDataType optionalUUIDType = add(13, Types.OPTIONAL_UUID);
|
||||
public final EntityDataType blockStateType = add(14, Types.VAR_INT);
|
||||
public final EntityDataType optionalBlockStateType = add(15, Types.VAR_INT);
|
||||
public final EntityDataType compoundTagType = add(16, Types.COMPOUND_TAG);
|
||||
public final EntityDataType particleType;
|
||||
public final EntityDataType particlesType;
|
||||
public final EntityDataType villagerDatatType = add(19, Types.VILLAGER_DATA);
|
||||
public final EntityDataType optionalVarIntType = add(20, Types.OPTIONAL_VAR_INT);
|
||||
public final EntityDataType poseType = add(21, Types.VAR_INT);
|
||||
public final EntityDataType catVariantType = add(22, Types.VAR_INT);
|
||||
public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE);
|
||||
public final EntityDataType frogVariantType = add(24, Types.VAR_INT);
|
||||
public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION);
|
||||
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE1_21_2);
|
||||
public final EntityDataType snifferState = add(27, Types.VAR_INT);
|
||||
public final EntityDataType armadilloState = add(28, Types.VAR_INT);
|
||||
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
|
||||
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
|
||||
|
||||
public EntityDataTypes1_21_2(final Type<Item> itemType, final ParticleType particleType, final Type<Particle[]> particlesType) {
|
||||
super(31);
|
||||
this.itemType = add(7, itemType);
|
||||
this.particleType = add(17, particleType);
|
||||
this.particlesType = add(18, particlesType);
|
||||
}
|
||||
}
|
||||
@@ -124,11 +124,11 @@ public class DataItem implements Item {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Item{" +
|
||||
return "DataItem{" +
|
||||
"identifier=" + identifier +
|
||||
", amount=" + amount +
|
||||
", data=" + data +
|
||||
", tag=" + tag +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,8 @@ public class StructuredItem implements Item {
|
||||
return new StructuredItem(0, 0);
|
||||
}
|
||||
|
||||
public static StructuredItem[] emptyArray(final int size) {
|
||||
final StructuredItem[] items = new StructuredItem[size];
|
||||
public static Item[] emptyArray(final int size) {
|
||||
final Item[] items = new Item[size];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = empty();
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern, boolean showInTooltip) {
|
||||
|
||||
public static final Type<ArmorTrim> TYPE = new Type<>(ArmorTrim.class) {
|
||||
public static final Type<ArmorTrim> TYPE1_20_5 = new Type<>(ArmorTrim.class) {
|
||||
@Override
|
||||
public ArmorTrim read(final ByteBuf buffer) {
|
||||
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE.read(buffer);
|
||||
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_20_5.read(buffer);
|
||||
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer);
|
||||
final boolean showInTooltip = buffer.readBoolean();
|
||||
return new ArmorTrim(material, pattern, showInTooltip);
|
||||
@@ -40,7 +40,39 @@ public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPatt
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ArmorTrim value) {
|
||||
ArmorTrimMaterial.TYPE.write(buffer, value.material);
|
||||
ArmorTrimMaterial.TYPE1_20_5.write(buffer, value.material);
|
||||
ArmorTrimPattern.TYPE.write(buffer, value.pattern);
|
||||
buffer.writeBoolean(value.showInTooltip);
|
||||
}
|
||||
};
|
||||
public static final Type<ArmorTrim> TYPE1_21_2 = new Type<>(ArmorTrim.class) {
|
||||
@Override
|
||||
public ArmorTrim read(final ByteBuf buffer) {
|
||||
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_2.read(buffer);
|
||||
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer);
|
||||
final boolean showInTooltip = buffer.readBoolean();
|
||||
return new ArmorTrim(material, pattern, showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ArmorTrim value) {
|
||||
ArmorTrimMaterial.TYPE1_21_2.write(buffer, value.material);
|
||||
ArmorTrimPattern.TYPE.write(buffer, value.pattern);
|
||||
buffer.writeBoolean(value.showInTooltip);
|
||||
}
|
||||
};
|
||||
public static final Type<ArmorTrim> TYPE1_21_4 = new Type<>(ArmorTrim.class) {
|
||||
@Override
|
||||
public ArmorTrim read(final ByteBuf buffer) {
|
||||
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_4.read(buffer);
|
||||
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer);
|
||||
final boolean showInTooltip = buffer.readBoolean();
|
||||
return new ArmorTrim(material, pattern, showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ArmorTrim value) {
|
||||
ArmorTrimMaterial.TYPE1_21_4.write(buffer, value.material);
|
||||
ArmorTrimPattern.TYPE.write(buffer, value.pattern);
|
||||
buffer.writeBoolean(value.showInTooltip);
|
||||
}
|
||||
|
||||
+81
-7
@@ -27,13 +27,19 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import java.util.Map;
|
||||
|
||||
public record ArmorTrimMaterial(String assetName, int itemId, float itemModelIndex,
|
||||
Int2ObjectMap<String> overrideArmorMaterials, Tag description) {
|
||||
Map<String, String> overrideArmorMaterials, Tag description) {
|
||||
|
||||
public static final HolderType<ArmorTrimMaterial> TYPE = new HolderType<>() {
|
||||
public ArmorTrimMaterial(final String assetName, final int itemId, final Map<String, String> overrideArmorMaterials, final Tag description) {
|
||||
this(assetName, itemId, 0F, overrideArmorMaterials, description);
|
||||
}
|
||||
|
||||
public static final HolderType<ArmorTrimMaterial> TYPE1_20_5 = new HolderType<>() {
|
||||
// The override key is an int, but given we don't use it at all and that creating a new type is annoying,
|
||||
// we'll just store it in the string map:tm:
|
||||
@Override
|
||||
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
|
||||
final String assetName = Types.STRING.read(buffer);
|
||||
@@ -41,10 +47,45 @@ public record ArmorTrimMaterial(String assetName, int itemId, float itemModelInd
|
||||
final float itemModelIndex = buffer.readFloat();
|
||||
|
||||
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Int2ObjectMap<String> overrideArmorMaterials = new Int2ObjectOpenHashMap<>(overrideArmorMaterialsSize);
|
||||
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>(overrideArmorMaterialsSize);
|
||||
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
|
||||
final int key = Types.VAR_INT.readPrimitive(buffer);
|
||||
final String value = Types.STRING.read(buffer);
|
||||
overrideArmorMaterials.put(Integer.toString(key), value);
|
||||
}
|
||||
|
||||
final Tag description = Types.TAG.read(buffer);
|
||||
return new ArmorTrimMaterial(assetName, item, itemModelIndex, overrideArmorMaterials, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
|
||||
Types.STRING.write(buffer, value.assetName());
|
||||
Types.VAR_INT.writePrimitive(buffer, value.itemId());
|
||||
buffer.writeFloat(value.itemModelIndex());
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
|
||||
for (final Map.Entry<String, String> entry : value.overrideArmorMaterials().entrySet()) {
|
||||
Types.VAR_INT.writePrimitive(buffer, Integer.parseInt(entry.getKey()));
|
||||
Types.STRING.write(buffer, entry.getValue());
|
||||
}
|
||||
|
||||
Types.TAG.write(buffer, value.description());
|
||||
}
|
||||
};
|
||||
|
||||
public static final HolderType<ArmorTrimMaterial> TYPE1_21_2 = new HolderType<>() {
|
||||
@Override
|
||||
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
|
||||
final String assetName = Types.STRING.read(buffer);
|
||||
final int item = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float itemModelIndex = buffer.readFloat();
|
||||
|
||||
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>(overrideArmorMaterialsSize);
|
||||
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
|
||||
final String key = Types.STRING.read(buffer);
|
||||
final String value = Types.STRING.read(buffer);
|
||||
overrideArmorMaterials.put(key, value);
|
||||
}
|
||||
|
||||
@@ -59,8 +100,41 @@ public record ArmorTrimMaterial(String assetName, int itemId, float itemModelInd
|
||||
buffer.writeFloat(value.itemModelIndex());
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
|
||||
for (final Int2ObjectMap.Entry<String> entry : value.overrideArmorMaterials().int2ObjectEntrySet()) {
|
||||
Types.VAR_INT.writePrimitive(buffer, entry.getIntKey());
|
||||
for (final Map.Entry<String, String> entry : value.overrideArmorMaterials().entrySet()) {
|
||||
Types.STRING.write(buffer, entry.getKey());
|
||||
Types.STRING.write(buffer, entry.getValue());
|
||||
}
|
||||
|
||||
Types.TAG.write(buffer, value.description());
|
||||
}
|
||||
};
|
||||
|
||||
public static final HolderType<ArmorTrimMaterial> TYPE1_21_4 = new HolderType<>() {
|
||||
@Override
|
||||
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
|
||||
final String assetName = Types.STRING.read(buffer);
|
||||
final int item = Types.VAR_INT.readPrimitive(buffer);
|
||||
|
||||
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>(overrideArmorMaterialsSize);
|
||||
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
|
||||
final String key = Types.STRING.read(buffer);
|
||||
final String value = Types.STRING.read(buffer);
|
||||
overrideArmorMaterials.put(key, value);
|
||||
}
|
||||
|
||||
final Tag description = Types.TAG.read(buffer);
|
||||
return new ArmorTrimMaterial(assetName, item, overrideArmorMaterials, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
|
||||
Types.STRING.write(buffer, value.assetName());
|
||||
Types.VAR_INT.writePrimitive(buffer, value.itemId());
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
|
||||
for (final Map.Entry<String, String> entry : value.overrideArmorMaterials().entrySet()) {
|
||||
Types.STRING.write(buffer, entry.getKey());
|
||||
Types.STRING.write(buffer, entry.getValue());
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -26,6 +26,7 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) {
|
||||
|
||||
@@ -44,6 +45,15 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
|
||||
}
|
||||
};
|
||||
|
||||
public AttributeModifiers1_21 rewrite(final Int2IntFunction rewriteFunction) {
|
||||
final AttributeModifier[] modifiers = new AttributeModifier[this.modifiers.length];
|
||||
for (int i = 0; i < this.modifiers.length; i++) {
|
||||
final AttributeModifier modifier = this.modifiers[i];
|
||||
modifiers[i] = new AttributeModifier(rewriteFunction.applyAsInt(modifier.attribute()), modifier.modifier(), modifier.slotType());
|
||||
}
|
||||
return new AttributeModifiers1_21(modifiers, showInTooltip);
|
||||
}
|
||||
|
||||
public record AttributeModifier(int attribute, ModifierData modifier, int slotType) {
|
||||
|
||||
public static final Type<AttributeModifier> TYPE = new Type<>(AttributeModifier.class) {
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<SoundEvent> sound,
|
||||
boolean hasConsumeParticles, ConsumeEffect<?>[] consumeEffects) {
|
||||
|
||||
public static final Type<?>[] EFFECT_TYPES = {
|
||||
ApplyStatusEffects.TYPE,
|
||||
Types.HOLDER_SET, // remove effects
|
||||
Types.EMPTY, // clear all effects
|
||||
Types.FLOAT, // teleport randomly
|
||||
Types.SOUND_EVENT // play sound
|
||||
};
|
||||
|
||||
public static final Type<Consumable1_21_2> TYPE = new Type<>(Consumable1_21_2.class) {
|
||||
@Override
|
||||
public Consumable1_21_2 read(final ByteBuf buffer) {
|
||||
final float consumeSeconds = buffer.readFloat();
|
||||
final int animationType = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Holder<SoundEvent> sound = Types.SOUND_EVENT.read(buffer);
|
||||
final boolean hasConsumeParticles = buffer.readBoolean();
|
||||
final ConsumeEffect<?>[] consumeEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
|
||||
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, consumeEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Consumable1_21_2 value) {
|
||||
buffer.writeFloat(value.consumeSeconds);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.animationType);
|
||||
Types.SOUND_EVENT.write(buffer, value.sound);
|
||||
buffer.writeBoolean(value.hasConsumeParticles);
|
||||
ConsumeEffect.ARRAY_TYPE.write(buffer, value.consumeEffects);
|
||||
}
|
||||
};
|
||||
|
||||
public record ConsumeEffect<T>(int id, Type<T> type, T value) {
|
||||
|
||||
public static final Type<ConsumeEffect<?>> TYPE = new Type<>(ConsumeEffect.class) {
|
||||
@Override
|
||||
public ConsumeEffect<?> read(final ByteBuf buffer) {
|
||||
// Oh no...
|
||||
final int effectType = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Type<?> type = EFFECT_TYPES[effectType];
|
||||
final Object value = type.read(buffer);
|
||||
return ConsumeEffect.of(effectType, type, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ConsumeEffect<?> value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.id);
|
||||
value.writeValue(buffer);
|
||||
}
|
||||
};
|
||||
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
|
||||
static <T> ConsumeEffect<T> of(final int id, final Type<T> type, final Object value) {
|
||||
//noinspection unchecked
|
||||
return new ConsumeEffect<>(id, type, (T) value);
|
||||
}
|
||||
|
||||
void writeValue(final ByteBuf buf) {
|
||||
this.type.write(buf, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
public record ApplyStatusEffects(PotionEffect[] effects, float probability) {
|
||||
|
||||
public static final Type<ApplyStatusEffects> TYPE = new Type<>(ApplyStatusEffects.class) {
|
||||
@Override
|
||||
public ApplyStatusEffects read(final ByteBuf buffer) {
|
||||
final PotionEffect[] effects = PotionEffect.ARRAY_TYPE.read(buffer);
|
||||
final float probability = buffer.readFloat();
|
||||
return new ApplyStatusEffects(effects, probability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ApplyStatusEffects value) {
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.effects);
|
||||
buffer.writeFloat(value.probability);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record CustomModelData1_21_4(float[] floats, boolean[] booleans, String[] strings, int[] colors) {
|
||||
|
||||
public static final Type<CustomModelData1_21_4> TYPE = new Type<>(CustomModelData1_21_4.class) {
|
||||
@Override
|
||||
public CustomModelData1_21_4 read(final ByteBuf buffer) {
|
||||
final float[] floats = Types.FLOAT_ARRAY_PRIMITIVE.read(buffer);
|
||||
final boolean[] booleans = Types.BOOLEAN_ARRAY_PRIMITIVE.read(buffer);
|
||||
final String[] strings = Types.STRING_ARRAY.read(buffer);
|
||||
final int[] colors = Types.INT_ARRAY_PRIMITIVE.read(buffer);
|
||||
return new CustomModelData1_21_4(floats, booleans, strings, colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final CustomModelData1_21_4 value) {
|
||||
Types.FLOAT_ARRAY_PRIMITIVE.write(buffer, value.floats());
|
||||
Types.BOOLEAN_ARRAY_PRIMITIVE.write(buffer, value.booleans());
|
||||
Types.STRING_ARRAY.write(buffer, value.strings());
|
||||
Types.INT_ARRAY_PRIMITIVE.write(buffer, value.colors());
|
||||
}
|
||||
};
|
||||
}
|
||||
+7
-20
@@ -25,32 +25,19 @@ package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public record MapDecorations(Map<String, MapDecoration> decorations) {
|
||||
public record DamageResistant(String typesTagKey) {
|
||||
|
||||
public static final Type<MapDecorations> TYPE = new Type<>(MapDecorations.class) {
|
||||
public static final Type<DamageResistant> TYPE = new Type<>(DamageResistant.class) {
|
||||
@Override
|
||||
public MapDecorations read(final ByteBuf buffer) {
|
||||
final Object2ObjectMap<String, MapDecoration> decorations = new Object2ObjectOpenHashMap<>();
|
||||
final int size = Types.VAR_INT.readPrimitive(buffer);
|
||||
for (int i = 0; i < size; i++) {
|
||||
final String id = Types.STRING.read(buffer);
|
||||
final MapDecoration decoration = MapDecoration.TYPE.read(buffer);
|
||||
decorations.put(id, decoration);
|
||||
}
|
||||
return new MapDecorations(decorations);
|
||||
public DamageResistant read(final ByteBuf buffer) {
|
||||
final String typesTagKey = Types.STRING.read(buffer);
|
||||
return new DamageResistant(typesTagKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final MapDecorations value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.decorations.size());
|
||||
for (final Map.Entry<String, MapDecoration> entry : value.decorations.entrySet()) {
|
||||
Types.STRING.write(buffer, entry.getKey());
|
||||
MapDecoration.TYPE.write(buffer, entry.getValue());
|
||||
}
|
||||
public void write(final ByteBuf buffer, final DamageResistant value) {
|
||||
Types.STRING.write(buffer, value.typesTagKey());
|
||||
}
|
||||
};
|
||||
}
|
||||
+9
-12
@@ -22,26 +22,23 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2.ConsumeEffect;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record FoodEffect(PotionEffect effect, float probability) {
|
||||
public record DeathProtection(ConsumeEffect<?>[] deathEffects) {
|
||||
|
||||
public static final Type<FoodEffect> TYPE = new Type<>(FoodEffect.class) {
|
||||
public static final Type<DeathProtection> TYPE = new Type<>(DeathProtection.class) {
|
||||
@Override
|
||||
public FoodEffect read(final ByteBuf buffer) {
|
||||
final PotionEffect effect = PotionEffect.TYPE.read(buffer);
|
||||
final float probability = buffer.readFloat();
|
||||
return new FoodEffect(effect, probability);
|
||||
public DeathProtection read(final ByteBuf buffer) {
|
||||
final ConsumeEffect<?>[] deathEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
|
||||
return new DeathProtection(deathEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodEffect value) {
|
||||
PotionEffect.TYPE.write(buffer, value.effect);
|
||||
buffer.writeFloat(value.probability);
|
||||
public void write(final ByteBuf buffer, final DeathProtection value) {
|
||||
ConsumeEffect.ARRAY_TYPE.write(buffer, value.deathEffects);
|
||||
}
|
||||
};
|
||||
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Nullable String model,
|
||||
@Nullable String cameraOverlay, @Nullable HolderSet allowedEntities, boolean dispensable,
|
||||
boolean swappable, boolean damageOnHurt) {
|
||||
|
||||
public static final Type<Equippable> TYPE = new Type<>(Equippable.class) {
|
||||
@Override
|
||||
public Equippable read(final ByteBuf buffer) {
|
||||
final int equipmentSlot = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
|
||||
final String model = Types.OPTIONAL_STRING.read(buffer);
|
||||
final String cameraOverlay = Types.OPTIONAL_STRING.read(buffer);
|
||||
final HolderSet allowedEntities = Types.OPTIONAL_HOLDER_SET.read(buffer);
|
||||
final boolean dispensable = buffer.readBoolean();
|
||||
final boolean swappable = buffer.readBoolean();
|
||||
final boolean damageOnHurt = buffer.readBoolean();
|
||||
return new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Equippable value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.equipmentSlot());
|
||||
Types.SOUND_EVENT.write(buffer, value.soundEvent());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.model());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.cameraOverlay());
|
||||
Types.OPTIONAL_HOLDER_SET.write(buffer, value.allowedEntities());
|
||||
buffer.writeBoolean(value.dispensable());
|
||||
buffer.writeBoolean(value.swappable());
|
||||
buffer.writeBoolean(value.damageOnHurt());
|
||||
}
|
||||
};
|
||||
|
||||
public Equippable rewrite(final Int2IntFunction soundIdRewriter) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriter);
|
||||
return soundEvent == this.soundEvent ? this : new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
|
||||
}
|
||||
}
|
||||
+31
-10
@@ -25,25 +25,27 @@ package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record FoodProperties(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
|
||||
Item usingConvertsTo, FoodEffect[] possibleEffects) {
|
||||
public record FoodProperties1_20_5(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
|
||||
@Nullable Item usingConvertsTo, FoodEffect[] possibleEffects) {
|
||||
|
||||
public static final Type<FoodProperties> TYPE1_20_5 = new Type<>(FoodProperties.class) {
|
||||
public static final Type<FoodProperties1_20_5> TYPE1_20_5 = new Type<>(FoodProperties1_20_5.class) {
|
||||
@Override
|
||||
public FoodProperties read(final ByteBuf buffer) {
|
||||
public FoodProperties1_20_5 read(final ByteBuf buffer) {
|
||||
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float saturationModifier = buffer.readFloat();
|
||||
final boolean canAlwaysEat = buffer.readBoolean();
|
||||
final float eatSeconds = buffer.readFloat();
|
||||
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer);
|
||||
return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, null, possibleEffects);
|
||||
return new FoodProperties1_20_5(nutrition, saturationModifier, canAlwaysEat, eatSeconds, null, possibleEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodProperties value) {
|
||||
public void write(final ByteBuf buffer, final FoodProperties1_20_5 value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
|
||||
buffer.writeFloat(value.saturationModifier);
|
||||
buffer.writeBoolean(value.canAlwaysEat);
|
||||
@@ -51,20 +53,20 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
|
||||
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
|
||||
}
|
||||
};
|
||||
public static final Type<FoodProperties> TYPE1_21 = new Type<FoodProperties>(FoodProperties.class) {
|
||||
public static final Type<FoodProperties1_20_5> TYPE1_21 = new Type<>(FoodProperties1_20_5.class) {
|
||||
@Override
|
||||
public FoodProperties read(final ByteBuf buffer) {
|
||||
public FoodProperties1_20_5 read(final ByteBuf buffer) {
|
||||
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float saturationModifier = buffer.readFloat();
|
||||
final boolean canAlwaysEat = buffer.readBoolean();
|
||||
final float eatSeconds = buffer.readFloat();
|
||||
final Item usingConvertsTo = Types1_21.OPTIONAL_ITEM.read(buffer);
|
||||
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer);
|
||||
return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, usingConvertsTo, possibleEffects);
|
||||
return new FoodProperties1_20_5(nutrition, saturationModifier, canAlwaysEat, eatSeconds, usingConvertsTo, possibleEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodProperties value) {
|
||||
public void write(final ByteBuf buffer, final FoodProperties1_20_5 value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
|
||||
buffer.writeFloat(value.saturationModifier);
|
||||
buffer.writeBoolean(value.canAlwaysEat);
|
||||
@@ -73,4 +75,23 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
|
||||
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
|
||||
}
|
||||
};
|
||||
|
||||
public record FoodEffect(PotionEffect effect, float probability) {
|
||||
|
||||
public static final Type<FoodEffect> TYPE = new Type<>(FoodEffect.class) {
|
||||
@Override
|
||||
public FoodEffect read(final ByteBuf buffer) {
|
||||
final PotionEffect effect = PotionEffect.TYPE.read(buffer);
|
||||
final float probability = buffer.readFloat();
|
||||
return new FoodEffect(effect, probability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodEffect value) {
|
||||
PotionEffect.TYPE.write(buffer, value.effect);
|
||||
buffer.writeFloat(value.probability);
|
||||
}
|
||||
};
|
||||
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record FoodProperties1_21_2(int nutrition, float saturationModifier, boolean canAlwaysEat) {
|
||||
|
||||
public static final Type<FoodProperties1_21_2> TYPE = new Type<>(FoodProperties1_21_2.class) {
|
||||
@Override
|
||||
public FoodProperties1_21_2 read(final ByteBuf buffer) {
|
||||
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float saturationModifier = buffer.readFloat();
|
||||
final boolean canAlwaysEat = buffer.readBoolean();
|
||||
return new FoodProperties1_21_2(nutrition, saturationModifier, canAlwaysEat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodProperties1_21_2 value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
|
||||
buffer.writeFloat(value.saturationModifier);
|
||||
buffer.writeBoolean(value.canAlwaysEat);
|
||||
}
|
||||
};
|
||||
}
|
||||
+12
-7
@@ -27,24 +27,29 @@ import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record Instrument(Holder<SoundEvent> soundEvent, int useDuration, float range) {
|
||||
public record Instrument1_20_5(Holder<SoundEvent> soundEvent, int useDuration, float range) {
|
||||
|
||||
public static final HolderType<Instrument> TYPE = new HolderType<>() {
|
||||
public static final HolderType<Instrument1_20_5> TYPE = new HolderType<>() {
|
||||
@Override
|
||||
public Instrument readDirect(final ByteBuf buffer) {
|
||||
public Instrument1_20_5 readDirect(final ByteBuf buffer) {
|
||||
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
|
||||
final int useDuration = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float range = buffer.readFloat();
|
||||
return new Instrument(soundEvent, useDuration, range);
|
||||
final float range = Types.FLOAT.readPrimitive(buffer);
|
||||
return new Instrument1_20_5(soundEvent, useDuration, range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final Instrument value) {
|
||||
public void writeDirect(final ByteBuf buffer, final Instrument1_20_5 value) {
|
||||
Types.SOUND_EVENT.write(buffer, value.soundEvent());
|
||||
Types.VAR_INT.writePrimitive(buffer, value.useDuration());
|
||||
buffer.writeFloat(value.range());
|
||||
Types.FLOAT.writePrimitive(buffer, value.range());
|
||||
}
|
||||
};
|
||||
|
||||
public Instrument1_20_5 rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
|
||||
return soundEvent == this.soundEvent ? this : new Instrument1_20_5(soundEvent, useDuration, range);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration, float range, Tag description) {
|
||||
|
||||
public static final HolderType<Instrument1_21_2> TYPE = new HolderType<>() {
|
||||
@Override
|
||||
public Instrument1_21_2 readDirect(final ByteBuf buffer) {
|
||||
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
|
||||
final float useDuration = Types.FLOAT.readPrimitive(buffer);
|
||||
final float range = Types.FLOAT.readPrimitive(buffer);
|
||||
final Tag description = Types.TAG.read(buffer);
|
||||
return new Instrument1_21_2(soundEvent, useDuration, range, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final Instrument1_21_2 value) {
|
||||
Types.SOUND_EVENT.write(buffer, value.soundEvent());
|
||||
Types.FLOAT.writePrimitive(buffer, value.useDuration());
|
||||
Types.FLOAT.writePrimitive(buffer, value.range());
|
||||
Types.TAG.write(buffer, value.description());
|
||||
}
|
||||
};
|
||||
|
||||
public Instrument1_21_2 rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
|
||||
return soundEvent == this.soundEvent ? this : new Instrument1_21_2(soundEvent, useDuration, range, description);
|
||||
}
|
||||
}
|
||||
+20
@@ -30,6 +30,7 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import com.viaversion.viaversion.util.Either;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record JukeboxPlayable(Either<Holder<JukeboxSong>, String> song, boolean showInTooltip) {
|
||||
|
||||
@@ -56,6 +57,20 @@ public record JukeboxPlayable(Either<Holder<JukeboxSong>, String> song, boolean
|
||||
}
|
||||
};
|
||||
|
||||
public JukeboxPlayable rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
if (song.isRight()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final Holder<JukeboxSong> songHolder = this.song.left();
|
||||
if (songHolder.hasId()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final JukeboxSong rewrittenSong = songHolder.value().rewrite(soundIdRewriteFunction);
|
||||
return rewrittenSong == songHolder.value() ? this : new JukeboxPlayable(Holder.of(rewrittenSong), showInTooltip);
|
||||
}
|
||||
|
||||
public record JukeboxSong(Holder<SoundEvent> soundEvent, Tag description,
|
||||
float lengthInSeconds, int comparatorOutput) {
|
||||
|
||||
@@ -77,5 +92,10 @@ public record JukeboxPlayable(Either<Holder<JukeboxSong>, String> song, boolean
|
||||
Types.VAR_INT.writePrimitive(buffer, value.comparatorOutput);
|
||||
}
|
||||
};
|
||||
|
||||
public JukeboxSong rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
|
||||
return soundEvent == this.soundEvent ? this : new JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
-3
@@ -27,15 +27,20 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects) {
|
||||
public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects,
|
||||
@Nullable String customName) {
|
||||
|
||||
public static final Type<PotionContents> TYPE = new Type<>(PotionContents.class) {
|
||||
public PotionContents(final @Nullable Integer potion, final @Nullable Integer customColor, final PotionEffect[] customEffects) {
|
||||
this(potion, customColor, customEffects, null);
|
||||
}
|
||||
|
||||
public static final Type<PotionContents> TYPE1_20_5 = new Type<>(PotionContents.class) {
|
||||
@Override
|
||||
public PotionContents read(final ByteBuf buffer) {
|
||||
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
|
||||
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
|
||||
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
|
||||
return new PotionContents(potion, customColor, customEffects);
|
||||
return new PotionContents(potion, customColor, customEffects, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,4 +58,31 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Type<PotionContents> TYPE1_21_2 = new Type<>(PotionContents.class) {
|
||||
@Override
|
||||
public PotionContents read(final ByteBuf buffer) {
|
||||
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
|
||||
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
|
||||
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
|
||||
final String customName = Types.OPTIONAL_STRING.read(buffer);
|
||||
return new PotionContents(potion, customColor, customEffects, customName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final PotionContents value) {
|
||||
buffer.writeBoolean(value.potion != null);
|
||||
if (value.potion != null) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.potion);
|
||||
}
|
||||
|
||||
buffer.writeBoolean(value.customColor != null);
|
||||
if (value.customColor != null) {
|
||||
buffer.writeInt(value.customColor);
|
||||
}
|
||||
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
|
||||
Types.OPTIONAL_STRING.write(buffer, value.customName);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.function.Function;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record UseCooldown(float seconds, @Nullable String cooldownGroup) {
|
||||
|
||||
public static final Type<UseCooldown> TYPE = new Type<>(UseCooldown.class) {
|
||||
@Override
|
||||
public UseCooldown read(final ByteBuf buffer) {
|
||||
final float seconds = buffer.readFloat();
|
||||
final String cooldownGroup = Types.OPTIONAL_STRING.read(buffer);
|
||||
return new UseCooldown(seconds, cooldownGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final UseCooldown value) {
|
||||
buffer.writeFloat(value.seconds());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.cooldownGroup());
|
||||
}
|
||||
};
|
||||
|
||||
public UseCooldown rewrite(final Function<String, String> idRewriter) {
|
||||
if (cooldownGroup == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final String mappedCooldownGroup = idRewriter.apply(cooldownGroup);
|
||||
return new UseCooldown(seconds, mappedCooldownGroup);
|
||||
}
|
||||
}
|
||||
@@ -215,4 +215,13 @@ public interface ViaPlatform<T> {
|
||||
* @return whether the platform has a plugin/mod with the given name
|
||||
*/
|
||||
boolean hasPlugin(String name);
|
||||
|
||||
/**
|
||||
* Returns whether the platform might be reloading.
|
||||
*
|
||||
* @return whether the platform might be reloading
|
||||
*/
|
||||
default boolean couldBeReloading() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -30,4 +30,9 @@ public interface ViaServerProxyPlatform<T> extends ViaPlatform<T> {
|
||||
* @return protocol detector service
|
||||
*/
|
||||
ProtocolDetectorService protocolDetectorService();
|
||||
|
||||
@Override
|
||||
default boolean couldBeReloading() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -198,6 +198,14 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
}
|
||||
}
|
||||
|
||||
public void registerFinishConfiguration(final CU packetType, final PacketHandler handler) {
|
||||
registerClientbound(packetType, wrapper -> {
|
||||
// TODO Temporary solution to handle the finish configuration packet already having changed our tracked protocol state in a previous handler
|
||||
wrapper.user().getProtocolInfo().setServerState(State.CONFIGURATION);
|
||||
handler.handle(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void loadMappingData() {
|
||||
getMappingData().load();
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
||||
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.exception.CancelException;
|
||||
@@ -374,6 +375,15 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the protocol's particle rewriter if present.
|
||||
*
|
||||
* @return particle rewriter
|
||||
*/
|
||||
default @Nullable ParticleRewriter getParticleRewriter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the protocol's tag rewriter if present.
|
||||
*
|
||||
|
||||
@@ -25,6 +25,7 @@ package com.viaversion.viaversion.api.protocol;
|
||||
import com.google.common.collect.Range;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.Direction;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
@@ -73,13 +74,14 @@ public interface ProtocolManager {
|
||||
Protocol getBaseProtocol();
|
||||
|
||||
/**
|
||||
* Returns the base protocol for a specific server protocol version.
|
||||
* Returns the base protocols for a specific server and client protocol version.
|
||||
* The standard base protocols deal with status and login packets for userconnection initialization.
|
||||
*
|
||||
* @param clientVersion client protocol version
|
||||
* @param serverVersion server protocol version
|
||||
* @return base protocol for the given server protocol version if present, else null
|
||||
* @return base protocols for the given server and client protocol version
|
||||
*/
|
||||
@Nullable Protocol getBaseProtocol(ProtocolVersion serverVersion);
|
||||
List<Protocol> getBaseProtocols(@Nullable ProtocolVersion clientVersion, @Nullable ProtocolVersion serverVersion);
|
||||
|
||||
/**
|
||||
* Returns an immutable collection of registered protocols.
|
||||
@@ -120,11 +122,12 @@ public interface ProtocolManager {
|
||||
* Registers and initializes a base protocol. Base Protocols registered later have higher priority.
|
||||
* Only base protocol will always be added to pipeline.
|
||||
*
|
||||
* @param direction direction of the base protocol
|
||||
* @param baseProtocol base protocol to register
|
||||
* @param supportedProtocols protocol versions supported by the base protocol
|
||||
* @throws IllegalArgumentException if the protocol is not a base protocol as given by {@link Protocol#isBaseProtocol()}
|
||||
*/
|
||||
void registerBaseProtocol(Protocol baseProtocol, Range<ProtocolVersion> supportedProtocols);
|
||||
void registerBaseProtocol(Direction direction, Protocol baseProtocol, Range<ProtocolVersion> supportedProtocols);
|
||||
|
||||
/**
|
||||
* Calculates and returns the protocol path from a client protocol version to server protocol version.
|
||||
|
||||
@@ -145,6 +145,18 @@ public interface PacketWrapper {
|
||||
*/
|
||||
<T> T passthrough(Type<T> type) throws InformativeException;
|
||||
|
||||
/**
|
||||
* Take a value from the input and write to the output, mapping the output type.
|
||||
* This only works for types implementing {@link com.viaversion.viaversion.api.type.TypeConverter}, which is generally only the primitive wrapper types.
|
||||
*
|
||||
* @param type The type to read.
|
||||
* @param mappedType The type to write.
|
||||
* @param <T> The return type of the type you wish to pass through.
|
||||
* @return The type which was read/written.
|
||||
* @throws InformativeException If it failed to read or write
|
||||
*/
|
||||
<T> T passthroughAndMap(Type<?> type, Type<T> mappedType) throws InformativeException;
|
||||
|
||||
/**
|
||||
* Take all the inputs and write them to the output.
|
||||
*
|
||||
@@ -224,6 +236,14 @@ public interface PacketWrapper {
|
||||
*/
|
||||
void sendRaw() throws InformativeException;
|
||||
|
||||
/**
|
||||
* Sends this packet to the associated user, submitted to netty's event loop.
|
||||
* <b>Unlike {@link #sendFuture(Class)}, this method does not handle the pipeline with packet id and data changes.</b>
|
||||
*
|
||||
* @throws InformativeException if it fails to write
|
||||
*/
|
||||
ChannelFuture sendFutureRaw() throws InformativeException;
|
||||
|
||||
/**
|
||||
* Sends this packet to the associated user, submitted to netty's event loop.
|
||||
* <b>Unlike {@link #send(Class)}, this method does not handle the pipeline with packet id and data changes.</b>
|
||||
|
||||
+3
-3
@@ -54,7 +54,7 @@ public abstract class PacketHandlers implements PacketHandler {
|
||||
* @param type type to map
|
||||
*/
|
||||
public <T> void map(Type<T> type) {
|
||||
handler(wrapper -> wrapper.write(type, wrapper.read(type)));
|
||||
handler(wrapper -> wrapper.passthrough(type));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,8 +63,8 @@ public abstract class PacketHandlers implements PacketHandler {
|
||||
* @param oldType old type
|
||||
* @param newType new type
|
||||
*/
|
||||
public void map(Type oldType, Type newType) {
|
||||
handler(wrapper -> wrapper.write(newType, wrapper.read(oldType)));
|
||||
public void map(Type<?> oldType, Type<?> newType) {
|
||||
handler(wrapper -> wrapper.passthroughAndMap(oldType, newType));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-6
@@ -43,7 +43,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>();
|
||||
|
||||
public static final ProtocolVersion v1_7_2 = register(4, "1.7.2-1.7.5", new SubVersionRange("1.7", 2, 5));
|
||||
@Deprecated(forRemoval=true) public static final ProtocolVersion v1_7_1 = v1_7_2;
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final ProtocolVersion v1_7_1 = v1_7_2;
|
||||
public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new SubVersionRange("1.7", 6, 10));
|
||||
public static final ProtocolVersion v1_8 = register(47, "1.8.x", new SubVersionRange("1.8", 0, 9));
|
||||
public static final ProtocolVersion v1_9 = register(107, "1.9");
|
||||
@@ -84,9 +85,15 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
public static final ProtocolVersion v1_20_2 = register(764, "1.20.2");
|
||||
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4));
|
||||
public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6));
|
||||
public static final ProtocolVersion v1_21 = register(767, "1.21");
|
||||
public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1));
|
||||
public static final ProtocolVersion v1_21_2 = register(768, "1.21.2-1.21.3", new SubVersionRange("1.21", 2, 3));
|
||||
public static final ProtocolVersion v1_21_4 = register(769, "1.21.4");
|
||||
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
|
||||
|
||||
static {
|
||||
unknown.known = false;
|
||||
}
|
||||
|
||||
public static ProtocolVersion register(int version, String name) {
|
||||
return register(version, -1, name);
|
||||
}
|
||||
@@ -150,7 +157,11 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
return protocolVersion;
|
||||
}
|
||||
}
|
||||
return new ProtocolVersion(VersionType.SPECIAL, version, -1, "Unknown (" + version + ")", null);
|
||||
|
||||
// Will be made nullable instead in the future...
|
||||
final ProtocolVersion unknown = new ProtocolVersion(versionType, version, -1, "Unknown (" + version + ")", null);
|
||||
unknown.known = false;
|
||||
return unknown;
|
||||
}
|
||||
|
||||
public static @NonNull ProtocolVersion getProtocol(final int version) {
|
||||
@@ -201,6 +212,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
private final int snapshotVersion;
|
||||
private final String name;
|
||||
private final Set<String> includedVersions;
|
||||
@Deprecated // Remove when getProtocol is made nullable
|
||||
private boolean known = true;
|
||||
|
||||
/**
|
||||
* Constructs a new ProtocolVersion instance.
|
||||
@@ -285,12 +298,12 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the protocol is set. Should only be unknown for unregistered protocols returned by {@link #getProtocol(int)}.
|
||||
* Returns whether the protocol version is {@link #unknown}. For checking if the protocol version is registered, use {@link #isRegistered(VersionType, int)}
|
||||
*
|
||||
* @return true if the protocol is set
|
||||
* @return true if the protocol version is unknown
|
||||
*/
|
||||
public boolean isKnown() {
|
||||
return version != -1;
|
||||
return known;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-1
@@ -104,7 +104,10 @@ public class ProtocolVersionRange {
|
||||
*/
|
||||
public boolean contains(final ProtocolVersion version) {
|
||||
if (this.ranges == null) return true;
|
||||
return this.ranges.stream().anyMatch(range -> range.contains(version));
|
||||
for (Range<ProtocolVersion> range : this.ranges) {
|
||||
if (range.contains(version)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,6 +28,31 @@ import com.viaversion.viaversion.api.platform.providers.Provider;
|
||||
@FunctionalInterface
|
||||
public interface VersionProvider extends Provider {
|
||||
|
||||
/**
|
||||
* Optionally allows platforms to specify the client version of a user. This is needed when the platform supports
|
||||
* connecting other version types then {@link VersionType#RELEASE} to the server.
|
||||
*
|
||||
* @param connection connection
|
||||
* @return client protocol version, or null if handshake packet should be used
|
||||
*/
|
||||
default ProtocolVersion getClientProtocol(UserConnection connection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #getClosestServerProtocol(UserConnection)} and catches any exceptions by returning null.
|
||||
*
|
||||
* @param connection connection
|
||||
* @return closest server protocol version to the user's protocol version
|
||||
*/
|
||||
default ProtocolVersion getServerProtocol(UserConnection connection) {
|
||||
try {
|
||||
return getClosestServerProtocol(connection);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closest server protocol version to the user's protocol version.
|
||||
* On non-proxy servers, this returns the actual server version.
|
||||
|
||||
@@ -59,13 +59,21 @@ public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter
|
||||
int newEntityId(int id);
|
||||
|
||||
/**
|
||||
* Handles and transforms metadata of an entity.
|
||||
* Returns the mapped entity (or the same if it has not changed).
|
||||
*
|
||||
* @param identifier unmapped entity identifier
|
||||
* @return mapped entity identifier
|
||||
*/
|
||||
String mappedEntityIdentifier(String identifier);
|
||||
|
||||
/**
|
||||
* Handles and transforms entity data of an entity.
|
||||
*
|
||||
* @param entityId entity id
|
||||
* @param metadataList full, mutable list of metadata
|
||||
* @param dataList full, mutable list of entity data
|
||||
* @param connection user connection
|
||||
*/
|
||||
void handleEntityData(int entityId, List<EntityData> metadataList, UserConnection connection);
|
||||
void handleEntityData(int entityId, List<EntityData> dataList, UserConnection connection);
|
||||
|
||||
/**
|
||||
* Returns the entity tracker for the current protocol.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
|
||||
public interface ParticleRewriter {
|
||||
|
||||
void rewriteParticle(UserConnection connection, Particle particle);
|
||||
|
||||
}
|
||||
@@ -45,12 +45,14 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
||||
import com.viaversion.viaversion.api.minecraft.ChunkPosition;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.BitSetType;
|
||||
import com.viaversion.viaversion.api.type.types.BooleanArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.BooleanType;
|
||||
import com.viaversion.viaversion.api.type.types.ByteArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.ByteType;
|
||||
import com.viaversion.viaversion.api.type.types.ComponentType;
|
||||
import com.viaversion.viaversion.api.type.types.DoubleType;
|
||||
import com.viaversion.viaversion.api.type.types.EmptyType;
|
||||
import com.viaversion.viaversion.api.type.types.FloatArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.FloatType;
|
||||
import com.viaversion.viaversion.api.type.types.IntArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.IntType;
|
||||
@@ -115,14 +117,17 @@ public final class Types {
|
||||
public static final Type<byte[]> OPTIONAL_BYTE_ARRAY_PRIMITIVE = new ByteArrayType.OptionalByteArrayType();
|
||||
public static final Type<byte[]> SHORT_BYTE_ARRAY = new ShortByteArrayType();
|
||||
public static final Type<byte[]> REMAINING_BYTES = new RemainingBytesType();
|
||||
public static final Type<int[]> INT_ARRAY_PRIMITIVE = new IntArrayType();
|
||||
|
||||
public static final ShortType SHORT = new ShortType();
|
||||
public static final UnsignedShortType UNSIGNED_SHORT = new UnsignedShortType();
|
||||
|
||||
public static final IntType INT = new IntType();
|
||||
public static final Type<int[]> INT_ARRAY_PRIMITIVE = new IntArrayType();
|
||||
|
||||
public static final FloatType FLOAT = new FloatType();
|
||||
public static final FloatType.OptionalFloatType OPTIONAL_FLOAT = new FloatType.OptionalFloatType();
|
||||
public static final Type<float[]> FLOAT_ARRAY_PRIMITIVE = new FloatArrayType();
|
||||
|
||||
public static final DoubleType DOUBLE = new DoubleType();
|
||||
|
||||
public static final LongType LONG = new LongType();
|
||||
@@ -130,6 +135,7 @@ public final class Types {
|
||||
|
||||
public static final BooleanType BOOLEAN = new BooleanType();
|
||||
public static final BooleanType.OptionalBooleanType OPTIONAL_BOOLEAN = new BooleanType.OptionalBooleanType();
|
||||
public static final Type<boolean[]> BOOLEAN_ARRAY_PRIMITIVE = new BooleanArrayType();
|
||||
|
||||
/* Other Types */
|
||||
public static final Type<JsonElement> COMPONENT = new ComponentType();
|
||||
@@ -149,6 +155,8 @@ public final class Types {
|
||||
public static final VarLongType VAR_LONG = new VarLongType();
|
||||
|
||||
/* MC Types */
|
||||
public static final Type<byte[]> SERVERBOUND_CUSTOM_PAYLOAD_DATA = new RemainingBytesType(Short.MAX_VALUE);
|
||||
|
||||
public static final Type<BlockPosition> BLOCK_POSITION1_8 = new BlockPositionType1_8();
|
||||
public static final Type<BlockPosition> OPTIONAL_POSITION1_8 = new BlockPositionType1_8.OptionalBlockPositionType();
|
||||
public static final Type<BlockPosition> BLOCK_POSITION1_14 = new BlockPositionType1_14();
|
||||
@@ -189,7 +197,10 @@ public final class Types {
|
||||
public static final Type<PlayerMessageSignature> OPTIONAL_PLAYER_MESSAGE_SIGNATURE = new PlayerMessageSignatureType.OptionalPlayerMessageSignatureType();
|
||||
public static final Type<PlayerMessageSignature[]> PLAYER_MESSAGE_SIGNATURE_ARRAY = new ArrayType<>(PLAYER_MESSAGE_SIGNATURE);
|
||||
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM = new BitSetType(6);
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM1_19_3 = new BitSetType(6);
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM1_21_2 = new BitSetType(7);
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM1_21_4 = new BitSetType(8);
|
||||
|
||||
public static final ByteArrayType SIGNATURE_BYTES = new ByteArrayType(256);
|
||||
public static final BitSetType ACKNOWLEDGED_BIT_SET = new BitSetType(20);
|
||||
public static final ByteArrayType.OptionalByteArrayType OPTIONAL_SIGNATURE_BYTES = new ByteArrayType.OptionalByteArrayType(256);
|
||||
|
||||
@@ -26,13 +26,22 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayType<T> extends Type<T[]> {
|
||||
private final Type<T> elementType;
|
||||
private final int maxLength;
|
||||
|
||||
public ArrayType(Type<T> type) {
|
||||
this(type, -1);
|
||||
}
|
||||
|
||||
public ArrayType(Type<T> type, int maxLength) {
|
||||
//noinspection unchecked
|
||||
super(type.getTypeName() + " Array", (Class<T[]>) getArrayClass(type.getOutputClass()));
|
||||
this.elementType = type;
|
||||
this.maxLength = maxLength;
|
||||
}
|
||||
|
||||
public static Class<?> getArrayClass(Class<?> componentType) {
|
||||
@@ -43,16 +52,40 @@ public class ArrayType<T> extends Type<T[]> {
|
||||
@Override
|
||||
public T[] read(ByteBuf buffer) {
|
||||
int amount = Types.VAR_INT.readPrimitive(buffer);
|
||||
T[] array = (T[]) Array.newInstance(elementType.getOutputClass(), amount);
|
||||
if (maxLength != -1 && amount > maxLength) {
|
||||
throw new IllegalArgumentException("Array length " + amount + " is longer than maximum " + maxLength);
|
||||
}
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
return amount < Short.MAX_VALUE ? readArray(buffer, amount) : readList(buffer, amount);
|
||||
}
|
||||
|
||||
private T[] readArray(ByteBuf buffer, int length) {
|
||||
T[] array = createArray(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = elementType.read(buffer);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private T[] readList(ByteBuf buffer, int length) {
|
||||
List<T> list = new ArrayList<>();
|
||||
for (int i = 0; i < length; i++) {
|
||||
list.add(elementType.read(buffer));
|
||||
}
|
||||
return list.toArray(createArray(0));
|
||||
}
|
||||
|
||||
private T[] createArray(int length) {
|
||||
//noinspection unchecked
|
||||
return (T[]) Array.newInstance(elementType.getOutputClass(), length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, T[] object) {
|
||||
if (maxLength != -1 && object.length > maxLength) {
|
||||
throw new IllegalArgumentException("Array length " + object.length + " is longer than maximum " + maxLength);
|
||||
}
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, object.length);
|
||||
for (T o : object) {
|
||||
elementType.write(buffer, o);
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
// Ok...
|
||||
public class BooleanArrayType extends Type<boolean[]> {
|
||||
|
||||
private final int length;
|
||||
|
||||
public BooleanArrayType(final int length) {
|
||||
super(boolean[].class);
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public BooleanArrayType() {
|
||||
super(boolean[].class);
|
||||
this.length = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final boolean[] object) {
|
||||
if (this.length != -1) {
|
||||
Preconditions.checkArgument(length == object.length, "Length does not match expected length");
|
||||
} else {
|
||||
Types.VAR_INT.writePrimitive(buffer, object.length);
|
||||
}
|
||||
for (final boolean b : object) {
|
||||
buffer.writeBoolean(b);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
final boolean[] array = new boolean[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = buffer.readBoolean();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,9 @@ public class ComponentType extends Type<JsonElement> {
|
||||
try {
|
||||
return JsonParser.parseString(s);
|
||||
} catch (JsonSyntaxException e) {
|
||||
Via.getPlatform().getLogger().severe("Error when trying to parse json: " + s);
|
||||
if (Via.getManager().isDebug()) {
|
||||
Via.getPlatform().getLogger().severe("Error when trying to parse json: " + s);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class FloatArrayType extends Type<float[]> {
|
||||
|
||||
private final int length;
|
||||
|
||||
public FloatArrayType(final int length) {
|
||||
super(float[].class);
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public FloatArrayType() {
|
||||
super(float[].class);
|
||||
this.length = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final float[] object) {
|
||||
if (this.length != -1) {
|
||||
Preconditions.checkArgument(length == object.length, "Length does not match expected length");
|
||||
} else {
|
||||
Types.VAR_INT.writePrimitive(buffer, object.length);
|
||||
}
|
||||
for (final float f : object) {
|
||||
buffer.writeFloat(f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
final float[] array = new float[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = buffer.readFloat();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,19 @@ public class IntType extends Type<Integer> implements TypeConverter<Integer> {
|
||||
return buffer.readInt();
|
||||
}
|
||||
|
||||
public int readPrimitive(ByteBuf buffer) {
|
||||
return buffer.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Integer object) {
|
||||
buffer.writeInt(object);
|
||||
}
|
||||
|
||||
public void writePrimitive(ByteBuf buffer, int object) {
|
||||
buffer.writeInt(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer from(Object o) {
|
||||
if (o instanceof Number number) {
|
||||
|
||||
@@ -26,19 +26,35 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class RemainingBytesType extends Type<byte[]> {
|
||||
private final int maxLength;
|
||||
|
||||
public RemainingBytesType() {
|
||||
this(-1);
|
||||
}
|
||||
|
||||
public RemainingBytesType(final int maxLength) {
|
||||
super(byte[].class);
|
||||
this.maxLength = maxLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(ByteBuf buffer) {
|
||||
byte[] array = new byte[buffer.readableBytes()];
|
||||
public byte[] read(final ByteBuf buffer) {
|
||||
final int bytes = buffer.readableBytes();
|
||||
if (maxLength != -1 && bytes > maxLength) {
|
||||
throw new RuntimeException("Remaining bytes cannot be longer than " + maxLength + " (got " + bytes + ")");
|
||||
}
|
||||
|
||||
final byte[] array = new byte[bytes];
|
||||
buffer.readBytes(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, byte[] object) {
|
||||
public void write(final ByteBuf buffer, final byte[] object) {
|
||||
if (maxLength != -1 && object.length > maxLength) {
|
||||
throw new RuntimeException("Remaining bytes cannot be longer than " + maxLength + " (got " + object.length + ")");
|
||||
}
|
||||
|
||||
buffer.writeBytes(object);
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,15 @@ public class VarIntType extends Type<Integer> implements TypeConverter<Integer>
|
||||
private static final int VALUE_BITS = 0x7F;
|
||||
private static final int MULTI_BYTE_BITS = ~VALUE_BITS;
|
||||
private static final int MAX_BYTES = 5;
|
||||
private static final int[] VAR_INT_LENGTHS = new int[65];
|
||||
|
||||
static {
|
||||
// Copied from Velocity https://github.com/PaperMC/Velocity/blob/08a42b3723633ea5eb6b96c0bb42180f3c2b07eb/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java#L166
|
||||
for (int i = 0; i <= 32; ++i) {
|
||||
VAR_INT_LENGTHS[i] = (int) Math.ceil((31d - (i - 1)) / 7d);
|
||||
}
|
||||
VAR_INT_LENGTHS[32] = 1; // Special case for the number 0.
|
||||
}
|
||||
|
||||
public VarIntType() {
|
||||
super("VarInt", Integer.class);
|
||||
@@ -88,4 +97,8 @@ public class VarIntType extends Type<Integer> implements TypeConverter<Integer>
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static int varIntLength(final int value) {
|
||||
return VAR_INT_LENGTHS[Integer.numberOfLeadingZeros(value)];
|
||||
}
|
||||
}
|
||||
+11
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
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.PaletteType;
|
||||
@@ -54,4 +55,14 @@ public final class ChunkSectionType1_18 extends Type<ChunkSection> {
|
||||
blockPaletteType.write(buffer, section.palette(PaletteType.BLOCKS));
|
||||
biomePaletteType.write(buffer, section.palette(PaletteType.BIOMES));
|
||||
}
|
||||
|
||||
public int serializedSize(final Chunk chunk) {
|
||||
int length = 0;
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
length += Short.BYTES
|
||||
+ blockPaletteType.serializedSize(section.palette(PaletteType.BLOCKS))
|
||||
+ biomePaletteType.serializedSize(section.palette(PaletteType.BIOMES));
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
+6
-17
@@ -52,14 +52,10 @@ public final class ChunkType1_18 extends Type<Chunk> {
|
||||
final CompoundTag heightMap = Types.NAMED_COMPOUND_TAG.read(buffer);
|
||||
|
||||
// Read sections
|
||||
final ByteBuf sectionsBuf = buffer.readBytes(Types.VAR_INT.readPrimitive(buffer));
|
||||
final ByteBuf sectionsBuf = buffer.readSlice(Types.VAR_INT.readPrimitive(buffer));
|
||||
final ChunkSection[] sections = new ChunkSection[ySectionCount];
|
||||
try {
|
||||
for (int i = 0; i < ySectionCount; i++) {
|
||||
sections[i] = sectionType.read(sectionsBuf);
|
||||
}
|
||||
} finally {
|
||||
sectionsBuf.release();
|
||||
for (int i = 0; i < ySectionCount; i++) {
|
||||
sections[i] = sectionType.read(sectionsBuf);
|
||||
}
|
||||
|
||||
final int blockEntitiesLength = Types.VAR_INT.readPrimitive(buffer);
|
||||
@@ -78,16 +74,9 @@ public final class ChunkType1_18 extends Type<Chunk> {
|
||||
|
||||
Types.NAMED_COMPOUND_TAG.write(buffer, chunk.getHeightMap());
|
||||
|
||||
final ByteBuf sectionBuffer = buffer.alloc().buffer();
|
||||
try {
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
sectionType.write(sectionBuffer, section);
|
||||
}
|
||||
sectionBuffer.readerIndex(0);
|
||||
Types.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
|
||||
buffer.writeBytes(sectionBuffer);
|
||||
} finally {
|
||||
sectionBuffer.release(); // release buffer
|
||||
Types.VAR_INT.writePrimitive(buffer, sectionType.serializedSize(chunk));
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
sectionType.write(buffer, section);
|
||||
}
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size());
|
||||
|
||||
+6
-17
@@ -52,14 +52,10 @@ public final class ChunkType1_20_2 extends Type<Chunk> {
|
||||
final CompoundTag heightMap = Types.COMPOUND_TAG.read(buffer);
|
||||
|
||||
// Read sections
|
||||
final ByteBuf sectionsBuf = buffer.readBytes(Types.VAR_INT.readPrimitive(buffer));
|
||||
final ByteBuf sectionsBuf = buffer.readSlice(Types.VAR_INT.readPrimitive(buffer));
|
||||
final ChunkSection[] sections = new ChunkSection[ySectionCount];
|
||||
try {
|
||||
for (int i = 0; i < ySectionCount; i++) {
|
||||
sections[i] = sectionType.read(sectionsBuf);
|
||||
}
|
||||
} finally {
|
||||
sectionsBuf.release();
|
||||
for (int i = 0; i < ySectionCount; i++) {
|
||||
sections[i] = sectionType.read(sectionsBuf);
|
||||
}
|
||||
|
||||
final int blockEntitiesLength = Types.VAR_INT.readPrimitive(buffer);
|
||||
@@ -78,16 +74,9 @@ public final class ChunkType1_20_2 extends Type<Chunk> {
|
||||
|
||||
Types.COMPOUND_TAG.write(buffer, chunk.getHeightMap());
|
||||
|
||||
final ByteBuf sectionBuffer = buffer.alloc().buffer();
|
||||
try {
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
sectionType.write(sectionBuffer, section);
|
||||
}
|
||||
sectionBuffer.readerIndex(0);
|
||||
Types.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
|
||||
buffer.writeBytes(sectionBuffer);
|
||||
} finally {
|
||||
sectionBuffer.release(); // release buffer
|
||||
Types.VAR_INT.writePrimitive(buffer, sectionType.serializedSize(chunk));
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
sectionType.write(buffer, section);
|
||||
}
|
||||
|
||||
Types.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size());
|
||||
|
||||
Loaded 100 of 359 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user