Compare commits

..
149 Commits
Author SHA1 Message Date
Nassim Jahnke a8acae2d5f 4.8.1 Release 2023-10-03 20:57:47 +10:00
Nassim Jahnke fdb7f47749 Properly throw the client information packet into the queue instead 2023-10-03 20:54:51 +10:00
Nassim Jahnke cabb95a3a4 Schedule send client information 2023-10-03 20:39:46 +10:00
Nassim Jahnke 0b93af88a3 Re-send client information when re-entering play state
Fixes #3442
2023-10-03 19:49:55 +10:00
Unoqwy 11cb113619 Fix disconnecting error for unknown mobs with metadata (#3443) 2023-10-03 09:46:02 +00:00
Nassim Jahnke 429e4f0bff Switch server state after sending game profile
Probably fixes #3453
2023-09-28 11:12:46 +10:00
Nassim Jahnke 3b0d1d961a Fix secondary effect reading in serverbound beacon
Fixes #3455
2023-09-28 09:34:26 +10:00
Nassim Jahnke b4720c723a Fix biome and chunk size preconditions 2023-09-27 14:35:20 +10:00
Nassim Jahnke 215cbc6310 Fix 1.20.2 custom potion effect handling
Fixes #3448
2023-09-27 11:30:35 +10:00
RK_01 f07ba9b527 Reduce delay for sequence acknowledgements (#3445) 2023-09-26 10:53:36 +10:00
Misode 5a20030ff3 [ci skip] Update Minecraft Wiki link to new domain after fork (#3446) 2023-09-26 10:52:03 +10:00
Nassim Jahnke 1b350c0c53 Try to fix ci 2023-09-26 10:40:44 +10:00
Nassim Jahnke 87db6fc75a [ci skip] Fix branch check 2023-09-26 00:17:33 +10:00
Nassim Jahnke 840770a350 Fix missing server state change 2023-09-25 20:11:29 +10:00
Nassim Jahnke 3997ea70f7 Fixup state splitting 2023-09-25 18:59:15 +10:00
Nassim Jahnke 854696abff Add separate client and server protocol state 2023-09-25 16:44:41 +10:00
Nassim Jahnke d92b9fdeaa Fix connection field search on 1.20.2 2023-09-25 09:57:55 +10:00
Nassim Jahnke 270d28f259 Don't cancel custom query answer 2023-09-25 08:56:26 +10:00
RK_01 ed1852ba40 Fix 1.20.2 -> 1.20.1 brand custom payloads properly (#3440) 2023-09-25 08:52:17 +10:00
riku6460 f91e6a83f9 Fix sign nbt on 1.20 client (#3436) 2023-09-24 13:02:31 +10:00
Nassim Jahnke 8a0e187621 Drop custom payloads with non-alphanumerical brands
For some reason the client errors only if it contains certain characters, needs further investigation. Mojang changed their string writing implementation, though the actual encoding does not seem to have changed, and this error does not occur anywhere else
2023-09-24 10:48:47 +10:00
Nassim Jahnke 0e8b5e8e98 Bump version to 4.8.1-SNAPSHOT 2023-09-24 10:47:43 +10:00
Nassim Jahnke e30dd63b3c [ci skip] Only publish releases from the main branch 2023-09-22 15:32:14 +10:00
Nassim Jahnke 489b28e520 4.8.0 Release 2023-09-21 10:34:20 +10:00
Nassim Jahnke d23e743550 Fix particle handling 2023-09-21 10:33:58 +10:00
Nassim Jahnke 16f89f2638 Don't re-enter config state if the dimension registry did not change 2023-09-19 21:14:45 +10:00
Nassim Jahnke fe5646a68c Re-send last resource pack on server switch 2023-09-19 11:54:03 +10:00
Nassim Jahnke 53aca791dd Fix reentering of the configuration state 2023-09-19 00:37:55 +10:00
Nassim Jahnke 1f0a4c26db 1.20.2-rc2 2023-09-19 00:07:43 +10:00
Nassim Jahnke 4c34ced240 Fix record handling due to no mappings
Fixes #3422
2023-09-16 13:28:15 +10:00
Nassim Jahnke 18c4f90cb0 Don't cancel system chat messages 2023-09-16 13:27:44 +10:00
Nassim Jahnke 9c90445c9c Release ConfigurationState buffers on disconnect
They're heap buffers, but still good practice
2023-09-16 13:27:23 +10:00
Nassim Jahnke 494e6ffc05 1.20.2-rc1 2023-09-16 10:19:49 +10:00
Nassim Jahnke a196dbc16b 1.20.2-pre4 2023-09-14 09:03:13 +10:00
Nassim Jahnke 8934bbdfc3 1.20.2-pre3 2023-09-12 23:06:54 +10:00
Myles 8316c59010 Merge pull request #3420 from Kichura/dev 2023-09-11 19:55:27 +01:00
Kichura 5ea1c1ec95 Use https instead of http for wiki.vg source. 2023-09-11 20:06:27 +02:00
Nassim Jahnke cc7c571a3c 1.20.2-pre2 2023-09-08 09:05:31 +10:00
Nassim Jahnke 06b4678b2d [ci skip] Add IDEA extension plugin 2023-09-06 11:20:32 +10:00
Nassim Jahnke a109118a97 1.20.2-pre1 2023-09-06 00:56:31 +10:00
Nassim Jahnke a135a1414c [ci skip] Update Gradle wrapper 2023-09-05 21:16:24 +10:00
Nassim Jahnke f50751ed48 [ci skip] Update blossom 2023-09-05 21:10:43 +10:00
Kichura 4b7998b4ea [ci skip] Update checkout to v4, Check for latest JDK 11 build (#3416) 2023-09-05 20:48:36 +10:00
Nassim Jahnke 6db1a2a614 Fix wrong packet type being used 2023-08-31 11:49:54 +10:00
Nassim Jahnke 625373827c Fix MetaTypes1_20_2 item type 2023-08-31 11:44:55 +10:00
Nassim Jahnke a9288ebd3a 23w35a 2023-08-31 00:42:47 +10:00
Nassim Jahnke 01bbb2c1c2 [ci skip] Update Hangar publish plugin 2023-08-26 20:04:06 +10:00
Nassim Jahnke 8dbc8e8eba Update mappings file for 23w33a 2023-08-18 01:28:55 +10:00
Nassim Jahnke 0c9f3aa080 23w33a 2023-08-18 01:27:00 +10:00
EnZaXD 00625be890 Move 1.9 backwards protocols to VB and move Chunk Types to the correct package (#3404) 2023-08-14 10:46:30 +10:00
Pablo Herrera e112f81ec8 Optimize memory allocation for data palette (#3402) 2023-08-14 10:40:10 +10:00
Nassim Jahnke 23f776a6ee Handle minecart blocks 2023-08-11 21:12:23 +10:00
Nassim Jahnke 0050872950 Update README 2023-08-11 21:12:03 +10:00
Nassim Jahnke 7e53f55509 Also publish dev branch builds to Hangar 2023-08-11 20:33:47 +10:00
Nassim Jahnke 1bf7962dc3 Call latestCommitHash only once 2023-08-11 16:24:27 +10:00
Nassim Jahnke 50176dc317 Include link to commit in autopublished changelog 2023-08-11 16:21:44 +10:00
Nassim Jahnke 9ed074d0d5 Handle changes block state ids 2023-08-11 15:52:53 +10:00
Nassim Jahnke 8bad8a10be Finish publishing action 2023-08-11 12:28:38 +10:00
Nassim Jahnke 34509e86c0 [ci skip] Add Velocity and Waterfall to publish config 2023-08-11 00:39:45 +10:00
Nassim Jahnke ef75bd567d [ci skip] GH already skips all actions with ci skip 2023-08-10 22:48:22 +10:00
Nassim Jahnke 7ed3e50e93 [ci skip] Skip commits with ci skip prefix 2023-08-10 22:46:15 +10:00
Nassim Jahnke a45eceaf1d Hello Hangar 😎 2023-08-10 22:18:23 +10:00
Nassim Jahnke 573cdfb3ac Merge remote-tracking branch 'origin/master' into dev 2023-08-10 21:49:26 +10:00
Nassim Jahnke 28787340d1 Setup Hangar and modrinth autopublishing 2023-08-10 21:29:03 +10:00
Nassim Jahnke c358245c0b Fix spawn tracker mapping data check 2023-08-10 17:14:01 +10:00
Nassim Jahnke cb073405b7 Effect ids start at 1 before 1.20.2 2023-08-10 17:08:36 +10:00
Nassim Jahnke f618f6a7d6 Actually write effect key 2023-08-10 13:51:15 +10:00
Nassim Jahnke c5e066e050 23w32a 2023-08-10 13:35:47 +10:00
riku6460 d954e1745d Fix itemArrayType of ItemRewriter on dev branch (#3398) 2023-08-09 07:38:24 +10:00
Nassim Jahnke 9c92ccea77 Finish up state switching 2023-08-06 15:40:15 +10:00
RK_01 2b9e0cec5c Fix maps with no map id set showing up as empty on 1.17+ (#3395) 2023-08-06 11:11:42 +10:00
RK_01 c1cd8bc03e Allow skylight to be set to null (#3396) 2023-08-06 11:08:52 +10:00
Nassim Jahnke 39efc5262e Add todo 2023-08-05 13:31:43 +10:00
Nassim Jahnke 6e5e115c3b Remove unnecessary rewriting code, fix recipe handlers 2023-08-05 12:28:39 +10:00
Nassim Jahnke fbcbd33c66 Small refactors 2023-08-04 12:35:35 +10:00
Nassim Jahnke 7bea3142bc Fix baseprotocol registration 2023-08-04 12:26:07 +10:00
Nassim Jahnke fb472c3454 Cleanup imports 2023-08-04 12:25:29 +10:00
Nassim Jahnke ac10bb3fd0 Complete 23w31a protocol 2023-08-04 12:22:18 +10:00
Nassim Jahnke 1bc3d407d1 More juicy, untested work 2023-08-03 23:03:42 +10:00
Nassim Jahnke 62c0ef360f More absolutely cursed WIP 2023-08-03 21:58:23 +10:00
Nassim Jahnke 8c6d104faa 23w31a eletric boogaloo 2023-08-03 19:47:18 +10:00
Nassim Jahnke f6b8c4a8c8 Rename rewriter classes 2023-08-03 18:38:18 +10:00
Nassim Jahnke 6586fc1436 More work on the snapshot 2023-08-03 18:36:30 +10:00
Nassim Jahnke 6dfd4747ee Start working on 23w31a 2023-08-03 13:58:22 +10:00
Nassim Jahnke 6377721ebd Fix non item display rotation
Fixes #3383
2023-07-24 20:56:45 +10:00
RK_01 2ec6185c46 Fix <= 1.14 position y sign reading (#3381) 2023-07-12 19:10:49 +02:00
Nassim Jahnke b22907748a Update gradle wrapper 2023-07-11 23:34:37 +02:00
Nassim Jahnke 1aee8a7a6c Don't create ack task when already disabled
Fixes #3373
2023-07-02 13:29:07 +02:00
Nassim Jahnke 7edb43844c Properly handle item display rotation change
Fixes #3354
2023-07-02 13:27:03 +02:00
sandtechnology f28aac5eb3 Handle more null TextComponent for 1.19 to 1.18.2 (#3366) 2023-06-24 11:12:14 +02:00
Nassim Jahnke 4971eeab6a Don't check block items for armor swapping 2023-06-22 11:03:11 +02:00
Pablo Herrera 0bb940e42d Fix missing block connection updates on cancelled place/remove (#3359) 2023-06-20 13:39:02 +02:00
Pablo Herrera e32933ada9 Fix late registration of join listener (#3360) 2023-06-19 17:02:05 +02:00
EnZaXD a817746edc Remove requirement for MovementTransmitterProvider (#3355) 2023-06-18 15:30:58 +02:00
RK_01 408392e796 Fixed some 1.9 -> 1.8 movement issues (#3353) 2023-06-18 14:51:37 +02:00
Kichura 20a4ae3e4b Use friendly names in CI tasks, Update shadow and blossom (#3349) 2023-06-15 09:48:13 +02:00
Nassim Jahnke 08b2d78165 Move dump creation to util class 2023-06-14 23:13:44 +02:00
FlorianMichael 17eb7b676a Remap old smithing menu to furnace in 1.20 2023-06-12 18:57:20 +02:00
Nassim Jahnke 9a1598b9ed Update 1.20/1.20.1 protocol version 2023-06-12 16:47:22 +02:00
Myles 9e7cd151bc Update version table to 1.20 2023-06-11 12:02:25 +01:00
David Luedtke 2a14f9a0cd Fix display rotation change 2023-06-09 12:17:11 +02:00
Ossi Erkkilä bf825d5ef6 Fix SpongeViaInjector#getServerProtocolVersion() for Sponge API-10+ (#3337) 2023-06-09 11:29:55 +02:00
EnZaXD 28ba4afc27 Added VersionInfo#getVersion to bypass Java inlining (#3344) 2023-06-09 08:52:30 +02:00
Nassim Jahnke 7f347231bb Bump version to 4.7.1-SNAPSHOT 2023-06-08 13:21:19 +02:00
Nassim Jahnke f1b5f9223a 4.7.0 Release 2023-06-06 13:30:57 +02:00
Nassim Jahnke e4a1530aa8 Fix >1.18 vibration particle handling 2023-06-06 13:28:02 +02:00
Nassim Jahnke 09b67fad63 Small cleanup 2023-06-06 12:30:56 +02:00
Nassim Jahnke 1b3c5b4032 Create its own packets enum for 1.14.4
Acknowledge player digging was only added then, make sure this is represented correctly
2023-06-05 09:06:15 +02:00
Nassim Jahnke b7d8a3c8d5 1.20-rc1 2023-05-31 15:40:23 +02:00
Kichura 9a515df0f3 Update dependencies (#3332) 2023-05-30 09:25:18 +02:00
Nassim Jahnke c6103f2f51 1.20-pre7 2023-05-29 16:54:45 +02:00
Nassim Jahnke 5c0eda76e8 Don't replace unchanged 1.12->1.13 translations with hard text
Also add the remaining unchanged keys to the file
Fixes #3284
2023-05-28 13:48:22 +02:00
Nassim Jahnke 544a28b06b 1.20-pre6 2023-05-25 15:09:42 +02:00
RK_01 5c145d0184 Fixed high CPU usage on Java 8 (#3325)
Fixed https://bugs.openjdk.java.net/browse/JDK-8129861 by setting the core size of the TaskScheduler ThreadPool to 1
2023-05-23 18:18:10 +02:00
Nassim Jahnke ed55bccfe4 Fix 1.19.3->1.19.4 statistics handling
Fixes #3324
2023-05-23 16:39:20 +02:00
Nassim Jahnke 5acc2fefbc 1.20-pre5 2023-05-23 15:40:54 +02:00
Nassim Jahnke 7f748b5c68 1.20-pre4 2023-05-19 15:40:54 +02:00
Nassim Jahnke 0ec03f8b09 1.20-pre3 2023-05-19 14:22:14 +02:00
Nassim Jahnke a70034e0b5 Remove early static initializer call
Weird NoClassDefFoundError going on
2023-05-18 11:53:34 +02:00
Nassim Jahnke 98a0fdca94 1.20-pre2 2023-05-16 16:00:36 +02:00
Nassim JahnkeandPantera 82961cc153 Add 1.20 sound mappings
Co-authored-by: Pantera (Mad_Daniel) <89838384+Pantera07@users.noreply.github.com>
2023-05-14 08:42:51 +02:00
Nassim Jahnke 6c0d891c9f Don't print mapping validity warning if conversion warnings are disabled 2023-05-14 08:38:24 +02:00
Nassim Jahnke 6fa387e6ab Update the rest of nbt files to be uncompressed 2023-05-10 15:53:53 +02:00
Nassim Jahnke 07bdb57694 1.20-pre1 2023-05-10 15:46:03 +02:00
Nassim Jahnke 75dd79347a Update mappings 2023-05-05 21:05:35 +02:00
Nassim Jahnke 9257890d3c Update protocol version 2023-05-05 18:50:15 +02:00
Nassim Jahnke 891f55192d 23w18a, maybe 2023-05-03 15:21:24 +02:00
EnZaXD 7adadc0d21 added PlayerAbilities Provider (#3311) 2023-05-03 09:17:51 +02:00
Camotoy 638378cddf Let records properly stop in 1.19.3 -> 1.19.4 (#3308)
Fixes #3307
2023-04-28 14:44:29 +02:00
Nassim Jahnke 56d772df34 23w17a 2023-04-26 18:46:52 +02:00
Nassim Jahnke 7bb5cf3ae9 Update Gradle wrapper 2023-04-26 12:23:02 +02:00
Nassim Jahnke b67e3c30fd Move packet construction of schedule send methods to event loop as well
Fixes #3306
2023-04-26 12:18:08 +02:00
EnZaXD a2e214ae18 Improve InventoryTracker16 Code (#3302) 2023-04-22 08:57:47 +02:00
Nassim Jahnke 54d8e29a7e 23w16a 2023-04-20 17:28:30 +02:00
Joseph Burton a2daa9c989 Fix PlayerLookTargetProvider, apparently this packet is written in two different places (#3301) 2023-04-19 14:43:39 +02:00
Nassim Jahnke 74cc42fecf Merge remote-tracking branch 'origin/master' into dev 2023-04-19 12:08:15 +02:00
Joseph Burton dd59ddbd4f Add PlayerLookTargetProvider (#3299) 2023-04-19 12:04:17 +02:00
Nassim Jahnke bcfc77aa7d Merge branch 'master' into dev 2023-04-18 13:35:14 +02:00
Nassim Jahnke 1a46346789 Handle optional block state entity meta 2023-04-18 13:34:20 +02:00
RK_01 394be165fd Handle ENTITY_TELEPORT's targeting the client player (#3296) 2023-04-14 16:38:39 +02:00
Nassim Jahnke 20d86374b5 23w14a 2023-04-05 15:25:37 +02:00
Nassim Jahnke 8864b161f9 Print plugin name in unsupported software matching 2023-04-02 09:41:20 +02:00
Nassim Jahnke 7b0160d6c3 Fix redstone blockconnections
Fixes #3281
2023-03-31 16:41:06 +02:00
Nassim Jahnke 7e5173982d 23w13a 2023-03-29 16:32:50 +02:00
Nassim Jahnke ee75f19790 Merge branch 'master' into dev
# Conflicts:
#	gradle.properties
2023-03-29 16:28:57 +02:00
Nassim Jahnke e54f6d1999 Override metatypeimpl tostring 2023-03-28 17:27:22 +02:00
Nassim Jahnke c46bb5bcf5 Update Folia check 2023-03-25 00:31:50 +01:00
Nassim Jahnke 9682b68251 Handle sign nbt changes 2023-03-24 11:19:51 +01:00
Nassim Jahnke 364cfad9d8 23w12a 2023-03-22 18:49:18 +01:00
165 changed files with 4786 additions and 1164 deletions

No files matched your search

+5 -9
View File
@@ -1,6 +1,3 @@
# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Java CI with Gradle
on: [push, pull_request]
@@ -13,16 +10,15 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 11
check-latest: true
- name: Build with Gradle
run: ./gradlew build
- uses: actions/upload-artifact@v3
with:
name: artifact
path: build/libs
+27
View File
@@ -0,0 +1,27 @@
name: Publish to Hangar and Modrinth
on:
push:
branches:
- master
- dev
jobs:
publish:
if: github.repository_owner == 'ViaVersion'
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
check-latest: true
- name: Publish
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew build modrinth publishAllPublicationsToHangar --stacktrace
+43 -33
View File
@@ -1,49 +1,41 @@
# ViaVersion - Spigot, Sponge, BungeeCord, Velocity
# ViaVersion
[![Latest Release](https://img.shields.io/github/v/release/ViaVersion/ViaVersion)](https://viaversion.com)
[![Build Status](https://github.com/ViaVersion/ViaVersion/actions/workflows/gradle.yml/badge.svg?branch=master)](https://github.com/ViaVersion/ViaVersion/actions)
[![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord)
**Allows the connection of higher client versions to lower server versions**
**Allows the connection of higher client versions to lower server versions -
it works on any platform you can think of.**
The base ViaVersion jar runs on Paper, Velocity, Bungee, and Sponge. We also have projects integrating ViaVersion to run
on Fabric, Forge, or as a standalone proxy to join from basically any client version on any server version from the
past decade. **See [HERE](https://github.com/ViaVersion) for an overview of the different Via\* projects.**
Supported Versions:
![Table (https://i.imgur.com/aSjHvQk.png)](https://i.imgur.com/aSjHvQk.png)
On Paper you may also use ProtocolSupport, but ensure you have the right build for your server version.
![Table (https://i.imgur.com/sTrVnC2.png)](https://i.imgur.com/sTrVnC2.png)
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/
Sources
Releases/Dev Builds
--------
**[OpenNBT](https://github.com/ViaVersion/OpenNBT)**
You can find official releases in the following places:
**[Via Mappings Generator](https://github.com/ViaVersion/Mappings)**
- **Hangar (for our plugins)**: https://hangar.papermc.io/ViaVersion/ViaVersion
- **Modrinth (for our mods)**: https://modrinth.com/mod/viaversion
- **GitHub**: https://github.com/ViaVersion/ViaVersion/releases
**[Mojang mappings](https://minecraft.fandom.com/wiki/Obfuscation_map)** (Thank you, Mojang, very cool)
Dev builds for **all** of our projects are on our Jenkins server:
**[wiki.vg](https://wiki.vg)** (Used for historic information regarding packet structure, we also contribute back)
**[Burger](https://github.com/Pokechu22/Burger)** (See [PAaaS](https://github.com/Matsv/Paaas))
Releases / Dev Builds
--------
You can find official releases here:
https://www.spigotmc.org/resources/viaversion.19254/history
- **Jenkins**: https://ci.viaversion.com
ViaVersion as a Dependency
----------
You can find official dev builds here:
**Jenkins:** https://ci.viaversion.com
**JavaDocs:** https://jd.viaversion.com
**Maven Repository:**
**Maven:**
```xml
<repository>
<id>viaversion-repo</id>
@@ -51,7 +43,6 @@ You can find official dev builds here:
</repository>
```
**API-artifact:**
```xml
<dependency>
<groupId>com.viaversion</groupId>
@@ -61,7 +52,17 @@ You can find official dev builds here:
</dependency>
```
Replace the version depending on your needs.
**Gradle:**
```kotlin
repositories {
maven("https://repo.viaversion.com")
}
dependencies {
compileOnly("com.viaversion:viaversion-api:VERSION") // Replace the version
}
```
If you need access to the existing protocol or platform implementations, use the parent artifact `viaversion`.
Please note the [differences in licensing](#license).
@@ -69,8 +70,8 @@ Please note the [differences in licensing](#license).
Building
--------
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out of
the `build/libs` directory.
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out
of the `build/libs` directory.
Mapping Files
@@ -78,12 +79,21 @@ Mapping Files
Mapping files are generated and managed in our [Mappings repository](https://github.com/ViaVersion/Mappings).
Resources
--------
- **[Via Mappings Generator](https://github.com/ViaVersion/Mappings)**
- **[Mojang mappings](https://minecraft.wiki/w/Obfuscation_map)** (Thank you, Mojang, very cool)
- **[wiki.vg](https://wiki.vg)** (Used for historic information regarding packet structure, we also contribute back)
- **[Burger](https://github.com/Pokechu22/Burger)** (See [PAaaS](https://github.com/Matsv/Paaas))
License
--------
The entirety of the [API directory](api) (including the legacy API directory) is licensed under the MIT License; see [licenses/MIT.md](licenses/MIT.md) for
The entirety of the [API directory](api) (including the legacy API directory) is licensed under the MIT License;
see [licenses/MIT.md](licenses/MIT.md) for
details.
Everything else, unless explicitly stated otherwise, is licensed under the GNU General Public License, including the end
product as a whole; see [licenses/GPL.md](licenses/GPL.md) for details.
Everything else, unless explicitly stated otherwise, is licensed under the GNU General Public License v3, including the
end-product as a whole; see [licenses/GPL.md](licenses/GPL.md) for details.
Special thanks to all our [Contributors](https://github.com/ViaVersion/ViaVersion/graphs/contributors).
@@ -83,8 +83,11 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new VersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18_2 = register(758, "1.18.2");
public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1");
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/2", new VersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new VersionRange("1.20", 0, 1));
public static final ProtocolVersion v1_20_2 = register(764, "1.20.2");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
+10 -3
View File
@@ -1,11 +1,18 @@
plugins {
id("net.kyori.blossom")
id("org.jetbrains.gradle.plugin.idea-ext")
id("via.shadow-conventions")
}
blossom {
replaceToken("\$VERSION", project.version)
replaceToken("\$IMPL_VERSION", "git-ViaVersion-${project.version}:${rootProject.latestCommitHash()}")
sourceSets {
main {
blossom {
javaSources {
property("version", project.version.toString())
property("impl_version", "git-ViaVersion-${project.version}:${rootProject.latestCommitHash()}")
}
}
}
}
dependencies {
@@ -31,5 +31,14 @@ public final class VersionInfo {
*
* @see ViaPlatform#getPluginVersion()
*/
public static final String VERSION = "$VERSION";
public static final String VERSION = "{{ version }}";
private static final String IMPLEMENTATION_VERSION = "{{ impl_version }}";
public static String getVersion() {
return VERSION;
}
public static String getImplementationVersion() {
return IMPLEMENTATION_VERSION;
}
}
@@ -63,7 +63,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes
*/
default int apiVersion() {
return 19;
return 20;
}
/**
@@ -23,6 +23,7 @@
package com.viaversion.viaversion.api.connection;
import com.viaversion.viaversion.api.protocol.ProtocolPipeline;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.State;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -33,10 +34,63 @@ public interface ProtocolInfo {
* Returns the protocol state the user is currently in.
*
* @return protocol state
* @deprecated server and client can be in different states, use {@link #getClientState()} or {@link #getServerState()}
*/
State getState();
@Deprecated/*(forRemoval = true)*/
default State getState() {
return this.getServerState();
}
void setState(State state);
/**
* Returns the protocol state the client is currently in.
*
* @return the client protocol state
*/
State getClientState();
/**
* Returns the protocol state the server is currently in.
*
* @return the server protocol state
*/
State getServerState();
/**
* Returns the protocol state for the given direction.
*
* @param direction protocol direction
* @return state for the given direction
*/
default State getState(final Direction direction) {
// Return the state the packet is coming from
return direction == Direction.CLIENTBOUND ? this.getServerState() : this.getClientState();
}
/**
* Sets both client and server state.
*
* @param state the new protocol state
* @see #setClientState(State)
* @see #setServerState(State)
*/
default void setState(final State state) {
this.setClientState(state);
this.setServerState(state);
}
/**
* Sets the client protocol state.
*
* @param clientState the new client protocol state
*/
void setClientState(State clientState);
/**
* Sets the server protocol state.
*
* @param serverState the new server protocol state
*/
void setServerState(State serverState);
/**
* Returns the user's protocol version, or -1 if not set.
@@ -38,4 +38,7 @@ public interface StorableObject {
default boolean clearOnServerSwitch() {
return true;
}
default void onRemove() {
}
}
@@ -101,6 +101,8 @@ public interface MappingData {
@Nullable Mappings getStatisticsMappings();
@Nullable Mappings getMenuMappings();
@Nullable Mappings getEnchantmentMappings();
@Nullable FullMappings getEntityMappings();
@@ -52,6 +52,7 @@ public class MappingDataBase implements MappingData {
protected Mappings statisticsMappings;
protected Mappings enchantmentMappings;
protected Mappings paintingMappings;
protected Mappings menuMappings;
protected Map<RegistryType, List<TagData>> tags;
public MappingDataBase(final String unmappedVersion, final String mappedVersion) {
@@ -71,6 +72,7 @@ public class MappingDataBase implements MappingData {
blockEntityMappings = loadMappings(data, "blockentities");
soundMappings = loadMappings(data, "sounds");
statisticsMappings = loadMappings(data, "statistics");
menuMappings = loadMappings(data, "menus");
enchantmentMappings = loadMappings(data, "enchantments");
paintingMappings = loadMappings(data, "paintings");
itemMappings = loadBiMappings(data, "items");
@@ -202,6 +204,11 @@ public class MappingDataBase implements MappingData {
return statisticsMappings;
}
@Override
public @Nullable Mappings getMenuMappings() {
return menuMappings;
}
@Override
public @Nullable Mappings getEnchantmentMappings() {
return enchantmentMappings;
@@ -236,7 +243,9 @@ public class MappingDataBase implements MappingData {
*/
protected int checkValidity(final int id, final int mappedId, final String type) {
if (mappedId == -1) {
getLogger().warning(String.format("Missing %s %s for %s %s %d", mappedVersion, type, unmappedVersion, type, id));
if (!Via.getConfig().isSuppressConversionWarnings()) {
getLogger().warning(String.format("Missing %s %s for %s %s %d", mappedVersion, type, unmappedVersion, type, id));
}
return 0;
}
return mappedId;
@@ -50,4 +50,14 @@ public final class Quaternion {
public float w() {
return w;
}
@Override
public String toString() {
return "Quaternion{" +
"x=" + x +
", y=" + y +
", z=" + z +
", w=" + w +
'}';
}
}
@@ -27,6 +27,10 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public interface BlockEntity {
static byte pack(int sectionX, int sectionZ) {
return (byte) (((sectionX) & 15) << 4 | (sectionZ & 15));
}
default byte sectionX() {
return (byte) ((packedXZ() >> 4) & 15);
}
@@ -47,6 +47,11 @@ public class ChunkSectionLightImpl implements ChunkSectionLight {
@Override
public void setSkyLight(byte[] data) {
if (data == null) {
this.skyLight = null;
return;
}
if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH);
if (this.skyLight == null) {
this.skyLight = new NibbleArray(data);
@@ -29,21 +29,24 @@ import it.unimi.dsi.fastutil.ints.IntList;
public final class DataPaletteImpl implements DataPalette {
private static final int DEFAULT_INITIAL_SIZE = 16;
private final IntList palette;
private final Int2IntMap inversePalette;
private final int[] values;
private final int sizeBits;
private ChunkData values;
public DataPaletteImpl(final int valuesLength) {
this(valuesLength, 8);
this(valuesLength, DEFAULT_INITIAL_SIZE);
}
public DataPaletteImpl(final int valuesLength, final int expectedPaletteLength) {
this.values = new int[valuesLength];
public DataPaletteImpl(final int valuesLength, final int initialSize) {
values = new EmptyChunkData(valuesLength);
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
// Pre-size the palette array/map
palette = new IntArrayList(expectedPaletteLength);
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
palette = new IntArrayList(initialSize);
// To get an initial table size of initialSize, need to scale it down by load factor.
inversePalette = new Int2IntOpenHashMap((int) (initialSize * Int2IntOpenHashMap.DEFAULT_LOAD_FACTOR));
inversePalette.defaultReturnValue(-1);
}
@@ -54,7 +57,7 @@ public final class DataPaletteImpl implements DataPalette {
@Override
public int idAt(final int sectionCoordinate) {
final int index = values[sectionCoordinate];
final int index = values.get(sectionCoordinate);
return palette.getInt(index);
}
@@ -67,17 +70,17 @@ public final class DataPaletteImpl implements DataPalette {
inversePalette.put(id, index);
}
values[sectionCoordinate] = index;
values.set(sectionCoordinate, index);
}
@Override
public int paletteIndexAt(final int packedCoordinate) {
return values[packedCoordinate];
return values.get(packedCoordinate);
}
@Override
public void setPaletteIndexAt(final int sectionCoordinate, final int index) {
values[sectionCoordinate] = index;
values.set(sectionCoordinate, index);
}
@Override
@@ -131,4 +134,77 @@ public final class DataPaletteImpl implements DataPalette {
palette.clear();
inversePalette.clear();
}
interface ChunkData {
int get(int idx);
void set(int idx, int val);
}
private class EmptyChunkData implements ChunkData {
private final int size;
public EmptyChunkData(int size) {
this.size = size;
}
@Override
public int get(int idx) {
return 0;
}
@Override
public void set(int idx, int val) {
if (val != 0) {
values = new ByteChunkData(size);
values.set(idx, val);
}
}
}
private class ByteChunkData implements ChunkData {
private final byte[] data;
public ByteChunkData(int size) {
this.data = new byte[size];
}
@Override
public int get(int idx) {
return data[idx] & 0xFF;
}
@Override
public void set(int idx, int val) {
// Overflowed size of byte (over 256 different materials), go up to short
if (val > 0xFF) {
values = new ShortChunkData(data);
values.set(idx, val);
return;
}
data[idx] = (byte) val;
}
}
private static class ShortChunkData implements ChunkData {
private final short[] data;
public ShortChunkData(byte[] data) {
this.data = new short[data.length];
for (int i = 0; i < data.length; i++) {
this.data[i] = (short) (data[i] & 0xFF);
}
}
@Override
public int get(int idx) {
return data[idx];
}
@Override
public void set(int idx, int val) {
data[idx] = (short) val;
}
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.metadata;
import java.util.Objects;
public final class ChunkPosition {
private final int chunkX;
private final int chunkZ;
public ChunkPosition(int chunkX, int chunkZ) {
this.chunkX = chunkX;
this.chunkZ = chunkZ;
}
public ChunkPosition(long chunkKey) {
this.chunkX = (int) chunkKey;
this.chunkZ = (int) (chunkKey >> 32);
}
public int chunkX() {
return chunkX;
}
public int chunkZ() {
return chunkZ;
}
public long chunkKey() {
return (long) chunkX & 0xffffffffL | ((long) chunkZ & 0xffffffffL) << 32;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ChunkPosition that = (ChunkPosition) o;
return chunkX == that.chunkX && chunkZ == that.chunkZ;
}
@Override
public int hashCode() {
return Objects.hash(chunkX, chunkZ);
}
@Override
public String toString() {
return "ChunkPosition{" +
"chunkX=" + chunkX +
", chunkZ=" + chunkZ +
'}';
}
}
@@ -63,6 +63,14 @@ public interface MetaType {
return type;
}
@Override
public String toString() {
return "MetaType{" +
"typeId=" + typeId +
", type=" + type +
'}';
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
@@ -0,0 +1,64 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.metadata.types;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
public final class MetaTypes1_20_2 extends AbstractMetaTypes {
public final MetaType byteType = add(0, Type.BYTE);
public final MetaType varIntType = add(1, Type.VAR_INT);
public final MetaType longType = add(2, Type.VAR_LONG);
public final MetaType floatType = add(3, Type.FLOAT);
public final MetaType stringType = add(4, Type.STRING);
public final MetaType componentType = add(5, Type.COMPONENT);
public final MetaType optionalComponentType = add(6, Type.OPTIONAL_COMPONENT);
public final MetaType itemType = add(7, Type.ITEM1_20_2);
public final MetaType booleanType = add(8, Type.BOOLEAN);
public final MetaType rotationType = add(9, Type.ROTATION);
public final MetaType positionType = add(10, Type.POSITION1_14);
public final MetaType optionalPositionType = add(11, Type.OPTIONAL_POSITION_1_14);
public final MetaType directionType = add(12, Type.VAR_INT);
public final MetaType optionalUUIDType = add(13, Type.OPTIONAL_UUID);
public final MetaType blockStateType = add(14, Type.VAR_INT);
public final MetaType optionalBlockStateType = add(15, Type.VAR_INT);
public final MetaType nbtType = add(16, Type.NAMELESS_NBT);
public final MetaType particleType;
public final MetaType villagerDatatType = add(18, Type.VILLAGER_DATA);
public final MetaType optionalVarIntType = add(19, Type.OPTIONAL_VAR_INT);
public final MetaType poseType = add(20, Type.VAR_INT);
public final MetaType catVariantType = add(21, Type.VAR_INT);
public final MetaType frogVariantType = add(22, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(23, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType paintingVariantType = add(24, Type.VAR_INT);
public final MetaType snifferState = add(25, Type.VAR_INT);
public final MetaType vectorType = add(26, Type.VECTOR3F);
public final MetaType quaternionType = add(27, Type.QUATERNION);
public MetaTypes1_20_2(final ParticleType particleType) {
super(28);
this.particleType = add(17, particleType);
}
}
@@ -22,6 +22,8 @@
*/
package com.viaversion.viaversion.api.platform;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface UnsupportedSoftware {
/**
@@ -38,10 +40,19 @@ public interface UnsupportedSoftware {
*/
String getReason();
/**
* Returns the name of unsupported software if present.
*
* @return name of unsupported software if it is matched, else null
*/
@Nullable String match();
/**
* Returns whether the unsupported software is present.
*
* @return true if the unsupported software is found
*/
boolean findMatch();
default boolean findMatch() {
return match() != null;
}
}
@@ -77,6 +77,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
/**
* Creates a protocol with automated id mapping if the respective packet type classes are not null.
* They are also required to track the CONFIGURATION state.
*/
protected AbstractProtocol(@Nullable Class<CU> unmappedClientboundPacketType, @Nullable Class<CM> mappedClientboundPacketType,
@Nullable Class<SM> mappedServerboundPacketType, @Nullable Class<SU> unmappedServerboundPacketType) {
@@ -95,6 +96,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
initialized = true;
registerPackets();
registerConfigurationChangeHandlers();
// Register the rest of the ids with no handlers if necessary
if (unmappedClientboundPacketType != null && mappedClientboundPacketType != null
@@ -117,6 +119,33 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
protected void registerConfigurationChangeHandlers() {
// Register handlers for protocol state switching
// Assuming ids will change too often, it is cleaner to register them here instead of the base protocols,
// even if there will be multiple of these handlers
final SU configurationAcknowledgedPacket = configurationAcknowledgedPacket();
if (configurationAcknowledgedPacket != null) {
registerServerbound(configurationAcknowledgedPacket, setClientStateHandler(State.CONFIGURATION));
}
final CU startConfigurationPacket = startConfigurationPacket();
if (startConfigurationPacket != null) {
registerClientbound(startConfigurationPacket, setServerStateHandler(State.CONFIGURATION));
}
final ServerboundPacketType finishConfigurationPacket = serverboundFinishConfigurationPacket();
if (finishConfigurationPacket != null) {
final int id = finishConfigurationPacket.getId();
registerServerbound(State.CONFIGURATION, id, id, setClientStateHandler(State.PLAY));
}
final ClientboundPacketType clientboundFinishConfigurationPacket = clientboundFinishConfigurationPacket();
if (clientboundFinishConfigurationPacket != null) {
final int id = clientboundFinishConfigurationPacket.getId();
registerClientbound(State.CONFIGURATION, id, id, setServerStateHandler(State.PLAY));
}
}
private <U extends PacketType, M extends PacketType> void registerPacketIdChanges(
Map<State, PacketTypeMap<U>> unmappedPacketTypes,
Map<State, PacketTypeMap<M>> mappedPacketTypes,
@@ -208,6 +237,28 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
return Collections.emptyMap();
}
protected @Nullable SU configurationAcknowledgedPacket() {
final Map<State, PacketTypeMap<SU>> packetTypes = packetTypesProvider.unmappedServerboundPacketTypes();
final PacketTypeMap<SU> packetTypeMap = packetTypes.get(State.PLAY);
return packetTypeMap != null ? packetTypeMap.typeByName("CONFIGURATION_ACKNOWLEDGED") : null;
}
protected @Nullable CU startConfigurationPacket() {
final Map<State, PacketTypeMap<CU>> packetTypes = packetTypesProvider.unmappedClientboundPacketTypes();
final PacketTypeMap<CU> packetTypeMap = packetTypes.get(State.PLAY);
return packetTypeMap != null ? packetTypeMap.typeByName("START_CONFIGURATION") : null;
}
protected @Nullable ServerboundPacketType serverboundFinishConfigurationPacket() {
// To be overridden
return null;
}
protected @Nullable ClientboundPacketType clientboundFinishConfigurationPacket() {
// To be overridden
return null;
}
// ---------------------------------------------------------------------------------
@Override
@@ -361,7 +412,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
private void throwRemapError(Direction direction, State state, int unmappedPacketId, int mappedPacketId, InformativeException e) throws InformativeException {
protected void throwRemapError(Direction direction, State state, int unmappedPacketId, int mappedPacketId, InformativeException e) throws InformativeException {
// Don't print errors during handshake/login/status
if (state != State.PLAY && direction == Direction.SERVERBOUND && !Via.getManager().debugHandler().enabled()) {
e.setShouldBePrinted(false);
@@ -404,6 +455,14 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
protected PacketHandler setClientStateHandler(final State state) {
return wrapper -> wrapper.user().getProtocolInfo().setClientState(state);
}
protected PacketHandler setServerStateHandler(final State state) {
return wrapper -> wrapper.user().getProtocolInfo().setClientState(state);
}
@Override
public PacketTypesProvider<CU, CM, SM, SU> getPacketTypesProvider() {
return packetTypesProvider;
@@ -69,10 +69,17 @@ public interface ProtocolPipeline extends SimpleProtocol {
/**
* Returns the list of protocols this pipeline contains.
*
* @return list of protocols in this pipe
* @return immutable list of protocols in this pipe
*/
List<Protocol> pipes();
/**
* Returns the list of protocols this pipeline contains in reversed order.
*
* @return immutable list of protocols in reversed direction
*/
List<Protocol> reversedPipes();
/**
* Returns whether this pipe has protocols that are not base protocols, as given by {@link Protocol#isBaseProtocol()}.
*
@@ -27,5 +27,6 @@ public enum State {
HANDSHAKE,
STATUS,
LOGIN,
CONFIGURATION,
PLAY
}
@@ -25,9 +25,11 @@ package com.viaversion.viaversion.api.protocol.packet.provider;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import com.viaversion.viaversion.api.protocol.packet.PacketType;
import org.checkerframework.checker.nullness.qual.Nullable;
final class PacketTypeArrayMap<P> implements PacketTypeMap<P> {
final class PacketTypeArrayMap<P extends PacketType> implements PacketTypeMap<P> {
private final Map<String, P> packetsByName;
private final P[] packets;
@@ -29,7 +29,7 @@ import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface PacketTypeMap<P> {
public interface PacketTypeMap<P extends PacketType> {
/**
* Returns the packet type by the given name.
@@ -67,11 +67,11 @@ public interface PacketTypeMap<P> {
return of(byName, types);
}
static <T> PacketTypeMap<T> of(final Map<String, T> packetsByName, final Int2ObjectMap<T> packetsById) {
static <T extends PacketType> PacketTypeMap<T> of(final Map<String, T> packetsByName, final Int2ObjectMap<T> packetsById) {
return new PacketTypeMapMap<>(packetsByName, packetsById);
}
static <T> PacketTypeMap<T> of(final Map<String, T> packetsByName, final T[] packets) {
static <T extends PacketType> PacketTypeMap<T> of(final Map<String, T> packetsByName, final T[] packets) {
return new PacketTypeArrayMap<>(packetsByName, packets);
}
}
@@ -22,12 +22,13 @@
*/
package com.viaversion.viaversion.api.protocol.packet.provider;
import com.viaversion.viaversion.api.protocol.packet.PacketType;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.Collection;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
final class PacketTypeMapMap<P> implements PacketTypeMap<P> {
final class PacketTypeMapMap<P extends PacketType> implements PacketTypeMap<P> {
private final Map<String, P> packetsByName;
private final Int2ObjectMap<P> packetsById;
@@ -83,6 +83,8 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/2", new VersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new VersionRange("1.20", 0, 1));
public static final ProtocolVersion v1_20_2 = register(764, "1.20.2");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
@@ -36,6 +35,7 @@ import com.viaversion.viaversion.api.minecraft.Vector;
import com.viaversion.viaversion.api.minecraft.Vector3f;
import com.viaversion.viaversion.api.minecraft.VillagerData;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.ChunkPosition;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.BooleanType;
import com.viaversion.viaversion.api.type.types.ByteArrayType;
@@ -59,15 +59,18 @@ import com.viaversion.viaversion.api.type.types.VarIntType;
import com.viaversion.viaversion.api.type.types.VarLongType;
import com.viaversion.viaversion.api.type.types.VoidType;
import com.viaversion.viaversion.api.type.types.minecraft.BlockChangeRecordType;
import com.viaversion.viaversion.api.type.types.minecraft.ChunkPositionType;
import com.viaversion.viaversion.api.type.types.minecraft.EulerAngleType;
import com.viaversion.viaversion.api.type.types.minecraft.FlatItemArrayType;
import com.viaversion.viaversion.api.type.types.minecraft.FlatItemType;
import com.viaversion.viaversion.api.type.types.minecraft.FlatVarIntItemArrayType;
import com.viaversion.viaversion.api.type.types.minecraft.FlatVarIntItemType;
import com.viaversion.viaversion.api.type.types.minecraft.GlobalPositionType;
import com.viaversion.viaversion.api.type.types.minecraft.Item1_20_2Type;
import com.viaversion.viaversion.api.type.types.minecraft.ItemArrayType;
import com.viaversion.viaversion.api.type.types.minecraft.ItemType;
import com.viaversion.viaversion.api.type.types.minecraft.NBTType;
import com.viaversion.viaversion.api.type.types.minecraft.NamelessNBTType;
import com.viaversion.viaversion.api.type.types.minecraft.OptionalVarIntType;
import com.viaversion.viaversion.api.type.types.minecraft.PlayerMessageSignatureType;
import com.viaversion.viaversion.api.type.types.minecraft.Position1_14Type;
@@ -163,10 +166,11 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Vector3f> VECTOR3F = new Vector3fType();
public static final Type<Quaternion> QUATERNION = new QuaternionType();
public static final Type<CompoundTag> NBT = new NBTType();
public static final Type<CompoundTag> NAMELESS_NBT = new NamelessNBTType();
public static final Type<CompoundTag[]> NBT_ARRAY = new ArrayType<>(Type.NBT);
public static final Type<GlobalPosition> GLOBAL_POSITION = new GlobalPositionType();
public static final Type<GlobalPosition> OPTIONAL_GLOBAL_POSITION = new GlobalPositionType.OptionalGlobalPositionType();
public static final Type<ChunkPosition> CHUNK_POSITION = new ChunkPositionType();
public static final Type<BlockChangeRecord> BLOCK_CHANGE_RECORD = new BlockChangeRecordType();
public static final Type<BlockChangeRecord[]> BLOCK_CHANGE_RECORD_ARRAY = new ArrayType<>(Type.BLOCK_CHANGE_RECORD);
@@ -194,6 +198,9 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Item[]> FLAT_ITEM_ARRAY_VAR_INT = new ArrayType<>(FLAT_ITEM);
public static final Type<Item[]> FLAT_VAR_INT_ITEM_ARRAY_VAR_INT = new ArrayType<>(FLAT_VAR_INT_ITEM);
public static final Type<Item> ITEM1_20_2 = new Item1_20_2Type();
public static final Type<Item[]> ITEM1_20_2_VAR_INT_ARRAY = new ArrayType<>(ITEM1_20_2);
/* Actual Class */
private final Class<? super T> outputClass;
private final String typeName;
@@ -83,5 +83,13 @@ public class Particle {
public void setValue(Object value) {
this.value = value;
}
@Override
public String toString() {
return "ParticleData{" +
"type=" + type +
", value=" + value +
'}';
}
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.minecraft;
import com.viaversion.viaversion.api.minecraft.metadata.ChunkPosition;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class ChunkPositionType extends Type<ChunkPosition> {
public ChunkPositionType() {
super(ChunkPosition.class);
}
@Override
public ChunkPosition read(ByteBuf buffer) throws Exception {
final long chunkKey = Type.LONG.readPrimitive(buffer);
return new ChunkPosition(chunkKey);
}
@Override
public void write(ByteBuf buffer, ChunkPosition chunkPosition) throws Exception {
Type.LONG.writePrimitive(buffer, chunkPosition.chunkKey());
}
}
@@ -0,0 +1,60 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.minecraft;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public class Item1_20_2Type extends BaseItemType {
public Item1_20_2Type() {
super("Item1_20_2Type");
}
@Override
public @Nullable Item read(final ByteBuf buffer) throws Exception {
if (!buffer.readBoolean()) {
return null;
}
final Item item = new DataItem();
item.setIdentifier(VAR_INT.readPrimitive(buffer));
item.setAmount(buffer.readByte());
item.setTag(NAMELESS_NBT.read(buffer));
return item;
}
@Override
public void write(final ByteBuf buffer, @Nullable final Item object) throws Exception {
if (object == null) {
buffer.writeBoolean(false);
} else {
buffer.writeBoolean(true);
VAR_INT.writePrimitive(buffer, object.identifier());
buffer.writeByte(object.amount());
NAMELESS_NBT.write(buffer, object.tag());
}
}
}
@@ -28,6 +28,7 @@ import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ItemType extends BaseItemType {
public ItemType() {
super("Item");
}
@@ -22,15 +22,14 @@
*/
package com.viaversion.viaversion.api.type.types.minecraft;
import com.github.steveice10.opennbt.NBTIO;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.limiter.TagLimiter;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.checkerframework.checker.nullness.qual.Nullable;
public class NBTType extends Type<CompoundTag> {
@@ -42,24 +41,45 @@ public class NBTType extends Type<CompoundTag> {
}
@Override
public CompoundTag read(ByteBuf buffer) throws Exception {
int readerIndex = buffer.readerIndex();
byte b = buffer.readByte();
if (b == 0) {
return null;
} else {
buffer.readerIndex(readerIndex);
return NBTIO.readTag((DataInput) new ByteBufInputStream(buffer), TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL));
}
public CompoundTag read(final ByteBuf buffer) throws Exception {
return read(buffer, true);
}
@Override
public void write(ByteBuf buffer, CompoundTag object) throws Exception {
if (object == null) {
buffer.writeByte(0);
} else {
ByteBufOutputStream bytebufStream = new ByteBufOutputStream(buffer);
NBTIO.writeTag((DataOutput) bytebufStream, object);
public void write(final ByteBuf buffer, final CompoundTag object) throws Exception {
write(buffer, object, "");
}
public static CompoundTag read(final ByteBuf buffer, final boolean readName) throws Exception {
final byte id = buffer.readByte();
if (id == 0) {
return null;
}
if (id != CompoundTag.ID) {
throw new IOException(String.format("Expected root tag to be a CompoundTag, was %s", id));
}
if (readName) {
buffer.skipBytes(buffer.readUnsignedShort());
}
final TagLimiter tagLimiter = TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL);
final CompoundTag tag = new CompoundTag();
tag.read(new ByteBufInputStream(buffer), tagLimiter);
return tag;
}
public static void write(final ByteBuf buffer, final CompoundTag tag, final @Nullable String name) throws Exception {
if (tag == null) {
buffer.writeByte(0);
return;
}
final ByteBufOutputStream out = new ByteBufOutputStream(buffer);
out.writeByte(CompoundTag.ID);
if (name != null) {
out.writeUTF(name);
}
tag.write(out);
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.minecraft;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class NamelessNBTType extends Type<CompoundTag> {
public NamelessNBTType() {
super(CompoundTag.class);
}
@Override
public CompoundTag read(final ByteBuf buffer) throws Exception {
return NBTType.read(buffer, false);
}
@Override
public void write(final ByteBuf buffer, final CompoundTag tag) throws Exception {
NBTType.write(buffer, tag, null);
}
}
@@ -105,6 +105,7 @@ public class ParticleType extends Type<Particle> {
String resourceLocation = Type.STRING.read(buf);
particle.add(Type.STRING, resourceLocation);
resourceLocation = Key.stripMinecraftNamespace(resourceLocation);
if (resourceLocation.equals("block")) {
particle.add(Type.POSITION1_14, Type.POSITION1_14.read(buf)); // Target block pos
@@ -115,6 +116,21 @@ public class ParticleType extends Type<Particle> {
}
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Arrival in ticks
};
public static final ParticleReader VIBRATION1_19 = (buf, particle) -> {
String resourceLocation = Type.STRING.read(buf);
particle.add(Type.STRING, resourceLocation);
resourceLocation = Key.stripMinecraftNamespace(resourceLocation);
if (resourceLocation.equals("block")) {
particle.add(Type.POSITION1_14, Type.POSITION1_14.read(buf)); // Target block pos
} else if (resourceLocation.equals("entity")) {
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Target entity
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Y offset
} else {
Via.getPlatform().getLogger().warning("Unknown vibration path position source type: " + resourceLocation);
}
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Arrival in ticks
};
public static final ParticleReader SCULK_CHARGE = (buf, particle) -> {
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Roll
};
@@ -28,26 +28,24 @@ import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class PositionType extends Type<Position> {
public PositionType() {
super(Position.class);
}
@Override
public Position read(ByteBuf buffer) {
long val = buffer.readLong();
long x = (val >> 38); // signed
long y = (val >> 26) & 0xfff; // unsigned
// this shifting madness is used to preserve sign
long z = (val << 38) >> 38; // signed
final long val = buffer.readLong();
final long x = (val >> 38);
final long y = (val << 26) >> 52;
final long z = (val << 38) >> 38;
return new Position((int) x, (short) y, (int) z);
}
@Override
public void write(ByteBuf buffer, Position object) {
buffer.writeLong((((long) object.x() & 0x3ffffff) << 38)
| ((((long) object.y()) & 0xfff) << 26)
| (object.z() & 0x3ffffff));
buffer.writeLong((object.x() & 0X3FFFFFFL) << 38 | (object.y() & 0XFFFL) << 26 | (object.z() & 0X3FFFFFFL));
}
public static final class OptionalPositionType extends OptionalType<Position> {
@@ -0,0 +1,53 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntityImpl;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class BlockEntityType1_20_2 extends Type<BlockEntity> {
public BlockEntityType1_20_2() {
super(BlockEntity.class);
}
@Override
public BlockEntity read(final ByteBuf buffer) throws Exception {
final byte xz = buffer.readByte();
final short y = buffer.readShort();
final int typeId = Type.VAR_INT.readPrimitive(buffer);
final CompoundTag tag = Type.NAMELESS_NBT.read(buffer);
return new BlockEntityImpl(xz, y, typeId, tag);
}
@Override
public void write(final ByteBuf buffer, final BlockEntity entity) throws Exception {
buffer.writeByte(entity.packedXZ());
buffer.writeShort(entity.y());
Type.VAR_INT.writePrimitive(buffer, entity.typeId());
Type.NAMELESS_NBT.write(buffer, entity.tag());
}
}
@@ -0,0 +1,38 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaTypes1_19_4;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import java.util.List;
public final class Types1_20 {
public static final ParticleType PARTICLE = new ParticleType(); // Only safe to use after protocol loading
public static final MetaTypes1_19_4 META_TYPES = new MetaTypes1_19_4(PARTICLE);
public static final Type<Metadata> METADATA = new MetadataType(META_TYPES);
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
}
@@ -0,0 +1,40 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaTypes1_20_2;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import java.util.List;
public final class Types1_20_2 {
public static final Type<BlockEntity> BLOCK_ENTITY = new BlockEntityType1_20_2();
public static final ParticleType PARTICLE = Types1_20.PARTICLE; // Only safe to use after protocol loading
public static final MetaTypes1_20_2 META_TYPES = new MetaTypes1_20_2(PARTICLE);
public static final Type<Metadata> METADATA = new MetadataType(META_TYPES);
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
}
+1 -1
View File
@@ -8,5 +8,5 @@ repositories {
dependencies {
// version must be manually kept in sync with the one in root project settings.gradle.kts
implementation("com.github.johnrengelman", "shadow", "8.1.0")
implementation("com.github.johnrengelman", "shadow", "8.1.1")
}
+18
View File
@@ -38,6 +38,24 @@ fun Project.latestCommitHash(): String {
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun Project.latestCommitMessage(): String {
val byteOut = ByteArrayOutputStream()
exec {
commandLine = listOf("git", "log", "-1", "--pretty=%B")
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun Project.branchName(): String {
val byteOut = ByteArrayOutputStream()
exec {
commandLine = listOf("git", "rev-parse", "--abbrev-ref", "HEAD")
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun JavaPluginExtension.javaTarget(version: Int) {
toolchain.languageVersion.set(JavaLanguageVersion.of(version))
}
@@ -55,7 +55,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
private static final boolean FOLIA = PaperViaInjector.hasClass("io.papermc.paper.threadedregions.RegionisedServer");
private static final boolean FOLIA = PaperViaInjector.hasClass("io.papermc.paper.threadedregions.RegionizedServer");
private static ViaVersionPlugin instance;
private final BukkitCommandHandler commandHandler;
private final BukkitViaConfig conf;
@@ -80,11 +80,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
// Config magic
conf = new BukkitViaConfig();
// Load a bunch of classes early with slow reflection and more classloading
if (conf.shouldRegisterUserConnectionOnJoin()) {
Via.getManager().getScheduler().execute(JoinListener::init);
}
}
@Override
@@ -108,12 +103,18 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
manager.init();
}
if (Via.getConfig().shouldRegisterUserConnectionOnJoin()) {
// When event priority ties, registration order is used.
// Must register without delay to ensure other plugins on lowest get the fix applied.
getServer().getPluginManager().registerEvents(new JoinListener(), this);
}
if (FOLIA) {
// Use Folia's RegionisedServerInitEvent to run code after the server has loaded
// Use Folia's RegionizedServerInitEvent to run code after the server has loaded
final Class<? extends Event> serverInitEventClass;
try {
//noinspection unchecked
serverInitEventClass = (Class<? extends Event>) Class.forName("io.papermc.paper.threadedregions.RegionisedServerInitEvent");
serverInitEventClass = (Class<? extends Event>) Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent");
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
@@ -46,8 +46,8 @@ public class JoinListener implements Listener {
Field gamePacketListenerField = null, connectionField = null, channelField = null;
try {
getHandleMethod = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle");
gamePacketListenerField = findField(getHandleMethod.getReturnType(), "PlayerConnection", "ServerGamePacketListenerImpl");
connectionField = findField(gamePacketListenerField.getType(), "NetworkManager", "Connection");
gamePacketListenerField = findField(false, getHandleMethod.getReturnType(), "PlayerConnection", "ServerGamePacketListenerImpl");
connectionField = findField(true, gamePacketListenerField.getType(), "NetworkManager", "Connection");
channelField = findField(connectionField.getType(), Class.forName("io.netty.channel.Channel"));
} catch (NoSuchMethodException | NoSuchFieldException | ClassNotFoundException e) {
Via.getPlatform().getLogger().log(
@@ -62,12 +62,9 @@ public class JoinListener implements Listener {
CHANNEL = channelField;
}
public static void init() {
}
// Loosely search a field with any name, as long as it matches a type name.
private static Field findField(Class<?> clazz, String... types) throws NoSuchFieldException {
for (Field field : clazz.getDeclaredFields()) {
private static Field findField(boolean all, Class<?> clazz, String... types) throws NoSuchFieldException {
for (Field field : all ? clazz.getFields() : clazz.getDeclaredFields()) {
String fieldTypeName = field.getType().getSimpleName();
for (String type : types) {
if (!fieldTypeName.equals(type)) {
@@ -39,12 +39,16 @@ public final class ArmorToggleListener extends ViaBukkitListener {
public void itemUse(final PlayerInteractEvent event) {
final Player player = event.getPlayer();
final ItemStack item = event.getItem();
if (item == null || event.getHand() == null || !isOnPipe(player)) {
if (item == null || event.getHand() == null) {
return;
}
final EquipmentSlot armorItemSlot = item.getType().getEquipmentSlot();
if (armorItemSlot != EquipmentSlot.HAND && armorItemSlot != EquipmentSlot.OFF_HAND) {
if (armorItemSlot == EquipmentSlot.HAND || armorItemSlot == EquipmentSlot.OFF_HAND || item.getType().isBlock()) {
return;
}
if (isOnPipe(player)) {
final PlayerInventory inventory = player.getInventory();
final ItemStack armor = inventory.getItem(armorItemSlot);
// If two pieces of armor are equal, the client will do nothing.
@@ -79,10 +79,6 @@ public class BukkitViaLoader implements ViaPlatformLoader {
public void load() {
registerListener(new UpdateListener());
if (Via.getConfig().shouldRegisterUserConnectionOnJoin()) {
registerListener(new JoinListener());
}
/* Base Protocol */
final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
@@ -39,7 +39,10 @@ public final class BukkitAckSequenceProvider extends AckSequenceProvider {
if (previousSequence == -1) {
final int serverProtocolVersion = connection.getProtocolInfo().getServerProtocolVersion();
final long delay = serverProtocolVersion > ProtocolVersion.v1_8.getVersion() && serverProtocolVersion < ProtocolVersion.v1_14.getVersion() ? 2 : 1;
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new AckSequenceTask(connection, sequenceStorage), delay);
if (plugin.isEnabled()) {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new AckSequenceTask(connection, sequenceStorage), delay);
}
}
}
}
@@ -25,6 +25,9 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.MovementTrac
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.viaversion.viaversion.util.PipelineUtil;
import io.netty.channel.ChannelHandlerContext;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -79,17 +82,15 @@ public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
}
}
@Override
public Object getFlyingPacket() {
if (idlePacket == null)
throw new NullPointerException("Could not locate flying packet");
if (idlePacket == null) throw new NullPointerException("Could not locate flying packet");
return idlePacket;
}
@Override
public Object getGroundPacket() {
if (idlePacket == null)
throw new NullPointerException("Could not locate flying packet");
if (idlePacket == null) throw new NullPointerException("Could not locate flying packet");
return idlePacket2;
}
@@ -112,7 +113,15 @@ public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
}
}
} else {
super.sendPlayer(info);
ChannelHandlerContext context = PipelineUtil.getContextBefore("decoder", info.getChannel().pipeline());
if (context != null) {
if (info.get(MovementTracker.class).isGround()) {
context.fireChannelRead(getGroundPacket());
} else {
context.fireChannelRead(getFlyingPacket());
}
info.get(MovementTracker.class).incrementIdlePacket();
}
}
}
}
@@ -28,12 +28,10 @@ import com.viaversion.viaversion.bungee.listeners.UpdateListener;
import com.viaversion.viaversion.bungee.providers.BungeeBossBarProvider;
import com.viaversion.viaversion.bungee.providers.BungeeEntityIdProvider;
import com.viaversion.viaversion.bungee.providers.BungeeMainHandProvider;
import com.viaversion.viaversion.bungee.providers.BungeeMovementTransmitter;
import com.viaversion.viaversion.bungee.providers.BungeeVersionProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MainHandProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -71,7 +69,6 @@ public class BungeeViaLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(EntityIdProvider.class, new BungeeEntityIdProvider());
if (Via.getAPI().getServerVersion().lowestSupportedVersion() < ProtocolVersion.v1_9.getVersion()) {
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
Via.getManager().getProviders().use(BossBarProvider.class, new BungeeBossBarProvider());
Via.getManager().getProviders().use(MainHandProvider.class, new BungeeMainHandProvider());
}
@@ -1,53 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bungee.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.MovementTracker;
public class BungeeMovementTransmitter extends MovementTransmitterProvider {
@Override
public Object getFlyingPacket() {
return null;
}
@Override
public Object getGroundPacket() {
return null;
}
public void sendPlayer(UserConnection userConnection) {
if (userConnection.getProtocolInfo().getState() == State.PLAY) {
PacketWrapper wrapper = PacketWrapper.create(ServerboundPackets1_8.PLAYER_MOVEMENT, null, userConnection);
MovementTracker tracker = userConnection.get(MovementTracker.class);
wrapper.write(Type.BOOLEAN, tracker.isGround());
try {
wrapper.scheduleSendToServer(Protocol1_9To1_8.class);
} catch (Exception e) {
e.printStackTrace();
}
tracker.incrementIdlePacket();
}
}
}
-9
View File
@@ -1,12 +1,3 @@
plugins {
id("net.kyori.blossom")
}
blossom {
replaceToken("\$VERSION", project.version)
replaceToken("\$IMPL_VERSION", "git-ViaVersion-${project.version}:${rootProject.latestCommitHash()}")
}
dependencies {
api(projects.viaversionApi)
api(projects.viaversionApiLegacy)
@@ -237,7 +237,8 @@ public class ViaManagerImpl implements ViaManager {
private void unsupportedSoftwareWarning() {
boolean found = false;
for (final UnsupportedSoftware software : platform.getUnsupportedSoftwareClasses()) {
if (!software.findMatch()) {
final String match = software.match();
if (match == null) {
continue;
}
@@ -249,7 +250,7 @@ public class ViaManagerImpl implements ViaManager {
found = true;
}
platform.getLogger().severe("We strongly advise against using " + software.getName() + ":");
platform.getLogger().severe("We strongly advise against using " + match + ":");
platform.getLogger().severe(software.getReason());
platform.getLogger().severe("");
}
@@ -17,32 +17,9 @@
*/
package com.viaversion.viaversion.commands.defaultsubs;
import com.google.common.io.CharStreams;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.api.command.ViaSubCommand;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.dump.DumpTemplate;
import com.viaversion.viaversion.dump.VersionInfo;
import com.viaversion.viaversion.util.GsonUtil;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InvalidObjectException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.logging.Level;
import com.viaversion.viaversion.util.DumpUtil;
public class DumpSubCmd extends ViaSubCommand {
@@ -57,124 +34,15 @@ public class DumpSubCmd extends ViaSubCommand {
}
@Override
public boolean execute(ViaCommandSender sender, String[] args) {
VersionInfo version = new VersionInfo(
System.getProperty("java.version"),
System.getProperty("os.name"),
Via.getAPI().getServerVersion().lowestSupportedVersion(),
Via.getManager().getProtocolManager().getSupportedVersions(),
Via.getPlatform().getPlatformName(),
Via.getPlatform().getPlatformVersion(),
Via.getPlatform().getPluginVersion(),
"$IMPL_VERSION",
Via.getManager().getSubPlatforms()
);
Map<String, Object> configuration = Via.getPlatform().getConfigurationProvider().getValues();
DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump(), Via.getManager().getInjector().getDump(), getPlayerSample(sender.getUUID()));
Via.getPlatform().runAsync(new Runnable() {
@Override
public void run() {
HttpURLConnection con;
try {
con = (HttpURLConnection) new URL("https://dump.viaversion.com/documents").openConnection();
} catch (IOException e) {
sender.sendMessage("§4Failed to dump, please check the console for more information");
Via.getPlatform().getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to ViaVersion Dump", e);
return;
}
try {
con.setRequestProperty("Content-Type", "application/json");
con.addRequestProperty("User-Agent", "ViaVersion/" + version.getPluginVersion());
con.setRequestMethod("POST");
con.setDoOutput(true);
OutputStream out = con.getOutputStream();
out.write(new GsonBuilder().setPrettyPrinting().create().toJson(template).getBytes(StandardCharsets.UTF_8));
out.close();
if (con.getResponseCode() == 429) {
sender.sendMessage("§4You can only paste once every minute to protect our systems.");
return;
}
String rawOutput = CharStreams.toString(new InputStreamReader(con.getInputStream()));
con.getInputStream().close();
JsonObject output = GsonUtil.getGson().fromJson(rawOutput, JsonObject.class);
if (!output.has("key"))
throw new InvalidObjectException("Key is not given in Hastebin output");
sender.sendMessage("§2We've made a dump with useful information, report your issue and provide this url: " + getUrl(output.get("key").getAsString()));
} catch (Exception e) {
sender.sendMessage("§4Failed to dump, please check the console for more information");
Via.getPlatform().getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to Hastebin", e);
try {
if (con.getResponseCode() < 200 || con.getResponseCode() > 400) {
String rawOutput = CharStreams.toString(new InputStreamReader(con.getErrorStream()));
con.getErrorStream().close();
Via.getPlatform().getLogger().log(Level.WARNING, "Page returned: " + rawOutput);
}
} catch (IOException e1) {
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to capture further info", e1);
}
}
public boolean execute(final ViaCommandSender sender, final String[] args) {
DumpUtil.postDump(sender.getUUID()).whenComplete((url, e) -> {
if (e != null) {
sender.sendMessage("§4" + e.getMessage());
return;
}
});
sender.sendMessage("§2We've made a dump with useful information, report your issue and provide this url: " + url);
});
return true;
}
private String getUrl(String id) {
return String.format("https://dump.viaversion.com/%s", id);
}
private JsonObject getPlayerSample(UUID senderUuid) {
JsonObject playerSample = new JsonObject();
// Player versions
JsonObject versions = new JsonObject();
playerSample.add("versions", versions);
Map<ProtocolVersion, Integer> playerVersions = new TreeMap<>((o1, o2) -> ProtocolVersion.getIndex(o2) - ProtocolVersion.getIndex(o1));
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(connection.getProtocolInfo().getProtocolVersion());
playerVersions.compute(protocolVersion, (v, num) -> num != null ? num + 1 : 1);
}
for (Map.Entry<ProtocolVersion, Integer> entry : playerVersions.entrySet()) {
versions.addProperty(entry.getKey().getName(), entry.getValue());
}
// Pipeline of sender
Set<List<String>> pipelines = new HashSet<>();
UserConnection senderConnection = Via.getAPI().getConnection(senderUuid);
if (senderConnection != null && senderConnection.getChannel() != null) {
pipelines.add(senderConnection.getChannel().pipeline().names());
}
// Other pipelines if different ones are found (3 max)
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
if (connection.getChannel() == null) {
continue;
}
List<String> names = connection.getChannel().pipeline().names();
if (pipelines.add(names) && pipelines.size() == 3) {
break;
}
}
int i = 0;
for (List<String> pipeline : pipelines) {
JsonArray senderPipeline = new JsonArray(pipeline.size());
for (String name : pipeline) {
senderPipeline.add(name);
}
playerSample.add("pipeline-" + i++, senderPipeline);
}
return playerSample;
}
}
@@ -72,6 +72,8 @@ public class ConnectionManagerImpl implements ConnectionManager {
UUID id = connection.getProtocolInfo().getUuid();
clients.remove(id);
}
connection.clearStoredObjects();
}
@Override
@@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.connection;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.ProtocolPipeline;
@@ -26,25 +27,42 @@ import java.util.UUID;
public class ProtocolInfoImpl implements ProtocolInfo {
private final UserConnection connection;
private State state = State.HANDSHAKE;
private State clientState = State.HANDSHAKE;
private State serverState = State.HANDSHAKE;
private int protocolVersion = -1;
private int serverProtocolVersion = -1;
private String username;
private UUID uuid;
private ProtocolPipeline pipeline;
public ProtocolInfoImpl(UserConnection connection) {
public ProtocolInfoImpl(final UserConnection connection) {
this.connection = connection;
}
@Override
public State getState() {
return state;
public State getClientState() {
return clientState;
}
@Override
public void setState(State state) {
this.state = state;
public void setClientState(final State clientState) {
if (Via.getManager().debugHandler().enabled()) {
Via.getPlatform().getLogger().info("Client state changed from " + this.clientState + " to " + clientState + " for " + connection.getProtocolInfo().getUuid());
}
this.clientState = clientState;
}
@Override
public State getServerState() {
return serverState;
}
@Override
public void setServerState(final State serverState) {
if (Via.getManager().debugHandler().enabled()) {
Via.getPlatform().getLogger().info("Server state changed from " + this.serverState + " to " + serverState + " for " + connection.getProtocolInfo().getUuid());
}
this.serverState = serverState;
}
@Override
@@ -108,7 +126,8 @@ public class ProtocolInfoImpl implements ProtocolInfo {
@Override
public String toString() {
return "ProtocolInfo{" +
"state=" + state +
"clientState=" + clientState +
", serverState=" + serverState +
", protocolVersion=" + protocolVersion +
", serverProtocolVersion=" + serverProtocolVersion +
", username='" + username + '\'' +
@@ -27,6 +27,7 @@ import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketTracker;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
@@ -94,12 +95,19 @@ public class UserConnectionImpl implements UserConnection {
@Override
public <T extends StorableObject> @Nullable T remove(Class<T> objectClass) {
return (T) storedObjects.remove(objectClass);
final StorableObject object = storedObjects.remove(objectClass);
if (object != null) {
object.onRemove();
}
return (T) object;
}
@Override
public void put(StorableObject object) {
storedObjects.put(object.getClass(), object);
final StorableObject previousObject = storedObjects.put(object.getClass(), object);
if (previousObject != null) {
previousObject.onRemove();
}
}
@Override
@@ -122,12 +130,21 @@ public class UserConnectionImpl implements UserConnection {
@Override
public void clearStoredObjects(boolean isServerSwitch) {
if (isServerSwitch) {
storedObjects.values().removeIf(StorableObject::clearOnServerSwitch);
storedObjects.values().removeIf(storableObject -> {
if (storableObject.clearOnServerSwitch()) {
storableObject.onRemove();
return true;
}
return false;
});
for (EntityTracker tracker : entityTrackers.values()) {
tracker.clearEntities();
tracker.trackClientEntity();
}
} else {
for (StorableObject object : storedObjects.values()) {
object.onRemove();
}
storedObjects.clear();
entityTrackers.clear();
}
@@ -308,8 +325,9 @@ public class UserConnectionImpl implements UserConnection {
}
PacketWrapper wrapper = new PacketWrapperImpl(id, buf, this);
State state = protocolInfo.getState(direction);
try {
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(), wrapper);
protocolInfo.getPipeline().transform(direction, state, wrapper);
} catch (CancelException ex) {
throw cancelSupplier.apply(ex);
}
@@ -37,7 +37,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis
private final UserConnection connection;
private final EntityType playerType;
private int clientEntityId = -1;
private int currentWorldSectionHeight = 16;
private int currentWorldSectionHeight = -1;
private int currentMinY;
private String currentWorld;
private int biomesSent = -1;
@@ -70,17 +70,20 @@ import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.Protocol1_19_1To
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.Protocol1_19_3To1_19_1;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.Protocol1_19_4To1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.Protocol1_20To1_19_4;
import com.viaversion.viaversion.protocols.protocol1_9_1to1_9.Protocol1_9_1To1_9;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3To1_9_1_2;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_9_1.Protocol1_9To1_9_1;
import com.viaversion.viaversion.util.Pair;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap;
import org.checkerframework.checker.nullness.qual.Nullable;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -101,8 +104,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import org.checkerframework.checker.nullness.qual.Nullable;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
public class ProtocolManagerImpl implements ProtocolManager {
private static final Protocol BASE_PROTOCOL = new BaseProtocol();
@@ -139,8 +140,6 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_9_1To1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getVersion(), ProtocolVersion.v1_9_2.getVersion()), ProtocolVersion.v1_9.getVersion());
registerProtocol(new Protocol1_9_3To1_9_1_2(), ProtocolVersion.v1_9_3, ProtocolVersion.v1_9_2);
registerProtocol(new Protocol1_9To1_9_1(), ProtocolVersion.v1_9, ProtocolVersion.v1_9_1);
registerProtocol(new Protocol1_9_1_2To1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getVersion(), ProtocolVersion.v1_9_2.getVersion()), ProtocolVersion.v1_9_3.getVersion());
registerProtocol(new Protocol1_10To1_9_3_4(), ProtocolVersion.v1_10, ProtocolVersion.v1_9_3);
registerProtocol(new Protocol1_11To1_10(), ProtocolVersion.v1_11, ProtocolVersion.v1_10);
@@ -180,6 +179,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_19_1To1_19(), ProtocolVersion.v1_19_1, ProtocolVersion.v1_19);
registerProtocol(new Protocol1_19_3To1_19_1(), ProtocolVersion.v1_19_3, ProtocolVersion.v1_19_1);
registerProtocol(new Protocol1_19_4To1_19_3(), ProtocolVersion.v1_19_4, ProtocolVersion.v1_19_3);
registerProtocol(new Protocol1_20To1_19_4(), ProtocolVersion.v1_20, ProtocolVersion.v1_19_4);
registerProtocol(new Protocol1_20_2To1_20(), ProtocolVersion.v1_20_2, ProtocolVersion.v1_20);
}
@Override
@@ -17,7 +17,6 @@
*/
package com.viaversion.viaversion.protocol;
import com.google.common.collect.Sets;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.debug.DebugHandler;
@@ -30,9 +29,10 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -42,8 +42,10 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
/**
* Protocol list ordered from client to server transforation with the base protocols at the end.
*/
private List<Protocol> protocolList;
private Set<Class<? extends Protocol>> protocolSet;
private final List<Protocol> protocolList = new CopyOnWriteArrayList<>();
private final Set<Class<? extends Protocol>> protocolSet = new HashSet<>();
private List<Protocol> reversedProtocolList = new CopyOnWriteArrayList<>();
private int baseProtocols;
public ProtocolPipelineImpl(UserConnection userConnection) {
this.userConnection = userConnection;
@@ -53,14 +55,12 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
@Override
protected void registerPackets() {
protocolList = new CopyOnWriteArrayList<>();
// Create a backing set for faster contains calls with larger pipes
protocolSet = Sets.newSetFromMap(new ConcurrentHashMap<>());
// This is a pipeline so we register basic pipes
Protocol baseProtocol = Via.getManager().getProtocolManager().getBaseProtocol();
final Protocol<?, ?, ?, ?> baseProtocol = Via.getManager().getProtocolManager().getBaseProtocol();
protocolList.add(baseProtocol);
reversedProtocolList.add(baseProtocol);
protocolSet.add(baseProtocol.getClass());
baseProtocols++;
}
@Override
@@ -69,44 +69,38 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
}
@Override
public void add(Protocol protocol) {
protocolList.add(protocol);
public synchronized void add(final Protocol protocol) {
if (protocol.isBaseProtocol()) {
// Add base protocol on top of previous ones
protocolList.add(baseProtocols, protocol);
reversedProtocolList.add(baseProtocols, protocol);
baseProtocols++;
} else {
protocolList.add(protocol);
reversedProtocolList.add(0, protocol);
}
protocolSet.add(protocol.getClass());
protocol.init(userConnection);
if (!protocol.isBaseProtocol()) {
moveBaseProtocolsToTail();
}
}
@Override
public void add(Collection<Protocol> protocols) {
public synchronized void add(final Collection<Protocol> protocols) {
protocolList.addAll(protocols);
for (Protocol protocol : protocols) {
for (final Protocol protocol : protocols) {
protocol.init(userConnection);
this.protocolSet.add(protocol.getClass());
protocolSet.add(protocol.getClass());
}
moveBaseProtocolsToTail();
refreshReversedList();
}
private void moveBaseProtocolsToTail() {
// Move base Protocols to the end, so the login packets can be modified by other protocols
List<Protocol> baseProtocols = null;
for (Protocol protocol : protocolList) {
if (protocol.isBaseProtocol()) {
if (baseProtocols == null) {
baseProtocols = new ArrayList<>();
}
baseProtocols.add(protocol);
}
}
if (baseProtocols != null) {
protocolList.removeAll(baseProtocols);
protocolList.addAll(baseProtocols);
}
private synchronized void refreshReversedList() {
final List<Protocol> protocols = new ArrayList<>(protocolList.subList(0, this.baseProtocols));
final List<Protocol> additionalProtocols = new ArrayList<>(protocolList.subList(this.baseProtocols, protocolList.size()));
Collections.reverse(additionalProtocols);
protocols.addAll(additionalProtocols);
reversedProtocolList = new CopyOnWriteArrayList<>(protocols);
}
@Override
@@ -119,7 +113,7 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
}
// Apply protocols
packetWrapper.apply(direction, state, 0, protocolList, direction == Direction.CLIENTBOUND);
packetWrapper.apply(direction, state, 0, protocolListFor(direction));
super.transform(direction, state, packetWrapper);
if (debugHandler.enabled() && debugHandler.logPostPacketTransform() && debugHandler.shouldLog(packetWrapper, direction)) {
@@ -127,6 +121,10 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
}
}
private List<Protocol> protocolListFor(final Direction direction) {
return Collections.unmodifiableList(direction == Direction.SERVERBOUND ? protocolList : reversedProtocolList);
}
private void logPacket(Direction direction, State state, PacketWrapper packetWrapper, int originalID) {
// Debug packet
int clientProtocol = userConnection.getProtocolInfo().getProtocolVersion();
@@ -166,7 +164,12 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
@Override
public List<Protocol> pipes() {
return protocolList;
return Collections.unmodifiableList(protocolList);
}
@Override
public List<Protocol> reversedPipes() {
return Collections.unmodifiableList(reversedProtocolList);
}
@Override
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.protocol.packet;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.Direction;
@@ -266,20 +267,37 @@ public class PacketWrapperImpl implements PacketWrapper {
}
private void send0(Class<? extends Protocol> protocol, boolean skipCurrentPipeline, boolean currentThread) throws Exception {
if (isCancelled()) return;
try {
ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.CLIENTBOUND);
if (currentThread) {
user().sendRawPacket(output);
} else {
user().scheduleSendRawPacket(output);
}
} catch (Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
if (isCancelled()) {
return;
}
final UserConnection connection = user();
if (currentThread) {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.CLIENTBOUND);
connection.sendRawPacket(output);
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
}
return;
}
connection.getChannel().eventLoop().submit(() -> {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.CLIENTBOUND);
connection.sendRawPacket(output);
} catch (final RuntimeException e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw new RuntimeException(e);
}
}
});
}
/**
@@ -291,12 +309,18 @@ public class PacketWrapperImpl implements PacketWrapper {
* @throws Exception if it fails to write
*/
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, Direction direction) throws Exception {
// Apply current pipeline - for outgoing protocol, the collection will be reversed in the apply method
Protocol[] protocols = user().getProtocolInfo().getPipeline().pipes().toArray(PROTOCOL_ARRAY);
boolean reverse = direction == Direction.CLIENTBOUND;
final ProtocolInfo protocolInfo = user().getProtocolInfo();
final List<Protocol> pipes = direction == Direction.SERVERBOUND ? protocolInfo.getPipeline().pipes() : protocolInfo.getPipeline().reversedPipes();
final List<Protocol> protocols = new ArrayList<>();
int index = -1;
for (int i = 0; i < protocols.length; i++) {
if (protocols[i].getClass() == packetProtocol) {
for (int i = 0; i < pipes.size(); i++) {
// Always add base protocols to the head
final Protocol protocol = pipes.get(i);
if (protocol.isBaseProtocol()) {
protocols.add(protocol);
}
if (protocol.getClass() == packetProtocol) {
index = i;
break;
}
@@ -308,15 +332,18 @@ public class PacketWrapperImpl implements PacketWrapper {
}
if (skipCurrentPipeline) {
index = reverse ? index - 1 : index + 1;
index = Math.min(index + 1, pipes.size());
}
// Add remaining protocols on top
protocols.addAll(pipes.subList(index, pipes.size()));
// Reset reader before we start
resetReader();
// Apply other protocols
apply(direction, user().getProtocolInfo().getState(), index, protocols, reverse);
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
apply(direction, protocolInfo.getState(direction), 0, protocols);
final ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
try {
writeToBuffer(output);
return output.retain();
@@ -385,15 +412,22 @@ public class PacketWrapperImpl implements PacketWrapper {
private PacketWrapperImpl apply(Direction direction, State state, int index, Protocol[] pipeline, boolean reverse) throws Exception {
// Reset the reader after every transformation for the packetWrapper, so it can be recycled across packets
State updatedState = state; // The state might change while transforming, so we need to check for that
if (reverse) {
for (int i = index; i >= 0; i--) {
pipeline[i].transform(direction, state, this);
pipeline[i].transform(direction, updatedState, this);
resetReader();
if (this.packetType != null) {
updatedState = this.packetType.state();
}
}
} else {
for (int i = index; i < pipeline.length; i++) {
pipeline[i].transform(direction, state, this);
pipeline[i].transform(direction, updatedState, this);
resetReader();
if (this.packetType != null) {
updatedState = this.packetType.state();
}
}
}
return this;
@@ -434,7 +468,9 @@ public class PacketWrapperImpl implements PacketWrapper {
}
private void sendToServerRaw(boolean currentThread) throws Exception {
if (isCancelled()) return;
if (isCancelled()) {
return;
}
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
try {
@@ -464,18 +500,33 @@ public class PacketWrapperImpl implements PacketWrapper {
return;
}
try {
ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.SERVERBOUND);
if (currentThread) {
user().sendRawPacketToServer(output);
} else {
user().scheduleSendRawPacketToServer(output);
}
} catch (Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
final UserConnection connection = user();
if (currentThread) {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.SERVERBOUND);
connection.sendRawPacketToServer(output);
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
}
return;
}
connection.getChannel().eventLoop().submit(() -> {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.SERVERBOUND);
connection.sendRawPacketToServer(output);
} catch (final RuntimeException e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw new RuntimeException(e);
}
}
});
}
@Override
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.protocols.base;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import java.util.UUID;
public class BaseProtocol1_16 extends BaseProtocol1_7 {
@@ -45,9 +45,6 @@ public class BaseProtocol1_7 extends AbstractProtocol {
@Override
protected void registerPackets() {
/* Outgoing Packets */
// Status Response Packet
registerClientbound(ClientboundStatusPackets.STATUS_RESPONSE, new PacketHandlers() { // Status Response Packet
@Override
public void register() {
@@ -122,7 +119,9 @@ public class BaseProtocol1_7 extends AbstractProtocol {
// Login Success Packet
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
ProtocolInfo info = wrapper.user().getProtocolInfo();
info.setState(State.PLAY);
if (info.getProtocolVersion() < ProtocolVersion.v1_20_2.getVersion()) { // On 1.20.2+, wait for the login ack
info.setState(State.PLAY);
}
UUID uuid = passthroughLoginUUID(wrapper);
info.setUuid(uuid);
@@ -147,7 +146,6 @@ public class BaseProtocol1_7 extends AbstractProtocol {
}
});
/* Incoming Packets */
// Login Start Packet
registerServerbound(ServerboundLoginPackets.HELLO, wrapper -> {
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
@@ -164,6 +162,11 @@ public class BaseProtocol1_7 extends AbstractProtocol {
future.addListener(f -> wrapper.user().getChannel().close());
}
});
registerServerbound(ServerboundLoginPackets.LOGIN_ACKNOWLEDGED, wrapper -> {
final ProtocolInfo info = wrapper.user().getProtocolInfo();
info.setState(State.CONFIGURATION);
});
}
@Override
@@ -23,7 +23,8 @@ import com.viaversion.viaversion.api.protocol.packet.State;
public enum ServerboundLoginPackets implements ServerboundPacketType {
HELLO, // 0x00
ENCRYPTION_KEY, // 0x01
CUSTOM_QUERY; // 0x02
CUSTOM_QUERY_ANSWER, // 0x02
LOGIN_ACKNOWLEDGED; // 0x03
@Override
public final int getId() {
@@ -31,9 +31,9 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_9;
import com.viaversion.viaversion.protocols.protocol1_10to1_9_3.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_10to1_9_3.storage.ResourcePackTracker;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -33,9 +33,9 @@ import com.viaversion.viaversion.protocols.protocol1_11to1_10.data.PotionColorMa
import com.viaversion.viaversion.protocols.protocol1_11to1_10.metadata.MetadataRewriter1_11To1_10;
import com.viaversion.viaversion.protocols.protocol1_11to1_10.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_11to1_10.storage.EntityTracker1_11;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.util.Pair;
@@ -40,9 +40,9 @@ import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.packets.Inventor
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.rewriter.SoundRewriter;
@@ -55,6 +55,7 @@ import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.Inventor
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PaintingProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockConnectionStorage;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker;
@@ -636,7 +637,8 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
// Fake the end of the packet
handler(wrapper -> {
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.OPTIONAL_POSITION, null);
final Position playerLookTarget = Via.getManager().getProviders().get(PlayerLookTargetProvider.class).getPlayerLookTarget(wrapper.user());
wrapper.write(Type.OPTIONAL_POSITION, playerLookTarget);
if (!wrapper.isCancelled() && Via.getConfig().get1_13TabCompleteDelay() > 0) {
TabCompleteTracker tracker = wrapper.user().get(TabCompleteTracker.class);
wrapper.cancel();
@@ -876,6 +878,7 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
public void register(ViaProviders providers) {
providers.register(BlockEntityProvider.class, new BlockEntityProvider());
providers.register(PaintingProvider.class, new PaintingProvider());
providers.register(PlayerLookTargetProvider.class, new PlayerLookTargetProvider());
}
// Based on method from https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/ChatColor.java
@@ -64,6 +64,8 @@ public final class ConnectionData {
}
public static void update(UserConnection user, Position position) throws Exception {
Boolean inSync = null;
for (BlockFace face : BlockFace.values()) {
Position pos = position.getRelative(face);
int blockState = blockConnectionProvider.getBlockData(user, pos.x(), pos.y(), pos.z());
@@ -73,8 +75,14 @@ public final class ConnectionData {
}
int newBlockState = handler.connect(user, pos, blockState);
if (newBlockState == blockState && blockConnectionProvider.storesBlocks()) {
continue;
if (newBlockState == blockState) {
if (inSync == null) {
inSync = blockConnectionProvider.storesBlocks(user, position);
}
// Blocks-states are the same, and known to be stored and not de-synced, skip update
if (inSync) {
continue;
}
}
updateBlockStorage(user, pos.x(), pos.y(), pos.z(), newBlockState);
@@ -100,8 +108,13 @@ public final class ConnectionData {
blockConnectionProvider.clearStorage(connection);
}
public static void markModified(UserConnection connection, Position pos) {
if (!needStoreBlocks()) return;
blockConnectionProvider.modifiedBlock(connection, pos);
}
public static boolean needStoreBlocks() {
return blockConnectionProvider.storesBlocks();
return blockConnectionProvider.storesBlocks(null, null);
}
public static void connectBlocks(UserConnection user, Chunk chunk) {
@@ -726,7 +739,7 @@ public final class ConnectionData {
Position pos = new Position(x, y, z);
int newBlockState = handler.connect(user, pos, blockState);
if (blockState != newBlockState || !blockConnectionProvider.storesBlocks()) {
if (blockState != newBlockState || !blockConnectionProvider.storesBlocks(user, null)) {
records.add(new BlockChangeRecord1_8(x & 0xF, y, z & 0xF, newBlockState));
updateBlockStorage(user, x, y, z, newBlockState);
}
@@ -18,8 +18,10 @@
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.platform.providers.Provider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import org.checkerframework.checker.nullness.qual.Nullable;
public class BlockConnectionProvider implements Provider {
@@ -44,6 +46,10 @@ public class BlockConnectionProvider implements Provider {
}
public void modifiedBlock(UserConnection connection, Position position) {
}
public void unloadChunk(UserConnection connection, int x, int z) {
}
@@ -52,7 +58,14 @@ public class BlockConnectionProvider implements Provider {
}
public boolean storesBlocks() {
/**
* True if blocks are stored, and are known to be accurate around the given position.
* If the client has modified the position (ie: placed or broken a block) this should return false.
*
* @param position The position at which block reliability should be checked, null for general-purpose
* @return true if the block & its neighbors are known to be correct
*/
public boolean storesBlocks(UserConnection user, @Nullable Position position) {
return false;
}
@@ -18,7 +18,9 @@
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockConnectionStorage;
import org.checkerframework.checker.nullness.qual.Nullable;
public class PacketBlockConnectionProvider extends BlockConnectionProvider {
@@ -42,6 +44,10 @@ public class PacketBlockConnectionProvider extends BlockConnectionProvider {
connection.get(BlockConnectionStorage.class).clear();
}
public void modifiedBlock(UserConnection connection, Position position) {
connection.get(BlockConnectionStorage.class).markModified(position);
}
@Override
public void unloadChunk(UserConnection connection, int x, int z) {
connection.get(BlockConnectionStorage.class).unloadChunk(x, z);
@@ -53,8 +59,10 @@ public class PacketBlockConnectionProvider extends BlockConnectionProvider {
}
@Override
public boolean storesBlocks() {
return true;
public boolean storesBlocks(UserConnection connection, @Nullable Position pos) {
if (pos == null || connection == null) return true;
return !connection.get(BlockConnectionStorage.class).recentlyModified(pos);
}
@Override
@@ -94,37 +94,38 @@ public class MappingData extends MappingDataBase {
}
}
Map<String, String> translateData = GsonUtil.getGson().fromJson(
Map<String, String> translationMappingData = GsonUtil.getGson().fromJson(
new InputStreamReader(MappingData.class.getClassLoader().getResourceAsStream("assets/viaversion/data/mapping-lang-1.12-1.13.json")),
new TypeToken<Map<String, String>>() {
}.getType());
try {
String[] lines;
try (Reader reader = new InputStreamReader(MappingData.class.getClassLoader()
.getResourceAsStream("assets/viaversion/data/en_US.properties"), StandardCharsets.UTF_8)) {
lines = CharStreams.toString(reader).split("\n");
}
for (String line : lines) {
if (line.isEmpty()) {
continue;
}
String[] keyAndTranslation = line.split("=", 2);
if (keyAndTranslation.length != 2) {
continue;
}
String key = keyAndTranslation[0];
String translation = keyAndTranslation[1].replaceAll("%(\\d\\$)?d", "%$1s").trim();
mojangTranslation.put(key, translation);
String dataValue = translateData.get(key);
if (dataValue != null) {
translateMapping.put(key, dataValue);
}
}
String[] unmappedTranslationLines;
try (Reader reader = new InputStreamReader(MappingData.class.getClassLoader()
.getResourceAsStream("assets/viaversion/data/en_US.properties"), StandardCharsets.UTF_8)) {
unmappedTranslationLines = CharStreams.toString(reader).split("\n");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
for (String line : unmappedTranslationLines) {
if (line.isEmpty()) {
continue;
}
String[] keyAndTranslation = line.split("=", 2);
if (keyAndTranslation.length != 2) {
continue;
}
String key = keyAndTranslation[0];
String translation = keyAndTranslation[1].replaceAll("%(\\d\\$)?d", "%$1s").trim();
mojangTranslation.put(key, translation);
// Null values in the file mean the key did not change AND the translation has the same amount of placeholders still
if (translationMappingData.containsKey(key)) {
String mappedKey = translationMappingData.get(key);
translateMapping.put(key, mappedKey != null ? mappedKey : key);
}
}
}
@@ -72,7 +72,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_12_1, Ser
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.ITEM_ARRAY, Type.FLAT_ITEM_ARRAY); // 1 - Window Values
handler(itemArrayHandler(Type.FLAT_ITEM_ARRAY));
handler(itemArrayToClientHandler(Type.FLAT_ITEM_ARRAY));
}
});
protocol.registerClientbound(ClientboundPackets1_12_1.WINDOW_PROPERTY, new PacketHandlers() {
@@ -36,6 +36,7 @@ import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionHandler;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.NamedSoundRewriter;
@@ -44,10 +45,11 @@ import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.BlockE
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PaintingProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
@@ -56,7 +58,7 @@ public class WorldPackets {
private static final IntSet VALID_BIOMES = new IntOpenHashSet(70, .99F);
static {
// Client will crash if it receives a invalid biome id
// Client will crash if it receives an invalid biome id
for (int i = 0; i < 50; i++) {
VALID_BIOMES.add(i);
}
@@ -535,6 +537,32 @@ public class WorldPackets {
});
}
});
// Incoming Packets
protocol.registerServerbound(ServerboundPackets1_13.PLAYER_BLOCK_PLACEMENT, wrapper -> {
Position pos = wrapper.passthrough(Type.POSITION);
wrapper.passthrough(Type.VAR_INT); // block face
wrapper.passthrough(Type.VAR_INT); // hand
wrapper.passthrough(Type.FLOAT); // cursor x
wrapper.passthrough(Type.FLOAT); // cursor y
wrapper.passthrough(Type.FLOAT); // cursor z
if (Via.getConfig().isServersideBlockConnections() && ConnectionData.needStoreBlocks()) {
ConnectionData.markModified(wrapper.user(), pos);
}
});
protocol.registerServerbound(ServerboundPackets1_13.PLAYER_DIGGING, wrapper -> {
int status = wrapper.passthrough(Type.VAR_INT); // Status
Position pos = wrapper.passthrough(Type.POSITION); // Location
wrapper.passthrough(Type.UNSIGNED_BYTE); // block face
// 0 = Started digging: if in creative this causes the block to break directly
// There's no point in storing the finished digging as it may never show-up (creative)
if (status == 0 && Via.getConfig().isServersideBlockConnections() && ConnectionData.needStoreBlocks()) {
ConnectionData.markModified(wrapper.user(), pos);
}
});
}
public static int toNewId(int oldId) {
@@ -0,0 +1,30 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.platform.providers.Provider;
import org.checkerframework.checker.nullness.qual.Nullable;
public class PlayerLookTargetProvider implements Provider {
@Nullable
public Position getPlayerLookTarget(final UserConnection info) {
return null;
}
}
@@ -17,21 +17,28 @@
*/
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage;
import com.google.common.collect.EvictingQueue;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.StorableObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import com.viaversion.viaversion.api.minecraft.Position;
import org.checkerframework.checker.nullness.qual.Nullable;
public class BlockConnectionStorage implements StorableObject {
private static Constructor<?> fastUtilLongObjectHashMap;
private final Map<Long, SectionData> blockStorage = createLongObjectMap();
@SuppressWarnings("UnstableApiUsage")
private final Queue<Position> modified = EvictingQueue.create(5);
// Cache to retrieve section quicker
private Long lastIndex;
private long lastIndex = -1;
private SectionData lastSection;
static {
@@ -88,10 +95,27 @@ public class BlockConnectionStorage implements StorableObject {
}
}
public void markModified(Position pos) {
// Avoid saving the same pos twice
if (!modified.contains(pos)) {
this.modified.add(pos);
}
}
public boolean recentlyModified(Position pos) {
for (Position p : modified) {
if (Math.abs(pos.x() - p.x()) + Math.abs(pos.y() - p.y()) + Math.abs(pos.z() - p.z()) <= 2) {
return true;
}
}
return false;
}
public void clear() {
blockStorage.clear();
lastSection = null;
lastIndex = null;
lastIndex = -1;
modified.clear();
}
public void unloadChunk(int x, int z) {
@@ -105,7 +129,7 @@ public class BlockConnectionStorage implements StorableObject {
}
private @Nullable SectionData getSection(long index) {
if (lastIndex != null && lastIndex == index) {
if (lastIndex == index) {
return lastSection;
}
lastIndex = index;
@@ -114,8 +138,8 @@ public class BlockConnectionStorage implements StorableObject {
private void removeSection(long index) {
blockStorage.remove(index);
if (lastIndex != null && lastIndex == index) {
lastIndex = null;
if (lastIndex == index) {
lastIndex = -1;
lastSection = null;
}
}
@@ -17,12 +17,15 @@
*/
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
public class TabCompleteTracker implements StorableObject {
private int transactionId;
@@ -35,7 +38,8 @@ public class TabCompleteTracker implements StorableObject {
PacketWrapper wrapper = PacketWrapper.create(ServerboundPackets1_12_1.TAB_COMPLETE, null, connection);
wrapper.write(Type.STRING, lastTabComplete);
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.OPTIONAL_POSITION, null);
final Position playerLookTarget = Via.getManager().getProviders().get(PlayerLookTargetProvider.class).getPlayerLookTarget(connection);
wrapper.write(Type.OPTIONAL_POSITION, playerLookTarget);
try {
wrapper.scheduleSendToServer(Protocol1_13To1_12_2.class);
} catch (Exception e) {
@@ -0,0 +1,127 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_14_4 implements ClientboundPacketType {
SPAWN_ENTITY, // 0x00
SPAWN_EXPERIENCE_ORB, // 0x01
SPAWN_GLOBAL_ENTITY, // 0x02
SPAWN_MOB, // 0x03
SPAWN_PAINTING, // 0x04
SPAWN_PLAYER, // 0x05
ENTITY_ANIMATION, // 0x06
STATISTICS, // 0x07
BLOCK_BREAK_ANIMATION, // 0x08
BLOCK_ENTITY_DATA, // 0x09
BLOCK_ACTION, // 0x0A
BLOCK_CHANGE, // 0x0B
BOSSBAR, // 0x0C
SERVER_DIFFICULTY, // 0x0D
CHAT_MESSAGE, // 0x0E
MULTI_BLOCK_CHANGE, // 0x0F
TAB_COMPLETE, // 0x10
DECLARE_COMMANDS, // 0x11
WINDOW_CONFIRMATION, // 0x12
CLOSE_WINDOW, // 0x13
WINDOW_ITEMS, // 0x14
WINDOW_PROPERTY, // 0x15
SET_SLOT, // 0x16
COOLDOWN, // 0x17
PLUGIN_MESSAGE, // 0x18
NAMED_SOUND, // 0x19
DISCONNECT, // 0x1A
ENTITY_STATUS, // 0x1B
EXPLOSION, // 0x1C
UNLOAD_CHUNK, // 0x1D
GAME_EVENT, // 0x1E
OPEN_HORSE_WINDOW, // 0x1F
KEEP_ALIVE, // 0x20
CHUNK_DATA, // 0x21
EFFECT, // 0x22
SPAWN_PARTICLE, // 0x23
UPDATE_LIGHT, // 0x24
JOIN_GAME, // 0x25
MAP_DATA, // 0x26
TRADE_LIST, // 0x27
ENTITY_POSITION, // 0x28
ENTITY_POSITION_AND_ROTATION, // 0x29
ENTITY_ROTATION, // 0x2A
ENTITY_MOVEMENT, // 0x2B
VEHICLE_MOVE, // 0x2C
OPEN_BOOK, // 0x2D
OPEN_WINDOW, // 0x2E
OPEN_SIGN_EDITOR, // 0x2F
CRAFT_RECIPE_RESPONSE, // 0x30
PLAYER_ABILITIES, // 0x31
COMBAT_EVENT, // 0x32
PLAYER_INFO, // 0x33
FACE_PLAYER, // 0x34
PLAYER_POSITION, // 0x35
UNLOCK_RECIPES, // 0x36
DESTROY_ENTITIES, // 0x37
REMOVE_ENTITY_EFFECT, // 0x38
RESOURCE_PACK, // 0x39
RESPAWN, // 0x3A
ENTITY_HEAD_LOOK, // 0x3B
SELECT_ADVANCEMENTS_TAB, // 0x3C
WORLD_BORDER, // 0x3D
CAMERA, // 0x3E
HELD_ITEM_CHANGE, // 0x3F
UPDATE_VIEW_POSITION, // 0x40
UPDATE_VIEW_DISTANCE, // 0x41
DISPLAY_SCOREBOARD, // 0x42
ENTITY_METADATA, // 0x43
ATTACH_ENTITY, // 0x44
ENTITY_VELOCITY, // 0x45
ENTITY_EQUIPMENT, // 0x46
SET_EXPERIENCE, // 0x47
UPDATE_HEALTH, // 0x48
SCOREBOARD_OBJECTIVE, // 0x49
SET_PASSENGERS, // 0x4A
TEAMS, // 0x4B
UPDATE_SCORE, // 0x4C
SPAWN_POSITION, // 0x4D
TIME_UPDATE, // 0x4E
TITLE, // 0x4F
ENTITY_SOUND, // 0x50
SOUND, // 0x51
STOP_SOUND, // 0x52
TAB_LIST, // 0x53
NBT_QUERY, // 0x54
COLLECT_ITEM, // 0x55
ENTITY_TELEPORT, // 0x56
ADVANCEMENTS, // 0x57
ENTITY_PROPERTIES, // 0x58
ENTITY_EFFECT, // 0x59
DECLARE_RECIPES, // 0x5A
TAGS, // 0x5B
ACKNOWLEDGE_PLAYER_DIGGING; // 0x5C
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -22,10 +22,10 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
public class Protocol1_14_4To1_14_3 extends AbstractProtocol<ClientboundPackets1_14, ClientboundPackets1_14, ServerboundPackets1_14, ServerboundPackets1_14> {
public class Protocol1_14_4To1_14_3 extends AbstractProtocol<ClientboundPackets1_14, ClientboundPackets1_14_4, ServerboundPackets1_14, ServerboundPackets1_14> {
public Protocol1_14_4To1_14_3() {
super(ClientboundPackets1_14.class, ClientboundPackets1_14.class, null, null);
super(ClientboundPackets1_14.class, ClientboundPackets1_14_4.class, null, null);
}
@Override
@@ -112,8 +112,7 @@ public enum ClientboundPackets1_14 implements ClientboundPacketType {
ENTITY_PROPERTIES, // 0x58
ENTITY_EFFECT, // 0x59
DECLARE_RECIPES, // 0x5A
TAGS, // 0x5B
ACKNOWLEDGE_PLAYER_DIGGING; // 0x5C
TAGS; // 0x5B
@Override
public int getId() {
@@ -25,7 +25,7 @@ import com.viaversion.viaversion.api.minecraft.entities.Entity1_15Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.metadata.MetadataRewriter1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
@@ -35,15 +35,15 @@ import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_14, ClientboundPackets1_15, ServerboundPackets1_14, ServerboundPackets1_14> {
public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_14_4, ClientboundPackets1_15, ServerboundPackets1_14, ServerboundPackets1_14> {
public static final MappingData MAPPINGS = new MappingDataBase("1.14", "1.15");
private final MetadataRewriter1_15To1_14_4 metadataRewriter = new MetadataRewriter1_15To1_14_4(this);
private final InventoryPackets itemRewriter = new InventoryPackets(this);
private TagRewriter<ClientboundPackets1_14> tagRewriter;
private TagRewriter<ClientboundPackets1_14_4> tagRewriter;
public Protocol1_15To1_14_4() {
super(ClientboundPackets1_14.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
super(ClientboundPackets1_14_4.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
}
@Override
@@ -54,16 +54,16 @@ public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_1
EntityPackets.register(this);
WorldPackets.register(this);
SoundRewriter<ClientboundPackets1_14> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_14.ENTITY_SOUND); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14.SOUND);
SoundRewriter<ClientboundPackets1_14_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_14_4.ENTITY_SOUND); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14_4.SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_14.STATISTICS);
new StatisticsRewriter<>(this).register(ClientboundPackets1_14_4.STATISTICS);
registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> itemRewriter.handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
tagRewriter = new TagRewriter<>(this);
tagRewriter.register(ClientboundPackets1_14.TAGS, RegistryType.ENTITY);
tagRewriter.register(ClientboundPackets1_14_4.TAGS, RegistryType.ENTITY);
}
@Override
@@ -24,13 +24,13 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import java.util.List;
public class MetadataRewriter1_15To1_14_4 extends EntityRewriter<ClientboundPackets1_14, Protocol1_15To1_14_4> {
public class MetadataRewriter1_15To1_14_4 extends EntityRewriter<ClientboundPackets1_14_4, Protocol1_15To1_14_4> {
public MetadataRewriter1_15To1_14_4(Protocol1_15To1_14_4 protocol) {
super(protocol);
@@ -24,21 +24,21 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.metadata.MetadataRewriter1_15To1_14_4;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import java.util.List;
public class EntityPackets {
public final class EntityPackets {
public static void register(Protocol1_15To1_14_4 protocol) {
MetadataRewriter1_15To1_14_4 metadataRewriter = protocol.get(MetadataRewriter1_15To1_14_4.class);
metadataRewriter.registerTrackerWithData(ClientboundPackets1_14.SPAWN_ENTITY, Entity1_15Types.FALLING_BLOCK);
metadataRewriter.registerTrackerWithData(ClientboundPackets1_14_4.SPAWN_ENTITY, Entity1_15Types.FALLING_BLOCK);
protocol.registerClientbound(ClientboundPackets1_14.SPAWN_MOB, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.SPAWN_MOB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // 0 - Entity ID
@@ -59,7 +59,7 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.SPAWN_PLAYER, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // 0 - Entity ID
@@ -79,7 +79,7 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.RESPAWN, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.RESPAWN, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
@@ -87,7 +87,7 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.JOIN_GAME, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Entity ID
@@ -105,8 +105,8 @@ public class EntityPackets {
}
});
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_14.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_14.DESTROY_ENTITIES);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_14_4.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_14_4.DESTROY_ENTITIES);
}
private static void sendMetadataPacket(PacketWrapper wrapper, int entityId, EntityRewriter<?, ?> rewriter) throws Exception {
@@ -18,13 +18,13 @@
package com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
public class InventoryPackets extends ItemRewriter<ClientboundPackets1_14, ServerboundPackets1_14, Protocol1_15To1_14_4> {
public class InventoryPackets extends ItemRewriter<ClientboundPackets1_14_4, ServerboundPackets1_14, Protocol1_15To1_14_4> {
public InventoryPackets(Protocol1_15To1_14_4 protocol) {
super(protocol);
@@ -32,14 +32,14 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_14, Serve
@Override
public void registerPackets() {
registerSetCooldown(ClientboundPackets1_14.COOLDOWN);
registerWindowItems(ClientboundPackets1_14.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
registerTradeList(ClientboundPackets1_14.TRADE_LIST);
registerSetSlot(ClientboundPackets1_14.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerEntityEquipment(ClientboundPackets1_14.ENTITY_EQUIPMENT, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_14.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
registerSetCooldown(ClientboundPackets1_14_4.COOLDOWN);
registerWindowItems(ClientboundPackets1_14_4.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
registerTradeList(ClientboundPackets1_14_4.TRADE_LIST);
registerSetSlot(ClientboundPackets1_14_4.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerEntityEquipment(ClientboundPackets1_14_4.ENTITY_EQUIPMENT, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_14_4.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_14.DECLARE_RECIPES);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_14_4.DECLARE_RECIPES);
registerClickWindow(ServerboundPackets1_14.CLICK_WINDOW, Type.FLAT_VAR_INT_ITEM);
registerCreativeInvAction(ServerboundPackets1_14.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
@@ -23,23 +23,23 @@ import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.types.Chunk1_15Type;
import com.viaversion.viaversion.rewriter.BlockRewriter;
public class WorldPackets {
public final class WorldPackets {
public static void register(Protocol1_15To1_14_4 protocol) {
BlockRewriter<ClientboundPackets1_14> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
BlockRewriter<ClientboundPackets1_14_4> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_14.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_14.BLOCK_CHANGE);
blockRewriter.registerMultiBlockChange(ClientboundPackets1_14.MULTI_BLOCK_CHANGE);
blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_14.ACKNOWLEDGE_PLAYER_DIGGING);
blockRewriter.registerBlockAction(ClientboundPackets1_14_4.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_14_4.BLOCK_CHANGE);
blockRewriter.registerMultiBlockChange(ClientboundPackets1_14_4.MULTI_BLOCK_CHANGE);
blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_14_4.ACKNOWLEDGE_PLAYER_DIGGING);
protocol.registerClientbound(ClientboundPackets1_14.CHUNK_DATA, wrapper -> {
protocol.registerClientbound(ClientboundPackets1_14_4.CHUNK_DATA, wrapper -> {
Chunk chunk = wrapper.read(new Chunk1_14Type());
wrapper.write(new Chunk1_15Type(), chunk);
@@ -79,8 +79,8 @@ public class WorldPackets {
}
});
blockRewriter.registerEffect(ClientboundPackets1_14.EFFECT, 1010, 2001);
protocol.registerClientbound(ClientboundPackets1_14.SPAWN_PARTICLE, new PacketHandlers() {
blockRewriter.registerEffect(ClientboundPackets1_14_4.EFFECT, 1010, 2001);
protocol.registerClientbound(ClientboundPackets1_14_4.SPAWN_PARTICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Particle ID
@@ -40,8 +40,7 @@ public class MappingData extends MappingDataBase {
@Override
public void loadExtras(final CompoundTag data) {
try {
// TODO Read uncompressed file
dimensionRegistry = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
dimensionRegistry = BinaryTagIO.readInputStream(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
} catch (final IOException e) {
Via.getPlatform().getLogger().severe("Error loading dimension registry:");
e.printStackTrace();
@@ -25,6 +25,7 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_16Types;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -40,6 +41,7 @@ import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.metadata.Metadat
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
@@ -195,10 +197,11 @@ public class Protocol1_16To1_15_2 extends AbstractProtocol<ClientboundPackets1_1
}
registerServerbound(ServerboundPackets1_16.PLAYER_ABILITIES, wrapper -> {
wrapper.passthrough(Type.BYTE);
// Flying and walking speed - not important anyways
wrapper.write(Type.FLOAT, 0.05F);
wrapper.write(Type.FLOAT, 0.1F);
wrapper.passthrough(Type.BYTE); // Flags
final PlayerAbilitiesProvider playerAbilities = Via.getManager().getProviders().get(PlayerAbilitiesProvider.class);
wrapper.write(Type.FLOAT, playerAbilities.getFlyingSpeed(wrapper.user()));
wrapper.write(Type.FLOAT, playerAbilities.getWalkingSpeed(wrapper.user()));
});
cancelServerbound(ServerboundPackets1_16.GENERATE_JIGSAW);
@@ -257,6 +260,11 @@ public class Protocol1_16To1_15_2 extends AbstractProtocol<ClientboundPackets1_1
.reader("item", ParticleType.Readers.VAR_INT_ITEM);
}
@Override
public void register(ViaProviders providers) {
providers.register(PlayerAbilitiesProvider.class, new PlayerAbilitiesProvider());
}
@Override
public void init(UserConnection userConnection) {
userConnection.addEntityTracker(this.getClass(), new EntityTrackerBase(userConnection, Entity1_16Types.PLAYER));
@@ -277,7 +277,7 @@ public class EntityPackets {
protocol.registerServerbound(ServerboundPackets1_16.ANIMATION, wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
// Don't send an arm swing if the player has an inventory opened.
if (inventoryTracker.getInventory() != -1) {
if (inventoryTracker.isInventoryOpen()) {
wrapper.cancel();
}
});
@@ -67,12 +67,11 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_15, Serve
handler(cursorRemapper);
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
int windowId = wrapper.get(Type.VAR_INT, 0);
int windowType = wrapper.get(Type.VAR_INT, 1);
if (windowType >= 20) { // smithing added with id 20
wrapper.set(Type.VAR_INT, 1, ++windowType);
}
inventoryTracker.setInventory((short) windowId);
inventoryTracker.setInventoryOpen(true);
});
}
});
@@ -83,7 +82,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_15, Serve
handler(cursorRemapper);
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventory((short) -1);
inventoryTracker.setInventoryOpen(false);
});
}
});
@@ -133,7 +132,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_15, Serve
protocol.registerServerbound(ServerboundPackets1_16.CLOSE_WINDOW, wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventory((short) -1);
inventoryTracker.setInventoryOpen(false);
});
protocol.registerServerbound(ServerboundPackets1_16.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
@@ -0,0 +1,32 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.Provider;
public class PlayerAbilitiesProvider implements Provider {
public float getFlyingSpeed(final UserConnection connection) {
return 0.05F;
}
public float getWalkingSpeed(final UserConnection connection) {
return 0.1F;
}
}
@@ -20,13 +20,13 @@ package com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public class InventoryTracker1_16 implements StorableObject {
private short inventory = -1;
private boolean inventoryOpen = false;
public short getInventory() {
return this.inventory;
public boolean isInventoryOpen() {
return inventoryOpen;
}
public void setInventory(short inventory) {
this.inventory = inventory;
public void setInventoryOpen(boolean inventoryOpen) {
this.inventoryOpen = inventoryOpen;
}
}
@@ -162,7 +162,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_16_2
}
}
});
registerMetaTypeHandler(Types1_17.META_TYPES.itemType, Types1_17.META_TYPES.blockStateType, Types1_17.META_TYPES.particleType);
registerMetaTypeHandler(Types1_17.META_TYPES.itemType, Types1_17.META_TYPES.blockStateType, null, Types1_17.META_TYPES.particleType);
// Ticks frozen added with id 7
filter().filterFamily(Entity1_17Types.ENTITY).addIndex(7);
@@ -17,6 +17,9 @@
*/
package com.viaversion.viaversion.protocols.protocol1_17to1_16_4.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -122,4 +125,23 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_16_
wrapper.cancel();
});
}
@Override
public Item handleItemToClient(Item item) {
if (item == null) return null;
CompoundTag tag = item.tag();
if (item.identifier() == 733) {
if (tag == null) {
item.setTag(tag = new CompoundTag());
}
if (!(tag.get("map") instanceof NumberTag)) {
tag.put("map", new IntTag(0));
}
}
item.setIdentifier(this.protocol.getMappingData().getNewItemId(item.identifier()));
return item;
}
}
@@ -96,7 +96,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_17_1
}
});
registerMetaTypeHandler(Types1_18.META_TYPES.itemType, null, null);
registerMetaTypeHandler(Types1_18.META_TYPES.itemType, null, null, null);
}
@Override
@@ -289,7 +289,7 @@ public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPa
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Entity1_19_3Types.initialize(this);
@@ -155,7 +155,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_1
final int id = meta.metaType().typeId();
meta.setMetaType(Types1_19_3.META_TYPES.byId(id >= 2 ? id + 1 : id)); // long added
});
registerMetaTypeHandler(Types1_19_3.META_TYPES.itemType, Types1_19_3.META_TYPES.blockStateType, Types1_19_3.META_TYPES.particleType);
registerMetaTypeHandler(Types1_19_3.META_TYPES.itemType, Types1_19_3.META_TYPES.blockStateType, null, Types1_19_3.META_TYPES.particleType);
filter().index(6).handler((event, meta) -> {
// Sitting pose added
@@ -48,7 +48,7 @@ public class RecipeRewriter1_19_3<C extends ClientboundPacketType> extends Recip
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.VAR_INT); // Crafting book category
handleIngredients(wrapper);
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
rewrite(wrapper.passthrough(itemType())); // Result
}
@Override
@@ -59,7 +59,7 @@ public class RecipeRewriter1_19_3<C extends ClientboundPacketType> extends Recip
for (int i = 0; i < ingredients; i++) {
handleIngredient(wrapper);
}
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
rewrite(wrapper.passthrough(itemType())); // Result
}
@Override
@@ -67,7 +67,7 @@ public class RecipeRewriter1_19_3<C extends ClientboundPacketType> extends Recip
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.VAR_INT); // Crafting book category
handleIngredient(wrapper);
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
rewrite(wrapper.passthrough(itemType())); // Result
wrapper.passthrough(Type.FLOAT); // EXP
wrapper.passthrough(Type.VAR_INT); // Cooking time
}
@@ -35,6 +35,7 @@ import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.packets.Invent
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.storage.PlayerVehicleTracker;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@@ -54,6 +55,7 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
super.registerPackets();
new TagRewriter<>(this).registerGeneric(ClientboundPackets1_19_3.TAGS);
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_3.STATISTICS);
final SoundRewriter<ClientboundPackets1_19_3> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_19_3.ENTITY_SOUND);
@@ -99,7 +101,7 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
}
@@ -34,8 +34,7 @@ public final class MappingData extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag data) {
try {
// TODO Read uncompressed file
damageTypesRegistry = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("damage-types-1.19.4.nbt"));
damageTypesRegistry = BinaryTagIO.readInputStream(MappingDataLoader.getResource("damage-types-1.19.4.nbt"));
} catch (final IOException e) {
throw new RuntimeException(e);
}
@@ -106,6 +106,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.SET_PASSENGERS, new PacketHandlers() {
@Override
protected void register() {
@@ -131,6 +132,30 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.ENTITY_TELEPORT, new PacketHandlers() {
@Override
protected void register() {
handler(wrapper -> {
final int entityId = wrapper.read(Type.VAR_INT); // entity id
final int clientEntityId = wrapper.user().getEntityTracker(Protocol1_19_4To1_19_3.class).clientEntityId();
if (entityId != clientEntityId) {
wrapper.write(Type.VAR_INT, entityId); // entity id
return;
}
wrapper.setPacketType(ClientboundPackets1_19_4.PLAYER_POSITION);
wrapper.passthrough(Type.DOUBLE); // x
wrapper.passthrough(Type.DOUBLE); // y
wrapper.passthrough(Type.DOUBLE); // z
wrapper.write(Type.FLOAT, wrapper.read(Type.BYTE) * 360F / 256F); // yaw
wrapper.write(Type.FLOAT, wrapper.read(Type.BYTE) * 360F / 256F); // pitch
wrapper.read(Type.BOOLEAN); // on ground
wrapper.write(Type.BYTE, (byte) 0); // flags
wrapper.write(Type.VAR_INT, -1); // teleport id
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.ENTITY_ANIMATION, new PacketHandlers() {
@Override
public void register() {
@@ -208,7 +233,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
}
meta.setMetaType(Types1_19_4.META_TYPES.byId(id));
});
registerMetaTypeHandler(Types1_19_4.META_TYPES.itemType, Types1_19_4.META_TYPES.blockStateType, Types1_19_4.META_TYPES.particleType);
registerMetaTypeHandler(Types1_19_4.META_TYPES.itemType, Types1_19_4.META_TYPES.blockStateType, Types1_19_4.META_TYPES.optionalBlockStateType, Types1_19_4.META_TYPES.particleType);
filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value();
@@ -40,10 +40,34 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_19_
blockRewriter.registerBlockAction(ClientboundPackets1_19_3.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_19_3.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange(ClientboundPackets1_19_3.MULTI_BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_19_3.EFFECT, 1010, 2001);
blockRewriter.registerChunkData1_19(ClientboundPackets1_19_3.CHUNK_DATA, Chunk1_18Type::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_19_3.BLOCK_ENTITY_DATA);
protocol.registerClientbound(ClientboundPackets1_19_3.EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // Effect Id
map(Type.POSITION1_14); // Location
map(Type.INT); // Data
handler(wrapper -> {
int id = wrapper.get(Type.INT, 0);
int data = wrapper.get(Type.INT, 1);
if (id == 1010) { // Play record
if (data >= 1092 && data <= 1106) {
// These IDs are valid records
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewItemId(data));
} else {
// Send stop record instead
wrapper.set(Type.INT, 0, 1011);
wrapper.set(Type.INT, 1, 0);
}
} else if (id == 2001) { // Block break + block break sound
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewBlockStateId(data));
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.OPEN_WINDOW, new PacketHandlers() {
@Override
public void register() {
@@ -64,6 +64,14 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
return element == null || element.isJsonNull() || (element.isJsonArray() && element.getAsJsonArray().size() == 0);
}
public static JsonElement mapTextComponentIfNull(JsonElement component) {
if (!isTextComponentNull(component)) {
return component;
} else {
return ChatRewriter.emptyComponent();
}
}
@Override
protected void registerPackets() {
final TagRewriter<ClientboundPackets1_18> tagRewriter = new TagRewriter<>(this);
@@ -118,16 +126,32 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
new StatisticsRewriter<>(this).register(ClientboundPackets1_18.STATISTICS);
final PacketHandler titleHandler = wrapper -> {
final JsonElement component = wrapper.read(Type.COMPONENT);
if (!isTextComponentNull(component)) {
wrapper.write(Type.COMPONENT, component);
} else {
wrapper.write(Type.COMPONENT, ChatRewriter.emptyComponent());
}
final PacketHandler singleNullTextComponentMapper = wrapper -> {
wrapper.write(Type.COMPONENT, mapTextComponentIfNull(wrapper.read(Type.COMPONENT)));
};
registerClientbound(ClientboundPackets1_18.TITLE_TEXT, titleHandler);
registerClientbound(ClientboundPackets1_18.TITLE_SUBTITLE, titleHandler);
registerClientbound(ClientboundPackets1_18.TITLE_TEXT, singleNullTextComponentMapper);
registerClientbound(ClientboundPackets1_18.TITLE_SUBTITLE, singleNullTextComponentMapper);
registerClientbound(ClientboundPackets1_18.ACTIONBAR, singleNullTextComponentMapper);
registerClientbound(ClientboundPackets1_18.SCOREBOARD_OBJECTIVE, wrapper -> {
wrapper.passthrough(Type.STRING); // Objective Name
byte action = wrapper.passthrough(Type.BYTE); // Mode
if (action == 0 || action == 2) {
wrapper.write(Type.COMPONENT, mapTextComponentIfNull(wrapper.read(Type.COMPONENT))); // Display Name
}
});
registerClientbound(ClientboundPackets1_18.TEAMS, wrapper -> {
wrapper.passthrough(Type.STRING); // Team Name
byte action = wrapper.passthrough(Type.BYTE); // Mode
if (action == 0 || action == 2) {
wrapper.write(Type.COMPONENT, mapTextComponentIfNull(wrapper.read(Type.COMPONENT))); // Display Name
wrapper.passthrough(Type.BYTE); // Flags
wrapper.passthrough(Type.STRING); // Name Tag Visibility
wrapper.passthrough(Type.STRING); // Collision rule
wrapper.passthrough(Type.VAR_INT); // Color
wrapper.write(Type.COMPONENT, mapTextComponentIfNull(wrapper.read(Type.COMPONENT))); // Prefix
wrapper.write(Type.COMPONENT, mapTextComponentIfNull(wrapper.read(Type.COMPONENT))); // Suffix
}
});
final CommandRewriter<ClientboundPackets1_18> commandRewriter = new CommandRewriter<>(this);
registerClientbound(ClientboundPackets1_18.DECLARE_COMMANDS, wrapper -> {
@@ -275,7 +299,7 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Entity1_19Types.initialize(this);
@@ -40,8 +40,7 @@ public final class MappingData extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag daata) {
try {
// TODO Read uncompressed file
final ListTag chatTypes = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("chat-types-1.19.nbt")).get("values");
final ListTag chatTypes = BinaryTagIO.readInputStream(MappingDataLoader.getResource("chat-types-1.19.nbt")).get("values");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");
Loaded 100 of 165 files, more files were not shown because too many files have changed in this diff. Show more