Compare commits

...
214 Commits
Author SHA1 Message Date
Nassim Jahnke 1fb3aa8c7a 5.5.1 Release 2025-10-12 18:44:11 +02:00
木葉 Scarlet f175a903a3 Improve some collection usages (#4659) 2025-10-12 18:21:13 +02:00
FlorianMichael 7c80e37e3a Rewrite item ids in 1.12.2->1.13 show_item hover events (#4671) 2025-10-12 18:16:10 +02:00
FlorianMichael ff61e1d897 [ci skip] Update README.md (#4681) 2025-10-12 17:44:30 +02:00
AmirAli Mollaei d49272a41f Fix error when wolf_variant registry data isn't sent in 1.20.5->1.21 (#4655) 2025-10-11 13:01:19 +02:00
Nassim Jahnke bea6df1174 Add april fools snapshot identifiers 2025-10-07 19:44:27 +02:00
Nassim Jahnke 4ca84f6001 Fix <1.13 sounds for VB/VR
Technically unused in VV for now, but may also replace some in-code sound mappings later
2025-10-07 17:42:16 +02:00
Nassim Jahnke 61c079af19 Add 1.21.10 to 1.21.9 version string
No protocol changes
2025-10-07 16:06:55 +02:00
Nassim Jahnke e0b9deb128 Handle repairable item id changes 2025-10-07 15:38:09 +02:00
Nassim Jahnke 1d89bc7f95 Handle deeper lock component changes 2025-10-07 15:23:25 +02:00
dependabot[bot] 28c18c33fa Bump gradle/actions from 4 to 5 (#4678)
Bumps [gradle/actions](https://github.com/gradle/actions) from 4 to 5.
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/v4...v5)

---
updated-dependencies:
- dependency-name: gradle/actions
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 23:37:44 +02:00
Nassim Jahnke d08cb1b743 Handle debug sticks with changed blocks/properties 2025-10-06 20:31:14 +02:00
Nassim Jahnke fb18f69a0b Fix world border scale in 1.21.7->1.21.9 2025-10-05 22:05:44 +02:00
Nassim Jahnke 56e1d32aa0 Implement equippable item data hashing 2025-10-05 21:35:35 +02:00
FlorianMichael d4aa5a2fb3 More fixes to team packet filtering in 1.20.3->1.20.5 (#4674) 2025-10-05 21:23:25 +02:00
Nassim Jahnke b54a87f465 Re-shuffle mapping files to reduce size, include sound identifiers 2025-10-05 15:27:32 +02:00
RK_01 5acfa9faf7 Implement 1.21.7 -> 1.21.9 debug sample subscription translation (#4668) 2025-10-05 08:48:42 +02:00
LeonTG 638f4cd19a Fix player team tracking in 1.20.3->1.20.5 packet filtering (#4673) 2025-10-05 03:41:41 +02:00
Nassim Jahnke baf12dd516 Handle particles in biome effects
Fixes #4666
2025-10-04 10:36:17 +02:00
Nassim Jahnke 4b6b26fbba Allow empty block entity mappings in item data 2025-10-03 20:02:06 +02:00
Nassim Jahnke 5c5784795d Bump version to 5.5.1-SNAPSHOT 2025-10-03 20:01:35 +02:00
Nassim Jahnke 1f8e7515b1 5.5.0 Release 2025-10-03 13:46:23 +02:00
Nassim Jahnke 3778698018 Fix resolvable profile type order 2025-10-03 13:46:23 +02:00
Nassim Jahnke 40dd2be139 Prepare for the release later 2025-10-03 13:46:23 +02:00
FlorianMichael edbe2c92ce Add entity identifier when downgrading entity data components 2025-10-03 13:46:23 +02:00
Nassim Jahnke b9ae1ef43e Handle unknown block entity/entity types 2025-10-03 13:46:23 +02:00
Nassim Jahnke 4631fd1977 Remove unhandled compound tag entity data from bad packets 2025-10-03 13:46:22 +02:00
Nassim Jahnke 3d25686745 Handle key changes in item_model 2025-10-03 13:46:22 +02:00
Nassim Jahnke 18b5b2626a Remove snapshot bit 2025-10-03 13:46:22 +02:00
Nassim Jahnke 219ad4737a 1.21.9-rc1 2025-10-03 13:46:22 +02:00
riku6460 b9368ae80a Fix lighting in the end dimension in 1.21.7->1.21.9 2025-10-03 13:46:22 +02:00
Nassim Jahnke 03c80ccff8 1.21.9-pre4 2025-10-03 13:46:22 +02:00
Nassim Jahnke f6aed5578f 1.21.9-pre3 2025-10-03 13:46:21 +02:00
Nassim Jahnke 646de0b1af Handle changed bees data 2025-10-03 13:46:21 +02:00
Nassim Jahnke 4e33a40ede 1.21.9-pre2 2025-10-03 13:46:21 +02:00
Nassim Jahnke 21b0ac7a43 1.21.9-pre1 2025-10-03 13:46:21 +02:00
Nassim Jahnke 15d3944700 Fix mannequin entity data reading 2025-10-03 13:46:21 +02:00
Nassim Jahnke acd9a6f57c 25w37a 2025-10-03 13:46:20 +02:00
Nassim Jahnke d5fe4e22b4 25w36a/b 2025-10-03 13:46:20 +02:00
Nassim Jahnke 9f0c38915a 25w35a 2025-10-03 13:46:20 +02:00
Nassim Jahnke bc7f081b3a I figured out the magic numbers 2025-10-03 13:46:20 +02:00
Nassim Jahnke 46b6627f9f 25w34b
Minus some dynamic player profile stuff
2025-10-03 13:46:20 +02:00
Nassim Jahnke 51cc1843ad 25w33a 2025-10-03 13:46:19 +02:00
Nassim Jahnke 98d1d2cb49 25w32a 2025-10-03 13:46:19 +02:00
Nassim Jahnke 556560a0f3 25w31a 2025-10-03 13:46:19 +02:00
FlorianMichael be2534c6e6 Add missing game test payload sanitize in 1.20->1.20.2 (#4661) 2025-10-02 16:14:50 +02:00
RaynLegends d40d1bd232 Fix system messages sent during config state hidden on <= 1.12.2 servers (#4650)
Fixes ViaVersion/issues#4478
2025-09-21 18:32:14 +02:00
Nassim Jahnke 6143f78ccf Update dependencies 2025-09-20 22:36:43 +02:00
EnZaXD 52cdebc3d3 Execute stored object clear call inside the event loop (#4652)
This fixes NPE exceptions when players disconnect. A packet goes through the pipeline after setActive(false) was called causing NPE exceptions.
2025-09-20 22:35:47 +02:00
EnZaXD cdccae95e0 Remove serialize versions from item hasher (#4651) 2025-09-16 21:24:42 +02:00
EnZaXD b0c45e3ed3 Fix wrong shulker box mapping in 1.12.2->1.13 (#4641)
Closes https://github.com/ViaVersion/ViaVersion/issues/4636
2025-09-14 18:53:16 +02:00
EnZaXD 3ba518650c Filter invalid remove teams packets in 1.20.3->1.20.5 (#4643)
Closes https://github.com/ViaVersion/ViaVersion/issues/4564
2025-09-13 11:23:18 +02:00
Nassim Jahnke 5a303996a1 Cleanup and fixes to storable object task 2025-09-05 19:35:04 +02:00
FlorianMichael 695534e8a8 Don't run movement transmitter provider in netty thread 2025-09-05 19:02:51 +02:00
EnZaXD 16ba011243 Rename ProtocolRunnable, always submit tick logic into event loop (#4644) 2025-09-03 17:05:53 +02:00
Nassim Jahnke 0ea7271157 Update deps 2025-09-03 07:42:12 +02:00
EnZaXD dc2b2f1407 Rename RedirectProtocolVersion (#4642) 2025-09-01 21:01:30 +02:00
Nassim Jahnke 85baefc69b Log channel close outside of event loop when debug is enabled 2025-08-31 22:39:15 +02:00
riku6460andFlorianMichael 41e0fdc20f Add EntityTracker#clear and clear entities on entering configuration state (#4638)
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-08-29 17:15:39 +02:00
dependabot[bot] 5c328fba33 Bump actions/setup-java from 4 to 5 (#4637)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 15:35:43 +02:00
EnZaXD 91b11878fb Fix ViaAPI#getConnection javadoc and remove not needed code (#4635) 2025-08-20 17:38:19 +02:00
Nassim Jahnke 0ea5e07d63 Don't replace velocity servers section when merging with default config 2025-08-19 16:14:03 +02:00
Nassim Jahnke 152e4e77a8 Handle custom name in banner etc. in 1.21.4->1.21.5
Newer clients handle errors gracefully and will parse them okay, but this'll make sure they are properly set
2025-08-17 16:41:26 +02:00
Nassim Jahnke cf20c6397d Fix spawn_particles key 2025-08-15 08:35:34 +02:00
Nassim Jahnke 981672e2cf Update particle types in enchantments 2025-08-14 18:22:55 +02:00
dependabot[bot] d10b600e72 [ci skip] Bump actions/checkout from 4 to 5 (#4627)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 08:23:33 +02:00
Nassim Jahnke de9cec36c7 Don't hash empty items in container 2025-08-10 15:39:45 +02:00
Nassim Jahnke 6eb561607c Fix bad reference 2025-08-10 15:12:22 +02:00
Nassim Jahnke db3e1f605a Fix hashing of maps in lists 2025-08-10 15:04:39 +02:00
Nassim Jahnke 31583fc2d3 Update deps 2025-08-09 18:43:37 +02:00
Nassim Jahnke 6096ce4eea Add option to log blocked joins
Closes #4613
2025-08-09 18:21:15 +02:00
Nassim Jahnke 873da12233 Check if custom_name lock data is actually present in 1.21.2
Fixes #4622
2025-08-09 17:50:04 +02:00
EnZaXD 78191ea366 [ci skip] Gradle & Shadow 9.0.0; Rewrite .gitignore file (#4606) 2025-08-09 14:18:03 +02:00
EnZaXD f8d7c5c193 [ci skip] Fix packet id comments (#4621) 2025-08-09 13:11:52 +02:00
EnZaXD bc9c979e7d Don't make the protocol pipeline depend on simple protocol (#4619) 2025-08-08 18:59:19 +02:00
EnZaXD d686a9ddf0 Move protocol logger creation to AbstractProtocol#createLogger (#4620)
Allows VB to delegate the used logger to the VB platform logger
2025-08-08 15:36:25 +02:00
EnZaXD 9dd610605f Don't put legacy show_text value through json conversion in 1.21.1->.5 (#4611) 2025-08-05 09:19:31 +02:00
EnZaXD 219e163ac2 Add statistic mappings for 1.21.5->1.21.6 (#4609) 2025-08-03 09:33:56 +02:00
EnZaXD 925e7b4664 Add some backwards compatibility functions to PacketTracker (#4607) 2025-08-02 15:09:46 +02:00
criticalcynical 5a9f040af8 Fix wrong connections being removed when switching servers on proxy platforms (#4576) 2025-07-29 20:35:20 +02:00
Nassim Jahnke 992ad7f35a Fix max packet size check 2025-07-29 20:28:37 +02:00
EnZaXD bb93ac011c Null check original root section (#4604) 2025-07-29 19:38:13 +02:00
Nassim Jahnke 4070ea9f02 Revamp max-pps config
Add a config section for setting max packet size, add a toggle for disabling each tracker fully
2025-07-29 12:27:51 +02:00
EnZaXD 499efa1608 Convert HIDE_ADDITIONAL_TOOLTIP in both directions in 1.21.4->1.21.5 (#4600) 2025-07-29 12:19:10 +02:00
Nassim Jahnke 0196d9c83e Bump version to 5.5.0-SNAPSHOT 2025-07-29 12:11:59 +02:00
Nassim Jahnke 4c316de042 5.4.2 Release 2025-07-23 23:03:10 +02:00
EnZaXD 8ee5d7e680 Add missing biome name translations in 1.17.1->1.18 (#4597) 2025-07-22 20:50:33 +02:00
Nassim Jahnke 64c128d414 Fix 1.8/1.9 thrown potion entity data handling
Fixes #4596
2025-07-21 23:55:03 +02:00
Nassim Jahnke 77d11fc593 Update attribute modifier types in show item hovers
Fixes #4593
2025-07-18 20:50:46 +02:00
Nassim Jahnke 2c72a09809 Strip namespace from custom attribute id when getting names 2025-07-18 11:01:52 +02:00
Nassim Jahnke 3dbd81da76 [ci skip] Split up publishing steps
Putting them into the same step meant if one publish action failed, the second one wouldn't run. Before this change, Modrinth would often block Hangar from publishing
2025-07-17 16:10:15 +02:00
Nassim Jahnke a0116c7ea7 Add 1.21.8 version string to 1.21.7 2025-07-17 14:33:58 +02:00
Nassim Jahnke fd5dadbe01 [ci skip] Clean up imports 2025-07-14 12:36:56 +02:00
Kai df87a02c38 Update ViaNBT (#4585) 2025-07-14 12:25:59 +02:00
EnZaXD bb293b3e5d Add cancel-swing-in-inventory option for 1.15.2->1.16 inventory swing fix (#4587) 2025-07-14 12:24:53 +02:00
EnZaXDanddewgs ff03892b25 Fix some directions not being included in chunk-border-fix; Reduce packets sent by checking for needed chunks (#4586)
Co-authored-by: dewgs <23721849+dewgs@users.noreply.github.com>
2025-07-14 12:21:28 +02:00
EnZaXD eb51306d82 Fix ItemFactory#getSpawnEgg NoSuchMethodError on older Paper builds (#4582) 2025-07-13 08:40:09 +02:00
EnZaXD 81eb3362f3 [ci skip] Add Java resolving plugin (#4577) 2025-07-12 10:31:23 +02:00
EnZaXD 7f06b03453 Remove StorableObject#clearOnServerSwitch (#4583) 2025-07-12 10:30:30 +02:00
RK_01 c16432de2a Fix anticheat flags when respawning with 1.21.2+ clients on older servers (#4573)
Fixes #4572
2025-07-07 21:40:01 +02:00
Nassim Jahnke b162dbdff0 Add missing null check to allowed_entities rewrite
Fixes #4568
2025-07-05 13:55:55 +02:00
Nassim Jahnke dfbe57e304 Rewrite Equippable allowed_entities
Fixes #4567
2025-07-04 17:17:05 +02:00
Nassim Jahnke 6f6dc2c641 Rewrite attribute modifiers automatically via interface
An id change in 1.21.5->1.21.6 was missed
2025-06-30 21:27:00 +02:00
Nassim Jahnke 06990ec0c9 Bump version to 5.4.2-SNAPSHOT 2025-06-30 21:26:14 +02:00
Nassim Jahnke 351b42b5e5 5.4.1 Release 2025-06-30 09:56:25 +02:00
Nassim Jahnke 20e3c832fb 1.21.7-rc2 2025-06-30 09:49:48 +02:00
Nassim Jahnke ec9c121da2 1.21.7-rc1 2025-06-30 09:49:47 +02:00
FlorianMichael 12c773edea Add missing translatable mappings (#4542)
Fixes #3331
Fixes #4273
2025-06-30 09:47:33 +02:00
Nassim Jahnke 97b411aa6d Manually handle text component boolean entries
Fixes #4558
2025-06-29 16:36:12 +02:00
Nassim Jahnke 24f6c4f0fd Implement hashing for potion contents 2025-06-29 15:50:56 +02:00
FlorianMichael 9409c7d22a [ci skip] Add SECURITY.md (#4520) 2025-06-29 15:36:49 +02:00
FlorianMichael 17d94a17f0 Always write length in LengthPrefixedTagType 2025-06-29 11:51:38 +02:00
riku6460andFlorianMichael a1cb4d3691 Add Types#CUSTOM_CLICK_ACTION_TAG for VB (#4557)
* Add LengthPrefixedTagType for CUSTOM_CLICK_ACTION

* Move type into own class, add instance into Types

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-06-29 07:21:48 +02:00
Nassim Jahnke 1d5070a480 Allow mapping sound event holders to empty sounds 2025-06-27 10:24:34 +02:00
FlorianMichaelanddewgs f612adbd0a Rewrite player & display name in player info packet in 1.12.2->1.13 (#4550)
Fixes Tablist plugins on some servers breaking since the game profile name sent is used to determine the scoreboard team which name we rewrite in other packets, also adds missing component rewriter calls to the display names (Not that important given its only translation keys, but we are already here).

Co-authored-by: dewgs <23721849+dewgs@users.noreply.github.com>
2025-06-25 13:31:17 +02:00
FlorianMichael 6716beec5a Remove arbitrary chat-nbt-fix config option in 1.11.1->1.12 (#4551) 2025-06-25 13:28:23 +02:00
Nassim Jahnke d22b00e4a6 Add helper methods for registry entry rewriting 2025-06-22 22:53:08 +02:00
Nassim Jahnke fe9ca49920 Update mcstructs 2025-06-22 10:38:33 +02:00
PacksoliteandNassim Jahnke e1837dc578 Fix legacy block picking on some Paper forks (#4496)
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2025-06-21 11:22:22 +02:00
booky 66eead2927 Fix missing clouds in 1.21.5->1.21.6 (#4538) 2025-06-21 11:00:19 +02:00
booky 937a2a2532 Fix server links button not visible in 1.21.5->1.21.6 (#4536)
The Minecraft 1.21.6 client will only show the server links if the the server_links dialog has been sent
2025-06-21 01:47:34 +02:00
Nassim Jahnke bee45ef9ef Use Cache get instead of Map compute
This may or may not fix concurrency issues from... somewhere (bad plugins/old guava impl?)
2025-06-20 21:40:37 +02:00
FlorianMichael 1946a65ab2 Add MathUtil#ceil 2025-06-20 21:36:44 +02:00
Nassim Jahnke f594a946d4 Bump version to 5.4.1-SNAPSHOT 2025-06-20 21:36:33 +02:00
Nassim Jahnke 7a0ec492d1 5.4.0 Release 2025-06-20 19:26:25 +02:00
Nassim Jahnke b4fac61eb9 Fix tinted leaves particle reading in 1.21.6 type 2025-06-20 19:26:19 +02:00
Nassim Jahnke 7817b7a422 Remove snapshot version 2025-06-17 02:14:13 +02:00
Nassim Jahnke ed266d296e 1.21.6-rc1 2025-06-17 02:13:06 +02:00
Nassim Jahnke 3ce324c1e1 1.21.6-pre4 2025-06-17 02:13:06 +02:00
Nassim Jahnke 835dc4733d 1.21.6-pre3 2025-06-17 02:13:06 +02:00
Nassim Jahnke aa66a6b482 1.21.6-pre2 2025-06-17 02:13:05 +02:00
Nassim Jahnke 406855d427 1.21.6-pre1 2025-06-17 02:13:05 +02:00
Nassim Jahnke fe5ba84f7a 25w21a 2025-06-17 02:13:05 +02:00
Nassim Jahnke f49495162b Use updated versioned types 2025-06-17 02:13:05 +02:00
Nassim Jahnke be5c451f42 25w20a 2025-06-17 02:13:05 +02:00
Nassim Jahnke 1517596a9f Add hashed item handling 2025-06-17 02:13:05 +02:00
Nassim Jahnke 6a89b84879 Fix attribute modifier writing 2025-06-17 02:13:05 +02:00
Nassim Jahnke c414458f1c 25w19a 2025-06-17 02:13:05 +02:00
Nassim Jahnke ec9086abc4 25w18a 2025-06-17 02:13:05 +02:00
Nassim Jahnke d6c16677fc 25w17a 2025-06-17 02:13:05 +02:00
Nassim Jahnke 7cd3a75ef8 Handle player_command change 2025-06-17 02:13:05 +02:00
Nassim Jahnke 0677cbaa3c 25w16a 2025-06-17 02:13:05 +02:00
Nassim Jahnke ab8b5abc48 25w15a
Is it 1.22? Is it 1.21.6? Who knows
2025-06-17 02:13:05 +02:00
FlorianMichael 60c67659d0 Filter invalid characters in command click events in 1.21.4->.5 (#4528)
Minecraft versions prior to 1.21.4 filter out invalid characters when handling the click event on the clientside while 1.21.5+ validates and throws in the network codec per ExtraCodecs#CHAT_STRING
2025-06-15 12:28:08 +02:00
dewgsandFlorianMichael 814190c2df Add missing dimension change checks for entity tracking (#4527)
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-06-14 17:29:40 +02:00
RK_01 04d647bfef Fix respawning with 1.21.2+ clients on older vanilla servers (#4509) 2025-06-12 18:18:37 +02:00
FlorianMichael 930bf67229 Don't always send player inputs on Fabric servers in 1.21->1.21.2 (#4523) 2025-06-11 02:52:21 +02:00
FlorianMichael 51c3085180 Validate tag identifiers in block predicates in 1.20.3->1.20.5 (#4522)
As usual, versions <= 1.20.4 have the entire parsing code in a try catch block while 1.20.5+ needs valid data.

Closes https://github.com/ViaVersion/ViaVersion/issues/4515
2025-06-09 15:08:00 +02:00
FlorianMichael b981223e0a Make workflows manual runnable (#4521) 2025-06-08 23:56:14 +02:00
FlorianMichael 3951cff03a Cancel out unmapped (block) ids in HolderSetImpl (#4512)
In VB, mapping data will return -1 for missing block ids (which is for almost all blocks the case). This is made so that VV rewriters can cancel these blocks away nicely (as mostly used in places where it's better to show the user nothing rather than wrong blocks, such as statistics).

Fixes https://github.com/ViaVersion/ViaVersion/issues/4510
2025-05-28 07:41:21 +02:00
Nassim Jahnke 77a6ae37c0 Fix game profile null id hashing
Fixes #4506
2025-05-27 15:28:35 +02:00
Nassim Jahnke 12e201633f Fix rabbit variant hashing 2025-05-27 14:28:04 +02:00
Nassim Jahnke 8eb005e775 Fix tropical fish pattern hashing 2025-05-27 14:05:40 +02:00
RK_01 4d39c0007f Add QoL API for GameProfile (#4505) 2025-05-27 08:39:08 +02:00
FlorianMichael d9609e60b8 Don't fail on book pages rewrite in 1.8->1.9 as per Vanilla behaviour (#4504) 2025-05-26 20:22:29 +02:00
Nassim Jahnke ab3927dff7 Implement our own hash writing
This avoids a lot of indirection, wrapping/boxing and data copying while also making sure we can immediately implement them on new snapshots without waiting for a separate (also ever-growing) library.

The HashBuilder is partially copied from MCStructs, everything else was built anew to intentionally stay away from Vanilla's Codec design
2025-05-26 12:37:58 +02:00
FlorianMichael 1a60c52fa3 Don't convert creative-slot-lock/map-post-processing in 1.20.3->.5 (#4500) 2025-05-22 21:38:18 +02:00
github-actions[bot]andgradle-update-robot f88dae1828 Update Gradle Wrapper from 8.14 to 8.14.1 (#4501)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2025-05-22 17:35:05 +02:00
Nassim JahnkeandFlorianMichael 2626773267 Refactor 1.20.5+ versioned types
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-05-17 15:12:52 +02:00
Nassim Jahnke f16f1905b7 Move container handling into handleShowItem directly
Fixes ViaVersion/ViaBackwards#1010
2025-05-15 11:08:44 +02:00
Nassim Jahnke cc435b2b02 Move item id setter below backup method 2025-05-14 14:01:03 +02:00
Nassim Jahnke eb2d603aae Add protected handleRewritablesToServer method 2025-05-14 13:29:40 +02:00
Nassim Jahnke c30e0f45bc Split up item rewriter methods even more
Item backups and its restoration processes have to be more carefully placed around Rewritable handling, so the original/restored data stays untouched
2025-05-14 13:22:32 +02:00
Nassim Jahnke ebb24c73a2 Don't call super handleItemToClient with custom item hasher 2025-05-13 23:12:06 +02:00
Nassim Jahnke 575c5b9abf Move restoreBackupData call up 2025-05-13 22:55:46 +02:00
Nassim Jahnke 812694d74d Split updateItemDataComponents in two 2025-05-13 22:45:25 +02:00
Nassim Jahnke 1efaffbc7d Implement more data conversion
Most importantly attributes
2025-05-12 18:59:41 +02:00
FlorianMichael b03b5f7da7 [ci skip] Make the runViaProxy task work with Gradle's configuration cache (#4483) 2025-05-12 17:53:54 +02:00
Nassim Jahnke 3554db9e3a Prepare for hashed item rewriting 2025-05-11 23:10:20 +02:00
Nassim Jahnke a6d58fc02b Only track item when necessary, cleanup 2025-05-11 23:10:18 +02:00
RaphiMC e2045295a0 Hash item data components in 1.21.4->1.21.5 2025-05-11 23:10:17 +02:00
FlorianMichael a6b219c0df [ci skip] Allow build if Git is not installed or the project is downloaded as code zip (#4477) 2025-05-11 22:26:35 +02:00
FlorianMichael 0b5721d81e Check for non-negative value for damage & repair cost in 1.20.3->.5 (#4491)
In 1.20.5, codecs introduced the non-negative int type which will fail if a value <= 0 is present. In 1.20.4, Mojang gracefully handled negative values

Fixes https://github.com/ViaVersion/ViaFabricPlus/issues/763
2025-05-11 22:05:59 +02:00
FlorianMichael 5bad61e210 Don't perform length validation on zero bit storage in 1.18 palette type (#4479)
Minecraft has its own ZeroBitStorage type for this case so we don't need to perform the validation, also removed the comments as this is just how our code should work to match Vanilla behaviour (at least for the first one; I did not verify the readValues code)

Closes https://github.com/ViaVersion/ViaVersion/issues/4476
2025-05-05 21:06:37 +02:00
FlorianMichael e597d8faaa [ci skip] Include platform launcher runtime dependency for tests (#4474) 2025-04-29 10:21:30 +02:00
FelixandFlorianMichael d9eb7109bd Add missing PLAYER_CHAT handlers in 1.20/1.21 versions (#4472)
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-04-28 11:57:10 +02:00
github-actions[bot]andgradle-update-robot 77d68306b6 Update Gradle Wrapper from 8.13 to 8.14 (#4471)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2025-04-26 16:33:53 +02:00
FlorianMichael 16aec9c0a1 Fix legacy item/entity hover event + potion id in 1.21.4->1.21.5 (#4469) 2025-04-23 20:52:53 +02:00
FlorianMichael c6cde5fc10 Cancel unknown block entities in BlockRewriter#registerBlockEntityData (#4466) 2025-04-22 16:05:44 +02:00
Nassim Jahnke bf84eb0141 Add separate config option for text component conversion errors 2025-04-20 15:57:22 +02:00
Nassim Jahnke 4dfc3bd2be Make parts of item data component rewriting more generic via an interface 2025-04-16 10:59:20 +02:00
Nassim Jahnke b0c53ffdd3 Make helper method in Copyable static 2025-04-15 21:20:57 +02:00
Nassim Jahnke d65b2abc46 Ignore invalid data in signs 2025-04-15 20:46:13 +02:00
Nassim Jahnke 03313a1681 Catch text conversion errors 2025-04-15 10:02:00 +02:00
Nassim Jahnke 78c5e2c8e3 Convert hover events to legacy deep 2025-04-14 08:57:04 +02:00
FlorianMichael e467c7c03f Set correct data types in 1.8->1.9 CONTAINER_CLICK (#4460) 2025-04-14 08:55:45 +02:00
Nassim Jahnke 0c01425641 5.3.2 Release 2025-04-13 15:45:15 +02:00
Nassim Jahnke 01d26e7ac5 Make trimStrings public 2025-04-12 15:37:19 +02:00
Nassim Jahnke 99ea6c32ad Add client and server protocol to informative exception data 2025-04-11 22:20:38 +02:00
Nassim Jahnke cf231d92b1 Update mcstructs
Fixes ViaVersion/ViaBackwards#988
2025-04-10 18:58:23 +02:00
FlorianMichael f555188428 [ci skip] Print correct max read length in StringType sanity checks (#4456) 2025-04-10 16:16:46 +02:00
FlorianMichael 93d6fa2e78 Only add (block) entity id if needed for tooltips in 1.20.3->.5 2025-04-09 17:22:33 +02:00
Nassim Jahnke 162fcafb36 Ignore unknown entity data too in 1.20.3->1.20.5
Fixes #4433
Closes #4451
2025-04-09 16:24:03 +02:00
FlorianMichael 3d0a0fe590 Send player input every tick when in boat in 1.21->1.21.2 (#4449) 2025-04-09 16:14:07 +02:00
bookyandFlorianMichael b06556a84e Fix advancement menu background keys (#4454)
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-04-09 15:56:06 +02:00
Nassim Jahnke ac8bb104b3 Fix primitive array copying 2025-04-08 15:54:02 +02:00
FlorianMichael 4b85ca7691 Fix handling of removed item components in 1.20.3->.5 component rewriter (#4452)
Only relevant for VB though as VV will never put empty structured data through it.
2025-04-08 15:34:30 +02:00
FlorianMichael ebd8eb79c1 Use correct version in json to tag conversion in 1.21.4->.5 (#4450) 2025-04-08 15:32:07 +02:00
Nassim Jahnke 09cffbfb33 Null check connection in Velocity connect listener 2025-04-05 18:35:24 +02:00
FlorianMichael 49a1bffc98 Only send the connection details if ViaVersion is active (#4434) 2025-04-05 11:54:06 +02:00
FlorianMichael da022a0b63 [ci skip] Fix ItemRewriter#registerContainerClick1_21_5 data order (#4435) 2025-04-05 11:53:36 +02:00
Nassim Jahnke 3beddaf522 Move show item container contents conversion to the right place
Fixes #4444
2025-04-05 11:53:08 +02:00
Nassim Jahnke 70139c6838 Bump version to 5.3.2-SNAPSHOT 2025-04-05 11:52:24 +02:00
Nassim Jahnke f040077c13 5.3.1 Release 2025-03-30 21:07:54 +02:00
Nassim Jahnke 1f404820b7 Track it on 1.21.4 servers already 2025-03-30 18:51:03 +02:00
Nassim Jahnke 742e70fff6 Small cleanup, track gamemode 2025-03-30 18:26:05 +02:00
Nassim Jahnke dd6a1a7f6e Update old version warning to <1.16 servers
The original <1.13 warning was added almost 5 years ago, since then more small issues have come up from newer clients having fundamental changes and server stats on those old versions have dropped even more. That said, ViaVersion will keep working on these servers presumably forever
2025-03-30 16:02:27 +02:00
Nassim Jahnke 08ef7c2f35 Add back legacy hover event conversion 2025-03-30 15:05:03 +02:00
Gero e128469313 Fix missing mapping of CHUNKS_BIOMES for 1.21.5 (#4425) 2025-03-30 11:56:29 +02:00
FlorianMichael cbb753271e [ci skip] Update repository declaration in GH workflow (#4424) 2025-03-29 20:28:41 +01:00
FlorianMichael 29f299d882 Update MCStructs to 3.0.0 (#4422) 2025-03-29 14:30:06 +01:00
Pablo Herrera 41138aabd1 Implement pick-block for legacy servers (#4412) 2025-03-29 13:07:44 +01:00
Nassim Jahnke b90f20cfeb Fix 1.20.3 disguised chat handler 2025-03-29 10:15:21 +01:00
Nassim Jahnke 585028beb7 Bump version to 5.3.1-SNAPSHOT 2025-03-29 10:14:45 +01:00
448 changed files with 13113 additions and 2750 deletions

No files matched your search

+5 -5
View File
@@ -1,6 +1,6 @@
name: Java CI with Gradle
on: [push, pull_request]
on: [push, pull_request, workflow_dispatch]
jobs:
build:
@@ -11,13 +11,13 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
@@ -26,7 +26,7 @@ jobs:
run: ./gradlew build
- name: Upload Artifacts to GitHub
# Only upload on the preview repository as there is no CI job for it.
if: ${{ github.repository == 'ViaVersionDev' && github.ref_name == 'preview' }}
if: ${{ github.repository == 'ViaVersion/ViaVersionDev' && github.ref_name == 'preview' }}
uses: actions/upload-artifact@v4
with:
name: Artifacts
+13 -5
View File
@@ -4,6 +4,7 @@ on:
branches:
- master
- dev
workflow_dispatch:
jobs:
publish:
@@ -11,19 +12,26 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
check-latest: true
- name: Publish
- name: Build
run: ./gradlew build
- name: Publish to Hangar
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
run: ./gradlew publishAllPublicationsToHangar --stacktrace
continue-on-error: true
- name: Publish to Modrinth
env:
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew build modrinth publishAllPublicationsToHangar --stacktrace
run: ./gradlew modrinth --stacktrace
continue-on-error: true
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Update Gradle Wrapper
+19 -98
View File
@@ -1,115 +1,36 @@
### Java files ###
*.class
# Gradle
# Package Files
#*.jar
*.war
*.ear
.gradle/
build/
out/
classes/
.kotlin/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Eclipse
*.launch
# Idea
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
# Ignore project files
*.iml
# Ignore IDEA directory
.idea/*
.idea/
!.idea/copyright/*
!.idea/scopes/*
# Include the project's dictionary
!.idea/dictionaries/
!.idea/dictionaries/*
# File-based project format:
*.iml
*.ipr
*.iws
### Plugin-specific files: ###
# IntelliJ
/out/
# VSCode
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.vscode/
bin/
.classpath
.project
# External tool builders
.externalToolBuilders/
# macOS
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
### MacOS ###
.DS_Store
### Run Folder (ViaProxy) ###
common/run/
# Misc
run/
+2 -4
View File
@@ -8,7 +8,7 @@
it works on any platform you can think of.**
The base ViaVersion jar runs on Paper and Velocity. We also have projects integrating ViaVersion to run
on Fabric, Forge, Bungee, Sponge, or as a standalone proxy to join from basically any client version on
on Fabric, Forge, Sponge, or as a standalone proxy to join from basically any client version on
any server version from the past decade. **See [HERE](https://viaversion.com) for an overview of the different Via\* projects.**
Note that ViaVersion will be able to **run best on either Paper servers or through [ViaFabricPlus](https://github.com/ViaVersion/ViaFabricPlus?tab=readme-ov-file#viafabricplus)** due to having
@@ -16,7 +16,7 @@ direct access to client/server state and more extensive API.
Supported Versions:
![Table (https://i.imgur.com/zrQTcf0.png)](https://i.imgur.com/zrQTcf0.png)
![Table (https://ci.viaversion.com/userContent/images/T.png)](https://ci.viaversion.com/userContent/images/T.png)
**User Docs:** https://docs.viaversion.com
@@ -87,12 +87,10 @@ of the `build/libs` directory.
You need JDK 17 or newer to build ViaVersion.
Mapping Files
--------------
Mapping files are generated and managed in our [Mappings repository](https://github.com/ViaVersion/Mappings). The generated mapping output is stored [here](./common/src/main/resources/assets/viaversion).
Resources
--------
+10
View File
@@ -0,0 +1,10 @@
# Security Policy
## Reporting a Vulnerability
If you discover a **security vulnerability**, please **do not** open a public issue. Instead, use one of the following **confidential contact methods**:
* **Email:** [security@viaversion.com](mailto:security@viaversion.com)
* **Discord:** Join our [Discord server](https://discord.gg/viaversion) and visit the [#exploit-report](https://discord.com/channels/316206679014244363/1388847764137316485) channel for further instructions.
If your issue is **not security-related** (e.g., bug reports, feature requests, or usage questions), please use the [GitHub Issues page](https://github.com/ViaVersion/ViaVersion/issues) or contact us via the [Discord server](https://discord.gg/viaversion).
+5 -1
View File
@@ -29,7 +29,11 @@ dependencies {
api(libs.snakeYaml)
compileOnlyApi(libs.netty)
compileOnlyApi(libs.guava)
compileOnlyApi(libs.guava) {
exclude("com.google.errorprone", "error_prone_annotations")
exclude("org.jspecify", "jspecify")
exclude("com.google.j2objc", "j2objc-annotations")
}
compileOnlyApi(libs.checkerQual)
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -123,7 +123,7 @@ public interface ViaAPI<T> {
boolean isInjected(UUID uuid);
/**
* Returns whether Via injected into this player connection. Note that this method may not work on
* Returns the injected UserConnection if present. Note that this method may not work on
* clientside implementations and is generally not recommended to be used. Use {@link ConnectionManager} instead.
*
* @param uuid uuid of the player
@@ -0,0 +1,27 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.configuration;
public record RateLimitConfig(boolean enabled, int maxRate, String maxRateKickMessage, int warningRate, int maxWarnings,
long trackingPeriodNanos, String warningKickMessage, String ratePlaceholder) {
}
@@ -147,6 +147,7 @@ public interface ViaVersionConfig extends Config {
*
* @return The number of packets a client can send per second.
*/
@Deprecated(forRemoval = true)
int getMaxPPS();
/**
@@ -154,6 +155,7 @@ public interface ViaVersionConfig extends Config {
*
* @return Kick message, with colour codes using '&amp;amp;'
*/
@Deprecated(forRemoval = true)
String getMaxPPSKickMessage();
/**
@@ -161,6 +163,7 @@ public interface ViaVersionConfig extends Config {
*
* @return Time in seconds that should be tracked for warnings
*/
@Deprecated(forRemoval = true)
int getTrackingPeriod();
/**
@@ -168,6 +171,7 @@ public interface ViaVersionConfig extends Config {
*
* @return The number of packets per second to count as a warning.
*/
@Deprecated(forRemoval = true)
int getWarningPPS();
/**
@@ -175,6 +179,7 @@ public interface ViaVersionConfig extends Config {
*
* @return The number of packets a client can send per second.
*/
@Deprecated(forRemoval = true)
int getMaxWarnings();
/**
@@ -182,8 +187,13 @@ public interface ViaVersionConfig extends Config {
*
* @return Kick message, with colour codes using '&amp;amp;'
*/
@Deprecated(forRemoval = true)
String getMaxWarningsKickMessage();
RateLimitConfig getPacketTrackerConfig();
RateLimitConfig getPacketSizeTrackerConfig();
/**
* Send supported versions in the status response packet
*
@@ -233,13 +243,6 @@ public interface ViaVersionConfig extends Config {
*/
boolean isChunkBorderFix();
/**
* Should we fix nbt array's in json chat messages for 1.12 clients
*
* @return true if enabled
*/
boolean is1_12NBTArrayFix();
/**
* Should we make team colours based on the last colour in team prefix
*
@@ -270,6 +273,8 @@ public interface ViaVersionConfig extends Config {
*/
String getBlockedDisconnectMsg();
boolean logBlockedJoins();
/**
* Get the message sent to players being kicked on reload.
* Players are kicked to stop the server crashing
@@ -285,6 +290,13 @@ public interface ViaVersionConfig extends Config {
*/
boolean isSuppressConversionWarnings();
/**
* Should we hide errors that occur when trying to convert text components?
*
* @return true if enabled
*/
boolean isSuppressTextComponentConversionWarnings();
/**
* Should we disable the 1.13 auto-complete feature to stop spam kicks? (for any server lower than 1.13)
*
@@ -478,4 +490,12 @@ public interface ViaVersionConfig extends Config {
* @return true if enabled
*/
boolean fix1_21PlacementRotation();
/**
* If enabled, cancel swing packets sent while having an inventory opened on 1.15.2 and below servers.
* This can cause false positives with anti-cheat plugins.
*
* @return true if enabled
*/
boolean cancelSwingInInventory();
}
@@ -30,15 +30,6 @@ package com.viaversion.viaversion.api.connection;
*/
public interface StorableObject {
/**
* Returns whether the object should be uncached on a server switch.
*
* @return whether the object should be uncached on a server switch
*/
default boolean clearOnServerSwitch() {
return true;
}
default void onRemove() {
}
}
@@ -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.data.item.ItemHasher;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketTracker;
@@ -99,6 +100,23 @@ public interface UserConnection {
*/
void addEntityTracker(Class<? extends Protocol> protocolClass, EntityTracker tracker);
/**
* Adds an item hasher to the user connection.
*
* @param protocolClass protocol class
* @param itemHasher item hasher
*/
void addItemHasher(Class<? extends Protocol> protocolClass, ItemHasher itemHasher);
/**
* Returns the item hasher by the given protocol class if present.
*
* @param protocolClass protocol class
* @param <T> item hasher type
* @return item hasher if present
*/
@Nullable <T extends ItemHasher> T getItemHasher(Class<? extends Protocol> protocolClass);
/**
* Returns the client world by the given protocol class if present.
*
@@ -121,17 +139,7 @@ public interface UserConnection {
/**
* Clear stored objects, entity trackers and client worlds.
*/
default void clearStoredObjects() {
clearStoredObjects(false);
}
/**
* Clear stored objects, entity trackers and client worlds.
* If cleared for a proxy server switch, some stored objects and tracker data will be retained.
*
* @param isServerSwitch whether the clear is due to a server switch
*/
void clearStoredObjects(boolean isServerSwitch);
void clearStoredObjects();
/**
* Sends a raw packet to the connection on the current thread.
@@ -186,9 +194,15 @@ public interface UserConnection {
/**
* Monitors serverbound packets and returns whether a packet can/should be processed.
*
* @param bytes the number of bytes in the packet
* @return false if this packet should be cancelled
*/
boolean checkServerboundPacket();
boolean checkServerboundPacket(int bytes);
@Deprecated(forRemoval = true)
default boolean checkServerboundPacket() {
return checkServerboundPacket(0);
}
/**
* Monitors clientbound packets and returns whether a packet can/should be processed.
@@ -201,6 +215,11 @@ public interface UserConnection {
* @see #checkClientboundPacket()
* @see #checkServerboundPacket()
*/
default boolean checkIncomingPacket(final int bytes) {
return isClientSide() ? checkClientboundPacket() : checkServerboundPacket(bytes);
}
@Deprecated(forRemoval = true)
default boolean checkIncomingPacket() {
return isClientSide() ? checkClientboundPacket() : checkServerboundPacket();
}
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.data;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.TagData;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -140,12 +141,14 @@ public interface MappingData {
@Nullable Mappings getBlockMappings();
@Nullable Mappings getBlockEntityMappings();
@Nullable FullMappings getFullBlockMappings();
@Nullable Mappings getBlockStateMappings();
@Nullable Mappings getSoundMappings();
@Nullable FullMappings getFullSoundMappings();
@Nullable Mappings getStatisticsMappings();
@Nullable Mappings getMenuMappings();
@@ -154,6 +157,8 @@ public interface MappingData {
@Nullable Mappings getPaintingMappings();
@Nullable FullMappings getBlockEntityMappings();
@Nullable FullMappings getAttributeMappings();
@Nullable FullMappings getEntityMappings();
@@ -163,4 +168,26 @@ public interface MappingData {
@Nullable FullMappings getRecipeSerializerMappings();
@Nullable FullMappings getDataComponentSerializerMappings();
default @Nullable FullMappings getFullMappings(final MappingType mappingType) {
return switch (mappingType) {
case ITEM -> getFullItemMappings();
case SOUND -> getFullSoundMappings();
case ENTITY -> getEntityMappings();
};
}
/**
* Set of block (not block state) ids that had their base type or properties changed.
*
* @return set of changed block ids, or null if not tracked/none are present
*/
@Nullable IntSet changedBlocks();
/**
* Type of mappings. Currently only relevant for ops writing of generic holder classes and expanded when needed.
*/
enum MappingType {
ITEM, SOUND, ENTITY
}
}
@@ -28,6 +28,8 @@ import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.TagData;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
@@ -44,17 +46,21 @@ public class MappingDataBase implements MappingData {
protected FullMappings recipeSerializerMappings;
protected FullMappings itemDataSerializerMappings;
protected FullMappings attributeMappings;
protected FullMappings blockEntityMappings;
protected ParticleMappings particleMappings;
protected BiMappings itemMappings;
protected BiMappings blockMappings;
protected Mappings blockStateMappings;
protected Mappings blockEntityMappings;
protected Mappings soundMappings;
protected Mappings statisticsMappings;
protected Mappings enchantmentMappings;
protected Mappings paintingMappings;
protected Mappings menuMappings;
protected Map<RegistryType, List<TagData>> tags;
/**
* Set of block ids that have had type or property changes.
*/
protected IntSet changedBlocks;
public MappingDataBase(final String unmappedVersion, final String mappedVersion) {
this.unmappedVersion = unmappedVersion;
@@ -68,10 +74,7 @@ public class MappingDataBase implements MappingData {
}
final CompoundTag data = readMappingsFile("mappings-" + unmappedVersion + "to" + mappedVersion + ".nbt");
blockMappings = loadBiMappings(data, "blocks");
blockStateMappings = loadMappings(data, "blockstates");
blockEntityMappings = loadMappings(data, "blockentities");
soundMappings = loadMappings(data, "sounds");
statisticsMappings = loadMappings(data, "statistics");
menuMappings = loadMappings(data, "menus");
enchantmentMappings = loadMappings(data, "enchantments");
@@ -80,12 +83,16 @@ public class MappingDataBase implements MappingData {
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
if (unmappedIdentifierData != null && mappedIdentifierData != null) {
itemMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "items");
itemMappings = loadFullOrBiMappings(data, unmappedIdentifierData, mappedIdentifierData, "items");
blockMappings = loadFullOrBiMappings(data, unmappedIdentifierData, mappedIdentifierData, "blocks");
soundMappings = loadFullOrBiMappings(data, unmappedIdentifierData, mappedIdentifierData, "sounds");
entityMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "entities");
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
blockEntityMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "blockentities");
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
@@ -99,6 +106,8 @@ public class MappingDataBase implements MappingData {
} else {
// Might not have identifiers in older versions
itemMappings = loadBiMappings(data, "items");
blockMappings = loadBiMappings(data, "blocks");
soundMappings = loadMappings(data, "sounds");
}
final CompoundTag tagsTag = data.getCompoundTag("tags");
@@ -109,6 +118,11 @@ public class MappingDataBase implements MappingData {
loadTags(RegistryType.ENTITY, tagsTag);
}
final IntArrayTag changedBlocks = data.getIntArrayTag("changed_blocks");
if (changedBlocks != null) {
this.changedBlocks = new IntOpenHashSet(changedBlocks.getValue());
}
loadExtras(data);
}
@@ -132,6 +146,11 @@ public class MappingDataBase implements MappingData {
return MappingDataLoader.INSTANCE.loadMappings(data, key);
}
protected @Nullable BiMappings loadFullOrBiMappings(final CompoundTag data, final CompoundTag unmappedIdentifiersTag, final CompoundTag mappedIdentifiersTag, final String key) {
final FullMappings mappings = loadFullMappings(data, unmappedIdentifiersTag, mappedIdentifiersTag, key);
return mappings != null ? mappings : loadBiMappings(data, key);
}
protected @Nullable FullMappings loadFullMappings(final CompoundTag data, final CompoundTag unmappedIdentifiersTag, final CompoundTag mappedIdentifiersTag, final String key) {
if (!unmappedIdentifiersTag.contains(key) || !mappedIdentifiersTag.contains(key)) {
return null;
@@ -208,8 +227,8 @@ public class MappingDataBase implements MappingData {
}
@Override
public int getOldSoundId(final int i) {
return soundMappings.getNewIdOrDefault(i, 0);
public int getOldSoundId(final int id) {
return soundMappings.inverse().getNewIdOrDefault(id, 0);
}
@Override
@@ -224,8 +243,8 @@ public class MappingDataBase implements MappingData {
@Override
public @Nullable FullMappings getFullItemMappings() {
if (itemMappings instanceof FullMappings) {
return (FullMappings) itemMappings;
if (itemMappings instanceof FullMappings fullItemMappings) {
return fullItemMappings;
}
return null;
}
@@ -241,7 +260,15 @@ public class MappingDataBase implements MappingData {
}
@Override
public @Nullable Mappings getBlockEntityMappings() {
public @Nullable FullMappings getFullBlockMappings() {
if (blockMappings instanceof FullMappings fullBlockMappings) {
return fullBlockMappings;
}
return null;
}
@Override
public @Nullable FullMappings getBlockEntityMappings() {
return blockEntityMappings;
}
@@ -255,6 +282,14 @@ public class MappingDataBase implements MappingData {
return soundMappings;
}
@Override
public @Nullable FullMappings getFullSoundMappings() {
if (soundMappings instanceof FullMappings fullSoundMappings) {
return fullSoundMappings;
}
return null;
}
@Override
public @Nullable Mappings getStatisticsMappings() {
return statisticsMappings;
@@ -300,6 +335,11 @@ public class MappingDataBase implements MappingData {
return recipeSerializerMappings;
}
@Override
public @Nullable IntSet changedBlocks() {
return changedBlocks;
}
protected Logger getLogger() {
return Via.getPlatform().getLogger();
}
@@ -210,7 +210,7 @@ public class MappingDataLoader {
return null;
}
final int mappedSize = tag.getIntTag("mappedSize").asInt();
final int mappedSize = tag.getInt("mappedSize", -1);
final byte strategy = tag.getByteTag("id").asByte();
final V mappings;
if (strategy == DIRECT_ID) {
@@ -82,6 +82,11 @@ public interface EntityTracker {
*/
void clearEntities();
/**
* Clears all stored data, including entity types, entity data and client entity id.
*/
void clear();
/**
* Returns the stored entity data if an entity with the id is tracked, else null.
* If no data has been initialized yet, it will be done and returned by this method.
@@ -123,6 +128,20 @@ public interface EntityTracker {
*/
void setClientEntityId(int clientEntityId);
/**
* Returns whether the client player has the "insta build" ability, usually from creative mode.
*
* @return whether the client player can insta build
*/
boolean canInstaBuild();
/**
* Sets whether the client player has the "insta build" ability, usually from creative mode.
*
* @param instaBuild whether the client player can insta build
*/
void setInstaBuild(boolean instaBuild);
/**
* Returns the current world section height (block height / 16).
* This is always 16 for sub 1.17 worlds.
@@ -166,6 +185,20 @@ public interface EntityTracker {
*/
void setCurrentWorld(String currentWorld);
/**
* Returns the id of the current dimension, or -1 if unset (i.e. before 1.20.5).
*
* @return id of the current dimension, or -1 if unset
*/
int currentDimensionId();
/**
* Sets the id of the current dimension.
*
* @param currentDimensionId id of the current dimension
*/
void setCurrentDimensionId(int currentDimensionId);
int biomesSent();
void setBiomesSent(int biomesSent);
@@ -0,0 +1,51 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.data.item;
import java.util.List;
/**
* Used for converting items to hashed items and caching them for later use during serverbound packets.
* <p>
* Most of this stays in the internal module given non-permanent, imperfect caching as well as missing converters.
*/
public interface ItemHasher {
/**
* Returns whether this connection is currently processing a clientbound player inventory packet.
* <p>
* Used for checking when it is necessary to track/process item data hashes.
*
* @return true if processing a clientbound inventory packet, false otherwise
*/
boolean isProcessingClientboundInventoryPacket();
void setProcessingClientboundInventoryPacket(boolean processingClientboundInventoryPacket);
/**
* Sets the enchantment registry for this connection.
*
* @param enchantments list of enchantment identifiers
*/
void setEnchantments(List<String> enchantments);
}
@@ -58,7 +58,7 @@ public class BlockChangeRecord1_16_2 implements BlockChangeRecord {
@Override
public short getY(int chunkSectionY) {
Preconditions.checkArgument(chunkSectionY >= 0, "Invalid chunkSectionY: " + chunkSectionY);
Preconditions.checkArgument(chunkSectionY >= 0, "Invalid chunkSectionY: %s", chunkSectionY);
return (short) ((chunkSectionY << 4) + sectionY);
}
@@ -33,7 +33,6 @@ public enum BlockFace {
TOP((byte) 0, (byte) 1, (byte) 0, EnumAxis.Y),
BOTTOM((byte) 0, (byte) -1, (byte) 0, EnumAxis.Y);
public static final BlockFace[] HORIZONTAL = {NORTH, SOUTH, EAST, WEST};
private static final Map<BlockFace, BlockFace> opposites = new EnumMap<>(BlockFace.class);
static {
@@ -24,22 +24,28 @@ package com.viaversion.viaversion.api.minecraft;
public enum GameMode {
NOT_SET(""),
SURVIVAL("Survival Mode"),
CREATIVE("Creative Mode"),
ADVENTURE("Adventure Mode"),
SPECTATOR("Spectator Mode");
NOT_SET("", -1),
SURVIVAL("Survival Mode", 0),
CREATIVE("Creative Mode", 1),
ADVENTURE("Adventure Mode", 2),
SPECTATOR("Spectator Mode", 3);
private final String text;
private final int id;
GameMode(String text) {
GameMode(String text, final int id) {
this.text = text;
this.id = id;
}
public String text() {
return text;
}
public int id() {
return id;
}
public static GameMode getById(int id) {
return switch (id) {
case -1 -> NOT_SET;
@@ -22,11 +22,35 @@
*/
package com.viaversion.viaversion.api.minecraft;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
public record GameProfile(@Nullable String name, @Nullable UUID id, Property[] properties) {
public record GameProfile(@Nullable String name, @Nullable UUID id, Property[] properties, boolean dynamic) {
public GameProfile(@Nullable final String name, @Nullable final UUID id, final Property[] properties) {
this(name, id, properties, true);
}
public GameProfile(@Nullable final String name, @Nullable final UUID id) {
this(name, id, new Property[0]);
}
public Map<String, List<Property>> propertiesMap() {
final Map<String, List<Property>> map = new HashMap<>();
for (Property property : properties) {
map.computeIfAbsent(property.name(), k -> new ArrayList<>()).add(property);
}
return map;
}
public record Property(String name, String value, @Nullable String signature) {
public Property(final String name, final String value) {
this(name, value, null);
}
}
}
@@ -23,6 +23,8 @@
package com.viaversion.viaversion.api.minecraft;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
import java.util.function.Supplier;
public interface Holder<T> {
@@ -88,5 +90,24 @@ public interface Holder<T> {
* @param rewriteFunction the function to rewrite the id
* @return a new holder with the id rewritten, or self
*/
Holder<T> updateId(final Int2IntFunction rewriteFunction);
default Holder<T> updateId(final Int2IntFunction rewriteFunction) {
return this.updateId(rewriteFunction, null);
}
/**
* Returns a new holder with the id rewritten using the given function, or self if this is a direct holder or the id did not change.
*
* @param rewriteFunction the function to rewrite the id
* @param ifMissing a supplier that provides a new holder if the id is missing (i.e. -1)
* @return a new holder with the id rewritten, or self
*/
Holder<T> updateId(Int2IntFunction rewriteFunction, Supplier<Holder<T>> ifMissing);
/**
* Returns a new holder with the value rewritten using the given function, or self if this is an id holder or the value did not change.
*
* @param rewriteFunction the function to rewrite the value
* @return a new holder with the value rewritten, or self
*/
Holder<T> updateValue(final Function<T, T> rewriteFunction);
}
@@ -22,7 +22,11 @@
*/
package com.viaversion.viaversion.api.minecraft;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
/**
* Set of ids that either holds a string tag key or an array of ids.
@@ -32,7 +36,7 @@ public interface HolderSet {
/**
* Creates a new holder set for the given tag.
*
* @param tagKey the tag key
* @param tagKey the tag key, not including '#'
* @return a new holder set
*/
static HolderSet of(final String tagKey) {
@@ -49,10 +53,29 @@ public interface HolderSet {
return new HolderSetImpl.Ids(ids);
}
static HolderSet fromTag(final Tag tag, final Function<String, Integer> mappingFunction) {
if (tag instanceof StringTag stringTag) {
if (stringTag.getValue().startsWith("#")) {
return HolderSet.of(stringTag.getValue().substring(1));
}
final int id = mappingFunction.apply(stringTag.getValue());
return HolderSet.of(new int[]{id});
} else if (tag instanceof ListTag<?> listTag) {
final int[] ids = new int[listTag.size()];
for (int i = 0; i < listTag.size(); i++) {
final String value = ((StringTag) listTag.get(i)).getValue();
ids[i] = mappingFunction.apply(value);
}
return HolderSet.of(ids);
}
throw new IllegalArgumentException();
}
/**
* Gets the tag key.
* Gets the tag key, not including '#'.
*
* @return the tag key
* @return the tag key without a '#'
* @see #hasTagKey()
*/
String tagKey();
@@ -67,11 +67,17 @@ final class HolderSetImpl {
@Override
public HolderSet rewrite(final Int2IntFunction idRewriter) {
// Filter out negative ids as they would come from missing VB mapping data. This happens especially
// with block ids which are not mapped and thus written as -1 so VV rewriters can cancel them nicely.
final int[] mappedIds = new int[ids.length];
for (int i = 0; i < mappedIds.length; i++) {
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
int validCount = 0;
for (final int id : ids) {
final int mappedId = idRewriter.applyAsInt(id);
if (mappedId != -1) {
mappedIds[validCount++] = mappedId;
}
}
return new Ids(mappedIds);
return new Ids(validCount == ids.length ? mappedIds : Arrays.copyOf(mappedIds, validCount));
}
@Override
@@ -24,6 +24,8 @@ package com.viaversion.viaversion.api.minecraft;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
import java.util.function.Supplier;
record IdHolder<T>(int id) implements Holder<T> {
@@ -47,14 +49,22 @@ record IdHolder<T>(int id) implements Holder<T> {
}
@Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
public Holder<T> updateId(final Int2IntFunction rewriteFunction, final Supplier<Holder<T>> ifMissing) {
final int rewrittenId = rewriteFunction.applyAsInt(id);
if (rewrittenId == id) {
return this;
}
if (rewrittenId == -1) {
if (ifMissing != null) {
return ifMissing.get();
}
throw new IllegalArgumentException("Received invalid id in updateId");
}
return Holder.of(rewrittenId);
}
@Override
public Holder<T> updateValue(final Function<T, T> rewriteFunction) {
return this;
}
}
@@ -121,7 +121,7 @@ public final class Particle implements IdHolder, Copyable {
@Override
public ParticleData<T> copy() {
return new ParticleData<>(type, copy(value));
return new ParticleData<>(type, Copyable.copy(value));
}
@Override
@@ -0,0 +1,37 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Profile that can be either dynamically filled by the client or is already static.
* The additional fields are optional overrides.
*/
public record ResolvableProfile(GameProfile profile, @Nullable String bodyTexture, @Nullable String capeTexture,
@Nullable String elytraTexture, @Nullable Integer modelType) {
public ResolvableProfile(final GameProfile profile) {
this(profile, null, null, null, null);
}
}
@@ -22,11 +22,21 @@
*/
package com.viaversion.viaversion.api.minecraft;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import org.checkerframework.checker.nullness.qual.Nullable;
public record SoundEvent(String identifier, @Nullable Float fixedRange) {
private static final Holder<SoundEvent> UNKNOWN = Holder.of(new SoundEvent("viaversion:unknown", 0F));
public SoundEvent withIdentifier(final String identifier) {
return new SoundEvent(identifier, this.fixedRange);
}
public static @Nullable Holder<SoundEvent> rewriteHolder(@Nullable final Holder<SoundEvent> holder, final Int2IntFunction soundRewriteFunction) {
if (holder == null) {
return null;
}
return holder.updateId(soundRewriteFunction, () -> UNKNOWN);
}
}
@@ -23,6 +23,8 @@
package com.viaversion.viaversion.api.minecraft;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
import java.util.function.Supplier;
record ValueHolder<T>(T value) implements Holder<T> {
@@ -42,7 +44,13 @@ record ValueHolder<T>(T value) implements Holder<T> {
}
@Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
public Holder<T> updateId(final Int2IntFunction rewriteFunction, final Supplier<Holder<T>> ifMissing) {
return this;
}
@Override
public Holder<T> updateValue(final Function<T, T> rewriteFunction) {
final T rewrittenValue = rewriteFunction.apply(value);
return rewrittenValue != value ? Holder.of(rewrittenValue) : this;
}
}
@@ -0,0 +1,28 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft;
public record Vector3d(double x, double y, double z) {
public static final Vector3d ZERO = new Vector3d(0, 0, 0);
}
@@ -0,0 +1,64 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.util.Key;
import java.util.List;
public interface CodecContext {
RegistryAccess registryAccess();
boolean mapped();
boolean isSupported(StructuredDataKey<?> key);
interface RegistryAccess {
Key item(int id);
Key enchantment(int id);
Key attributeModifier(int id);
Key dataComponentType(int id);
Key entity(int id);
Key blockEntity(int id);
Key sound(int id);
Key key(MappingData.MappingType mappingType, int id);
int id(MappingData.MappingType mappingType, String identifier);
static RegistryAccess of(final List<String> enchantments, final MappingData mappingData) {
return new RegistryAccessImpl(enchantments, mappingData);
}
RegistryAccess withMapped(boolean mapped);
}
}
@@ -0,0 +1,110 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.type.Type;
import java.util.function.Consumer;
public class DelegatingOps implements Ops {
private final Ops delegate;
public DelegatingOps(final Ops delegate) {
this.delegate = delegate;
}
@Override
public CodecContext context() {
return delegate.context();
}
@Override
public void writeByte(final byte b) {
delegate.writeByte(b);
}
@Override
public void writeBytes(final byte[] array) {
delegate.writeBytes(array);
}
@Override
public void writeBoolean(final boolean b) {
delegate.writeBoolean(b);
}
@Override
public void writeShort(final short s) {
delegate.writeShort(s);
}
@Override
public void writeString(final CharSequence sequence) {
delegate.writeString(sequence);
}
@Override
public void writeInt(final int i) {
delegate.writeInt(i);
}
@Override
public void writeLong(final long l) {
delegate.writeLong(l);
}
@Override
public void writeFloat(final float f) {
delegate.writeFloat(f);
}
@Override
public void writeDouble(final double d) {
delegate.writeDouble(d);
}
@Override
public void writeInts(final int[] array) {
delegate.writeInts(array);
}
@Override
public void writeLongs(final long[] array) {
delegate.writeLongs(array);
}
@Override
public void writeList(final Consumer<ListSerializer> consumer) {
delegate.writeList(consumer);
}
@Override
public void writeMap(final Consumer<MapSerializer> consumer) {
delegate.writeMap(consumer);
}
@Override
public <V> void write(final Type<V> type, final V value) {
delegate.write(type, value);
}
}
@@ -0,0 +1,135 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import java.util.Objects;
import java.util.function.Consumer;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface Ops {
CodecContext context();
void writeByte(byte b);
void writeBytes(byte[] array);
void writeBoolean(boolean b);
void writeShort(short s);
void writeString(CharSequence sequence);
void writeInt(int i);
void writeLong(long l);
void writeFloat(float f);
void writeDouble(double d);
void writeInts(int[] array);
void writeLongs(long[] array);
void writeList(Consumer<ListSerializer> consumer);
void writeMap(Consumer<MapSerializer> consumer);
<V> void write(final Type<V> type, final V value);
interface ListSerializer {
<V> ListSerializer write(Type<V> valueType, V value);
ListSerializer writeList(Consumer<ListSerializer> consumer);
ListSerializer writeMap(Consumer<MapSerializer> consumer);
}
interface MapSerializer {
<K, V> MapSerializer write(Type<K> keyType, K key, Type<V> valueType, V value);
default <V> MapSerializer write(final String key, final Type<V> type, final V value) {
write(Types.STRING, key, type, value);
return this;
}
/**
* Writes the given value or default value if the value is null.
*
* @param key map key
* @param type type of the value
* @param value the value to write, or null
* @param def default value to write if the value is null
* @return self
* @param <V> value type
*/
default <V> MapSerializer write(final String key, final Type<V> type, @Nullable final V value, final V def) {
write(Types.STRING, key, type, value != null ? value : def);
return this;
}
/**
* Writes the given value if it is not null.
*
* @param key map key
* @param type type of the value
* @param value the value to write, or null
* @return self
* @param <V> value type
*/
default <V> MapSerializer writeOptional(final String key, final Type<V> type, @Nullable final V value) {
if (value != null) {
write(Types.STRING, key, type, value);
}
return this;
}
/**
* Writes the given value if it is not null and not equal to the default value.
*
* @param key map key
* @param type type of the value
* @param value the value to write, or null
* @param def default value to compare against
* @return self
* @param <V> value type
*/
default <V> MapSerializer writeOptional(final String key, final Type<V> type, @Nullable final V value, final V def) {
if (value != null && !Objects.deepEquals(value, def)) {
write(Types.STRING, key, type, value);
}
return this;
}
MapSerializer writeList(String key, Consumer<ListSerializer> consumer);
MapSerializer writeMap(String key, Consumer<MapSerializer> consumer);
<T> MapSerializer writeInlinedMap(Type<T> valueType, T value);
}
}
@@ -0,0 +1,108 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.util.Key;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
final class RegistryAccessImpl implements CodecContext.RegistryAccess {
private final List<String> enchantments;
private final MappingData mappingData;
private final boolean mapped;
RegistryAccessImpl(final List<String> enchantments, final MappingData mappingData) {
this.enchantments = enchantments;
this.mappingData = mappingData;
this.mapped = false;
}
private RegistryAccessImpl(final List<String> enchantments, final MappingData mappingData, final boolean mapped) {
this.enchantments = enchantments;
this.mappingData = mappingData;
this.mapped = mapped;
}
@Override
public Key item(final int id) {
return key(mappingData.getFullItemMappings(), id);
}
@Override
public Key enchantment(final int id) {
final String identifier = id >= 0 && id < this.enchantments.size() ? this.enchantments.get(id) : null;
return key(identifier, id);
}
@Override
public Key attributeModifier(final int id) {
return key(mappingData.getAttributeMappings(), id);
}
@Override
public Key dataComponentType(final int id) {
return key(mappingData.getDataComponentSerializerMappings(), id);
}
@Override
public Key entity(final int id) {
return key(mappingData.getEntityMappings(), id);
}
@Override
public Key blockEntity(final int id) {
return key(mappingData.getBlockEntityMappings(), id);
}
@Override
public Key sound(final int id) {
return key(mappingData.getFullSoundMappings(), id);
}
@Override
public Key key(final MappingData.MappingType mappingType, final int id) {
return key(mappingData.getFullMappings(mappingType), id);
}
@Override
public int id(final MappingData.MappingType mappingType, final String identifier) {
final FullMappings mappings = mappingData.getFullMappings(mappingType);
return mapped ? mappings.mappedId(identifier) : mappings.id(identifier);
}
private Key key(final FullMappings mappings, final int id) {
final String identifier = mapped ? mappings.mappedIdentifier(id) : mappings.identifier(id);
return key(identifier, id);
}
private Key key(@Nullable final String identifier, final int id) {
return identifier != null ? Key.of(identifier) : Key.of("viaversion", "unknown/" + id);
}
@Override
public CodecContext.RegistryAccess withMapped(final boolean mapped) {
return this.mapped == mapped ? this : new RegistryAccessImpl(this.enchantments, this.mappingData, mapped);
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.type.Type;
import java.util.function.Consumer;
public class ThrowingOps implements Ops {
@Override
public CodecContext context() {
throw new UnsupportedOperationException();
}
@Override
public void writeByte(final byte b) {
throw new UnsupportedOperationException();
}
@Override
public void writeBytes(final byte[] array) {
throw new UnsupportedOperationException();
}
@Override
public void writeBoolean(final boolean b) {
throw new UnsupportedOperationException();
}
@Override
public void writeShort(final short s) {
throw new UnsupportedOperationException();
}
@Override
public void writeString(final CharSequence sequence) {
throw new UnsupportedOperationException();
}
@Override
public void writeInt(final int i) {
throw new UnsupportedOperationException();
}
@Override
public void writeLong(final long l) {
throw new UnsupportedOperationException();
}
@Override
public void writeFloat(final float f) {
throw new UnsupportedOperationException();
}
@Override
public void writeDouble(final double d) {
throw new UnsupportedOperationException();
}
@Override
public void writeInts(final int[] array) {
throw new UnsupportedOperationException();
}
@Override
public void writeLongs(final long[] array) {
throw new UnsupportedOperationException();
}
@Override
public void writeList(final Consumer<ListSerializer> consumer) {
throw new UnsupportedOperationException();
}
@Override
public void writeMap(final Consumer<MapSerializer> consumer) {
throw new UnsupportedOperationException();
}
@Override
public <V> void write(final Type<V> type, final V value) {
throw new UnsupportedOperationException();
}
}
@@ -20,22 +20,26 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
package com.viaversion.viaversion.api.minecraft.codec.hash;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType1_12;
import java.util.List;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
public final class Types1_12 {
/**
* Hash operations. Note that this is different from Vanilla codecs, where this
* instead acts as a (re-usable) hasher directly rather than each method having
* self-contained return values.
*/
public interface Hasher extends Ops {
/**
* Entity data type for 1.12
* Returns the current hash value.
*
* @return the current hash value
*/
public static final Type<EntityData> ENTITY_DATA = new EntityDataType1_12();
int hash();
/**
* Entity data list type for 1.12
* Resets the hasher to its initial state.
*/
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
void reset();
}
@@ -23,6 +23,8 @@
package com.viaversion.viaversion.api.minecraft.data;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.util.ArrayUtil;
import com.viaversion.viaversion.util.Copyable;
import io.netty.buffer.ByteBuf;
import java.util.Objects;
@@ -61,7 +63,7 @@ final class FilledStructuredData<T> implements StructuredData<T> {
@Override
public StructuredData<T> copy() {
return new FilledStructuredData<>(this.key, this.copy(this.value), this.id);
return new FilledStructuredData<>(this.key, Copyable.copy(this.value), this.id);
}
@Override
@@ -101,7 +103,7 @@ final class FilledStructuredData<T> implements StructuredData<T> {
public String toString() {
return "FilledStructuredData{" +
"key=" + key +
", value=" + value +
", value=" + ArrayUtil.toString(value) +
", id=" + id +
'}';
}
@@ -241,7 +241,7 @@ public final class StructuredDataContainer implements Copyable {
/**
* Sets the lookup for serializer ids. Required to call most of the other methods.
*
* @param protocol protocol to retreive the id of the serializer from
* @param protocol protocol to retrieve the id of the serializer from
* @param mappedNames if the names are mapped (true if structures from the mapped version are added, false for the unmapped version)
*/
public void setIdLookup(final Protocol<?, ?, ?, ?> protocol, final boolean mappedNames) {
@@ -284,6 +284,10 @@ public final class StructuredDataContainer implements Copyable {
return data;
}
public boolean isEmpty() {
return data.isEmpty();
}
@Override
public String toString() {
return "StructuredDataContainer{" +
@@ -27,57 +27,72 @@ import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.EitherHolder;
import com.viaversion.viaversion.api.minecraft.GameProfile;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_20_5;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_2;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_5;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate.AdventureModePredicateType1_21_5;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21;
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
import com.viaversion.viaversion.api.minecraft.item.data.Bee;
import com.viaversion.viaversion.api.minecraft.item.data.BlockEntityData;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.CustomModelData1_21_4;
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant;
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
import com.viaversion.viaversion.api.minecraft.item.data.DebugStickState;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantable;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.EnumTypes;
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.FoodProperties1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.ItemModel;
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
import com.viaversion.viaversion.api.minecraft.item.data.LockCode;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
import com.viaversion.viaversion.api.minecraft.item.data.ProvidesTrimMaterial;
import com.viaversion.viaversion.api.minecraft.item.data.Repairable;
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
import com.viaversion.viaversion.api.minecraft.item.data.TooltipDisplay;
import com.viaversion.viaversion.api.minecraft.item.data.TropicalFishPattern;
import com.viaversion.viaversion.api.minecraft.item.data.EntityData;
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.minecraft.item.data.Weapon;
import com.viaversion.viaversion.api.minecraft.item.data.WritableBook;
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.EitherType;
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.api.type.types.version.Types1_21_5;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
import com.viaversion.viaversion.util.Either;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Unit;
/**
* Holds data component keys.
*
* @param identifier string identifier
* @param type data type
* @param <T> data type
* @see VersionedTypes
*/
public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<CompoundTag> CUSTOM_DATA = new StructuredDataKey<>("custom_data", Types.COMPOUND_TAG);
@@ -86,20 +101,20 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Integer> DAMAGE = new StructuredDataKey<>("damage", Types.VAR_INT);
public static final StructuredDataKey<Unbreakable> UNBREAKABLE1_20_5 = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE);
public static final StructuredDataKey<Unit> UNBREAKABLE1_21_5 = new StructuredDataKey<>("unbreakable", Types.EMPTY);
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
public static final StructuredDataKey<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<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TEXT_COMPONENT_TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TEXT_COMPONENT_TAG);
public static final StructuredDataKey<ItemModel> ITEM_MODEL = new StructuredDataKey<>("item_model", ItemModel.TYPE);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TEXT_COMPONENT_TAG, 256));
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", EnumTypes.RARITY);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS1_20_5 = new StructuredDataKey<>("enchantments", Enchantments.TYPE1_20_5);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS1_21_5 = new StructuredDataKey<>("enchantments", Enchantments.TYPE1_21_5);
// 1.21.5+ predicates are in their own key classes
public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON1_20_5 = new StructuredDataKey<>("can_place_on", AdventureModePredicate.TYPE1_20_5);
public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON1_21_5 = new StructuredDataKey<>("can_place_on", new AdventureModePredicateType1_21_5(Types1_21_5.STRUCTURED_DATA_ARRAY));
public static final StructuredDataKey<AdventureModePredicate> CAN_BREAK1_20_5 = new StructuredDataKey<>("can_break", AdventureModePredicate.TYPE1_20_5);
public static final StructuredDataKey<AdventureModePredicate> CAN_BREAK1_21_5 = new StructuredDataKey<>("can_break", new AdventureModePredicateType1_21_5(Types1_21_5.STRUCTURED_DATA_ARRAY));
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.TYPE1_21);
public static final StructuredDataKey<AttributeModifiers1_21> ATTRIBUTE_MODIFIERS1_21_5 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_21.TYPE1_21_5);
public static final StructuredDataKey<AttributeModifiers1_21> ATTRIBUTE_MODIFIERS1_21_6 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_21.TYPE1_21_6);
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);
@@ -113,21 +128,19 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
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<Item> USE_REMAINDER1_21_5 = new StructuredDataKey<>("use_remainder", Types1_21_5.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> TOOL1_20_5 = new StructuredDataKey<>("tool", ToolProperties.TYPE1_20_5);
public static final StructuredDataKey<ToolProperties> TOOL1_21_5 = new StructuredDataKey<>("tool", ToolProperties.TYPE1_21_5);
public static final StructuredDataKey<Weapon> WEAPON = new StructuredDataKey<>("weapon", Weapon.TYPE);
public static final StructuredDataKey<Integer> ENCHANTABLE = new StructuredDataKey<>("enchantable", Types.VAR_INT);
public static final StructuredDataKey<Enchantable> ENCHANTABLE = new StructuredDataKey<>("enchantable", Enchantable.TYPE);
public static final StructuredDataKey<Equippable> EQUIPPABLE1_21_2 = new StructuredDataKey<>("equippable", Equippable.TYPE1_21_2);
public static final StructuredDataKey<Equippable> EQUIPPABLE1_21_5 = new StructuredDataKey<>("equippable", Equippable.TYPE1_21_5);
public static final StructuredDataKey<HolderSet> REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET);
public static final StructuredDataKey<Equippable> EQUIPPABLE1_21_6 = new StructuredDataKey<>("equippable", Equippable.TYPE1_21_6);
public static final StructuredDataKey<Repairable> REPAIRABLE = new StructuredDataKey<>("repairable", Repairable.TYPE);
public static final StructuredDataKey<Unit> GLIDER = new StructuredDataKey<>("glider", Types.EMPTY);
public static final StructuredDataKey<String> TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.STRING);
public static final StructuredDataKey<Key> TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.RESOURCE_LOCATION);
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE);
public static final StructuredDataKey<BlocksAttacks> BLOCKS_ATTACKS = new StructuredDataKey<>("blocks_attacks", BlocksAttacks.TYPE);
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS1_20_5 = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE1_20_5);
@@ -138,30 +151,22 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Integer> MAP_ID = new StructuredDataKey<>("map_id", Types.VAR_INT);
public static final StructuredDataKey<CompoundTag> MAP_DECORATIONS = new StructuredDataKey<>("map_decorations", Types.COMPOUND_TAG);
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[]> CHARGED_PROJECTILES1_21_5 = new StructuredDataKey<>("charged_projectiles", Types1_21_5.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<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<Item[]> BUNDLE_CONTENTS1_21_5 = new StructuredDataKey<>("bundle_contents", Types1_21_5.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<Float> POTION_DURATION_SCALE = new StructuredDataKey<>("potion_duration_scale", Types.FLOAT);
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<WritableBook> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", WritableBook.TYPE);
public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE);
public static final StructuredDataKey<ArmorTrim> TRIM1_20_5 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_20_5);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_2 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_2);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_4 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_4);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_5 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_5);
public static final StructuredDataKey<CompoundTag> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<DebugStickState> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", DebugStickState.TYPE);
public static final StructuredDataKey<CompoundTag> ENTITY_DATA1_20_5 = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<EntityData> ENTITY_DATA1_21_9 = new StructuredDataKey<>("entity_data", EntityData.TYPE);
public static final StructuredDataKey<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA1_20_5 = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<BlockEntityData> BLOCK_ENTITY_DATA1_21_9 = new StructuredDataKey<>("block_entity_data", BlockEntityData.TYPE);
public static final StructuredDataKey<Holder<Instrument1_20_5>> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
public static final StructuredDataKey<EitherHolder<Instrument1_21_2>> INSTRUMENT1_21_5 = new StructuredDataKey<>("instrument", Instrument1_21_2.EITHER_HOLDER_TYPE);
@@ -169,51 +174,58 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT);
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE1_21 = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE1_21);
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE1_21_5 = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE1_21_5);
public static final StructuredDataKey<String> PROVIDES_BANNER_PATTERNS = new StructuredDataKey<>("provides_banner_patterns", Types.STRING);
public static final StructuredDataKey<Key> PROVIDES_BANNER_PATTERNS = new StructuredDataKey<>("provides_banner_patterns", Types.TAG_KEY);
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG);
public static final StructuredDataKey<LodestoneTracker> LODESTONE_TRACKER = new StructuredDataKey<>("lodestone_tracker", LodestoneTracker.TYPE);
public static final StructuredDataKey<FireworkExplosion> FIREWORK_EXPLOSION = new StructuredDataKey<>("firework_explosion", FireworkExplosion.TYPE);
public static final StructuredDataKey<Fireworks> FIREWORKS = new StructuredDataKey<>("fireworks", Fireworks.TYPE);
public static final StructuredDataKey<GameProfile> PROFILE = new StructuredDataKey<>("profile", Types.GAME_PROFILE);
public static final StructuredDataKey<String> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Types.STRING);
public static final StructuredDataKey<GameProfile> PROFILE1_20_5 = new StructuredDataKey<>("profile", Types.GAME_PROFILE);
public static final StructuredDataKey<ResolvableProfile> PROFILE1_21_9 = new StructuredDataKey<>("profile", Types.RESOLVABLE_PROFILE);
public static final StructuredDataKey<Key> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Types.RESOURCE_LOCATION);
public static final StructuredDataKey<BannerPatternLayer[]> BANNER_PATTERNS = new StructuredDataKey<>("banner_patterns", BannerPatternLayer.ARRAY_TYPE);
public static final StructuredDataKey<Integer> BASE_COLOR = new StructuredDataKey<>("base_color", Types.VAR_INT);
public static final StructuredDataKey<Integer> BASE_COLOR = new StructuredDataKey<>("base_color", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
public static final StructuredDataKey<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<Item[]> CONTAINER1_21_5 = new StructuredDataKey<>("container", Types1_21_5.ITEM_ARRAY);
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE);
public static final StructuredDataKey<Bee[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);
public static final StructuredDataKey<Bee[]> BEES1_20_5 = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE1_20_5);
public static final StructuredDataKey<Bee[]> BEES1_21_9 = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE1_21_9);
public static final StructuredDataKey<Tag> LOCK1_20_5 = new StructuredDataKey<>("lock", Types.TAG);
public static final StructuredDataKey<LockCode> LOCK1_21_2 = new StructuredDataKey<>("lock", LockCode.TYPE);
public static final StructuredDataKey<CompoundTag> CONTAINER_LOOT = new StructuredDataKey<>("container_loot", Types.COMPOUND_TAG);
public static final StructuredDataKey<Holder<SoundEvent>> BREAK_SOUND = new StructuredDataKey<>("break_sound", Types.SOUND_EVENT);
public static final StructuredDataKey<Integer> VILLAGER_VARIANT = new StructuredDataKey<>("villager/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> VILLAGER_VARIANT = new StructuredDataKey<>("villager/variant", EnumTypes.VILLAGER_TYPE);
public static final StructuredDataKey<Integer> WOLF_VARIANT = new StructuredDataKey<>("wolf/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> WOLF_SOUND_VARIANT = new StructuredDataKey<>("wolf/sound_variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> WOLF_COLLAR = new StructuredDataKey<>("wolf/collar", Types.VAR_INT);
public static final StructuredDataKey<Integer> FOX_VARIANT = new StructuredDataKey<>("fox/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> SALMON_SIZE = new StructuredDataKey<>("salmon/size", Types.VAR_INT);
public static final StructuredDataKey<Integer> PARROT_VARIANT = new StructuredDataKey<>("parrot/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> TROPICAL_FISH_PATTERN = new StructuredDataKey<>("tropical_fish/pattern", Types.VAR_INT);
public static final StructuredDataKey<Integer> TROPICAL_FISH_BASE_COLOR = new StructuredDataKey<>("tropical_fish/base_color", Types.VAR_INT);
public static final StructuredDataKey<Integer> TROPICAL_FISH_PATTERN_COLOR = new StructuredDataKey<>("tropical_fish/pattern_color", Types.VAR_INT);
public static final StructuredDataKey<Integer> MOOSHROOM_VARIANT = new StructuredDataKey<>("mooshroom/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> RABBIT_VARIANT = new StructuredDataKey<>("rabbit/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> WOLF_COLLAR = new StructuredDataKey<>("wolf/collar", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<Integer> FOX_VARIANT = new StructuredDataKey<>("fox/variant", EnumTypes.FOX_VARIANT);
public static final StructuredDataKey<Integer> SALMON_SIZE = new StructuredDataKey<>("salmon/size", EnumTypes.SALMON_VARIANT);
public static final StructuredDataKey<Integer> PARROT_VARIANT = new StructuredDataKey<>("parrot/variant", EnumTypes.PARROT_VARIANT);
public static final StructuredDataKey<TropicalFishPattern> TROPICAL_FISH_PATTERN = new StructuredDataKey<>("tropical_fish/pattern", TropicalFishPattern.TYPE);
public static final StructuredDataKey<Integer> TROPICAL_FISH_BASE_COLOR = new StructuredDataKey<>("tropical_fish/base_color", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<Integer> TROPICAL_FISH_PATTERN_COLOR = new StructuredDataKey<>("tropical_fish/pattern_color", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<Integer> MOOSHROOM_VARIANT = new StructuredDataKey<>("mooshroom/variant", EnumTypes.MUSHROOM_COW_VARIANT);
public static final StructuredDataKey<Integer> RABBIT_VARIANT = new StructuredDataKey<>("rabbit/variant", EnumTypes.RABBIT_VARIANT);
public static final StructuredDataKey<Integer> PIG_VARIANT = new StructuredDataKey<>("pig/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> COW_VARIANT = new StructuredDataKey<>("cow/variant", Types.VAR_INT);
public static final StructuredDataKey<Either<Integer, String>> CHICKEN_VARIANT = new StructuredDataKey<>("chicken/variant", new EitherType<>(Types.VAR_INT, Types.STRING)); // ???
public static final StructuredDataKey<Integer> FROG_VARIANT = new StructuredDataKey<>("frog/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> HORSE_VARIANT = new StructuredDataKey<>("horse/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> HORSE_VARIANT = new StructuredDataKey<>("horse/variant", EnumTypes.HORSE_VARIANT);
public static final StructuredDataKey<Holder<PaintingVariant>> PAINTING_VARIANT = new StructuredDataKey<>("painting/variant", PaintingVariant.TYPE1_21_2);
public static final StructuredDataKey<Integer> LLAMA_VARIANT = new StructuredDataKey<>("llama/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> AXOLOTL_VARIANT = new StructuredDataKey<>("axolotl/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> LLAMA_VARIANT = new StructuredDataKey<>("llama/variant", EnumTypes.LLAMA_VARIANT);
public static final StructuredDataKey<Integer> AXOLOTL_VARIANT = new StructuredDataKey<>("axolotl/variant", EnumTypes.AXOLOTL_VARIANT);
public static final StructuredDataKey<Integer> CAT_VARIANT = new StructuredDataKey<>("cat/variant", Types.VAR_INT);
public static final StructuredDataKey<Integer> CAT_COLLAR = new StructuredDataKey<>("cat/collar", Types.VAR_INT);
public static final StructuredDataKey<Integer> SHEEP_COLOR = new StructuredDataKey<>("sheep/color", Types.VAR_INT);
public static final StructuredDataKey<Integer> SHULKER_COLOR = new StructuredDataKey<>("shulker/color", Types.VAR_INT);
public static final StructuredDataKey<Integer> CAT_COLLAR = new StructuredDataKey<>("cat/collar", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<Integer> SHEEP_COLOR = new StructuredDataKey<>("sheep/color", EnumTypes.DYE_COLOR);
public static final StructuredDataKey<Integer> SHULKER_COLOR = new StructuredDataKey<>("shulker/color", EnumTypes.DYE_COLOR);
// These are only safe to use after protocol loading
public static final StructuredDataKeys1_20_5 V1_20_5 = VersionedTypes.V1_20_5.structuredDataKeys();
public static final StructuredDataKeys1_20_5 V1_21 = VersionedTypes.V1_21.structuredDataKeys();
public static final StructuredDataKeys1_21_2 V1_21_2 = VersionedTypes.V1_21_2.structuredDataKeys();
public static final StructuredDataKeys1_21_2 V1_21_4 = VersionedTypes.V1_21_4.structuredDataKeys();
public static final StructuredDataKeys1_21_5 V1_21_5 = VersionedTypes.V1_21_5.structuredDataKeys();
public static final StructuredDataKeys1_21_5 V1_21_6 = VersionedTypes.V1_21_6.structuredDataKeys();
public static final StructuredDataKeys1_21_5 V1_21_9 = VersionedTypes.V1_21_9.structuredDataKeys();
@Override
public String toString() {
@@ -0,0 +1,40 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.data.version;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public class StructuredDataKeys1_20_5 extends VersionedStructuredDataKeys {
public final StructuredDataKey<Item[]> container;
public final StructuredDataKey<Item[]> chargedProjectiles;
public final StructuredDataKey<Item[]> bundleContents;
public StructuredDataKeys1_20_5(final VersionedTypesHolder types) {
this.container = add("container", types.itemArray());
this.chargedProjectiles = add("charged_projectiles", types.itemArray());
this.bundleContents = add("bundle_contents", types.itemArray());
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.data.version;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.ContainterContents.ContainerContentsType;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public class StructuredDataKeys1_21_2 extends VersionedStructuredDataKeys {
public final StructuredDataKey<Item[]> container;
public final StructuredDataKey<Item[]> chargedProjectiles;
public final StructuredDataKey<Item[]> bundleContents;
public final StructuredDataKey<Item> useRemainder;
public StructuredDataKeys1_21_2(final VersionedTypesHolder types) {
this.container = add("container", new ContainerContentsType(types.item()));
this.chargedProjectiles = add("charged_projectiles", types.itemArray());
this.bundleContents = add("bundle_contents", types.itemArray());
this.useRemainder = add("use_remainder", types.item());
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.data.version;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate.AdventureModePredicateType1_21_5;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public class StructuredDataKeys1_21_5 extends StructuredDataKeys1_21_2 {
public final StructuredDataKey<AdventureModePredicate> canPlaceOn;
public final StructuredDataKey<AdventureModePredicate> canBreak;
public StructuredDataKeys1_21_5(final VersionedTypesHolder types) {
super(types);
final AdventureModePredicateType1_21_5 adventureModePredicateType = new AdventureModePredicateType1_21_5(types.structuredDataArray());
this.canPlaceOn = add("can_place_on", adventureModePredicateType);
this.canBreak = add("can_break", adventureModePredicateType);
this.unsupportedForOps.add(this.canPlaceOn);
this.unsupportedForOps.add(this.canBreak);
}
}
@@ -20,25 +20,31 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
package com.viaversion.viaversion.api.minecraft.data.version;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkSectionType1_9;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType1_9;
import it.unimi.dsi.fastutil.objects.ReferenceArraySet;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public final class Types1_9 {
/**
* Entity data type for 1.9
*/
public static final Type<EntityData> ENTITY_DATA = new EntityDataType1_9();
/**
* Entity data list type for 1.9
*/
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
public abstract class VersionedStructuredDataKeys {
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_9();
private final List<StructuredDataKey<?>> keys = new ArrayList<>();
protected final Set<StructuredDataKey<?>> unsupportedForOps = new ReferenceArraySet<>();
protected <T> StructuredDataKey<T> add(final String identifier, final Type<T> type) {
final StructuredDataKey<T> key = new StructuredDataKey<>(identifier, type);
this.keys.add(key);
return key;
}
public List<StructuredDataKey<?>> keys() {
return this.keys;
}
public boolean supportsOps(final StructuredDataKey<?> key) {
return !unsupportedForOps.contains(key);
}
}
@@ -22,8 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class EntityTypes1_10 {
@@ -143,7 +143,7 @@ public class EntityTypes1_10 {
SPIDER(52, ABSTRACT_MONSTER),
CAVE_SPIDER(59, SPIDER);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private static final Int2ObjectMap<EntityType> TYPES;
private final int id;
private final EntityType parent;
@@ -184,7 +184,9 @@ public class EntityTypes1_10 {
}
static {
for (EntityType type : EntityType.values()) {
final EntityType[] values = EntityType.values();
TYPES = new Int2ObjectOpenHashMap<>(values.length);
for (EntityType type : values) {
TYPES.put(type.id, type);
}
}
@@ -230,7 +232,7 @@ public class EntityTypes1_10 {
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
private final int id;
private final int data;
@@ -238,7 +240,7 @@ public class EntityTypes1_10 {
static {
for (ObjectType type : ObjectType.values()) {
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
}
}
@@ -268,7 +270,7 @@ public class EntityTypes1_10 {
}
public static ObjectType findById(final int id, final int data) {
final Map<Integer, ObjectType> types = TYPES.get(id);
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
if (types == null) {
return null;
}
@@ -22,8 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class EntityTypes1_11 {
@@ -168,7 +168,7 @@ public class EntityTypes1_11 {
EVOKER(34, ABSTRACT_MONSTER),
VINDICATOR(36, ABSTRACT_MONSTER);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private static final Int2ObjectMap<EntityType> TYPES;
private final int id;
private final EntityType parent;
@@ -209,7 +209,9 @@ public class EntityTypes1_11 {
}
static {
for (EntityType type : EntityType.values()) {
final EntityType[] values = EntityType.values();
TYPES = new Int2ObjectOpenHashMap<>(values.length);
for (EntityType type : values) {
TYPES.put(type.id, type);
}
}
@@ -257,7 +259,7 @@ public class EntityTypes1_11 {
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
private final int id;
private final int data;
@@ -265,7 +267,7 @@ public class EntityTypes1_11 {
static {
for (ObjectType type : ObjectType.values()) {
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
}
}
@@ -295,7 +297,7 @@ public class EntityTypes1_11 {
}
public static ObjectType findById(final int id, final int data) {
final Map<Integer, ObjectType> types = TYPES.get(id);
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
if (types == null) {
return null;
}
@@ -22,8 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class EntityTypes1_12 {
@@ -174,7 +174,7 @@ public class EntityTypes1_12 {
EVOKER(34, SPELLCASTER_ILLAGER),
ILLUSIONER(37, SPELLCASTER_ILLAGER);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private static final Int2ObjectMap<EntityType> TYPES;
private final int id;
private final EntityType parent;
@@ -215,7 +215,9 @@ public class EntityTypes1_12 {
}
static {
for (EntityType type : EntityType.values()) {
final EntityType[] values = EntityType.values();
TYPES = new Int2ObjectOpenHashMap<>(values.length);
for (EntityType type : values) {
TYPES.put(type.id, type);
}
}
@@ -263,7 +265,7 @@ public class EntityTypes1_12 {
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
private final int id;
private final int data;
@@ -271,7 +273,7 @@ public class EntityTypes1_12 {
static {
for (ObjectType type : ObjectType.values()) {
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
}
}
@@ -301,7 +303,7 @@ public class EntityTypes1_12 {
}
public static ObjectType findById(final int id, final int data) {
final Map<Integer, ObjectType> types = TYPES.get(id);
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
if (types == null) {
return null;
}
@@ -22,8 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class EntityTypes1_13 {
@@ -185,7 +185,7 @@ public class EntityTypes1_13 {
EVOKER(21, SPELLCASTER_ILLAGER),
ILLUSIONER(31, SPELLCASTER_ILLAGER);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private static final Int2ObjectMap<EntityType> TYPES;
private final int id;
private final EntityType parent;
@@ -226,7 +226,9 @@ public class EntityTypes1_13 {
}
static {
for (EntityType type : EntityType.values()) {
final EntityType[] values = EntityType.values();
TYPES = new Int2ObjectOpenHashMap<>(values.length);
for (EntityType type : values) {
TYPES.put(type.id, type);
}
}
@@ -275,7 +277,7 @@ public class EntityTypes1_13 {
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL),
TRIDENT(94, EntityType.TRIDENT);
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
private final int id;
private final int data;
@@ -283,7 +285,7 @@ public class EntityTypes1_13 {
static {
for (ObjectType type : ObjectType.values()) {
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
}
}
@@ -313,7 +315,7 @@ public class EntityTypes1_13 {
}
public static ObjectType findById(final int id, final int data) {
final Map<Integer, ObjectType> types = TYPES.get(id);
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
if (types == null) {
return null;
}
@@ -213,7 +213,7 @@ public enum EntityTypes1_14 implements EntityType {
EntityTypes1_14(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_14(final EntityType parent, @Nullable final String identifier) {
@@ -214,7 +214,7 @@ public enum EntityTypes1_15 implements EntityType {
EntityTypes1_15(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_15(final EntityType parent, @Nullable final String identifier) {
@@ -218,7 +218,7 @@ public enum EntityTypes1_16 implements EntityType {
EntityTypes1_16(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_16(final EntityType parent, @Nullable final String identifier) {
@@ -221,7 +221,7 @@ public enum EntityTypes1_16_2 implements EntityType {
EntityTypes1_16_2(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_16_2(final EntityType parent, @Nullable final String identifier) {
@@ -227,7 +227,7 @@ public enum EntityTypes1_17 implements EntityType {
EntityTypes1_17(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_17(final EntityType parent, @Nullable final String identifier) {
@@ -232,7 +232,7 @@ public enum EntityTypes1_19 implements EntityType {
EntityTypes1_19(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_19(final EntityType parent, @Nullable final String identifier) {
@@ -233,7 +233,7 @@ public enum EntityTypes1_19_3 implements EntityType {
EntityTypes1_19_3(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_19_3(final EntityType parent, @Nullable final String identifier) {
@@ -240,7 +240,7 @@ public enum EntityTypes1_19_4 implements EntityType {
EntityTypes1_19_4(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_19_4(final EntityType parent, @Nullable final String identifier) {
@@ -242,7 +242,7 @@ public enum EntityTypes1_20_3 implements EntityType {
EntityTypes1_20_3(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_20_3(final EntityType parent, @Nullable final String identifier) {
@@ -248,7 +248,7 @@ public enum EntityTypes1_20_5 implements EntityType {
EntityTypes1_20_5(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_20_5(final EntityType parent, @Nullable final String identifier) {
@@ -272,7 +272,7 @@ public enum EntityTypes1_21_2 implements EntityType {
EntityTypes1_21_2(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_2(final EntityType parent, @Nullable final String identifier) {
@@ -271,7 +271,7 @@ public enum EntityTypes1_21_4 implements EntityType {
EntityTypes1_21_4(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_4(final EntityType parent, @Nullable final String identifier) {
@@ -0,0 +1,318 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_21_6 implements EntityType {
ENTITY(null, null),
AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(ENTITY),
EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(ENTITY),
ITEM(ENTITY),
TNT(ENTITY),
OMINOUS_ITEM_SPAWNER(ENTITY),
MARKER(ENTITY),
LIGHTNING_BOLT(ENTITY),
INTERACTION(ENTITY),
DISPLAY(ENTITY, null),
BLOCK_DISPLAY(DISPLAY),
ITEM_DISPLAY(DISPLAY),
TEXT_DISPLAY(DISPLAY),
// Hanging entities
HANGING_ENTITY(ENTITY, null),
LEASH_KNOT(HANGING_ENTITY),
PAINTING(HANGING_ENTITY),
ITEM_FRAME(HANGING_ENTITY),
GLOW_ITEM_FRAME(ITEM_FRAME),
// Projectiles
PROJECTILE(ENTITY, null),
ITEM_PROJECTILE(PROJECTILE, null),
SNOWBALL(ITEM_PROJECTILE),
ENDER_PEARL(ITEM_PROJECTILE),
EGG(ITEM_PROJECTILE),
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
FIREWORK_ROCKET(PROJECTILE),
LLAMA_SPIT(PROJECTILE),
SHULKER_BULLET(PROJECTILE),
FISHING_BOBBER(PROJECTILE),
WITHER_SKULL(PROJECTILE),
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
ABSTRACT_THROWN_POTION(ITEM_PROJECTILE, null),
SPLASH_POTION(ABSTRACT_THROWN_POTION),
LINGERING_POTION(ABSTRACT_THROWN_POTION),
ABSTRACT_ARROW(PROJECTILE, null),
ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(ABSTRACT_ARROW),
ABSTRACT_FIREBALL(ENTITY, null),
FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(ABSTRACT_FIREBALL),
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
// Vehicles
VEHICLE(ENTITY, null),
ABSTRACT_MINECART(VEHICLE, null),
MINECART(ABSTRACT_MINECART),
FURNACE_MINECART(ABSTRACT_MINECART),
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
TNT_MINECART(ABSTRACT_MINECART),
SPAWNER_MINECART(ABSTRACT_MINECART),
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
ABSTRACT_BOAT(VEHICLE, null),
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
ACACIA_BOAT(ABSTRACT_BOAT),
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
BAMBOO_RAFT(ABSTRACT_BOAT),
BIRCH_BOAT(ABSTRACT_BOAT),
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
CHERRY_BOAT(ABSTRACT_BOAT),
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
DARK_OAK_BOAT(ABSTRACT_BOAT),
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
JUNGLE_BOAT(ABSTRACT_BOAT),
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
MANGROVE_BOAT(ABSTRACT_BOAT),
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
OAK_BOAT(ABSTRACT_BOAT),
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
PALE_OAK_BOAT(ABSTRACT_BOAT),
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
SPRUCE_BOAT(ABSTRACT_BOAT),
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
// Living entities as a larger subclass
LIVING_ENTITY(ENTITY, null),
ARMOR_STAND(LIVING_ENTITY),
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),
HAPPY_GHAST(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
MOOSHROOM(ABSTRACT_COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(ABSTRACT_HORSE),
CAMEL(ABSTRACT_HORSE),
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(ABSTRACT_CHESTED_HORSE),
MULE(ABSTRACT_CHESTED_HORSE),
LLAMA(ABSTRACT_CHESTED_HORSE),
TRADER_LLAMA(LLAMA),
// Monsters
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
BLAZE(ABSTRACT_MONSTER),
CREEPER(ABSTRACT_MONSTER),
ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(ABSTRACT_MONSTER),
GIANT(ABSTRACT_MONSTER),
SILVERFISH(ABSTRACT_MONSTER),
VEX(ABSTRACT_MONSTER),
WITHER(ABSTRACT_MONSTER),
BREEZE(ABSTRACT_MONSTER),
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
CREAKING(ABSTRACT_MONSTER),
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(ABSTRACT_SKELETON),
BOGGED(ABSTRACT_SKELETON),
ZOMBIE(ABSTRACT_MONSTER),
DROWNED(ZOMBIE),
HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(ZOMBIE),
GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(GUARDIAN),
SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(SPIDER),
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
// Water mobs
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
DOLPHIN(AGEABLE_WATER_CREATURE),
SQUID(AGEABLE_WATER_CREATURE),
GLOW_SQUID(SQUID),
WATER_ANIMAL(PATHFINDER_MOB, null),
ABSTRACT_FISH(WATER_ANIMAL, null),
PUFFERFISH(ABSTRACT_FISH),
TADPOLE(ABSTRACT_FISH),
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
COD(ABSTRACT_SCHOOLING_FISH),
SALMON(ABSTRACT_SCHOOLING_FISH),
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
// Raiders
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
WITCH(ABSTRACT_RAIDER),
RAVAGER(ABSTRACT_RAIDER),
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
VINDICATOR(ABSTRACT_ILLAGER),
PILLAGER(ABSTRACT_ILLAGER),
EVOKER(SPELLCASTER_ILLAGER),
ILLUSIONER(SPELLCASTER_ILLAGER);
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final EntityType parent;
private final String identifier;
private int id = -1;
EntityTypes1_21_6(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_6(final EntityType parent, @Nullable final String identifier) {
this.parent = parent;
this.identifier = identifier;
}
@Override
public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
}
return id;
}
@Override
public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent;
}
@Override
public boolean isAbstractType() {
return identifier == null;
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
}
}
@@ -0,0 +1,323 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_21_9 implements EntityType {
ENTITY(null, null),
AREA_EFFECT_CLOUD(ENTITY),
END_CRYSTAL(ENTITY),
EVOKER_FANGS(ENTITY),
EXPERIENCE_ORB(ENTITY),
EYE_OF_ENDER(ENTITY),
FALLING_BLOCK(ENTITY),
ITEM(ENTITY),
TNT(ENTITY),
OMINOUS_ITEM_SPAWNER(ENTITY),
MARKER(ENTITY),
LIGHTNING_BOLT(ENTITY),
INTERACTION(ENTITY),
DISPLAY(ENTITY, null),
BLOCK_DISPLAY(DISPLAY),
ITEM_DISPLAY(DISPLAY),
TEXT_DISPLAY(DISPLAY),
// Hanging entities
HANGING_ENTITY(ENTITY, null),
LEASH_KNOT(HANGING_ENTITY),
PAINTING(HANGING_ENTITY),
ITEM_FRAME(HANGING_ENTITY),
GLOW_ITEM_FRAME(ITEM_FRAME),
// Projectiles
PROJECTILE(ENTITY, null),
ITEM_PROJECTILE(PROJECTILE, null),
SNOWBALL(ITEM_PROJECTILE),
ENDER_PEARL(ITEM_PROJECTILE),
EGG(ITEM_PROJECTILE),
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
FIREWORK_ROCKET(PROJECTILE),
LLAMA_SPIT(PROJECTILE),
SHULKER_BULLET(PROJECTILE),
FISHING_BOBBER(PROJECTILE),
WITHER_SKULL(PROJECTILE),
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
ABSTRACT_THROWN_POTION(ITEM_PROJECTILE, null),
SPLASH_POTION(ABSTRACT_THROWN_POTION),
LINGERING_POTION(ABSTRACT_THROWN_POTION),
ABSTRACT_ARROW(PROJECTILE, null),
ARROW(ABSTRACT_ARROW),
SPECTRAL_ARROW(ABSTRACT_ARROW),
TRIDENT(ABSTRACT_ARROW),
ABSTRACT_FIREBALL(ENTITY, null),
FIREBALL(ABSTRACT_FIREBALL),
SMALL_FIREBALL(ABSTRACT_FIREBALL),
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
// Vehicles
VEHICLE(ENTITY, null),
ABSTRACT_MINECART(VEHICLE, null),
MINECART(ABSTRACT_MINECART),
FURNACE_MINECART(ABSTRACT_MINECART),
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
TNT_MINECART(ABSTRACT_MINECART),
SPAWNER_MINECART(ABSTRACT_MINECART),
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
ABSTRACT_BOAT(VEHICLE, null),
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
ACACIA_BOAT(ABSTRACT_BOAT),
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
BAMBOO_RAFT(ABSTRACT_BOAT),
BIRCH_BOAT(ABSTRACT_BOAT),
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
CHERRY_BOAT(ABSTRACT_BOAT),
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
DARK_OAK_BOAT(ABSTRACT_BOAT),
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
JUNGLE_BOAT(ABSTRACT_BOAT),
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
MANGROVE_BOAT(ABSTRACT_BOAT),
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
OAK_BOAT(ABSTRACT_BOAT),
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
PALE_OAK_BOAT(ABSTRACT_BOAT),
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
SPRUCE_BOAT(ABSTRACT_BOAT),
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
// Living entities as a larger subclass
LIVING_ENTITY(ENTITY, null),
ARMOR_STAND(LIVING_ENTITY),
// Players
AVATAR(LIVING_ENTITY, null),
MANNEQUIN(AVATAR),
PLAYER(AVATAR),
// Mobs as a larger subclass
MOB(LIVING_ENTITY, null),
ENDER_DRAGON(MOB),
SLIME(MOB),
MAGMA_CUBE(SLIME),
// Ambient mobs
AMBIENT_CREATURE(MOB, null),
BAT(AMBIENT_CREATURE),
// Flying mobs
FLYING_MOB(MOB, null),
GHAST(FLYING_MOB),
PHANTOM(FLYING_MOB),
// Pathfinder mobs and its subclasses
PATHFINDER_MOB(MOB, null),
ALLAY(PATHFINDER_MOB),
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
SNOW_GOLEM(ABSTRACT_GOLEM),
IRON_GOLEM(ABSTRACT_GOLEM),
SHULKER(ABSTRACT_GOLEM),
COPPER_GOLEM(ABSTRACT_GOLEM),
// Ageable mobs and (tamable) animals
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
VILLAGER(ABSTRACT_VILLAGER),
WANDERING_TRADER(ABSTRACT_VILLAGER),
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
AXOLOTL(ABSTRACT_ANIMAL),
CHICKEN(ABSTRACT_ANIMAL),
PANDA(ABSTRACT_ANIMAL),
PIG(ABSTRACT_ANIMAL),
POLAR_BEAR(ABSTRACT_ANIMAL),
RABBIT(ABSTRACT_ANIMAL),
SHEEP(ABSTRACT_ANIMAL),
BEE(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
FROG(ABSTRACT_ANIMAL),
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
HAPPY_GHAST(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
MOOSHROOM(ABSTRACT_COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
HORSE(ABSTRACT_HORSE),
SKELETON_HORSE(ABSTRACT_HORSE),
ZOMBIE_HORSE(ABSTRACT_HORSE),
CAMEL(ABSTRACT_HORSE),
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
DONKEY(ABSTRACT_CHESTED_HORSE),
MULE(ABSTRACT_CHESTED_HORSE),
LLAMA(ABSTRACT_CHESTED_HORSE),
TRADER_LLAMA(LLAMA),
// Monsters
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
BLAZE(ABSTRACT_MONSTER),
CREEPER(ABSTRACT_MONSTER),
ENDERMITE(ABSTRACT_MONSTER),
ENDERMAN(ABSTRACT_MONSTER),
GIANT(ABSTRACT_MONSTER),
SILVERFISH(ABSTRACT_MONSTER),
VEX(ABSTRACT_MONSTER),
WITHER(ABSTRACT_MONSTER),
BREEZE(ABSTRACT_MONSTER),
ZOGLIN(ABSTRACT_MONSTER),
WARDEN(ABSTRACT_MONSTER),
CREAKING(ABSTRACT_MONSTER),
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
SKELETON(ABSTRACT_SKELETON),
STRAY(ABSTRACT_SKELETON),
WITHER_SKELETON(ABSTRACT_SKELETON),
BOGGED(ABSTRACT_SKELETON),
ZOMBIE(ABSTRACT_MONSTER),
DROWNED(ZOMBIE),
HUSK(ZOMBIE),
ZOMBIFIED_PIGLIN(ZOMBIE),
ZOMBIE_VILLAGER(ZOMBIE),
GUARDIAN(ABSTRACT_MONSTER),
ELDER_GUARDIAN(GUARDIAN),
SPIDER(ABSTRACT_MONSTER),
CAVE_SPIDER(SPIDER),
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
PIGLIN(ABSTRACT_PIGLIN),
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
// Water mobs
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
DOLPHIN(AGEABLE_WATER_CREATURE),
SQUID(AGEABLE_WATER_CREATURE),
GLOW_SQUID(SQUID),
WATER_ANIMAL(PATHFINDER_MOB, null),
ABSTRACT_FISH(WATER_ANIMAL, null),
PUFFERFISH(ABSTRACT_FISH),
TADPOLE(ABSTRACT_FISH),
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
COD(ABSTRACT_SCHOOLING_FISH),
SALMON(ABSTRACT_SCHOOLING_FISH),
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
// Raiders
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
WITCH(ABSTRACT_RAIDER),
RAVAGER(ABSTRACT_RAIDER),
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
VINDICATOR(ABSTRACT_ILLAGER),
PILLAGER(ABSTRACT_ILLAGER),
EVOKER(SPELLCASTER_ILLAGER),
ILLUSIONER(SPELLCASTER_ILLAGER);
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
private final EntityType parent;
private final String identifier;
private int id = -1;
EntityTypes1_21_9(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_9(final EntityType parent, @Nullable final String identifier) {
this.parent = parent;
this.identifier = identifier;
}
@Override
public int getId() {
if (id == -1) {
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
}
return id;
}
@Override
public String identifier() {
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
return identifier;
}
@Override
public @Nullable EntityType getParent() {
return parent;
}
@Override
public boolean isAbstractType() {
return identifier == null;
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
}
}
@@ -22,8 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class EntityTypes1_8 {
@@ -135,7 +135,7 @@ public class EntityTypes1_8 {
SPIDER(52, ABSTRACT_MONSTER),
CAVE_SPIDER(59, SPIDER);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private static final Int2ObjectMap<EntityType> TYPES;
private final int id;
private final EntityType parent;
@@ -176,7 +176,9 @@ public class EntityTypes1_8 {
}
static {
for (EntityType type : EntityType.values()) {
final EntityType[] values = EntityType.values();
TYPES = new Int2ObjectOpenHashMap<>(values.length);
for (EntityType type : values) {
TYPES.put(type.id, type);
}
}
@@ -218,7 +220,7 @@ public class EntityTypes1_8 {
ARMOR_STAND(78, EntityType.ARMOR_STAND),
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK);
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
private final int id;
private final int data;
@@ -226,7 +228,7 @@ public class EntityTypes1_8 {
static {
for (ObjectType type : ObjectType.values()) {
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
}
}
@@ -256,7 +258,7 @@ public class EntityTypes1_8 {
}
public static ObjectType findById(final int id, final int data) {
final Map<Integer, ObjectType> types = TYPES.get(id);
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
if (types == null) {
return null;
}
@@ -22,8 +22,8 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class EntityTypes1_9 {
@@ -142,7 +142,7 @@ public class EntityTypes1_9 {
SPIDER(52, ABSTRACT_MONSTER),
CAVE_SPIDER(59, SPIDER);
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
private static final Int2ObjectMap<EntityType> TYPES;
private final int id;
private final EntityType parent;
@@ -183,7 +183,9 @@ public class EntityTypes1_9 {
}
static {
for (EntityType type : EntityType.values()) {
final EntityType[] values = EntityType.values();
TYPES = new Int2ObjectOpenHashMap<>(values.length);
for (EntityType type : values) {
TYPES.put(type.id, type);
}
}
@@ -229,7 +231,7 @@ public class EntityTypes1_9 {
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private static final Map<Integer, Map<Integer, ObjectType>> TYPES = new HashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<ObjectType>> TYPES = new Int2ObjectOpenHashMap<>();
private final int id;
private final int data;
@@ -237,7 +239,7 @@ public class EntityTypes1_9 {
static {
for (ObjectType type : ObjectType.values()) {
TYPES.computeIfAbsent(type.id, k -> new HashMap<>()).put(type.data, type);
TYPES.computeIfAbsent(type.id, k -> new Int2ObjectOpenHashMap<>()).put(type.data, type);
}
}
@@ -267,7 +269,7 @@ public class EntityTypes1_9 {
}
public static ObjectType findById(final int id, final int data) {
final Map<Integer, ObjectType> types = TYPES.get(id);
final Int2ObjectMap<ObjectType> types = TYPES.get(id);
if (types == null) {
return null;
}
@@ -22,12 +22,9 @@
*/
package com.viaversion.viaversion.api.minecraft.entitydata.types;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
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_20_5;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public final class EntityDataTypes1_20_5 extends AbstractEntityDataTypes {
@@ -38,7 +35,7 @@ public final class EntityDataTypes1_20_5 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_20_5.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);
@@ -63,9 +60,10 @@ public final class EntityDataTypes1_20_5 extends AbstractEntityDataTypes {
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
public EntityDataTypes1_20_5(final ParticleType particleType, final ArrayType<Particle> particlesType) {
public EntityDataTypes1_20_5(final VersionedTypesHolder types) {
super(31);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
this.itemType = add(7, types.item());
this.particleType = add(17, types.particle());
this.particlesType = add(18, types.particles());
}
}
@@ -23,14 +23,10 @@
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.ArrayType;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
@@ -66,10 +62,10 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
public EntityDataTypes1_21(final Type<Item> itemType, final ParticleType particleType, final ArrayType<Particle> particlesType) {
public EntityDataTypes1_21(final VersionedTypesHolder types) {
super(31);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
this.itemType = add(7, types.item());
this.particleType = add(17, types.particle());
this.particlesType = add(18, types.particles());
}
}
@@ -23,13 +23,10 @@
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;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public final class EntityDataTypes1_21_2 extends AbstractEntityDataTypes {
@@ -65,10 +62,10 @@ public final class EntityDataTypes1_21_2 extends AbstractEntityDataTypes {
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) {
public EntityDataTypes1_21_2(final VersionedTypesHolder types) {
super(31);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
this.itemType = add(7, types.item());
this.particleType = add(17, types.particle());
this.particlesType = add(18, types.particles());
}
}
@@ -23,12 +23,9 @@
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.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;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public final class EntityDataTypes1_21_5 extends AbstractEntityDataTypes {
@@ -68,10 +65,10 @@ public final class EntityDataTypes1_21_5 extends AbstractEntityDataTypes {
public final EntityDataType vector3FType = add(33, Types.VECTOR3F);
public final EntityDataType quaternionType = add(34, Types.QUATERNION);
public EntityDataTypes1_21_5(final Type<Item> itemType, final ParticleType particleType, final Type<Particle[]> particlesType) {
public EntityDataTypes1_21_5(final VersionedTypesHolder types) {
super(35);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
this.itemType = add(7, types.item());
this.particleType = add(17, types.particle());
this.particlesType = add(18, types.particles());
}
}
@@ -0,0 +1,76 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.entitydata.types;
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
public final class EntityDataTypes1_21_9 extends AbstractEntityDataTypes {
public final EntityDataType byteType = add(0, Types.BYTE);
public final EntityDataType varIntType = add(1, Types.VAR_INT);
public final EntityDataType longType = add(2, Types.VAR_LONG);
public final EntityDataType floatType = add(3, Types.FLOAT);
public final EntityDataType stringType = add(4, Types.STRING);
public final EntityDataType componentType = add(5, Types.TAG);
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
public final EntityDataType itemType;
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
public final EntityDataType optionalBlockPositionType = add(11, Types.OPTIONAL_POSITION_1_14);
public final EntityDataType directionType = add(12, Types.VAR_INT);
public final EntityDataType optionalUUIDType = add(13, Types.OPTIONAL_UUID);
public final EntityDataType blockStateType = add(14, Types.VAR_INT);
public final EntityDataType optionalBlockStateType = add(15, Types.VAR_INT);
public final EntityDataType particleType;
public final EntityDataType particlesType;
public final EntityDataType villagerDatatType = add(18, Types.VILLAGER_DATA);
public final EntityDataType optionalVarIntType = add(19, Types.OPTIONAL_VAR_INT);
public final EntityDataType poseType = add(20, Types.VAR_INT);
public final EntityDataType catVariantType = add(21, Types.VAR_INT);
public final EntityDataType cowVariantType = add(22, Types.VAR_INT);
public final EntityDataType wolfVariantType = add(23, Types.VAR_INT);
public final EntityDataType wolfSoundVariantType = add(24, Types.VAR_INT);
public final EntityDataType frogVariantType = add(25, Types.VAR_INT);
public final EntityDataType pigVariantType = add(26, Types.VAR_INT);
public final EntityDataType chickenVariantType = add(27, Types.VAR_INT);
public final EntityDataType optionalGlobalPosition = add(28, Types.OPTIONAL_GLOBAL_POSITION);
public final EntityDataType paintingVariantType = add(29, PaintingVariant.TYPE1_21_2);
public final EntityDataType snifferState = add(30, Types.VAR_INT);
public final EntityDataType armadilloState = add(31, Types.VAR_INT);
public final EntityDataType copperGolemState = add(32, Types.VAR_INT);
public final EntityDataType weatheringCopperState = add(33, Types.VAR_INT);
public final EntityDataType vector3FType = add(34, Types.VECTOR3F);
public final EntityDataType quaternionType = add(35, Types.QUATERNION);
public final EntityDataType mannequinProfileType = add(36, Types.RESOLVABLE_PROFILE);
public EntityDataTypes1_21_9(final VersionedTypesHolder types) {
super(37);
this.itemType = add(7, types.item());
this.particleType = add(16, types.particle());
this.particlesType = add(17, types.particles());
}
}
@@ -39,4 +39,7 @@ public interface HashedItem extends ItemBase {
Int2IntMap dataHashesById();
IntSet removedDataIds();
@Override
HashedItem copy();
}
@@ -79,6 +79,11 @@ public class HashedStructuredItem implements HashedItem {
return this.removedData;
}
@Override
public HashedItem copy() {
return new HashedStructuredItem(identifier, amount, new Int2IntOpenHashMap(dataHashes), new IntOpenHashSet(removedData));
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
@@ -24,10 +24,9 @@ package com.viaversion.viaversion.api.minecraft.item;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.util.Copyable;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface Item extends ItemBase, Copyable {
public interface Item extends ItemBase {
/**
* Returns the item data. Always 0 for 1.13+ items.
@@ -22,11 +22,13 @@
*/
package com.viaversion.viaversion.api.minecraft.item;
import com.viaversion.viaversion.util.Copyable;
/**
* @see Item
* @see HashedItem
*/
public interface ItemBase {
public interface ItemBase extends Copyable {
/**
* Returns the item identifier.
@@ -64,4 +66,7 @@ public interface ItemBase {
default boolean isEmpty() {
return identifier() == 0 || amount() <= 0;
}
@Override
ItemBase copy();
}
@@ -22,14 +22,17 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record AdventureModePredicate(BlockPredicate[] predicates, boolean showInTooltip) implements Copyable {
public record AdventureModePredicate(BlockPredicate[] predicates,
boolean showInTooltip) implements Copyable, Rewritable {
public AdventureModePredicate(final BlockPredicate[] predicates) {
this(predicates, true);
@@ -70,16 +73,17 @@ public record AdventureModePredicate(BlockPredicate[] predicates, boolean showIn
}
}
public AdventureModePredicate rewrite(final Int2IntFunction blockIdRewriter) {
@Override
public AdventureModePredicate rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final BlockPredicate[] predicates = new BlockPredicate[this.predicates.length];
for (int i = 0; i < predicates.length; i++) {
predicates[i] = this.predicates[i].rewrite(blockIdRewriter);
predicates[i] = this.predicates[i].rewrite(connection, protocol, clientbound);
}
return new AdventureModePredicate(predicates, showInTooltip);
}
@Override
public AdventureModePredicate copy() {
return new AdventureModePredicate(copy(predicates), showInTooltip);
return new AdventureModePredicate(Copyable.copy(predicates), showInTooltip);
}
}
@@ -22,12 +22,15 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern, boolean showInTooltip) {
public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern,
boolean showInTooltip) implements Rewritable {
public ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern) {
this(material, pattern, true);
@@ -96,15 +99,16 @@ public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPatt
}
};
public ArmorTrim rewrite(final Int2IntFunction idRewriteFunction) {
@Override
public ArmorTrim rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
Holder<ArmorTrimMaterial> material = this.material;
if (material.isDirect()) {
material = Holder.of(material.value().rewrite(idRewriteFunction));
material = Holder.of(material.value().rewrite(connection, protocol, clientbound));
}
Holder<ArmorTrimPattern> pattern = this.pattern;
if (pattern.isDirect()) {
pattern = Holder.of(pattern.value().rewrite(idRewriteFunction));
pattern = Holder.of(pattern.value().rewrite(connection, protocol, clientbound));
}
return new ArmorTrim(material, pattern, showInTooltip);
}
@@ -23,16 +23,19 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import java.util.Map;
public record ArmorTrimMaterial(String assetName, int itemId, float itemModelIndex,
Map<String, String> overrideArmorMaterials, Tag description) implements Copyable {
Map<String, String> overrideArmorMaterials,
Tag description) implements Copyable, Rewritable {
public ArmorTrimMaterial(final String assetName, final int itemId, final Map<String, String> overrideArmorMaterials, final Tag description) {
this(assetName, itemId, 0F, overrideArmorMaterials, description);
@@ -175,8 +178,9 @@ public record ArmorTrimMaterial(String assetName, int itemId, float itemModelInd
}
};
public ArmorTrimMaterial rewrite(final Int2IntFunction idRewriteFunction) {
return new ArmorTrimMaterial(assetName, idRewriteFunction.applyAsInt(itemId), itemModelIndex, overrideArmorMaterials, description);
@Override
public ArmorTrimMaterial rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return new ArmorTrimMaterial(assetName, Rewritable.rewriteItem(protocol, clientbound, itemId), itemModelIndex, overrideArmorMaterials, description);
}
@Override
@@ -23,13 +23,15 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record ArmorTrimPattern(String assetName, int itemId, Tag description, boolean decal) implements Copyable {
public record ArmorTrimPattern(String assetName, int itemId, Tag description, boolean decal) implements Copyable, Rewritable {
public ArmorTrimPattern(final String assetName, final Tag description, final boolean decal) {
this(assetName, 0, description, decal);
@@ -70,8 +72,9 @@ public record ArmorTrimPattern(String assetName, int itemId, Tag description, bo
}
};
public ArmorTrimPattern rewrite(final Int2IntFunction idRewriteFunction) {
return new ArmorTrimPattern(assetName, idRewriteFunction.applyAsInt(itemId), description, decal);
@Override
public ArmorTrimPattern rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return new ArmorTrimPattern(assetName, Rewritable.rewriteItem(protocol, clientbound, itemId), description, decal);
}
@Override
@@ -22,14 +22,21 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public record AttributeModifiers1_20_5(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable {
public record AttributeModifiers1_20_5(AttributeModifier[] modifiers,
boolean showInTooltip) implements Copyable, Rewritable {
public static final Type<AttributeModifiers1_20_5> TYPE = new Type<>(AttributeModifiers1_20_5.class) {
@Override
@@ -48,7 +55,24 @@ public record AttributeModifiers1_20_5(AttributeModifier[] modifiers, boolean sh
@Override
public AttributeModifiers1_20_5 copy() {
return new AttributeModifiers1_20_5(copy(modifiers), showInTooltip);
return new AttributeModifiers1_20_5(Copyable.copy(modifiers), showInTooltip);
}
@Override
public AttributeModifiers1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
if (mappings == null) {
return this;
}
final List<AttributeModifier> modifiers = new ArrayList<>(this.modifiers.length);
for (final AttributeModifier modifier : this.modifiers) {
final int mappedId = clientbound ? mappings.getNewId(modifier.attribute()) : mappings.inverse().getNewId(modifier.attribute());
if (mappedId != -1) {
modifiers.add(new AttributeModifier(mappedId, modifier.modifier(), modifier.slotType()));
}
}
return new AttributeModifiers1_20_5(modifiers.toArray(AttributeModifier[]::new), this.showInTooltip);
}
public record AttributeModifier(int attribute, ModifierData modifier, int slotType) {
@@ -22,14 +22,23 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.ArrayList;
import java.util.List;
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable {
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable, Rewritable {
public AttributeModifiers1_21(final AttributeModifier[] modifiers) {
this(modifiers, true);
@@ -38,27 +47,49 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
public static final Type<AttributeModifiers1_21> TYPE1_21 = new Type<>(AttributeModifiers1_21.class) {
@Override
public AttributeModifiers1_21 read(final ByteBuf buffer) {
final AttributeModifier[] modifiers = AttributeModifier.ARRAY_TYPE.read(buffer);
final AttributeModifier[] modifiers = AttributeModifier.ARRAY_TYPE1_21.read(buffer);
final boolean showInTooltip = buffer.readBoolean();
return new AttributeModifiers1_21(modifiers, showInTooltip);
}
@Override
public void write(final ByteBuf buffer, final AttributeModifiers1_21 value) {
AttributeModifier.ARRAY_TYPE.write(buffer, value.modifiers());
AttributeModifier.ARRAY_TYPE1_21.write(buffer, value.modifiers());
buffer.writeBoolean(value.showInTooltip());
}
};
public static final Type<AttributeModifiers1_21> TYPE1_21_5 = new Type<>(AttributeModifiers1_21.class) {
@Override
public AttributeModifiers1_21 read(final ByteBuf buffer) {
final AttributeModifier[] modifiers = AttributeModifier.ARRAY_TYPE.read(buffer);
final AttributeModifier[] modifiers = AttributeModifier.ARRAY_TYPE1_21.read(buffer);
return new AttributeModifiers1_21(modifiers);
}
@Override
public void write(final ByteBuf buffer, final AttributeModifiers1_21 value) {
AttributeModifier.ARRAY_TYPE.write(buffer, value.modifiers());
AttributeModifier.ARRAY_TYPE1_21.write(buffer, value.modifiers());
}
@Override
public void write(final Ops ops, final AttributeModifiers1_21 value) {
ops.write(AttributeModifier.ARRAY_TYPE1_21, value.modifiers);
}
};
public static final Type<AttributeModifiers1_21> TYPE1_21_6 = new Type<>(AttributeModifiers1_21.class) {
@Override
public AttributeModifiers1_21 read(final ByteBuf buffer) {
final AttributeModifier[] modifiers = AttributeModifier.ARRAY_TYPE1_21_6.read(buffer);
return new AttributeModifiers1_21(modifiers);
}
@Override
public void write(final ByteBuf buffer, final AttributeModifiers1_21 value) {
AttributeModifier.ARRAY_TYPE1_21_6.write(buffer, value.modifiers());
}
@Override
public void write(final Ops ops, final AttributeModifiers1_21 value) {
ops.write(AttributeModifier.ARRAY_TYPE1_21_6, value.modifiers);
}
};
@@ -66,19 +97,42 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
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());
modifiers[i] = new AttributeModifier(rewriteFunction.applyAsInt(modifier.attribute()), modifier.modifier(), modifier.slotType(), modifier.display());
}
return new AttributeModifiers1_21(modifiers, showInTooltip);
}
@Override
public AttributeModifiers1_21 copy() {
return new AttributeModifiers1_21(copy(modifiers), showInTooltip);
return new AttributeModifiers1_21(Copyable.copy(modifiers), showInTooltip);
}
public record AttributeModifier(int attribute, ModifierData modifier, int slotType) {
@Override
public AttributeModifiers1_21 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
if (mappings == null) {
return this;
}
public static final Type<AttributeModifier> TYPE = new Type<>(AttributeModifier.class) {
final List<AttributeModifier> modifiers = new ArrayList<>(this.modifiers.length);
for (final AttributeModifier modifier : this.modifiers) {
final int mappedId = clientbound ? mappings.getNewId(modifier.attribute()) : mappings.inverse().getNewId(modifier.attribute());
if (mappedId != -1) {
modifiers.add(new AttributeModifier(mappedId, modifier.modifier(), modifier.slotType(), modifier.display()));
}
}
return new AttributeModifiers1_21(modifiers.toArray(AttributeModifier[]::new), this.showInTooltip);
}
public record AttributeModifier(int attribute, ModifierData modifier, int slotType, Display display) {
private static final String[] EQUIPMENT_SLOT_GROUPS = {"any", "mainhand", "offhand", "hand", "feet", "legs", "chest", "head", "armor", "body", "saddle"};
private static final String[] OPERATION = {"add_value", "add_multiplied_base", "add_multiplied_total"};
public AttributeModifier(final int attribute, final ModifierData modifier, final int slotType) {
this(attribute, modifier, slotType, Display.DEFAULT);
}
public static final Type<AttributeModifier> TYPE1_21 = new Type<>(AttributeModifier.class) {
@Override
public AttributeModifier read(final ByteBuf buffer) {
final int attribute = Types.VAR_INT.readPrimitive(buffer);
@@ -93,8 +147,62 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
ModifierData.TYPE.write(buffer, value.modifier);
Types.VAR_INT.writePrimitive(buffer, value.slotType);
}
@Override
public void write(final Ops ops, final AttributeModifier value) {
final Key attribute = ops.context().registryAccess().attributeModifier(value.attribute);
ops.writeMap(map -> map
.write("type", Types.RESOURCE_LOCATION, attribute)
.write("id", Types.RESOURCE_LOCATION, Key.of(value.modifier.id()))
.write("amount", Types.DOUBLE, value.modifier.amount)
.write("operation", Types.STRING, OPERATION[value.modifier.operation()])
.writeOptional("slot", Types.STRING, EQUIPMENT_SLOT_GROUPS[value.slotType()], "any"));
}
};
public static final Type<AttributeModifier[]> ARRAY_TYPE = new ArrayType<>(TYPE);
public static final Type<AttributeModifier[]> ARRAY_TYPE1_21 = new ArrayType<>(TYPE1_21);
public static final Type<AttributeModifier> TYPE1_21_6 = new Type<>(AttributeModifier.class) {
@Override
public AttributeModifier read(final ByteBuf buffer) {
final int attribute = Types.VAR_INT.readPrimitive(buffer);
final ModifierData modifier = ModifierData.TYPE.read(buffer);
final int slot = Types.VAR_INT.readPrimitive(buffer);
final int displayType = Types.VAR_INT.readPrimitive(buffer);
final Display display = displayType == OverrideText.ID ? new OverrideText(Types.TAG.read(buffer)) : new Display(displayType);
return new AttributeModifier(attribute, modifier, slot, display);
}
@Override
public void write(final ByteBuf buffer, final AttributeModifier value) {
Types.VAR_INT.writePrimitive(buffer, value.attribute);
ModifierData.TYPE.write(buffer, value.modifier);
Types.VAR_INT.writePrimitive(buffer, value.slotType);
value.display.write(buffer);
}
@Override
public void write(final Ops ops, final AttributeModifier value) {
final Key attribute = ops.context().registryAccess().attributeModifier(value.attribute);
ops.writeMap(map -> {
map.write("type", Types.RESOURCE_LOCATION, attribute)
.write("id", Types.RESOURCE_LOCATION, Key.of(value.modifier.id()))
.write("amount", Types.DOUBLE, value.modifier.amount)
.write("operation", Types.STRING, OPERATION[value.modifier.operation()])
.writeOptional("slot", Types.STRING, EQUIPMENT_SLOT_GROUPS[value.slotType()], "any");
if (value.display.equals(Display.DEFAULT)) {
return;
}
map.writeMap("display", display -> {
display.write("type", Types.STRING, Display.DISPLAY_TYPES[value.display.id()]);
if (value.display instanceof final OverrideText overrideText) {
display.write("value", Types.TEXT_COMPONENT_TAG, overrideText.component);
}
});
});
}
};
public static final Type<AttributeModifier[]> ARRAY_TYPE1_21_6 = new ArrayType<>(TYPE1_21_6);
}
public record ModifierData(String id, double amount, int operation) {
@@ -116,4 +224,52 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
}
};
}
public static class Display implements Copyable {
public static final String[] DISPLAY_TYPES = {"default", "hidden", "override_text"};
public static final Display DEFAULT = new Display(0);
private final int id;
public Display(final int id) {
this.id = id;
}
public int id() {
return this.id;
}
public void write(final ByteBuf buf) {
Types.VAR_INT.writePrimitive(buf, this.id);
}
@Override
public Display copy() {
return this;
}
}
public static final class OverrideText extends Display {
public static final int ID = 2;
private final Tag component;
public OverrideText(final Tag component) {
super(ID);
this.component = component;
}
public Tag component() {
return this.component;
}
@Override
public void write(final ByteBuf buf) {
super.write(buf);
Types.TAG.write(buf, this.component);
}
@Override
public OverrideText copy() {
return new OverrideText(this.component.copy());
}
}
}
@@ -23,31 +23,70 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import io.netty.buffer.ByteBuf;
public record Bee(CompoundTag entityData, int ticksInHive, int minTicksInHive) implements Copyable {
public record Bee(EntityData entityData, int ticksInHive, int minTicksInHive) implements Copyable {
public static final Type<Bee> TYPE = new Type<>(Bee.class) {
public Bee(final CompoundTag entityData, final int ticksInHive, final int minTicksInHive) {
this(new EntityData(-1, entityData), ticksInHive, minTicksInHive);
}
public static final Type<Bee> TYPE1_20_5 = new Type<>(Bee.class) {
@Override
public Bee read(final ByteBuf buffer) {
final CompoundTag entityData = Types.COMPOUND_TAG.read(buffer);
final int ticksInHive = Types.VAR_INT.readPrimitive(buffer);
final int minTicksInHive = Types.VAR_INT.readPrimitive(buffer);
return new Bee(new EntityData(-1, entityData), ticksInHive, minTicksInHive);
}
@Override
public void write(final ByteBuf buffer, final Bee value) {
Types.COMPOUND_TAG.write(buffer, value.entityData.tag());
Types.VAR_INT.writePrimitive(buffer, value.ticksInHive);
Types.VAR_INT.writePrimitive(buffer, value.minTicksInHive);
}
@Override
public void write(final Ops ops, final Bee value) {
ops.writeMap(map -> map
.writeOptional("entity_data", Types.COMPOUND_TAG, value.entityData.tag(), new CompoundTag())
.write("ticks_in_hive", Types.INT, value.ticksInHive)
.write("min_ticks_in_hive", Types.INT, value.minTicksInHive));
}
};
public static final Type<Bee[]> ARRAY_TYPE1_20_5 = new ArrayType<>(TYPE1_20_5);
public static final Type<Bee> TYPE1_21_9 = new Type<>(Bee.class) {
@Override
public Bee read(final ByteBuf buffer) {
final EntityData entityData = EntityData.TYPE.read(buffer);
final int ticksInHive = Types.VAR_INT.readPrimitive(buffer);
final int minTicksInHive = Types.VAR_INT.readPrimitive(buffer);
return new Bee(entityData, ticksInHive, minTicksInHive);
}
@Override
public void write(final ByteBuf buffer, final Bee value) {
Types.COMPOUND_TAG.write(buffer, value.entityData);
EntityData.TYPE.write(buffer, value.entityData);
Types.VAR_INT.writePrimitive(buffer, value.ticksInHive);
Types.VAR_INT.writePrimitive(buffer, value.minTicksInHive);
}
@Override
public void write(final Ops ops, final Bee value) {
ops.writeMap(map -> map
.write("entity_data", EntityData.TYPE, value.entityData)
.write("ticks_in_hive", Types.INT, value.ticksInHive)
.write("min_ticks_in_hive", Types.INT, value.minTicksInHive));
}
};
public static final Type<Bee[]> ARRAY_TYPE = new ArrayType<>(TYPE);
public static final Type<Bee[]> ARRAY_TYPE1_21_9 = new ArrayType<>(TYPE1_21_9);
@Override
public Bee copy() {
@@ -0,0 +1,65 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record BlockEntityData(int type, CompoundTag tag) implements Rewritable {
public static final Type<BlockEntityData> TYPE = new Type<>(BlockEntityData.class) {
@Override
public BlockEntityData read(final ByteBuf buffer) {
final int type = Types.VAR_INT.readPrimitive(buffer);
final CompoundTag tag = Types.COMPOUND_TAG.read(buffer);
return new BlockEntityData(type, tag);
}
@Override
public void write(final ByteBuf buffer, final BlockEntityData value) {
Types.VAR_INT.writePrimitive(buffer, value.type);
Types.COMPOUND_TAG.write(buffer, value.tag);
}
@Override
public void write(final Ops ops, final BlockEntityData data) {
ops.writeMap(map -> map
.write("id", Types.RESOURCE_LOCATION, ops.context().registryAccess().blockEntity(data.type))
.writeInlinedMap(Types.COMPOUND_TAG, data.tag)
);
}
};
@Override
public BlockEntityData rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final int mappedType = protocol.getMappingData().getBlockEntityMappings().getNewId(type);
// Empty mappings might be possible for removed block entities, set a dummy value in that case. Will be handled fine by server and client without losing data
return new BlockEntityData(mappedType != -1 ? mappedType : 0, tag);
}
}
@@ -23,23 +23,27 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.predicate.DataComponentMatchers;
import com.viaversion.viaversion.api.minecraft.data.predicate.DataComponentMatchers.DataComponentMatchersType;
import com.viaversion.viaversion.api.minecraft.data.predicate.DataComponentPredicate;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import org.checkerframework.checker.nullness.qual.Nullable;
public record BlockPredicate(@Nullable HolderSet holderSet, StatePropertyMatcher @Nullable [] propertyMatchers,
@Nullable CompoundTag tag, DataComponentMatchers dataMatchers) implements Copyable {
@Nullable CompoundTag tag,
DataComponentMatchers dataMatchers) implements Copyable, Rewritable {
public BlockPredicate(@Nullable final HolderSet holderSet, final StatePropertyMatcher @Nullable [] propertyMatchers, @Nullable final CompoundTag tag) {
this(holderSet, propertyMatchers, tag, null);
this(holderSet, propertyMatchers, tag, new DataComponentMatchers(new StructuredData[0], new DataComponentPredicate[0]));
}
public static final Type<BlockPredicate> TYPE1_20_5 = new Type<>(BlockPredicate.class) {
@@ -96,17 +100,18 @@ public record BlockPredicate(@Nullable HolderSet holderSet, StatePropertyMatcher
}
}
public BlockPredicate rewrite(final Int2IntFunction blockIdRewriter) {
@Override
public BlockPredicate rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
if (holderSet == null || holderSet.hasTagKey()) {
return this;
}
final HolderSet updatedHolders = holderSet.rewrite(blockIdRewriter);
final HolderSet updatedHolders = holderSet.rewrite(Rewritable.blockRewriteFunction(protocol, clientbound));
return new BlockPredicate(updatedHolders, propertyMatchers, tag);
}
@Override
public BlockPredicate copy() {
return new BlockPredicate(holderSet, copy(propertyMatchers), tag == null ? null : tag.copy());
return new BlockPredicate(holderSet, Copyable.copy(propertyMatchers), tag == null ? null : tag.copy());
}
}
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
@@ -50,6 +51,15 @@ public record BlockStateProperties(Map<String, String> properties) implements Co
Types.STRING.write(buffer, entry.getValue());
}
}
@Override
public void write(final Ops ops, final BlockStateProperties value) {
ops.writeMap(map -> {
for (final Map.Entry<String, String> entry : value.properties.entrySet()) {
map.write(Types.STRING, entry.getKey(), Types.STRING, entry.getValue());
}
});
}
};
@Override
@@ -22,12 +22,15 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -39,7 +42,7 @@ public record BlocksAttacks(
@Nullable String bypassedByTag,
@Nullable Holder<SoundEvent> blockSound,
@Nullable Holder<SoundEvent> disableSound
) {
) implements Rewritable {
public static final Type<BlocksAttacks> TYPE = new Type<>(BlocksAttacks.class) {
@@ -67,6 +70,13 @@ public record BlocksAttacks(
}
};
@Override
public BlocksAttacks rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> blockSound = SoundEvent.rewriteHolder(this.blockSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> disableSound = SoundEvent.rewriteHolder(this.disableSound, Rewritable.soundRewriteFunction(protocol, clientbound));
return new BlocksAttacks(this.blockDelaySeconds, this.disableCooldownScale, this.damageReductions, this.itemDamage, this.bypassedByTag, blockSound, disableSound);
}
public record DamageReduction(float horizontalBlockingAngle, @Nullable HolderSet type, float base, float factor) {
public static final Type<DamageReduction> TYPE = new Type<>(DamageReduction.class) {
@@ -22,17 +22,20 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<SoundEvent> sound,
boolean hasConsumeParticles, ConsumeEffect<?>[] consumeEffects) implements Copyable {
boolean hasConsumeParticles,
ConsumeEffect<?>[] consumeEffects) implements Copyable, Rewritable {
public static final Type<?>[] EFFECT_TYPES = {
ApplyStatusEffects.TYPE,
@@ -111,13 +114,14 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
};
}
public Consumable1_21_2 rewrite(final Int2IntFunction soundIdRewriteFunction) {
final Holder<SoundEvent> soundHolder = this.sound.updateId(soundIdRewriteFunction);
@Override
public Consumable1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundHolder = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundHolder == this.sound ? this : new Consumable1_21_2(consumeSeconds, animationType, soundHolder, hasConsumeParticles, consumeEffects);
}
@Override
public Consumable1_21_2 copy() {
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, copy(consumeEffects));
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, Copyable.copy(consumeEffects));
}
}
@@ -0,0 +1,59 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
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;
public final class ContainterContents {
// Just write it as Item[] directly, makes processing easier (until op reading is needed)
public static final class ContainerContentsType extends ArrayType<Item> {
private final Type<Item> itemType;
public ContainerContentsType(final Type<Item> itemType) {
super(itemType, 256);
this.itemType = itemType;
}
@Override
public void write(final Ops ops, final Item[] value) {
ops.writeList(list -> {
for (int i = 0; i < value.length; i++) {
final Item item = value[i];
if (item.isEmpty()) {
continue;
}
final int slot = i;
list.writeMap(map -> map
.write("slot", Types.INT, slot)
.write("item", itemType, item));
}
});
}
}
}
@@ -22,12 +22,16 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.ArrayUtil;
import com.viaversion.viaversion.util.Copyable;
import io.netty.buffer.ByteBuf;
public record CustomModelData1_21_4(float[] floats, boolean[] booleans, String[] strings, int[] colors) implements Copyable {
public record CustomModelData1_21_4(float[] floats, boolean[] booleans, String[] strings,
int[] colors) implements Copyable {
public static final Type<CustomModelData1_21_4> TYPE = new Type<>(CustomModelData1_21_4.class) {
@Override
@@ -46,10 +50,19 @@ public record CustomModelData1_21_4(float[] floats, boolean[] booleans, String[]
Types.STRING_ARRAY.write(buffer, value.strings());
Types.INT_ARRAY_PRIMITIVE.write(buffer, value.colors());
}
@Override
public void write(final Ops ops, final CustomModelData1_21_4 value) {
ops.writeMap(map -> map
.writeOptional("floats", new ArrayType<>(Types.FLOAT), ArrayUtil.boxedArray(value.floats), new Float[0])
.writeOptional("flags", new ArrayType<>(Types.BOOLEAN), ArrayUtil.boxedArray(value.booleans), new Boolean[0])
.writeOptional("strings", Types.STRING_ARRAY, value.strings(), new String[0])
.writeOptional("colors", new ArrayType<>(Types.INT), ArrayUtil.boxedArray(value.colors), new Integer[0]));
}
};
@Override
public CustomModelData1_21_4 copy() {
return new CustomModelData1_21_4(copy(floats), copy(booleans), copy(strings), copy(colors));
return new CustomModelData1_21_4(Copyable.copy(floats), Copyable.copy(booleans), Copyable.copy(strings), Copyable.copy(colors));
}
}
@@ -22,22 +22,19 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import com.viaversion.viaversion.util.Key;
public record DamageResistant(String typesTagKey) {
public record DamageResistant(Key typesTagKey) {
public static final Type<DamageResistant> TYPE = new Type<>(DamageResistant.class) {
@Override
public DamageResistant read(final ByteBuf buffer) {
final String typesTagKey = Types.STRING.read(buffer);
return new DamageResistant(typesTagKey);
}
public static final Type<DamageResistant> TYPE = new TransformingType<>(Types.RESOURCE_LOCATION, DamageResistant.class, DamageResistant::new, DamageResistant::typesTagKey) {
@Override
public void write(final ByteBuf buffer, final DamageResistant value) {
Types.STRING.write(buffer, value.typesTagKey());
public void write(final Ops ops, final DamageResistant value) {
ops.writeMap(map -> map.write("types", Types.TAG_KEY, value.typesTagKey));
}
};
}
@@ -44,6 +44,6 @@ public record DeathProtection(ConsumeEffect<?>[] deathEffects) implements Copyab
@Override
public DeathProtection copy() {
return new DeathProtection(copy(deathEffects));
return new DeathProtection(Copyable.copy(deathEffects));
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.TransformingType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
public record DebugStickState(CompoundTag tag) implements Rewritable, Copyable {
public static final Type<DebugStickState> TYPE = TransformingType.of(Types.COMPOUND_TAG, DebugStickState.class, DebugStickState::new, DebugStickState::tag);
@Override
public DebugStickState rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
CompoundTag updatedTag = tag;
if (clientbound && protocol.getMappingData() != null && protocol.getMappingData().changedBlocks() != null) {
updatedTag = tag.copy();
// Anything beyond this isn't worth the disk space/handling
updatedTag.entrySet().removeIf(entry -> {
final int blockId = protocol.getMappingData().getFullBlockMappings().id(entry.getKey());
return protocol.getMappingData().changedBlocks().contains(blockId);
});
}
return new DebugStickState(updatedTag);
}
@Override
public DebugStickState copy() {
return new DebugStickState(tag.copy());
}
}
@@ -22,7 +22,9 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public record DyedColor(int rgb, boolean showInTooltip) {
@@ -56,5 +58,10 @@ public record DyedColor(int rgb, boolean showInTooltip) {
public void write(final ByteBuf buffer, final DyedColor value) {
buffer.writeInt(value.rgb);
}
@Override
public void write(final Ops ops, final DyedColor dyedColor) {
ops.write(Types.INT, dyedColor.rgb);
}
};
}
@@ -20,26 +20,29 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkSectionType1_8;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType1_8;
import java.util.List;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public final class Types1_8 {
public record Enchantable(int value) {
/**
* Entity data type for 1.8
*/
public static final Type<EntityData> ENTITY_DATA = new EntityDataType1_8();
/**
* Entity data list type for 1.8
*/
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
public static final Type<Enchantable> TYPE = new Type<>(Enchantable.class) {
@Override
public Enchantable read(final ByteBuf buffer) {
return new Enchantable(Types.VAR_INT.readPrimitive(buffer));
}
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_8();
@Override
public void write(final ByteBuf buffer, final Enchantable value) {
Types.VAR_INT.writePrimitive(buffer, value.value);
}
@Override
public void write(final Ops ops, final Enchantable enchantable) {
ops.writeMap(map -> map.write("value", Types.INT, enchantable.value));
}
};
}
@@ -22,9 +22,11 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Key;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
@@ -81,6 +83,16 @@ public record Enchantments(Int2IntMap enchantments, boolean showInTooltip) imple
Types.VAR_INT.writePrimitive(buffer, entry.getIntValue());
}
}
@Override
public void write(final Ops ops, final Enchantments value) {
ops.writeMap(map -> {
for (final Int2IntMap.Entry entry : value.enchantments.int2IntEntrySet()) {
final Key key = ops.context().registryAccess().enchantment(entry.getIntKey());
map.write(Types.RESOURCE_LOCATION, key, Types.VAR_INT, entry.getIntValue());
}
});
}
};
public Enchantments(final boolean showInTooltip) {
@@ -0,0 +1,70 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
public record EntityData(int type, CompoundTag tag) implements Rewritable, Copyable {
public static final Type<EntityData> TYPE = new Type<>(EntityData.class) {
@Override
public EntityData read(final ByteBuf buffer) {
final int type = Types.VAR_INT.readPrimitive(buffer);
final CompoundTag tag = Types.COMPOUND_TAG.read(buffer);
return new EntityData(type, tag);
}
@Override
public void write(final ByteBuf buffer, final EntityData value) {
Types.VAR_INT.writePrimitive(buffer, value.type);
Types.COMPOUND_TAG.write(buffer, value.tag);
}
@Override
public void write(final Ops ops, final EntityData data) {
ops.writeMap(map -> map
.write("id", Types.RESOURCE_LOCATION, ops.context().registryAccess().entity(data.type))
.writeInlinedMap(Types.COMPOUND_TAG, data.tag)
);
}
};
@Override
public EntityData rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final int mappedType = protocol.getMappingData().getEntityMappings().getNewId(type);
return new EntityData(mappedType, tag);
}
@Override
public EntityData copy() {
return new EntityData(type, tag.copy());
}
}
@@ -0,0 +1,54 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.types.EnumType;
import com.viaversion.viaversion.api.type.types.EnumType.Fallback;
import com.viaversion.viaversion.api.type.types.FakeEnumType;
import com.viaversion.viaversion.api.type.types.RegistryValueType;
import java.util.List;
import static com.viaversion.viaversion.api.type.types.FakeEnumType.Entry.of;
/**
* Enum types that aren't associated with any specific item data in this package.
*/
public final class EnumTypes {
public static final EnumType DYE_COLOR = new EnumType("white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black");
public static final EnumType RARITY = new EnumType("common", "uncommon", "rare", "epic");
public static final EnumType FOX_VARIANT = new EnumType("red", "snow");
public static final EnumType SALMON_VARIANT = new EnumType(Fallback.CLAMP, "small", "medium", "large");
public static final EnumType PARROT_VARIANT = new EnumType(Fallback.CLAMP, "red_blue", "blue", "green", "yellow_blue", "gray");
public static final EnumType MUSHROOM_COW_VARIANT = new EnumType(Fallback.CLAMP, "red", "brown");
public static final EnumType HORSE_VARIANT = new EnumType(Fallback.WRAP, "white", "creamy", "chestnut", "brown", "black", "gray", "dark_brown");
public static final EnumType LLAMA_VARIANT = new EnumType(Fallback.CLAMP, "creamy", "white", "brown", "gray");
public static final EnumType AXOLOTL_VARIANT = new EnumType("lucy", "wild", "gold", "cyan", "blue");
public static final EnumType EQUIPMENT_SLOT = new EnumType("mainhand", "feet", "legs", "chest", "head", "offhand", "body", "saddle");
// Enums with non-ordinal ids
public static final FakeEnumType RABBIT_VARIANT = new FakeEnumType(List.of("brown", "white", "black", "white_splotched", "gold", "salt"), of(99, "evil"));
// Pretty much enums, but with a resource location
public static final RegistryValueType VILLAGER_TYPE = new RegistryValueType("desert", "jungle", "plains", "savanna", "snow", "swamp", "taiga");
public static final RegistryValueType POTION = new RegistryValueType("water", "mundane", "thick", "awkward", "night_vision", "long_night_vision", "invisibility", "long_invisibility", "leaping", "long_leaping", "strong_leaping", "fire_resistance", "long_fire_resistance", "swiftness", "long_swiftness", "strong_swiftness", "slowness", "long_slowness", "strong_slowness", "turtle_master", "long_turtle_master", "strong_turtle_master", "water_breathing", "long_water_breathing", "healing", "strong_healing", "harming", "strong_harming", "poison", "long_poison", "strong_poison", "regeneration", "long_regeneration", "strong_regeneration", "strength", "long_strength", "strong_strength", "weakness", "long_weakness", "luck", "slow_falling", "long_slow_falling", "wind_charged", "weaving", "oozing", "infested");
public static final RegistryValueType MOB_EFFECT = new RegistryValueType("speed", "slowness", "haste", "mining_fatigue", "strength", "instant_health", "instant_damage", "jump_boost", "nausea", "regeneration", "resistance", "fire_resistance", "water_breathing", "invisibility", "blindness", "night_vision", "hunger", "weakness", "poison", "wither", "health_boost", "absorption", "saturation", "glowing", "levitation", "luck", "unluck", "slow_falling", "conduit_power", "dolphins_grace", "bad_omen", "hero_of_the_village", "darkness", "trial_omen", "raid_omen", "wind_charged", "weaving", "oozing", "infested");
}
@@ -22,24 +22,36 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import 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, boolean equipOnInteract) {
boolean swappable, boolean damageOnHurt, boolean equipOnInteract,
boolean canBeSheared, Holder<SoundEvent> shearingSound) implements Rewritable {
public Equippable(final int equipmentSlot, final Holder<SoundEvent> soundEvent, @Nullable final String model, @Nullable final String cameraOverlay,
@Nullable final HolderSet allowedEntities, final boolean dispensable, final boolean swappable, final boolean damageOnHurt) {
this(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, true);
}
public Equippable(final int equipmentSlot, final Holder<SoundEvent> soundEvent, @Nullable final String model, @Nullable final String cameraOverlay,
@Nullable final HolderSet allowedEntities, final boolean dispensable, final boolean swappable, final boolean damageOnHurt, final boolean equipOnInteract) {
this(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, false, Holder.of(0));
}
public static final Type<Equippable> TYPE1_21_2 = new Type<>(Equippable.class) {
@Override
public Equippable read(final ByteBuf buffer) {
@@ -93,10 +105,79 @@ public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Null
buffer.writeBoolean(value.damageOnHurt());
buffer.writeBoolean(value.equipOnInteract());
}
@Override
public void write(final Ops ops, final Equippable value) {
final Holder<SoundEvent> defaultEquipSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "item.armor.equip_generic"));
ops.writeMap(map -> map
.write("slot", EnumTypes.EQUIPMENT_SLOT, value.equipmentSlot)
.writeOptional("equip_sound", Types.SOUND_EVENT, value.soundEvent, defaultEquipSound)
.writeOptional("asset_id", Types.RESOURCE_LOCATION, value.model != null ? Key.of(value.model) : null)
.writeOptional("camera_overlay", Types.RESOURCE_LOCATION, value.cameraOverlay != null ? Key.of(value.cameraOverlay) : null)
.writeOptional("allowed_entities", new HolderSetType(MappingData.MappingType.ENTITY), value.allowedEntities)
.writeOptional("dispensable", Types.BOOLEAN, value.dispensable, true)
.writeOptional("swappable", Types.BOOLEAN, value.swappable, true)
.writeOptional("damage_on_hurt", Types.BOOLEAN, value.damageOnHurt, true)
.writeOptional("equip_on_interact", Types.BOOLEAN, value.equipOnInteract, false));
}
};
public static final Type<Equippable> TYPE1_21_6 = new Type<>(Equippable.class) {
@Override
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();
final boolean equipOnInteract = buffer.readBoolean();
final boolean canBeSheared = buffer.readBoolean();
final Holder<SoundEvent> shearingSound = Types.SOUND_EVENT.read(buffer);
return new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, canBeSheared, shearingSound);
}
@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());
buffer.writeBoolean(value.equipOnInteract());
buffer.writeBoolean(value.canBeSheared());
Types.SOUND_EVENT.write(buffer, value.shearingSound());
}
@Override
public void write(final Ops ops, final Equippable value) {
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "item.armor.equip_generic"));
final Holder<SoundEvent> defaultShearingSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "item.shears.snip"));
ops.writeMap(map -> map
.write("slot", EnumTypes.EQUIPMENT_SLOT, value.equipmentSlot)
.writeOptional("equip_sound", Types.SOUND_EVENT, value.soundEvent, defaultSound)
.writeOptional("asset_id", Types.RESOURCE_LOCATION, value.model != null ? Key.of(value.model) : null)
.writeOptional("camera_overlay", Types.RESOURCE_LOCATION, value.cameraOverlay != null ? Key.of(value.cameraOverlay) : null)
.writeOptional("allowed_entities", new HolderSetType(MappingData.MappingType.ENTITY), value.allowedEntities)
.writeOptional("dispensable", Types.BOOLEAN, value.dispensable, true)
.writeOptional("swappable", Types.BOOLEAN, value.swappable, true)
.writeOptional("damage_on_hurt", Types.BOOLEAN, value.damageOnHurt, true)
.writeOptional("equip_on_interact", Types.BOOLEAN, value.equipOnInteract, false)
.writeOptional("can_be_sheared", Types.BOOLEAN, value.canBeSheared, false)
.writeOptional("shearing_sound", Types.SOUND_EVENT, value.shearingSound, defaultShearingSound));
}
};
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, equipOnInteract);
@Override
public Equippable rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> shearingSound = SoundEvent.rewriteHolder(this.shearingSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final HolderSet allowedEntities = this.allowedEntities != null ? this.allowedEntities.rewrite(Rewritable.entityRewriteFunction(protocol, clientbound)) : null;
return soundEvent == this.soundEvent && shearingSound == this.shearingSound && allowedEntities == this.allowedEntities ? this
: new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, canBeSheared, shearingSound);
}
}
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -74,6 +75,13 @@ public abstract class Filterable<T> {
optionalElementType.write(buffer, value.filtered());
}
@Override
public void write(final Ops ops, final F value) {
ops.writeMap(map -> map
.write("raw", elementType, value.raw())
.writeOptional("filtered", elementType, value.filtered()));
}
protected abstract F create(T raw, T filtered);
}
}
@@ -23,12 +23,16 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class FilterableComponent extends Filterable<Tag> {
public final class FilterableComponent extends Filterable<Tag> implements Copyable, Rewritable {
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
@Override
@@ -41,4 +45,21 @@ public final class FilterableComponent extends Filterable<Tag> {
public FilterableComponent(final Tag raw, @Nullable final Tag filtered) {
super(raw, filtered);
}
@Override
public FilterableComponent rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
if (protocol.getComponentRewriter() == null) {
return this;
}
final FilterableComponent copy = copy();
protocol.getComponentRewriter().processTag(connection, copy.raw());
protocol.getComponentRewriter().processTag(connection, copy.filtered());
return copy;
}
@Override
public FilterableComponent copy() {
return new FilterableComponent(raw().copy(), filtered() != null ? filtered().copy() : null);
}
}
@@ -22,13 +22,18 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.ArrayUtil;
import com.viaversion.viaversion.util.Copyable;
import io.netty.buffer.ByteBuf;
public record FireworkExplosion(int shape, int[] colors, int[] fadeColors, boolean hasTrail, boolean hasTwinkle) implements Copyable {
public record FireworkExplosion(int shape, int[] colors, int[] fadeColors, boolean hasTrail,
boolean hasTwinkle) implements Copyable {
public static final String[] SHAPES = {"small_ball", "large_ball", "star", "creeper", "burst"};
public static final Type<FireworkExplosion> TYPE = new Type<>(FireworkExplosion.class) {
@Override
public FireworkExplosion read(final ByteBuf buffer) {
@@ -48,11 +53,21 @@ public record FireworkExplosion(int shape, int[] colors, int[] fadeColors, boole
buffer.writeBoolean(value.hasTrail);
buffer.writeBoolean(value.hasTwinkle);
}
@Override
public void write(final Ops ops, final FireworkExplosion value) {
ops.writeMap(map -> map
.write("shape", Types.STRING, SHAPES[value.shape])
.writeOptional("colors", new ArrayType<>(Types.INT), ArrayUtil.boxedArray(value.colors), new Integer[0])
.writeOptional("fade_colors", new ArrayType<>(Types.INT), ArrayUtil.boxedArray(value.fadeColors), new Integer[0])
.writeOptional("has_trail", Types.BOOLEAN, value.hasTrail, false)
.writeOptional("has_twinkle", Types.BOOLEAN, value.hasTwinkle, false));
}
};
public static final Type<FireworkExplosion[]> ARRAY_TYPE = new ArrayType<>(TYPE);
@Override
public FireworkExplosion copy() {
return new FireworkExplosion(shape, copy(colors), copy(fadeColors), hasTrail, hasTwinkle);
return new FireworkExplosion(shape, Copyable.copy(colors), Copyable.copy(fadeColors), hasTrail, hasTwinkle);
}
}
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
@@ -42,10 +43,17 @@ public record Fireworks(int flightDuration, FireworkExplosion[] explosions) impl
Types.VAR_INT.writePrimitive(buffer, value.flightDuration);
FireworkExplosion.ARRAY_TYPE.write(buffer, value.explosions);
}
@Override
public void write(final Ops ops, final Fireworks value) {
ops.writeMap(map -> map
.writeOptional("flight_duration", Types.UNSIGNED_BYTE, (short) value.flightDuration, (short) 0)
.writeOptional("explosions", FireworkExplosion.ARRAY_TYPE, value.explosions, new FireworkExplosion[0]));
}
};
@Override
public Fireworks copy() {
return new Fireworks(flightDuration, copy(explosions));
return new Fireworks(flightDuration, Copyable.copy(explosions));
}
}
Loaded 100 of 448 files, more files were not shown because too many files have changed in this diff. Show more