Compare commits

...
428 Commits
Author SHA1 Message Date
KennyTV b98f208a98 3.0.0 2020-06-23 15:08:10 +02:00
KennyTV bdc79c43eb Remove unmapped piston warning
Remove some wont-fix/unneeded todos
2020-06-19 17:47:43 +02:00
KennyTV f83ac57d8f 1.16 pre7 2020-06-16 19:02:31 +02:00
KennyTV 124f5a5b87 1.16 pre6 2020-06-15 20:12:04 +02:00
KennyTV 4a8a475d55 Properly write interact sneaking boolean 2020-06-12 18:56:30 +02:00
KennyTV 86cf835d53 1.16 pre5 2020-06-12 17:17:35 +02:00
KennyTV 166b4314fd 1.16 pre4 2020-06-11 19:29:56 +02:00
KennyTV 615cd40cae 1.16 pre3 2020-06-10 18:36:00 +02:00
KennyTV 25220621e7 Fix 1.14->1.13 entity id rewriting 2020-06-10 17:32:41 +02:00
KennyTV e3faa0d77d Move to proper FU usage 2020-06-09 08:13:52 +02:00
KennyTV 6de1ba9f30 Move to proper FU usage 2020-06-08 23:59:17 +02:00
KennyTV 79708fe952 Fix 1.14.0-1.14.3 acknowledge player digging kick 2020-06-08 18:03:00 +02:00
KennyTV 16b68f7e3d Use fastutil soft wrappers 2020-06-08 18:03:00 +02:00
KennyTV 71d5aab1b0 Cancel 1.14 bell block action
Fixes #209
2020-06-08 18:01:40 +02:00
KennyTV 3bda6dd503 Remove new statistics 2020-06-08 09:39:10 +02:00
KennyTV 5ff7767353 Use packet type constants for automated channel mapping 2020-06-06 16:15:28 +02:00
KennyTV d334a202e7 1.16-pre1 2020-06-04 23:42:17 +02:00
KennyTV eec16eb5bb Fix nether biome id 2020-06-04 09:32:46 +02:00
KennyTV ee86b109b2 Fix ghost items 2020-06-04 09:30:19 +02:00
KennyTV 004d0d2b23 Some metadata and entity rewriter cleanup 2020-06-03 22:48:48 +02:00
KennyTV cf5e5590ad Remove more unnecessary map lookups 2020-06-03 18:36:22 +02:00
KennyTV 5988ab4c19 Some minor optimizations 2020-06-03 11:20:17 +02:00
KennyTV e25abe57e0 Re-add translatable handler to 1.14 item handling
Reeeee
2020-06-03 08:56:28 +02:00
KennyTV 3d50c36ce3 Remove translatable handler from 1.13/1.14 item handling
Lore and name weren't actually components in those versions
Fixes #207
2020-06-03 08:48:18 +02:00
KennyTV 38ed381094 Handle color for items and entities, handle item translatable components 2020-06-02 12:13:21 +02:00
KennyTV 2698725401 Remove unnecessary override 2020-06-02 11:19:28 +02:00
KennyTV aec46ecd38 Refactor/optimize chat component rewriter 2020-06-02 11:14:26 +02:00
KennyTV c2fb40b4e1 20w22a 2020-05-29 15:20:39 +02:00
KennyTV 8b4733258b Fix show_entity and show_item in 1.16->1.15 2020-05-28 13:29:24 +02:00
KennyTV 4b0e352849 Use correct gamemode type in respawn packet 2020-05-23 12:49:21 +02:00
KennyTV 611dd93bb9 Extend from VV soundrewriter 2020-05-23 11:21:42 +02:00
KennyTV cb8cdf27a4 20w21a 2020-05-20 17:08:15 +02:00
KennyTV f487f13e82 Fix ender pearl sound in 1.11->1.10 2020-05-18 00:28:04 +02:00
KennyTV 13bcce6d30 20w20a 2020-05-13 18:32:10 +02:00
KennyTV a30b48d8e9 Fix stop sound source reading 2020-05-09 15:31:54 +02:00
KennyTV e7ab178449 Fix load ordering issue with VV
Fixes #204
2020-05-09 09:49:26 +02:00
KennyTV 040558e01f Remap smithing inventory to anvil 2020-05-08 09:21:16 +02:00
KennyTV d4a76b0ff5 Minor cleanup 2020-05-04 11:18:48 +02:00
KennyTV 446f46db83 Fix entity rewriting 2020-04-30 17:16:47 +02:00
KennyTV e49c355580 Fix missing channel remap
Fixes #202
2020-04-30 16:26:04 +02:00
KennyTV 8fbcd71e09 Handle soul speed enchant 2020-04-29 21:50:41 +02:00
KennyTV 6e9155ba80 20w18a 2020-04-29 18:19:38 +02:00
KennyTV c2d81e6e9d Map the sound name in stop sound packets 2020-04-28 11:23:56 +02:00
KennyTV 8409f6fb2a Fix show_item count tag 2020-04-27 14:24:52 +02:00
KennyTV 29908523b0 Async mapping loader change 2020-04-25 13:30:26 +02:00
KennyTV 48a69f1411 Add sanity check for implementation version 2020-04-24 11:45:54 +02:00
KennyTV 49daeb33c0 Also process hovered text 2020-04-23 12:37:29 +02:00
KennyTV b1ca8cc2a0 Approximate hex color to chat color, fix show_text hover
TODO: show_entity hover
2020-04-23 12:25:09 +02:00
KennyTV 2b0745dc2c 20w17a 2020-04-22 23:25:57 +02:00
KennyTV 4d701b1c4e Use properly renamed entity type constants 2020-04-22 19:30:41 +02:00
KennyTV 0cb41c970b Load legacy mappings from dir if present 2020-04-19 14:02:52 +02:00
KennyTV 345d78976a Add VB version to dumps 2020-04-17 21:11:36 +02:00
KennyTV 11417fa04e Add sanity check for skullowner tag rewrite
Fixes #199
2020-04-17 20:47:22 +02:00
KennyTV c0668f1ee7 Update 20w16a translation mappings 2020-04-17 09:46:16 +02:00
KennyTV b11c5e27c5 20w16a, fix strider meta 2020-04-15 18:24:13 +02:00
KennyTV 99482b611f Pass VB plugin instance for listener creation 2020-04-14 19:01:19 +02:00
KennyTV 46577b4396 Only send missing entity warning when debug is enabled
Too prominent plugins fail at respecting the tracking range of the player for packet entities, and people have shown not to be able to find the first appearance of the warning with its explanation
2020-04-11 18:57:56 +02:00
KennyTV 6ab2e2f0b2 Fix npe in mapping loading 2020-04-09 16:40:46 +02:00
KennyTV b8dde25f3a 20w15a, minimize diffmappings 2020-04-08 19:40:34 +02:00
KennyTV 32c26a5539 Open book when using lecterns on Bukkit
Fixes #194
2020-04-06 15:24:31 +02:00
KennyTV f263f757de Async mapping data loading 2020-04-05 22:57:32 +02:00
KennyTV ecceac660d 20w14a 2020-04-02 22:27:42 +02:00
KennyTV 910f5d98dc Fix 1.13->1.12.2 enchantment table preview
Fixes #192
2020-03-31 19:13:41 +02:00
KennyTV 1d48bf5086 20w13a 2020-03-25 21:03:09 +01:00
KennyTV 432977614f Fix skull item nbt 2020-03-23 11:13:38 +01:00
KennyTV 60164a7383 Transform tile entity uuid nbt 2020-03-20 21:12:53 +01:00
KennyTV 1b70321018 Fix parrot shoulder tracker 2020-03-19 10:32:55 +01:00
KennyTV 3b24b0dfe1 20w12a 2020-03-18 20:35:56 +01:00
KennyTV 6b73de2510 Fix number casting in 1.13 enchantments 2020-03-16 12:01:21 +01:00
KennyTV 5909103c56 Fix wrong protocol 2020-03-15 23:32:26 +01:00
KennyTV 99884107fc Fix falling block conversion
Fixes #187
2020-03-15 23:31:34 +01:00
KennyTV 8087b42c40 Map named sound packets, some cleanup 2020-03-15 12:09:56 +01:00
KennyTV 2b269a6563 20w11a 2020-03-11 22:55:04 +01:00
KennyTV af88a57983 Fix spawn egg conversion from 1.13->1.12.2, some cleanup 2020-03-05 19:03:09 +01:00
KennyTV 9a5d4197fc 20w10a mappings 2020-03-04 18:49:39 +01:00
KennyTV 126300b388 Map obsidian tear particles 2020-02-27 12:33:15 +01:00
KennyTV 334ae94577 Update translation mappings 2020-02-27 08:24:15 +01:00
KennyTV 1d1c3fdc06 20w09a 2020-02-26 19:29:41 +01:00
KennyTV ace1e6c553 20w07a 2020-02-14 17:00:24 +01:00
KennyTV 9550151de6 Make startup debug more consistent 2020-02-12 13:53:24 +01:00
Jonathan Leitschuh 947ff8e5ac Use HTTPS instead of HTTP to resolve dependencies (#183)
This fixes a security vulnerability in this project where the `pom.xml`
files were configuring Maven to resolve dependencies over HTTP instead of
HTTPS.

Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
2020-02-11 17:35:23 +01:00
KennyTV 2b76a5bc17 Resolve memory leak 2020-02-09 14:13:54 +01:00
KennyTV ba7333184b Partly fix memory leak, remove some unnecessary concurrenthashmap usages
The block entity caching in 1.13->1.12 protocol did not uncache any of the positions/blocks - this at least clears the cache on respawn, but an uncache in the chunkunload is still required to be done
2020-02-09 13:10:06 +01:00
KennyTV d6fe7914e8 More entity rewriter cleanup 2020-02-09 11:48:47 +01:00
KennyTV a4ed18f59b Entity rewriter cleanup 2020-02-07 22:32:24 +01:00
KennyTV 57602f2cee Sound mappings 2020-02-07 16:46:58 +01:00
KennyTV 78d85b7080 Item and particle mappings 2020-02-07 09:35:54 +01:00
KennyTV 91f784f3f3 20w09a (missing: sounds, items) 2020-02-06 12:02:33 +01:00
KennyTV 0f1f9328ae Use VV 1.11 EntityIdRewriter 2020-02-05 20:38:03 +01:00
KennyTV c560373be3 Fix 1.11->1.10 potion splash effect 2020-02-04 14:53:15 +01:00
KennyTV d9e5f650f1 Disable face player fix by default (unlikely to be used too often) 2020-02-03 11:16:08 +01:00
KennyTV 3144c6fb19 Make the tracker warning slightly more aggressive 2020-02-03 11:02:02 +01:00
KennyTV 7296fd58ec Map 1.14 campfire particles 2020-02-02 10:16:31 +01:00
KennyTV 2334f6c5c9 Fix NPE 2020-02-01 12:44:56 +01:00
KennyTV 152b9db80f Actually set legacy block remaps 2020-02-01 12:07:27 +01:00
KennyTV 01121dedf3 Configurable block/item mappings (1.9-1.12), cleanup
Resolves #39
2020-02-01 11:58:02 +01:00
KennyTV 8df3815e82 Give the output jar a nicer name 2020-01-29 16:59:52 +01:00
KennyTV 83ef8572c1 Farewell, lombok!
Also replaced some optionals with simple nullable objects
2020-01-27 19:41:59 +01:00
KennyTV aca265956f Handle 1.14 zombies/skeletons holding up arms 2020-01-27 18:43:03 +01:00
KennyTV 08743513ca Replicate explosion sound on 1.15 servers 2020-01-27 14:20:52 +01:00
KennyTV 7578671fc6 Fix 1.13 item mapping 2020-01-27 09:03:03 +01:00
KennyTV b2df8fc0d9 Custom item mappings (1.12-1.15)
Item mappings as well as their names can now be freely modified in the respective mapping files.
(Todo: 1.9-1.11)
2020-01-26 20:52:08 +01:00
KennyTV b62c8c46e3 Minor optimizations to legacy block rewriting 2020-01-26 15:41:25 +01:00
KennyTV 96b9a023c1 Update readme 2020-01-26 11:48:42 +01:00
KennyTV 4b3f1be599 Add api version to prevent legacy data loading 2020-01-22 12:43:21 +01:00
KennyTV d3bcc9f6c8 Prepare 1.15.2 support (if no protocol changes on release) 2020-01-19 19:14:29 +01:00
KennyTV 4680c0f3d2 Remove 1.12 flyingspeed attribute 2020-01-18 10:29:53 +01:00
KennyTV e809c117c4 Handle translatable messages (1.15->...->1.12) 2020-01-16 23:23:29 +01:00
KennyTV 80ef8a401d Minor change to rewriter register 2020-01-16 17:12:25 +01:00
KennyTV b00ae1b701 Handle 1.13->1.12.2 translatable key changes 2020-01-16 11:09:26 +01:00
KennyTV 8878a18108 Handle 1.13->1.12.2 (general) statistics 2020-01-15 22:53:34 +01:00
KennyTV 9d3bec1aa1 Handle 1.13 areaeffectcloud particle data 2020-01-14 19:43:04 +01:00
KennyTV 1857244eae We need playerteleport for caching, not entityteleport 2020-01-14 14:15:40 +01:00
KennyTV d7f67065be Handle face player packet 2020-01-14 13:51:33 +01:00
KennyTV 8c1923b077 WIP Face player 2020-01-14 13:51:02 +01:00
KennyTV ed67bd888e Fix another 1.14 particle error 2020-01-13 22:43:15 +01:00
KennyTV 95dd94f645 Remap 1.15 particles for areaeffectcloud 2020-01-13 22:29:21 +01:00
KennyTV 71e24d9797 Map new 1.15 particles, fix remap in 1.14 2020-01-13 22:24:44 +01:00
KennyTV d50c26dd55 Fix book edit 2020-01-12 10:18:09 +01:00
KennyTV d3ecce71fa Fix 1.14 lightning tracking
Fixes https://github.com/ViaVersion/ViaRewind/issues/145
2020-01-10 14:59:00 +01:00
KennyTV e40300d0b1 Fix 1.14 particle rewriting
In the used common method, the id rewriting is done after the data handling
2020-01-09 21:59:12 +01:00
KennyTV 884dcbe5b9 Map debug stick 2020-01-07 18:46:19 +01:00
KennyTV 26fab9f1ea Cleanup some block rewriting 2020-01-06 17:59:29 +01:00
KennyTV 07cc5fd7ed Let users move and change block/sound mappings in the data folder 2020-01-06 16:34:39 +01:00
KennyTV b1c4d563b4 Add option to (not) add the 1.13 scoreboard team color 2020-01-02 19:34:31 +01:00
KennyTV 617f1d3876 Add additional info to entity warning in teleport packet 2020-01-02 18:25:43 +01:00
KennyTV 3e01afbe17 Fix skull rotation
Fixes #121
2019-12-30 14:24:44 +01:00
KennyTV b339216533 Remap shulker boxes to droppers (for a full block hitbox) 2019-12-29 12:16:56 +01:00
KennyTV edc4f71403 Fix inventory titles being overriden
Fixes #175
2019-12-25 12:01:04 +01:00
KennyTV 5d8f86e9eb Change immediaterespawn flag on gamestate change 2019-12-24 17:26:41 +01:00
KennyTV de2c3b3719 Store config values for direct access 2019-12-24 09:57:11 +01:00
KennyTV 35f531d051 Instantly respawn sub 1.15 clients if gamerule is set 2019-12-23 22:55:57 +01:00
KennyTV f95b05866c Cleanup and fix CanPlaceOn/CanDestroy nbt tags 2019-12-22 12:40:21 +01:00
KennyTV 12819a63a3 Suppress stored entity warning if disabled in Via config
... pretty sure reports of this occurring are caused by HolographicDisplay, but still investigating ;)
2019-12-18 20:05:52 +01:00
KennyTV 6b8f9d87f2 1.15.1 2019-12-17 18:33:21 +01:00
KennyTV cc93551339 Add more info to missing entity warning in position cache 2019-12-16 20:58:53 +01:00
KennyTV 98eb47c360 Update VV item/position usage 2019-12-14 11:34:57 +01:00
Gerrygames 31b3acdba7 acknowledge player digging 2019-12-11 20:36:47 +01:00
KennyTV 03b7f995f6 Send empty list instead of implicit byte for metadata 2019-12-11 19:11:53 +01:00
KennyTV a642e46eb3 Cleanup outdated VV check 2019-12-11 12:35:55 +01:00
KennyTV a25b002fa8 Fix acknowledge player digging 2019-12-11 11:58:55 +01:00
Nassim 653a38fbba Merge pull request #170 from KennyTV/abstraction
Fix trade list
2019-12-10 20:45:07 +01:00
KennyTV 9177dff34f Fix trade list 2019-12-09 19:29:36 +01:00
Myles 449d45da9b Merge pull request #169 from Gerrygames/abstraction
use isSuppressConversionWarnings
2019-12-09 11:24:18 +00:00
Gerrygames f22b6138b9 use isSuppressConversionWarnings 2019-12-09 12:21:24 +01:00
Myles f959a388c0 Merge pull request #168 from KennyTV/1.15
1.15 (and a lot of other improvements/fixes) 🎉
2019-12-07 17:10:55 +00:00
KennyTV e55ff0130c 1.15 (and a lot of other improvements/fixes) 🎉 2019-12-07 17:14:17 +01:00
KennyTV 3b48aa8076 Merge remote-tracking branch 'upstream/master' into 1.15
# Conflicts:
#	README.md
2019-12-07 17:02:19 +01:00
Nassim 10217f5c5f Merge dev, fixed suffix length check (#165)
* fix falling block data remap (#161)

* Update README.md (#162)

* fix item hover event on 1.11 (#164)

* Fix kick for overly long suffix
2019-11-21 09:24:28 +00:00
Jo0001 2531e9f353 Fix typo in README.md (#163) 2019-10-27 12:32:44 +00:00
ForceUpdate1 5bb87bc059 Update README.md (#162) 2019-10-24 22:39:44 +02:00
Gerrygames 91ca18de3e Merge remote-tracking branch 'mats/dev' into mats_abstraction 2019-10-20 13:48:47 +02:00
Gerrygames e7e315983e fix remaps in wrong direction (#160) 2019-10-20 12:36:58 +01:00
Nassim 0da10a2864 Fix 1.11 enchant remapping, arrow velocity and bed handling (#159)
* Arrow velocity and entity meta error fix

* Fix 1.11 enchant remapping, some minor cleanup
2019-10-13 21:20:52 +01:00
creeper123123321 b21fce2506 Fix typo (#41) (#157) 2019-10-13 17:33:42 +01:00
Nassim 8e032f6499 Cleanup entity tracking/rewrites and item rewrites (#155)
* Cleanup entity tracking and rewrites

* Fix

* Item rewriter cleanup
2019-10-12 10:08:18 +01:00
Nassim 1d12eb0b95 Cleanup entity tracking and rewrites, cleanup 1.14.1->1.14 protocol (#148) 2019-09-24 12:53:25 +01:00
Nassim 6a0e553c96 Use VV entity types (#147) 2019-09-23 12:33:28 +01:00
Nassim f0da0624f7 Fix villager and llama meta rewrites (#146) 2019-09-23 09:00:03 +01:00
Nassim 8e2d640f8c Be able to suppress plugin channel name warnings (#142) 2019-09-13 10:07:51 +01:00
Nassim b879076026 Check if non-full light fix is disabled (#143) 2019-09-13 10:07:32 +01:00
Nassim fdcab0d5a8 (Custom) enchant remap fixes, non full block light fix (#124)
* Fix 1.13 enchant conversion + custom enchants

* Remove redundant check

* More enchant remap fixes, add config option for custom enchant display

* Fix non full blocks "saving" block light
2019-09-09 14:23:09 +01:00
Nassim e6059845aa Remap tridents, fix falling dust and lingering potions (#140)
* Fix falling dust particle for 1.9 clients

* Fix concurrent meta addition / lingering potions
Fixes #125

* Remap trident and trident sounds
2019-09-07 13:49:05 +01:00
Nassim 781ef86af6 Send valid biomes again + remap new ones (#136)
* Remap biomes

* Fix base shulker box remappings, remove unnecessary int/short casting
2019-08-18 08:09:45 +01:00
Gerrygames 3ecf898d0a Fix explosion block desync (#131) 2019-08-14 09:39:12 +01:00
Nassim 1c82d51734 Fix pistonhandler with serverside blockconnections (#130) 2019-08-14 09:38:51 +01:00
ForceUpdate1 b7bd93cfb6 Some improvements 👀 (#126)
* fix particle remaps
fix use bed packets
fix npe in piston handler

* remove todo

* Revert "fix plugin channel remap"

This reverts commit 960197c0

* reformat code

* Comments added
2019-08-04 09:39:43 +01:00
Myles 5a7a8eb334 Merge pull request #119 from ForceUpdate1/dev
Fix plugin channel remap 1.13 -> 1.12 🙌
2019-08-03 09:51:53 +01:00
Myles 0e10b6b54b Merge pull request #127 from ForceUpdate1/particleFix
Fix RGB Particles ✨
2019-08-03 09:51:33 +01:00
Marco 2376dad26a fix rgb particle 2019-08-03 10:43:54 +02:00
Marco 2fc0eac1e2 change to ViaBackwards logger 2019-08-03 00:38:06 +02:00
Marco 04793f41c5 Merge branch 'dev' of https://github.com/ViaVersion/ViaBackwards into dev 2019-08-02 21:59:00 +02:00
Myles e481c45b62 Merge pull request #123 from Gerrygames/dev
fix #122 and wrong byte types in trade list packets
2019-07-26 10:40:05 +01:00
Gerrygames 66b7b461b7 use correct byte type in trade list packets 2019-07-26 10:53:53 +02:00
Gerrygames 751c585469 fix #122 2019-07-22 22:38:12 +02:00
Myles 485c8270fa Merge pull request #116 from KennyTV/dev
New version support, some fixes
2019-07-19 12:07:52 +01:00
KennyTV 24d77278f6 Fix typo 2019-07-19 13:01:10 +02:00
KennyTV d66eb0c56b 1.14.4 support 2019-07-19 12:53:37 +02:00
Foorcee 960197c02e fix plugin channel remap 2019-07-19 08:47:02 +02:00
ForceUpdate1 21a6852593 Merge pull request #6 from ViaVersion/dev
merge upstream
2019-07-11 09:11:50 +02:00
KennyTV c186d13ae5 Fix trade item rewrites 2019-07-06 19:36:50 +02:00
KennyTV 01018fe600 Remap 1.13 piston tile entity 2019-07-05 10:22:38 +02:00
Mats cba2566c21 Merge pull request #114 from KennyTV/dev
Remap 1.14 enchantments
2019-07-03 21:37:31 +02:00
Matsv b9cb23e353 🔧 Fix commandblock rewrite 2019-07-03 16:28:19 +02:00
KennyTV e9ffe66131 Fix 1.14 dummy enchant being lost 1.13 conversion 2019-07-02 19:48:42 +02:00
KennyTV d6a1f06b35 Refactor 1.13 enchantment rewrites 2019-07-02 19:09:16 +02:00
KennyTV d124b2ddfe Fix npe in 1.13 enchant remaps 2019-06-30 11:23:42 +02:00
KennyTV 92e9eab85e Remap 1.14 enchants, show enchantment level in 1.13 remaps 2019-06-30 10:45:16 +02:00
KennyTV 1d9a0773c7 Set version to 3.0.0-SNAPSHOT 2019-06-30 10:44:43 +02:00
Matsv 105e6f23a2 ✨ Rewrite particles 2019-06-29 21:08:24 +02:00
Mats ff1bf45fd2 Merge pull request #109 from ForceUpdate1/1.14
[WIP] Add 1.14.x support, some 1.13.x fixes
2019-06-29 15:12:36 +02:00
KennyTV 21bd518f45 Properly fix recipe book from 1.14.3 2019-06-25 12:34:01 +02:00
KennyTV 167b715048 Fix new recipe type 2019-06-25 09:16:03 +02:00
KennyTV 1c94e0ead2 Fix 2019-06-24 17:28:32 +02:00
KennyTV b4c30dbff3 Update to 1.14.3 2019-06-24 17:24:21 +02:00
creeper123123321 5e1143af4b Use correct fabric.mod.json metadata keys 2019-06-16 10:21:38 -03:00
creeper123123321 ac571df2cd rebased into 1.14 branch 2019-06-16 10:05:06 -03:00
creeper123123321 fd8c89ae17 Don't shade Log4J API 2019-06-16 09:53:03 -03:00
creeper123123321 3acba1b8e2 ViaFabric platform 2019-06-16 09:53:03 -03:00
KennyTV 0c7c7ba05c Fix trident entitytype 2019-06-13 11:45:58 +02:00
Gerrygames 4070efd803 fix wrong light mask 2019-06-12 17:42:11 +02:00
KennyTV 6c27c1e863 whoops 2019-06-09 11:13:42 +02:00
KennyTV dc12f26f05 Let there be light 2019-06-09 11:11:33 +02:00
KennyTV 3f9e66bd7b Fix recipe book data 2019-06-07 14:46:48 +02:00
KennyTV 9849eebda3 Remap 1.14 spawn eggs 2019-06-07 14:40:00 +02:00
KennyTV 8f84efb833 Hotfix untracked entity 2019-06-02 20:17:55 +02:00
KennyTV 0084f764ba Fix block remaps 2019-06-02 00:00:38 +02:00
Marco c2d72214de impl first block id remaps 2019-05-30 15:36:11 +02:00
Marco d64e75d374 inventory name remap 2019-05-30 14:46:31 +02:00
Marco a12b39b67f remap cartography_table inventory 2019-05-30 14:04:50 +02:00
KennyTV 25b5b1ca8c Remap berry bushes to vines 2019-05-29 14:00:33 +02:00
KennyTV afe7c69ec1 1.14.2 2019-05-28 13:11:31 +02:00
KennyTV 955056ae61 Remap bell to goldblock 2019-05-28 13:11:22 +02:00
KennyTV 041796c85d Fix zombie submob metadata 2019-05-27 09:45:57 +02:00
KennyTV f684ed2801 Merge remote-tracking branch 'origin/1.14' into 1.14 2019-05-25 11:49:51 +02:00
KennyTV 92b8a7fd58 Fix bell item remap 2019-05-25 11:49:35 +02:00
Marco dc18190452 fix inventory slot sizes 2019-05-25 11:41:40 +02:00
Marco 4239d75275 fix intentory rewrites furnace, blast furnace, grindstone, smoker 2019-05-25 11:32:40 +02:00
Marco 111ead2719 Merge remote-tracking branch 'origin/1.14' into 1.14
# Conflicts:
#	core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java
2019-05-25 11:04:33 +02:00
Marco f3710c4fcf fix item rewrites at to server 2019-05-25 11:03:51 +02:00
KennyTV fda618d7e8 Finish (?) 1.14 mappings 2019-05-25 10:47:36 +02:00
Marco 89099a6f0d fix item remaps 2019-05-25 01:37:32 +02:00
KennyTV 41d286feb5 1.14 sign item mappings 2019-05-24 15:59:10 +02:00
Foorcee e043ef5f66 Merge remote-tracking branch 'origin/1.14' into 1.14 2019-05-24 13:28:51 +02:00
Foorcee 070661c623 reimpl. item remaps 2019-05-24 13:28:36 +02:00
KennyTV 1d2f9c6d4c A bunch of 1.14 mappings 2019-05-24 13:28:26 +02:00
KennyTV 884113ae3c Set pom version 2019-05-24 12:43:17 +02:00
KennyTV 649d2d1381 Some 1.13 item mappings 2019-05-24 11:20:44 +02:00
Marco Neuhaus a44d18fb87 Merge remote-tracking branch 'origin/1.14' into 1.14 2019-05-23 19:14:38 +02:00
Marco Neuhaus f85ef70366 fix dust particle 2019-05-23 19:14:01 +02:00
KennyTV 8d02b00cc3 Remap mushroom stem item 2019-05-23 13:17:27 +02:00
KennyTV 747943258e Add remaining 1.13 -> 1.12 mappings 2019-05-23 13:00:33 +02:00
KennyTV b20c2cbc3b Fix lever mappings 2019-05-23 11:38:49 +02:00
Marco Neuhaus b466ed9eb8 fix particle rewrites 2019-05-22 23:53:05 +02:00
KennyTV a29e88f535 Make 'em blocks placeable again! 2019-05-22 19:55:19 +02:00
KennyTV 85a5ae44e1 Fix minecarts 2019-05-22 18:35:20 +02:00
KennyTV 3107094faa Turtle egg and sea pickle mappings 2019-05-22 17:24:33 +02:00
KennyTV 885ae3f63b Add trident to EntityType1_13 2019-05-22 16:23:56 +02:00
KennyTV 88cfa40776 Fix painting and xp orb tracker 2019-05-22 15:27:48 +02:00
Marco 1dc4a771a3 fix wandering traders + trades 2019-05-22 11:27:27 +02:00
Marco 24bfa82c0c fix item remaps 2019-05-21 23:35:49 +02:00
Marco 4b0881263b add missing remaps 2019-05-21 23:10:11 +02:00
Gerrygames 3d1aa03abb fix cats and ocelots 2019-05-21 23:06:22 +02:00
Gerrygames 114dbedfb7 fix missing metadata index check 2019-05-21 22:28:28 +02:00
Gerrygames a9ee4ae88b Merge remote-tracking branch 'force/1.14' into 1.14 2019-05-21 22:16:06 +02:00
Gerrygames e4638688f5 fix mapping size 2019-05-21 22:15:56 +02:00
Marco 347da9c309 Merge remote-tracking branch 'origin/1.14' into 1.14 2019-05-21 22:07:50 +02:00
Marco 19d86058f9 add entity remaps 2019-05-21 22:07:43 +02:00
Gerrygames a7126b39dc fix horse armor 2019-05-21 22:05:36 +02:00
Gerrygames dd454d56f3 fix display name 2019-05-21 21:50:57 +02:00
Gerrygames 96b05bcd4f Use logger 2019-05-21 19:43:58 +02:00
Gerrygames 9aa98846d2 fix mappings 2019-05-21 19:16:56 +02:00
Gerrygames 8102506468 a few mappings for 1.14 2019-05-21 18:42:52 +02:00
Gerrygames 05e1fef42c remove pose metadata correctly, add debug 2019-05-21 17:40:26 +02:00
Gerrygames 1911bc55cd further work on 1.14 metadata 📃 2019-05-21 17:19:49 +02:00
Marco 0bb4539d57 first metadata rewriting 2019-05-21 16:33:23 +02:00
Marco Neuhaus 028350de3e fix arrows 2019-05-20 22:08:08 +02:00
Marco Neuhaus 4493f1c3a6 fix spawn object 2019-05-20 21:51:45 +02:00
Marco 2c66e21268 fix more problems 2019-05-19 20:47:05 +02:00
Marco 3706b72855 update 1.13.2 -> 1.14 Packet Ids 2019-05-19 19:15:50 +02:00
Marco cb396c8534 fix 1.14.1 2019-05-19 16:54:27 +02:00
Marco Neuhaus 53d753932f register protocol 2019-05-15 13:47:10 +02:00
Marco Neuhaus e4a54fbade add 1.14.1 support (not tested yet) 2019-05-15 13:44:59 +02:00
ForceUpdate1 13c157d2fc Merge pull request #5 from ViaVersion/1.14
1.14
2019-05-15 13:26:19 +02:00
ForceUpdate1 c9eee58a80 Merge pull request #4 from ViaVersion/dev
Dev
2019-05-15 13:24:07 +02:00
Myles 2584d2934d Merge branch 'master' into dev 2019-05-12 16:08:39 +01:00
Myles 271079370d Merge pull request #108 from creeper123123321/patch-1
Stop shading guava
2019-05-12 16:08:20 +01:00
creeper123123321 15324dd149 Stop shading guava 2019-05-12 11:35:28 -03:00
Myles 6072b9a74e Merge pull request #107 from Gerrygames/1.13
Fix map packet
2019-05-07 12:22:06 +01:00
Gerrygames 9441a1e49e fix map packet 2019-05-07 13:13:15 +02:00
Myles aaaa396f2c Merge pull request #106 from Gerrygames/fix_jukebox
Fix play record rewrites
2019-05-01 22:20:58 +01:00
Marco Neuhaus da67500eaa fix play record rewrites 2019-05-01 14:46:06 +02:00
Myles adc8c56862 Merge branch 'master' into dev 2019-04-23 15:50:05 +01:00
Myles cec91ee159 Fix compiling 2019-04-23 15:49:38 +01:00
Myles 4e36ac59b0 Merge branch 'master' into dev 2019-04-23 13:04:23 +01:00
Myles 608df43225 Use ViaVersion libraries 2019-04-23 13:04:03 +01:00
Myles cc68a6fa4c Merge branch 'master' into dev 2019-04-21 12:13:23 +01:00
Myles 6877304de1 Merge pull request #104 from creeper123123321/master
Set item to null when shift clicking
2019-04-20 23:24:02 +01:00
creeper123123321 bb2e089f27 Set item to null when shift clicking 2019-04-20 18:33:29 -03:00
Myles 2d0db67a29 Merge branch 'master' into dev 2019-04-19 16:29:57 +01:00
Myles 44d71ec538 Merge pull request #97 from creeper123123321/master
Workaround for #48
2019-04-19 11:40:49 +01:00
Myles 86c1a035f6 Merge pull request #102 from creeper123123321/dev
1.13: Fix sound underflow + tag name conflict + when rewriting of item nbt should occur
2019-04-11 15:39:16 +01:00
creeper123123321 77efe57015 fix tag name conflict 2019-03-30 16:33:02 -03:00
creeper123123321 6f20b874c5 fix possible array out of bounds 2019-03-30 15:08:31 -03:00
creeper123123321 1f3ed39eb6 fix toServer 2019-03-30 14:39:45 -03:00
Mats b6e1e7e35b Merge pull request #101 from creeper123123321/1.14
merge dev and add -19w11b suffix
2019-03-16 22:18:40 +01:00
creeper123123321 b8c87cfa2e Fix wrong position remappings 2019-03-16 17:29:23 -03:00
creeper123123321 ebb964dbd5 merge dev and add -19w11b suffix 2019-03-16 14:29:21 -03:00
Matsv 6c49c0b2d3 ✨ Fix paintings 2019-03-16 16:43:46 +01:00
Mats 0eff5ece5f Merge pull request #100 from creeper123123321/dev
[WIP] Snapshot support
2019-03-16 16:33:04 +01:00
Matsv 68aae77877 🐛 Fix recipe book crash 2019-03-16 16:15:49 +01:00
Matsv 6fb9f9adf3 🆘 Hacky way to fix flower pots 2019-03-16 16:03:32 +01:00
Matsv 0497ce198d 🔧 Start working on flower pot special treatment 2019-03-16 15:11:23 +01:00
creeper123123321 91acf71454 fix aoob exception 2019-03-16 09:41:24 -03:00
creeper123123321 1885840768 19w11b 2019-03-16 09:28:33 -03:00
creeper123123321 d99c5f5e60 metadata 2019-03-16 09:28:33 -03:00
creeper123123321 3252d48383 fix npe, remove living bed position 2019-03-16 09:28:32 -03:00
creeper123123321 8e2feeb375 fix 18 serializer error 2019-03-16 09:28:32 -03:00
creeper123123321 912a109c91 trying to rewrite entity data 2019-03-16 09:28:32 -03:00
creeper123123321 de4789822e stonecutting handling - todo opennbt long array 2019-03-16 09:28:32 -03:00
creeper123123321 b2b5ed2ae8 probably bugged 1.14 -> 1.13.2 protocol 2019-03-16 09:28:32 -03:00
Matsv 092057431c 🚀 Bump version for the development branch 2019-03-16 13:00:19 +01:00
Matsv 1130ba6e87 Merge branch 'master' of https://github.com/Matsv/ViaBackwards into dev 2019-03-16 12:04:21 +01:00
creeper123123321 a352822afa shorter workaround 2019-03-07 14:56:00 -03:00
creeper123123321 ce63e5ee62 Revert "Workaround for #48"
This reverts commit df53ce3e1c.
2019-03-07 14:49:54 -03:00
creeper123123321 df53ce3e1c Workaround for #48 2019-03-07 14:38:19 -03:00
Myles 414fdac20a Merge pull request #96 from Gerrygames/1.13_items
add missing wood rewrites
2019-02-19 19:32:51 +00:00
Marco Neuhaus d6c37db4eb add missing wood rewrites 2019-02-18 21:56:38 +01:00
Myles 0c94a85dcc Merge pull request #95 from creeper123123321/master
Do not register new incoming packets
2019-02-16 13:30:05 +00:00
creeper123123321 0fe233c7ed Do not register new incoming packets 2019-02-16 11:21:53 -02:00
Mats b1246b6ffc Merge pull request #94 from Gerrygames/1.13_items
add dummy enchantment for 1.13 enchatments
2019-02-16 10:02:26 +01:00
Mats 1c04ec7c55 Merge pull request #92 from creeper123123321/dev
Better tab-complete
2019-02-16 10:01:44 +01:00
Marco Neuhaus e35f264e89 Merge branch 'dev' of https://github.com/Matsv/ViaBackwards into 1.13_items
# Conflicts:
#	core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/BlockItemPackets1_13.java
2019-02-16 00:07:36 +01:00
Marco Neuhaus 02bdaa5ddb Merge branch 'dev' of https://github.com/Gerrygames/ViaBackwards into 1.13_items 2019-02-16 00:03:58 +01:00
Marco Neuhaus cd230b601d add dummy enchantments for 1.13 enchatments 2019-02-16 00:00:05 +01:00
Myles 4574d9d9b8 Merge pull request #93 from Gerrygames/1.13_items
fix enchantments
2019-02-15 22:15:44 +00:00
Marco Neuhaus 934bd4d1db fix enchantments 2019-02-15 23:12:11 +01:00
creeper123123321 66336bca0f ooops 2019-02-15 18:30:48 -02:00
creeper123123321 829857be7c Use boolean + string 2019-02-15 18:24:42 -02:00
creeper123123321 6e5f9e0741 Better tab-complete 2019-02-15 18:03:06 -02:00
Mats 19d2c8fcb9 Merge pull request #91 from creeper123123321/dev
Login plugin request and response
2019-02-03 13:54:59 +01:00
creeper123123321 9e12a199cf Login plugin request and response 2019-02-02 17:19:30 -02:00
Mats c310290bbc Merge pull request #90 from Gerrygames/1.13
fix ConcurrentModificationException
2019-01-30 22:19:01 +01:00
Gerrygames ff68a5182a fix ConcurrentModificationException 2019-01-28 14:45:52 +01:00
Matsv 9b7a4b79f7 📎 Rename 1.13.2 classes 2019-01-27 14:25:27 +01:00
Matsv 58b8f4004b 📎 Rename 1.13.1 classes 2019-01-27 14:16:05 +01:00
Matsv 8477e20725 ♻ Rewrite Entity 1.13.1 the ViaBackwards way & remove incorrect metadata & 1.13 rewrite 2019-01-27 14:06:48 +01:00
Matsv 99ffbc1bfa 🔥 Merge branch 'master' of https://github.com/Matsv/ViaBackwards into dev
# Conflicts:
#	core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsPlatform.java
2019-01-27 13:06:09 +01:00
Matsv 29f1f3ea7c ✨ Reformat code 2019-01-27 13:01:24 +01:00
Mats ce93f48a55 Merge pull request #75 from creeper123123321/master
Velocity and maybe better version detector
2019-01-27 12:58:45 +01:00
Mats bf7ea31d35 Merge pull request #89 from Gerrygames/dev
remap trading gui 1.13.1 to 1.13
2019-01-27 12:58:08 +01:00
Mats 0965acafd7 Merge pull request #88 from Gerrygames/1.13_items
Add remap for 1.13 Items
2019-01-27 12:57:27 +01:00
Marco Neuhaus 2d53b812ea remove debug messages and fix enchantment rewrite 2019-01-27 12:40:58 +01:00
Gerrygames 316ae1020e remap trading gui 1.131 to 1.13 2019-01-26 19:25:24 +01:00
Marco Neuhaus b15c55fb28 fix rewrite and add pumpkin rewrite 2019-01-26 16:51:39 +01:00
Marco Neuhaus c0dbda5882 Merge branch 'dev' of https://github.com/Matsv/ViaBackwards into 1.13_items
# Conflicts:
#	core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/PlayerPacket1_13.java
2019-01-26 16:47:58 +01:00
creeper123123321 9ee8e6efa7 Velocity and maybe better version detector 2019-01-26 11:48:28 -02:00
Matsv f9e2a37816 Merge with masta 2019-01-26 12:29:55 +01:00
Matsv ec33f48674 Merge with masta 2019-01-26 12:23:18 +01:00
Marco Neuhaus 847a54493a add more rewirtes 2019-01-23 20:49:49 +01:00
Foorcee 0d0334a963 add more 2019-01-23 17:37:59 +01:00
Foorcee 16514526c1 add some more items rewrites 2019-01-23 17:28:53 +01:00
Marco Neuhaus ef5125e972 fix rewrite 2019-01-23 15:02:55 +01:00
Myles 5aaa352705 Merge pull request #86 from Gerrygames/master
fix package name
2019-01-23 13:39:50 +00:00
Myles 15db59f439 Merge pull request #84 from Gerrygames/removeUnusedColor
remove unused colors from team prefix/suffix
2019-01-23 13:39:20 +00:00
Gerrygames 8448b9628e replace tabs 2019-01-23 14:37:07 +01:00
Marco Neuhaus 55b4f6c080 fix rewrite 2019-01-23 13:31:05 +01:00
Marco Neuhaus 53b4151a26 start implementing item rewrite 2019-01-23 13:11:52 +01:00
Marco Neuhaus e6b438a9e0 Merge remote-tracking branch 'remotes/origin/removeUnusedColor' into 1.13_items 2019-01-23 12:26:38 +01:00
Gerrygames 2f1c54ca93 fix package name 2019-01-23 11:15:26 +01:00
Myles f05bbbc2a1 Merge pull request #83 from Gerrygames/1.13
fix tab complete
2019-01-22 22:54:29 +00:00
Gerrygames 42bfe19c9c block action block ids 2019-01-22 22:37:24 +01:00
Gerrygames 22a486752b remove sysout 2019-01-22 21:49:17 +01:00
Gerrygames 8519ad8cf1 fix actionbar color 2019-01-22 21:41:49 +01:00
Gerrygames 7b9cde9946 fix wrong protocol 2019-01-22 21:25:53 +01:00
Gerrygames c539cc6e57 fix NPE 2019-01-22 20:59:00 +01:00
Gerrygames 3fc55638f9 fix NPE 2019-01-22 20:33:39 +01:00
Gerrygames e5a110f24f fix mapping issue 2019-01-22 15:42:09 +01:00
Gerrygames ccf132ff50 remove unused colors from team prefix/suffix 2019-01-22 14:41:50 +01:00
Gerrygames 4f9334c1dd fix tab complete 2019-01-22 13:58:06 +01:00
Matsv 905cd9cf0d Merge branch 'master' of https://github.com/Matsv/ViaBackwards into dev 2019-01-21 22:23:43 +01:00
Matsv 085c9e13ad Fix typo 2019-01-21 22:23:25 +01:00
Mats 7c49689738 Merge pull request #81 from Gerrygames/1.13
fix teams packet, rewrite items in metadata
2019-01-21 22:18:12 +01:00
Gerrygames 3b2128acaa fix metadata index 2019-01-21 22:16:35 +01:00
Mats 233c1c80b4 Merge pull request #82 from Gerrygames/master
use BLOCK_CHANGE_RECORD_ARRAY
2019-01-21 22:15:59 +01:00
Gerrygames 34ed045ba6 arrow metadata fix 2019-01-21 21:35:40 +01:00
Gerrygames 0018159c89 fix tab complete 2019-01-21 21:12:48 +01:00
Gerrygames 97bd12fc33 use BLOCK_CHANGE_RECORD_ARRAY 2019-01-21 16:24:05 +01:00
Gerrygames 5a3b59ce29 fix boss bar packet 2019-01-21 16:05:46 +01:00
Gerrygames 88e83f9aad use ViaBackwards logger instead of ViaVersions 2019-01-21 14:37:48 +01:00
Gerrygames fadebbc17b rewrite items in metadata 2019-01-21 14:18:24 +01:00
Gerrygames e261ced701 fix teams packet 2019-01-21 14:04:29 +01:00
Matsv 03768d7124 Handle mob spawner changes 2019-01-20 20:23:40 +01:00
Matsv 520eb15ce9 Handle skull block entities 2019-01-20 17:19:26 +01:00
Matsv fd4c9b5e6c Implement banner block entity 2019-01-20 16:08:53 +01:00
Matsv 803ae8a7ac Implement flowerpot handling 2019-01-20 14:49:51 +01:00
Matsv 97b81cf782 Implement basic block entity interface & handle beds 2019-01-20 14:15:21 +01:00
Matsv 404dce4a32 Handle new wolf colors 2019-01-20 12:06:24 +01:00
Matsv be8c1b69dc Implement tab-complete 2019-01-19 18:54:26 +01:00
Matsv c9067354c0 Rewrite AreaEffectCloud (TODO Particle rewrite) 2019-01-19 16:11:15 +01:00
Matsv c829e857d2 Remove debug comments 2019-01-19 15:55:13 +01:00
Matsv 842631feef Rewrite metadata changes en add missing entity track 2019-01-19 15:53:31 +01:00
Matsv 87f217ca37 Rewrite entity types 2019-01-19 14:04:11 +01:00
Matsv 3cd91d87a4 Rewrite meta types 2019-01-19 12:50:33 +01:00
Matsv d1d94570e7 Handle metadata & entity type rewrite 2019-01-19 12:35:30 +01:00
Matsv bc0cb10406 Handle entity/dimension tracking correctly 2019-01-19 12:11:11 +01:00
Mats 6634cd1377 Merge pull request #79 from Gerrygames/1.13
Plugin messages/new packets
2019-01-19 11:52:56 +01:00
Gerrygames d6ca3891a1 lever mapping 2019-01-18 14:13:21 +01:00
Gerrygames 99af95e0a8 mapping for doors 2019-01-18 13:55:04 +01:00
Gerrygames fbbce29da7 fix some missing mappings 2019-01-18 13:33:14 +01:00
Gerrygames 688654adcc remove debug 2019-01-18 11:44:41 +01:00
Gerrygames 9ad0c34603 most of the easy block mappings 2019-01-18 11:42:29 +01:00
Gerrygames 8d7fee16b8 Plugin messages/new packets 2019-01-17 17:30:25 +01:00
Mats cc68ef758f Merge pull request #77 from Gerrygames/1.13
sound and entity id mappings
2019-01-16 14:43:53 +01:00
Gerrygames c950fe2125 sound and entity id mappings 2019-01-16 14:41:40 +01:00
Mats e0b48f5f49 Merge pull request #76 from Gerrygames/1.13
some more progress on 1.13
2019-01-16 13:12:53 +01:00
Gerrygames b9a2404f9c some more progress on 1.13 2019-01-16 12:47:30 +01:00
Gerrygames f0ef119440 Rewrite map colors added in 1.12 2018-12-05 13:33:42 +00:00
Myles 45cece245c Merge branch 'master' into dev 2018-12-05 13:27:35 +00:00
Myles 4bac50dec2 Merge pull request #66 from ForceUpdate1/master
Implement 1.13, 1.13.1 support for 1.13.2 servers
2018-12-04 15:23:31 +00:00
Myles 814ccf1b29 Merge pull request #70 from Gerrygames/master
ViaVersion 2.0.0 compatibility
2018-11-26 08:07:40 +00:00
Gerrygames 7296017ab8 ViaVersion 2.0.0 compatibility 2018-11-20 15:32:49 +01:00
Marco Neuhaus d0dec2539d fix books 2018-11-13 10:59:33 +01:00
Marco Neuhaus ae3142c2f5 remove fileheader 2018-11-12 23:52:56 +01:00
Marco Neuhaus a5599deb8e add Support 1.13.2 to 1.13.1
little particle fix for 1.13.1 to 1.13
2018-11-12 23:47:11 +01:00
ForceUpdate1 989439926c Merge pull request #2 from ForceUpdate1/master
1.13.1 support
2018-11-12 22:19:23 +01:00
ForceUpdate1 f636b67dca Merge branch 'dev' into master 2018-11-12 22:19:12 +01:00
ForceUpdate1 7db91a9a38 Merge pull request #1 from Matsv/dev
Dev
2018-11-12 22:17:08 +01:00
Matsv d484545bef Change keepAlive's initial value to fix Gerrygames/ViaRewind#14 2018-11-10 18:17:53 +00:00
Matsv ce7c525155 Basic block translation 2018-10-25 16:04:20 +02:00
Matsv 9d34038eab Rewrite changed packet ids 2018-10-25 14:01:03 +02:00
Matsv e91ed55963 Merge branch 'master' of https://github.com/Matsv/ViaBackwards into dev
# Conflicts:
#	all/pom.xml
#	bukkit/pom.xml
#	bungee/pom.xml
#	core/pom.xml
#	pom.xml
#	sponge/pom.xml
2018-10-25 10:32:27 +02:00
Marco Neuhaus f2e35a0c5a add comment 2018-08-28 19:47:01 +02:00
Marco Neuhaus 00ad68389c add mappings for bossbar
add mappings for tab complete
2018-08-28 18:49:13 +02:00
Marco Neuhaus bc19f1a57d add mappings for advancements
add mappings for tags
2018-08-28 18:13:56 +02:00
Marco Neuhaus 35cabf34b0 Add support for 1.13 at 1.13.1 server
TODO:
* add Tab complete
* add boss bar
* add Advancements
* add tags
2018-08-28 18:06:57 +02:00
Myles c7159721cb Remove protocols for now
So it gives outdated version message instead of errors...
2018-08-21 16:44:44 +01:00
Myles f8a6e9723a Merge pull request #65 from Gerrygames/dev
Rewrite map colors added in 1.12
2018-08-16 14:41:38 +01:00
Gerrygames 69c68bf300 Rewrite map colors added in 1.12 2018-08-16 15:15:44 +02:00
Matsv 4919b8748a Preparations for 1.13 support development 2018-07-22 23:15:59 +02:00
Myles 43ad787bda Merge pull request #50 from Matsv/master
Merge master into dev
2018-07-10 12:19:49 +01:00
creeper123123321 f9ad3b59f1 Fix #25 (#38)
* Fix #25

* Update PlayerPackets1_11.java
2018-03-19 22:45:43 +01:00
Matsv 2a756616f4 Change keepAlive's initial value to fix Gerrygames/ViaRewind#14 2018-02-05 20:51:34 +01:00
Myles 7fbd546d43 Ensure ViaBackwards init is after ViaVersion on sponge 2017-10-12 12:16:38 +01:00
Myles 903c1999eb Don't use casting for validation of keep alive, use hashCodes.
Also disregard valid ones sent twice.
2017-09-30 21:08:05 +01:00
Myles d36a076942 2.3.1 - Disregard any incorrect keep-alives, credits to @Shevchik 2017-09-20 14:16:22 +01:00
Myles 30f339400e 2.3.0 - 1.12.2 Support 2017-09-19 00:25:33 +01:00
CDAGaming af190b0422 Update Dependencies (#24)
* Update Dependencies

* Undo Guava Dependency Changes
2017-08-23 02:05:50 +02:00
167 changed files with 28752 additions and 4232 deletions

No files matched your search

-8
View File
@@ -1,8 +0,0 @@
### What is the output url of /viaversion dump?
>
### How/when does this error happen? login?:
>
### Is there an error in the console? Use pastebin.com. Is there a kick message?:
>
+26
View File
@@ -0,0 +1,26 @@
---
name: Bug report
about: Create a bug report so we can fix it
---
**Describe the bug, provide any errors**
A clear and concise description of what the bug is. Can you https://hastebin.com the error?
**How can we reproduce it?**
Steps to reproduce the behavior:
1. Login on 1.12'
2. Click on '....'
3. The '....' is displayed wrong
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**ViaVersion Dump:**
- Type /viaversion dump, and put the link here.
**Additional server info**
Do you use a proxy (eg. BungeeCord)? What software do you use and what plugins?
+18 -4
View File
@@ -1,7 +1,21 @@
Copyright (c) 2016 Matsv
MIT License
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:
Copyright (c) 2016-2020
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
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 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.
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.
+14 -3
View File
@@ -3,8 +3,19 @@
Allows older Minecraft versions on a newer Minecraft server
Requires [ViaVersion](http://viaversion.com) to be installed
Releases / Dev Builds
-
**Requires [ViaVersion](https://www.spigotmc.org/resources/viaversion.19254/) to be installed**
You can find the latest dev builds here:\
**Jenkins:** https://ci.viaversion.com/view/ViaBackwards/
**Spigot page:** https://www.spigotmc.org/resources/viabackwards.27448/
### Supported versions:
![supported_versions](http://i.imgur.com/gXCifhK.png)
---
**Maven:** https://repo.viaversion.com/
**Issue tracker:** https://github.com/ViaVersion/ViaBackwards/issues
**List of contributors:** https://github.com/ViaVersion/ViaBackwards/graphs/contributors
+71 -5
View File
@@ -12,24 +12,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>viabackwards-parent</artifactId>
<groupId>nl.matsv</groupId>
<version>2.2.0</version>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>viabackwards-all</artifactId>
<name>ViaBackwards</name>
<build>
<finalName>${project.name}-${project.version}</finalName>
<defaultGoal>clean install</defaultGoal>
<plugins>
<!-- Write git commit hash into build properties -->
<plugin>
<groupId>net.md-5</groupId>
<artifactId>scriptus</artifactId>
<version>0.3.2</version>
<configuration>
<format>git-ViaBackwards-${project.parent.version}:%s</format>
</configuration>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>describe</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestEntries>
<!--suppress MavenModelInspection -->
<Implementation-Version>${describe}</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -40,10 +72,26 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<version>3.2.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>false</minimizeJar>
<relocations>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>us.myles.viaversion.libs.gson</shadedPattern>
</relocation>
<relocation>
<pattern>net.md_5.bungee</pattern>
<shadedPattern>us.myles.viaversion.libs.bungeecordchat</shadedPattern>
<includes>
<include>net.md_5.bungee.api.chat.**</include>
<include>net.md_5.bungee.api.ChatColor</include>
<include>net.md_5.bungee.api.ChatMessageType</include>
<include>net.md_5.bungee.chat.**</include>
</includes>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
@@ -62,24 +110,42 @@
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-core</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-bukkit</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-bungee</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-fabric</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-sponge</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-velocity</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
</project>
+4 -3
View File
@@ -12,12 +12,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>viabackwards-parent</artifactId>
<groupId>nl.matsv</groupId>
<version>2.2.0</version>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>viabackwards-bukkit</artifactId>
@@ -32,13 +32,14 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.11-R0.1-SNAPSHOT</version>
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-core</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -11,12 +11,26 @@
package nl.matsv.viabackwards;
import nl.matsv.viabackwards.api.ViaBackwardsPlatform;
import nl.matsv.viabackwards.listener.LecternInteractListener;
import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.bukkit.platform.BukkitViaLoader;
public class BukkitPlugin extends JavaPlugin implements ViaBackwardsPlatform {
@Override
public void onEnable() {
this.init();
init(getDataFolder());
Via.getPlatform().runSync(this::onServerLoaded);
}
private void onServerLoaded() {
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_14.getId()) {
BukkitViaLoader loader = (BukkitViaLoader) Via.getManager().getLoader();
loader.storeListener(new LecternInteractListener(this)).register();
}
}
@Override
@@ -0,0 +1,47 @@
package nl.matsv.viabackwards.listener;
import nl.matsv.viabackwards.BukkitPlugin;
import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Lectern;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
public class LecternInteractListener extends ViaBukkitListener {
public LecternInteractListener(BukkitPlugin plugin) {
super(plugin, Protocol1_13_2To1_14.class);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onLecternInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (!isOnPipe(player)) return;
Block block = event.getClickedBlock();
if (block == null || block.getType() != Material.LECTERN) return;
Lectern lectern = (Lectern) block.getState();
ItemStack book = lectern.getInventory().getItem(0);
if (book == null) return;
BookMeta meta = (BookMeta) book.getItemMeta();
// Open a book with the text of the lectern's writable book
ItemStack newBook = new ItemStack(Material.WRITTEN_BOOK);
BookMeta newBookMeta = (BookMeta) newBook.getItemMeta();
newBookMeta.setPages(meta.getPages());
newBookMeta.setAuthor("an upsidedown person");
newBookMeta.setTitle("buk");
newBook.setItemMeta(newBookMeta);
player.openBook(newBook);
event.setCancelled(true);
}
}
+4 -3
View File
@@ -1,10 +1,11 @@
name: ViaBackwards
version: ${project.version}
description: Allows 1.9.x on a 1.10 Spigot server
description: Allow older Minecraft versions to connect to a newer server version.
main: nl.matsv.viabackwards.BukkitPlugin
api-version: 1.13
authors: [Matsv]
website: https://matsv.nl
authors: [Matsv, KennyTV, Gerrygames, creeper123123321, ForceUpdate1]
website: ${project.url}
load: STARTUP
depend: [ViaVersion]
+4 -3
View File
@@ -12,12 +12,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>viabackwards-parent</artifactId>
<groupId>nl.matsv</groupId>
<version>2.2.0</version>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>viabackwards-bungee</artifactId>
@@ -34,7 +34,7 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.11-SNAPSHOT</version>
<version>1.15-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -43,6 +43,7 @@
<groupId>nl.matsv</groupId>
<artifactId>viabackwards-core</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -12,12 +12,13 @@ package nl.matsv.viabackwards;
import net.md_5.bungee.api.plugin.Plugin;
import nl.matsv.viabackwards.api.ViaBackwardsPlatform;
import us.myles.ViaVersion.api.Via;
public class BungeePlugin extends Plugin implements ViaBackwardsPlatform {
@Override
public void onEnable() {
this.init();
public void onLoad() {
Via.getManager().addEnableListener(() -> this.init(getDataFolder()));
}
// Why is this not a thing in Bungee? O_o
+1 -1
View File
@@ -1,5 +1,5 @@
name: ViaBackwards
main: nl.matsv.viabackwards.BungeePlugin
author: Matsv
author: "Matsv, KennyTV, Gerrygames, creeper123123321, ForceUpdate1"
version: ${project.version}
depends: [ViaVersion]
+2 -11
View File
@@ -12,22 +12,15 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>viabackwards-parent</artifactId>
<groupId>nl.matsv</groupId>
<version>2.2.0</version>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>viabackwards-core</artifactId>
<repositories>
<repository>
<id>viaversion-repo</id>
<url>https://repo.viaversion.com/</url>
</repository>
</repositories>
<dependencies>
<!-- Netty (Network Library) -->
<dependency>
@@ -38,6 +31,4 @@
<optional>true</optional>
</dependency>
</dependencies>
</project>
@@ -11,17 +11,26 @@
package nl.matsv.viabackwards;
import com.google.common.base.Preconditions;
import lombok.Getter;
import nl.matsv.viabackwards.api.ViaBackwardsConfig;
import nl.matsv.viabackwards.api.ViaBackwardsPlatform;
public class ViaBackwards {
@Getter
private static ViaBackwardsPlatform platform;
public static void init(ViaBackwardsPlatform platform) {
private static ViaBackwardsPlatform platform;
private static ViaBackwardsConfig config;
public static void init(ViaBackwardsPlatform platform, ViaBackwardsConfig config) {
Preconditions.checkArgument(platform != null, "ViaBackwards is already initialized");
ViaBackwards.platform = platform;
ViaBackwards.config = config;
}
public static ViaBackwardsPlatform getPlatform() {
return platform;
}
public static ViaBackwardsConfig getConfig() {
return config;
}
}
@@ -0,0 +1,61 @@
package nl.matsv.viabackwards;
import us.myles.ViaVersion.util.Config;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class ViaBackwardsConfig extends Config implements nl.matsv.viabackwards.api.ViaBackwardsConfig {
private boolean addCustomEnchantsToLore;
private boolean addTeamColorToPrefix;
private boolean fix1_13FacePlayer;
public ViaBackwardsConfig(File configFile) {
super(configFile);
}
@Override
public void reloadConfig() {
super.reloadConfig();
loadFields();
}
private void loadFields() {
addCustomEnchantsToLore = getBoolean("add-custom-enchants-into-lore", true);
addTeamColorToPrefix = getBoolean("add-teamcolor-to-prefix", true);
fix1_13FacePlayer = getBoolean("fix-1_13-face-player", false);
}
@Override
public boolean addCustomEnchantsToLore() {
return addCustomEnchantsToLore;
}
@Override
public boolean addTeamColorTo1_13Prefix() {
return addTeamColorToPrefix;
}
@Override
public boolean isFix1_13FacePlayer() {
return fix1_13FacePlayer;
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> map) {
}
@Override
public List<String> getUnsupportedOptions() {
return Collections.emptyList();
}
}
@@ -1,17 +1,36 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ServerboundPacketType;
public abstract class BackwardsProtocol extends Protocol {
public abstract class BackwardsProtocol<C1 extends ClientboundPacketType, C2 extends ClientboundPacketType, S1 extends ServerboundPacketType, S2 extends ServerboundPacketType>
extends Protocol<C1, C2, S1, S2> {
protected BackwardsProtocol() {
super();
}
protected BackwardsProtocol(boolean hasMappingDataToLoad) {
super(hasMappingDataToLoad);
}
protected BackwardsProtocol(@Nullable Class<C1> oldClientboundPacketEnum, @Nullable Class<C2> clientboundPacketEnum,
@Nullable Class<S1> oldServerboundPacketEnum, @Nullable Class<S2> serverboundPacketEnum) {
super(oldClientboundPacketEnum, clientboundPacketEnum, oldServerboundPacketEnum, serverboundPacketEnum, false);
}
protected BackwardsProtocol(@Nullable Class<C1> oldClientboundPacketEnum, @Nullable Class<C2> clientboundPacketEnum,
@Nullable Class<S1> oldServerboundPacketEnum, @Nullable Class<S2> serverboundPacketEnum, boolean hasMappingDatatToLoad) {
super(oldClientboundPacketEnum, clientboundPacketEnum, oldServerboundPacketEnum, serverboundPacketEnum, hasMappingDatatToLoad);
}
/**
* Waits for the given protocol to be loaded to then asynchronously execute the runnable for this protocol.
*/
protected void executeAsyncAfterLoaded(Class<? extends Protocol> protocolClass, Runnable runnable) {
ProtocolRegistry.addMappingLoaderFuture(getClass(), protocolClass, runnable);
}
}
@@ -0,0 +1,25 @@
package nl.matsv.viabackwards.api;
public interface ViaBackwardsConfig {
/**
* Mimics name and level of a custom enchant through the item's lore.
*
* @return true if enabled
*/
boolean addCustomEnchantsToLore();
/**
* Writes the color of the scoreboard team after the prefix.
*
* @return true if enabled
*/
boolean addTeamColorTo1_13Prefix();
/**
* Converts the new 1.13 face player packets to look packets.
*
* @return true if enabled
*/
boolean isFix1_13FacePlayer();
}
@@ -11,56 +11,96 @@
package nl.matsv.viabackwards.api;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.ViaBackwardsConfig;
import nl.matsv.viabackwards.api.rewriters.TranslatableRewriter;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.protocol.protocol1_12_1to1_12_2.Protocol1_12_1To1_12_2;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import nl.matsv.viabackwards.protocol.protocol1_12to1_12_1.Protocol1_12To1_12_1;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.Protocol1_13_1To1_13_2;
import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14;
import nl.matsv.viabackwards.protocol.protocol1_13to1_13_1.Protocol1_13To1_13_1;
import nl.matsv.viabackwards.protocol.protocol1_14_1to1_14_2.Protocol1_14_1To1_14_2;
import nl.matsv.viabackwards.protocol.protocol1_14_2to1_14_3.Protocol1_14_2To1_14_3;
import nl.matsv.viabackwards.protocol.protocol1_14_3to1_14_4.Protocol1_14_3To1_14_4;
import nl.matsv.viabackwards.protocol.protocol1_14_4to1_15.Protocol1_14_4To1_15;
import nl.matsv.viabackwards.protocol.protocol1_14to1_14_1.Protocol1_14To1_14_1;
import nl.matsv.viabackwards.protocol.protocol1_15_1to1_15_2.Protocol1_15_1To1_15_2;
import nl.matsv.viabackwards.protocol.protocol1_15_2to1_16.Protocol1_15_2To1_16;
import nl.matsv.viabackwards.protocol.protocol1_15to1_15_1.Protocol1_15To1_15_1;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.update.Version;
import java.lang.reflect.Field;
import java.util.Collections;
import java.io.File;
import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
/**
* Initialize ViaBackwards
*/
default void init() {
ViaBackwards.init(this);
import static us.myles.ViaVersion.api.protocol.ProtocolRegistry.registerProtocol;
if (!isOutdated()) {
ProtocolRegistry.registerProtocol(new Protocol1_9_4To1_10(), Collections.singletonList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_10.getId());
ProtocolRegistry.registerProtocol(new Protocol1_10To1_11(), Collections.singletonList(ProtocolVersion.v1_10.getId()), ProtocolVersion.v1_11.getId());
ProtocolRegistry.registerProtocol(new Protocol1_11To1_11_1(), Collections.singletonList(ProtocolVersion.v1_11.getId()), ProtocolVersion.v1_11_1.getId());
ProtocolRegistry.registerProtocol(new Protocol1_11_1To1_12(), Collections.singletonList(ProtocolVersion.v1_11_1.getId()), ProtocolVersion.v1_12.getId());
ProtocolRegistry.registerProtocol(new Protocol1_12To1_12_1(), Collections.singletonList(ProtocolVersion.v1_12.getId()), ProtocolVersion.v1_12_1.getId());
}
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "3.0.0";
/**
* Initialize ViaBackwards.
*/
default void init(File dataFolder) {
ViaBackwardsConfig config = new ViaBackwardsConfig(new File(dataFolder, "config.yml"));
config.reloadConfig();
ViaBackwards.init(this, config);
if (isOutdated()) return;
String version = ViaBackwards.class.getPackage().getImplementationVersion();
Via.getManager().getSubPlatforms().add(version != null ? version : "UNKNOWN");
getLogger().info("Loading translations...");
TranslatableRewriter.loadTranslatables();
getLogger().info("Registering protocols...");
registerProtocol(new Protocol1_9_4To1_10(), ProtocolVersion.v1_9_3, ProtocolVersion.v1_10);
registerProtocol(new Protocol1_10To1_11(), ProtocolVersion.v1_10, ProtocolVersion.v1_11);
registerProtocol(new Protocol1_11To1_11_1(), ProtocolVersion.v1_11, ProtocolVersion.v1_11_1);
registerProtocol(new Protocol1_11_1To1_12(), ProtocolVersion.v1_11_1, ProtocolVersion.v1_12);
registerProtocol(new Protocol1_12To1_12_1(), ProtocolVersion.v1_12, ProtocolVersion.v1_12_1);
registerProtocol(new Protocol1_12_1To1_12_2(), ProtocolVersion.v1_12_1, ProtocolVersion.v1_12_2);
registerProtocol(new Protocol1_12_2To1_13(), ProtocolVersion.v1_12_2, ProtocolVersion.v1_13);
registerProtocol(new Protocol1_13To1_13_1(), ProtocolVersion.v1_13, ProtocolVersion.v1_13_1);
registerProtocol(new Protocol1_13_1To1_13_2(), ProtocolVersion.v1_13_1, ProtocolVersion.v1_13_2);
registerProtocol(new Protocol1_13_2To1_14(), ProtocolVersion.v1_13_2, ProtocolVersion.v1_14);
registerProtocol(new Protocol1_14To1_14_1(), ProtocolVersion.v1_14, ProtocolVersion.v1_14_1);
registerProtocol(new Protocol1_14_1To1_14_2(), ProtocolVersion.v1_14_1, ProtocolVersion.v1_14_2);
registerProtocol(new Protocol1_14_2To1_14_3(), ProtocolVersion.v1_14_2, ProtocolVersion.v1_14_3);
registerProtocol(new Protocol1_14_3To1_14_4(), ProtocolVersion.v1_14_3, ProtocolVersion.v1_14_4);
registerProtocol(new Protocol1_14_4To1_15(), ProtocolVersion.v1_14_4, ProtocolVersion.v1_15);
registerProtocol(new Protocol1_15To1_15_1(), ProtocolVersion.v1_15, ProtocolVersion.v1_15_1);
registerProtocol(new Protocol1_15_1To1_15_2(), ProtocolVersion.v1_15_1, ProtocolVersion.v1_15_2);
registerProtocol(new Protocol1_15_2To1_16(), ProtocolVersion.v1_15_2, ProtocolVersion.v1_16);
}
/**
* Logger provided by the platform
* Logger provided by the platform.
*
* @return logger instance
*/
Logger getLogger();
// TODO remove or better implement later
default boolean isOutdated() {
boolean upToDate = false;
try {
Class<?> clazz = Class.forName("us.myles.ViaVersion.api.protocol.ProtocolVersion");
Field v1_12_1 = clazz.getField("v1_12_1");
upToDate = (v1_12_1 != null);
} catch (ClassNotFoundException | NoSuchFieldException ignored) {
}
if (!upToDate) {
String vvVersion = Via.getPlatform().getPluginVersion();
if (vvVersion != null && new Version(vvVersion).compareTo(new Version(MINIMUM_VV_VERSION + "--")) < 0) {
getLogger().severe("================================");
getLogger().severe("YOUR VIAVERSION IS OUTDATED");
getLogger().severe("PLEASE USE THE LATEST VERSION");
getLogger().severe("PLEASE USE VIAVERSION " + MINIMUM_VV_VERSION + " OR NEWER");
getLogger().severe("LINK: https://viaversion.com");
getLogger().severe("VIABACKWARDS WILL NOW DISABLE");
getLogger().severe("================================");
@@ -73,7 +113,14 @@ public interface ViaBackwardsPlatform {
}
/**
* Disable the plugin
* Disable the plugin.
*/
void disable();
/**
* Returns ViaBackwards's data folder.
*
* @return data folder
*/
File getDataFolder();
}
@@ -0,0 +1,23 @@
package nl.matsv.viabackwards.api.data;
import net.md_5.bungee.api.ChatColor;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
public class MappedItem {
private final int id;
private final String jsonName;
public MappedItem(int id, String name) {
this.id = id;
this.jsonName = ChatRewriter.legacyTextToJson(ChatColor.RESET + name);
}
public int getId() {
return id;
}
public String getJsonName() {
return jsonName;
}
}
@@ -0,0 +1,61 @@
package nl.matsv.viabackwards.api.data;
import net.md_5.bungee.api.ChatColor;
import nl.matsv.viabackwards.utils.Block;
import org.jetbrains.annotations.Nullable;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
public class MappedLegacyBlockItem {
private final int id;
private final short data;
private final String name;
private final Block block;
private BlockEntityHandler blockEntityHandler;
public MappedLegacyBlockItem(int id, short data, @Nullable String name, boolean block) {
this.id = id;
this.data = data;
this.name = name != null ? ChatColor.RESET + name : null;
this.block = block ? new Block(id, data) : null;
}
public int getId() {
return id;
}
public short getData() {
return data;
}
public String getName() {
return name;
}
public boolean isBlock() {
return block != null;
}
public Block getBlock() {
return block;
}
public boolean hasBlockEntityHandler() {
return blockEntityHandler != null;
}
@Nullable
public BlockEntityHandler getBlockEntityHandler() {
return blockEntityHandler;
}
public void setBlockEntityHandler(@Nullable BlockEntityHandler blockEntityHandler) {
this.blockEntityHandler = blockEntityHandler;
}
@FunctionalInterface
public interface BlockEntityHandler {
CompoundTag handleOrNewCompoundTag(int block, CompoundTag tag);
}
}
@@ -0,0 +1,56 @@
package nl.matsv.viabackwards.api.data;
import nl.matsv.viabackwards.ViaBackwards;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectMap;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import java.util.HashMap;
import java.util.Map;
/**
* Backwards mappings for newly (!) added items.
*/
public class VBItemMappings {
private final Int2ObjectMap<MappedItem> itemMapping;
public VBItemMappings(JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping) {
Map<Integer, MappedItem> itemMapping = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : diffMapping.entrySet()) {
JsonObject object = entry.getValue().getAsJsonObject();
String mappedIdName = object.getAsJsonPrimitive("id").getAsString();
Map.Entry<String, JsonElement> value = MappingDataLoader.findValue(newMapping, mappedIdName);
if (value == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("No key for " + mappedIdName + " :( ");
}
continue;
}
Map.Entry<String, JsonElement> oldEntry = MappingDataLoader.findValue(oldMapping, entry.getKey());
if (oldEntry == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("No old entry for " + mappedIdName + " :( ");
}
continue;
}
int id = Integer.parseInt(oldEntry.getKey());
int mappedId = Integer.parseInt(value.getKey());
String name = object.getAsJsonPrimitive("name").getAsString();
itemMapping.put(id, new MappedItem(mappedId, name));
}
this.itemMapping = new Int2ObjectOpenHashMap<>(itemMapping, 1F);
}
@Nullable
public MappedItem getMappedItem(int id) {
return itemMapping.get(id);
}
}
@@ -0,0 +1,125 @@
package nl.matsv.viabackwards.api.data;
import nl.matsv.viabackwards.ViaBackwards;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.viaversion.libs.gson.JsonArray;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonIOException;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.gson.JsonPrimitive;
import us.myles.viaversion.libs.gson.JsonSyntaxException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
public class VBMappingDataLoader {
public static JsonObject loadFromDataDir(String name) {
File file = new File(ViaBackwards.getPlatform().getDataFolder(), name);
if (!file.exists()) return loadData(name);
// Load the file from the platform's directory if present
try (FileReader reader = new FileReader(file)) {
return GsonUtil.getGson().fromJson(reader, JsonObject.class);
} catch (JsonSyntaxException e) {
ViaBackwards.getPlatform().getLogger().warning(name + " is badly formatted!");
e.printStackTrace();
ViaBackwards.getPlatform().getLogger().warning("Falling back to resource's file!");
return loadData(name);
} catch (IOException | JsonIOException e) {
e.printStackTrace();
}
return null;
}
public static JsonObject loadData(String name) {
InputStream stream = VBMappingDataLoader.class.getClassLoader().getResourceAsStream("assets/viabackwards/data/" + name);
try (InputStreamReader reader = new InputStreamReader(stream)) {
return GsonUtil.getGson().fromJson(reader, JsonObject.class);
} catch (IOException e) {
return null;
}
}
public static void mapIdentifiers(short[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers, JsonObject diffIdentifiers) {
mapIdentifiers(output, oldIdentifiers, newIdentifiers, diffIdentifiers, true);
}
public static void mapIdentifiers(short[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers, JsonObject diffIdentifiers, boolean warnOnMissing) {
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
String key = entry.getValue().getAsString();
Map.Entry<String, JsonElement> value = MappingDataLoader.findValue(newIdentifiers, key);
if (value == null) {
if (diffIdentifiers != null) {
// Search in diff mappings
JsonPrimitive diffValueJson = diffIdentifiers.getAsJsonPrimitive(key);
String diffValue = diffValueJson != null ? diffValueJson.getAsString() : null;
int dataIndex;
if (diffValue == null && (dataIndex = key.indexOf('[')) != -1
&& (diffValueJson = diffIdentifiers.getAsJsonPrimitive(key.substring(0, dataIndex))) != null) {
// Check for wildcard mappings
diffValue = diffValueJson.getAsString();
// Keep original properties if value ends with [
if (diffValue.endsWith("[")) {
diffValue += key.substring(dataIndex + 1);
}
}
if (diffValue != null) {
value = MappingDataLoader.findValue(newIdentifiers, diffValue);
}
}
if (value == null) {
// Nothing found :(
if (warnOnMissing && !Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("No key for " + entry.getValue() + " :( ");
}
continue;
}
}
output[Integer.parseInt(entry.getKey())] = Short.parseShort(value.getKey());
}
}
public static void mapIdentifiers(short[] output, JsonArray oldIdentifiers, JsonArray newIdentifiers, JsonObject diffIdentifiers, boolean warnOnMissing) {
int i = -1;
for (JsonElement oldIdentifier : oldIdentifiers) {
i++;
String key = oldIdentifier.getAsString();
Integer index = MappingDataLoader.findIndex(newIdentifiers, key);
if (index == null) {
// Search in diff mappings
if (diffIdentifiers != null) {
JsonPrimitive diffValue = diffIdentifiers.getAsJsonPrimitive(key);
if (diffValue == null) {
if (warnOnMissing && !Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("No diff key for " + key + " :( ");
}
continue;
}
String mappedName = diffValue.getAsString();
if (mappedName.isEmpty()) continue; // "empty" remaps
index = MappingDataLoader.findIndex(newIdentifiers, mappedName);
}
if (index == null) {
if (warnOnMissing && !Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("No key for " + key + " :( ");
}
continue;
}
}
output[i] = index.shortValue();
}
}
}
@@ -0,0 +1,48 @@
package nl.matsv.viabackwards.api.data;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.viaversion.libs.gson.JsonArray;
import us.myles.viaversion.libs.gson.JsonObject;
import java.util.Arrays;
public class VBMappings extends Mappings {
public VBMappings(JsonObject oldMapping, JsonObject newMapping, boolean warnOnMissing) {
this(oldMapping, newMapping, null, warnOnMissing);
}
public VBMappings(int size, JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping) {
this(size, oldMapping, newMapping, diffMapping, true);
}
public VBMappings(JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping) {
this(oldMapping, newMapping, diffMapping, true);
}
public VBMappings(int size, JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping, boolean warnOnMissing) {
super(create(size, oldMapping, newMapping, diffMapping, warnOnMissing));
}
public VBMappings(JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping, boolean warnOnMissing) {
super(create(oldMapping.entrySet().size(), oldMapping, newMapping, diffMapping, warnOnMissing));
}
public VBMappings(JsonArray oldMapping, JsonArray newMapping, JsonObject diffMapping) {
super(create(oldMapping, newMapping, diffMapping, true));
}
private static short[] create(int size, JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping, boolean warnOnMissing) {
short[] oldToNew = new short[size];
Arrays.fill(oldToNew, (short) -1);
VBMappingDataLoader.mapIdentifiers(oldToNew, oldMapping, newMapping, diffMapping, warnOnMissing);
return oldToNew;
}
private static short[] create(JsonArray oldMapping, JsonArray newMapping, JsonObject diffMapping, boolean warnOnMissing) {
short[] oldToNew = new short[oldMapping.size()];
Arrays.fill(oldToNew, (short) -1);
VBMappingDataLoader.mapIdentifiers(oldToNew, oldMapping, newMapping, diffMapping, warnOnMissing);
return oldToNew;
}
}
@@ -0,0 +1,43 @@
package nl.matsv.viabackwards.api.data;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.viaversion.libs.gson.JsonArray;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import java.util.HashMap;
import java.util.Map;
/**
* Backwards mappings for sound ids and names.
*/
public class VBSoundMappings {
private final Map<String, String> namedSoundMappings = new HashMap<>();
private final Mappings idMappings;
public VBSoundMappings(JsonArray oldSounds, JsonArray newSounds, JsonObject diffMapping) {
idMappings = new VBMappings(oldSounds, newSounds, diffMapping);
for (Map.Entry<String, JsonElement> entry : diffMapping.entrySet()) {
String key = entry.getKey();
if (key.indexOf(':') == -1) {
key = "minecraft:" + key;
}
String value = entry.getValue().getAsString();
if (value.indexOf(':') == -1) {
value = "minecraft:" + value;
}
namedSoundMappings.put(key, value);
}
}
@Nullable
public String getNewId(String oldId) {
return namedSoundMappings.get(oldId);
}
public int getNewId(int oldId) {
return idMappings.getNewId(oldId);
}
}
@@ -1,72 +0,0 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.entities.blockitem;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import nl.matsv.viabackwards.utils.Block;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
@RequiredArgsConstructor
@Getter
public class BlockItemSettings {
private final int id;
private Item repItem;
private Block repBlock;
private BlockEntityHandler blockEntityHandler;
private ItemHandler itemHandler;
public BlockItemSettings repItem(Item item) {
this.repItem = item;
return this;
}
public BlockItemSettings repBlock(Block block) {
this.repBlock = block;
return this;
}
public BlockItemSettings blockEntityHandler(BlockEntityHandler handler) {
this.blockEntityHandler = handler;
return this;
}
public BlockItemSettings itemHandler(ItemHandler handler) {
this.itemHandler = handler;
return this;
}
public boolean hasRepItem() {
return repItem != null;
}
public boolean hasRepBlock() {
return repBlock != null;
}
public boolean hasEntityHandler() {
return blockEntityHandler != null;
}
public boolean hasItemTagHandler() {
return itemHandler != null;
}
public interface BlockEntityHandler {
CompoundTag handleOrNewCompoundTag(int block, CompoundTag tag);
}
public interface ItemHandler {
Item handle(Item i);
}
}
@@ -14,5 +14,6 @@ import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
public interface MetaHandler {
Metadata handle(MetaHandlerEvent e) throws RemovedValueException;
}
@@ -10,33 +10,77 @@
package nl.matsv.viabackwards.api.entities.meta;
import lombok.AllArgsConstructor;
import lombok.Getter;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import java.util.Optional;
import java.util.ArrayList;
import java.util.List;
@Getter
@AllArgsConstructor
public class MetaHandlerEvent {
private UserConnection user;
private EntityTracker.StoredEntity entity;
private int index = -1;
private Metadata data;
@Getter
private MetaStorage storage;
private final UserConnection user;
private final EntityTracker.StoredEntity entity;
private final int index;
private final Metadata data;
private final MetaStorage storage;
private List<Metadata> extraData;
public MetaHandlerEvent(UserConnection user, EntityTracker.StoredEntity entity, int index, Metadata data, MetaStorage storage) {
this.user = user;
this.entity = entity;
this.index = index;
this.data = data;
this.storage = storage;
}
public boolean hasData() {
return data != null;
}
public Optional<Metadata> getMetaByIndex(int index) {
for (Metadata meta : getStorage().getMetaDataList())
if (index == meta.getId())
return Optional.of(meta);
return Optional.empty();
public Metadata getMetaByIndex(int index) {
for (Metadata meta : storage.getMetaDataList()) {
if (index == meta.getId()) {
return meta;
}
}
return null;
}
public void clearExtraData() {
extraData = null;
}
public void createMeta(Metadata metadata) {
(extraData != null ? extraData : (extraData = new ArrayList<>())).add(metadata);
}
public UserConnection getUser() {
return user;
}
public EntityTracker.StoredEntity getEntity() {
return entity;
}
public int getIndex() {
return index;
}
public Metadata getData() {
return data;
}
public MetaStorage getStorage() {
return storage;
}
/**
* May be null, use {@link #createMeta(Metadata)} for adding metadata.
*/
@Nullable
public List<Metadata> getExtraData() {
return extraData;
}
}
@@ -10,27 +10,22 @@
package nl.matsv.viabackwards.api.entities.meta;
import lombok.Getter;
import lombok.ToString;
import nl.matsv.viabackwards.api.entities.types.AbstractEntityType;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import java.util.List;
@ToString
@Getter
public class MetaHandlerSettings {
private AbstractEntityType filterType;
private boolean filterFamily = false;
private EntityType filterType;
private boolean filterFamily;
private int filterIndex = -1;
private MetaHandler handler;
public MetaHandlerSettings filter(AbstractEntityType type) {
public MetaHandlerSettings filter(EntityType type) {
return filter(type, filterFamily, filterIndex);
}
public MetaHandlerSettings filter(AbstractEntityType type, boolean filterFamily) {
public MetaHandlerSettings filter(EntityType type, boolean filterFamily) {
return filter(type, filterFamily, filterIndex);
}
@@ -38,18 +33,18 @@ public class MetaHandlerSettings {
return filter(filterType, filterFamily, index);
}
public MetaHandlerSettings filter(AbstractEntityType type, int index) {
public MetaHandlerSettings filter(EntityType type, int index) {
return filter(type, filterFamily, index);
}
public MetaHandlerSettings filter(AbstractEntityType type, boolean filterFamily, int index) {
public MetaHandlerSettings filter(EntityType type, boolean filterFamily, int index) {
this.filterType = type;
this.filterFamily = filterFamily;
this.filterIndex = index;
return this;
}
public void handle(MetaHandler handler) {
public void handle(@Nullable MetaHandler handler) {
this.handler = handler;
}
@@ -63,7 +58,7 @@ public class MetaHandlerSettings {
public void removed() {
handle(e -> {
throw new RemovedValueException();
throw RemovedValueException.EX;
});
}
@@ -83,20 +78,41 @@ public class MetaHandlerSettings {
return filterFamily;
}
public boolean isGucci(AbstractEntityType type, Metadata metadata) {
if (hasHandler()) {
if (hasType()) {
List<AbstractEntityType> family = type.getParents();
if (isFilterFamily()) {
if (!family.contains(getFilterType()))
return false;
} else {
if (!getFilterType().is(type))
return false;
}
}
return !(hasIndex() && metadata.getId() != getFilterIndex());
/**
* Returns true if the metadata should be handled by this object.
*
* @param type entity type
* @param metadata metadata
* @return true if gucci
*/
public boolean isGucci(EntityType type, Metadata metadata) {
if (!hasHandler()) return false;
if (hasType() && (filterFamily ? !type.isOrHasParent(filterType) : !filterType.is(type))) {
return false;
}
return false;
return !hasIndex() || metadata.getId() == filterIndex;
}
public EntityType getFilterType() {
return filterType;
}
public int getFilterIndex() {
return filterIndex;
}
@Nullable
public MetaHandler getHandler() {
return handler;
}
@Override
public String toString() {
return "MetaHandlerSettings{" +
"filterType=" + filterType +
", filterFamily=" + filterFamily +
", filterIndex=" + filterIndex +
", handler=" + handler +
'}';
}
}
@@ -10,36 +10,78 @@
package nl.matsv.viabackwards.api.entities.storage;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
@RequiredArgsConstructor
@Getter
@ToString
public class EntityData {
private final int id;
private final boolean isObject;
private String mobName;
private final int replacementId;
private final int objectData;
private String mobName;
private MetaCreator defaultMeta;
public EntityData(int id, int replacementId) {
this.id = id;
this.replacementId = replacementId;
}
public EntityData jsonName(String name) {
this.mobName = ChatRewriter.legacyTextToJson(name);
return this;
}
public EntityData mobName(String name) {
this.mobName = name;
return this;
}
public void spawnMetadata(MetaCreator handler) {
public EntityData spawnMetadata(MetaCreator handler) {
this.defaultMeta = handler;
return this;
}
public boolean hasBaseMeta() {
return this.defaultMeta != null;
}
public int getId() {
return id;
}
@Nullable
public String getMobName() {
return mobName;
}
public int getReplacementId() {
return replacementId;
}
@Nullable
public MetaCreator getDefaultMeta() {
return defaultMeta;
}
public boolean isObject() {
return false;
}
public int getObjectData() {
return -1;
}
@Override
public String toString() {
return "EntityData{" +
"id=" + id +
", mobName='" + mobName + '\'' +
", replacementId=" + replacementId +
", defaultMeta=" + defaultMeta +
'}';
}
@FunctionalInterface
public interface MetaCreator {
void handle(MetaStorage storage);
void createMeta(MetaStorage storage);
}
}
@@ -0,0 +1,22 @@
package nl.matsv.viabackwards.api.entities.storage;
public class EntityObjectData extends EntityData {
private final boolean isObject;
private final int objectData;
public EntityObjectData(int id, boolean isObject, int replacementId, int objectData) {
super(id, replacementId);
this.isObject = isObject;
this.objectData = objectData;
}
@Override
public boolean isObject() {
return isObject;
}
@Override
public int getObjectData() {
return objectData;
}
}
@@ -0,0 +1,97 @@
package nl.matsv.viabackwards.api.entities.storage;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.rewriters.EntityRewriterBase;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import java.util.function.Supplier;
public class EntityPositionHandler {
public static final double RELATIVE_MOVE_FACTOR = 32 * 128;
private final EntityRewriterBase<?> entityRewriter;
private final Class<? extends EntityPositionStorage> storageClass;
private final Supplier<? extends EntityPositionStorage> storageSupplier;
private boolean warnedForMissingEntity;
public EntityPositionHandler(EntityRewriterBase<?> entityRewriter,
Class<? extends EntityPositionStorage> storageClass, Supplier<? extends EntityPositionStorage> storageSupplier) {
this.entityRewriter = entityRewriter;
this.storageClass = storageClass;
this.storageSupplier = storageSupplier;
}
public void cacheEntityPosition(PacketWrapper wrapper, boolean create, boolean relative) throws Exception {
cacheEntityPosition(wrapper,
wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), create, relative);
}
public void cacheEntityPosition(PacketWrapper wrapper, double x, double y, double z, boolean create, boolean relative) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityTracker.StoredEntity storedEntity = entityRewriter.getEntityTracker(wrapper.user()).getEntity(entityId);
if (storedEntity == null) {
if (Via.getManager().isDebug()) { // There is too many plugins violating this out there, and reading seems to be hard! :>
ViaBackwards.getPlatform().getLogger().warning("Stored entity with id " + entityId + " missing at position: " + x + " - " + y + " - " + z + " in " + storageClass.getSimpleName());
if (entityId == -1 && x == 0 && y == 0 && z == 0) {
ViaBackwards.getPlatform().getLogger().warning("DO NOT REPORT THIS TO VIA, THIS IS A PLUGIN ISSUE");
} else if (!warnedForMissingEntity) {
warnedForMissingEntity = true;
ViaBackwards.getPlatform().getLogger().warning("This is very likely caused by a plugin sending a teleport packet for an entity outside of the player's range.");
}
}
return;
}
EntityPositionStorage positionStorage = create ? storageSupplier.get() : storedEntity.get(storageClass);
if (positionStorage == null) {
ViaBackwards.getPlatform().getLogger().warning("Stored entity with id " + entityId + " missing " + storageClass.getSimpleName());
return;
}
positionStorage.setCoordinates(x, y, z, relative);
storedEntity.put(positionStorage);
}
public EntityPositionStorage getStorage(UserConnection user, int entityId) {
EntityTracker.StoredEntity storedEntity = user.get(EntityTracker.class).get(entityRewriter.getProtocol()).getEntity(entityId);
EntityPositionStorage entityStorage;
if (storedEntity == null || (entityStorage = storedEntity.get(EntityPositionStorage.class)) == null) {
ViaBackwards.getPlatform().getLogger().warning("Untracked entity with id " + entityId + " in " + storageClass.getSimpleName());
return null;
}
return entityStorage;
}
public static void writeFacingAngles(PacketWrapper wrapper, double x, double y, double z, double targetX, double targetY, double targetZ) {
double dX = targetX - x;
double dY = targetY - y;
double dZ = targetZ - z;
double r = Math.sqrt(dX * dX + dY * dY + dZ * dZ);
double yaw = -Math.atan2(dX, dZ) / Math.PI * 180;
if (yaw < 0) {
yaw = 360 + yaw;
}
double pitch = -Math.asin(dY / r) / Math.PI * 180;
wrapper.write(Type.BYTE, (byte) (yaw * 256f / 360f));
wrapper.write(Type.BYTE, (byte) (pitch * 256f / 360f));
}
public static void writeFacingDegrees(PacketWrapper wrapper, double x, double y, double z, double targetX, double targetY, double targetZ) {
double dX = targetX - x;
double dY = targetY - y;
double dZ = targetZ - z;
double r = Math.sqrt(dX * dX + dY * dY + dZ * dZ);
double yaw = -Math.atan2(dX, dZ) / Math.PI * 180;
if (yaw < 0) {
yaw = 360 + yaw;
}
double pitch = -Math.asin(dY / r) / Math.PI * 180;
wrapper.write(Type.FLOAT, (float) yaw);
wrapper.write(Type.FLOAT, (float) pitch);
}
}
@@ -0,0 +1,31 @@
package nl.matsv.viabackwards.api.entities.storage;
public abstract class EntityPositionStorage implements EntityStorage {
private double x;
private double y;
private double z;
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public void setCoordinates(double x, double y, double z, boolean relative) {
if (relative) {
this.x += x;
this.y += y;
this.z += z;
} else {
this.x = x;
this.y = y;
this.z = z;
}
}
}
@@ -10,5 +10,5 @@
package nl.matsv.viabackwards.api.entities.storage;
public class EntityStorage {
public interface EntityStorage {
}
@@ -10,20 +10,17 @@
package nl.matsv.viabackwards.api.entities.storage;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.types.AbstractEntityType;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.EntityType;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject {
private Map<BackwardsProtocol, ProtocolEntityTracker> trackers = new ConcurrentHashMap<>();
private final Map<BackwardsProtocol, ProtocolEntityTracker> trackers = new ConcurrentHashMap<>();
public EntityTracker(UserConnection user) {
super(user);
@@ -33,45 +30,43 @@ public class EntityTracker extends StoredObject {
trackers.put(protocol, new ProtocolEntityTracker());
}
@Nullable
public ProtocolEntityTracker get(BackwardsProtocol protocol) {
return trackers.get(protocol);
}
public class ProtocolEntityTracker {
private Map<Integer, StoredEntity> entityMap = new ConcurrentHashMap<>();
public static class ProtocolEntityTracker {
private final Map<Integer, StoredEntity> entityMap = new ConcurrentHashMap<>();
public void trackEntityType(int id, AbstractEntityType type) {
if (entityMap.containsKey(id))
return;
entityMap.put(id, new StoredEntity(id, type));
public void trackEntityType(int id, EntityType type) {
entityMap.putIfAbsent(id, new StoredEntity(id, type));
}
public void removeEntity(int id) {
entityMap.remove(id);
}
public AbstractEntityType getEntityType(int id) {
if (containsEntity(id))
return getEntity(id).get().getType();
return null;
@Nullable
public EntityType getEntityType(int id) {
StoredEntity storedEntity = entityMap.get(id);
return storedEntity != null ? storedEntity.getType() : null;
}
public Optional<StoredEntity> getEntity(int id) {
return Optional.ofNullable(entityMap.get(id));
}
public boolean containsEntity(int id) {
return entityMap.containsKey(id);
@Nullable
public StoredEntity getEntity(int id) {
return entityMap.get(id);
}
}
@RequiredArgsConstructor
@Getter
@ToString
public class StoredEntity {
public static final class StoredEntity {
private final int entityId;
private final AbstractEntityType type;
Map<Class<? extends EntityStorage>, EntityStorage> storedObjects = new ConcurrentHashMap<>();
private final EntityType type;
private final Map<Class<? extends EntityStorage>, EntityStorage> storedObjects = new ConcurrentHashMap<>();
private StoredEntity(final int entityId, final EntityType type) {
this.entityId = entityId;
this.type = type;
}
/**
* Get an object from the storage
@@ -80,6 +75,7 @@ public class EntityTracker extends StoredObject {
* @param <T> The type of the class you want to get.
* @return The requested object
*/
@Nullable
public <T extends EntityStorage> T get(Class<T> objectClass) {
return (T) storedObjects.get(objectClass);
}
@@ -102,5 +98,22 @@ public class EntityTracker extends StoredObject {
public void put(EntityStorage object) {
storedObjects.put(object.getClass(), object);
}
public int getEntityId() {
return entityId;
}
public EntityType getType() {
return type;
}
@Override
public String toString() {
return "StoredEntity{" +
"entityId=" + entityId +
", type=" + type +
", storedObjects=" + storedObjects +
'}';
}
}
}
@@ -10,43 +10,42 @@
package nl.matsv.viabackwards.api.entities.storage;
import lombok.*;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import java.util.List;
import java.util.Optional;
@Getter
@Setter
@ToString
@AllArgsConstructor
public class MetaStorage {
@NonNull
private List<Metadata> metaDataList;
public MetaStorage(List<Metadata> metaDataList) {
this.metaDataList = metaDataList;
}
public boolean has(Metadata data) {
return this.getMetaDataList().contains(data);
return this.metaDataList.contains(data);
}
public void delete(Metadata data) {
this.getMetaDataList().remove(data);
this.metaDataList.remove(data);
}
public void delete(int index) {
Optional<Metadata> data = get(index);
if (data.isPresent())
delete(data.get());
metaDataList.removeIf(meta -> meta.getId() == index);
}
public void add(Metadata data) {
this.getMetaDataList().add(data);
this.metaDataList.add(data);
}
public Optional<Metadata> get(int index) {
for (Metadata meta : this.getMetaDataList())
if (index == meta.getId())
return Optional.of(meta);
return Optional.empty();
@Nullable
public Metadata get(int index) {
for (Metadata meta : this.metaDataList) {
if (index == meta.getId()) {
return meta;
}
}
return null;
}
public Metadata getOrDefault(int index, Metadata data) {
@@ -54,10 +53,23 @@ public class MetaStorage {
}
public Metadata getOrDefault(int index, boolean removeIfExists, Metadata data) {
Optional<Metadata> existingData = get(index);
Metadata existingData = get(index);
if (removeIfExists && existingData != null) {
delete(existingData);
}
return existingData != null ? existingData : data;
}
if (removeIfExists && existingData.isPresent())
delete(existingData.get());
return existingData.orElse(data);
public List<Metadata> getMetaDataList() {
return metaDataList;
}
public void setMetaDataList(List<Metadata> metaDataList) {
this.metaDataList = metaDataList;
}
@Override
public String toString() {
return "MetaStorage{" + "metaDataList=" + metaDataList + '}';
}
}
@@ -0,0 +1,56 @@
package nl.matsv.viabackwards.api.entities.storage;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
public abstract class PlayerPositionStorage extends StoredObject {
private double x;
private double y;
private double z;
protected PlayerPositionStorage(UserConnection user) {
super(user);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public void setX(final double x) {
this.x = x;
}
public void setY(final double y) {
this.y = y;
}
public void setZ(final double z) {
this.z = z;
}
public void setCoordinates(PacketWrapper wrapper, boolean relative) throws Exception {
setCoordinates(wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), relative);
}
public void setCoordinates(double x, double y, double z, boolean relative) {
if (relative) {
this.x += x;
this.y += y;
this.z += z;
} else {
this.x = x;
this.y = y;
this.z = z;
}
}
}
@@ -1,242 +0,0 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.entities.types;
import lombok.AllArgsConstructor;
import lombok.Getter;
import nl.matsv.viabackwards.ViaBackwards;
import us.myles.ViaVersion.api.Via;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
// 1.10 Entity / Object ids
public class EntityType1_10 {
public static EntityType getTypeFromId(int typeID, boolean isObject) {
Optional<EntityType> type;
if (isObject)
type = ObjectType.getPCEntity(typeID);
else
type = EntityType.findById(typeID);
if (!type.isPresent()) {
if (!Via.getConfig().isSuppressMetadataErrors())
ViaBackwards.getPlatform().getLogger().severe("[EntityType1_10] Could not find type id " + typeID + " isObject=" + isObject);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type.get();
}
@AllArgsConstructor
@Getter
public enum EntityType implements AbstractEntityType {
ENTITY(-1),
DROPPED_ITEM(1, EntityType.ENTITY),
EXPERIENCE_ORB(2, EntityType.ENTITY),
LEASH_HITCH(8, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
PAINTING(9, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
ARROW(10, EntityType.ENTITY),
SNOWBALL(11, EntityType.ENTITY), // Actually EntityProjectile
FIREBALL(12, EntityType.ENTITY),
SMALL_FIREBALL(13, EntityType.ENTITY),
ENDER_PEARL(14, EntityType.ENTITY), // Actually EntityProjectile
ENDER_SIGNAL(15, EntityType.ENTITY),
THROWN_EXP_BOTTLE(17, EntityType.ENTITY),
ITEM_FRAME(18, EntityType.ENTITY), // Actually EntityHanging
WITHER_SKULL(19, EntityType.ENTITY),
PRIMED_TNT(20, EntityType.ENTITY),
FALLING_BLOCK(21, EntityType.ENTITY),
FIREWORK(22, EntityType.ENTITY),
TIPPED_ARROW(23, EntityType.ARROW),
SPECTRAL_ARROW(24, EntityType.ARROW),
SHULKER_BULLET(25, EntityType.ENTITY),
DRAGON_FIREBALL(26, EntityType.FIREBALL),
ENTITY_LIVING(-1, ENTITY),
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
ENTITY_HUMAN(-1, ENTITY_LIVING),
ARMOR_STAND(30, EntityType.ENTITY_LIVING),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
MINECART_COMMAND(40, MINECART_ABSTRACT),
BOAT(41, ENTITY),
MINECART_RIDEABLE(42, MINECART_ABSTRACT),
MINECART_CHEST(43, MINECART_ABSTRACT),
MINECART_FURNACE(44, MINECART_ABSTRACT),
MINECART_TNT(45, MINECART_ABSTRACT),
MINECART_HOPPER(46, MINECART_ABSTRACT),
MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
CREEPER(50, ENTITY_INSENTIENT),
SKELETON(51, ENTITY_INSENTIENT),
SPIDER(52, ENTITY_INSENTIENT),
GIANT(53, ENTITY_INSENTIENT),
ZOMBIE(54, ENTITY_INSENTIENT),
SLIME(55, ENTITY_INSENTIENT),
GHAST(56, ENTITY_INSENTIENT),
PIG_ZOMBIE(57, ZOMBIE),
ENDERMAN(58, ENTITY_INSENTIENT),
CAVE_SPIDER(59, SPIDER),
SILVERFISH(60, ENTITY_INSENTIENT),
BLAZE(61, ENTITY_INSENTIENT),
MAGMA_CUBE(62, SLIME),
ENDER_DRAGON(63, ENTITY_INSENTIENT),
WITHER(64, ENTITY_INSENTIENT),
BAT(65, ENTITY_INSENTIENT),
WITCH(66, ENTITY_INSENTIENT),
ENDERMITE(67, ENTITY_INSENTIENT),
GUARDIAN(68, ENTITY_INSENTIENT),
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
SHULKER(69, EntityType.IRON_GOLEM),
PIG(90, ENTITY_AGEABLE),
SHEEP(91, ENTITY_AGEABLE),
COW(92, ENTITY_AGEABLE),
CHICKEN(93, ENTITY_AGEABLE),
SQUID(94, ENTITY_INSENTIENT),
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
MUSHROOM_COW(96, COW),
SNOWMAN(97, EntityType.IRON_GOLEM),
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
HORSE(100, ENTITY_AGEABLE),
RABBIT(101, ENTITY_AGEABLE),
POLAR_BEAR(102, ENTITY_AGEABLE),
VILLAGER(120, ENTITY_AGEABLE),
ENDER_CRYSTAL(200, ENTITY),
SPLASH_POTION(-1, ENTITY),
LINGERING_POTION(-1, SPLASH_POTION),
AREA_EFFECT_CLOUD(-1, ENTITY),
EGG(-1, ENTITY),
FISHING_HOOK(-1, ENTITY),
LIGHTNING(-1, ENTITY),
WEATHER(-1, ENTITY),
PLAYER(-1, ENTITY_HUMAN),
COMPLEX_PART(-1, ENTITY);
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
public static Optional<EntityType> findById(int id) {
if (id == -1) // Check if this is called
return Optional.empty();
for (EntityType ent : EntityType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.empty();
}
@Override
public boolean is(AbstractEntityType... types) {
for (AbstractEntityType type : types)
if (is(type))
return true;
return false;
}
@Override
public boolean is(AbstractEntityType type) {
return this == type;
}
@Override
public boolean isOrHasParent(AbstractEntityType type) {
EntityType parent = this;
do {
if (parent.equals(type))
return true;
parent = parent.getParent();
} while (parent != null);
return false;
}
@Override
public List<AbstractEntityType> getParents() {
List<AbstractEntityType> types = new ArrayList<>();
EntityType parent = this;
do {
types.add(parent);
parent = parent.getParent();
} while (parent != null);
return types;
}
}
@AllArgsConstructor
@Getter
public enum ObjectType implements AbstractObjectType {
BOAT(1, EntityType.BOAT),
ITEM(2, EntityType.DROPPED_ITEM),
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
MINECART(10, EntityType.MINECART_ABSTRACT),
TNT_PRIMED(50, EntityType.PRIMED_TNT),
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
SNOWBALL(61, EntityType.SNOWBALL),
EGG(62, EntityType.EGG),
FIREBALL(63, EntityType.FIREBALL),
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
POTION(73, EntityType.SPLASH_POTION),
THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
FIREWORK(76, EntityType.FIREWORK),
LEASH(77, EntityType.LEASH_HITCH),
ARMOR_STAND(78, EntityType.ARMOR_STAND),
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private final int id;
private final EntityType type;
public static Optional<ObjectType> findById(int id) {
if (id == -1)
return Optional.empty();
for (ObjectType ent : ObjectType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.empty();
}
public static Optional<EntityType> getPCEntity(int id) {
Optional<ObjectType> output = findById(id);
if (!output.isPresent())
return Optional.empty();
return Optional.of(output.get().getType());
}
}
}
@@ -1,271 +0,0 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.entities.types;
import lombok.AllArgsConstructor;
import lombok.Getter;
import nl.matsv.viabackwards.ViaBackwards;
import us.myles.ViaVersion.api.Via;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class EntityType1_11 {
public static EntityType getTypeFromId(int typeID, boolean isObject) throws Exception {
Optional<EntityType> type;
if (isObject)
type = ObjectType.getPCEntity(typeID);
else
type = EntityType.findById(typeID);
if (!type.isPresent()) {
if (!Via.getConfig().isSuppressMetadataErrors())
ViaBackwards.getPlatform().getLogger().severe("[EntityType1_11] Could not find type id " + typeID + " isObject=" + isObject);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type.get();
}
@AllArgsConstructor
@Getter
public enum EntityType implements AbstractEntityType {
ENTITY(-1),
DROPPED_ITEM(1, ENTITY),
EXPERIENCE_ORB(2, ENTITY),
LEASH_HITCH(8, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
PAINTING(9, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
ARROW(10, ENTITY),
SNOWBALL(11, ENTITY), // Actually EntityProjectile
FIREBALL(12, ENTITY),
SMALL_FIREBALL(13, ENTITY),
ENDER_PEARL(14, ENTITY), // Actually EntityProjectile
ENDER_SIGNAL(15, ENTITY),
THROWN_EXP_BOTTLE(17, ENTITY),
ITEM_FRAME(18, ENTITY), // Actually EntityHanging
WITHER_SKULL(19, ENTITY),
PRIMED_TNT(20, ENTITY),
FALLING_BLOCK(21, ENTITY),
FIREWORK(22, ENTITY),
SPECTRAL_ARROW(24, ARROW),
SHULKER_BULLET(25, ENTITY),
DRAGON_FIREBALL(26, FIREBALL),
EVOCATION_FANGS(33, ENTITY),
ENTITY_LIVING(-1, ENTITY),
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
ENTITY_HUMAN(-1, ENTITY_LIVING),
ARMOR_STAND(30, ENTITY_LIVING),
EVOCATION_ILLAGER(34, ENTITY_INSENTIENT),
VEX(35, ENTITY_INSENTIENT),
VINDICATION_ILLAGER(36, ENTITY_INSENTIENT),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
MINECART_COMMAND(40, MINECART_ABSTRACT),
BOAT(41, ENTITY),
MINECART_RIDEABLE(42, MINECART_ABSTRACT),
MINECART_CHEST(43, MINECART_ABSTRACT),
MINECART_FURNACE(44, MINECART_ABSTRACT),
MINECART_TNT(45, MINECART_ABSTRACT),
MINECART_HOPPER(46, MINECART_ABSTRACT),
MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
CREEPER(50, ENTITY_INSENTIENT),
ABSTRACT_SKELETON(-1, ENTITY_INSENTIENT),
SKELETON(51, ABSTRACT_SKELETON),
WITHER_SKELETON(5, ABSTRACT_SKELETON),
STRAY(6, ABSTRACT_SKELETON),
SPIDER(52, ENTITY_INSENTIENT),
GIANT(53, ENTITY_INSENTIENT),
ZOMBIE(54, ENTITY_INSENTIENT),
HUSK(23, ZOMBIE),
ZOMBIE_VILLAGER(27, ZOMBIE),
SLIME(55, ENTITY_INSENTIENT),
GHAST(56, ENTITY_INSENTIENT),
PIG_ZOMBIE(57, ZOMBIE),
ENDERMAN(58, ENTITY_INSENTIENT),
CAVE_SPIDER(59, SPIDER),
SILVERFISH(60, ENTITY_INSENTIENT),
BLAZE(61, ENTITY_INSENTIENT),
MAGMA_CUBE(62, SLIME),
ENDER_DRAGON(63, ENTITY_INSENTIENT),
WITHER(64, ENTITY_INSENTIENT),
BAT(65, ENTITY_INSENTIENT),
WITCH(66, ENTITY_INSENTIENT),
ENDERMITE(67, ENTITY_INSENTIENT),
GUARDIAN(68, ENTITY_INSENTIENT),
ELDER_GUARDIAN(4, EntityType.GUARDIAN), // Moved down to avoid illegal forward reference
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
SHULKER(69, EntityType.IRON_GOLEM),
PIG(90, ENTITY_AGEABLE),
SHEEP(91, ENTITY_AGEABLE),
COW(92, ENTITY_AGEABLE),
CHICKEN(93, ENTITY_AGEABLE),
SQUID(94, ENTITY_INSENTIENT),
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
MUSHROOM_COW(96, COW),
SNOWMAN(97, EntityType.IRON_GOLEM),
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
ABSTRACT_HORSE(-1, ENTITY_AGEABLE),
HORSE(100, ABSTRACT_HORSE),
SKELETON_HORSE(28, ABSTRACT_HORSE),
ZOMBIE_HORSE(29, ABSTRACT_HORSE),
CHESTED_HORSE(-1, ABSTRACT_HORSE),
DONKEY(31, CHESTED_HORSE),
MULE(32, CHESTED_HORSE),
LIAMA(103, CHESTED_HORSE),
RABBIT(101, ENTITY_AGEABLE),
POLAR_BEAR(102, ENTITY_AGEABLE),
VILLAGER(120, ENTITY_AGEABLE),
ENDER_CRYSTAL(200, ENTITY),
SPLASH_POTION(-1, ENTITY),
LINGERING_POTION(-1, SPLASH_POTION),
AREA_EFFECT_CLOUD(-1, ENTITY),
EGG(-1, ENTITY),
FISHING_HOOK(-1, ENTITY),
LIGHTNING(-1, ENTITY),
WEATHER(-1, ENTITY),
PLAYER(-1, ENTITY_HUMAN),
COMPLEX_PART(-1, ENTITY),
LIAMA_SPIT(-1, ENTITY);
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
public static Optional<EntityType> findById(int id) {
if (id == -1) // Check if this is called
return Optional.empty();
for (EntityType ent : EntityType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.empty();
}
@Override
public boolean is(AbstractEntityType... types) {
for (AbstractEntityType type : types)
if (is(type))
return true;
return false;
}
@Override
public boolean is(AbstractEntityType type) {
return this == type;
}
@Override
public boolean isOrHasParent(AbstractEntityType type) {
EntityType parent = this;
do {
if (parent.equals(type))
return true;
parent = parent.getParent();
} while (parent != null);
return false;
}
@Override
public List<AbstractEntityType> getParents() {
List<AbstractEntityType> types = new ArrayList<>();
EntityType parent = this;
do {
types.add(parent);
parent = parent.getParent();
} while (parent != null);
return types;
}
}
@AllArgsConstructor
@Getter
public enum ObjectType implements AbstractObjectType {
BOAT(1, EntityType.BOAT),
ITEM(2, EntityType.DROPPED_ITEM),
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
MINECART(10, EntityType.MINECART_ABSTRACT),
TNT_PRIMED(50, EntityType.PRIMED_TNT),
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
TIPPED_ARROW(60, EntityType.ARROW),
SNOWBALL(61, EntityType.SNOWBALL),
EGG(62, EntityType.EGG),
FIREBALL(63, EntityType.FIREBALL),
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
LIAMA_SPIT(68, EntityType.LIAMA_SPIT),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
POTION(73, EntityType.SPLASH_POTION),
THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
FIREWORK(76, EntityType.FIREWORK),
LEASH(77, EntityType.LEASH_HITCH),
ARMOR_STAND(78, EntityType.ARMOR_STAND),
EVOCATION_FANGS(79, EntityType.EVOCATION_FANGS),
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private final int id;
private final EntityType type;
public static Optional<ObjectType> findById(int id) {
if (id == -1)
return Optional.empty();
for (ObjectType ent : ObjectType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.empty();
}
public static Optional<EntityType> getPCEntity(int id) {
Optional<ObjectType> output = findById(id);
if (!output.isPresent())
return Optional.empty();
return Optional.of(output.get().getType());
}
}
}
@@ -1,274 +0,0 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.entities.types;
import lombok.AllArgsConstructor;
import lombok.Getter;
import nl.matsv.viabackwards.ViaBackwards;
import us.myles.ViaVersion.api.Via;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class EntityType1_12 {
public static EntityType getTypeFromId(int typeID, boolean isObject) throws Exception {
Optional<EntityType> type;
if (isObject)
type = ObjectType.getPCEntity(typeID);
else
type = EntityType.findById(typeID);
if (!type.isPresent()) {
if (!Via.getConfig().isSuppressMetadataErrors())
ViaBackwards.getPlatform().getLogger().severe("[EntityType1_12] Could not find type id " + typeID + " isObject=" + isObject);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type.get();
}
@AllArgsConstructor
@Getter
public enum EntityType implements AbstractEntityType {
ENTITY(-1),
DROPPED_ITEM(1, ENTITY),
EXPERIENCE_ORB(2, ENTITY),
LEASH_HITCH(8, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
PAINTING(9, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
ARROW(10, ENTITY),
SNOWBALL(11, ENTITY), // Actually EntityProjectile
FIREBALL(12, ENTITY),
SMALL_FIREBALL(13, ENTITY),
ENDER_PEARL(14, ENTITY), // Actually EntityProjectile
ENDER_SIGNAL(15, ENTITY),
THROWN_EXP_BOTTLE(17, ENTITY),
ITEM_FRAME(18, ENTITY), // Actually EntityHanging
WITHER_SKULL(19, ENTITY),
PRIMED_TNT(20, ENTITY),
FALLING_BLOCK(21, ENTITY),
FIREWORK(22, ENTITY),
SPECTRAL_ARROW(24, ARROW),
SHULKER_BULLET(25, ENTITY),
DRAGON_FIREBALL(26, FIREBALL),
EVOCATION_FANGS(33, ENTITY),
ENTITY_LIVING(-1, ENTITY),
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
ENTITY_HUMAN(-1, ENTITY_LIVING),
ARMOR_STAND(30, ENTITY_LIVING),
ENTITY_ILLAGER_ABSTRACT(-1, ENTITY_INSENTIENT),
EVOCATION_ILLAGER(34, ENTITY_ILLAGER_ABSTRACT),
VEX(35, ENTITY_INSENTIENT),
VINDICATION_ILLAGER(36, ENTITY_ILLAGER_ABSTRACT),
ILLUSION_ILLAGER(37, EVOCATION_ILLAGER),
// Vehicles
MINECART_ABSTRACT(-1, ENTITY),
MINECART_COMMAND(40, MINECART_ABSTRACT),
BOAT(41, ENTITY),
MINECART_RIDEABLE(42, MINECART_ABSTRACT),
MINECART_CHEST(43, MINECART_ABSTRACT),
MINECART_FURNACE(44, MINECART_ABSTRACT),
MINECART_TNT(45, MINECART_ABSTRACT),
MINECART_HOPPER(46, MINECART_ABSTRACT),
MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
CREEPER(50, ENTITY_INSENTIENT),
ABSTRACT_SKELETON(-1, ENTITY_INSENTIENT),
SKELETON(51, ABSTRACT_SKELETON),
WITHER_SKELETON(5, ABSTRACT_SKELETON),
STRAY(6, ABSTRACT_SKELETON),
SPIDER(52, ENTITY_INSENTIENT),
GIANT(53, ENTITY_INSENTIENT),
ZOMBIE(54, ENTITY_INSENTIENT),
HUSK(23, ZOMBIE),
ZOMBIE_VILLAGER(27, ZOMBIE),
SLIME(55, ENTITY_INSENTIENT),
GHAST(56, ENTITY_INSENTIENT),
PIG_ZOMBIE(57, ZOMBIE),
ENDERMAN(58, ENTITY_INSENTIENT),
CAVE_SPIDER(59, SPIDER),
SILVERFISH(60, ENTITY_INSENTIENT),
BLAZE(61, ENTITY_INSENTIENT),
MAGMA_CUBE(62, SLIME),
ENDER_DRAGON(63, ENTITY_INSENTIENT),
WITHER(64, ENTITY_INSENTIENT),
BAT(65, ENTITY_INSENTIENT),
WITCH(66, ENTITY_INSENTIENT),
ENDERMITE(67, ENTITY_INSENTIENT),
GUARDIAN(68, ENTITY_INSENTIENT),
ELDER_GUARDIAN(4, EntityType.GUARDIAN), // Moved down to avoid illegal forward reference
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
SHULKER(69, EntityType.IRON_GOLEM),
PIG(90, ENTITY_AGEABLE),
SHEEP(91, ENTITY_AGEABLE),
COW(92, ENTITY_AGEABLE),
CHICKEN(93, ENTITY_AGEABLE),
SQUID(94, ENTITY_INSENTIENT),
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
MUSHROOM_COW(96, COW),
SNOWMAN(97, EntityType.IRON_GOLEM),
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
PARROT(105, ENTITY_TAMEABLE_ANIMAL),
ABSTRACT_HORSE(-1, ENTITY_AGEABLE),
HORSE(100, ABSTRACT_HORSE),
SKELETON_HORSE(28, ABSTRACT_HORSE),
ZOMBIE_HORSE(29, ABSTRACT_HORSE),
CHESTED_HORSE(-1, ABSTRACT_HORSE),
DONKEY(31, CHESTED_HORSE),
MULE(32, CHESTED_HORSE),
LIAMA(103, CHESTED_HORSE),
RABBIT(101, ENTITY_AGEABLE),
POLAR_BEAR(102, ENTITY_AGEABLE),
VILLAGER(120, ENTITY_AGEABLE),
ENDER_CRYSTAL(200, ENTITY),
SPLASH_POTION(-1, ENTITY),
LINGERING_POTION(-1, SPLASH_POTION),
AREA_EFFECT_CLOUD(-1, ENTITY),
EGG(-1, ENTITY),
FISHING_HOOK(-1, ENTITY),
LIGHTNING(-1, ENTITY),
WEATHER(-1, ENTITY),
PLAYER(-1, ENTITY_HUMAN),
COMPLEX_PART(-1, ENTITY),
LIAMA_SPIT(-1, ENTITY);
private final int id;
private final EntityType parent;
EntityType(int id) {
this.id = id;
this.parent = null;
}
public static Optional<EntityType> findById(int id) {
if (id == -1) // Check if this is called
return Optional.empty();
for (EntityType ent : EntityType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.empty();
}
@Override
public boolean is(AbstractEntityType... types) {
for (AbstractEntityType type : types)
if (is(type))
return true;
return false;
}
@Override
public boolean is(AbstractEntityType type) {
return this == type;
}
@Override
public boolean isOrHasParent(AbstractEntityType type) {
EntityType parent = this;
do {
if (parent.equals(type))
return true;
parent = parent.getParent();
} while (parent != null);
return false;
}
@Override
public List<AbstractEntityType> getParents() {
List<AbstractEntityType> types = new ArrayList<>();
EntityType parent = this;
do {
types.add(parent);
parent = parent.getParent();
} while (parent != null);
return types;
}
}
@AllArgsConstructor
@Getter
public enum ObjectType implements AbstractObjectType {
BOAT(1, EntityType.BOAT),
ITEM(2, EntityType.DROPPED_ITEM),
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
MINECART(10, EntityType.MINECART_ABSTRACT),
TNT_PRIMED(50, EntityType.PRIMED_TNT),
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
TIPPED_ARROW(60, EntityType.ARROW),
SNOWBALL(61, EntityType.SNOWBALL),
EGG(62, EntityType.EGG),
FIREBALL(63, EntityType.FIREBALL),
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
LIAMA_SPIT(68, EntityType.LIAMA_SPIT),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
POTION(73, EntityType.SPLASH_POTION),
THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
FIREWORK(76, EntityType.FIREWORK),
LEASH(77, EntityType.LEASH_HITCH),
ARMOR_STAND(78, EntityType.ARMOR_STAND),
EVOCATION_FANGS(79, EntityType.EVOCATION_FANGS),
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
private final int id;
private final EntityType type;
public static Optional<ObjectType> findById(int id) {
if (id == -1)
return Optional.empty();
for (ObjectType ent : ObjectType.values())
if (ent.getId() == id)
return Optional.of(ent);
return Optional.empty();
}
public static Optional<EntityType> getPCEntity(int id) {
Optional<ObjectType> output = findById(id);
if (!output.isPresent())
return Optional.empty();
return Optional.of(output.get().getType());
}
}
}
@@ -13,4 +13,14 @@ package nl.matsv.viabackwards.api.exceptions;
import java.io.IOException;
public class RemovedValueException extends IOException {
/**
* May be cached since it is never actually printed, only checked.
*/
public static final RemovedValueException EX = new RemovedValueException() {
@Override
public Throwable fillInStackTrace() {
return this;
}
};
}
@@ -1,226 +0,0 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.rewriters;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import net.md_5.bungee.api.ChatColor;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.blockitem.BlockItemSettings;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data.BlockColors;
import nl.matsv.viabackwards.utils.Block;
import nl.matsv.viabackwards.utils.ItemUtil;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.viaversion.libs.opennbt.conversion.builtin.CompoundTagConverter;
import us.myles.viaversion.libs.opennbt.tag.builtin.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class BlockItemRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private static final CompoundTagConverter converter = new CompoundTagConverter();
private final Map<Integer, BlockItemSettings> replacementData = new ConcurrentHashMap<>();
protected BlockItemSettings rewrite(int itemId) {
BlockItemSettings settings = new BlockItemSettings(itemId);
replacementData.put(itemId, settings);
return settings;
}
protected Item handleItemToClient(Item i) {
if (i == null)
return null;
if (!replacementData.containsKey((int) i.getId()))
return i;
BlockItemSettings data = replacementData.get((int) i.getId());
Item original = ItemUtil.copyItem(i);
if (data.hasRepItem()) {
i = ItemUtil.copyItem(data.getRepItem());
if (i.getTag() == null)
i.setTag(new CompoundTag(""));
// Backup data for toServer
i.getTag().put(createViaNBT(original));
// Keep original data
if (original.getTag() != null)
for (Tag ai : original.getTag())
i.getTag().put(ai);
// Handle colors
if (i.getTag().contains("display")) {
CompoundTag tag = i.getTag().get("display");
if (tag.contains("Name")) {
String value = (String) tag.get("Name").getValue();
tag.put(new StringTag("Name",
value.replaceAll("%viabackwards_color%", BlockColors.get((int) original.getData()))));
}
}
i.setAmount(original.getAmount());
// Keep original data when -1
if (i.getData() == -1)
i.setData(original.getData());
}
if (data.hasItemTagHandler()) {
if (!i.getTag().contains("ViaBackwards|" + getProtocolName()))
i.getTag().put(createViaNBT(original));
data.getItemHandler().handle(i);
}
return i;
}
protected Item handleItemToServer(Item item) {
if (item == null || item.getTag() == null)
return null;
CompoundTag tag = item.getTag();
if (tag.contains("ViaBackwards|" + getProtocolName())) {
CompoundTag via = tag.get("ViaBackwards|" + getProtocolName());
short id = (short) via.get("id").getValue();
short data = (short) via.get("data").getValue();
byte amount = (byte) via.get("amount").getValue();
CompoundTag extras = via.get("extras");
item.setId(id);
item.setData(data);
item.setAmount(amount);
item.setTag(converter.convert("", converter.convert(extras)));
// Remove data tag
tag.remove("ViaBackwards|" + getProtocolName());
}
return item;
}
public int handleBlockID(int idx) {
int type = idx >> 4;
int meta = idx & 15;
if (!containsBlock(type))
return idx;
Block b = handleBlock(type, meta);
return (b.getId() << 4 | (b.getData() & 15));
}
public Block handleBlock(int block, int data) {
if (!containsBlock(block))
return null;
Block b = replacementData.get(block).getRepBlock().clone();
// For some blocks, the data can still be useful (:
if (b.getData() == -1)
b.setData(data);
return b;
}
protected void handleChunk(Chunk chunk) {
// Map Block Entities
Map<Pos, CompoundTag> tags = new HashMap<>();
for (CompoundTag tag : chunk.getBlockEntities()) {
if (!(tag.contains("x") && tag.contains("y") && tag.contains("z")))
continue;
Pos pos = new Pos(
(int) tag.get("x").getValue() % 16,
(int) tag.get("y").getValue(),
(int) tag.get("z").getValue() % 16);
tags.put(pos, tag);
}
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null)
continue;
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
int block = section.getBlock(x, y, z);
int btype = block >> 4;
int meta = block & 15;
if (containsBlock(btype)) {
Block b = handleBlock(btype, meta); // Type / data
section.setBlock(x, y, z, b.getId(), b.getData());
}
// Entity Tags
if (hasBlockEntityHandler(btype)) {
Pos pos = new Pos(x, (y + (i << 4)), z);
CompoundTag tag = null;
if (tags.containsKey(pos)) {
tag = tags.get(pos);
} else {
tag = new CompoundTag("");
tag.put(new IntTag("x", x + (chunk.getX() << 4)));
tag.put(new IntTag("y", y + (i << 4)));
tag.put(new IntTag("z", z + (chunk.getZ() << 4)));
chunk.getBlockEntities().add(tag);
}
replacementData.get(btype).getBlockEntityHandler().handleOrNewCompoundTag(block, tag);
}
}
}
}
}
}
protected boolean containsBlock(int block) {
return replacementData.containsKey(block) && replacementData.get(block).hasRepBlock();
}
protected boolean hasBlockEntityHandler(int block) {
return replacementData.containsKey(block) && replacementData.get(block).hasEntityHandler();
}
protected boolean hasItemTagHandler(int block) {
return replacementData.containsKey(block) && replacementData.get(block).hasItemTagHandler();
}
private CompoundTag createViaNBT(Item i) {
CompoundTag tag = new CompoundTag("ViaBackwards|" + getProtocolName());
tag.put(new ShortTag("id", i.getId()));
tag.put(new ShortTag("data", i.getData()));
tag.put(new ByteTag("amount", i.getAmount()));
if (i.getTag() != null) {
tag.put(converter.convert("extras", converter.convert(i.getTag())));
} else
tag.put(new CompoundTag("extras"));
return tag;
}
protected CompoundTag getNamedTag(String text) {
CompoundTag tag = new CompoundTag("");
tag.put(new CompoundTag("display"));
((CompoundTag) tag.get("display")).put(new StringTag("Name", ChatColor.RESET + text));
return tag;
}
private String getProtocolName() {
return getProtocol().getClass().getSimpleName();
}
@Data
@AllArgsConstructor
@ToString
@EqualsAndHashCode
private class Pos {
private int x, y, z;
}
}
@@ -0,0 +1,168 @@
package nl.matsv.viabackwards.api.rewriters;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
import us.myles.viaversion.libs.opennbt.tag.builtin.ByteTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ShortTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EnchantmentRewriter {
private final Map<String, String> enchantmentMappings = new HashMap<>();
private final String nbtTagName;
private final boolean jsonFormat;
public EnchantmentRewriter(String nbtTagName, boolean jsonFormat) {
this.nbtTagName = nbtTagName;
this.jsonFormat = jsonFormat;
}
public EnchantmentRewriter(String nbtTagName) {
this(nbtTagName, true);
}
public void registerEnchantment(String key, String replacementLore) {
enchantmentMappings.put(key, replacementLore);
}
public void handleToClient(Item item) {
CompoundTag tag = item.getTag();
if (tag == null) return;
if (tag.get("Enchantments") instanceof ListTag) {
rewriteEnchantmentsToClient(tag, false);
}
if (tag.get("StoredEnchantments") instanceof ListTag) {
rewriteEnchantmentsToClient(tag, true);
}
}
public void handleToServer(Item item) {
CompoundTag tag = item.getTag();
if (tag == null) return;
if (tag.contains(nbtTagName + "|Enchantments")) {
rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(nbtTagName + "|StoredEnchantments")) {
rewriteEnchantmentsToServer(tag, true);
}
}
public void rewriteEnchantmentsToClient(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "Enchantments";
ListTag enchantments = tag.get(key);
ListTag remappedEnchantments = new ListTag(nbtTagName + "|" + key, CompoundTag.class);
List<Tag> lore = new ArrayList<>();
for (Tag enchantmentEntry : enchantments.clone()) {
String newId = (String) ((CompoundTag) enchantmentEntry).get("id").getValue();
String enchantmentName = enchantmentMappings.get(newId);
if (enchantmentName != null) {
enchantments.remove(enchantmentEntry);
Number level = (Number) ((CompoundTag) enchantmentEntry).get("lvl").getValue();
String loreValue = enchantmentName + " " + getRomanNumber(level.intValue());
if (jsonFormat) {
loreValue = ChatRewriter.legacyTextToJson(loreValue);
}
lore.add(new StringTag("", loreValue));
remappedEnchantments.add(enchantmentEntry);
}
}
if (!lore.isEmpty()) {
if (!storedEnchant && enchantments.size() == 0) {
CompoundTag dummyEnchantment = new CompoundTag("");
dummyEnchantment.put(new StringTag("id", ""));
dummyEnchantment.put(new ShortTag("lvl", (short) 0));
enchantments.add(dummyEnchantment);
tag.put(new ByteTag(nbtTagName + "|dummyEnchant"));
}
tag.put(remappedEnchantments);
CompoundTag display = tag.get("display");
if (display == null) {
tag.put(display = new CompoundTag("display"));
}
ListTag loreTag = display.get("Lore");
if (loreTag == null) {
display.put(loreTag = new ListTag("Lore", StringTag.class));
}
lore.addAll(loreTag.getValue());
loreTag.setValue(lore);
}
}
public void rewriteEnchantmentsToServer(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "Enchantments";
ListTag remappedEnchantments = tag.get(nbtTagName + "|" + key);
ListTag enchantments = tag.get(key);
if (enchantments == null) {
enchantments = new ListTag(key, CompoundTag.class);
}
if (!storedEnchant && tag.remove(nbtTagName + "|dummyEnchant") != null) {
for (Tag enchantment : enchantments.clone()) {
String id = (String) ((CompoundTag) enchantment).get("id").getValue();
if (id.isEmpty()) {
enchantments.remove(enchantment);
}
}
}
CompoundTag display = tag.get("display");
// A few null checks just to be safe, though they shouldn't actually be
ListTag lore = display != null ? display.get("Lore") : null;
for (Tag enchantment : remappedEnchantments.clone()) {
enchantments.add(enchantment);
if (lore != null && lore.size() != 0) {
lore.remove(lore.get(0));
}
}
if (lore != null && lore.size() == 0) {
display.remove("Lore");
if (display.isEmpty()) {
tag.remove("display");
}
}
tag.put(enchantments);
tag.remove(remappedEnchantments.getName());
}
public static String getRomanNumber(int number) {
switch (number) {
case 1:
return "I";
case 2:
return "II";
case 3:
return "III";
case 4:
return "IV";
case 5:
return "V";
case 6:
return "VI";
case 7:
return "VII";
case 8:
return "VIII";
case 9:
return "IX";
case 10:
return "X";
default:
return Integer.toString(number);
}
}
}
@@ -1,159 +1,114 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.rewriters;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.meta.MetaHandlerEvent;
import nl.matsv.viabackwards.api.entities.meta.MetaHandlerSettings;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import nl.matsv.viabackwards.api.entities.types.AbstractEntityType;
import nl.matsv.viabackwards.api.entities.types.AbstractObjectType;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_14;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.IdRewriteFunction;
import us.myles.ViaVersion.api.type.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
@RequiredArgsConstructor
public abstract class EntityRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private final Map<AbstractEntityType, EntityData> entityTypes = new ConcurrentHashMap<>();
private final Map<AbstractObjectType, EntityData> objectTypes = new ConcurrentHashMap<>();
private final List<MetaHandlerSettings> metaHandlers = new ArrayList<>();
public abstract class EntityRewriter<T extends BackwardsProtocol> extends EntityRewriterBase<T> {
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
private MetaType displayNameMetaType = MetaType1_9.String;
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
private int displayNameIndex = 2;
protected AbstractEntityType getEntityType(UserConnection connection, int id) {
return getEntityTracker(connection).getEntityType(id);
protected EntityRewriter(T protocol) {
super(protocol, MetaType1_14.OptChat, 2);
}
protected void addTrackedEntity(UserConnection connection, int entityId, AbstractEntityType type) {
getEntityTracker(connection).trackEntityType(entityId, type);
protected EntityRewriter(T protocol, MetaType displayType) {
super(protocol, displayType, 2);
}
protected Optional<EntityData> getEntityData(AbstractEntityType type) {
if (!entityTypes.containsKey(type))
return Optional.empty();
return Optional.of(entityTypes.get(type));
}
protected Optional<EntityData> getObjectData(AbstractObjectType type) {
if (!objectTypes.containsKey(type))
return Optional.empty();
return Optional.of(objectTypes.get(type));
}
protected EntityData regEntType(AbstractEntityType oldEnt, AbstractEntityType replacement) {
return regEntType(oldEnt, (short) replacement.getId());
}
private EntityData regEntType(AbstractEntityType oldEnt, short replacementId) {
EntityData data = new EntityData(oldEnt.getId(), false, replacementId, -1);
entityTypes.put(oldEnt, data);
return data;
}
protected EntityData regObjType(AbstractObjectType oldObj, AbstractObjectType replacement, int data) {
return regObjType(oldObj, (short) replacement.getId(), data);
}
private EntityData regObjType(AbstractObjectType oldObj, short replacementId, int data) {
EntityData entData = new EntityData(oldObj.getId(), true, replacementId, data);
objectTypes.put(oldObj, entData);
return entData;
}
public MetaHandlerSettings registerMetaHandler() {
MetaHandlerSettings settings = new MetaHandlerSettings();
metaHandlers.add(settings);
return settings;
}
protected MetaStorage handleMeta(UserConnection user, int entityId, MetaStorage storage) throws Exception {
Optional<EntityTracker.StoredEntity> optEntity = getEntityTracker(user).getEntity(entityId);
if (!optEntity.isPresent()) {
if (!Via.getConfig().isSuppressMetadataErrors())
ViaBackwards.getPlatform().getLogger().warning("Metadata for entity id: " + entityId + " not sent because the entity doesn't exist. " + storage);
throw new CancelException();
}
EntityTracker.StoredEntity entity = optEntity.get();
AbstractEntityType type = entity.getType();
List<Metadata> newList = new CopyOnWriteArrayList<>();
for (MetaHandlerSettings settings : metaHandlers) {
for (Metadata md : storage.getMetaDataList()) {
Metadata nmd = md;
try {
if (settings.isGucci(type, nmd))
nmd = settings.getHandler().handle(new MetaHandlerEvent(user, entity, nmd.getId(), nmd, storage));
if (nmd == null)
throw new RemovedValueException();
newList.add(nmd);
} catch (RemovedValueException ignored) {
} catch (Exception e) {
if (Via.getManager().isDebug()) {
Logger log = ViaBackwards.getPlatform().getLogger();
log.warning("Unable to handle metadata " + nmd);
log.warning("Full metadata list " + storage);
e.printStackTrace();
public void registerSpawnTrackerWithData(ClientboundPacketType packetType, EntityType fallingBlockType, IdRewriteFunction blockStateRewriter) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - Entity UUID
map(Type.VAR_INT); // 2 - Entity Type
map(Type.DOUBLE); // 3 - X
map(Type.DOUBLE); // 4 - Y
map(Type.DOUBLE); // 5 - Z
map(Type.BYTE); // 6 - Pitch
map(Type.BYTE); // 7 - Yaw
map(Type.INT); // 8 - Data
handler(wrapper -> {
EntityType entityType = setOldEntityId(wrapper);
if (entityType == fallingBlockType) {
int blockState = wrapper.get(Type.INT, 0);
wrapper.set(Type.INT, 0, blockStateRewriter.rewrite(blockState));
}
}
});
}
storage.setMetaDataList(new ArrayList<>(newList));
newList.clear();
}
// Handle Entity Name
Optional<Metadata> opMd = storage.get(getDisplayNameIndex());
if (opMd.isPresent()) {
Optional<EntityData> opEd = getEntityData(type);
if (opEd.isPresent()) {
Metadata data = opMd.get();
EntityData entData = opEd.get();
if (entData.getMobName() != null &&
(data.getValue() == null || ((String) data.getValue()).isEmpty()) &&
data.getMetaType().getTypeID() == getDisplayNameMetaType().getTypeID())
data.setValue(entData.getMobName());
}
}
return storage;
});
}
protected EntityTracker.ProtocolEntityTracker getEntityTracker(UserConnection user) {
return user.get(EntityTracker.class).get(getProtocol());
public void registerSpawnTracker(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Entity UUID
map(Type.VAR_INT); // 2 - Entity Type
handler(wrapper -> setOldEntityId(wrapper));
}
});
}
private EntityType setOldEntityId(PacketWrapper wrapper) throws Exception {
int typeId = wrapper.get(Type.VAR_INT, 1);
EntityType entityType = getTypeFromId(typeId);
addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), entityType);
int oldTypeId = getOldEntityId(entityType.getId());
if (typeId != oldTypeId) {
wrapper.set(Type.VAR_INT, 1, oldTypeId);
}
return entityType;
}
/**
* Helper method to handle a metadata list packet and its full initial meta rewrite.
*/
protected void registerMetadataRewriter(ClientboundPacketType packetType, Type<List<Metadata>> oldMetaType, Type<List<Metadata>> newMetaType) {
getProtocol().registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
if (oldMetaType != null) {
map(oldMetaType, newMetaType);
} else {
map(newMetaType);
}
handler(wrapper -> {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityType type = getEntityType(wrapper.user(), entityId);
MetaStorage storage = new MetaStorage(wrapper.get(newMetaType, 0));
handleMeta(wrapper.user(), entityId, storage);
EntityData entityData = getEntityData(type);
//TODO only do this once for a first meta packet?
if (entityData != null) {
if (entityData.hasBaseMeta()) {
entityData.getDefaultMeta().createMeta(storage);
}
}
wrapper.set(newMetaType, 0, storage.getMetaDataList());
});
}
});
}
protected void registerMetadataRewriter(ClientboundPacketType packetType, Type<List<Metadata>> metaType) {
registerMetadataRewriter(packetType, null, metaType);
}
}
@@ -0,0 +1,299 @@
package nl.matsv.viabackwards.api.rewriters;
import com.google.common.base.Preconditions;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.meta.MetaHandlerEvent;
import nl.matsv.viabackwards.api.entities.meta.MetaHandlerSettings;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.viaversion.libs.fastutil.ints.Int2IntMap;
import us.myles.viaversion.libs.fastutil.ints.Int2IntOpenHashMap;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* Entity rewriter base class.
*
* @see EntityRewriter
* @see LegacyEntityRewriter
*/
public abstract class EntityRewriterBase<T extends BackwardsProtocol> extends Rewriter<T> {
private final Map<EntityType, EntityData> entityTypes = new HashMap<>();
private final List<MetaHandlerSettings> metaHandlers = new ArrayList<>();
private final MetaType displayNameMetaType;
private final int displayNameIndex;
protected Int2IntMap typeMapping;
EntityRewriterBase(T protocol) {
this(protocol, MetaType1_9.String, 2);
}
EntityRewriterBase(T protocol, MetaType displayNameMetaType, int displayNameIndex) {
super(protocol);
this.displayNameMetaType = displayNameMetaType;
this.displayNameIndex = displayNameIndex;
}
protected EntityType getEntityType(UserConnection connection, int id) {
return getEntityTracker(connection).getEntityType(id);
}
protected void addTrackedEntity(PacketWrapper wrapper, int entityId, EntityType type) throws Exception {
getEntityTracker(wrapper.user()).trackEntityType(entityId, type);
}
protected boolean hasData(EntityType type) {
return entityTypes.containsKey(type);
}
@Nullable
protected EntityData getEntityData(EntityType type) {
return entityTypes.get(type);
}
/**
* Note that both types should be of the SAME version.
*
* @param oldType old type of the higher version
* @param replacement new type of the higher version
* @return created entity data
* @see #mapEntityDirect(EntityType, EntityType) for id only rewriting
*/
protected EntityData mapEntity(EntityType oldType, EntityType replacement) {
Preconditions.checkArgument(oldType.getClass() == replacement.getClass());
// Already rewrite the id here
int mappedReplacementId = getOldEntityId(replacement.getId());
EntityData data = new EntityData(oldType.getId(), mappedReplacementId);
mapEntityDirect(oldType.getId(), mappedReplacementId);
entityTypes.put(oldType, data);
return data;
}
/**
* Maps entity ids based on the enum constant's names.
*
* @param oldTypes entity types of the higher version
* @param newTypeClass entity types enum class of the lower version
* @param <T> new type class
*/
public <T extends Enum<T> & EntityType> void mapTypes(EntityType[] oldTypes, Class<T> newTypeClass) {
if (typeMapping == null) {
typeMapping = new Int2IntOpenHashMap(oldTypes.length, 1F);
typeMapping.defaultReturnValue(-1);
}
for (EntityType oldType : oldTypes) {
try {
T newType = Enum.valueOf(newTypeClass, oldType.name());
typeMapping.put(oldType.getId(), newType.getId());
} catch (IllegalArgumentException ignored) {
}
}
}
/**
* Directly maps the entity without any other rewriting.
*
* @param oldType type of the higher version
* @param newType type of the lower version
* @see #mapEntity(EntityType, EntityType) for mapping with data
*/
public void mapEntityDirect(EntityType oldType, EntityType newType) {
Preconditions.checkArgument(oldType.getClass() != newType.getClass());
mapEntityDirect(oldType.getId(), newType.getId());
}
private void mapEntityDirect(int oldType, int newType) {
if (typeMapping == null) {
typeMapping = new Int2IntOpenHashMap();
typeMapping.defaultReturnValue(-1);
}
typeMapping.put(oldType, newType);
}
public MetaHandlerSettings registerMetaHandler() {
MetaHandlerSettings settings = new MetaHandlerSettings();
metaHandlers.add(settings);
return settings;
}
protected MetaStorage handleMeta(UserConnection user, int entityId, MetaStorage storage) throws Exception {
EntityTracker.StoredEntity storedEntity = getEntityTracker(user).getEntity(entityId);
if (storedEntity == null) {
if (!Via.getConfig().isSuppressMetadataErrors()) {
ViaBackwards.getPlatform().getLogger().warning("Metadata for entity id: " + entityId + " not sent because the entity doesn't exist. " + storage);
}
throw CancelException.CACHED;
}
EntityType type = storedEntity.getType();
for (MetaHandlerSettings settings : metaHandlers) {
List<Metadata> newData = new ArrayList<>();
for (Metadata meta : storage.getMetaDataList()) {
MetaHandlerEvent event = null;
try {
Metadata modifiedMeta = meta;
if (settings.isGucci(type, meta)) {
event = new MetaHandlerEvent(user, storedEntity, meta.getId(), meta, storage);
modifiedMeta = settings.getHandler().handle(event);
if (event.getExtraData() != null) {
newData.addAll(event.getExtraData());
event.clearExtraData();
}
}
if (modifiedMeta == null) {
throw RemovedValueException.EX;
}
newData.add(modifiedMeta);
} catch (RemovedValueException e) {
// Add the additionally created data here in case of an interruption
if (event != null && event.getExtraData() != null) {
newData.addAll(event.getExtraData());
}
} catch (Exception e) {
Logger log = ViaBackwards.getPlatform().getLogger();
log.warning("Unable to handle metadata " + meta + " for entity type " + type);
log.warning(storage.getMetaDataList().stream().sorted(Comparator.comparingInt(Metadata::getId))
.map(Metadata::toString).collect(Collectors.joining("\n", "Full metadata list: ", "")));
e.printStackTrace();
}
}
storage.setMetaDataList(newData);
}
// Handle Entity Name
Metadata data = storage.get(displayNameIndex);
if (data != null) {
EntityData entityData = getEntityData(type);
if (entityData != null && entityData.getMobName() != null
&& (data.getValue() == null || ((String) data.getValue()).isEmpty())
&& data.getMetaType().getTypeID() == displayNameMetaType.getTypeID()) {
data.setValue(entityData.getMobName());
}
}
return storage;
}
public void registerRespawn(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT);
handler(wrapper -> {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
clientWorld.setEnvironment(wrapper.get(Type.INT, 0));
});
}
});
}
public void registerJoinGame(ClientboundPacketType packetType, EntityType playerType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(wrapper -> {
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
clientChunks.setEnvironment(wrapper.get(Type.INT, 1));
getEntityTracker(wrapper.user()).trackEntityType(wrapper.get(Type.INT, 0), playerType);
});
}
});
}
/**
* Helper method to handle player, painting, or xp orb trackers without meta changes.
*/
protected void registerExtraTracker(ClientboundPacketType packetType, EntityType entityType, Type intType) {
getProtocol().registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(intType); // 0 - Entity id
handler(wrapper -> addTrackedEntity(wrapper, (int) wrapper.get(intType, 0), entityType));
}
});
}
protected void registerExtraTracker(ClientboundPacketType packetType, EntityType entityType) {
registerExtraTracker(packetType, entityType, Type.VAR_INT);
}
protected void registerEntityDestroy(ClientboundPacketType packetType) {
getProtocol().registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY_PRIMITIVE); // 0 - Entity ids
handler(wrapper -> {
EntityTracker.ProtocolEntityTracker tracker = getEntityTracker(wrapper.user());
for (int entity : wrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0)) {
tracker.removeEntity(entity);
}
});
}
});
}
// ONLY TRACKS, DOESN'T REWRITE IDS
protected PacketHandler getTrackerHandler(Type intType, int typeIndex) {
return wrapper -> {
Number id = (Number) wrapper.get(intType, typeIndex);
addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), getTypeFromId(id.intValue()));
};
}
protected PacketHandler getTrackerHandler() {
return getTrackerHandler(Type.VAR_INT, 1);
}
protected PacketHandler getTrackerHandler(EntityType entityType, Type intType) {
return wrapper -> addTrackedEntity(wrapper, (int) wrapper.get(intType, 0), entityType);
}
protected PacketHandler getDimensionHandler(int index) {
return wrapper -> {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, index);
clientWorld.setEnvironment(dimensionId);
};
}
public EntityTracker.ProtocolEntityTracker getEntityTracker(UserConnection user) {
return user.get(EntityTracker.class).get(getProtocol());
}
protected abstract EntityType getTypeFromId(int typeId);
public int getOldEntityId(int newId) {
return typeMapping != null ? typeMapping.getOrDefault(newId, newId) : newId;
}
}
@@ -0,0 +1,103 @@
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.data.MappedItem;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.rewriters.IdRewriteFunction;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
public abstract class ItemRewriter<T extends BackwardsProtocol> extends ItemRewriterBase<T> {
private final MappedItemFunction mappedItemFunction;
private final TranslatableRewriter translatableRewriter;
protected ItemRewriter(T protocol, @Nullable TranslatableRewriter translatableRewriter,
@Nullable IdRewriteFunction oldRewriter, @Nullable IdRewriteFunction newRewriter, MappedItemFunction mappedItemFunction) {
super(protocol, oldRewriter, newRewriter, true);
this.translatableRewriter = translatableRewriter;
this.mappedItemFunction = mappedItemFunction;
}
protected ItemRewriter(T protocol, @Nullable TranslatableRewriter translatableRewriter, MappedItemFunction mappedItemFunction) {
super(protocol, true);
this.translatableRewriter = translatableRewriter;
this.mappedItemFunction = mappedItemFunction;
}
@Override
@Nullable
public Item handleItemToClient(Item item) {
if (item == null) return null;
CompoundTag tag = null;
boolean textChanged = false;
if (translatableRewriter != null
&& item.getTag() != null && (tag = item.getTag().get("display")) != null) {
// Handle name and lore components
StringTag name = tag.get("Name");
if (name != null) {
String newValue = translatableRewriter.processText(name.getValue());
if (name.getValue().equals(newValue)) {
textChanged = true;
}
name.setValue(newValue);
}
ListTag lore = tag.get("Lore");
if (lore != null) {
for (Tag loreEntry : lore) {
if (!(loreEntry instanceof StringTag)) continue;
StringTag stringTag = (StringTag) loreEntry;
String newValue = translatableRewriter.processText(stringTag.getValue());
if (stringTag.getValue().equals(newValue)) {
textChanged = true;
}
stringTag.setValue(newValue);
}
}
}
if (textChanged) {
// Backup data for toServer
item.getTag().put(createViaNBT(item));
}
MappedItem data = mappedItemFunction.get(item.getIdentifier());
if (data == null) {
// Just rewrite the id
return super.handleItemToClient(item);
}
// Backup data for toServer if not already done above
if (!textChanged) {
if (item.getTag() == null) {
item.setTag(new CompoundTag(""));
}
item.getTag().put(createViaNBT(item));
}
// Set remapped id
item.setIdentifier(data.getId());
// Set custom name - only done if there is no original one
if (tag == null) {
item.getTag().put(tag = new CompoundTag("display"));
}
if (!tag.contains("Name")) {
tag.put(new StringTag("Name", data.getJsonName()));
}
return item;
}
@FunctionalInterface
public interface MappedItemFunction {
@Nullable
MappedItem get(int id);
}
}
@@ -0,0 +1,94 @@
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.rewriters.IdRewriteFunction;
import us.myles.viaversion.libs.opennbt.conversion.builtin.CompoundTagConverter;
import us.myles.viaversion.libs.opennbt.tag.builtin.ByteTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ShortTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
public abstract class ItemRewriterBase<T extends BackwardsProtocol> extends Rewriter<T> {
protected static final CompoundTagConverter CONVERTER = new CompoundTagConverter();
protected final IdRewriteFunction toClientRewriter;
protected final IdRewriteFunction toServerRewriter;
protected final String nbtTagName;
protected final boolean jsonNameFormat;
protected ItemRewriterBase(T protocol, @Nullable IdRewriteFunction toClientRewriter, @Nullable IdRewriteFunction toServerRewriter, boolean jsonNameFormat) {
super(protocol);
this.toClientRewriter = toClientRewriter;
this.toServerRewriter = toServerRewriter;
this.jsonNameFormat = jsonNameFormat;
nbtTagName = "VB|" + protocol.getClass().getSimpleName();
}
protected ItemRewriterBase(T protocol, boolean jsonNameFormat) {
this(protocol, null, null, jsonNameFormat);
}
@Nullable
public Item handleItemToClient(Item item) {
if (item == null) return null;
if (toClientRewriter != null) {
item.setIdentifier(toClientRewriter.rewrite(item.getIdentifier()));
}
return item;
}
@Nullable
public Item handleItemToServer(Item item) {
if (item == null) return null;
CompoundTag tag = item.getTag();
if (tag == null) {
if (toServerRewriter != null) {
item.setIdentifier(toServerRewriter.rewrite(item.getIdentifier()));
}
return item;
}
CompoundTag viaTag = tag.remove(nbtTagName);
if (viaTag != null) {
short id = (short) viaTag.get("id").getValue();
item.setIdentifier(id);
Tag dataTag = viaTag.get("data");
short data = dataTag != null ? (short) dataTag.getValue() : 0;
item.setData(data);
Tag amountTag = viaTag.get("amount");
byte amount = amountTag != null ? (byte) amountTag.getValue() : 1;
item.setAmount(amount);
CompoundTag extras = viaTag.get("extras");
if (extras != null) {
item.setTag(CONVERTER.convert("", CONVERTER.convert(extras)));
}
} else {
// Rewrite id normally
if (toServerRewriter != null) {
item.setIdentifier(toServerRewriter.rewrite(item.getIdentifier()));
}
}
return item;
}
protected CompoundTag createViaNBT(Item item) {
CompoundTag tag = new CompoundTag(nbtTagName);
tag.put(new ShortTag("id", (short) item.getIdentifier()));
if (item.getAmount() != 1) {
tag.put(new ByteTag("amount", item.getAmount()));
}
if (item.getData() != 0) {
tag.put(new ShortTag("data", item.getData()));
}
if (item.getTag() != null) {
tag.put(CONVERTER.convert("extras", CONVERTER.convert(item.getTag())));
}
return tag;
}
}
@@ -0,0 +1,300 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.rewriters;
import net.md_5.bungee.api.ChatColor;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.data.MappedLegacyBlockItem;
import nl.matsv.viabackwards.api.data.VBMappingDataLoader;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data.BlockColors;
import nl.matsv.viabackwards.utils.Block;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.rewriters.IdRewriteFunction;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectMap;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.gson.JsonPrimitive;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.IntTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
import java.util.HashMap;
import java.util.Map;
public abstract class LegacyBlockItemRewriter<T extends BackwardsProtocol> extends ItemRewriterBase<T> {
private static final Map<String, Int2ObjectMap<MappedLegacyBlockItem>> LEGACY_MAPPINGS = new HashMap<>();
protected final Int2ObjectMap<MappedLegacyBlockItem> replacementData;
static {
JsonObject jsonObject = VBMappingDataLoader.loadFromDataDir("legacy-mappings.json");
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
Int2ObjectMap<MappedLegacyBlockItem> mappings = new Int2ObjectOpenHashMap<>(8);
LEGACY_MAPPINGS.put(entry.getKey(), mappings);
for (Map.Entry<String, JsonElement> dataEntry : entry.getValue().getAsJsonObject().entrySet()) {
JsonObject object = dataEntry.getValue().getAsJsonObject();
int id = object.getAsJsonPrimitive("id").getAsInt();
JsonPrimitive jsonData = object.getAsJsonPrimitive("data");
short data = jsonData != null ? jsonData.getAsShort() : 0;
String name = object.getAsJsonPrimitive("name").getAsString();
JsonPrimitive blockField = object.getAsJsonPrimitive("block");
boolean block = blockField != null && blockField.getAsBoolean();
if (dataEntry.getKey().indexOf('-') != -1) {
// Range of ids
String[] split = dataEntry.getKey().split("-", 2);
int from = Integer.parseInt(split[0]);
int to = Integer.parseInt(split[1]);
// Special block color handling
if (name.contains("%color%")) {
for (int i = from; i <= to; i++) {
mappings.put(i, new MappedLegacyBlockItem(id, data, name.replace("%color%", BlockColors.get(i - from)), block));
}
} else {
MappedLegacyBlockItem mappedBlockItem = new MappedLegacyBlockItem(id, data, name, block);
for (int i = from; i <= to; i++) {
mappings.put(i, mappedBlockItem);
}
}
} else {
mappings.put(Integer.parseInt(dataEntry.getKey()), new MappedLegacyBlockItem(id, data, name, block));
}
}
}
}
protected LegacyBlockItemRewriter(T protocol, @Nullable IdRewriteFunction oldRewriter, @Nullable IdRewriteFunction newRewriter) {
super(protocol, oldRewriter, newRewriter, false);
replacementData = LEGACY_MAPPINGS.get(protocol.getClass().getSimpleName().split("To")[1].replace("_", "."));
}
protected LegacyBlockItemRewriter(T protocol) {
this(protocol, null, null);
}
@Override
@Nullable
public Item handleItemToClient(Item item) {
if (item == null) return null;
MappedLegacyBlockItem data = replacementData.get(item.getIdentifier());
if (data == null) {
// Just rewrite the id
return super.handleItemToClient(item);
}
if (item.getTag() == null) {
item.setTag(new CompoundTag(""));
}
// Backup data for toServer
short originalData = item.getData();
item.getTag().put(createViaNBT(item));
item.setIdentifier(data.getId());
// Keep original data if mapped data is set to -1
if (data.getData() != -1) {
item.setData(data.getData());
}
// Set display name
if (data.getName() != null) {
CompoundTag tag = item.getTag().get("display");
if (tag == null) {
item.getTag().put(tag = new CompoundTag("display"));
}
StringTag nameTag = tag.get("Name");
if (nameTag == null) {
tag.put(nameTag = new StringTag("Name", data.getName()));
}
// Handle colors
String value = nameTag.getValue();
if (value.contains("%vb_color%")) {
tag.put(new StringTag("Name", value.replace("%vb_color%", BlockColors.get(originalData))));
}
}
return item;
}
public int handleBlockID(int idx) {
int type = idx >> 4;
int meta = idx & 15;
Block b = handleBlock(type, meta);
if (b == null) return idx;
return (b.getId() << 4 | (b.getData() & 15));
}
@Nullable
public Block handleBlock(int blockId, int data) {
MappedLegacyBlockItem settings = replacementData.get(blockId);
if (settings == null || !settings.isBlock()) return null;
Block block = settings.getBlock();
// For some blocks, the data can still be useful (:
if (block.getData() == -1) {
return block.withData(data);
}
return block;
}
protected void handleChunk(Chunk chunk) {
// Map Block Entities
Map<Pos, CompoundTag> tags = new HashMap<>();
for (CompoundTag tag : chunk.getBlockEntities()) {
Tag xTag;
Tag yTag;
Tag zTag;
if ((xTag = tag.get("x")) == null || (yTag = tag.get("y")) == null || (zTag = tag.get("z")) == null) {
continue;
}
Pos pos = new Pos(
(int) xTag.getValue() & 0xF,
(int) yTag.getValue(),
(int) zTag.getValue() & 0xF);
tags.put(pos, tag);
// Handle given Block Entities
ChunkSection section = chunk.getSections()[pos.getY() >> 4];
if (section == null) continue;
int block = section.getFlatBlock(pos.getX(), pos.getY() & 0xF, pos.getZ());
int btype = block >> 4;
MappedLegacyBlockItem settings = replacementData.get(btype);
if (settings != null && settings.hasBlockEntityHandler()) {
settings.getBlockEntityHandler().handleOrNewCompoundTag(block, tag);
}
}
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null) continue;
boolean hasBlockEntityHandler = false;
// Map blocks
for (int j = 0; j < section.getPaletteSize(); j++) {
int block = section.getPaletteEntry(j);
int btype = block >> 4;
int meta = block & 0xF;
Block b = handleBlock(btype, meta);
if (b != null) {
section.setPaletteEntry(j, (b.getId() << 4) | (b.getData() & 0xF));
}
// We already know that is has a handler
if (hasBlockEntityHandler) continue;
MappedLegacyBlockItem settings = replacementData.get(btype);
if (settings != null && settings.hasBlockEntityHandler()) {
hasBlockEntityHandler = true;
}
}
if (!hasBlockEntityHandler) continue;
// We need to handle a Block Entity :(
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
int block = section.getFlatBlock(x, y, z);
int btype = block >> 4;
int meta = block & 15;
MappedLegacyBlockItem settings = replacementData.get(btype);
if (settings == null || !settings.hasBlockEntityHandler()) continue;
Pos pos = new Pos(x, (y + (i << 4)), z);
// Already handled above
if (tags.containsKey(pos)) continue;
CompoundTag tag = new CompoundTag("");
tag.put(new IntTag("x", x + (chunk.getX() << 4)));
tag.put(new IntTag("y", y + (i << 4)));
tag.put(new IntTag("z", z + (chunk.getZ() << 4)));
settings.getBlockEntityHandler().handleOrNewCompoundTag(block, tag);
chunk.getBlockEntities().add(tag);
}
}
}
}
}
protected CompoundTag getNamedTag(String text) {
CompoundTag tag = new CompoundTag("");
tag.put(new CompoundTag("display"));
text = ChatColor.RESET + text;
((CompoundTag) tag.get("display")).put(new StringTag("Name", jsonNameFormat ? ChatRewriter.legacyTextToJson(text) : text));
return tag;
}
private static final class Pos {
private final int x;
private final short y;
private final int z;
private Pos(int x, int y, int z) {
this.x = x;
this.y = (short) y;
this.z = z;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pos pos = (Pos) o;
if (x != pos.x) return false;
if (y != pos.y) return false;
return z == pos.z;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
result = 31 * result + z;
return result;
}
@Override
public String toString() {
return "Pos{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
}
}
}
@@ -0,0 +1,127 @@
package nl.matsv.viabackwards.api.rewriters;
import us.myles.viaversion.libs.opennbt.tag.builtin.*;
import java.util.*;
public class LegacyEnchantmentRewriter {
private final Map<Short, String> enchantmentMappings = new HashMap<>();
private final String nbtTagName;
private Set<Short> hideLevelForEnchants;
public LegacyEnchantmentRewriter(String nbtTagName) {
this.nbtTagName = nbtTagName;
}
public void registerEnchantment(int id, String replacementLore) {
enchantmentMappings.put((short) id, replacementLore);
}
public void rewriteEnchantmentsToClient(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "ench";
ListTag enchantments = tag.get(key);
ListTag remappedEnchantments = new ListTag(nbtTagName + "|" + key, CompoundTag.class);
List<Tag> lore = new ArrayList<>();
for (Tag enchantmentEntry : enchantments.clone()) {
Short newId = (Short) ((CompoundTag) enchantmentEntry).get("id").getValue();
String enchantmentName = enchantmentMappings.get(newId);
if (enchantmentName != null) {
enchantments.remove(enchantmentEntry);
Number level = (Number) ((CompoundTag) enchantmentEntry).get("lvl").getValue();
if (hideLevelForEnchants != null && hideLevelForEnchants.contains(newId)) {
lore.add(new StringTag("", enchantmentName));
} else {
lore.add(new StringTag("", enchantmentName + " " + EnchantmentRewriter.getRomanNumber(level.shortValue())));
}
remappedEnchantments.add(enchantmentEntry);
}
}
if (!lore.isEmpty()) {
if (!storedEnchant && enchantments.size() == 0) {
CompoundTag dummyEnchantment = new CompoundTag("");
dummyEnchantment.put(new ShortTag("id", (short) 0));
dummyEnchantment.put(new ShortTag("lvl", (short) 0));
enchantments.add(dummyEnchantment);
tag.put(new ByteTag(nbtTagName + "|dummyEnchant"));
IntTag hideFlags = tag.get("HideFlags");
if (hideFlags == null) {
hideFlags = new IntTag("HideFlags");
} else {
tag.put(new IntTag(nbtTagName + "|oldHideFlags", hideFlags.getValue()));
}
int flags = hideFlags.getValue() | 1;
hideFlags.setValue(flags);
tag.put(hideFlags);
}
tag.put(remappedEnchantments);
CompoundTag display = tag.get("display");
if (display == null) {
tag.put(display = new CompoundTag("display"));
}
ListTag loreTag = display.get("Lore");
if (loreTag == null) {
display.put(loreTag = new ListTag("Lore", StringTag.class));
}
lore.addAll(loreTag.getValue());
loreTag.setValue(lore);
}
}
public void rewriteEnchantmentsToServer(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "ench";
ListTag remappedEnchantments = tag.get(nbtTagName + "|" + key);
ListTag enchantments = tag.get(key);
if (enchantments == null) {
enchantments = new ListTag(key, CompoundTag.class);
}
if (!storedEnchant && tag.remove(nbtTagName + "|dummyEnchant") != null) {
for (Tag enchantment : enchantments.clone()) {
Short id = (Short) ((CompoundTag) enchantment).get("id").getValue();
Short level = (Short) ((CompoundTag) enchantment).get("lvl").getValue();
if (id == 0 && level == 0) {
enchantments.remove(enchantment);
}
}
IntTag hideFlags = tag.remove(nbtTagName + "|oldHideFlags");
if (hideFlags != null) {
tag.put(new IntTag("HideFlags", hideFlags.getValue()));
} else {
tag.remove("HideFlags");
}
}
CompoundTag display = tag.get("display");
// A few null checks just to be safe, though they shouldn't actually be
ListTag lore = display != null ? display.get("Lore") : null;
for (Tag enchantment : remappedEnchantments.clone()) {
enchantments.add(enchantment);
if (lore != null && lore.size() != 0) {
lore.remove(lore.get(0));
}
}
if (lore != null && lore.size() == 0) {
display.remove("Lore");
if (display.isEmpty()) {
tag.remove("display");
}
}
tag.put(enchantments);
tag.remove(remappedEnchantments.getName());
}
public void setHideLevelForEnchants(int... enchants) {
this.hideLevelForEnchants = new HashSet<>();
for (int enchant : enchants) {
hideLevelForEnchants.add((short) enchant);
}
}
}
@@ -0,0 +1,124 @@
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.EntityObjectData;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.entities.ObjectType;
import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public abstract class LegacyEntityRewriter<T extends BackwardsProtocol> extends EntityRewriterBase<T> {
private final Map<ObjectType, EntityData> objectTypes = new HashMap<>();
protected LegacyEntityRewriter(T protocol) {
super(protocol);
}
protected LegacyEntityRewriter(T protocol, MetaType displayType) {
super(protocol, displayType, 2);
}
protected EntityObjectData mapObjectType(ObjectType oldObjectType, ObjectType replacement, int data) {
EntityObjectData entData = new EntityObjectData(oldObjectType.getId(), true, replacement.getId(), data);
objectTypes.put(oldObjectType, entData);
return entData;
}
@Nullable
protected EntityData getObjectData(ObjectType type) {
return objectTypes.get(type);
}
protected void registerMetadataRewriter(ClientboundPacketType packetType, Type<List<Metadata>> oldMetaType, Type<List<Metadata>> newMetaType) {
getProtocol().registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
if (oldMetaType != null) {
map(oldMetaType, newMetaType);
} else {
map(newMetaType);
}
handler(wrapper -> {
List<Metadata> metadata = wrapper.get(newMetaType, 0);
wrapper.set(newMetaType, 0,
handleMeta(wrapper.user(), wrapper.get(Type.VAR_INT, 0), new MetaStorage(metadata)).getMetaDataList());
});
}
});
}
protected void registerMetadataRewriter(ClientboundPacketType packetType, Type<List<Metadata>> metaType) {
registerMetadataRewriter(packetType, null, metaType);
}
protected PacketHandler getMobSpawnRewriter(Type<List<Metadata>> metaType) {
return wrapper -> {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityType type = getEntityType(wrapper.user(), entityId);
MetaStorage storage = new MetaStorage(wrapper.get(metaType, 0));
handleMeta(wrapper.user(), entityId, storage);
EntityData entityData = getEntityData(type);
if (entityData != null) {
wrapper.set(Type.VAR_INT, 1, entityData.getReplacementId());
if (entityData.hasBaseMeta()) {
entityData.getDefaultMeta().createMeta(storage);
}
}
// Rewrite Metadata
wrapper.set(metaType, 0, storage.getMetaDataList());
};
}
protected PacketHandler getObjectTrackerHandler() {
return wrapper -> addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), getObjectTypeFromId(wrapper.get(Type.BYTE, 0)));
}
protected PacketHandler getTrackerAndMetaHandler(Type<List<Metadata>> metaType, EntityType entityType) {
return wrapper -> {
addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), entityType);
List<Metadata> metaDataList = handleMeta(wrapper.user(), wrapper.get(Type.VAR_INT, 0),
new MetaStorage(wrapper.get(metaType, 0))).getMetaDataList();
wrapper.set(metaType, 0, metaDataList);
};
}
protected PacketHandler getObjectRewriter(Function<Byte, ObjectType> objectGetter) {
return wrapper -> {
ObjectType type = objectGetter.apply(wrapper.get(Type.BYTE, 0));
if (type == null) {
ViaBackwards.getPlatform().getLogger().warning("Could not find Entity Type" + wrapper.get(Type.BYTE, 0));
return;
}
EntityData data = getObjectData(type);
if (data != null) {
wrapper.set(Type.BYTE, 0, (byte) data.getReplacementId());
if (data.getObjectData() != -1) {
wrapper.set(Type.INT, 0, data.getObjectData());
}
}
};
}
protected EntityType getObjectTypeFromId(int typeId) {
return getTypeFromId(typeId);
}
}
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectMap;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
public abstract class LegacySoundRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
protected final Int2ObjectMap<SoundData> soundRewrites = new Int2ObjectOpenHashMap<>(64);
protected LegacySoundRewriter(T protocol) {
super(protocol);
}
public SoundData added(int id, int replacement) {
return added(id, replacement, -1);
}
public SoundData added(int id, int replacement, float newPitch) {
SoundData data = new SoundData(replacement, true, newPitch, true);
soundRewrites.put(id, data);
return data;
}
public SoundData removed(int id) {
SoundData data = new SoundData(-1, false, -1, false);
soundRewrites.put(id, data);
return data;
}
public int handleSounds(int soundId) {
int newSoundId = soundId;
SoundData data = soundRewrites.get(soundId);
if (data != null) return data.getReplacementSound();
for (Int2ObjectMap.Entry<SoundData> entry : soundRewrites.int2ObjectEntrySet()) {
if (soundId > entry.getIntKey()) {
if (entry.getValue().isAdded()) {
newSoundId--;
} else {
newSoundId++;
}
}
}
return newSoundId;
}
public boolean hasPitch(int soundId) {
SoundData data = soundRewrites.get(soundId);
return data != null && data.isChangePitch();
}
public float handlePitch(int soundId) {
SoundData data = soundRewrites.get(soundId);
return data != null ? data.getNewPitch() : 1F;
}
public static final class SoundData {
private final int replacementSound;
private final boolean changePitch;
private final float newPitch;
private final boolean added;
public SoundData(int replacementSound, boolean changePitch, float newPitch, boolean added) {
this.replacementSound = replacementSound;
this.changePitch = changePitch;
this.newPitch = newPitch;
this.added = added;
}
public int getReplacementSound() {
return replacementSound;
}
public boolean isChangePitch() {
return changePitch;
}
public float getNewPitch() {
return newPitch;
}
public boolean isAdded() {
return added;
}
}
}
@@ -0,0 +1,33 @@
package nl.matsv.viabackwards.api.rewriters;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
public abstract class RecipeRewriter {
protected final ItemRewriterBase rewriter;
protected RecipeRewriter(ItemRewriterBase rewriter) {
this.rewriter = rewriter;
}
public abstract void handle(PacketWrapper wrapper, String type) throws Exception;
public void registerDefaultHandler(ClientboundPacketType packetType) {
rewriter.getProtocol().registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
String type = wrapper.passthrough(Type.STRING).replace("minecraft:", "");
String id = wrapper.passthrough(Type.STRING); // Recipe Identifier
handle(wrapper, type);
}
});
}
});
}
}
@@ -10,33 +10,35 @@
package nl.matsv.viabackwards.api.rewriters;
import lombok.Getter;
import nl.matsv.viabackwards.api.BackwardsProtocol;
public abstract class Rewriter<T extends BackwardsProtocol> {
@Getter
private T protocol;
protected final T protocol;
protected Rewriter(final T protocol) {
this.protocol = protocol;
}
/**
* Register everything
*
* @param protocol Protocol instance
* Register everything.
*/
public void register(T protocol) {
this.protocol = protocol;
registerPackets(protocol);
public void register() {
registerPackets();
registerRewrites();
}
/**
* Register packet listeners
*
* @param protocol Protocol instance
* Register packet listeners.
*/
protected abstract void registerPackets(T protocol);
protected abstract void registerPackets();
/**
* Register rewrites
* Register rewrites.
*/
protected abstract void registerRewrites();
protected void registerRewrites() {
}
public T getProtocol() {
return protocol;
}
}
@@ -1,75 +1,73 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.api.rewriters;
import lombok.AllArgsConstructor;
import lombok.Data;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.IdRewriteFunction;
import us.myles.ViaVersion.api.type.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
public abstract class SoundRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private Map<Integer, SoundData> soundRewrites = new ConcurrentHashMap<>();
public class SoundRewriter extends us.myles.ViaVersion.api.rewriters.SoundRewriter {
public SoundData added(int id, int replacement) {
return added(id, replacement, -1);
private final Function<String, String> stringIdRewriter;
public SoundRewriter(BackwardsProtocol protocol, IdRewriteFunction idRewriter, Function<String, String> stringIdRewriter) {
super(protocol, idRewriter);
this.stringIdRewriter = stringIdRewriter;
}
public SoundData added(int id, int replacement, float newPitch) {
SoundData data = new SoundData(replacement, true, newPitch, true);
soundRewrites.put(id, data);
return data;
public SoundRewriter(BackwardsProtocol protocol, IdRewriteFunction idRewriter) {
this(protocol, idRewriter, null);
}
public SoundData removed(int id) {
SoundData data = new SoundData(-1, false, -1, false);
soundRewrites.put(id, data);
return data;
}
public int handleSounds(int soundId) {
int newSoundId = soundId;
if (soundRewrites.containsKey(soundId))
return soundRewrites.get(soundId).getReplacementSound();
for (Map.Entry<Integer, SoundData> entry : soundRewrites.entrySet()) {
if (soundId > entry.getKey()) {
if (entry.getValue().isAdded()) {
newSoundId--;
} else {
newSoundId++;
}
public void registerNamedSound(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Sound identifier
handler(wrapper -> {
String soundId = wrapper.get(Type.STRING, 0);
String mappedId = stringIdRewriter.apply(soundId);
if (mappedId == null) return;
if (!mappedId.isEmpty()) {
wrapper.set(Type.STRING, 0, mappedId);
} else {
wrapper.cancel();
}
});
}
}
return newSoundId;
});
}
public boolean hasPitch(int soundId) {
if (soundRewrites.containsKey(soundId))
return soundRewrites.get(soundId).isChangePitch();
return false;
}
public void registerStopSound(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
byte flags = wrapper.passthrough(Type.BYTE);
if ((flags & 0x02) == 0) return; // No sound specified
public float handlePitch(int soundId) {
if (soundRewrites.containsKey(soundId))
return soundRewrites.get(soundId).getNewPitch();
return 1f;
}
if ((flags & 0x01) != 0) {
wrapper.passthrough(Type.VAR_INT); // Source
}
@Data
@AllArgsConstructor
public class SoundData {
private int replacementSound;
private boolean changePitch = false;
private float newPitch = 1f;
private boolean added;
String soundId = wrapper.read(Type.STRING);
String mappedId = stringIdRewriter.apply(soundId);
if (mappedId == null) {
// No mapping found
wrapper.write(Type.STRING, soundId);
return;
}
if (!mappedId.isEmpty()) {
wrapper.write(Type.STRING, mappedId);
} else {
// Cancel if set to empty
wrapper.cancel();
}
});
}
});
}
}
@@ -0,0 +1,228 @@
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.data.VBMappingDataLoader;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.gson.JsonPrimitive;
import java.util.HashMap;
import java.util.Map;
public class TranslatableRewriter {
private static final Map<String, Map<String, String>> TRANSLATABLES = new HashMap<>();
protected final BackwardsProtocol protocol;
protected final Map<String, String> newTranslatables;
public static void loadTranslatables() {
JsonObject jsonObject = VBMappingDataLoader.loadData("translation-mappings.json");
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
Map<String, String> versionMappings = new HashMap<>();
TRANSLATABLES.put(entry.getKey(), versionMappings);
for (Map.Entry<String, JsonElement> translationEntry : entry.getValue().getAsJsonObject().entrySet()) {
versionMappings.put(translationEntry.getKey(), translationEntry.getValue().getAsString());
}
}
}
public TranslatableRewriter(BackwardsProtocol protocol) {
this(protocol, protocol.getClass().getSimpleName().split("To")[1].replace("_", "."));
}
public TranslatableRewriter(BackwardsProtocol protocol, String sectionIdentifier) {
this.protocol = protocol;
final Map<String, String> newTranslatables = TRANSLATABLES.get(sectionIdentifier);
if (newTranslatables == null) {
ViaBackwards.getPlatform().getLogger().warning("Error loading " + sectionIdentifier + " translatables!");
this.newTranslatables = new HashMap<>();
} else
this.newTranslatables = newTranslatables;
}
public void registerPing() {
protocol.registerOutgoing(State.LOGIN, 0x00, 0x00, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING))));
}
});
}
public void registerDisconnect(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING))));
}
});
}
public void registerChatMessage(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING))));
}
});
}
public void registerBossBar(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UUID);
map(Type.VAR_INT);
handler(wrapper -> {
int action = wrapper.get(Type.VAR_INT, 0);
if (action == 0 || action == 3) {
wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING)));
}
});
}
});
}
public void registerLegacyOpenWindow(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Id
map(Type.STRING); // Window Type
handler(wrapper -> wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING))));
}
});
}
public void registerOpenWindow(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Id
map(Type.VAR_INT); // Window Type
handler(wrapper -> wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING))));
}
});
}
public void registerCombatEvent(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
if (wrapper.passthrough(Type.VAR_INT) == 2) {
wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.INT);
wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING)));
}
});
}
});
}
public void registerTitle(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int action = wrapper.passthrough(Type.VAR_INT);
if (action >= 0 && action <= 2) {
wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING)));
}
});
}
});
}
public void registerTabList(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING)));
wrapper.write(Type.STRING, processText(wrapper.read(Type.STRING)));
});
}
});
}
public String processText(String value) {
JsonElement root = GsonUtil.getJsonParser().parse(value);
processText(root);
return root.toString();
}
protected void processText(JsonElement element) {
if (element == null || element.isJsonNull()) return;
if (element.isJsonArray()) {
processAsArray(element);
return;
}
if (element.isJsonPrimitive()) {
handleText(element.getAsJsonPrimitive());
return;
}
JsonObject object = element.getAsJsonObject();
JsonPrimitive text = object.getAsJsonPrimitive("text");
if (text != null) {
handleText(text);
}
JsonElement translate = object.get("translate");
if (translate != null) {
handleTranslate(object, translate.getAsString());
JsonElement with = object.get("with");
if (with != null) {
processAsArray(with);
}
}
JsonElement extra = object.get("extra");
if (extra != null) {
processAsArray(extra);
}
JsonObject hoverEvent = object.getAsJsonObject("hoverEvent");
if (hoverEvent != null) {
handleHoverEvent(hoverEvent);
}
}
protected void handleText(JsonPrimitive text) {
// In case this is needed in the future
}
protected void handleTranslate(JsonObject root, String translate) {
String newTranslate = newTranslatables.get(translate);
if (newTranslate != null) {
root.addProperty("translate", newTranslate);
}
}
protected void handleHoverEvent(JsonObject hoverEvent) {
String action = hoverEvent.getAsJsonPrimitive("action").getAsString();
if (action.equals("show_text")) {
JsonElement value = hoverEvent.get("value");
processText(value != null ? value : hoverEvent.get("contents"));
} else if (action.equals("show_entity")) {
JsonObject contents = hoverEvent.getAsJsonObject("contents");
if (contents != null) {
processText(contents.get("name"));
}
}
}
private void processAsArray(JsonElement element) {
for (JsonElement jsonElement : element.getAsJsonArray()) {
processText(jsonElement);
}
}
}
@@ -1,144 +0,0 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_10to1_11;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
/*
Copied from ViaVersion //TODO implement in EntityTypes?
*/
public class EntityTypeNames {
private static BiMap<String, String> newToOldNames = HashBiMap.create();
static {
add("AreaEffectCloud", "minecraft:area_effect_cloud");
add("ArmorStand", "minecraft:armor_stand");
add("Arrow", "minecraft:arrow");
add("Bat", "minecraft:bat");
add("Blaze", "minecraft:blaze");
add("Boat", "minecraft:boat");
add("CaveSpider", "minecraft:cave_spider");
add("Chicken", "minecraft:chicken");
add("Cow", "minecraft:cow");
add("Creeper", "minecraft:creeper");
add("Donkey", "minecraft:donkey");
add("DragonFireball", "minecraft:dragon_fireball");
add("ElderGuardian", "minecraft:elder_guardian");
add("EnderCrystal", "minecraft:ender_crystal");
add("EnderDragon", "minecraft:ender_dragon");
add("Enderman", "minecraft:enderman");
add("Endermite", "minecraft:endermite");
add("EntityHorse", "minecraft:horse");
add("EyeOfEnderSignal", "minecraft:eye_of_ender_signal");
add("FallingSand", "minecraft:falling_block");
add("Fireball", "minecraft:fireball");
add("FireworksRocketEntity", "minecraft:fireworks_rocket");
add("Ghast", "minecraft:ghast");
add("Giant", "minecraft:giant");
add("Guardian", "minecraft:guardian");
add("Husk", "minecraft:husk");
add("Item", "minecraft:item");
add("ItemFrame", "minecraft:item_frame");
add("LavaSlime", "minecraft:magma_cube");
add("LeashKnot", "minecraft:leash_knot");
add("MinecartChest", "minecraft:chest_minecart");
add("MinecartCommandBlock", "minecraft:commandblock_minecart");
add("MinecartFurnace", "minecraft:furnace_minecart");
add("MinecartHopper", "minecraft:hopper_minecart");
add("MinecartRideable", "minecraft:minecart");
add("MinecartSpawner", "minecraft:spawner_minecart");
add("MinecartTNT", "minecraft:tnt_minecart");
add("Mule", "minecraft:mule");
add("MushroomCow", "minecraft:mooshroom");
add("Ozelot", "minecraft:ocelot");
add("Painting", "minecraft:painting");
add("Pig", "minecraft:pig");
add("PigZombie", "minecraft:zombie_pigman");
add("PolarBear", "minecraft:polar_bear");
add("PrimedTnt", "minecraft:tnt");
add("Rabbit", "minecraft:rabbit");
add("Sheep", "minecraft:sheep");
add("Shulker", "minecraft:shulker");
add("ShulkerBullet", "minecraft:shulker_bullet");
add("Silverfish", "minecraft:silverfish");
add("Skeleton", "minecraft:skeleton");
add("SkeletonHorse", "minecraft:skeleton_horse");
add("Slime", "minecraft:slime");
add("SmallFireball", "minecraft:small_fireball");
add("Snowball", "minecraft:snowball");
add("SnowMan", "minecraft:snowman");
add("SpectralArrow", "minecraft:spectral_arrow");
add("Spider", "minecraft:spider");
add("Squid", "minecraft:squid");
add("Stray", "minecraft:stray");
add("ThrownEgg", "minecraft:egg");
add("ThrownEnderpearl", "minecraft:ender_pearl");
add("ThrownExpBottle", "minecraft:xp_bottle");
add("ThrownPotion", "minecraft:potion");
add("Villager", "minecraft:villager");
add("VillagerGolem", "minecraft:villager_golem");
add("Witch", "minecraft:witch");
add("WitherBoss", "minecraft:wither");
add("WitherSkeleton", "minecraft:wither_skeleton");
add("WitherSkull", "minecraft:wither_skull");
add("Wolf", "minecraft:wolf");
add("XPOrb", "minecraft:xp_orb");
add("Zombie", "minecraft:zombie");
add("ZombieHorse", "minecraft:zombie_horse");
add("ZombieVillager", "minecraft:zombie_villager");
}
// Other way around (-:
private static void add(String oldName, String newName) {
newToOldNames.put(newName, oldName);
}
public static void toClient(CompoundTag tag) {
if (tag.get("id") instanceof StringTag) {
StringTag id = tag.get("id");
if (newToOldNames.containsKey(id.getValue())) {
id.setValue(newToOldNames.get(id.getValue()));
}
}
}
public static void toClientSpawner(CompoundTag tag) {
if (tag != null && tag.contains("SpawnData")) {
CompoundTag spawnData = tag.get("SpawnData");
if (spawnData != null && spawnData.contains("id"))
toClient(spawnData);
}
}
public static void toClientItem(Item item) {
if (hasEntityTag(item)) {
CompoundTag entityTag = item.getTag().get("EntityTag");
toClient(entityTag);
}
}
private static boolean hasEntityTag(Item item) {
if (item != null && item.getId() == 383) { // Monster Egg
CompoundTag tag = item.getTag();
if (tag != null && tag.contains("EntityTag") && tag.get("EntityTag") instanceof CompoundTag) {
if (((CompoundTag) tag.get("EntityTag")).get("id") instanceof StringTag) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,31 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11;
import us.myles.viaversion.libs.fastutil.ints.Int2IntMap;
import us.myles.viaversion.libs.fastutil.ints.Int2IntOpenHashMap;
public class PotionSplashHandler {
private static final Int2IntMap DATA = new Int2IntOpenHashMap(14, 1F);
static {
DATA.defaultReturnValue(-1);
DATA.put(2039713, 5); // night vision
DATA.put(8356754, 7); // invisibility
DATA.put(2293580, 9); // jump boost
DATA.put(14981690, 12); // fire resistance
DATA.put(8171462, 14); // swiftness
DATA.put(5926017, 17); // slowness
DATA.put(3035801, 19); // water breathing
DATA.put(16262179, 21); // instant health
DATA.put(4393481, 23); // instant damage
DATA.put(5149489, 25); // poison
DATA.put(13458603, 28); // regeneration
DATA.put(9643043, 31); // strength
DATA.put(4738376, 34); // weakness
DATA.put(3381504, 36); // luck
}
public static int getOldData(int data) {
return DATA.get(data);
}
}
@@ -10,7 +10,6 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11;
import lombok.Getter;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.BlockItemPackets1_11;
@@ -19,36 +18,52 @@ import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.PlayerPackets1_
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.SoundPackets1_11;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage.WindowTracker;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_10To1_11 extends BackwardsProtocol {
@Getter
public class Protocol1_10To1_11 extends BackwardsProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
private EntityPackets1_11 entityPackets; // Required for the item rewriter
@Getter
private BlockItemPackets1_11 blockItemPackets;
public Protocol1_10To1_11() {
super(ClientboundPackets1_9_3.class, ClientboundPackets1_9_3.class, ServerboundPackets1_9_3.class, ServerboundPackets1_9_3.class);
}
@Override
protected void registerPackets() {
(entityPackets = new EntityPackets1_11()).register(this);
(entityPackets = new EntityPackets1_11(this)).register();
new PlayerPackets1_11().register(this);
(blockItemPackets = new BlockItemPackets1_11()).register(this);
new SoundPackets1_11().register(this);
(blockItemPackets = new BlockItemPackets1_11(this)).register();
new SoundPackets1_11(this).register();
}
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class))
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
}
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class))
if (!user.has(EntityTracker.class)) {
user.put(new EntityTracker(user));
}
if (!user.has(WindowTracker.class))
if (!user.has(WindowTracker.class)) {
user.put(new WindowTracker(user));
}
// Init protocol in EntityTracker
user.get(EntityTracker.class).initProtocol(this);
}
public EntityPackets1_11 getEntityPackets() {
return entityPackets;
}
public BlockItemPackets1_11 getBlockItemPackets() {
return blockItemPackets;
}
}
@@ -11,52 +11,57 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets;
import net.md_5.bungee.api.ChatColor;
import nl.matsv.viabackwards.api.data.MappedLegacyBlockItem;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.api.entities.types.EntityType1_11;
import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.EntityTypeNames;
import nl.matsv.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import nl.matsv.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage.ChestedHorseStorage;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage.WindowTracker;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data.BlockColors;
import nl.matsv.viabackwards.utils.Block;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_11Types;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks.Chunk1_9_3_4;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.EntityIdRewriter;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
import java.util.Arrays;
import java.util.Optional;
public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11> {
@Override
protected void registerPackets(Protocol1_10To1_11 protocol) {
/* Item packets */
public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<Protocol1_10To1_11> {
// Set slot packet
protocol.registerOutgoing(State.PLAY, 0x16, 0x16, new PacketRemapper() {
private LegacyEnchantmentRewriter enchantmentRewriter;
public BlockItemPackets1_11(Protocol1_10To1_11 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
ItemRewriter itemRewriter = new ItemRewriter(protocol, this::handleItemToClient, this::handleItemToServer);
protocol.registerOutgoing(ClientboundPackets1_9_3.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM); // 2 - Slot Value
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0);
wrapper.set(Type.ITEM, 0, handleItemToClient(stack));
}
});
handler(itemRewriter.itemToClientHandler(Type.ITEM));
// Handle Llama
handler(new PacketHandler() {
@@ -76,8 +81,7 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
}
});
// Window items packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x14, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.WINDOW_ITEMS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
@@ -108,26 +112,10 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
}
});
// Entity Equipment Packet
protocol.registerOutgoing(State.PLAY, 0x3C, 0x3C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.VAR_INT); // 1 - Slot ID
map(Type.ITEM); // 2 - Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0);
wrapper.set(Type.ITEM, 0, handleItemToClient(stack));
}
});
}
});
itemRewriter.registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT, Type.ITEM);
// Plugin message Packet -> Trading
protocol.registerOutgoing(State.PLAY, 0x18, 0x18, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Channel
@@ -138,14 +126,15 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.BYTE);
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem)
if (secondItem) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
@@ -157,139 +146,102 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
}
});
// Click window packet
protocol.registerIncoming(State.PLAY, 0x07, 0x07, new PacketRemapper() {
protocol.registerIncoming(ServerboundPackets1_9_3.CLICK_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
handler(itemRewriter.itemToServerHandler(Type.ITEM));
// Llama slot
handler(new PacketHandler() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
public void handle(PacketWrapper wrapper) throws Exception {
if (isLlama(wrapper.user())) {
Optional<ChestedHorseStorage> horse = getChestedHorse(wrapper.user());
if (!horse.isPresent())
return;
ChestedHorseStorage storage = horse.get();
int clickSlot = wrapper.get(Type.SHORT, 0);
int correctSlot = getOldSlotId(storage, clickSlot);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
}
});
// Llama slot
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (isLlama(wrapper.user())) {
Optional<ChestedHorseStorage> horse = getChestedHorse(wrapper.user());
if (!horse.isPresent())
return;
ChestedHorseStorage storage = horse.get();
int clickSlot = wrapper.get(Type.SHORT, 0);
int correctSlot = getOldSlotId(storage, clickSlot);
wrapper.set(Type.SHORT, 0, ((Integer) correctSlot).shortValue());
}
}
});
wrapper.set(Type.SHORT, 0, ((Integer) correctSlot).shortValue());
}
}
}
);
});
}
});
// Creative Inventory Action
protocol.registerIncoming(State.PLAY, 0x18, 0x18, new PacketRemapper() {
itemRewriter.registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION, Type.ITEM);
protocol.registerOutgoing(ClientboundPackets1_9_3.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void registerMap() {
map(Type.SHORT); // 0 - Slot
map(Type.ITEM); // 1 - Clicked Item
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); // Use the 1.10 Chunk type since nothing changed.
Chunk chunk = wrapper.passthrough(type);
handleChunk(chunk);
// only patch it for signs for now
for (CompoundTag tag : chunk.getBlockEntities()) {
Tag idTag = tag.get("id");
if (!(idTag instanceof StringTag)) continue;
String id = (String) idTag.getValue();
if (id.equals("minecraft:sign")) {
((StringTag) idTag).setValue("Sign");
}
});
}
}
}
);
});
}
});
/* Block packets */
protocol.registerOutgoing(ClientboundPackets1_9_3.BLOCK_CHANGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
// Chunk packet
protocol.registerOutgoing(State.PLAY, 0x20, 0x20, new PacketRemapper() {
handler(new PacketHandler() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); // Use the 1.10 Chunk type since nothing changed.
Chunk1_9_3_4 chunk = (Chunk1_9_3_4) wrapper.passthrough(type);
handleChunk(chunk);
// only patch it for signs for now, TODO-> Find all the block entities old/new to replace ids and implement in ViaVersion
chunk.getBlockEntities().stream()
.filter(tag -> tag.contains("id") && tag.get("id") instanceof StringTag)
.forEach(tag -> {
String id = (String) tag.get("id").getValue();
if (id.equals("minecraft:sign")) {
((StringTag) tag.get("id")).setValue("Sign");
}
});
}
});
public void handle(PacketWrapper wrapper) throws Exception {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockID(idx));
}
}
);
});
}
});
// Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x0B, 0x0B, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.MULTI_BLOCK_CHANGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(new PacketHandler() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockID(idx));
}
});
public void handle(PacketWrapper wrapper) throws Exception {
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(handleBlockID(record.getBlockId()));
}
}
}
);
});
}
});
// Multi Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x10, 0x10, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int count = wrapper.passthrough(Type.VAR_INT); // Array length
for (int i = 0; i < count; i++) {
wrapper.passthrough(Type.UNSIGNED_BYTE); // Horizontal position
wrapper.passthrough(Type.UNSIGNED_BYTE); // Y coords
int id = wrapper.read(Type.VAR_INT); // Block ID
wrapper.write(Type.VAR_INT, handleBlockID(id));
}
}
});
}
}
);
// Update Block Entity
protocol.registerOutgoing(State.PLAY, 0x09, 0x09, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.BLOCK_ENTITY_DATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Position
@@ -306,15 +258,14 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
// Handler Spawners
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 1) {
CompoundTag tag = wrapper.get(Type.NBT, 0);
EntityTypeNames.toClientSpawner(tag);
EntityIdRewriter.toClientSpawner(tag, true);
}
}
});
}
});
// Open window packet
protocol.registerOutgoing(State.PLAY, 0x13, 0x13, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.OPEN_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
@@ -344,8 +295,7 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
}
});
// Close Window Packet
protocol.registerOutgoing(State.PLAY, 0x12, 0x12, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.CLOSE_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
// Inventory tracking
@@ -361,8 +311,7 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
});
// Close Window Incoming Packet
protocol.registerIncoming(State.PLAY, 0x08, 0x08, new PacketRemapper() {
protocol.registerIncoming(ServerboundPackets1_9_3.CLOSE_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
// Inventory tracking
@@ -389,47 +338,66 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
@Override
protected void registerRewrites() {
// ShulkerBoxes to EnderChest
for (int i = 219; i < 235; i++)
rewrite(i)
.repItem(new Item((short) 130, (byte) 1, (short) 0, getNamedTag("1.11 " + BlockColors.get(i - 219) + " Shulker Box")))
.repBlock(new Block(130, 4)) // TODO investigate this
.blockEntityHandler((block, tag) -> {
tag.remove("id");
tag.put(new StringTag("id", "minecraft:chest"));
return tag;
});
// Observer to Dispenser
rewrite(218).repItem(new Item((short) 23, (byte) 1, (short) 0, getNamedTag("1.11 Observer"))).repBlock(new Block(23, -1));
// Handle spawner block entity
rewrite(52).blockEntityHandler((b, tag) -> {
EntityTypeNames.toClientSpawner(tag);
// Handle spawner block entity (map to itself with custom handler)
MappedLegacyBlockItem data = replacementData.computeIfAbsent(52, s -> new MappedLegacyBlockItem(52, (short) -1, null, false));
data.setBlockEntityHandler((b, tag) -> {
EntityIdRewriter.toClientSpawner(tag, true);
return tag;
});
// Rewrite spawn eggs
rewrite(383).itemHandler((i) -> {
EntityTypeNames.toClientItem(i);
return i;
});
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName);
enchantmentRewriter.registerEnchantment(71, "§cCurse of Vanishing");
enchantmentRewriter.registerEnchantment(10, "§cCurse of Binding");
// Totem of Undying to Dead Bush
rewrite(449).repItem(new Item((short) 32, (byte) 1, (short) 0, getNamedTag("1.11 Totem of Undying")));
enchantmentRewriter.setHideLevelForEnchants(71, 10); // Curses do not display their level
}
// Shulker shell to Popped Chorus Fruit
rewrite(450).repItem(new Item((short) 433, (byte) 1, (short) 0, getNamedTag("1.11 Shulker Shell")));
@Override
public Item handleItemToClient(Item item) {
if (item == null) return null;
super.handleItemToClient(item);
CompoundTag tag = item.getTag();
if (tag == null) return item;
// Rewrite spawn eggs (id checks are done in the method itself)
EntityIdRewriter.toClientItem(item, true);
if (tag.get("ench") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, false);
}
if (tag.get("StoredEnchantments") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, true);
}
return item;
}
@Override
public Item handleItemToServer(final Item item) {
if (item == null) return null;
super.handleItemToServer(item);
CompoundTag tag = item.getTag();
if (tag == null) return item;
// Rewrite spawn eggs (id checks are done in the method itself)
EntityIdRewriter.toServerItem(item, true);
if (tag.contains(nbtTagName + "|ench")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(nbtTagName + "|StoredEnchantments")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, true);
}
return item;
}
private boolean isLlama(UserConnection user) {
WindowTracker tracker = user.get(WindowTracker.class);
if (tracker.getInventory() != null && tracker.getInventory().equals("EntityHorse")) {
EntityTracker.ProtocolEntityTracker entTracker = user.get(EntityTracker.class).get(getProtocol());
Optional<EntityTracker.StoredEntity> optEntity = entTracker.getEntity(tracker.getEntityId());
if (optEntity.isPresent() && optEntity.get().getType().is(EntityType1_11.EntityType.LIAMA))
return true;
EntityTracker.StoredEntity storedEntity = entTracker.getEntity(tracker.getEntityId());
return storedEntity != null && storedEntity.getType().is(Entity1_11Types.EntityType.LIAMA);
}
return false;
}
@@ -438,14 +406,13 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
WindowTracker tracker = user.get(WindowTracker.class);
if (tracker.getInventory() != null && tracker.getInventory().equals("EntityHorse")) {
EntityTracker.ProtocolEntityTracker entTracker = user.get(EntityTracker.class).get(getProtocol());
Optional<EntityTracker.StoredEntity> optEntity = entTracker.getEntity(tracker.getEntityId());
if (optEntity.isPresent())
return Optional.of(optEntity.get().get(ChestedHorseStorage.class));
EntityTracker.StoredEntity storedEntity = entTracker.getEntity(tracker.getEntityId());
if (storedEntity != null)
return Optional.of(storedEntity.get(ChestedHorseStorage.class));
}
return Optional.empty();
}
// TODO improve the llama inventory part
private int getNewSlotId(ChestedHorseStorage storage, int slotId) {
int totalSlots = !storage.isChested() ? 38 : 53;
int strength = storage.isChested() ? storage.getLiamaStrength() : 0;
@@ -480,7 +447,7 @@ public class BlockItemPackets1_11 extends BlockItemRewriter<Protocol1_10To1_11>
int endNonExistingFormula = 2 + 3 * (storage.isChested() ? 5 : 0);
if (slotId >= startNonExistingFormula && slotId < endNonExistingFormula)
return new Item((short) 166, (byte) 1, (short) 0, getNamedTag(ChatColor.RED + "SLOT DISABLED"));
return new Item(166, (byte) 1, (short) 0, getNamedTag(ChatColor.RED + "SLOT DISABLED"));
if (slotId == 1)
return null;
return current;
@@ -10,38 +10,60 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import nl.matsv.viabackwards.api.entities.types.AbstractEntityType;
import nl.matsv.viabackwards.api.entities.types.EntityType1_12;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.rewriters.EntityRewriter;
import nl.matsv.viabackwards.api.rewriters.LegacyEntityRewriter;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.PotionSplashHandler;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage.ChestedHorseStorage;
import nl.matsv.viabackwards.utils.Block;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.entities.Entity1_11Types;
import us.myles.ViaVersion.api.entities.Entity1_12Types;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import java.util.Optional;
import static nl.matsv.viabackwards.api.entities.types.EntityType1_11.*;
public class EntityPackets1_11 extends LegacyEntityRewriter<Protocol1_10To1_11> {
public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
public EntityPackets1_11(Protocol1_10To1_11 protocol) {
super(protocol);
}
@Override
protected void registerPackets(Protocol1_10To1_11 protocol) {
// Spawn Object
protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_9_3.EFFECT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT);
map(Type.POSITION);
map(Type.INT);
handler(wrapper -> {
int type = wrapper.get(Type.INT, 0);
if (type == 2002 || type == 2007) {
// 2007 potion id doesn't exist in 1.10
if (type == 2007) {
wrapper.set(Type.INT, 0, 2002);
}
int mappedData = PotionSplashHandler.getOldData(wrapper.get(Type.INT, 1));
if (mappedData != -1) {
wrapper.set(Type.INT, 1, mappedData);
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
@@ -55,44 +77,15 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
map(Type.INT); // 8 - data
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
getTypeFromId(wrapper.get(Type.BYTE, 0), true)
);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Optional<ObjectType> type = ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent()) {
Optional<EntityData> optEntDat = getObjectData(type.get());
if (optEntDat.isPresent()) {
EntityData data = optEntDat.get();
wrapper.set(Type.BYTE, 0, ((Integer) data.getReplacementId()).byteValue());
if (data.getObjectData() != -1)
wrapper.set(Type.INT, 0, data.getObjectData());
}
} else {
if (Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Could not find Entity Type" + wrapper.get(Type.BYTE, 0));
}
}
}
});
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> Entity1_11Types.ObjectType.findById(id).orElse(null)));
// Handle FallingBlock blocks
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Optional<EntityType1_12.ObjectType> type = EntityType1_12.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get().equals(EntityType1_12.ObjectType.FALLING_BLOCK)) {
Optional<Entity1_12Types.ObjectType> type = Entity1_12Types.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == Entity1_12Types.ObjectType.FALLING_BLOCK) {
int objectData = wrapper.get(Type.INT, 0);
int objType = objectData & 4095;
int data = objectData >> 12 & 15;
@@ -108,49 +101,10 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
}
});
// Spawn Experience Orb
protocol.registerOutgoing(State.PLAY, 0x01, 0x01, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, Entity1_11Types.EntityType.EXPERIENCE_ORB);
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, Entity1_11Types.EntityType.WEATHER);
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
ObjectType.THROWN_EXP_BOTTLE.getType()
);
}
});
}
});
// Spawn Global Entity
protocol.registerOutgoing(State.PLAY, 0x02, 0x02, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.BYTE); // 1 - Type
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.WEATHER // Always thunder according to wiki.vg
);
}
});
}
});
// Spawn Mob
protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_MOB, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
@@ -168,23 +122,14 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
map(Types1_9.METADATA_LIST); // 12 - Metadata
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
getTypeFromId(wrapper.get(Type.UNSIGNED_BYTE, 0), false)
);
}
});
handler(getTrackerHandler(Type.UNSIGNED_BYTE, 0));
// Rewrite entity type / metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
AbstractEntityType type = getEntityType(wrapper.user(), entityId);
EntityType type = getEntityType(wrapper.user(), entityId);
MetaStorage storage = new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0));
handleMeta(
@@ -193,12 +138,12 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
storage
);
Optional<EntityData> optEntDat = getEntityData(type);
if (optEntDat.isPresent()) {
EntityData data = optEntDat.get();
wrapper.set(Type.UNSIGNED_BYTE, 0, ((Integer) data.getReplacementId()).shortValue());
if (data.hasBaseMeta())
data.getDefaultMeta().handle(storage);
EntityData entityData = getEntityData(type);
if (entityData != null) {
wrapper.set(Type.UNSIGNED_BYTE, 0, (short) entityData.getReplacementId());
if (entityData.hasBaseMeta()) {
entityData.getDefaultMeta().createMeta(storage);
}
}
// Rewrite Metadata
@@ -212,74 +157,11 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
}
});
// Spawn Painting
protocol.registerOutgoing(State.PLAY, 0x04, 0x04, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_PAINTING, Entity1_11Types.EntityType.PAINTING);
registerJoinGame(ClientboundPackets1_9_3.JOIN_GAME, Entity1_11Types.EntityType.PLAYER);
registerRespawn(ClientboundPackets1_9_3.RESPAWN);
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.PAINTING
);
}
});
}
});
// Join game
protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.INT, 0),
EntityType.PLAYER
);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Respawn Packet (save dimension id)
protocol.registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Dimension ID
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 0);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Spawn Player
protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_PLAYER, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
@@ -291,78 +173,14 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
map(Type.BYTE); // 6 - Pitch
map(Types1_9.METADATA_LIST); // 7 - Metadata list
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.PLAYER
);
}
});
// Rewrite Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0))
).getMetaDataList()
);
}
});
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, Entity1_11Types.EntityType.PLAYER));
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x30, 0x30, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity IDS
registerEntityDestroy(ClientboundPackets1_9_3.DESTROY_ENTITIES);
registerMetadataRewriter(ClientboundPackets1_9_3.ENTITY_METADATA, Types1_9.METADATA_LIST);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
getEntityTracker(wrapper.user()).removeEntity(entity);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x39, 0x39, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_9.METADATA_LIST); // 1 - Metadata list
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0))
).getMetaDataList()
);
}
});
}
});
// Entity Status
protocol.registerOutgoing(State.PLAY, 0x1B, 0x1B, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.ENTITY_STATUS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
@@ -378,7 +196,6 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
wrapper.setId(0x1E); // Change Game State
wrapper.write(Type.UNSIGNED_BYTE, (short) 10); // Play Elder Guardian animation
wrapper.write(Type.FLOAT, 0F);
}
}
});
@@ -389,39 +206,39 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
@Override
protected void registerRewrites() {
// Guardian
regEntType(EntityType.ELDER_GUARDIAN, EntityType.GUARDIAN);
mapEntity(Entity1_11Types.EntityType.ELDER_GUARDIAN, Entity1_11Types.EntityType.GUARDIAN);
// Skeletons
regEntType(EntityType.WITHER_SKELETON, EntityType.SKELETON).spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(1)));
regEntType(EntityType.STRAY, EntityType.SKELETON).spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(2)));
mapEntity(Entity1_11Types.EntityType.WITHER_SKELETON, Entity1_11Types.EntityType.SKELETON).mobName("Wither Skeleton").spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(1)));
mapEntity(Entity1_11Types.EntityType.STRAY, Entity1_11Types.EntityType.SKELETON).mobName("Stray").spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(2)));
// Zombies
regEntType(EntityType.HUSK, EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 6));
regEntType(EntityType.ZOMBIE_VILLAGER, EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 1));
mapEntity(Entity1_11Types.EntityType.HUSK, Entity1_11Types.EntityType.ZOMBIE).mobName("Husk").spawnMetadata(storage -> handleZombieType(storage, 6));
mapEntity(Entity1_11Types.EntityType.ZOMBIE_VILLAGER, Entity1_11Types.EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 1));
// Horses
regEntType(EntityType.HORSE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(0))); // Nob able to ride the horse without having the MetaType sent.
regEntType(EntityType.DONKEY, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
regEntType(EntityType.MULE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(2)));
regEntType(EntityType.SKELETON_HORSE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(4)));
regEntType(EntityType.ZOMBIE_HORSE, EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(3)));
mapEntity(Entity1_11Types.EntityType.HORSE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(0))); // Nob able to ride the horse without having the MetaType sent.
mapEntity(Entity1_11Types.EntityType.DONKEY, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
mapEntity(Entity1_11Types.EntityType.MULE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(2)));
mapEntity(Entity1_11Types.EntityType.SKELETON_HORSE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(4)));
mapEntity(Entity1_11Types.EntityType.ZOMBIE_HORSE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(3)));
// New mobs
regEntType(EntityType.EVOCATION_FANGS, EntityType.SHULKER);
regEntType(EntityType.EVOCATION_ILLAGER, EntityType.VILLAGER).mobName("Evoker");
regEntType(EntityType.VEX, EntityType.BAT).mobName("Vex");
regEntType(EntityType.VINDICATION_ILLAGER, EntityType.VILLAGER).mobName("Vindicator").spawnMetadata(storage -> storage.add(new Metadata(13, MetaType1_9.VarInt, 4))); // Base Profession
regEntType(EntityType.LIAMA, EntityType.HORSE).mobName("Llama").spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
regEntType(EntityType.LIAMA_SPIT, EntityType.SNOWBALL);
mapEntity(Entity1_11Types.EntityType.EVOCATION_FANGS, Entity1_11Types.EntityType.SHULKER);
mapEntity(Entity1_11Types.EntityType.EVOCATION_ILLAGER, Entity1_11Types.EntityType.VILLAGER).mobName("Evoker");
mapEntity(Entity1_11Types.EntityType.VEX, Entity1_11Types.EntityType.BAT).mobName("Vex");
mapEntity(Entity1_11Types.EntityType.VINDICATION_ILLAGER, Entity1_11Types.EntityType.VILLAGER).mobName("Vindicator").spawnMetadata(storage -> storage.add(new Metadata(13, MetaType1_9.VarInt, 4))); // Base Profession
mapEntity(Entity1_11Types.EntityType.LIAMA, Entity1_11Types.EntityType.HORSE).mobName("Llama").spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
mapEntity(Entity1_11Types.EntityType.LIAMA_SPIT, Entity1_11Types.EntityType.SNOWBALL);
regObjType(ObjectType.LIAMA_SPIT, ObjectType.SNOWBALL, -1);
mapObjectType(Entity1_11Types.ObjectType.LIAMA_SPIT, Entity1_11Types.ObjectType.SNOWBALL, -1);
// Replace with endertorchthingies
regObjType(ObjectType.EVOCATION_FANGS, ObjectType.FALLING_BLOCK, 198 | 1 << 12);
mapObjectType(Entity1_11Types.ObjectType.EVOCATION_FANGS, Entity1_11Types.ObjectType.FALLING_BLOCK, 198 | 1 << 12);
// Handle ElderGuardian & target metadata
registerMetaHandler().filter(EntityType.GUARDIAN, true, 12).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.GUARDIAN, true, 12).handle(e -> {
Metadata data = e.getData();
boolean b = (boolean) data.getValue();
int bitmask = b ? 0x02 : 0;
if (e.getEntity().getType().is(EntityType.ELDER_GUARDIAN))
if (e.getEntity().getType().is(Entity1_11Types.EntityType.ELDER_GUARDIAN))
bitmask |= 0x04;
data.setMetaType(MetaType1_9.Byte);
@@ -431,17 +248,17 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
});
// Handle skeleton swing
registerMetaHandler().filter(EntityType.ABSTRACT_SKELETON, true, 12).handleIndexChange(13);
registerMetaHandler().filter(Entity1_11Types.EntityType.ABSTRACT_SKELETON, true, 12).handleIndexChange(13);
/*
ZOMBIE CHANGES
*/
registerMetaHandler().filter(EntityType.ZOMBIE, true).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.ZOMBIE, true).handle(e -> {
Metadata data = e.getData();
switch (data.getId()) {
case 13:
throw new RemovedValueException();
throw RemovedValueException.EX;
case 14:
data.setId(15);
break;
@@ -459,7 +276,7 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
});
// Handle Evocation Illager
registerMetaHandler().filter(EntityType.EVOCATION_ILLAGER, 12).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.EVOCATION_ILLAGER, 12).handle(e -> {
Metadata data = e.getData();
data.setId(13);
data.setMetaType(MetaType1_9.VarInt);
@@ -469,14 +286,14 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
});
// Handle Vex (Remove this field completely since the position is not updated correctly when idling for bats. Sad ):
registerMetaHandler().filter(EntityType.VEX, 12).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.VEX, 12).handle(e -> {
Metadata data = e.getData();
data.setValue((byte) 0x00);
return data;
});
// Handle VindicationIllager
registerMetaHandler().filter(EntityType.VINDICATION_ILLAGER, 12).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.VINDICATION_ILLAGER, 12).handle(e -> {
Metadata data = e.getData();
data.setId(13);
data.setMetaType(MetaType1_9.VarInt);
@@ -491,7 +308,7 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
*/
// Handle horse flags
registerMetaHandler().filter(EntityType.ABSTRACT_HORSE, true, 13).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.ABSTRACT_HORSE, true, 13).handle(e -> {
Metadata data = e.getData();
byte b = (byte) data.getValue();
if (e.getEntity().has(ChestedHorseStorage.class) &&
@@ -502,30 +319,27 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
return data;
});
// Create chested horse storage TODO create on mob spawn?
registerMetaHandler().filter(EntityType.CHESTED_HORSE, true).handle(e -> {
// Create chested horse storage
registerMetaHandler().filter(Entity1_11Types.EntityType.CHESTED_HORSE, true).handle(e -> {
if (!e.getEntity().has(ChestedHorseStorage.class))
e.getEntity().put(new ChestedHorseStorage());
return e.getData();
});
// Handle Horse (Correct owner)
registerMetaHandler().filter(EntityType.ABSTRACT_HORSE, true, 14).handleIndexChange(16);
// Handle horse armor
registerMetaHandler().filter(EntityType.HORSE, 16).handleIndexChange(17);
registerMetaHandler().filter(Entity1_11Types.EntityType.HORSE, 16).handleIndexChange(17);
// Handle chested horse
registerMetaHandler().filter(EntityType.CHESTED_HORSE, true, 15).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.CHESTED_HORSE, true, 15).handle(e -> {
ChestedHorseStorage storage = e.getEntity().get(ChestedHorseStorage.class);
boolean b = (boolean) e.getData().getValue();
storage.setChested(b);
throw new RemovedValueException();
throw RemovedValueException.EX;
});
// Get rid of Liama metadata
registerMetaHandler().filter(EntityType.LIAMA).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.LIAMA).handle(e -> {
Metadata data = e.getData();
ChestedHorseStorage storage = e.getEntity().get(ChestedHorseStorage.class);
@@ -534,19 +348,22 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
switch (index) {
case 16:
storage.setLiamaStrength((int) data.getValue());
throw new RemovedValueException();
throw RemovedValueException.EX;
case 17:
storage.setLiamaCarpetColor((int) data.getValue());
throw new RemovedValueException();
throw RemovedValueException.EX;
case 18:
storage.setLiamaVariant((int) data.getValue());
throw new RemovedValueException();
throw RemovedValueException.EX;
}
return e.getData();
});
// Handle Horse (Correct owner)
registerMetaHandler().filter(Entity1_11Types.EntityType.ABSTRACT_HORSE, true, 14).handleIndexChange(16);
// Handle villager - Change non-existing profession
registerMetaHandler().filter(EntityType.VILLAGER, 13).handle(e -> {
registerMetaHandler().filter(Entity1_11Types.EntityType.VILLAGER, 13).handle(e -> {
Metadata data = e.getData();
if ((int) data.getValue() == 5)
data.setValue(0);
@@ -555,7 +372,7 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
});
// handle new Shulker color meta
registerMetaHandler().filter(EntityType.SHULKER, 15).removed();
registerMetaHandler().filter(Entity1_11Types.EntityType.SHULKER, 15).removed();
}
@@ -579,10 +396,10 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
}
private void handleZombieType(MetaStorage storage, int type) {
Optional<Metadata> meta = storage.get(13);
if (!meta.isPresent())
Metadata meta = storage.get(13);
if (meta == null) {
storage.add(getZombieTypeMeta(type));
}
}
/*
@@ -596,4 +413,13 @@ public class EntityPackets1_11 extends EntityRewriter<Protocol1_10To1_11> {
return new Metadata(14, MetaType1_9.VarInt, type);
}
@Override
protected EntityType getTypeFromId(int typeId) {
return Entity1_11Types.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(int typeId) {
return Entity1_11Types.getTypeFromId(typeId, true);
}
}
@@ -16,22 +16,20 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_11to1_10.Protocol1_11To1_10;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
public class PlayerPackets1_11 {
private static final ValueTransformer<Short, Float> toNewFloat = new ValueTransformer<Short, Float>(Type.FLOAT) {
private static final ValueTransformer<Short, Float> TO_NEW_FLOAT = new ValueTransformer<Short, Float>(Type.FLOAT) {
@Override
public Float transform(PacketWrapper wrapper, Short inputValue) throws Exception {
return (float) (inputValue / 16);
return inputValue / 15f;
}
};
public void register(Protocol1_10To1_11 protocol) {
/* Outgoing packets */
// Title packet
protocol.registerOutgoing(State.PLAY, 0x45, 0x45, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.TITLE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Action
@@ -45,53 +43,47 @@ public class PlayerPackets1_11 {
if (action == 2) {
// Convert to the old actionbar way
PacketWrapper actionbar = new PacketWrapper(0x0F, null, wrapper.user()); // Chat Message packet
actionbar.write(Type.STRING, wrapper.read(Type.STRING));
String msg = wrapper.read(Type.STRING);
msg = ChatRewriter.jsonTextToLegacy(msg);
msg = "{\"text\":\"" + msg + "\"}";
actionbar.write(Type.STRING, msg);
actionbar.write(Type.BYTE, (byte) 2); // Above hotbar
actionbar.send(Protocol1_11To1_10.class);
actionbar.send(Protocol1_10To1_11.class);
wrapper.cancel(); // Cancel the title packet
return;
}
if (action > 2)
if (action > 2) {
wrapper.set(Type.VAR_INT, 0, action - 1); // Move everything one position down
}
}
});
}
});
// Collect item packet
protocol.registerOutgoing(State.PLAY, 0x48, 0x48, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.COLLECT_ITEM, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Collected entity id
map(Type.VAR_INT); // 1 - Collector entity id
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
packetWrapper.read(Type.VAR_INT); // Ignore pickup item count
}
});
handler(wrapper -> wrapper.read(Type.VAR_INT)); // Ignore item pickup count
}
});
/* Incoming packets */
// Block placement packet
protocol.registerIncoming(State.PLAY, 0x1C, 0x1C, new PacketRemapper() {
protocol.registerIncoming(ServerboundPackets1_9_3.PLAYER_BLOCK_PLACEMENT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Location
map(Type.VAR_INT); // 1 - Face
map(Type.VAR_INT); // 2 - Hand
map(Type.UNSIGNED_BYTE, toNewFloat);
map(Type.UNSIGNED_BYTE, toNewFloat);
map(Type.UNSIGNED_BYTE, toNewFloat);
map(Type.UNSIGNED_BYTE, TO_NEW_FLOAT);
map(Type.UNSIGNED_BYTE, TO_NEW_FLOAT);
map(Type.UNSIGNED_BYTE, TO_NEW_FLOAT);
}
});
}
@@ -10,19 +10,23 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets;
import nl.matsv.viabackwards.api.rewriters.SoundRewriter;
import nl.matsv.viabackwards.api.rewriters.LegacySoundRewriter;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
public class SoundPackets1_11 extends LegacySoundRewriter<Protocol1_10To1_11> {
public SoundPackets1_11(Protocol1_10To1_11 protocol) {
super(protocol);
}
public class SoundPackets1_11 extends SoundRewriter<Protocol1_10To1_11> {
@Override
protected void registerPackets(Protocol1_10To1_11 protocol) {
// Named sound effect
protocol.registerOutgoing(State.PLAY, 0x19, 0x19, new PacketRemapper() {
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_9_3.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Sound name
@@ -35,8 +39,7 @@ public class SoundPackets1_11 extends SoundRewriter<Protocol1_10To1_11> {
}
});
// Sound effect
protocol.registerOutgoing(State.PLAY, 0x46, 0x46, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Sound name
@@ -74,7 +77,8 @@ public class SoundPackets1_11 extends SoundRewriter<Protocol1_10To1_11> {
added(176, 227); // entity.elder_guardian.flop -> entity.guardian.flop
removed(196); // entity.experience_orb.touch
// 1.10 entity.experience_orb.touch was removed; subtract id and properly map ender pearl sound on that id
soundRewrites.put(196, new SoundData(193, false, -1, false));
added(197, 402, 1.8f); // entity.evocation_fangs.attack -> entity.zombie.attack_iron_door
added(198, 370, 0.4f); // entity.evocation_illager.ambient -> entity.villager.ambient
@@ -10,18 +10,48 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import nl.matsv.viabackwards.api.entities.storage.EntityStorage;
@Getter
@Setter
@ToString
public class ChestedHorseStorage extends EntityStorage {
private boolean chested = false;
private int liamaStrength = 0;
public class ChestedHorseStorage implements EntityStorage {
private boolean chested;
private int liamaStrength;
private int liamaCarpetColor = -1;
private int liamaVariant = 0;
private int liamaVariant;
public boolean isChested() {
return chested;
}
public void setChested(boolean chested) {
this.chested = chested;
}
public int getLiamaStrength() {
return liamaStrength;
}
public void setLiamaStrength(int liamaStrength) {
this.liamaStrength = liamaStrength;
}
public int getLiamaCarpetColor() {
return liamaCarpetColor;
}
public void setLiamaCarpetColor(int liamaCarpetColor) {
this.liamaCarpetColor = liamaCarpetColor;
}
public int getLiamaVariant() {
return liamaVariant;
}
public void setLiamaVariant(int liamaVariant) {
this.liamaVariant = liamaVariant;
}
@Override
public String toString() {
return "ChestedHorseStorage{" + "chested=" + chested + ", liamaStrength=" + liamaStrength + ", liamaCarpetColor=" + liamaCarpetColor + ", liamaVariant=" + liamaVariant + '}';
}
}
@@ -10,15 +10,9 @@
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
@Getter
@ToString
@Setter
public class WindowTracker extends StoredObject {
private String inventory;
private int entityId = -1;
@@ -26,5 +20,26 @@ public class WindowTracker extends StoredObject {
public WindowTracker(UserConnection user) {
super(user);
}
public String getInventory() {
return inventory;
}
public void setInventory(String inventory) {
this.inventory = inventory;
}
public int getEntityId() {
return entityId;
}
public void setEntityId(int entityId) {
this.entityId = entityId;
}
@Override
public String toString() {
return "WindowTracker{" + "inventory='" + inventory + '\'' + ", entityId=" + entityId + '}';
}
}
@@ -8,44 +8,66 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_12to1_11_1;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12;
import lombok.Getter;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data.ShoulderTracker;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.packets.*;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data.ShoulderTracker;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets.BlockItemPackets1_12;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets.ChatPackets1_12;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets.EntityPackets1_12;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets.SoundPackets1_12;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ServerboundPackets1_12;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
@Getter
public class Protocol1_11_1To1_12 extends BackwardsProtocol {
// TODO store all rewriters and make them easy accessible?
public class Protocol1_11_1To1_12 extends BackwardsProtocol<ClientboundPackets1_12, ClientboundPackets1_9_3, ServerboundPackets1_12, ServerboundPackets1_9_3> {
private EntityPackets1_12 entityPackets;
private BlockItemPackets1_12 blockItemPackets;
public Protocol1_11_1To1_12() {
super(ClientboundPackets1_12.class, ClientboundPackets1_9_3.class, ServerboundPackets1_12.class, ServerboundPackets1_9_3.class);
}
@Override
protected void registerPackets() {
new ChangedPacketIds1_12().register(this);
(entityPackets = new EntityPackets1_12()).register(this);
(blockItemPackets = new BlockItemPackets1_12()).register(this);
new SoundPackets1_12().register(this);
new ChatPackets1_12().register(this);
(entityPackets = new EntityPackets1_12(this)).register();
(blockItemPackets = new BlockItemPackets1_12(this)).register();
new SoundPackets1_12(this).register();
new ChatPackets1_12(this).register();
cancelOutgoing(ClientboundPackets1_12.ADVANCEMENTS);
cancelOutgoing(ClientboundPackets1_12.UNLOCK_RECIPES);
cancelOutgoing(ClientboundPackets1_12.SELECT_ADVANCEMENTS_TAB);
}
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class))
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
}
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class))
if (!user.has(EntityTracker.class)) {
user.put(new EntityTracker(user));
}
user.put(new ShoulderTracker(user));
// Init protocol in EntityTracker
user.get(EntityTracker.class).initProtocol(this);
}
public EntityPackets1_12 getEntityPackets() {
return entityPackets;
}
public BlockItemPackets1_12 getBlockItemPackets() {
return blockItemPackets;
}
}
@@ -8,13 +8,13 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class AdvancementTranslations {
private static final Map<String, String> advancements = new ConcurrentHashMap<>();
private static final Map<String, String> advancements = new HashMap<>();
static {
add("advancements.nether.get_wither_skull.title", "Spooky Scary Skeleton");
@@ -140,10 +140,6 @@ public class AdvancementTranslations {
advancements.put(key, value);
}
public static boolean has(String key) {
return advancements.containsKey(key);
}
public static String get(String key) {
return advancements.get(key);
}
@@ -8,31 +8,31 @@
* 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 nl.matsv.viabackwards.api.entities.types;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data;
import java.util.List;
public class BlockColors {
private static final String[] COLORS = new String[16];
public interface AbstractEntityType {
static {
COLORS[0] = "White";
COLORS[1] = "Orange";
COLORS[2] = "Magenta";
COLORS[3] = "Light Blue";
COLORS[4] = "Yellow";
COLORS[5] = "Lime";
COLORS[6] = "Pink";
COLORS[7] = "Gray";
COLORS[8] = "Light Gray";
COLORS[9] = "Cyan";
COLORS[10] = "Purple";
COLORS[11] = "Blue";
COLORS[12] = "Brown";
COLORS[13] = "Green";
COLORS[14] = "Red";
COLORS[15] = "Black";
}
/**
* Get the metadata id
*
* @return the metadata index
*/
int getId();
/**
* Get the parent class of the entity
*
* @return parent EntityType
*/
AbstractEntityType getParent();
boolean is(AbstractEntityType... types);
boolean is(AbstractEntityType type);
boolean isOrHasParent(AbstractEntityType type);
List<AbstractEntityType> getParents();
public static String get(int key) {
return key >= 0 && key < COLORS.length ? COLORS[key] : "Unknown color";
}
}
@@ -0,0 +1,80 @@
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data;
import us.myles.viaversion.libs.fastutil.ints.Int2IntMap;
import us.myles.viaversion.libs.fastutil.ints.Int2IntOpenHashMap;
public class MapColorMapping {
private static final Int2IntMap MAPPING = new Int2IntOpenHashMap(64, 1F);
static {
MAPPING.defaultReturnValue(-1);
MAPPING.put(144, 59); // (148, 124, 114) -> (148, 124, 114)
MAPPING.put(145, 56); // (180, 153, 139) -> (180, 153, 139)
MAPPING.put(146, 56); // (209, 177, 161) -> (209, 177, 161)
MAPPING.put(147, 45); // (111, 94, 85) -> (111, 94, 85)
MAPPING.put(148, 63); // (112, 58, 25) -> (112, 58, 25)
MAPPING.put(149, 60); // (137, 71, 31) -> (137, 71, 31)
MAPPING.put(150, 60); // (159, 82, 36) -> (159, 82, 36)
MAPPING.put(151, 136); // (84, 43, 19) -> (84, 43, 19)
MAPPING.put(152, 83); // (105, 61, 76) -> (105, 61, 76)
MAPPING.put(153, 83); // (129, 75, 93) -> (129, 75, 93)
MAPPING.put(154, 80); // (149, 87, 108) -> (149, 87, 108)
MAPPING.put(155, 115); // (79, 46, 57) -> (79, 46, 57)
MAPPING.put(156, 39); // (79, 76, 97) -> (79, 76, 97)
MAPPING.put(157, 39); // (97, 93, 119) -> (97, 93, 119)
MAPPING.put(158, 36); // (112, 108, 138) -> (112, 108, 138)
MAPPING.put(159, 47); // (59, 57, 73) -> (59, 57, 73)
MAPPING.put(160, 60); // (131, 94, 25) -> (131, 94, 25)
MAPPING.put(161, 61); // (160, 115, 31) -> (160, 115, 31)
MAPPING.put(162, 62); // (186, 133, 36) -> (186, 133, 36)
MAPPING.put(163, 137); // (98, 70, 19) -> (98, 70, 19)
MAPPING.put(164, 108); // (73, 83, 37) -> (73, 83, 37)
MAPPING.put(165, 108); // (89, 101, 46) -> (89, 101, 46)
MAPPING.put(166, 109); // (103, 117, 53) -> (103, 117, 53)
MAPPING.put(167, 111); // (55, 62, 28) -> (55, 62, 28)
MAPPING.put(168, 112); // (113, 54, 55) -> (113, 54, 55)
MAPPING.put(169, 113); // (138, 66, 67) -> (138, 66, 67)
MAPPING.put(170, 114); // (160, 77, 78) -> (160, 77, 78)
MAPPING.put(171, 115); // (85, 41, 41) -> (85, 41, 41)
MAPPING.put(172, 118); // (40, 29, 25) -> (40, 29, 25)
MAPPING.put(173, 107); // (49, 35, 30) -> (49, 35, 30)
MAPPING.put(174, 107); // (57, 41, 35) -> (57, 41, 35)
MAPPING.put(175, 118); // (30, 22, 19) -> (30, 22, 19)
MAPPING.put(176, 91); // (95, 76, 69) -> (95, 76, 69)
MAPPING.put(177, 45); // (116, 92, 85) -> (116, 92, 85)
MAPPING.put(178, 46); // (135, 107, 98) -> (135, 107, 98)
MAPPING.put(179, 47); // (71, 57, 52) -> (71, 57, 52)
MAPPING.put(180, 85); // (61, 65, 65) -> (61, 65, 65)
MAPPING.put(181, 44); // (75, 79, 79) -> (75, 79, 79)
MAPPING.put(182, 27); // (87, 92, 92) -> (87, 92, 92)
MAPPING.put(183, 84); // (46, 49, 49) -> (46, 49, 49)
MAPPING.put(184, 83); // (86, 52, 62) -> (86, 52, 62)
MAPPING.put(185, 83); // (105, 63, 76) -> (105, 63, 76)
MAPPING.put(186, 83); // (122, 73, 88) -> (122, 73, 88)
MAPPING.put(187, 84); // (65, 39, 47) -> (65, 39, 47)
MAPPING.put(188, 84); // (54, 44, 65) -> (54, 44, 65)
MAPPING.put(189, 71); // (66, 53, 79) -> (66, 53, 79)
MAPPING.put(190, 71); // (76, 62, 92) -> (76, 62, 92)
MAPPING.put(191, 87); // (40, 33, 49) -> (40, 33, 49)
MAPPING.put(192, 107); // (54, 35, 25) -> (54, 35, 25)
MAPPING.put(193, 139); // (66, 43, 30) -> (66, 43, 30)
MAPPING.put(194, 43); // (76, 50, 35) -> (76, 50, 35)
MAPPING.put(195, 107); // (40, 26, 19) -> (40, 26, 19)
MAPPING.put(196, 111); // (54, 58, 30) -> (54, 58, 30)
MAPPING.put(197, 111); // (66, 71, 36) -> (66, 71, 36)
MAPPING.put(198, 111); // (76, 82, 42) -> (76, 82, 42)
MAPPING.put(199, 107); // (40, 43, 22) -> (40, 43, 22)
MAPPING.put(200, 112); // (100, 42, 32) -> (100, 42, 32)
MAPPING.put(201, 113); // (123, 52, 40) -> (123, 52, 40)
MAPPING.put(202, 113); // (142, 60, 46) -> (142, 60, 46)
MAPPING.put(203, 115); // (75, 32, 24) -> (75, 32, 24)
MAPPING.put(204, 116); // (26, 16, 11) -> (26, 16, 11)
MAPPING.put(205, 117); // (32, 19, 14) -> (32, 19, 14)
MAPPING.put(206, 107); // (37, 22, 16) -> (37, 22, 16)
MAPPING.put(207, 119); // (20, 12, 8) -> (20, 12, 8)
}
public static int getNearestOldColor(int color) {
return MAPPING.getOrDefault(color, color);
}
}
@@ -8,13 +8,28 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data;
import lombok.Data;
import nl.matsv.viabackwards.api.entities.storage.EntityStorage;
@Data
public class ParrotStorage extends EntityStorage {
public class ParrotStorage implements EntityStorage {
private boolean tamed = true;
private boolean sitting = true;
public boolean isTamed() {
return tamed;
}
public void setTamed(boolean tamed) {
this.tamed = tamed;
}
public boolean isSitting() {
return sitting;
}
public void setSitting(boolean sitting) {
this.sitting = sitting;
}
}
@@ -8,23 +8,17 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import net.md_5.bungee.api.ChatColor;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.Protocol1_12To1_11_1;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
@Getter
@Setter
@ToString
public class ShoulderTracker extends StoredObject {
private int entityId;
private String leftShoulder;
@@ -37,11 +31,11 @@ public class ShoulderTracker extends StoredObject {
public void update() {
PacketWrapper wrapper = new PacketWrapper(0x0F, null, getUser());
wrapper.write(Type.STRING, Protocol1_9TO1_8.fixJson(generateString()));
wrapper.write(Type.STRING, Protocol1_9To1_8.fixJson(generateString()));
wrapper.write(Type.BYTE, (byte) 2);
try {
wrapper.send(Protocol1_12To1_11_1.class);
wrapper.send(Protocol1_11_1To1_12.class);
} catch (Exception e) {
ViaBackwards.getPlatform().getLogger().severe("Failed to send the shoulder indication");
e.printStackTrace();
@@ -85,4 +79,33 @@ public class ShoulderTracker extends StoredObject {
return builder.toString();
}
public int getEntityId() {
return entityId;
}
public void setEntityId(int entityId) {
this.entityId = entityId;
}
public String getLeftShoulder() {
return leftShoulder;
}
public void setLeftShoulder(String leftShoulder) {
this.leftShoulder = leftShoulder;
}
public String getRightShoulder() {
return rightShoulder;
}
public void setRightShoulder(String rightShoulder) {
this.rightShoulder = rightShoulder;
}
@Override
public String toString() {
return "ShoulderTracker{" + "entityId=" + entityId + ", leftShoulder='" + leftShoulder + '\'' + ", rightShoulder='" + rightShoulder + '\'' + '}';
}
}
@@ -0,0 +1,249 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets;
import nl.matsv.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data.MapColorMapping;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<Protocol1_11_1To1_12> {
public BlockItemPackets1_12(Protocol1_11_1To1_12 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_12.MAP_DATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.BOOLEAN);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int count = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < count * 3; i++) {
wrapper.passthrough(Type.BYTE);
}
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
short columns = wrapper.passthrough(Type.UNSIGNED_BYTE);
if (columns <= 0) return;
short rows = wrapper.passthrough(Type.UNSIGNED_BYTE);
wrapper.passthrough(Type.BYTE); //X
wrapper.passthrough(Type.BYTE); //Z
byte[] data = wrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
for (int i = 0; i < data.length; i++) {
short color = (short) (data[i] & 0xFF);
if (color > 143) {
color = (short) MapColorMapping.getNearestOldColor(color);
data[i] = (byte) color;
}
}
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, data);
}
});
}
});
ItemRewriter itemRewriter = new ItemRewriter(protocol, this::handleItemToClient, this::handleItemToServer);
itemRewriter.registerSetSlot(ClientboundPackets1_12.SET_SLOT, Type.ITEM);
itemRewriter.registerWindowItems(ClientboundPackets1_12.WINDOW_ITEMS, Type.ITEM_ARRAY);
itemRewriter.registerEntityEquipment(ClientboundPackets1_12.ENTITY_EQUIPMENT, Type.ITEM);
// Plugin message Packet -> Trading
protocol.registerOutgoing(ClientboundPackets1_12.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem)
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
}
}
}
});
}
});
protocol.registerIncoming(ServerboundPackets1_9_3.CLICK_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (wrapper.get(Type.VAR_INT, 0) == 1) { // Shift click
// https://github.com/ViaVersion/ViaVersion/pull/754
// Previously clients grab the item from the clicked slot *before* it has
// been moved however now they grab the slot item *after* it has been moved
// and send that in the packet.
wrapper.set(Type.ITEM, 0, null); // Set null item (probably will work)
// Apologize (may happen in some cases, maybe if inventory is full?)
PacketWrapper confirm = wrapper.create(0x6);
confirm.write(Type.BYTE, wrapper.get(Type.UNSIGNED_BYTE, 0).byteValue());
confirm.write(Type.SHORT, wrapper.get(Type.SHORT, 1));
confirm.write(Type.BOOLEAN, false); // Success - not used
wrapper.sendToServer(Protocol1_11_1To1_12.class, true, true);
wrapper.cancel();
confirm.sendToServer(Protocol1_11_1To1_12.class, true, true);
return;
}
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
}
});
}
});
itemRewriter.registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION, Type.ITEM);
protocol.registerOutgoing(ClientboundPackets1_12.CHUNK_DATA, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); // Use the 1.9.4 Chunk type since nothing changed.
Chunk chunk = wrapper.passthrough(type);
handleChunk(chunk);
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_12.BLOCK_CHANGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockID(idx));
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_12.MULTI_BLOCK_CHANGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(handleBlockID(record.getBlockId()));
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_12.BLOCK_ENTITY_DATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Position
map(Type.UNSIGNED_BYTE); // 1 - Action
map(Type.NBT); // 2 - NBT
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Remove bed color
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 11)
wrapper.cancel();
}
});
}
});
protocol.getEntityPackets().registerMetaHandler().handle(e -> {
Metadata data = e.getData();
if (data.getMetaType().getType().equals(Type.ITEM)) // Is Item
data.setValue(handleItemToClient((Item) data.getValue()));
return data;
});
protocol.registerIncoming(ServerboundPackets1_9_3.CLIENT_STATUS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Action ID
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
// Open Inventory
if (wrapper.get(Type.VAR_INT, 0) == 2) {
wrapper.cancel();
}
}
});
}
});
}
}
@@ -0,0 +1,48 @@
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.viaversion.libs.gson.JsonArray;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.gson.JsonPrimitive;
public class ChatItemRewriter {
public static void toClient(JsonElement element, UserConnection user) {
if (element instanceof JsonObject) {
JsonObject obj = (JsonObject) element;
if (obj.has("hoverEvent")) {
if (obj.get("hoverEvent") instanceof JsonObject) {
JsonObject hoverEvent = (JsonObject) obj.get("hoverEvent");
if (hoverEvent.has("action") && hoverEvent.has("value")) {
String type = hoverEvent.get("action").getAsString();
if (type.equals("show_item") || type.equals("show_entity")) {
JsonElement value = hoverEvent.get("value");
if (value.isJsonArray()) {
JsonArray newArray = new JsonArray();
int index = 0;
for (JsonElement valueElement : value.getAsJsonArray()) {
if (valueElement.isJsonPrimitive() && valueElement.getAsJsonPrimitive().isString()) {
String newValue = index + ":" + valueElement.getAsString();
newArray.add(new JsonPrimitive(newValue));
}
}
hoverEvent.add("value", newArray);
}
}
}
}
} else if (obj.has("extra")) {
toClient(obj.get("extra"), user);
}
} else if (element instanceof JsonArray) {
JsonArray array = (JsonArray) element;
for (JsonElement value : array) {
toClient(value, user);
}
}
}
}
@@ -8,52 +8,51 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.packets;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.rewriters.Rewriter;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.data.AdvancementTranslations;
import us.myles.ViaVersion.api.PacketWrapper;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data.AdvancementTranslations;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.gson.JsonParser;
import java.util.Map;
public class ChatPackets1_12 extends Rewriter<Protocol1_11_1To1_12> {
public ChatPackets1_12(Protocol1_11_1To1_12 protocol) {
super(protocol);
}
@Override
protected void registerPackets(Protocol1_11_1To1_12 protocol) {
// Chat Message (ClientBound)
protocol.registerOutgoing(State.PLAY, 0x0F, 0x0F, new PacketRemapper() {
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_12.CHAT_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Json Data
map(Type.BYTE); // 1 - Position
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
JsonParser parser = new JsonParser();
try {
JsonObject object = parser.parse(wrapper.get(Type.STRING, 0)).getAsJsonObject();
handler(wrapper -> {
try {
JsonObject object = GsonUtil.getJsonParser().parse(wrapper.get(Type.STRING, 0)).getAsJsonObject();
// Skip if the root doesn't contain translate
if (object.has("translate")) {
handleTranslations(object);
}
// Skip if the root doesn't contain translate
if (object.has("translate"))
handleTranslations(object);
wrapper.set(Type.STRING, 0, object.toString());
} catch (Exception e) {
// Only print if ViaVer debug is enabled
if (Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().severe("Failed to handle translations");
e.printStackTrace();
}
ChatItemRewriter.toClient(object, wrapper.user());
wrapper.set(Type.STRING, 0, object.toString());
} catch (Exception e) {
// Only print if ViaVer debug is enabled
if (Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().severe("Failed to handle translations");
e.printStackTrace();
}
}
});
@@ -62,17 +61,20 @@ public class ChatPackets1_12 extends Rewriter<Protocol1_11_1To1_12> {
}
// TODO improve this, not copying will cause ConcurrentModificationException
// improve this, not copying will cause ConcurrentModificationException
public void handleTranslations(JsonObject object) {
JsonObject copiedObj = copy(object);
if (object.isJsonObject()) {
for (Map.Entry<String, JsonElement> entry : copiedObj.entrySet()) {
// Get the text that doesn't exist for 1.11 <
if (entry.getKey().equalsIgnoreCase("translate") && AdvancementTranslations.has(entry.getValue().getAsString())) {
String trans = entry.getValue().getAsString();
object.remove("translate");
object.addProperty("translate", AdvancementTranslations.get(trans));
if (entry.getKey().equalsIgnoreCase("translate")) {
String translate = entry.getValue().getAsString();
String text = AdvancementTranslations.get(translate);
if (text != null) {
object.addProperty("translate", text);
}
}
// Handle arrays
if (entry.getValue().isJsonArray())
@@ -97,10 +99,4 @@ public class ChatPackets1_12 extends Rewriter<Protocol1_11_1To1_12> {
}
return result;
}
@Override
protected void registerRewrites() {
}
}
@@ -0,0 +1,308 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.rewriters.LegacyEntityRewriter;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data.ParrotStorage;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data.ShoulderTracker;
import nl.matsv.viabackwards.utils.Block;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.entities.Entity1_12Types;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_12;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_12;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import java.util.Optional;
public class EntityPackets1_12 extends LegacyEntityRewriter<Protocol1_11_1To1_12> {
public EntityPackets1_12(Protocol1_11_1To1_12 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_12.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.BYTE); // 2 - Type
map(Type.DOUBLE); // 3 - x
map(Type.DOUBLE); // 4 - y
map(Type.DOUBLE); // 5 - z
map(Type.BYTE); // 6 - Pitch
map(Type.BYTE); // 7 - Yaw
map(Type.INT); // 8 - data
// Track Entity
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> Entity1_12Types.ObjectType.findById(id).orElse(null)));
// Handle FallingBlock blocks
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Optional<Entity1_12Types.ObjectType> type = Entity1_12Types.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == Entity1_12Types.ObjectType.FALLING_BLOCK) {
int objectData = wrapper.get(Type.INT, 0);
int objType = objectData & 4095;
int data = objectData >> 12 & 15;
Block block = getProtocol().getBlockItemPackets().handleBlock(objType, data);
if (block == null) {
return;
}
wrapper.set(Type.INT, 0, block.getId() | block.getData() << 12);
}
}
});
}
});
registerExtraTracker(ClientboundPackets1_12.SPAWN_EXPERIENCE_ORB, Entity1_12Types.EntityType.EXPERIENCE_ORB);
registerExtraTracker(ClientboundPackets1_12.SPAWN_GLOBAL_ENTITY, Entity1_12Types.EntityType.WEATHER);
protocol.registerOutgoing(ClientboundPackets1_12.SPAWN_MOB, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.VAR_INT); // 2 - Entity Type
map(Type.DOUBLE); // 3 - X
map(Type.DOUBLE); // 4 - Y
map(Type.DOUBLE); // 5 - Z
map(Type.BYTE); // 6 - Yaw
map(Type.BYTE); // 7 - Pitch
map(Type.BYTE); // 8 - Head Pitch
map(Type.SHORT); // 9 - Velocity X
map(Type.SHORT); // 10 - Velocity Y
map(Type.SHORT); // 11 - Velocity Z
map(Types1_12.METADATA_LIST); // 12 - Metadata
// Track entity
handler(getTrackerHandler());
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_12.METADATA_LIST));
}
});
registerExtraTracker(ClientboundPackets1_12.SPAWN_PAINTING, Entity1_12Types.EntityType.PAINTING);
protocol.registerOutgoing(ClientboundPackets1_12.SPAWN_PLAYER, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Player UUID
map(Type.DOUBLE); // 2 - X
map(Type.DOUBLE); // 3 - Y
map(Type.DOUBLE); // 4 - Z
map(Type.BYTE); // 5 - Yaw
map(Type.BYTE); // 6 - Pitch
map(Types1_12.METADATA_LIST); // 7 - Metadata list
handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, Entity1_12Types.EntityType.PLAYER));
}
});
protocol.registerOutgoing(ClientboundPackets1_12.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(getTrackerHandler(Entity1_12Types.EntityType.PLAYER, Type.INT));
handler(getDimensionHandler(1));
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ShoulderTracker tracker = wrapper.user().get(ShoulderTracker.class);
tracker.setEntityId(wrapper.get(Type.INT, 0));
}
});
// Send fake inventory achievement
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
PacketWrapper wrapper = new PacketWrapper(0x07, null, packetWrapper.user());
wrapper.write(Type.VAR_INT, 1);
wrapper.write(Type.STRING, "achievement.openInventory");
wrapper.write(Type.VAR_INT, 1);
wrapper.send(Protocol1_11_1To1_12.class);
}
});
}
});
registerRespawn(ClientboundPackets1_12.RESPAWN);
registerEntityDestroy(ClientboundPackets1_12.DESTROY_ENTITIES);
registerMetadataRewriter(ClientboundPackets1_12.ENTITY_METADATA, Types1_12.METADATA_LIST);
protocol.registerOutgoing(ClientboundPackets1_12.ENTITY_PROPERTIES, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.INT);
handler(wrapper -> {
int size = wrapper.get(Type.INT, 0);
int newSize = size;
for (int i = 0; i < size; i++) {
String key = wrapper.read(Type.STRING);
// Remove new attribute
if (key.equals("generic.flyingSpeed")) {
newSize--;
wrapper.read(Type.DOUBLE);
int modSize = wrapper.read(Type.VAR_INT);
for (int j = 0; j < modSize; j++) {
wrapper.read(Type.UUID);
wrapper.read(Type.DOUBLE);
wrapper.read(Type.BYTE);
}
} else {
wrapper.write(Type.STRING, key);
wrapper.passthrough(Type.DOUBLE);
int modSize = wrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < modSize; j++) {
wrapper.passthrough(Type.UUID);
wrapper.passthrough(Type.DOUBLE);
wrapper.passthrough(Type.BYTE);
}
}
}
if (newSize != size) {
wrapper.set(Type.INT, 0, newSize);
}
});
}
});
}
@Override
protected void registerRewrites() {
mapEntity(Entity1_12Types.EntityType.PARROT, Entity1_12Types.EntityType.BAT).mobName("Parrot").spawnMetadata(storage -> storage.add(new Metadata(12, MetaType1_12.Byte, (byte) 0x00)));
mapEntity(Entity1_12Types.EntityType.ILLUSION_ILLAGER, Entity1_12Types.EntityType.EVOCATION_ILLAGER).mobName("Illusioner");
// Handle Illager
registerMetaHandler().filter(Entity1_12Types.EntityType.EVOCATION_ILLAGER, true, 12).removed();
registerMetaHandler().filter(Entity1_12Types.EntityType.EVOCATION_ILLAGER, true, 13).handleIndexChange(12);
registerMetaHandler().filter(Entity1_12Types.EntityType.ILLUSION_ILLAGER, 0).handle(e -> {
byte mask = (byte) e.getData().getValue();
if ((mask & 0x20) == 0x20)
mask &= ~0x20;
e.getData().setValue(mask);
return e.getData();
});
// Create Parrot storage
registerMetaHandler().filter(Entity1_12Types.EntityType.PARROT, true).handle(e -> {
if (!e.getEntity().has(ParrotStorage.class))
e.getEntity().put(new ParrotStorage());
return e.getData();
});
// Parrot remove animal metadata
registerMetaHandler().filter(Entity1_12Types.EntityType.PARROT, 12).removed(); // Is baby
registerMetaHandler().filter(Entity1_12Types.EntityType.PARROT, 13).handle(e -> {
Metadata data = e.getData();
ParrotStorage storage = e.getEntity().get(ParrotStorage.class);
boolean isSitting = (((byte) data.getValue()) & 0x01) == 0x01;
boolean isTamed = (((byte) data.getValue()) & 0x04) == 0x04;
if (!storage.isTamed() && isTamed) {
// TODO do something to let the user know it's done
}
storage.setTamed(isTamed);
if (isSitting) {
data.setId(12);
data.setValue((byte) 0x01);
storage.setSitting(true);
} else if (storage.isSitting()) {
data.setId(12);
data.setValue((byte) 0x00);
storage.setSitting(false);
} else
throw RemovedValueException.EX;
return data;
}); // Flags (Is sitting etc, might be useful in the future
registerMetaHandler().filter(Entity1_12Types.EntityType.PARROT, 14).removed(); // Owner
registerMetaHandler().filter(Entity1_12Types.EntityType.PARROT, 15).removed(); // Variant
// Left shoulder entity data
registerMetaHandler().filter(Entity1_12Types.EntityType.PLAYER, 15).handle(e -> {
CompoundTag tag = (CompoundTag) e.getData().getValue();
ShoulderTracker tracker = e.getUser().get(ShoulderTracker.class);
if (tag.isEmpty() && tracker.getLeftShoulder() != null) {
tracker.setLeftShoulder(null);
tracker.update();
} else if (tag.contains("id") && e.getEntity().getEntityId() == tracker.getEntityId()) {
String id = (String) tag.get("id").getValue();
if (tracker.getLeftShoulder() == null || !tracker.getLeftShoulder().equals(id)) {
tracker.setLeftShoulder(id);
tracker.update();
}
}
throw RemovedValueException.EX;
});
// Right shoulder entity data
registerMetaHandler().filter(Entity1_12Types.EntityType.PLAYER, 16).handle(e -> {
CompoundTag tag = (CompoundTag) e.getData().getValue();
ShoulderTracker tracker = e.getUser().get(ShoulderTracker.class);
if (tag.isEmpty() && tracker.getRightShoulder() != null) {
tracker.setRightShoulder(null);
tracker.update();
} else if (tag.contains("id") && e.getEntity().getEntityId() == tracker.getEntityId()) {
String id = (String) tag.get("id").getValue();
if (tracker.getRightShoulder() == null || !tracker.getRightShoulder().equals(id)) {
tracker.setRightShoulder(id);
tracker.update();
}
}
throw RemovedValueException.EX;
});
}
@Override
protected EntityType getTypeFromId(int typeId) {
return Entity1_12Types.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
return Entity1_12Types.getTypeFromId(typeId, true);
}
}
@@ -8,21 +8,25 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.packets;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.packets;
import nl.matsv.viabackwards.api.rewriters.SoundRewriter;
import nl.matsv.viabackwards.protocol.protocol1_12to1_11_1.Protocol1_11_1To1_12;
import nl.matsv.viabackwards.api.rewriters.LegacySoundRewriter;
import nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
public class SoundPackets1_12 extends LegacySoundRewriter<Protocol1_11_1To1_12> {
public SoundPackets1_12(Protocol1_11_1To1_12 protocol) {
super(protocol);
}
public class SoundPackets1_12 extends SoundRewriter<Protocol1_11_1To1_12> {
@Override
protected void registerPackets(Protocol1_11_1To1_12 protocol) {
// Named sound effect
protocol.registerOutgoing(State.PLAY, 0x19, 0x19, new PacketRemapper() {
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_12.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Sound name
@@ -35,8 +39,7 @@ public class SoundPackets1_12 extends SoundRewriter<Protocol1_11_1To1_12> {
}
});
// Sound effect
protocol.registerOutgoing(State.PLAY, 0x48, 0x46, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_12.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Sound name
@@ -52,13 +55,15 @@ public class SoundPackets1_12 extends SoundRewriter<Protocol1_11_1To1_12> {
public void handle(PacketWrapper wrapper) throws Exception {
int oldId = wrapper.get(Type.VAR_INT, 0);
int newId = handleSounds(oldId);
if (newId == -1)
if (newId == -1) {
wrapper.cancel();
else {
if (hasPitch(oldId))
wrapper.set(Type.FLOAT, 1, handlePitch(oldId));
wrapper.set(Type.VAR_INT, 0, newId);
return;
}
if (hasPitch(oldId)) {
wrapper.set(Type.FLOAT, 1, handlePitch(oldId));
}
wrapper.set(Type.VAR_INT, 0, newId);
}
});
}
@@ -10,35 +10,46 @@
package nl.matsv.viabackwards.protocol.protocol1_11to1_11_1;
import lombok.Getter;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.packets.EntityPackets1_11_1;
import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.packets.ItemPackets1_11_1;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
@Getter
public class Protocol1_11To1_11_1 extends BackwardsProtocol {
public class Protocol1_11To1_11_1 extends BackwardsProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
private EntityPackets1_11_1 entityPackets;
public Protocol1_11To1_11_1() {
super(ClientboundPackets1_9_3.class, ClientboundPackets1_9_3.class, ServerboundPackets1_9_3.class, ServerboundPackets1_9_3.class);
}
@Override
protected void registerPackets() {
(entityPackets = new EntityPackets1_11_1()).register(this);
new ItemPackets1_11_1().register(this);
(entityPackets = new EntityPackets1_11_1(this)).register();
new ItemPackets1_11_1(this).register();
}
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class))
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
}
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class))
if (!user.has(EntityTracker.class)) {
user.put(new EntityTracker(user));
}
// Init protocol in EntityTracker
user.get(EntityTracker.class).initProtocol(this);
}
public EntityPackets1_11_1 getEntityPackets() {
return entityPackets;
}
}
@@ -10,31 +10,24 @@
package nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.packets;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import nl.matsv.viabackwards.api.entities.types.AbstractEntityType;
import nl.matsv.viabackwards.api.rewriters.EntityRewriter;
import nl.matsv.viabackwards.api.rewriters.LegacyEntityRewriter;
import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.entities.Entity1_11Types;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import java.util.Optional;
public class EntityPackets1_11_1 extends LegacyEntityRewriter<Protocol1_11To1_11_1> {
import static nl.matsv.viabackwards.api.entities.types.EntityType1_11.*;
public class EntityPackets1_11_1 extends EntityRewriter<Protocol1_11To1_11_1> {
public EntityPackets1_11_1(Protocol1_11To1_11_1 protocol) {
super(protocol);
}
@Override
protected void registerPackets(Protocol1_11To1_11_1 protocol) {
// Spawn Object
protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
@@ -48,83 +41,15 @@ public class EntityPackets1_11_1 extends EntityRewriter<Protocol1_11To1_11_1> {
map(Type.INT); // 8 - data
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
getTypeFromId(wrapper.get(Type.BYTE, 0), true)
);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Optional<ObjectType> type = ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent()) {
Optional<EntityData> optEntDat = getObjectData(type.get());
if (optEntDat.isPresent()) {
EntityData data = optEntDat.get();
wrapper.set(Type.BYTE, 0, ((Integer) data.getReplacementId()).byteValue());
if (data.getObjectData() != -1)
wrapper.set(Type.INT, 0, data.getObjectData());
}
} else {
if (Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Could not find Entity Type" + wrapper.get(Type.BYTE, 0));
}
}
}
});
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> Entity1_11Types.ObjectType.findById(id).orElse(null)));
}
});
// Spawn Experience Orb
protocol.registerOutgoing(State.PLAY, 0x01, 0x01, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, Entity1_11Types.EntityType.EXPERIENCE_ORB);
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, Entity1_11Types.EntityType.WEATHER);
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
ObjectType.THROWN_EXP_BOTTLE.getType()
);
}
});
}
});
// Spawn Global Entity
protocol.registerOutgoing(State.PLAY, 0x02, 0x02, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.BYTE); // 1 - Type
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.WEATHER // Always thunder according to wiki.vg
);
}
});
}
});
// Spawn Mob
protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_MOB, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
@@ -142,119 +67,18 @@ public class EntityPackets1_11_1 extends EntityRewriter<Protocol1_11To1_11_1> {
map(Types1_9.METADATA_LIST); // 12 - Metadata
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
getTypeFromId(wrapper.get(Type.VAR_INT, 1), false)
);
}
});
handler(getTrackerHandler());
// Rewrite entity type / metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = wrapper.get(Type.VAR_INT, 0);
AbstractEntityType type = getEntityType(wrapper.user(), entityId);
MetaStorage storage = new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0));
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
storage
);
Optional<EntityData> optEntDat = getEntityData(type);
if (optEntDat.isPresent()) {
EntityData data = optEntDat.get();
wrapper.set(Type.VAR_INT, 1, data.getReplacementId());
if (data.hasBaseMeta())
data.getDefaultMeta().handle(storage);
}
// Rewrite Metadata
wrapper.set(
Types1_9.METADATA_LIST,
0,
storage.getMetaDataList()
);
}
});
handler(getMobSpawnRewriter(Types1_9.METADATA_LIST));
}
});
// Spawn Painting
protocol.registerOutgoing(State.PLAY, 0x04, 0x04, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_PAINTING, Entity1_11Types.EntityType.PAINTING);
registerJoinGame(ClientboundPackets1_9_3.JOIN_GAME, Entity1_11Types.EntityType.PLAYER);
registerRespawn(ClientboundPackets1_9_3.RESPAWN);
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.PAINTING
);
}
});
}
});
// Join game
protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.INT, 0),
EntityType.PLAYER
);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Respawn Packet (save dimension id)
protocol.registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Dimension ID
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 0);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Spawn Player
protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_PLAYER, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
@@ -266,83 +90,30 @@ public class EntityPackets1_11_1 extends EntityRewriter<Protocol1_11To1_11_1> {
map(Type.BYTE); // 6 - Pitch
map(Types1_9.METADATA_LIST); // 7 - Metadata list
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
EntityType.PLAYER
);
}
});
// Rewrite Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0))
).getMetaDataList()
);
}
});
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, Entity1_11Types.EntityType.PLAYER));
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x30, 0x30, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity IDS
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
getEntityTracker(wrapper.user()).removeEntity(entity);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x39, 0x39, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_9.METADATA_LIST); // 1 - Metadata list
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
new MetaStorage(wrapper.get(Types1_9.METADATA_LIST, 0))
).getMetaDataList()
);
}
});
}
});
registerEntityDestroy(ClientboundPackets1_9_3.DESTROY_ENTITIES);
registerMetadataRewriter(ClientboundPackets1_9_3.ENTITY_METADATA, Types1_9.METADATA_LIST);
}
@Override
protected void registerRewrites() {
// Handle non-existing firework metadata (index 7 entity id for boosting)
registerMetaHandler().filter(EntityType.FIREWORK, 7).removed();
registerMetaHandler().filter(Entity1_11Types.EntityType.FIREWORK, 7).removed();
// Handle non-existing pig metadata (index 14 - boost time)
registerMetaHandler().filter(EntityType.PIG, 14).removed();
registerMetaHandler().filter(Entity1_11Types.EntityType.PIG, 14).removed();
}
@Override
protected EntityType getTypeFromId(int typeId) {
return Entity1_11Types.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
return Entity1_11Types.getTypeFromId(typeId, true);
}
}
@@ -10,76 +10,39 @@
package nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.packets;
import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter;
import nl.matsv.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import nl.matsv.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
import nl.matsv.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag;
public class ItemPackets1_11_1 extends BlockItemRewriter<Protocol1_11To1_11_1> {
public class ItemPackets1_11_1 extends LegacyBlockItemRewriter<Protocol1_11To1_11_1> {
private LegacyEnchantmentRewriter enchantmentRewriter;
public ItemPackets1_11_1(Protocol1_11To1_11_1 protocol) {
super(protocol);
}
@Override
protected void registerPackets(Protocol1_11To1_11_1 protocol) {
// Set slot packet
protocol.registerOutgoing(State.PLAY, 0x16, 0x16, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM); // 2 - Slot Value
protected void registerPackets() {
ItemRewriter itemRewriter = new ItemRewriter(protocol, this::handleItemToClient, this::handleItemToServer);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0);
wrapper.set(Type.ITEM, 0, handleItemToClient(stack));
}
});
}
});
// Window items packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x14, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.ITEM_ARRAY); // 1 - Window Values
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0);
for (int i = 0; i < stacks.length; i++)
stacks[i] = handleItemToClient(stacks[i]);
}
});
}
});
// Entity Equipment Packet
protocol.registerOutgoing(State.PLAY, 0x3C, 0x3C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.VAR_INT); // 1 - Slot ID
map(Type.ITEM); // 2 - Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0);
wrapper.set(Type.ITEM, 0, handleItemToClient(stack));
}
});
}
});
itemRewriter.registerSetSlot(ClientboundPackets1_9_3.SET_SLOT, Type.ITEM);
itemRewriter.registerWindowItems(ClientboundPackets1_9_3.WINDOW_ITEMS, Type.ITEM_ARRAY);
itemRewriter.registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT, Type.ITEM);
// Plugin message Packet -> Trading
protocol.registerOutgoing(State.PLAY, 0x18, 0x18, new PacketRemapper() {
protocol.registerOutgoing(ClientboundPackets1_9_3.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Channel
@@ -90,14 +53,15 @@ public class ItemPackets1_11_1 extends BlockItemRewriter<Protocol1_11To1_11_1> {
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.BYTE);
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem)
if (secondItem) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
@@ -109,52 +73,16 @@ public class ItemPackets1_11_1 extends BlockItemRewriter<Protocol1_11To1_11_1> {
}
});
// Click window packet
protocol.registerIncoming(State.PLAY, 0x07, 0x07, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
}
});
}
}
);
// Creative Inventory Action
protocol.registerIncoming(State.PLAY, 0x18, 0x18, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT); // 0 - Slot
map(Type.ITEM); // 1 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
}
});
}
}
);
itemRewriter.registerClickWindow(ServerboundPackets1_9_3.CLICK_WINDOW, Type.ITEM);
itemRewriter.registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION, Type.ITEM);
// Handle item metadata
protocol.getEntityPackets().registerMetaHandler().handle(e -> {
Metadata data = e.getData();
if (data.getMetaType().getType().equals(Type.ITEM)) // Is Item
if (data.getMetaType().getType().equals(Type.ITEM)) { // Is Item
data.setValue(handleItemToClient((Item) data.getValue()));
}
return data;
});
@@ -162,6 +90,41 @@ public class ItemPackets1_11_1 extends BlockItemRewriter<Protocol1_11To1_11_1> {
@Override
protected void registerRewrites() {
rewrite(452).repItem(new Item((short) 265, (byte) 1, (short) 0, getNamedTag("1.11.2 Iron Nugget")));
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName);
enchantmentRewriter.registerEnchantment(22, "§7Sweeping Edge");
}
@Override
public Item handleItemToClient(final Item item) {
if (item == null) return null;
super.handleItemToClient(item);
CompoundTag tag = item.getTag();
if (tag == null) return item;
if (tag.get("ench") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, false);
}
if (tag.get("StoredEnchantments") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, true);
}
return item;
}
@Override
public Item handleItemToServer(final Item item) {
if (item == null) return null;
super.handleItemToServer(item);
CompoundTag tag = item.getTag();
if (tag == null) return item;
if (tag.contains(nbtTagName + "|ench")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(nbtTagName + "|StoredEnchantments")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, true);
}
return item;
}
}
@@ -8,14 +8,28 @@
* 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 nl.matsv.viabackwards.utils;
package nl.matsv.viabackwards.protocol.protocol1_12_1to1_12_2;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
public class ItemUtil {
public class KeepAliveTracker extends StoredObject {
private long keepAlive = Integer.MAX_VALUE;
public static Item copyItem(Item item) {
if (item == null) return null;
return new Item(item.getId(), item.getAmount(), item.getData(), item.getTag() != null ? item.getTag().clone() : null);
public KeepAliveTracker(UserConnection user) {
super(user);
}
public long getKeepAlive() {
return keepAlive;
}
public void setKeepAlive(long keepAlive) {
this.keepAlive = keepAlive;
}
@Override
public String toString() {
return "KeepAliveTracker{" + "keepAlive=" + keepAlive + '}';
}
}
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_1to1_12_2;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
public class Protocol1_12_1To1_12_2 extends BackwardsProtocol<ClientboundPackets1_12_1, ClientboundPackets1_12_1, ServerboundPackets1_12_1, ServerboundPackets1_12_1> {
public Protocol1_12_1To1_12_2() {
super(ClientboundPackets1_12_1.class, ClientboundPackets1_12_1.class, ServerboundPackets1_12_1.class, ServerboundPackets1_12_1.class);
}
@Override
protected void registerPackets() {
registerOutgoing(ClientboundPackets1_12_1.KEEP_ALIVE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
Long keepAlive = packetWrapper.read(Type.LONG);
packetWrapper.user().get(KeepAliveTracker.class).setKeepAlive(keepAlive);
packetWrapper.write(Type.VAR_INT, keepAlive.hashCode());
}
});
}
});
registerIncoming(ServerboundPackets1_12_1.KEEP_ALIVE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
int keepAlive = packetWrapper.read(Type.VAR_INT);
long realKeepAlive = packetWrapper.user().get(KeepAliveTracker.class).getKeepAlive();
if (keepAlive != Long.hashCode(realKeepAlive)) {
packetWrapper.cancel(); // Wrong data, cancel packet
return;
}
packetWrapper.write(Type.LONG, realKeepAlive);
// Reset KeepAliveTracker (to prevent sending same valid value in a row causing a timeout)
packetWrapper.user().get(KeepAliveTracker.class).setKeepAlive(Integer.MAX_VALUE);
}
});
}
});
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new KeepAliveTracker(userConnection));
}
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 withregisterOutgoing restriction, including withregisterOutgoing 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", WITHregisterOutgoing 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, registerOutgoing OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
import nl.matsv.viabackwards.api.rewriters.TranslatableRewriter;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.BackwardsMappings;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.PaintingMapping;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.BlockItemPackets1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.EntityPackets1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.PlayerPacket1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.SoundPackets1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.PlayerPositionStorage1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.TabCompleteStorage;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.viaversion.libs.gson.JsonObject;
public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_13, ClientboundPackets1_12_1, ServerboundPackets1_13, ServerboundPackets1_12_1> {
private BlockItemPackets1_13 blockItemPackets;
public Protocol1_12_2To1_13() {
super(ClientboundPackets1_13.class, ClientboundPackets1_12_1.class, ServerboundPackets1_13.class, ServerboundPackets1_12_1.class);
}
@Override
protected void registerPackets() {
executeAsyncAfterLoaded(Protocol1_13To1_12_2.class, () -> {
BackwardsMappings.init();
PaintingMapping.init();
Via.getManager().getProviders().register(BackwardsBlockEntityProvider.class, new BackwardsBlockEntityProvider());
});
TranslatableRewriter translatableRewriter = new TranslatableRewriter(this) {
@Override
protected void handleTranslate(JsonObject root, String translate) {
String newTranslate = newTranslatables.get(translate);
if (newTranslate != null || (newTranslate = BackwardsMappings.translateMappings.get(translate)) != null) {
root.addProperty("translate", newTranslate);
}
}
};
translatableRewriter.registerPing();
translatableRewriter.registerBossBar(ClientboundPackets1_13.BOSSBAR);
translatableRewriter.registerChatMessage(ClientboundPackets1_13.CHAT_MESSAGE);
translatableRewriter.registerLegacyOpenWindow(ClientboundPackets1_13.OPEN_WINDOW);
translatableRewriter.registerDisconnect(ClientboundPackets1_13.DISCONNECT);
translatableRewriter.registerCombatEvent(ClientboundPackets1_13.COMBAT_EVENT);
translatableRewriter.registerTitle(ClientboundPackets1_13.TITLE);
translatableRewriter.registerTabList(ClientboundPackets1_13.TAB_LIST);
(blockItemPackets = new BlockItemPackets1_13(this)).register();
new EntityPackets1_13(this).register();
new PlayerPacket1_13(this).register();
new SoundPackets1_13(this).register();
cancelOutgoing(ClientboundPackets1_13.DECLARE_COMMANDS); //TODO
cancelOutgoing(ClientboundPackets1_13.NBT_QUERY);
cancelOutgoing(ClientboundPackets1_13.CRAFT_RECIPE_RESPONSE);
cancelOutgoing(ClientboundPackets1_13.UNLOCK_RECIPES);
cancelOutgoing(ClientboundPackets1_13.ADVANCEMENTS);
cancelOutgoing(ClientboundPackets1_13.DECLARE_RECIPES);
cancelOutgoing(ClientboundPackets1_13.TAGS);
cancelIncoming(ServerboundPackets1_12_1.CRAFT_RECIPE_REQUEST);
cancelIncoming(ServerboundPackets1_12_1.RECIPE_BOOK_DATA);
}
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
}
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class)) {
user.put(new EntityTracker(user));
}
// Init protocol in EntityTracker
user.get(EntityTracker.class).initProtocol(this);
// Register Block Storage
if (!user.has(BackwardsBlockStorage.class)) {
user.put(new BackwardsBlockStorage(user));
}
// Register Block Storage
if (!user.has(TabCompleteStorage.class)) {
user.put(new TabCompleteStorage(user));
}
if (ViaBackwards.getConfig().isFix1_13FacePlayer() && !user.has(PlayerPositionStorage1_13.class)) {
user.put(new PlayerPositionStorage1_13(user));
}
}
public BlockItemPackets1_13 getBlockItemPackets() {
return blockItemPackets;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.IntTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.ListTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
public class BannerHandler implements BackwardsBlockEntityHandler {
private static final int WALL_BANNER_START = 7110; // 4 each
private static final int WALL_BANNER_STOP = 7173;
private static final int BANNER_START = 6854; // 16 each
private static final int BANNER_STOP = 7109;
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
// Normal banners
if (blockId >= BANNER_START && blockId <= BANNER_STOP) {
int color = (blockId - BANNER_START) >> 4;
tag.put(new IntTag("Base", (15 - color)));
}
// Wall banners
else if (blockId >= WALL_BANNER_START && blockId <= WALL_BANNER_STOP) {
int color = (blockId - WALL_BANNER_START) >> 2;
tag.put(new IntTag("Base", (15 - color)));
} else {
ViaBackwards.getPlatform().getLogger().warning("Why does this block have the banner block entity? :(" + tag);
}
// Invert colors
Tag patternsTag = tag.get("Patterns");
if (patternsTag instanceof ListTag) {
for (Tag pattern : (ListTag) patternsTag) {
if (!(pattern instanceof CompoundTag)) continue;
IntTag c = ((CompoundTag) pattern).get("Color");
c.setValue(15 - c.getValue()); // Invert color id
}
}
return tag;
}
}
@@ -8,25 +8,22 @@
* 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 nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets;
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.IntTag;
public class ChangedPackets1_10 {
public class BedHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
public void register(BackwardsProtocol protocol) {
/* ServerBound packets */
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
int offset = blockId - 748;
int color = offset >> 4;
// ResourcePack status
protocol.registerIncoming(State.PLAY, 0x16, 0x16, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING, Type.NOTHING); // 0 - Hash
map(Type.VAR_INT); // 1 - Result
}
});
tag.put(new IntTag("color", color));
return tag;
}
}
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectMap;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.IntTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
public class FlowerPotHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
private static final Int2ObjectMap<Pair<String, Byte>> FLOWERS = new Int2ObjectOpenHashMap<>(22, 1F);
private static final Pair<String, Byte> AIR = new Pair<>("minecraft:air", (byte) 0);
static {
FLOWERS.put(5265, AIR);
register(5266, "minecraft:sapling", (byte) 0);
register(5267, "minecraft:sapling", (byte) 1);
register(5268, "minecraft:sapling", (byte) 2);
register(5269, "minecraft:sapling", (byte) 3);
register(5270, "minecraft:sapling", (byte) 4);
register(5271, "minecraft:sapling", (byte) 5);
register(5272, "minecraft:tallgrass", (byte) 2);
register(5273, "minecraft:yellow_flower", (byte) 0);
register(5274, "minecraft:red_flower", (byte) 0);
register(5275, "minecraft:red_flower", (byte) 1);
register(5276, "minecraft:red_flower", (byte) 2);
register(5277, "minecraft:red_flower", (byte) 3);
register(5278, "minecraft:red_flower", (byte) 4);
register(5279, "minecraft:red_flower", (byte) 5);
register(5280, "minecraft:red_flower", (byte) 6);
register(5281, "minecraft:red_flower", (byte) 7);
register(5282, "minecraft:red_flower", (byte) 8);
register(5283, "minecraft:red_mushroom", (byte) 0);
register(5284, "minecraft:brown_mushroom", (byte) 0);
register(5285, "minecraft:deadbush", (byte) 0);
register(5286, "minecraft:cactus", (byte) 0);
}
private static void register(int id, String identifier, byte data) {
FLOWERS.put(id, new Pair<>(identifier, data));
}
public static boolean isFlowah(int id) {
return id >= 5265 && id <= 5286;
}
public Pair<String, Byte> getOrDefault(int blockId) {
Pair<String, Byte> pair = FLOWERS.get(blockId);
return pair != null ? pair : AIR;
}
// TODO THIS IS NEVER CALLED BECAUSE ITS NO LONGER A BLOCK ENTITY :(
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
Pair<String, Byte> item = getOrDefault(blockId);
tag.put(new StringTag("Item", item.getKey()));
tag.put(new IntTag("Data", item.getValue()));
return tag;
}
}
@@ -0,0 +1,100 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.BackwardsMappings;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.IntTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
public class PistonHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
private final Map<String, Integer> pistonIds = new HashMap<>();
public PistonHandler() {
if (Via.getConfig().isServersideBlockConnections()) {
Map<String, Integer> keyToId;
try {
Field field = ConnectionData.class.getDeclaredField("keyToId");
field.setAccessible(true);
keyToId = (Map<String, Integer>) field.get(null);
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
return;
}
for (Map.Entry<String, Integer> entry : keyToId.entrySet()) {
if (!entry.getKey().contains("piston")) continue;
addEntries(entry.getKey(), entry.getValue());
}
} else {
JsonObject mappings = MappingDataLoader.getMappingsCache().get("mapping-1.13.json").getAsJsonObject("blocks");
for (Map.Entry<String, JsonElement> blockState : mappings.entrySet()) {
String key = blockState.getValue().getAsString();
if (!key.contains("piston")) continue;
addEntries(key, Integer.parseInt(blockState.getKey()));
}
}
}
// There doesn't seem to be a nicer way around it :(
private void addEntries(String data, int id) {
id = BackwardsMappings.blockMappings.getNewId(id);
pistonIds.put(data, id);
String substring = data.substring(10);
if (!substring.startsWith("piston") && !substring.startsWith("sticky_piston")) return;
// Swap properties and add them to the map
String[] split = data.substring(0, data.length() - 1).split("\\[");
String[] properties = split[1].split(",");
data = split[0] + "[" + properties[1] + "," + properties[0] + "]";
pistonIds.put(data, id);
}
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
CompoundTag blockState = tag.get("blockState");
String dataFromTag = getDataFromTag(blockState);
if (dataFromTag == null) return tag;
Integer id = pistonIds.get(dataFromTag);
if (id == null) {
//TODO see why this could be null and if this is bad
return tag;
}
tag.put(new IntTag("blockId", id >> 4));
tag.put(new IntTag("blockData", id & 15));
return tag;
}
// The type hasn't actually been updated in the blockstorage, so we need to construct it
private String getDataFromTag(CompoundTag tag) {
StringTag name = tag.get("Name");
if (name == null) return null;
CompoundTag properties = tag.get("Properties");
if (properties == null) return name.getValue();
StringJoiner joiner = new StringJoiner(",", name.getValue() + "[", "]");
for (Tag property : properties) {
if (!(property instanceof StringTag)) continue;
joiner.add(property.getName() + "=" + ((StringTag) property).getValue());
}
return joiner.toString();
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.viaversion.libs.opennbt.tag.builtin.ByteTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
public class SkullHandler implements BackwardsBlockEntityHandler {
private static final int SKULL_START = 5447;
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
int diff = blockId - SKULL_START;
int pos = diff % 20;
byte type = (byte) Math.floor(diff / 20f);
// Set type
tag.put(new ByteTag("SkullType", type));
// Remove wall skulls
if (pos < 4) {
return tag;
}
// Add rotation for normal skulls
tag.put(new ByteTag("Rot", (byte) ((pos - 4) & 255)));
return tag;
}
}
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.EntityNameRewrites;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.Tag;
public class SpawnerHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
Tag dataTag = tag.get("SpawnData");
if (dataTag instanceof CompoundTag) {
CompoundTag data = (CompoundTag) dataTag;
Tag idTag = data.get("id");
if (idTag instanceof StringTag) {
StringTag s = (StringTag) idTag;
s.setValue(EntityNameRewrites.rewrite(s.getValue()));
}
}
return tag;
}
}
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.data.VBItemMappings;
import nl.matsv.viabackwards.api.data.VBMappingDataLoader;
import nl.matsv.viabackwards.api.data.VBMappings;
import nl.matsv.viabackwards.api.data.VBSoundMappings;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.StatisticMappings;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectMap;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import us.myles.viaversion.libs.gson.JsonPrimitive;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class BackwardsMappings {
public static final Int2ObjectMap<String> statisticMappings = new Int2ObjectOpenHashMap<>();
public static final Map<String, String> translateMappings = new HashMap<>();
public static BlockMappingsShortArray blockMappings;
public static VBSoundMappings soundMappings;
public static VBItemMappings itemMappings;
public static Mappings enchantmentMappings;
public static void init() {
ViaBackwards.getPlatform().getLogger().info("Loading 1.13 -> 1.12.2 mappings...");
JsonObject mapping1_12 = MappingDataLoader.getMappingsCache().get("mapping-1.12.json");
JsonObject mapping1_13 = MappingDataLoader.getMappingsCache().get("mapping-1.13.json");
JsonObject mapping1_12_2to1_13 = VBMappingDataLoader.loadFromDataDir("mapping-1.12.2to1.13.json");
blockMappings = new BlockMappingsShortArray(mapping1_13.getAsJsonObject("blocks"), mapping1_12.getAsJsonObject("blocks"), mapping1_12_2to1_13.getAsJsonObject("blockstates"));
itemMappings = new VBItemMappings(mapping1_13.getAsJsonObject("items"), mapping1_12.getAsJsonObject("items"), mapping1_12_2to1_13.getAsJsonObject("items"));
soundMappings = new VBSoundMappings(mapping1_13.getAsJsonArray("sounds"), mapping1_12.getAsJsonArray("sounds"), mapping1_12_2to1_13.getAsJsonObject("sounds"));
enchantmentMappings = new VBMappings(mapping1_13.getAsJsonObject("enchantments"), mapping1_12.getAsJsonObject("enchantments"), false);
for (Map.Entry<String, Integer> entry : StatisticMappings.statistics.entrySet()) {
statisticMappings.put(entry.getValue().intValue(), entry.getKey());
}
for (Map.Entry<String, String> entry : MappingData.translateMapping.entrySet()) {
translateMappings.put(entry.getValue(), entry.getKey());
}
}
// Has lots of compat layers, so we can't use the default Via method
private static void mapIdentifiers(short[] output, JsonObject newIdentifiers, JsonObject oldIdentifiers, JsonObject mapping) {
for (Map.Entry<String, JsonElement> entry : newIdentifiers.entrySet()) {
String key = entry.getValue().getAsString();
Map.Entry<String, JsonElement> value = MappingDataLoader.findValue(oldIdentifiers, key);
short hardId = -1;
if (value == null) {
JsonPrimitive replacement = mapping.getAsJsonPrimitive(key);
int propertyIndex;
if (replacement == null && (propertyIndex = key.indexOf('[')) != -1) {
replacement = mapping.getAsJsonPrimitive(key.substring(0, propertyIndex));
}
if (replacement != null) {
if (replacement.getAsString().startsWith("id:")) {
String id = replacement.getAsString().replace("id:", "");
hardId = Short.parseShort(id);
value = MappingDataLoader.findValue(oldIdentifiers, oldIdentifiers.getAsJsonPrimitive(id).getAsString());
} else {
value = MappingDataLoader.findValue(oldIdentifiers, replacement.getAsString());
}
}
if (value == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
if (replacement != null) {
ViaBackwards.getPlatform().getLogger().warning("No key for " + entry.getValue() + "/" + replacement.getAsString() + " :( ");
} else {
ViaBackwards.getPlatform().getLogger().warning("No key for " + entry.getValue() + " :( ");
}
}
continue;
}
}
output[Integer.parseInt(entry.getKey())] = hardId != -1 ? hardId : Short.parseShort(value.getKey());
}
}
public static class BlockMappingsShortArray {
private final short[] oldToNew = new short[8582];
private BlockMappingsShortArray(JsonObject newIdentifiers, JsonObject oldIdentifiers, JsonObject mapping) {
Arrays.fill(oldToNew, (short) -1);
mapIdentifiers(oldToNew, newIdentifiers, oldIdentifiers, mapping);
}
public int getNewId(int old) {
return old >= 0 && old < oldToNew.length ? oldToNew[old] : -1;
}
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data;
import java.util.HashMap;
import java.util.Map;
public class EntityNameRewrites {
private static final Map<String, String> ENTITY_NAMES = new HashMap<>();
static {
// CHANGED NAMES IN 1.13
reg("commandblock_minecart", "command_block_minecart");
reg("ender_crystal", "end_crystal");
reg("evocation_fangs", "evoker_fangs");
reg("evocation_illager", "evoker");
reg("eye_of_ender_signal", "eye_of_ender");
reg("fireworks_rocket", "firework_rocket");
reg("illusion_illager", "illusioner");
reg("snowman", "snow_golem");
reg("villager_golem", "iron_golem");
reg("vindication_illager", "vindicator");
reg("xp_bottle", "experience_bottle");
reg("xp_orb", "experience_orb");
}
private static void reg(String past, String future) {
ENTITY_NAMES.put("minecraft:" + future, "minecraft:" + past);
}
public static String rewrite(String entName) {
String entityName = ENTITY_NAMES.get(entName);
if (entityName != null) {
return entityName;
}
entityName = ENTITY_NAMES.get("minecraft:" + entName);
if (entityName != null) {
return entityName;
} else
return entName;
}
}
@@ -0,0 +1,29 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.EntityTypeRewriter;
import us.myles.viaversion.libs.fastutil.ints.Int2IntMap;
import us.myles.viaversion.libs.fastutil.ints.Int2IntOpenHashMap;
import java.lang.reflect.Field;
public class EntityTypeMapping {
private static final Int2IntMap TYPES = new Int2IntOpenHashMap();
static {
TYPES.defaultReturnValue(-1);
try {
Field field = EntityTypeRewriter.class.getDeclaredField("ENTITY_TYPES");
field.setAccessible(true);
Int2IntMap entityTypes = (Int2IntMap) field.get(null);
for (Int2IntMap.Entry entry : entityTypes.int2IntEntrySet()) {
EntityTypeMapping.TYPES.put(entry.getIntValue(), entry.getIntKey());
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
}
}
public static int getOldId(int type1_13) {
return TYPES.get(type1_13);
}
}
@@ -0,0 +1,26 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.NamedSoundRewriter;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class NamedSoundMapping {
private static final Map<String, String> SOUNDS = new HashMap<>();
static {
try {
Field field = NamedSoundRewriter.class.getDeclaredField("oldToNew");
field.setAccessible(true);
Map<String, String> sounds = (Map<String, String>) field.get(null);
sounds.forEach((sound1_12, sound1_13) -> NamedSoundMapping.SOUNDS.put(sound1_13, sound1_12));
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
}
}
public static String getOldId(String sound1_13) {
return SOUNDS.get(sound1_13);
}
}
@@ -0,0 +1,45 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectMap;
import us.myles.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
public class PaintingMapping {
private static final Int2ObjectMap<String> PAINTINGS = new Int2ObjectOpenHashMap<>(26, 1F);
public static void init() {
add("Kebab");
add("Aztec");
add("Alban");
add("Aztec2");
add("Bomb");
add("Plant");
add("Wasteland");
add("Pool");
add("Courbet");
add("Sea");
add("Sunset");
add("Creebet");
add("Wanderer");
add("Graham");
add("Match");
add("Bust");
add("Stage");
add("Void");
add("SkullAndRoses");
add("Wither");
add("Fighters");
add("Pointer");
add("Pigscene");
add("BurningSkull");
add("Skeleton");
add("DonkeyKong");
}
private static void add(String motive) {
PAINTINGS.put(PAINTINGS.size(), motive);
}
public static String getStringId(int id) {
return PAINTINGS.getOrDefault(id, "kebab");
}
}
@@ -0,0 +1,189 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.BlockItemPackets1_13;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import java.util.List;
public class ParticleMapping {
private static final ParticleData[] particles;
static {
ParticleHandler blockHandler = new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
return rewrite(wrapper.read(Type.VAR_INT));
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
return rewrite((int) data.get(0).getValue());
}
private int[] rewrite(int newType) {
int blockType = BlockItemPackets1_13.toOldId(newType);
int type = blockType >> 4;
int meta = blockType & 15;
return new int[]{type + (meta << 12)};
}
};
particles = new ParticleData[]{
rewrite(16), // (0->16) minecraft:ambient_entity_effect -> mobSpellAmbient
rewrite(20), // (1->20) minecraft:angry_villager -> angryVillager
rewrite(35), // (2->35) minecraft:barrier -> barrier
rewrite(37, blockHandler),
// (3->37) minecraft:block -> blockcrack
rewrite(4), // (4->4) minecraft:bubble -> bubble
rewrite(29), // (5->29) minecraft:cloud -> cloud
rewrite(9), // (6->9) minecraft:crit -> crit
rewrite(44), // (7->44) minecraft:damage_indicator -> damageIndicator‌
rewrite(42), // (8->42) minecraft:dragon_breath -> dragonbreath
rewrite(19), // (9->19) minecraft:dripping_lava -> dripLava
rewrite(18), // (10->18) minecraft:dripping_water -> dripWater
rewrite(30, new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
float r = wrapper.read(Type.FLOAT);
float g = wrapper.read(Type.FLOAT);
float b = wrapper.read(Type.FLOAT);
float scale = wrapper.read(Type.FLOAT);
wrapper.set(Type.FLOAT, 3, r); // 5 - Offset X index=3
wrapper.set(Type.FLOAT, 4, g); // 6 - Offset Y index=4
wrapper.set(Type.FLOAT, 5, b); // 7 - Offset Z index=5
wrapper.set(Type.FLOAT, 6, scale); // 8 - Particle Data index=6
wrapper.set(Type.INT, 1, 0); // 9 - Particle Count index=1 enable rgb particle
return null;
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
return null;
}
}), // (11->30) minecraft:dust -> reddust
rewrite(13), // (12->13) minecraft:effect -> spell
rewrite(41), // (13->41) minecraft:elder_guardian -> mobappearance
rewrite(10), // (14->10) minecraft:enchanted_hit -> magicCrit‌
rewrite(25), // (15->25) minecraft:enchant -> enchantmenttable
rewrite(43), // (16->43) minecraft:end_rod -> endRod
rewrite(15), // (17->15) minecraft:entity_effect -> mobSpell
rewrite(2), // (18->2) minecraft:explosion_emitter -> hugeexplosion
rewrite(1), // (19->1) minecraft:explosion -> largeexplode
rewrite(46, blockHandler),
// (20->46) minecraft:falling_dust -> fallingdust
rewrite(3), // (21->3) minecraft:firework -> fireworksSpark
rewrite(6), // (22->6) minecraft:fishing -> wake
rewrite(26), // (23->26) minecraft:flame -> flame
rewrite(21), // (24->21) minecraft:happy_villager -> happyVillager
rewrite(34), // (25->34) minecraft:heart -> heart
rewrite(14), // (26->14) minecraft:instant_effect -> instantSpell
rewrite(36, new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
return rewrite(protocol, wrapper.read(Type.FLAT_ITEM));
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
return rewrite(protocol, (Item) data.get(0).getValue());
}
private int[] rewrite(Protocol1_12_2To1_13 protocol, Item newItem) {
Item item = protocol.getBlockItemPackets().handleItemToClient(newItem);
return new int[]{item.getIdentifier(), item.getData()};
}
}), // (27->36) minecraft:item -> iconcrack
rewrite(33), // (28->33) minecraft:item_slime -> slime
rewrite(31), // (29->31) minecraft:item_snowball -> snowballpoof
rewrite(12), // (30->12) minecraft:large_smoke -> largesmoke
rewrite(27), // (31->27) minecraft:lava -> lava
rewrite(22), // (32->22) minecraft:mycelium -> townaura
rewrite(23), // (33->23) minecraft:note -> note
rewrite(0), // (34->0) minecraft:poof -> explode
rewrite(24), // (35->24) minecraft:portal -> portal
rewrite(39), // (36->39) minecraft:rain -> droplet
rewrite(11), // (37->11) minecraft:smoke -> smoke
rewrite(48), // (38->48) minecraft:spit -> spit
rewrite(12), // (39->-1) minecraft:squid_ink -> squid_ink -> large_smoke
rewrite(45), // (40->45) minecraft:sweep_attack -> sweepAttack‌
rewrite(47), // (41->47) minecraft:totem_of_undying -> totem
rewrite(7), // (42->7) minecraft:underwater -> suspended‌
rewrite(5), // (43->5) minecraft:splash -> splash
rewrite(17), // (44->17) minecraft:witch -> witchMagic
rewrite(4), // (45->4) minecraft:bubble_pop -> bubble
rewrite(4), // (46->4) minecraft:current_down -> bubble
rewrite(4), // (47->4) minecraft:bubble_column_up -> bubble
rewrite(18), // (48->-1) minecraft:nautilus -> nautilus -> dripWater
rewrite(18), // (49->18) minecraft:dolphin -> dripWater
};
}
public static ParticleData getMapping(int id) {
return particles[id];
}
private static ParticleData rewrite(int replacementId) {
return new ParticleData(replacementId);
}
private static ParticleData rewrite(int replacementId, ParticleHandler handler) {
return new ParticleData(replacementId, handler);
}
interface ParticleHandler {
int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception;
int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data);
}
public static final class ParticleData {
private final int historyId;
private final ParticleHandler handler;
private ParticleData(int historyId, ParticleHandler handler) {
this.historyId = historyId;
this.handler = handler;
}
private ParticleData(int historyId) {
this(historyId, null);
}
public int[] rewriteData(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
if (handler == null) return null;
return handler.rewrite(protocol, wrapper);
}
public int[] rewriteMeta(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
if (handler == null) return null;
return handler.rewrite(protocol, data);
}
public int getHistoryId() {
return historyId;
}
public ParticleHandler getHandler() {
return handler;
}
}
}
@@ -0,0 +1,411 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.entities.storage.EntityPositionHandler;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.rewriters.LegacyEntityRewriter;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.EntityTypeMapping;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.PaintingMapping;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.ParticleMapping;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.PlayerPositionStorage1_13;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.entities.Entity1_13Types;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_12;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.api.type.types.version.Types1_12;
import us.myles.ViaVersion.api.type.types.version.Types1_13;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import java.util.Optional;
public class EntityPackets1_13 extends LegacyEntityRewriter<Protocol1_12_2To1_13> {
public EntityPackets1_13(Protocol1_12_2To1_13 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_13.PLAYER_POSITION, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return;
PlayerPositionStorage1_13 playerStorage = wrapper.user().get(PlayerPositionStorage1_13.class);
byte bitField = wrapper.get(Type.BYTE, 0);
playerStorage.setX(toSet(bitField, 0, playerStorage.getX(), wrapper.get(Type.DOUBLE, 0)));
playerStorage.setY(toSet(bitField, 1, playerStorage.getY(), wrapper.get(Type.DOUBLE, 1)));
playerStorage.setZ(toSet(bitField, 2, playerStorage.getZ(), wrapper.get(Type.DOUBLE, 2)));
}
private double toSet(int field, int bitIndex, double origin, double packetValue) {
// If bit is set, coordinate is relative
return (field & (1 << bitIndex)) != 0 ? origin + packetValue : packetValue;
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.SPAWN_ENTITY, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.UUID);
map(Type.BYTE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.BYTE);
map(Type.BYTE);
map(Type.INT);
handler(getObjectTrackerHandler());
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Optional<Entity1_13Types.ObjectType> optionalType = Entity1_13Types.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (!optionalType.isPresent()) return;
Entity1_13Types.ObjectType type = optionalType.get();
if (type == Entity1_13Types.ObjectType.FALLING_BLOCK) {
int blockState = wrapper.get(Type.INT, 0);
int combined = BlockItemPackets1_13.toOldId(blockState);
combined = ((combined >> 4) & 0xFFF) | ((combined & 0xF) << 12);
wrapper.set(Type.INT, 0, combined);
} else if (type == Entity1_13Types.ObjectType.ITEM_FRAME) {
int data = wrapper.get(Type.INT, 0);
switch (data) {
case 3:
data = 0;
break;
case 4:
data = 1;
break;
case 5:
data = 3;
break;
}
wrapper.set(Type.INT, 0, data);
} else if (type == Entity1_13Types.ObjectType.TRIDENT) {
wrapper.set(Type.BYTE, 0, (byte) Entity1_13Types.ObjectType.TIPPED_ARROW.getId());
}
}
});
}
});
registerExtraTracker(ClientboundPackets1_13.SPAWN_EXPERIENCE_ORB, Entity1_13Types.EntityType.EXPERIENCE_ORB);
registerExtraTracker(ClientboundPackets1_13.SPAWN_GLOBAL_ENTITY, Entity1_13Types.EntityType.LIGHTNING_BOLT);
protocol.registerOutgoing(ClientboundPackets1_13.SPAWN_MOB, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.UUID);
map(Type.VAR_INT);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BYTE);
map(Type.SHORT);
map(Type.SHORT);
map(Type.SHORT);
map(Types1_13.METADATA_LIST, Types1_12.METADATA_LIST);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int type = wrapper.get(Type.VAR_INT, 1);
EntityType entityType = Entity1_13Types.getTypeFromId(type, false);
addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), entityType);
int oldId = EntityTypeMapping.getOldId(type);
if (oldId == -1) {
if (!hasData(entityType)) {
ViaBackwards.getPlatform().getLogger().warning("Could not find 1.12 entity type for 1.13 entity type " + type + "/" + entityType);
}
} else {
wrapper.set(Type.VAR_INT, 1, oldId);
}
}
});
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_12.METADATA_LIST));
}
});
protocol.registerOutgoing(ClientboundPackets1_13.SPAWN_PLAYER, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.UUID);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.BYTE);
map(Type.BYTE);
map(Types1_13.METADATA_LIST, Types1_12.METADATA_LIST);
handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, Entity1_13Types.EntityType.PLAYER));
}
});
protocol.registerOutgoing(ClientboundPackets1_13.SPAWN_PAINTING, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
map(Type.UUID);
handler(getTrackerHandler(Entity1_13Types.EntityType.PAINTING, Type.VAR_INT));
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int motive = wrapper.read(Type.VAR_INT);
String title = PaintingMapping.getStringId(motive);
wrapper.write(Type.STRING, title);
}
});
}
});
registerJoinGame(ClientboundPackets1_13.JOIN_GAME, Entity1_13Types.EntityType.PLAYER);
protocol.registerOutgoing(ClientboundPackets1_13.RESPAWN, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Dimension ID
handler(getDimensionHandler(0));
handler(wrapper -> wrapper.user().get(BackwardsBlockStorage.class).clear());
}
});
registerEntityDestroy(ClientboundPackets1_13.DESTROY_ENTITIES);
registerMetadataRewriter(ClientboundPackets1_13.ENTITY_METADATA, Types1_13.METADATA_LIST, Types1_12.METADATA_LIST);
// Face Player (new packet)
protocol.registerOutgoing(ClientboundPackets1_13.FACE_PLAYER, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel();
if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return;
// We will just accept a possible, very minor mismatch between server and client position,
// and will take the server's one in both cases, else we would have to cache all entities' positions.
final int anchor = wrapper.read(Type.VAR_INT); // feet/eyes enum
final double x = wrapper.read(Type.DOUBLE);
final double y = wrapper.read(Type.DOUBLE);
final double z = wrapper.read(Type.DOUBLE);
PlayerPositionStorage1_13 positionStorage = wrapper.user().get(PlayerPositionStorage1_13.class);
// Send teleport packet to client
PacketWrapper positionAndLook = wrapper.create(0x2F);
positionAndLook.write(Type.DOUBLE, 0D);
positionAndLook.write(Type.DOUBLE, 0D);
positionAndLook.write(Type.DOUBLE, 0D);
//TODO properly cache and calculate head position?
EntityPositionHandler.writeFacingDegrees(positionAndLook, positionStorage.getX(),
anchor == 1 ? positionStorage.getY() + 1.62 : positionStorage.getY(),
positionStorage.getZ(), x, y, z);
positionAndLook.write(Type.BYTE, (byte) 7); // bitfield, 0=absolute, 1=relative - x,y,z relative, yaw,pitch absolute
positionAndLook.write(Type.VAR_INT, -1);
positionAndLook.send(Protocol1_12_2To1_13.class, true, true);
}
});
}
});
if (ViaBackwards.getConfig().isFix1_13FacePlayer()) {
PacketRemapper movementRemapper = new PacketRemapper() {
@Override
public void registerMap() {
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
handler(wrapper -> wrapper.user().get(PlayerPositionStorage1_13.class).setCoordinates(wrapper, false));
}
};
protocol.registerIncoming(ServerboundPackets1_12_1.PLAYER_POSITION, movementRemapper); // Player Position
protocol.registerIncoming(ServerboundPackets1_12_1.PLAYER_POSITION_AND_ROTATION, movementRemapper); // Player Position And Look (serverbound)
protocol.registerIncoming(ServerboundPackets1_12_1.VEHICLE_MOVE, movementRemapper); // Vehicle Move (serverbound)
}
}
@Override
protected void registerRewrites() {
// Rewrite new Entity 'drowned'
mapEntity(Entity1_13Types.EntityType.DROWNED, Entity1_13Types.EntityType.ZOMBIE_VILLAGER).mobName("Drowned");
// Fishy
mapEntity(Entity1_13Types.EntityType.COD, Entity1_13Types.EntityType.SQUID).mobName("Cod");
mapEntity(Entity1_13Types.EntityType.SALMON, Entity1_13Types.EntityType.SQUID).mobName("Salmon");
mapEntity(Entity1_13Types.EntityType.PUFFERFISH, Entity1_13Types.EntityType.SQUID).mobName("Puffer Fish");
mapEntity(Entity1_13Types.EntityType.TROPICAL_FISH, Entity1_13Types.EntityType.SQUID).mobName("Tropical Fish");
// Phantom
mapEntity(Entity1_13Types.EntityType.PHANTOM, Entity1_13Types.EntityType.PARROT).mobName("Phantom").spawnMetadata(storage -> {
// The phantom is grey/blue so let's do yellow/blue
storage.add(new Metadata(15, MetaType1_12.VarInt, 3));
});
// Dolphin
mapEntity(Entity1_13Types.EntityType.DOLPHIN, Entity1_13Types.EntityType.SQUID).mobName("Dolphin");
// Turtle
mapEntity(Entity1_13Types.EntityType.TURTLE, Entity1_13Types.EntityType.OCELOT).mobName("Turtle");
// Rewrite Meta types
registerMetaHandler().handle(e -> {
Metadata meta = e.getData();
int typeId = meta.getMetaType().getTypeID();
// Rewrite optional chat to chat
if (typeId == 5) {
meta.setMetaType(MetaType1_12.String);
if (meta.getValue() == null) {
meta.setValue("");
}
}
// Rewrite items
else if (typeId == 6) {
meta.setMetaType(MetaType1_12.Slot);
Item item = (Item) meta.getValue();
meta.setValue(protocol.getBlockItemPackets().handleItemToClient(item));
}
// Discontinue particles
else if (typeId == 15) {
meta.setMetaType(MetaType1_12.Discontinued);
}
// Rewrite to 1.12 ids
else if (typeId > 5) {
meta.setMetaType(MetaType1_12.byId(
typeId - 1
));
}
return meta;
});
// Rewrite Custom Name from Chat to String
registerMetaHandler().filter(Entity1_13Types.EntityType.ENTITY, true, 2).handle(e -> {
Metadata meta = e.getData();
String value = (String) meta.getValue();
if (value.isEmpty()) return meta;
meta.setValue(ChatRewriter.jsonTextToLegacy(value));
return meta;
});
// Handle zombie metadata
registerMetaHandler().filter(Entity1_13Types.EntityType.ZOMBIE, true, 15).removed();
registerMetaHandler().filter(Entity1_13Types.EntityType.ZOMBIE, true).handle(e -> {
Metadata meta = e.getData();
if (meta.getId() > 15) {
meta.setId(meta.getId() - 1);
}
return meta;
});
// Handle turtle metadata (Remove them all for now)
registerMetaHandler().filter(Entity1_13Types.EntityType.TURTLE, 13).removed(); // Home pos
registerMetaHandler().filter(Entity1_13Types.EntityType.TURTLE, 14).removed(); // Has egg
registerMetaHandler().filter(Entity1_13Types.EntityType.TURTLE, 15).removed(); // Laying egg
registerMetaHandler().filter(Entity1_13Types.EntityType.TURTLE, 16).removed(); // Travel pos
registerMetaHandler().filter(Entity1_13Types.EntityType.TURTLE, 17).removed(); // Going home
registerMetaHandler().filter(Entity1_13Types.EntityType.TURTLE, 18).removed(); // Traveling
// Remove additional fish meta
registerMetaHandler().filter(Entity1_13Types.EntityType.ABSTRACT_FISHES, true, 12).removed();
registerMetaHandler().filter(Entity1_13Types.EntityType.ABSTRACT_FISHES, true, 13).removed();
// Remove phantom size
registerMetaHandler().filter(Entity1_13Types.EntityType.PHANTOM, 12).removed();
// Remove boat splash timer
registerMetaHandler().filter(Entity1_13Types.EntityType.BOAT, 12).removed();
// Remove Trident special loyalty level
registerMetaHandler().filter(Entity1_13Types.EntityType.TRIDENT, 7).removed();
// Handle new wolf colors
registerMetaHandler().filter(Entity1_13Types.EntityType.WOLF, 17).handle(e -> {
Metadata meta = e.getData();
meta.setValue(15 - (int) meta.getValue());
return meta;
});
// Rewrite AreaEffectCloud
registerMetaHandler().filter(Entity1_13Types.EntityType.AREA_EFFECT_CLOUD, 9).handle(e -> {
Metadata meta = e.getData();
Particle particle = (Particle) meta.getValue();
ParticleMapping.ParticleData data = ParticleMapping.getMapping(particle.getId());
int firstArg = 0;
int secondArg = 0;
int[] particleArgs = data.rewriteMeta(protocol, particle.getArguments());
if (particleArgs != null && particleArgs.length != 0) {
firstArg = particleArgs[0];
secondArg = particleArgs.length == 2 ? particleArgs[1] : 0;
}
e.createMeta(new Metadata(9, MetaType1_12.VarInt, data.getHistoryId()));
e.createMeta(new Metadata(10, MetaType1_12.VarInt, firstArg));
e.createMeta(new Metadata(11, MetaType1_12.VarInt, secondArg));
throw RemovedValueException.EX;
});
}
@Override
protected EntityType getTypeFromId(int typeId) {
return Entity1_13Types.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
return Entity1_13Types.getTypeFromId(typeId, true);
}
@Override
public int getOldEntityId(final int newId) {
return EntityTypeMapping.getOldId(newId);
}
}
@@ -0,0 +1,551 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets;
import com.google.common.base.Joiner;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.rewriters.Rewriter;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.BackwardsMappings;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.ParticleMapping;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.TabCompleteStorage;
import nl.matsv.viabackwards.utils.ChatUtil;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueCreator;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
public class PlayerPacket1_13 extends Rewriter<Protocol1_12_2To1_13> {
public PlayerPacket1_13(Protocol1_12_2To1_13 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
// Login Plugin Request
protocol.registerOutgoing(State.LOGIN, 0x04, -1, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
packetWrapper.cancel();
packetWrapper.create(0x02, new ValueCreator() { // Plugin response
@Override
public void write(PacketWrapper newWrapper) throws Exception {
newWrapper.write(Type.VAR_INT, packetWrapper.read(Type.VAR_INT)); // Packet id
newWrapper.write(Type.BOOLEAN, false); // Success
}
}).sendToServer(Protocol1_12_2To1_13.class);
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String channel = wrapper.read(Type.STRING);
if (channel.equals("minecraft:trader_list")) {
wrapper.write(Type.STRING, "MC|TrList");
wrapper.passthrough(Type.INT); //Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
//Input Item
Item input = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, getProtocol().getBlockItemPackets().handleItemToClient(input));
//Output Item
Item output = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, getProtocol().getBlockItemPackets().handleItemToClient(output));
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); //Has second item
if (secondItem) {
//Second Item
Item second = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, getProtocol().getBlockItemPackets().handleItemToClient(second));
}
wrapper.passthrough(Type.BOOLEAN); //Trade disabled
wrapper.passthrough(Type.INT); //Number of tools uses
wrapper.passthrough(Type.INT); //Maximum number of trade uses
}
} else {
String oldChannel = InventoryPackets.getOldPluginChannelId(channel);
if (oldChannel == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring outgoing plugin message with channel: " + channel);
}
wrapper.cancel();
return;
}
wrapper.write(Type.STRING, oldChannel);
if (oldChannel.equals("REGISTER") || oldChannel.equals("UNREGISTER")) {
String[] channels = new String(wrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (String s : channels) {
String rewritten = InventoryPackets.getOldPluginChannelId(s);
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in outgoing REGISTER: " + s);
}
}
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
}
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.SPAWN_PARTICLE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(Type.FLOAT); // 2 - X
map(Type.FLOAT); // 3 - Y
map(Type.FLOAT); // 4 - Z
map(Type.FLOAT); // 5 - Offset X
map(Type.FLOAT); // 6 - Offset Y
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ParticleMapping.ParticleData old = ParticleMapping.getMapping(wrapper.get(Type.INT, 0));
wrapper.set(Type.INT, 0, old.getHistoryId());
int[] data = old.rewriteData(protocol, wrapper);
if (data != null) {
for (int i : data)
wrapper.write(Type.VAR_INT, i);
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.PLAYER_INFO, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper packetWrapper) throws Exception {
TabCompleteStorage storage = packetWrapper.user().get(TabCompleteStorage.class);
int action = packetWrapper.passthrough(Type.VAR_INT);
int nPlayers = packetWrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < nPlayers; i++) {
UUID uuid = packetWrapper.passthrough(Type.UUID);
if (action == 0) { // Add
String name = packetWrapper.passthrough(Type.STRING);
storage.usernames.put(uuid, name);
int nProperties = packetWrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < nProperties; j++) {
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.STRING);
if (packetWrapper.passthrough(Type.BOOLEAN)) {
packetWrapper.passthrough(Type.STRING);
}
}
packetWrapper.passthrough(Type.VAR_INT);
packetWrapper.passthrough(Type.VAR_INT);
if (packetWrapper.passthrough(Type.BOOLEAN)) {
packetWrapper.passthrough(Type.STRING);
}
} else if (action == 1) { // Update Game Mode
packetWrapper.passthrough(Type.VAR_INT);
} else if (action == 2) { // Update Ping
packetWrapper.passthrough(Type.VAR_INT);
} else if (action == 3) { // Update Display Name
if (packetWrapper.passthrough(Type.BOOLEAN)) {
packetWrapper.passthrough(Type.STRING);
}
} else if (action == 4) { // Remove Player
storage.usernames.remove(uuid);
}
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.SCOREBOARD_OBJECTIVE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
map(Type.BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
byte mode = wrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) {
String value = wrapper.read(Type.STRING);
value = ChatRewriter.jsonTextToLegacy(value);
if (value.length() > 32) value = value.substring(0, 32);
wrapper.write(Type.STRING, value);
int type = wrapper.read(Type.VAR_INT);
wrapper.write(Type.STRING, type == 1 ? "hearts" : "integer");
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.TEAMS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
map(Type.BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
byte action = wrapper.get(Type.BYTE, 0);
if (action == 0 || action == 2) {
String displayName = wrapper.read(Type.STRING);
displayName = ChatRewriter.jsonTextToLegacy(displayName);
displayName = ChatUtil.removeUnusedColor(displayName, 'f');
if (displayName.length() > 32) displayName = displayName.substring(0, 32);
wrapper.write(Type.STRING, displayName);
byte flags = wrapper.read(Type.BYTE);
String nameTagVisibility = wrapper.read(Type.STRING);
String collisionRule = wrapper.read(Type.STRING);
int colour = wrapper.read(Type.VAR_INT);
if (colour == 21) {
colour = -1;
}
String prefix = wrapper.read(Type.STRING);
String suffix = wrapper.read(Type.STRING);
prefix = prefix == null || prefix.equals("null") ? "" : ChatRewriter.jsonTextToLegacy(prefix);
if (ViaBackwards.getConfig().addTeamColorTo1_13Prefix()) {
prefix += "§" + (colour > -1 && colour <= 15 ? Integer.toHexString(colour) : "r");
}
prefix = ChatUtil.removeUnusedColor(prefix, 'f', true);
if (prefix.length() > 16) prefix = prefix.substring(0, 16);
if (prefix.endsWith("§")) prefix = prefix.substring(0, prefix.length() - 1);
suffix = suffix == null || suffix.equals("null") ? "" : ChatRewriter.jsonTextToLegacy(suffix);
suffix = ChatUtil.removeUnusedColor(suffix, 'f');
if (suffix.length() > 16) suffix = suffix.substring(0, 16);
if (suffix.endsWith("§")) suffix = suffix.substring(0, suffix.length() - 1);
wrapper.write(Type.STRING, prefix);
wrapper.write(Type.STRING, suffix);
wrapper.write(Type.BYTE, flags);
wrapper.write(Type.STRING, nameTagVisibility);
wrapper.write(Type.STRING, collisionRule);
wrapper.write(Type.BYTE, (byte) colour);
}
if (action == 0 || action == 3 || action == 4) {
wrapper.passthrough(Type.STRING_ARRAY); //Entities
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.TAB_COMPLETE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
TabCompleteStorage storage = wrapper.user().get(TabCompleteStorage.class);
if (storage.lastRequest == null) {
wrapper.cancel();
return;
}
if (storage.lastId != wrapper.read(Type.VAR_INT)) wrapper.cancel();
int start = wrapper.read(Type.VAR_INT);
int length = wrapper.read(Type.VAR_INT);
int lastRequestPartIndex = storage.lastRequest.lastIndexOf(' ') + 1;
if (lastRequestPartIndex != start) wrapper.cancel(); // Client only replaces after space
if (length != storage.lastRequest.length() - lastRequestPartIndex) {
wrapper.cancel(); // We can't set the length in previous versions
}
int count = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < count; i++) {
String match = wrapper.read(Type.STRING);
wrapper.write(Type.STRING, (start == 0 && !storage.lastAssumeCommand ? "/" : "") + match);
// Ignore tooltip
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.STRING);
}
}
}
});
}
});
protocol.registerIncoming(ServerboundPackets1_12_1.TAB_COMPLETE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
TabCompleteStorage storage = wrapper.user().get(TabCompleteStorage.class);
int id = ThreadLocalRandom.current().nextInt();
wrapper.write(Type.VAR_INT, id);
String command = wrapper.read(Type.STRING);
boolean assumeCommand = wrapper.read(Type.BOOLEAN);
wrapper.read(Type.OPTIONAL_POSITION);
if (!assumeCommand) {
if (command.startsWith("/")) {
command = command.substring(1);
} else {
wrapper.cancel();
PacketWrapper response = wrapper.create(0xE);
List<String> usernames = new ArrayList<>();
for (String value : storage.usernames.values()) {
if (value.toLowerCase().startsWith(command.substring(command.lastIndexOf(' ') + 1).toLowerCase())) {
usernames.add(value);
}
}
response.write(Type.VAR_INT, usernames.size());
for (String value : usernames) {
response.write(Type.STRING, value);
}
response.send(protocol.getClass());
}
}
wrapper.write(Type.STRING, command);
storage.lastId = id;
storage.lastAssumeCommand = assumeCommand;
storage.lastRequest = command;
});
}
});
protocol.registerIncoming(ServerboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
String channel = wrapper.read(Type.STRING);
switch (channel) {
case "MC|BSign":
case "MC|BEdit":
wrapper.setId(0x0B);
Item book = wrapper.read(Type.ITEM);
wrapper.write(Type.FLAT_ITEM, getProtocol().getBlockItemPackets().handleItemToServer(book));
boolean signing = channel.equals("MC|BSign");
wrapper.write(Type.BOOLEAN, signing);
break;
case "MC|ItemName":
wrapper.setId(0x1C);
break;
case "MC|AdvCmd":
byte type = wrapper.read(Type.BYTE);
if (type == 0) {
//Information from https://wiki.vg/index.php?title=Plugin_channels&oldid=14089
//The Notchain client only uses this for command block minecarts and uses MC|AutoCmd for blocks, but the Notchian server still accepts it for either.
//Maybe older versions used this and we need to implement this? The issues is that we would have to save the command block types
wrapper.setId(0x22);
wrapper.cancel();
ViaBackwards.getPlatform().getLogger().warning("Client send MC|AdvCmd custom payload to update command block, weird!");
} else if (type == 1) {
wrapper.setId(0x23);
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT)); //Entity Id
wrapper.passthrough(Type.STRING); //Command
wrapper.passthrough(Type.BOOLEAN); //Track Output
} else {
wrapper.cancel();
}
break;
case "MC|AutoCmd": {
wrapper.setId(0x22);
int x = wrapper.read(Type.INT);
int y = wrapper.read(Type.INT);
int z = wrapper.read(Type.INT);
wrapper.write(Type.POSITION, new Position(x, (short) y, z));
wrapper.passthrough(Type.STRING); //Command
byte flags = 0;
if (wrapper.read(Type.BOOLEAN)) flags |= 0x01; //Track Output
String mode = wrapper.read(Type.STRING);
int modeId = mode.equals("SEQUENCE") ? 0 : mode.equals("AUTO") ? 1 : 2;
wrapper.write(Type.VAR_INT, modeId);
if (wrapper.read(Type.BOOLEAN)) flags |= 0x02; //Is conditional
if (wrapper.read(Type.BOOLEAN)) flags |= 0x04; //Automatic
wrapper.write(Type.BYTE, flags);
break;
}
case "MC|Struct": {
wrapper.setId(0x25);
int x = wrapper.read(Type.INT);
int y = wrapper.read(Type.INT);
int z = wrapper.read(Type.INT);
wrapper.write(Type.POSITION, new Position(x, (short) y, z));
wrapper.write(Type.VAR_INT, wrapper.read(Type.BYTE) - 1);
String mode = wrapper.read(Type.STRING);
int modeId = mode.equals("SAVE") ? 0 : mode.equals("LOAD") ? 1 : mode.equals("CORNER") ? 2 : 3;
wrapper.write(Type.VAR_INT, modeId);
wrapper.passthrough(Type.STRING); //Name
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue()); //Offset X
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue()); //Offset Y
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue()); //Offset Z
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue()); //Size X
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue()); //Size Y
wrapper.write(Type.BYTE, wrapper.read(Type.INT).byteValue()); //Size Z
String mirror = wrapper.read(Type.STRING);
int mirrorId = mode.equals("NONE") ? 0 : mode.equals("LEFT_RIGHT") ? 1 : 2;
String rotation = wrapper.read(Type.STRING);
int rotationId = mode.equals("NONE") ? 0 : mode.equals("CLOCKWISE_90") ? 1 : mode.equals("CLOCKWISE_180") ? 2 : 3;
wrapper.passthrough(Type.STRING); //Metadata
byte flags = 0;
if (wrapper.read(Type.BOOLEAN)) flags |= 0x01; //Ignore entities
if (wrapper.read(Type.BOOLEAN)) flags |= 0x02; //Show air
if (wrapper.read(Type.BOOLEAN)) flags |= 0x04; //Show bounding box
wrapper.passthrough(Type.FLOAT); //Integrity
wrapper.passthrough(Type.VAR_LONG); //Seed
wrapper.write(Type.BYTE, flags);
break;
}
case "MC|Beacon":
wrapper.setId(0x20);
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT)); //Primary Effect
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT)); //Secondary Effect
break;
case "MC|TrSel":
wrapper.setId(0x1F);
wrapper.write(Type.VAR_INT, wrapper.read(Type.INT)); //Slot
break;
case "MC|PickItem":
wrapper.setId(0x15);
break;
default:
String newChannel = InventoryPackets.getNewPluginChannelId(channel);
if (newChannel == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring incoming plugin message with channel: " + channel);
}
wrapper.cancel();
return;
}
wrapper.write(Type.STRING, newChannel);
if (newChannel.equals("minecraft:register") || newChannel.equals("minecraft:unregister")) {
String[] channels = new String(wrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (String s : channels) {
String rewritten = InventoryPackets.getNewPluginChannelId(s);
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in incoming REGISTER: " + s);
}
}
if (!rewrittenChannels.isEmpty()) {
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
} else {
wrapper.cancel();
return;
}
}
break;
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.STATISTICS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int size = wrapper.get(Type.VAR_INT, 0);
int newSize = size;
for (int i = 0; i < size; i++) {
int categoryId = wrapper.read(Type.VAR_INT);
int statisticId = wrapper.read(Type.VAR_INT);
String name = "";
// categories 0-7 (items, blocks, entities) - probably not feasible
switch (categoryId) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
wrapper.read(Type.VAR_INT); // remove value
newSize--;
continue;
case 8:
name = BackwardsMappings.statisticMappings.get(statisticId);
if (name == null) {
wrapper.read(Type.VAR_INT);
newSize--;
continue;
}
break;
}
wrapper.write(Type.STRING, name); // string id
wrapper.passthrough(Type.VAR_INT); // value
}
if (newSize != size) {
wrapper.set(Type.VAR_INT, 0, newSize);
}
}
});
}
});
}
}
@@ -0,0 +1,85 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.rewriters.Rewriter;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.BackwardsMappings;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.NamedSoundMapping;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
public class SoundPackets1_13 extends Rewriter<Protocol1_12_2To1_13> {
private static final String[] SOUND_SOURCES = {"master", "music", "record", "weather", "block", "hostile", "neutral", "player", "ambient", "voice"};
public SoundPackets1_13(Protocol1_12_2To1_13 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_13.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
handler(wrapper -> {
String newSound = wrapper.get(Type.STRING, 0);
String oldSound = NamedSoundMapping.getOldId(newSound);
if (oldSound != null || (oldSound = BackwardsMappings.soundMappings.getNewId(newSound)) != null) {
wrapper.set(Type.STRING, 0, oldSound);
} else if (!Via.getConfig().isSuppressConversionWarnings()) {
ViaBackwards.getPlatform().getLogger().warning("Unknown named sound in 1.13->1.12 protocol: " + newSound);
}
});
}
});
// Stop Sound -> Plugin Message
protocol.registerOutgoing(ClientboundPackets1_13.STOP_SOUND, ClientboundPackets1_12_1.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
wrapper.write(Type.STRING, "MC|StopSound");
byte flags = wrapper.read(Type.BYTE);
String source;
if ((flags & 0x01) != 0) {
source = SOUND_SOURCES[wrapper.read(Type.VAR_INT)];
} else {
source = "";
}
String sound;
if ((flags & 0x02) != 0) {
sound = BackwardsMappings.soundMappings.getNewId(wrapper.read(Type.STRING));
if (sound == null) {
sound = "";
}
} else {
sound = "";
}
wrapper.write(Type.STRING, source);
wrapper.write(Type.STRING, sound);
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT);
handler(wrapper -> {
int newSound = wrapper.get(Type.VAR_INT, 0);
int oldSound = BackwardsMappings.soundMappings.getNewId(newSound);
if (oldSound == -1) {
wrapper.cancel();
} else {
wrapper.set(Type.VAR_INT, 0, oldSound);
}
});
}
});
}
}
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers.*;
import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.platform.providers.Provider;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.IntTag;
import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag;
import java.util.HashMap;
import java.util.Map;
public class BackwardsBlockEntityProvider implements Provider {
private final Map<String, BackwardsBlockEntityProvider.BackwardsBlockEntityHandler> handlers = new HashMap<>();
public BackwardsBlockEntityProvider() {
handlers.put("minecraft:flower_pot", new FlowerPotHandler()); // TODO requires special treatment, manually send
handlers.put("minecraft:bed", new BedHandler());
handlers.put("minecraft:banner", new BannerHandler());
handlers.put("minecraft:skull", new SkullHandler());
handlers.put("minecraft:mob_spawner", new SpawnerHandler());
handlers.put("minecraft:piston", new PistonHandler());
}
/**
* Check if a block entity handler is present
*
* @param key Id of the NBT data ex: minecraft:bed
* @return true if present
*/
public boolean isHandled(String key) {
return handlers.containsKey(key);
}
/**
* Transform blocks to block entities!
*
* @param user The user
* @param position The position of the block entity
* @param tag The block entity tag
*/
public CompoundTag transform(UserConnection user, Position position, CompoundTag tag) throws Exception {
String id = (String) tag.get("id").getValue();
BackwardsBlockEntityHandler handler = handlers.get(id);
if (handler == null) {
if (Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Unhandled BlockEntity " + id + " full tag: " + tag);
}
return tag;
}
BackwardsBlockStorage storage = user.get(BackwardsBlockStorage.class);
Integer blockId = storage.get(position);
if (blockId == null) {
if (Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Handled BlockEntity does not have a stored block :( " + id + " full tag: " + tag);
}
return tag;
}
return handler.transform(user, blockId, tag);
}
/**
* Transform blocks to block entities!
*
* @param user The user
* @param position The position of the block entity
* @param id The block entity id
*/
public CompoundTag transform(UserConnection user, Position position, String id) throws Exception {
CompoundTag tag = new CompoundTag("");
tag.put(new StringTag("id", id));
tag.put(new IntTag("x", Math.toIntExact(position.getX())));
tag.put(new IntTag("y", Math.toIntExact(position.getY())));
tag.put(new IntTag("z", Math.toIntExact(position.getZ())));
return this.transform(user, position, tag);
}
public interface BackwardsBlockEntityHandler {
CompoundTag transform(UserConnection user, int blockId, CompoundTag tag);
}
}
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2016 Matsv
*
* 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 nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.viaversion.libs.fastutil.ints.IntOpenHashSet;
import us.myles.viaversion.libs.fastutil.ints.IntSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class BackwardsBlockStorage extends StoredObject {
// This BlockStorage is very exclusive (;
private static final IntSet WHITELIST = new IntOpenHashSet(779);
static {
// Flower pots
for (int i = 5265; i <= 5286; i++) {
WHITELIST.add(i);
}
// Add those beds
for (int i = 0; i < (16 * 16); i++) {
WHITELIST.add(748 + i);
}
// Add the banners
for (int i = 6854; i <= 7173; i++) {
WHITELIST.add(i);
}
// Spawner
WHITELIST.add(1647);
// Skulls
for (int i = 5447; i <= 5566; i++) {
WHITELIST.add(i);
}
// pistons
for (int i = 1028; i <= 1039; i++) {
WHITELIST.add(i);
}
for (int i = 1047; i <= 1082; i++) {
WHITELIST.add(i);
}
for (int i = 1099; i <= 1110; i++) {
WHITELIST.add(i);
}
}
private final Map<Position, Integer> blocks = new ConcurrentHashMap<>();
public BackwardsBlockStorage(UserConnection user) {
super(user);
}
public void checkAndStore(Position position, int block) {
if (!WHITELIST.contains(block)) {
// Remove if not whitelisted
blocks.remove(position);
return;
}
blocks.put(position, block);
}
public boolean isWelcome(int block) {
return WHITELIST.contains(block);
}
public Integer get(Position position) {
return blocks.get(position);
}
public int remove(Position position) {
return blocks.remove(position);
}
public void clear() {
blocks.clear();
}
public Map<Position, Integer> getBlocks() {
return blocks;
}
}
@@ -0,0 +1,11 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage;
import nl.matsv.viabackwards.api.entities.storage.PlayerPositionStorage;
import us.myles.ViaVersion.api.data.UserConnection;
public class PlayerPositionStorage1_13 extends PlayerPositionStorage {
public PlayerPositionStorage1_13(UserConnection user) {
super(user);
}
}
@@ -0,0 +1,19 @@
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class TabCompleteStorage extends StoredObject {
public int lastId;
public String lastRequest;
public boolean lastAssumeCommand;
public Map<UUID, String> usernames = new HashMap<>();
public TabCompleteStorage(UserConnection user) {
super(user);
}
}
Loaded 100 of 167 files, more files were not shown because too many files have changed in this diff. Show more