Compare commits

...
560 Commits
Author SHA1 Message Date
KennyTV 2a118acf77 3.1.1 Release, 1.16.3 support 2020-09-09 15:48:26 +02:00
KennyTV ececd96718 Workaround pre 1.16.2 MC-68487
Fixes #255
2020-09-03 00:17:41 +02:00
KennyTV e9ace2dd6b Fix mapping loading on Sponge
Fixes #257
2020-09-02 10:11:36 +02:00
KennyTV c72f8f766d *Actually* don't cast the ping description 2020-08-24 13:02:16 +02:00
KennyTV 1b89327d84 Don't cast the ping description 2020-08-24 13:01:22 +02:00
KennyTV 8a8c1a33a6 Check if block entity id tag is present 2020-08-20 20:37:02 +02:00
KennyTV 761249d39f Fix 1.16.2 type mapping
Fixes ViaVersion/ViaVersion#2021
2020-08-20 11:16:16 +02:00
DoctorMacc e03da34f55 Don't assume CanPlaceOn tag is ListTag
I guess somewhere in my testing I made a CanPlaceOn tag that was a byte value and the client disconnected on me when I put ViaBackwards on my testing instance. This commit doesn't translate the CanPlaceOn tag if it isn't a ListTag.
2020-08-17 08:58:14 +02:00
KennyTV 03ec04cc8d Process motd description rgb colors
Fixes ViaVersion/ViaVersion#1999
2020-08-16 10:50:22 +02:00
KennyTV f387899dab Fix chain mappings 2020-08-13 17:53:31 +02:00
KennyTV ce49daa300 Rewrite custom stats ids 2020-08-13 13:59:23 +02:00
KennyTV 249a720cee Fix wrong clientpackettype 2020-08-12 22:37:34 +02:00
KennyTV fa59cbcc01 Update VV usage 2020-08-12 22:35:34 +02:00
KennyTV 803c24f4d3 Rewrite item/block/entity ids in statistics 2020-08-12 22:32:19 +02:00
KennyTV 5e19a5af33 Back to snapshot 2020-08-12 16:34:39 +02:00
KennyTV 8911f1eb94 Don't cancel 1.16.2 multi block change packets
Tfw the logic works but you do a stupid, different error for the same packet on two different projects
2020-08-11 21:37:26 +02:00
KennyTV 6f0bd98be2 3.1.0 Release 2020-08-11 08:50:33 +02:00
KennyTV e325a03c0a Fix effects value 2020-08-10 22:03:05 +02:00
KennyTV b9317df859 Use effects data to determine legacy dimension, cleanup ClientWorld usage 2020-08-10 21:21:10 +02:00
KennyTV 11bb1349e9 Compare to correct tag in lore processing 2020-08-10 18:03:46 +02:00
KennyTV 6289e9317d Remove casting in display saving
Fixes #246
2020-08-09 21:59:37 +02:00
KennyTV 2d9d67bcb2 Merge branch 'master' into dev 2020-08-08 09:15:59 +02:00
KennyTV 62fd868130 Update issue template 2020-08-08 09:15:31 +02:00
KennyTV b2b8c48fd0 Eliminate full copying/saving of item tags
This unnecessarily stores a hell of a lot of unneeded data and heavily accumulates the more versions the pipeline goes down to.
2020-08-07 10:07:39 +02:00
KennyTV 9f9d05d3c6 1.16.2-pre3 2020-08-06 20:23:22 +02:00
KennyTV 6e01a0affd 1.16.2-pre2 2020-08-05 18:23:23 +02:00
KennyTV d6d6307550 Map netherite tools and armor to diamond
Addresses #243
2020-08-05 10:41:37 +02:00
KennyTV 1afdf0fb81 Process player info entries with 1.16->1.15 color correction 2020-07-30 15:43:34 +02:00
KennyTV fd529ce967 Properly implement color diff
Semi fixes #239
2020-07-30 15:22:27 +02:00
KennyTV c5ba1864d1 1.16.2-Pre1 2020-07-29 17:27:13 +02:00
KennyTV 831b8ad5ad Don't remove white chatcolor in 1.13->1.12 suffix
Fixes #236
2020-07-26 09:28:06 +02:00
KennyTV 58256b5b64 *moonwalks out* 2020-07-22 21:53:35 +02:00
KennyTV d209e9b768 20w30a, bump version to match VV's 2020-07-22 21:52:48 +02:00
KennyTV 61b1f0d8a4 More reciperewriter cleanup 2020-07-15 11:49:33 +02:00
KennyTV 2748624dde Write default registry for 1.16/1.16.1 clients
Actually processing the monster that is the .2 registry would be unreasonable, and there shouldn't be any reason to keep using those two versions (and not -1.15.2 or +1.16.2)
2020-07-11 22:29:19 +02:00
KennyTV d5b19b8869 Merge branch 'master' into dev 2020-07-09 17:10:45 +02:00
KennyTV 650f89e1ce Don't send air block break particles to sub 1.12 players
Fixes #227
2020-07-09 17:10:31 +02:00
KennyTV 00172ee675 Fix vindicator meta casting
Fixes #226
2020-07-09 14:55:52 +02:00
KennyTV 45aab8f9f2 Map biomes 2020-07-09 14:40:54 +02:00
KennyTV 1e455b0391 20w28a 2020-07-09 13:26:33 +02:00
KennyTV 59cb67da6e Fix empty json in 1.14->1.13 items 2020-07-06 15:06:01 +02:00
KennyTV 6b96e1a8e2 Fix 1.12->1.11 title json null
Fixes #217
2020-07-06 14:57:14 +02:00
KennyTV 5ef94d94e6 Rewrite item nbt attributes 2020-07-02 16:00:17 +02:00
KennyTV a59c384884 Send dummy respawn on same dimension switch 2020-07-02 13:20:49 +02:00
KennyTV 7638d678bb Move RecipeRewriter to VV, cleanup advancements+trade list 2020-07-02 00:26:44 +02:00
KennyTV f3c30130d2 20w27a 2020-07-01 22:32:35 +02:00
KennyTV bb583065f3 Cleanup some tag rewriting 2020-06-30 21:16:19 +02:00
KennyTV f5bb30559d Make map data type read consistent 2020-06-30 17:09:46 +02:00
KennyTV 87afb84a4d Fix server switching to 1.16 servers on Bungee
Fixes #216
2020-06-30 13:56:38 +02:00
KennyTV 07078b21f1 Improve map color rewriter, cc Gerrygames 2020-06-30 13:25:38 +02:00
KennyTV 63d3dcb31b Make this more readable with the base colors 2020-06-30 12:41:09 +02:00
KennyTV 478e663506 Handle new map item colors 2020-06-30 12:33:40 +02:00
KennyTV 6bb8ae1dfc Fix json entity names 2020-06-29 18:28:40 +02:00
KennyTV 2cea70e643 Fix chat meta conversion
Fixes #213
2020-06-29 10:01:27 +02:00
KennyTV 54de77a110 Correct component type in advancements 2020-06-28 11:56:22 +02:00
KennyTV e38cb88640 Fix item particle id
Fixes ViaVersion/ViaVersion#1852
2020-06-28 09:20:01 +02:00
KennyTV 8deeda641a VV now has these methods 2020-06-28 09:11:11 +02:00
KennyTV f75420a642 Fix 1.12 chat reading 2020-06-27 22:08:22 +02:00
KennyTV efd435e908 Update 1.16 translations 2020-06-27 19:27:06 +02:00
KennyTV 875ffb7f2d Use JsonElement for chat components 2020-06-27 17:05:07 +02:00
KennyTV 385ca98125 Fix NPE
Fixes #211
2020-06-25 14:30:05 +02:00
KennyTV c4630039c4 Also handle block entity data nbt 2020-06-25 11:30:45 +02:00
KennyTV cf6df691d2 Bump dependencies 2020-06-25 10:32:05 +02:00
KennyTV 76dfbe030e Version bump to 3.0.2-SNAPSHOT 2020-06-24 14:36:31 +02:00
KennyTV c7a168d3b3 3.0.1 Release 2020-06-24 14:24:29 +02:00
KennyTV b79bf429f7 1.16.1 2020-06-24 14:16:21 +02:00
KennyTV 6e1c482e2d Version graph 2020-06-24 10:43:59 +02:00
KennyTV b506060e48 Fix component length read 2020-06-23 19:20:39 +02:00
KennyTV 8294f6af4f Bump version to 3.0.1-SNAPSHOT 2020-06-23 17:11:40 +02:00
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
Matsv f7824e1df5 Bump version 2017-08-04 14:03:35 +02:00
Matsv 2168145d58 Prevent crash for now 2017-08-03 15:44:34 +02:00
Matsv ebb1323129 Prepare for 1.12.1 2017-08-02 14:08:37 +02:00
Matsv 34ca6324c5 Possibility to suppress type not found errors 2017-07-30 12:23:00 +02:00
Matsv 908931e174 Make metadata item rewrite check the Type instead of the MetaType fixes #17 2017-07-30 12:17:20 +02:00
Matsv 1f15c9e8f1 Back to snapshot 2017-07-30 12:14:59 +02:00
Matsv 9a0686685c Bump version 2017-07-29 14:11:43 +02:00
Matsv ccc63966c6 Change shulkerbox data fixes #15 2017-07-29 14:05:10 +02:00
Matsv 18d8ab068d Remove debug message 2017-07-29 13:32:03 +02:00
Matsv 227396d08a Format replacement items differently 2017-07-29 13:24:17 +02:00
Matsv dbc92572fd Fix NPE for unknown beds & keep original NBT data 2017-07-29 13:19:59 +02:00
Matsv ea2f603cf7 Possibility to hide warning using suppressMetadataErrors fixes #14 2017-07-04 21:12:09 +02:00
Matsv a5aa9e7281 Handle nulls in EntityRewriter (#11) 2017-06-21 19:30:48 +02:00
Matsv 0e5ee7063f Back to snapshot 2017-06-14 17:57:12 +02:00
Matsv d95630c4d0 Bump version 2017-06-14 17:31:32 +02:00
Matsv 451202335d Add supported versions to README 2017-06-14 16:27:42 +02:00
Matsv 36be58f775 Change sout to logger 2017-06-14 15:41:36 +02:00
Matsv a23204a86c Use a hanging bat for sitting parrot 2017-06-14 15:16:52 +02:00
Matsv 4928dab3f0 Fix achievement popup "Open Inventory" visible forever 2017-06-14 14:59:48 +02:00
Matsv b6bf2cd950 Handle observer facing position 2017-06-13 21:06:07 +02:00
Matsv 469936308c Implement shoulder indication 2017-06-13 20:48:02 +02:00
Matsv d330b64bba Modify pitch instead of changing volume (-: 2017-06-13 19:34:30 +02:00
Matsv 258ca46428 Remap 1_12 sounds 2017-06-13 19:30:36 +02:00
Matsv e4998e267e Remove some todos 2017-06-13 17:10:56 +02:00
Matsv adc84452d5 Fix invisible illusionator 2017-06-13 16:56:47 +02:00
Matsv ce89d1c724 Store Parrot tamed data 2017-06-13 16:32:43 +02:00
Matsv 354660a374 Change ShulkerBoxes to EnderChests to fix breaking/picking it up 2017-06-13 15:38:16 +02:00
Matsv a47e845847 Fix Llama inventory offset, replacement sounds for 1.11 & fix NPE 2017-06-13 15:33:43 +02:00
Matsv da84e30936 Rename some classes 2017-06-13 13:59:48 +02:00
Matsv 0f52fdf3b6 Let the knowledge book glow (: 2017-06-13 13:55:48 +02:00
Matsv dfe8c90da4 Patch signs not empty in 1.9-1.9.2 2017-06-13 13:40:28 +02:00
Matsv 9ed4a15b32 Implement a color variable for item names 2017-06-12 21:50:21 +02:00
Matsv 961991a316 Fix null translate chat message fields 2017-06-12 21:28:26 +02:00
Matsv e9878f68b9 Basic advancements handling 2017-06-12 21:06:30 +02:00
Matsv 95532bcdd5 Show entity names when replaced 2017-06-12 19:18:44 +02:00
Matsv a8e81935cc Handle FallingBlocks in 1.9.4-1.11.2 2017-06-10 16:34:08 +02:00
Matsv 2a1f6602ba Fix the Item Rewriter, implement 1.12 block rewrites & handle fallingblocks 2017-06-10 16:15:37 +02:00
Matsv d113e11c3b Metadata change voor illagers (Should be changed @ wiki.vg) 2017-06-08 19:35:26 +02:00
Matsv 5a4dd8bb6a ILLUSION_ILLAGER -> EVOCATION_ILLAGER (Better suggestions are welcome, bow will be invisible with the current entity.) 2017-06-08 18:43:23 +02:00
Matsv 85286095d7 Parrot -> Bat 2017-06-08 18:29:38 +02:00
Matsv 34d9ccbd5b Let PAaaS generate the sound changes 2017-06-08 17:27:58 +02:00
Matsv d98a511757 Bump viaversion & handle metadata changes 2017-06-08 17:07:55 +02:00
Matsv cb93950785 Map Packet ID changes for 1.12 2017-06-08 16:29:01 +02:00
Matsv ddf5324a82 Rename disabled llama slots & bump viaversion 2017-06-08 15:39:10 +02:00
Matsv 67d3eef37a Handle new Llama inventory 2017-06-08 15:31:34 +02:00
Matsv 7fda9dba0d Woops, forgot the new Shulker Shell item 2017-06-03 12:39:35 +02:00
Matsv da2e802e29 Handle chested horse metadata correctly 2017-06-03 12:22:47 +02:00
Matsv 347d449f51 Fix invisible shulkerboxes 2017-06-03 12:05:37 +02:00
Matsv 41d1ceb7cd Play Guardian animation when Totem of Undying is used. 2017-06-03 11:54:05 +02:00
Matsv 2060a698bd Fix Spawn eggs 2017-06-03 11:47:08 +02:00
Matsv ff73405d92 Rewrite Entity Type for spawners 2017-06-01 20:26:10 +02:00
Matsv 878230ebb1 Cleanup BlockItemRewriter & EntityRewriter 2017-06-01 19:09:48 +02:00
Matsv f33c694dd3 Cancel Shulker Decleration @ Update Block Entity & rewrite some sounds 2017-06-01 15:03:27 +02:00
Matsv 5ef109c037 Rewrite SoundRewriter and generate placeholders for 1.11 2017-05-31 21:02:34 +02:00
Matsv 373f519464 Cleanup 2017-05-31 14:09:50 +02:00
Matsv 51c502486e Continue 1.11 update. 2017-05-31 00:03:42 +02:00
Matsv 168803ae8a Update ViaVersion 2016-12-26 13:36:07 +01:00
Matsv a22ab7f625 Update ViaVersion 2016-12-26 13:34:55 +01:00
Matsv 4e5a12a514 Remove the instanceof check since it's no longer required. 2016-11-19 15:57:08 +01:00
Matsv 6cf94fce66 Change the way how EntityTrackers work to work correctly with multiple versions (WIP) 2016-11-19 15:51:38 +01:00
Matsv 0549cb5c3a Merge branches 'dev' and 'master' of https://github.com/Matsv/ViaBackwards into dev 2016-11-19 12:01:57 +01:00
Matsv 58810243dc Start working on the 1.11 update (Far from stable) 2016-11-19 12:01:22 +01:00
Matsv 04508e8c5c Back to snapshot 2016-11-19 10:57:55 +01:00
169 changed files with 31058 additions and 1575 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?:
>
+31
View File
@@ -0,0 +1,31 @@
---
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://paste.gg/ 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?
**Checklist**
- [ ] I have included a ViaVersion dump
- [ ] If applicable, I have included a paste (not a screenshot) of the error
- [ ] I have tried a build from https://ci.viaversion.com/ and the issue still persists
+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.
+22 -2
View File
@@ -1,7 +1,27 @@
# ViaBackwards
Allows 1.9.x on a 1.10 Spigot server
Allows older Minecraft versions on a newer Minecraft server
Supported versions
-
**Green** = ViaVersion\
**Purple** = ViaBackwards addition
![supported_versions](https://i.imgur.com/HBihr0t.png)
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/
Requires [ViaVersion](http://viaversion.com) to be installed
**Spigot page:** https://www.spigotmc.org/resources/viabackwards.27448/
---
**Maven:** https://repo.viaversion.com/
**Issue tracker:** https://github.com/ViaVersion/ViaBackwards/issues
**List of contributors:** https://github.com/ViaVersion/ViaBackwards/graphs/contributors
-9
View File
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
cd .. &&
echo "Start maven build" &&
mvn clean install &&
echo "Copying" &&
cd ./all/ &&
cp ./target/viabackwards-all-2.0-DEV.jar /home/adr/mc/Spigot/TestServers/BungeeCord/plugins/ &&
echo "Done."
+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.0</version>
<version>3.1.1</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.0</version>
<version>3.1.1</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.10.2-R0.1-SNAPSHOT</version>
<version>1.16.1-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>
@@ -10,11 +10,31 @@
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
public void disable() {
getPluginLoader().disablePlugin(this);
}
}
@@ -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.0</version>
<version>3.1.1</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.10-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>
@@ -11,11 +11,17 @@
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()));
}
@Override
public void disable() {
}
}
+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.0</version>
<version>3.1.1</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,15 +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,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.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() {
}
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();
}
@@ -0,0 +1,132 @@
/*
* 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 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_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_16_2to1_16_3.Protocol1_16_2To1_16_3;
import nl.matsv.viabackwards.protocol.protocol1_16to1_16_1.Protocol1_16To1_16_1;
import nl.matsv.viabackwards.protocol.protocol1_16_1to1_16_2.Protocol1_16_1To1_16_2;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.update.Version;
import java.io.File;
import java.util.logging.Logger;
import static us.myles.ViaVersion.api.protocol.ProtocolRegistry.registerProtocol;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "3.1.1";
/**
* 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);
registerProtocol(new Protocol1_16To1_16_1(), ProtocolVersion.v1_16, ProtocolVersion.v1_16_1);
registerProtocol(new Protocol1_16_1To1_16_2(), ProtocolVersion.v1_16_1, ProtocolVersion.v1_16_2);
registerProtocol(new Protocol1_16_2To1_16_3(), ProtocolVersion.v1_16_2, ProtocolVersion.v1_16_3);
}
/**
* Logger provided by the platform.
*
* @return logger instance
*/
Logger getLogger();
default boolean isOutdated() {
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 VIAVERSION " + MINIMUM_VV_VERSION + " OR NEWER");
getLogger().severe("LINK: https://ci.viaversion.com/");
getLogger().severe("VIABACKWARDS WILL NOW DISABLE");
getLogger().severe("================================");
disable();
return true;
}
return false;
}
/**
* 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).toString();
}
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);
}
}
@@ -8,11 +8,12 @@
* 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;
package nl.matsv.viabackwards.api.entities.meta;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
public interface MetaRewriter {
Metadata handleMetadata(boolean isObject, int entityType, Metadata data) throws RemovedValueException;
public interface MetaHandler {
Metadata handle(MetaHandlerEvent e) throws RemovedValueException;
}
@@ -0,0 +1,86 @@
/*
* 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.meta;
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.ArrayList;
import java.util.List;
public class MetaHandlerEvent {
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 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;
}
}
@@ -0,0 +1,118 @@
/*
* 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.meta;
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;
public class MetaHandlerSettings {
private EntityType filterType;
private boolean filterFamily;
private int filterIndex = -1;
private MetaHandler handler;
public MetaHandlerSettings filter(EntityType type) {
return filter(type, filterFamily, filterIndex);
}
public MetaHandlerSettings filter(EntityType type, boolean filterFamily) {
return filter(type, filterFamily, filterIndex);
}
public MetaHandlerSettings filter(int index) {
return filter(filterType, filterFamily, index);
}
public MetaHandlerSettings filter(EntityType type, int index) {
return filter(type, filterFamily, index);
}
public MetaHandlerSettings filter(EntityType type, boolean filterFamily, int index) {
this.filterType = type;
this.filterFamily = filterFamily;
this.filterIndex = index;
return this;
}
public void handle(@Nullable MetaHandler handler) {
this.handler = handler;
}
public void handleIndexChange(final int newIndex) {
handle(e -> {
Metadata data = e.getData();
data.setId(newIndex);
return data;
});
}
public void removed() {
handle(e -> {
throw RemovedValueException.EX;
});
}
public boolean hasHandler() {
return handler != null;
}
public boolean hasType() {
return filterType != null;
}
public boolean hasIndex() {
return filterIndex > -1;
}
public boolean isFilterFamily() {
return filterFamily;
}
/**
* 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 !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 +
'}';
}
}
@@ -0,0 +1,90 @@
/*
* 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.storage;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter;
public class EntityData {
private final int id;
private final int replacementId;
private Object 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 EntityData spawnMetadata(MetaCreator handler) {
this.defaultMeta = handler;
return this;
}
public boolean hasBaseMeta() {
return this.defaultMeta != null;
}
public int getId() {
return id;
}
/**
* @return custom mobname, can be either a String or a JsonElement
*/
@Nullable
public Object 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 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;
}
}
}
@@ -8,16 +8,7 @@
* 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.storage;
package nl.matsv.viabackwards.api.entities.storage;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@AllArgsConstructor
@EqualsAndHashCode
public class EntityType {
private boolean object;
private short entityType;
public interface EntityStorage {
}
@@ -0,0 +1,119 @@
/*
* 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.storage;
import nl.matsv.viabackwards.api.BackwardsProtocol;
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.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject {
private final Map<BackwardsProtocol, ProtocolEntityTracker> trackers = new ConcurrentHashMap<>();
public EntityTracker(UserConnection user) {
super(user);
}
public void initProtocol(BackwardsProtocol protocol) {
trackers.put(protocol, new ProtocolEntityTracker());
}
@Nullable
public ProtocolEntityTracker get(BackwardsProtocol protocol) {
return trackers.get(protocol);
}
public static class ProtocolEntityTracker {
private final Map<Integer, StoredEntity> entityMap = new ConcurrentHashMap<>();
public void trackEntityType(int id, EntityType type) {
entityMap.putIfAbsent(id, new StoredEntity(id, type));
}
public void removeEntity(int id) {
entityMap.remove(id);
}
@Nullable
public EntityType getEntityType(int id) {
StoredEntity storedEntity = entityMap.get(id);
return storedEntity != null ? storedEntity.getType() : null;
}
@Nullable
public StoredEntity getEntity(int id) {
return entityMap.get(id);
}
}
public static final class StoredEntity {
private final int entityId;
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
*
* @param objectClass The class of the object to get
* @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);
}
/**
* Check if the storage has an object
*
* @param objectClass The object class to check
* @return True if the object is in the storage
*/
public boolean has(Class<? extends EntityStorage> objectClass) {
return storedObjects.containsKey(objectClass);
}
/**
* Put an object into the stored objects based on class
*
* @param object The object to store.
*/
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 +
'}';
}
}
}
@@ -0,0 +1,75 @@
/*
* 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.storage;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import java.util.List;
public class MetaStorage {
private List<Metadata> metaDataList;
public MetaStorage(List<Metadata> metaDataList) {
this.metaDataList = metaDataList;
}
public boolean has(Metadata data) {
return this.metaDataList.contains(data);
}
public void delete(Metadata data) {
this.metaDataList.remove(data);
}
public void delete(int index) {
metaDataList.removeIf(meta -> meta.getId() == index);
}
public void add(Metadata data) {
this.metaDataList.add(data);
}
@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) {
return getOrDefault(index, false, data);
}
public Metadata getOrDefault(int index, boolean removeIfExists, Metadata data) {
Metadata existingData = get(index);
if (removeIfExists && existingData != null) {
delete(existingData);
}
return existingData != null ? existingData : 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;
}
}
}
@@ -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,107 +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 nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.utils.Block;
import nl.matsv.viabackwards.utils.ItemUtil;
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.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<Short, Item> itemRewriter = new ConcurrentHashMap<>();
private final Map<Integer, Block> blockRewriter = new ConcurrentHashMap<>();
protected void rewriteItem(int oldItem, Item newItem) {
itemRewriter.put((short) oldItem, newItem);
}
protected void rewriteBlockItem(int oldId, Item newItem, Block newBlock) {
itemRewriter.put((short) oldId, newItem);
blockRewriter.put(oldId, newBlock);
}
protected Item handleItemToClient(Item item) {
if (item == null)
return null;
if (!itemRewriter.containsKey(item.getId()))
return item;
Item i = ItemUtil.copyItem(itemRewriter.get(item.getId()));
if (i.getTag() == null)
i.setTag(new CompoundTag(""));
i.getTag().put(createViaNBT(item));
if (item.getTag() != null)
for (Tag ai : item.getTag())
i.getTag().put(ai);
i.setAmount(item.getAmount());
return i;
}
protected Item handleItemToServer(Item item) {
if (item == null || item.getTag() == null)
return null;
CompoundTag tag = item.getTag();
if (tag.contains("ViaBackwards")) {
CompoundTag via = tag.get("ViaBackwards");
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");
}
return item;
}
protected Block handleBlock(int block) {
if (!containsBlock(block))
return null;
return blockRewriter.get(block);
}
protected boolean containsBlock(int block) {
return blockRewriter.containsKey(block);
}
private CompoundTag createViaNBT(Item i) {
CompoundTag tag = new CompoundTag("ViaBackwards");
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", text));
return tag;
}
}
@@ -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).toString();
}
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,117 +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.RequiredArgsConstructor;
import nl.matsv.viabackwards.ViaBackwards;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.MetaRewriter;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.api.storage.EntityType;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.data.UserConnection;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
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_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.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<Short, Short> entityTypes = new ConcurrentHashMap<>();
private final Map<Short, Short> objectTypes = new ConcurrentHashMap<>();
public abstract class EntityRewriter<T extends BackwardsProtocol> extends EntityRewriterBase<T> {
private final List<MetaRewriter> metaRewriters = new ArrayList<>();
protected short getNewEntityType(UserConnection connection, int id) {
EntityType type = getEntityType(connection, id);
if (type.isObject()) {
return getNewObjectId(type.getEntityType());
} else {
return getNewEntityId(type.getEntityType());
}
protected EntityRewriter(T protocol) {
super(protocol, MetaType1_14.OptChat, 2);
}
protected EntityType getEntityType(UserConnection connection, int id) {
return connection.get(EntityTracker.class).getEntityType(id);
protected EntityRewriter(T protocol, MetaType displayType) {
super(protocol, displayType, 2);
}
protected void addTrackedEntity(UserConnection connection, int entityId, boolean isObject, short typeId) {
connection.get(EntityTracker.class).trackEntityType(entityId, new EntityType(isObject, typeId));
}
protected void rewriteEntityId(int oldId, int newId) {
entityTypes.put((short) oldId, (short) newId);
}
protected boolean isRewriteEntityId(short id) {
return entityTypes.containsKey(id);
}
protected short getNewEntityId(short oldId) {
if (!isRewriteEntityId(oldId))
return oldId;
return entityTypes.get(oldId);
}
protected void rewriteObjectId(int oldId, int newId) {
objectTypes.put((short) oldId, (short) newId);
}
protected boolean isRewriteObjectId(short id) {
return objectTypes.containsKey(id);
}
protected short getNewObjectId(short oldId) {
if (!isRewriteObjectId(oldId))
return oldId;
return objectTypes.get(oldId);
}
public void registerMetaRewriter(MetaRewriter rewriter) {
metaRewriters.add(rewriter);
}
protected List<Metadata> handleMeta(UserConnection userConnection, int entityId, List<Metadata> metaData) {
EntityTracker tracker = userConnection.get(EntityTracker.class);
EntityType type = tracker.getEntityType(entityId);
List<Metadata> newMeta = new CopyOnWriteArrayList<>();
for (Metadata md : metaData) {
Metadata nmd = md;
try {
for (MetaRewriter rewriter : metaRewriters) {
if (type != null)
nmd = rewriter.handleMetadata(type.isObject(), type.getEntityType(), nmd);
else
nmd = rewriter.handleMetadata(false, -1, nmd);
if (nmd == null)
throw new RemovedValueException();
}
newMeta.add(nmd);
} catch (RemovedValueException ignored) {
} catch (Exception e) {
if (ViaVersion.getInstance().isDebug()) {
Logger log = ViaBackwards.getPlatform().getLogger();
log.warning("Unable to handle metadata " + md);
log.warning("Full metadata list " + metaData);
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));
}
});
}
});
}
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 newMeta;
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,270 @@
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 || data.getValue().toString().isEmpty())
&& data.getMetaType().getTypeID() == displayNameMetaType.getTypeID()) {
data.setValue(entityData.getMobName());
}
}
return storage;
}
/**
* 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.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.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 display = null;
if (translatableRewriter != null
&& item.getTag() != null && (display = item.getTag().get("display")) != null) {
// Handle name and lore components
StringTag name = display.get("Name");
if (name != null) {
String newValue = translatableRewriter.processText(name.getValue()).toString();
if (!newValue.equals(name.getValue())) {
saveNameTag(display, name);
}
name.setValue(newValue);
}
ListTag lore = display.get("Lore");
if (lore != null) {
ListTag original = null;
boolean changed = false;
for (Tag loreEntryTag : lore) {
if (!(loreEntryTag instanceof StringTag)) continue;
StringTag loreEntry = (StringTag) loreEntryTag;
String newValue = translatableRewriter.processText(loreEntry.getValue()).toString();
if (!changed && !newValue.equals(loreEntry.getValue())) {
changed = true;
original = lore.clone();
}
loreEntry.setValue(newValue);
}
if (changed) {
saveLoreTag(display, original);
}
}
}
MappedItem data = mappedItemFunction.get(item.getIdentifier());
if (data == null) {
// Just rewrite the id
return super.handleItemToClient(item);
}
// Set remapped id
item.setIdentifier(data.getId());
// Set custom name - only done if there is no original one
if (item.getTag() == null) {
item.setTag(new CompoundTag(""));
}
if (display == null) {
item.getTag().put(display = new CompoundTag("display"));
}
if (!display.contains("Name")) {
display.put(new StringTag("Name", data.getJsonName()));
display.put(new ByteTag(nbtTagName + "|customName"));
}
return item;
}
@FunctionalInterface
public interface MappedItemFunction {
@Nullable
MappedItem get(int id);
}
}
@@ -0,0 +1,83 @@
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.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 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;
if (toServerRewriter != null) {
item.setIdentifier(toServerRewriter.rewrite(item.getIdentifier()));
}
restoreDisplayTag(item);
return item;
}
protected void saveNameTag(CompoundTag displayTag, StringTag original) {
displayTag.put(new StringTag(nbtTagName + "|o" + original.getName(), original.getValue()));
}
protected void saveLoreTag(CompoundTag displayTag, ListTag original) {
displayTag.put(new ListTag(nbtTagName + "|o" + original.getName(), original.getValue()));
}
protected void restoreDisplayTag(Item item) {
if (item.getTag() == null) return;
CompoundTag display = item.getTag().get("display");
if (display != null) {
// Remove custom name / restore original name
if (display.remove(nbtTagName + "|customName") != null) {
display.remove("Name");
} else {
restoreDisplayTag(display, "Name");
}
// Restore lore
restoreDisplayTag(display, "Lore");
}
}
protected void restoreDisplayTag(CompoundTag displayTag, String tagName) {
Tag original = displayTag.remove(nbtTagName + "|o" + tagName);
if (original != null) {
displayTag.put(original);
}
}
}
@@ -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.ByteTag;
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);
}
short originalData = item.getData();
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) {
if (item.getTag() == null) {
item.setTag(new CompoundTag(""));
}
CompoundTag display = item.getTag().get("display");
if (display == null) {
item.getTag().put(display = new CompoundTag("display"));
}
StringTag nameTag = display.get("Name");
if (nameTag == null) {
display.put(nameTag = new StringTag("Name", data.getName()));
display.put(new ByteTag(nbtTagName + "|customName"));
}
// Handle colors
String value = nameTag.getValue();
if (value.contains("%vb_color%")) {
display.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).toString() : 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,154 @@
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 us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
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 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));
});
}
});
}
protected 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);
});
}
});
}
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;
}
}
}
@@ -13,26 +13,32 @@ package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
public abstract class Rewriter<T extends BackwardsProtocol> {
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) {
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,51 +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 nl.matsv.viabackwards.api.BackwardsProtocol;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class SoundIdRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private Map<Integer, Integer> soundRewriter = new ConcurrentHashMap<>();
private Map<Integer, Float> pitchRewriter = new ConcurrentHashMap<>();
protected void rewriteSound(int newId, int oldId) {
soundRewriter.put(newId, oldId);
}
protected void rewriteSound(int newId, int oldId, float newPitch) {
rewriteSound(newId, oldId);
pitchRewriter.put(newId, newPitch);
}
public int handleSounds(int soundId) {
int newSoundId = soundId;
if (soundRewriter.containsKey(soundId))
newSoundId = soundId = soundRewriter.get(soundId);
for (Integer i : soundRewriter.keySet()) {
if (soundId > i)
newSoundId--;
}
return newSoundId;
}
public boolean hasPitch(int soundId) {
return pitchRewriter.containsKey(soundId);
}
public float handlePitch(int soundId) {
if (pitchRewriter.containsKey(soundId))
return pitchRewriter.get(soundId);
return -1;
}
}
@@ -0,0 +1,73 @@
package nl.matsv.viabackwards.api.rewriters;
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.function.Function;
public class SoundRewriter extends us.myles.ViaVersion.api.rewriters.SoundRewriter {
private final Function<String, String> stringIdRewriter;
public SoundRewriter(BackwardsProtocol protocol, IdRewriteFunction idRewriter, Function<String, String> stringIdRewriter) {
super(protocol, idRewriter);
this.stringIdRewriter = stringIdRewriter;
}
public SoundRewriter(BackwardsProtocol protocol, IdRewriteFunction idRewriter) {
this(protocol, idRewriter, null);
}
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();
}
});
}
});
}
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
if ((flags & 0x01) != 0) {
wrapper.passthrough(Type.VAR_INT); // Source
}
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,116 @@
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.rewriters.ComponentRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
import java.util.HashMap;
import java.util.Map;
public class TranslatableRewriter extends ComponentRewriter {
private static final Map<String, Map<String, String>> TRANSLATABLES = new HashMap<>();
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) {
super(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 -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
public void registerDisconnect(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
public void registerChatMessage(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
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 -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
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 -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
public void registerTabList(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
processText(wrapper.passthrough(Type.COMPONENT));
processText(wrapper.passthrough(Type.COMPONENT));
});
}
});
}
@Override
protected void handleTranslate(JsonObject root, String translate) {
String newTranslate = newTranslatables.get(translate);
if (newTranslate != null) {
root.addProperty("translate", newTranslate);
}
}
}
@@ -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);
}
}
@@ -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_10to1_11;
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;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.EntityPackets1_11;
import nl.matsv.viabackwards.protocol.protocol1_10to1_11.packets.PlayerPackets1_11;
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<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
private EntityPackets1_11 entityPackets; // Required for the item rewriter
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(this)).register();
new PlayerPackets1_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)) {
user.put(new ClientWorld(user));
}
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class)) {
user.put(new EntityTracker(user));
}
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;
}
}
@@ -0,0 +1,457 @@
/*
* 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.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.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 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.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 LegacyBlockItemRewriter<Protocol1_10To1_11> {
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(itemRewriter.itemToClientHandler(Type.ITEM));
// Handle Llama
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 currentSlot = wrapper.get(Type.SHORT, 0);
wrapper.set(Type.SHORT, 0, ((Integer) (currentSlot = getNewSlotId(storage, currentSlot))).shortValue());
wrapper.set(Type.ITEM, 0, getNewItem(storage, currentSlot, wrapper.get(Type.ITEM, 0)));
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_9_3.WINDOW_ITEMS, 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]);
if (isLlama(wrapper.user())) {
Optional<ChestedHorseStorage> horse = getChestedHorse(wrapper.user());
if (!horse.isPresent())
return;
ChestedHorseStorage storage = horse.get();
stacks = Arrays.copyOf(stacks, !storage.isChested() ? 38 : 53);
for (int i = stacks.length - 1; i >= 0; i--) {
stacks[getNewSlotId(storage, i)] = stacks[i];
stacks[i] = getNewItem(storage, i, stacks[i]);
}
wrapper.set(Type.ITEM_ARRAY, 0, stacks);
}
}
});
}
});
itemRewriter.registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT, Type.ITEM);
// Plugin message Packet -> Trading
protocol.registerOutgoing(ClientboundPackets1_9_3.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(itemRewriter.itemToServerHandler(Type.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());
}
}
});
}
});
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 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.
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");
}
}
}
});
}
});
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
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_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 handle(PacketWrapper wrapper) throws Exception {
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(handleBlockID(record.getBlockId()));
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_9_3.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 on shulkerbox decleration
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 10) {
wrapper.cancel();
}
// Handler Spawners
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 1) {
CompoundTag tag = wrapper.get(Type.NBT, 0);
EntityIdRewriter.toClientSpawner(tag, true);
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_9_3.OPEN_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.STRING); // 1 - Window Type
map(Type.COMPONENT); // 2 - Title
map(Type.UNSIGNED_BYTE); // 3 - Slots
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityId = -1;
// Passthrough Entity ID
if (wrapper.get(Type.STRING, 0).equals("EntityHorse")) {
entityId = wrapper.passthrough(Type.INT);
}
// Track Inventory
String inventory = wrapper.get(Type.STRING, 0);
WindowTracker windowTracker = wrapper.user().get(WindowTracker.class);
windowTracker.setInventory(inventory);
windowTracker.setEntityId(entityId);
// Change llama slotcount to the donkey one
if (isLlama(wrapper.user())) {
wrapper.set(Type.UNSIGNED_BYTE, 1, (short) 17);
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_9_3.CLOSE_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
// Inventory tracking
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
WindowTracker windowTracker = wrapper.user().get(WindowTracker.class);
windowTracker.setInventory(null);
windowTracker.setEntityId(-1);
}
});
}
});
protocol.registerIncoming(ServerboundPackets1_9_3.CLOSE_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
// Inventory tracking
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
WindowTracker windowTracker = wrapper.user().get(WindowTracker.class);
windowTracker.setInventory(null);
windowTracker.setEntityId(-1);
}
});
}
});
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;
});
}
@Override
protected void registerRewrites() {
// 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;
});
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName);
enchantmentRewriter.registerEnchantment(71, "§cCurse of Vanishing");
enchantmentRewriter.registerEnchantment(10, "§cCurse of Binding");
enchantmentRewriter.setHideLevelForEnchants(71, 10); // Curses do not display their level
}
@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());
EntityTracker.StoredEntity storedEntity = entTracker.getEntity(tracker.getEntityId());
return storedEntity != null && storedEntity.getType().is(Entity1_11Types.EntityType.LIAMA);
}
return false;
}
private Optional<ChestedHorseStorage> getChestedHorse(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());
EntityTracker.StoredEntity storedEntity = entTracker.getEntity(tracker.getEntityId());
if (storedEntity != null)
return Optional.of(storedEntity.get(ChestedHorseStorage.class));
}
return Optional.empty();
}
private int getNewSlotId(ChestedHorseStorage storage, int slotId) {
int totalSlots = !storage.isChested() ? 38 : 53;
int strength = storage.isChested() ? storage.getLiamaStrength() : 0;
int startNonExistingFormula = 2 + 3 * strength;
int offsetForm = 15 - (3 * strength);
if (slotId >= startNonExistingFormula && totalSlots > (slotId + offsetForm))
return offsetForm + slotId;
if (slotId == 1)
return 0;
return slotId;
}
private int getOldSlotId(ChestedHorseStorage storage, int slotId) {
int strength = storage.isChested() ? storage.getLiamaStrength() : 0;
int startNonExistingFormula = 2 + 3 * strength;
int endNonExistingFormula = 2 + 3 * (storage.isChested() ? 5 : 0);
int offsetForm = endNonExistingFormula - startNonExistingFormula;
if (slotId == 1 || slotId >= startNonExistingFormula && slotId < endNonExistingFormula)
return 0;
if (slotId >= endNonExistingFormula)
return slotId - offsetForm;
if (slotId == 0)
return 1;
return slotId;
}
private Item getNewItem(ChestedHorseStorage storage, int slotId, Item current) {
int strength = storage.isChested() ? storage.getLiamaStrength() : 0;
int startNonExistingFormula = 2 + 3 * strength;
int endNonExistingFormula = 2 + 3 * (storage.isChested() ? 5 : 0);
if (slotId >= startNonExistingFormula && slotId < endNonExistingFormula)
return new Item(166, (byte) 1, (short) 0, getNamedTag(ChatColor.RED + "SLOT DISABLED"));
if (slotId == 1)
return null;
return current;
}
}
@@ -0,0 +1,423 @@
/*
* 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.packets;
import nl.matsv.viabackwards.api.entities.storage.EntityData;
import nl.matsv.viabackwards.api.entities.storage.MetaStorage;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
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.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.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import java.util.Optional;
public class EntityPackets1_11 extends LegacyEntityRewriter<Protocol1_10To1_11> {
public EntityPackets1_11(Protocol1_10To1_11 protocol) {
super(protocol);
}
@Override
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
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_11Types.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_9_3.SPAWN_EXPERIENCE_ORB, Entity1_11Types.EntityType.EXPERIENCE_ORB);
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, Entity1_11Types.EntityType.WEATHER);
protocol.registerOutgoing(ClientboundPackets1_9_3.SPAWN_MOB, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.VAR_INT, Type.UNSIGNED_BYTE); // 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_9.METADATA_LIST); // 12 - Metadata
// Track entity
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);
EntityType 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
);
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
wrapper.set(
Types1_9.METADATA_LIST,
0,
storage.getMetaDataList()
);
}
});
}
});
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);
protocol.registerOutgoing(ClientboundPackets1_9_3.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_9.METADATA_LIST); // 7 - Metadata list
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, Entity1_11Types.EntityType.PLAYER));
}
});
registerEntityDestroy(ClientboundPackets1_9_3.DESTROY_ENTITIES);
registerMetadataRewriter(ClientboundPackets1_9_3.ENTITY_METADATA, Types1_9.METADATA_LIST);
protocol.registerOutgoing(ClientboundPackets1_9_3.ENTITY_STATUS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.BYTE); // 1 - Entity Status
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
byte b = wrapper.get(Type.BYTE, 0);
if (b == 35) {
wrapper.clearPacket();
wrapper.setId(0x1E); // Change Game State
wrapper.write(Type.UNSIGNED_BYTE, (short) 10); // Play Elder Guardian animation
wrapper.write(Type.FLOAT, 0F);
}
}
});
}
});
}
@Override
protected void registerRewrites() {
// Guardian
mapEntity(Entity1_11Types.EntityType.ELDER_GUARDIAN, Entity1_11Types.EntityType.GUARDIAN);
// Skeletons
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
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
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
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);
mapObjectType(Entity1_11Types.ObjectType.LIAMA_SPIT, Entity1_11Types.ObjectType.SNOWBALL, -1);
// Replace with endertorchthingies
mapObjectType(Entity1_11Types.ObjectType.EVOCATION_FANGS, Entity1_11Types.ObjectType.FALLING_BLOCK, 198 | 1 << 12);
// Handle ElderGuardian & target metadata
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(Entity1_11Types.EntityType.ELDER_GUARDIAN))
bitmask |= 0x04;
data.setMetaType(MetaType1_9.Byte);
data.setValue((byte) bitmask);
return data;
});
// Handle skeleton swing
registerMetaHandler().filter(Entity1_11Types.EntityType.ABSTRACT_SKELETON, true, 12).handleIndexChange(13);
/*
ZOMBIE CHANGES
*/
registerMetaHandler().filter(Entity1_11Types.EntityType.ZOMBIE, true).handle(e -> {
Metadata data = e.getData();
switch (data.getId()) {
case 13:
throw RemovedValueException.EX;
case 14:
data.setId(15);
break;
case 15:
data.setId(14);
break;
// Profession
case 16:
data.setId(13);
data.setValue(1 + (int) data.getValue());
break;
}
return data;
});
// Handle Evocation Illager
registerMetaHandler().filter(Entity1_11Types.EntityType.EVOCATION_ILLAGER, 12).handle(e -> {
Metadata data = e.getData();
data.setId(13);
data.setMetaType(MetaType1_9.VarInt);
data.setValue(((Byte) data.getValue()).intValue()); // Change the profession for the states
return data;
});
// Handle Vex (Remove this field completely since the position is not updated correctly when idling for bats. Sad ):
registerMetaHandler().filter(Entity1_11Types.EntityType.VEX, 12).handle(e -> {
Metadata data = e.getData();
data.setValue((byte) 0x00);
return data;
});
// Handle VindicationIllager
registerMetaHandler().filter(Entity1_11Types.EntityType.VINDICATION_ILLAGER, 12).handle(e -> {
Metadata data = e.getData();
data.setId(13);
data.setMetaType(MetaType1_9.VarInt);
data.setValue(((Number) data.getValue()).intValue() == 1 ? 2 : 4);
return data;
});
/*
HORSES
*/
// Handle horse flags
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) &&
e.getEntity().get(ChestedHorseStorage.class).isChested()) {
b |= 0x08; // Chested
data.setValue(b);
}
return data;
});
// 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 armor
registerMetaHandler().filter(Entity1_11Types.EntityType.HORSE, 16).handleIndexChange(17);
// Handle chested horse
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 RemovedValueException.EX;
});
// Get rid of Liama metadata
registerMetaHandler().filter(Entity1_11Types.EntityType.LIAMA).handle(e -> {
Metadata data = e.getData();
ChestedHorseStorage storage = e.getEntity().get(ChestedHorseStorage.class);
int index = e.getIndex();
// Store them for later (:
switch (index) {
case 16:
storage.setLiamaStrength((int) data.getValue());
throw RemovedValueException.EX;
case 17:
storage.setLiamaCarpetColor((int) data.getValue());
throw RemovedValueException.EX;
case 18:
storage.setLiamaVariant((int) data.getValue());
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(Entity1_11Types.EntityType.VILLAGER, 13).handle(e -> {
Metadata data = e.getData();
if ((int) data.getValue() == 5)
data.setValue(0);
return data;
});
// handle new Shulker color meta
registerMetaHandler().filter(Entity1_11Types.EntityType.SHULKER, 15).removed();
}
/*
0 - Skeleton
1 - Wither Skeleton
2 - Stray
*/
private Metadata getSkeletonTypeMeta(int type) {
return new Metadata(12, MetaType1_9.VarInt, type);
}
/*
0 - Zombie
1-5 - Villager with profession
6 - Husk
*/
private Metadata getZombieTypeMeta(int type) {
return new Metadata(13, MetaType1_9.VarInt, type);
}
private void handleZombieType(MetaStorage storage, int type) {
Metadata meta = storage.get(13);
if (meta == null) {
storage.add(getZombieTypeMeta(type));
}
}
/*
Horse 0
Donkey 1
Mule 2
Zombie horse 3
Skeleton horse 4
*/
private Metadata getHorseMetaType(int type) {
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);
}
}
@@ -0,0 +1,88 @@
/*
* 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.packets;
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.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
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.gson.JsonElement;
public class PlayerPackets1_11 {
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 inputValue / 15f;
}
};
public void register(Protocol1_10To1_11 protocol) {
protocol.registerOutgoing(ClientboundPackets1_9_3.TITLE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Action
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int action = wrapper.get(Type.VAR_INT, 0);
// Handle the new ActionBar
if (action == 2) {
// Convert to the old actionbar way
PacketWrapper actionbar = new PacketWrapper(0x0F, null, wrapper.user()); // Chat Message packet
JsonElement msg = wrapper.read(Type.COMPONENT);
actionbar.write(Type.COMPONENT, msg);
actionbar.write(Type.BYTE, (byte) 2); // Above hotbar
actionbar.send(Protocol1_10To1_11.class);
wrapper.cancel(); // Cancel the title packet
return;
}
if (action > 2) {
wrapper.set(Type.VAR_INT, 0, action - 1); // Move everything one position down
}
}
});
}
});
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(wrapper -> wrapper.read(Type.VAR_INT)); // Ignore item pickup count
}
});
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, TO_NEW_FLOAT);
map(Type.UNSIGNED_BYTE, TO_NEW_FLOAT);
map(Type.UNSIGNED_BYTE, TO_NEW_FLOAT);
}
});
}
}
@@ -0,0 +1,116 @@
/*
* 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.packets;
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.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);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_9_3.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(Type.FLOAT); // 6 - Pitch
}
});
protocol.registerOutgoing(ClientboundPackets1_9_3.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(Type.FLOAT); // 6 - Pitch
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int oldId = wrapper.get(Type.VAR_INT, 0);
int newId = handleSounds(oldId);
if (newId == -1)
wrapper.cancel();
else {
if (hasPitch(oldId))
wrapper.set(Type.FLOAT, 1, handlePitch(oldId));
wrapper.set(Type.VAR_INT, 0, newId);
}
}
});
}
});
}
@Override
protected void registerRewrites() {
// Sound replacements, suggestions are always welcome
// Automatically generated from PAaaS
added(85, 121, 0.5f); // block.shulker_box.close -> block.wooden_trapdoor.close
added(86, 122, 0.5f); // block.shulker_box.open -> block.wooden_trapdoor.open
added(176, 227); // entity.elder_guardian.flop -> entity.guardian.flop
// 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
added(199, 255, 1.3f); // entity.evocation_illager.cast_spell -> entity.irongolem.hurt
added(200, 418, 1.3f); // entity.evocation_illager.death -> entity.zombie_villager.death
added(201, 372, 1.3f); // entity.evocation_illager.hurt -> entity.villager.hurt
added(202, 137, 0.8f); // entity.evocation_illager.prepare_attack -> entity.elder_guardian.curse
added(203, 78, 2f); // entity.evocation_illager.prepare_summon -> block.portal.trigger
added(204, 376, 0.6f); // entity.evocation_illager.prepare_wololo -> entity.witch.ambient
added(279, 230, 1.5f); // entity.llama.ambient -> entity.horse.ambient
added(280, 231, 1.6f); // entity.llama.angry -> entity.horse.angry
added(281, 164); // entity.llama.chest -> entity.donkey.chest
added(282, 165, 1.2f); // entity.llama.death -> entity.donkey.death
added(283, 235, 1.1f); // entity.llama.eat -> entity.horse.eat
added(284, 166); // entity.llama.hurt -> entity.donkey.hurt
added(285, 323, 1.7f); // entity.llama.spit -> entity.shulker.shoot
added(286, 241, 0.8f); // entity.llama.step -> entity.horse.step
added(287, 423, 0.5f); // entity.llama.swag -> item.armor.equip_generic
added(296, 164); // entity.mule.chest -> entity.donkey.chest
added(390, 233, 0.1f); // entity.vex.ambient -> entity.horse.breathe
added(391, 168, 2f); // entity.vex.charge -> entity.elder_guardian.ambient
added(392, 144, 0.5f); // entity.vex.death -> entity.cat.death
added(393, 146, 2f); // entity.vex.hurt -> entity.cat.hurt
added(400, 370, 0.7f); // entity.vindication_illager.ambient -> entity.villager.ambient
added(401, 371, 0.8f); // entity.vindication_illager.death -> entity.villager.death
added(402, 372, 0.7f); // entity.vindication_illager.hurt -> entity.villager.hurt
added(450, 423, 1.1f); // item.armor.equip_elytra -> item.armor.equip_generic
added(455, 427, 1.1f); // item.bottle.empty -> item.bottle.fill
added(470, 2, 0.5f); // item.totem.use -> block.anvil.destroy
}
}
@@ -0,0 +1,57 @@
/*
* 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.storage;
import nl.matsv.viabackwards.api.entities.storage.EntityStorage;
public class ChestedHorseStorage implements EntityStorage {
private boolean chested;
private int liamaStrength;
private int liamaCarpetColor = -1;
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 + '}';
}
}
@@ -8,36 +8,38 @@
* 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.storage;
package nl.matsv.viabackwards.protocol.protocol1_10to1_11.storage;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class WindowTracker extends StoredObject {
private String inventory;
private int entityId = -1;
public class EntityTracker extends StoredObject {
private Map<Integer, EntityType> entityMap = new ConcurrentHashMap<>();
public EntityTracker(UserConnection user) {
public WindowTracker(UserConnection user) {
super(user);
}
public void trackEntityType(int id, EntityType type) {
if (entityMap.containsKey(id))
return;
entityMap.put(id, type);
public String getInventory() {
return inventory;
}
public void removeEntity(int id) {
entityMap.remove(id);
public void setInventory(String inventory) {
this.inventory = inventory;
}
public EntityType getEntityType(int id) {
return entityMap.get(id);
public int getEntityId() {
return entityId;
}
public boolean containsEntity(int id) {
return entityMap.containsKey(id);
public void setEntityId(int entityId) {
this.entityId = entityId;
}
@Override
public String toString() {
return "WindowTracker{" + "inventory='" + inventory + '\'' + ", entityId=" + entityId + '}';
}
}
@@ -0,0 +1,90 @@
/*
* 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;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.entities.storage.EntityTracker;
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.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
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;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import us.myles.viaversion.libs.gson.JsonElement;
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() {
(entityPackets = new EntityPackets1_12(this)).register();
(blockItemPackets = new BlockItemPackets1_12(this)).register();
new SoundPackets1_12(this).register();
new ChatPackets1_12(this).register();
registerOutgoing(ClientboundPackets1_12.TITLE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int action = wrapper.passthrough(Type.VAR_INT);
if (action >= 0 && action <= 2) {
JsonElement component = wrapper.read(Type.COMPONENT);
wrapper.write(Type.COMPONENT, Protocol1_9To1_8.fixJson(component.toString()));
}
});
}
});
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)) {
user.put(new ClientWorld(user));
}
// Register EntityTracker if it doesn't exist yet.
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;
}
}
@@ -0,0 +1,146 @@
/*
* 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.data;
import java.util.HashMap;
import java.util.Map;
public class AdvancementTranslations {
private static final Map<String, String> advancements = new HashMap<>();
static {
add("advancements.nether.get_wither_skull.title", "Spooky Scary Skeleton");
add("advancements.husbandry.break_diamond_hoe.description", "Completely use up a diamond hoe, and then reevaluate your life choices");
add("advancements.nether.fast_travel.description", "Use the Nether to travel 7km in the Overworld");
add("advancements.story.enter_the_end.description", "Enter the End Portal");
add("advancements.story.follow_ender_eye.title", "Eye Spy");
add("advancements.toast.task", "Advancement Made!");
add("advancements.nether.find_fortress.description", "Break your way into a Nether Fortress");
add("advancements.story.form_obsidian.description", "Form and mine a block of Obsidian");
add("advancements.adventure.sniper_duel.description", "Kill a skeleton with an arrow from more than 50 meters");
add("advancements.end.root.description", "Or the beginning?");
add("advancements.adventure.kill_a_mob.title", "Monster Hunter");
add("advancements.end.elytra.description", "Find an Elytra");
add("advancements.end.dragon_breath.description", "Collect dragon's breath in a glass bottle");
add("advancements.story.enter_the_nether.title", "We Need to Go Deeper");
add("advancements.story.upgrade_tools.title", "Getting an Upgrade");
add("advancements.story.lava_bucket.title", "Hot Stuff");
add("advancements.story.shiny_gear.title", "Cover Me With Diamonds");
add("advancements.story.smelt_iron.description", "Smelt an iron ingot");
add("chat.type.advancement.goal", "%s has reached the goal %s");
add("advancements.husbandry.break_diamond_hoe.title", "Serious Dedication");
add("advancements.story.iron_tools.description", "Upgrade your pickaxe");
add("advancements.end.respawn_dragon.title", "The End... Again...");
add("advancements.husbandry.tame_an_animal.description", "Tame an animal");
add("advancements.end.levitate.description", "Levitate up 50 blocks from the attacks of a Shulker");
add("advancements.adventure.shoot_arrow.description", "Shoot something with a bow and arrow");
add("advancements.nether.root.description", "Bring summer clothes");
add("advancements.story.enchant_item.description", "Enchant an item at an Enchanting Table");
add("advancements.adventure.root.title", "Adventure");
add("advancements.adventure.trade.title", "What a Deal!");
add("advancements.husbandry.breed_all_animals.title", "Two by Two");
add("advancements.nether.find_fortress.title", "A Terrible Fortress");
add("advancements.nether.create_full_beacon.title", "Beaconator");
add("advancements.story.cure_zombie_villager.description", "Weaken and then cure a zombie villager");
add("advancements.toast.challenge", "Challenge Complete!");
add("advancements.nether.create_full_beacon.description", "Bring a beacon to full power");
add("advancements.story.follow_ender_eye.description", "Follow an Ender Eye");
add("advancements.end.find_end_city.title", "The City at the End of the Game");
add("chat.type.advancement.challenge", "%s has completed the challenge %s");
add("advancements.story.deflect_arrow.title", "Not Today, Thank You");
add("advancements.adventure.kill_all_mobs.description", "Kill one of every hostile monster");
add("advancements.story.smelt_iron.title", "Acquire Hardware");
add("advancements.end.levitate.title", "Great View From Up Here");
add("advancements.end.kill_dragon.title", "Free the End");
add("advancements.end.kill_dragon.description", "Good luck");
add("advancements.nether.brew_potion.title", "Local Brewery");
add("advancements.story.enchant_item.title", "Enchanter");
add("advancements.end.respawn_dragon.description", "Respawn the ender dragon");
add("advancements.nether.uneasy_alliance.title", "Uneasy Alliance");
add("advancements.nether.root.title", "Nether");
add("advancements.nether.brew_potion.description", "Brew a potion");
add("advancements.nether.obtain_blaze_rod.title", "Into Fire");
add("advancements.nether.summon_wither.title", "Withering Heights");
add("advancements.story.root.title", "Minecraft");
add("advancements.husbandry.balanced_diet.description", "Eat everything that is edible, even if it's not good for you");
add("advancements.nether.uneasy_alliance.description", "Rescue a Ghast from the Nether, bring it safely home to the Overworld... and then kill it.");
add("advancements.husbandry.breed_all_animals.description", "Breed all the animals!");
add("advancements.adventure.kill_all_mobs.title", "Monsters Hunted");
add("advancements.story.cure_zombie_villager.title", "Zombie Doctor");
add("advancements.husbandry.plant_seed.title", "A Seedy Place");
add("advancements.end.dragon_breath.title", "You Need a Mint");
add("advancements.story.mine_stone.title", "Stone Age");
add("advancements.end.find_end_city.description", "Go on in, what could happen?");
add("advancements.nether.create_beacon.description", "Construct and place a Beacon");
add("advancements.adventure.summon_iron_golem.title", "Hired Help");
add("advancements.end.elytra.title", "Sky's the Limit");
add("chat.type.advancement.task", "%s has made the advancement %s");
add("advancements.story.deflect_arrow.description", "Deflect an arrow with a shield");
add("advancements.nether.all_effects.description", "Have every effect applied at the same time");
add("advancements.story.enter_the_nether.description", "Build, light and enter a Nether Portal");
add("advancements.story.mine_diamond.title", "Diamonds!");
add("advancements.husbandry.balanced_diet.title", "A Balanced Diet");
add("advancements.husbandry.root.title", "Husbandry");
add("advancements.story.root.description", "The heart and story of the game");
add("advancements.story.upgrade_tools.description", "Construct a better pickaxe");
add("advancements.nether.all_effects.title", "How Did We Get Here?");
add("advancements.end.enter_end_gateway.title", "Remote Getaway");
add("advancements.story.mine_stone.description", "Mine stone with your new pickaxe");
add("advancements.husbandry.root.description", "The world is full of friends and food");
add("advancements.end.dragon_egg.title", "The Next Generation");
add("advancements.toast.goal", "Goal Reached!");
add("advancements.empty", "There doesn't seem to be anything here...");
add("advancements.husbandry.tame_an_animal.title", "Best Friends Forever");
add("advancements.end.root.title", "The End");
add("advancements.husbandry.breed_an_animal.title", "The Parrots and the Bats");
add("advancements.story.mine_diamond.description", "Acquire diamonds");
add("advancements.adventure.sleep_in_bed.title", "Sweet dreams");
add("advancements.nether.return_to_sender.title", "Return to Sender");
add("advancements.story.obtain_armor.title", "Suit Up");
add("advancements.adventure.kill_a_mob.description", "Kill any hostile monster");
add("advancements.nether.all_potions.description", "Have every potion effect applied at the same time");
add("advancements.story.iron_tools.title", "Isn't It Iron Pick");
add("advancements.adventure.sleep_in_bed.description", "Change your respawn point");
add("advancements.husbandry.plant_seed.description", "Plant a seed and watch it grow");
add("advancements.husbandry.breed_an_animal.description", "Breed two animals together");
add("advancements.adventure.shoot_arrow.title", "Take Aim");
add("advancements.adventure.adventuring_time.description", "Discover every biome");
add("advancements.adventure.adventuring_time.title", "Adventuring Time");
add("advancements.nether.get_wither_skull.description", "Obtain a wither skeleton's skull");
add("advancements.adventure.summon_iron_golem.description", "Summon an Iron Golem to help defend a village");
add("advancements.nether.return_to_sender.description", "Destroy a Ghast with a fireball");
add("advancements.adventure.trade.description", "Successfully trade with a Villager");
add("advancements.story.obtain_armor.description", "Protect yourself with a piece of iron armor");
add("advancements.adventure.root.description", "Adventure, exploration and combat");
add("advancements.nether.create_beacon.title", "Bring Home the Beacon");
add("advancements.end.dragon_egg.description", "Hold the Dragon Egg");
add("advancements.nether.obtain_blaze_rod.description", "Relieve a Blaze of its rod");
add("advancements.story.lava_bucket.description", "Fill a bucket with lava");
add("advancements.story.form_obsidian.title", "Ice Bucket Challenge");
add("advancements.story.enter_the_end.title", "The End?");
add("advancements.nether.fast_travel.title", "Subspace Bubble");
add("advancements.end.enter_end_gateway.description", "Escape the island");
add("advancements.adventure.totem_of_undying.title", "Postmortal");
add("advancements.nether.all_potions.title", "A Furious Cocktail");
add("advancements.adventure.sniper_duel.title", "Sniper duel");
add("advancements.nether.summon_wither.description", "Summon the Wither");
add("advancements.adventure.totem_of_undying.description", "Use a Totem of Undying to cheat death");
add("advancements.story.shiny_gear.description", "Diamond armor saves lives");
}
private static void add(String key, String value) {
advancements.put(key, value);
}
public static String get(String key) {
return advancements.get(key);
}
}
@@ -8,25 +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.protocol.protocol1_9_4to1_10.packets;
package nl.matsv.viabackwards.protocol.protocol1_11_1to1_12.data;
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;
public class BlockColors {
private static final String[] COLORS = new String[16];
public class ChangedPackets {
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";
}
public void register(BackwardsProtocol protocol) {
/* ServerBound packets */
// 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
}
});
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);
}
}
@@ -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_11_1to1_12.data;
import nl.matsv.viabackwards.api.entities.storage.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;
}
}
@@ -0,0 +1,111 @@
/*
* 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.data;
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_9to1_8.Protocol1_9To1_8;
public class ShoulderTracker extends StoredObject {
private int entityId;
private String leftShoulder;
private String rightShoulder;
public ShoulderTracker(UserConnection user) {
super(user);
}
public void update() {
PacketWrapper wrapper = new PacketWrapper(0x0F, null, getUser());
wrapper.write(Type.COMPONENT, Protocol1_9To1_8.fixJson(generateString()));
wrapper.write(Type.BYTE, (byte) 2);
try {
wrapper.send(Protocol1_11_1To1_12.class);
} catch (Exception e) {
ViaBackwards.getPlatform().getLogger().severe("Failed to send the shoulder indication");
e.printStackTrace();
}
}
// Does actionbar not support json colors? :(
private String generateString() {
StringBuilder builder = new StringBuilder();
// Empty spaces because the non-json formatting is weird
builder.append(" ");
if (leftShoulder == null)
builder.append(ChatColor.RED).append(ChatColor.BOLD).append("Nothing");
else
builder.append(ChatColor.DARK_GREEN).append(ChatColor.BOLD).append(getName(leftShoulder));
builder.append(ChatColor.DARK_GRAY).append(ChatColor.BOLD).append(" <- ")
.append(ChatColor.GRAY).append(ChatColor.BOLD).append("Shoulders")
.append(ChatColor.DARK_GRAY).append(ChatColor.BOLD).append(" -> ");
if (rightShoulder == null)
builder.append(ChatColor.RED).append(ChatColor.BOLD).append("Nothing");
else
builder.append(ChatColor.DARK_GREEN).append(ChatColor.BOLD).append(getName(rightShoulder));
return builder.toString();
}
private String getName(String current) {
if (current.startsWith("minecraft:"))
current = current.substring(10);
String[] array = current.split("_");
StringBuilder builder = new StringBuilder();
for (String s : array) {
builder.append(s.substring(0, 1).toUpperCase())
.append(s.substring(1))
.append(" ");
}
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.UNSIGNED_BYTE); // X
wrapper.passthrough(Type.UNSIGNED_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);
}
}
}
}
@@ -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_11_1to1_12.packets;
import nl.matsv.viabackwards.api.rewriters.Rewriter;
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.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import us.myles.viaversion.libs.gson.JsonElement;
import us.myles.viaversion.libs.gson.JsonObject;
public class ChatPackets1_12 extends Rewriter<Protocol1_11_1To1_12> {
private final ComponentRewriter componentRewriter = new ComponentRewriter() {
@Override
protected void handleTranslate(JsonObject object, String translate) {
String text = AdvancementTranslations.get(translate);
if (text != null) {
object.addProperty("translate", text);
}
}
};
public ChatPackets1_12(Protocol1_11_1To1_12 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_12.CHAT_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
JsonElement element = wrapper.passthrough(Type.COMPONENT);
componentRewriter.processText(element);
});
}
});
}
}
@@ -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);
}
}
@@ -0,0 +1,144 @@
/*
* 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.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.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);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_12.NAMED_SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(Type.FLOAT); // 6 - Pitch
}
});
protocol.registerOutgoing(ClientboundPackets1_12.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(Type.FLOAT); // 6 - Pitch
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int oldId = wrapper.get(Type.VAR_INT, 0);
int newId = handleSounds(oldId);
if (newId == -1) {
wrapper.cancel();
return;
}
if (hasPitch(oldId)) {
wrapper.set(Type.FLOAT, 1, handlePitch(oldId));
}
wrapper.set(Type.VAR_INT, 0, newId);
}
});
}
});
}
@Override
protected void registerRewrites() {
// Replacement sounds, suggestions are always welcome
// Automatically generated from PAaaS
added(26, 277, 1.4f); // block.end_portal.spawn -> entity.lightning.thunder
added(27, -1); // block.end_portal_frame.fill
added(72, 70); // block.note.bell -> block.note.harp
added(73, 70); // block.note.chime -> block.note.harp
added(74, 70); // block.note.flute -> block.note.harp
added(75, 70); // block.note.guitar -> block.note.harp
added(80, 70); // block.note.xylophone -> block.note.harp
added(150, -1); // entity.boat.paddle_land
added(151, -1); // entity.boat.paddle_water
added(152, -1); // entity.bobber.retrieve
added(195, -1); // entity.endereye.death
added(274, 198, 0.8f); // entity.illusion_illager.ambient -> entity.evocation_illager.ambient
added(275, 199, 0.8f); // entity.illusion_illager.cast_spell -> entity.evocation_illager.cast_spell
added(276, 200, 0.8f); // entity.illusion_illager.death -> entity.evocation_illager.death
added(277, 201, 0.8f); // entity.illusion_illager.hurt -> entity.evocation_illager.hurt
added(278, 191, 0.9f); // entity.illusion_illager.mirror_move -> entity.endermen.teleport
added(279, 203, 1.5f); // entity.illusion_illager.prepare_blindness -> entity.evocation_illager.prepare_summon
added(280, 202, 0.8f); // entity.illusion_illager.prepare_mirror -> entity.evocation_illager.prepare_attack
added(319, 133, 0.6f); // entity.parrot.ambient -> entity.bat.ambient
added(320, 134, 1.7f); // entity.parrot.death -> entity.bat.death
added(321, 219, 1.5f); // entity.parrot.eat -> entity.generic.eat
added(322, 136, 0.7f); // entity.parrot.fly -> entity.bat.loop
added(323, 135, 1.6f); // entity.parrot.hurt -> entity.bat.hurt
added(324, 138, 1.5f); // entity.parrot.imitate.blaze -> entity.blaze.ambient
added(325, 163, 1.5f); // entity.parrot.imitate.creeper -> entity.creeper.primed
added(326, 170, 1.5f); // entity.parrot.imitate.elder_guardian -> entity.elder_guardian.ambient
added(327, 178, 1.5f); // entity.parrot.imitate.enderdragon -> entity.enderdragon.ambient
added(328, 186, 1.5f); // entity.parrot.imitate.enderman -> entity.endermen.ambient
added(329, 192, 1.5f); // entity.parrot.imitate.endermite -> entity.endermite.ambient
added(330, 198, 1.5f); // entity.parrot.imitate.evocation_illager -> entity.evocation_illager.ambient
added(331, 226, 1.5f); // entity.parrot.imitate.ghast -> entity.ghast.ambient
added(332, 259, 1.5f); // entity.parrot.imitate.husk -> entity.husk.ambient
added(333, 198, 1.3f); // entity.parrot.imitate.illusion_illager -> entity.evocation_illager.ambient
added(334, 291, 1.5f); // entity.parrot.imitate.magmacube -> entity.magmacube.squish
added(335, 321, 1.5f); // entity.parrot.imitate.polar_bear -> entity.polar_bear.ambient
added(336, 337, 1.5f); // entity.parrot.imitate.shulker -> entity.shulker.ambient
added(337, 347, 1.5f); // entity.parrot.imitate.silverfish -> entity.silverfish.ambient
added(338, 351, 1.5f); // entity.parrot.imitate.skeleton -> entity.skeleton.ambient
added(339, 363, 1.5f); // entity.parrot.imitate.slime -> entity.slime.squish
added(340, 376, 1.5f); // entity.parrot.imitate.spider -> entity.spider.ambient
added(341, 385, 1.5f); // entity.parrot.imitate.stray -> entity.stray.ambient
added(342, 390, 1.5f); // entity.parrot.imitate.vex -> entity.vex.ambient
added(343, 400, 1.5f); // entity.parrot.imitate.vindication_illager -> entity.vindication_illager.ambient
added(344, 403, 1.5f); // entity.parrot.imitate.witch -> entity.witch.ambient
added(345, 408, 1.5f); // entity.parrot.imitate.wither -> entity.wither.ambient
added(346, 414, 1.5f); // entity.parrot.imitate.wither_skeleton -> entity.wither_skeleton.ambient
added(347, 418, 1.5f); // entity.parrot.imitate.wolf -> entity.wolf.ambient
added(348, 427, 1.5f); // entity.parrot.imitate.zombie -> entity.zombie.ambient
added(349, 438, 1.5f); // entity.parrot.imitate.zombie_pigman -> entity.zombie_pig.ambient
added(350, 442, 1.5f); // entity.parrot.imitate.zombie_villager -> entity.zombie_villager.ambient
added(351, 155); // entity.parrot.step -> entity.chicken.step
added(368, 316); // entity.player.hurt_drown -> entity.player.hurt
added(369, 316); // entity.player.hurt_on_fire -> entity.player.hurt
// No replacement sounds for these, since it could be confusing, the toast doesn't show up
added(544, -1); // ui.toast.in
added(545, -1); // ui.toast.out
added(546, 317, 1.5f); // ui.toast.challenge_complete
}
}
@@ -0,0 +1,55 @@
/*
* 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_11to1_11_1;
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;
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(this)).register();
new ItemPackets1_11_1(this).register();
}
@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);
}
public EntityPackets1_11_1 getEntityPackets() {
return entityPackets;
}
}
@@ -0,0 +1,119 @@
/*
* 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_11to1_11_1.packets;
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.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.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
public class EntityPackets1_11_1 extends LegacyEntityRewriter<Protocol1_11To1_11_1> {
public EntityPackets1_11_1(Protocol1_11To1_11_1 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
protocol.registerOutgoing(ClientboundPackets1_9_3.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_11Types.ObjectType.findById(id).orElse(null)));
}
});
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, Entity1_11Types.EntityType.EXPERIENCE_ORB);
registerExtraTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, Entity1_11Types.EntityType.WEATHER);
protocol.registerOutgoing(ClientboundPackets1_9_3.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_9.METADATA_LIST); // 12 - Metadata
// Track entity
handler(getTrackerHandler());
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_9.METADATA_LIST));
}
});
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);
protocol.registerOutgoing(ClientboundPackets1_9_3.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_9.METADATA_LIST); // 7 - Metadata list
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, Entity1_11Types.EntityType.PLAYER));
}
});
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(Entity1_11Types.EntityType.FIREWORK, 7).removed();
// Handle non-existing pig metadata (index 14 - boost time)
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);
}
}
@@ -0,0 +1,130 @@
/*
* 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_11to1_11_1.packets;
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.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 LegacyBlockItemRewriter<Protocol1_11To1_11_1> {
private LegacyEnchantmentRewriter enchantmentRewriter;
public ItemPackets1_11_1(Protocol1_11To1_11_1 protocol) {
super(protocol);
}
@Override
protected void registerPackets() {
ItemRewriter itemRewriter = new ItemRewriter(protocol, this::handleItemToClient, this::handleItemToServer);
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(ClientboundPackets1_9_3.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
}
}
}
});
}
});
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
data.setValue(handleItemToClient((Item) data.getValue()));
}
return data;
});
}
@Override
protected void registerRewrites() {
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;
}
}
@@ -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_1to1_12_2;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
public class KeepAliveTracker extends StoredObject {
private long keepAlive = Integer.MAX_VALUE;
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,28 +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.chunks;
package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import lombok.AllArgsConstructor;
import lombok.Data;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
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;
import java.util.List;
@Data
@AllArgsConstructor
public class Chunk1_10 implements Chunk {
private int x;
private int z;
private boolean groundUp;
private int bitmask;
private ChunkSection1_10[] sections;
private byte[] biomeData;
private List<CompoundTag> blockEntities;
public class BedHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
@Override
public boolean isBiomeData() {
return biomeData != null;
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
int offset = blockId - 748;
int color = offset >> 4;
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.CUSTOM_STATS.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,197 @@
/*
* 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)};
}
@Override
public boolean isBlockHandler() {
return true;
}
};
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);
}
public interface ParticleHandler {
int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception;
int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data);
default boolean isBlockHandler() {
return false;
}
}
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,416 @@
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 = meta.getValue().toString();
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) {
if (data.getHandler().isBlockHandler() && particleArgs[0] == 0) {
// Air doesn't have a break particle for sub 1.13 clients -> glass pane
particleArgs[0] = 102;
}
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,566 @@
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 us.myles.viaversion.libs.gson.JsonElement;
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) {
if (old.getHandler().isBlockHandler() && data[0] == 0) {
// Cancel air block particles
wrapper.cancel();
return;
}
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.COMPONENT);
}
} 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.COMPONENT);
}
} 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.COMPONENT).toString();
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;
}
JsonElement prefixComponent = wrapper.read(Type.COMPONENT);
JsonElement suffixComponent = wrapper.read(Type.COMPONENT);
String prefix = prefixComponent == null || prefixComponent.isJsonNull() ? "" : ChatRewriter.jsonTextToLegacy(prefixComponent.toString());
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);
String suffix = suffixComponent == null || suffixComponent.isJsonNull() ? "" : ChatRewriter.jsonTextToLegacy(suffixComponent.toString());
suffix = ChatUtil.removeUnusedColor(suffix, '\0'); // Don't remove white coloring
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);
}
}
@@ -0,0 +1,20 @@
package nl.matsv.viabackwards.protocol.protocol1_12to1_12_1;
import nl.matsv.viabackwards.api.BackwardsProtocol;
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_12to1_11_1.ClientboundPackets1_12;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.ServerboundPackets1_12;
public class Protocol1_12To1_12_1 extends BackwardsProtocol<ClientboundPackets1_12_1, ClientboundPackets1_12, ServerboundPackets1_12_1, ServerboundPackets1_12> {
public Protocol1_12To1_12_1() {
super(ClientboundPackets1_12_1.class, ClientboundPackets1_12.class, ServerboundPackets1_12_1.class, ServerboundPackets1_12.class);
}
@Override
protected void registerPackets() {
cancelOutgoing(ClientboundPackets1_12_1.CRAFT_RECIPE_RESPONSE);
cancelIncoming(ServerboundPackets1_12.PREPARE_CRAFTING_GRID);
}
}
@@ -0,0 +1,94 @@
package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets.EntityPackets1_13_2;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets.InventoryPackets1_13_2;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets.WorldPackets1_13_2;
import us.myles.ViaVersion.api.PacketWrapper;
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.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
public class Protocol1_13_1To1_13_2 extends BackwardsProtocol<ClientboundPackets1_13, ClientboundPackets1_13, ServerboundPackets1_13, ServerboundPackets1_13> {
public Protocol1_13_1To1_13_2() {
super(ClientboundPackets1_13.class, ClientboundPackets1_13.class, ServerboundPackets1_13.class, ServerboundPackets1_13.class);
}
@Override
protected void registerPackets() {
InventoryPackets1_13_2.register(this);
WorldPackets1_13_2.register(this);
EntityPackets1_13_2.register(this);
registerIncoming(ServerboundPackets1_13.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM);
}
});
registerOutgoing(ClientboundPackets1_13.ADVANCEMENTS, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN))
wrapper.passthrough(Type.STRING);
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.COMPONENT); // Title
wrapper.passthrough(Type.COMPONENT); // Description
Item icon = wrapper.read(Type.FLAT_VAR_INT_ITEM);
wrapper.write(Type.FLAT_ITEM, icon);
wrapper.passthrough(Type.VAR_INT); // Frame type
int flags = wrapper.passthrough(Type.INT); // Flags
if ((flags & 1) != 0)
wrapper.passthrough(Type.STRING); // Background texture
wrapper.passthrough(Type.FLOAT); // X
wrapper.passthrough(Type.FLOAT); // Y
}
wrapper.passthrough(Type.STRING_ARRAY); // Criteria
int arrayLength = wrapper.passthrough(Type.VAR_INT);
for (int array = 0; array < arrayLength; array++) {
wrapper.passthrough(Type.STRING_ARRAY); // String array
}
}
}
});
}
});
new StatisticsRewriter(this, null, null, null, id -> {
int newId = id;
if (newId > 40) {
if (id == 41) return -1;
newId--;
}
if (newId > 25) {
if (id <= 28) return -1;
newId -= 3;
}
if (newId > 22) {
if (id <= 24) return -1;
newId -= 2;
}
return newId;
}).register(ClientboundPackets1_13.STATISTICS);
}
}
@@ -0,0 +1,94 @@
package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.Protocol1_13_1To1_13_2;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13_2;
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_13;
import us.myles.ViaVersion.api.type.types.version.Types1_13_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
public class EntityPackets1_13_2 {
public static void register(Protocol1_13_1To1_13_2 protocol) {
protocol.registerOutgoing(ClientboundPackets1_13.SPAWN_MOB, 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 - 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_13_2.METADATA_LIST, Types1_13.METADATA_LIST); // 12 - Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (Metadata metadata : wrapper.get(Types1_13.METADATA_LIST, 0)) {
if (metadata.getMetaType() == MetaType1_13_2.Slot) {
metadata.setMetaType(MetaType1_13.Slot);
}
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.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_13_2.METADATA_LIST, Types1_13.METADATA_LIST); // 7 - Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (Metadata metadata : wrapper.get(Types1_13.METADATA_LIST, 0)) {
if (metadata.getMetaType() == MetaType1_13_2.Slot) {
metadata.setMetaType(MetaType1_13.Slot);
}
}
}
});
}
});
protocol.registerOutgoing(ClientboundPackets1_13.ENTITY_METADATA, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_13_2.METADATA_LIST, Types1_13.METADATA_LIST); // 1 - Metadata list
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (Metadata metadata : wrapper.get(Types1_13.METADATA_LIST, 0)) {
if (metadata.getMetaType() == MetaType1_13_2.Slot) {
metadata.setMetaType(MetaType1_13.Slot);
}
}
}
});
}
});
}
}
@@ -0,0 +1,132 @@
package nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.packets;
import nl.matsv.viabackwards.protocol.protocol1_13_1to1_13_2.Protocol1_13_1To1_13_2;
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.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
public class InventoryPackets1_13_2 {
public static void register(Protocol1_13_1To1_13_2 protocol) {
protocol.registerOutgoing(ClientboundPackets1_13.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.FLAT_VAR_INT_ITEM, Type.FLAT_ITEM); // 2 - Slot Value
}
});
protocol.registerOutgoing(ClientboundPackets1_13.WINDOW_ITEMS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.FLAT_VAR_INT_ITEM_ARRAY, Type.FLAT_ITEM_ARRAY); // 1 - Window Values
}
});
protocol.registerOutgoing(ClientboundPackets1_13.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
String channel = wrapper.get(Type.STRING, 0);
if (channel.equals("minecraft:trader_list") || channel.equals("trader_list")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
// Input Item
wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM));
// Output Item
wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM));
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) {
wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_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.registerOutgoing(ClientboundPackets1_13.ENTITY_EQUIPMENT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.VAR_INT); // 1 - Slot ID
map(Type.FLAT_VAR_INT_ITEM, Type.FLAT_ITEM); // 2 - Item
}
});
protocol.registerOutgoing(ClientboundPackets1_13.DECLARE_RECIPES, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int recipesNo = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < recipesNo; i++) {
wrapper.passthrough(Type.STRING); // Id
String type = wrapper.passthrough(Type.STRING);
if (type.equals("crafting_shapeless")) {
wrapper.passthrough(Type.STRING); // Group
int ingredientsNo = wrapper.passthrough(Type.VAR_INT);
for (int i1 = 0; i1 < ingredientsNo; i1++) {
wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT));
}
wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM));
} else if (type.equals("crafting_shaped")) {
int ingredientsNo = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.STRING); // Group
for (int i1 = 0; i1 < ingredientsNo; i1++) {
wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT));
}
wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM));
} else if (type.equals("smelting")) {
wrapper.passthrough(Type.STRING); // Group
// Ingredient start
wrapper.write(Type.FLAT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT));
// Ingredient end
wrapper.write(Type.FLAT_ITEM, wrapper.read(Type.FLAT_VAR_INT_ITEM));
wrapper.passthrough(Type.FLOAT); // EXP
wrapper.passthrough(Type.VAR_INT); // Cooking time
}
}
}
});
}
});
protocol.registerIncoming(ServerboundPackets1_13.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.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); // 5 - Clicked Item
}
});
protocol.registerIncoming(ServerboundPackets1_13.CREATIVE_INVENTORY_ACTION, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT); // 0 - Slot
map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); // 1 - Clicked Item
}
});
}
}
Loaded 100 of 169 files, more files were not shown because too many files have changed in this diff. Show more