Compare commits

...
126 Commits
Author SHA1 Message Date
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
157 changed files with 4328 additions and 1085 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.fandom.com/wiki/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;
}
/**
@@ -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) {
@@ -96,6 +97,19 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
registerPackets();
// Register handlers for protocol state switching
// TODO Only register one of those handlers, possibly somehow in the base protocol
final SU configurationAcknowledgedPacket = configurationAcknowledgedPacket();
if (configurationAcknowledgedPacket != null) {
registerServerbound(configurationAcknowledgedPacket, wrapper -> wrapper.user().getProtocolInfo().setState(State.CONFIGURATION));
}
final ServerboundPacketType finishConfigurationPacket = finishConfigurationPacket();
if (finishConfigurationPacket != null) {
final int id = finishConfigurationPacket.getId();
registerServerbound(State.CONFIGURATION, id, id, wrapper -> wrapper.user().getProtocolInfo().setState(State.PLAY));
}
// Register the rest of the ids with no handlers if necessary
if (unmappedClientboundPacketType != null && mappedClientboundPacketType != null
&& unmappedClientboundPacketType != mappedClientboundPacketType) {
@@ -208,6 +222,17 @@ 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 ServerboundPacketType finishConfigurationPacket() {
// To be overridden
return null;
}
// ---------------------------------------------------------------------------------
@Override
@@ -361,7 +386,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);
@@ -27,5 +27,6 @@ public enum State {
HANDSHAKE,
STATUS,
LOGIN,
PLAY
PLAY,
CONFIGURATION
}
@@ -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,15 @@
*/
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 org.checkerframework.checker.nullness.qual.Nullable;
import java.io.IOException;
public class NBTType extends Type<CompoundTag> {
@@ -43,23 +43,50 @@ 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));
}
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);
write(buffer, object, "");
}
public static CompoundTag read(final ByteBuf buffer, final boolean readName) throws Exception {
final int readerIndex = buffer.readerIndex();
final byte b = buffer.readByte();
if (b == 0) {
return null;
}
buffer.readerIndex(readerIndex);
final ByteBufInputStream in = new ByteBufInputStream(buffer);
final int id = in.readByte();
if (id != CompoundTag.ID) {
throw new IOException(String.format("Expected root tag to be a CompoundTag, was %s", id));
}
if (readName) {
in.skipBytes(in.readUnsignedShort());
}
final TagLimiter tagLimiter = TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL);
final CompoundTag tag = new CompoundTag();
tag.read(in, 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", "branch")
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);
}
@@ -62,9 +62,6 @@ 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()) {
@@ -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
@@ -94,12 +94,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 +129,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();
}
@@ -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
@@ -266,20 +266,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);
}
}
});
}
/**
@@ -434,7 +451,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 +483,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 {
@@ -33,10 +33,12 @@ import com.viaversion.viaversion.api.protocol.version.VersionProvider;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocol.ProtocolManagerImpl;
import com.viaversion.viaversion.protocol.ServerProtocolVersionSingleton;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.util.ChatColorUtil;
import com.viaversion.viaversion.util.GsonUtil;
import io.netty.channel.ChannelFuture;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
@@ -45,9 +47,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 +121,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()) {
info.setState(State.PLAY);
}
UUID uuid = passthroughLoginUUID(wrapper);
info.setUuid(uuid);
@@ -147,7 +148,6 @@ public class BaseProtocol1_7 extends AbstractProtocol {
}
});
/* Incoming Packets */
// Login Start Packet
registerServerbound(ServerboundLoginPackets.HELLO, wrapper -> {
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
@@ -164,6 +164,8 @@ public class BaseProtocol1_7 extends AbstractProtocol {
future.addListener(f -> wrapper.user().getChannel().close());
}
});
registerServerbound(ServerboundLoginPackets.LOGIN_ACKNOWLEDGED, wrapper -> wrapper.user().getProtocolInfo().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");
@@ -24,15 +24,18 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
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.Particle;
import com.viaversion.viaversion.api.type.types.version.Types1_18;
import com.viaversion.viaversion.api.type.types.version.Types1_19;
import com.viaversion.viaversion.data.entity.DimensionDataImpl;
@@ -41,6 +44,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.DimensionRegistryStorage;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import java.io.IOException;
import java.util.ArrayList;
@@ -353,9 +357,29 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_18,
@Override
protected void registerRewrites() {
filter().handler((event, meta) -> meta.setMetaType(Types1_19.META_TYPES.byId(meta.metaType().typeId())));
filter().handler((event, meta) -> {
meta.setMetaType(Types1_19.META_TYPES.byId(meta.metaType().typeId()));
registerMetaTypeHandler(Types1_19.META_TYPES.itemType, Types1_19.META_TYPES.blockStateType, Types1_19.META_TYPES.particleType);
final MetaType type = meta.metaType();
if (type == Types1_19.META_TYPES.particleType) {
final Particle particle = (Particle) meta.getValue();
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (particle.getId() == particleMappings.id("vibration")) {
// Remove the position
particle.getArguments().remove(0);
final String resourceLocation = Key.stripMinecraftNamespace(particle.getArguments().get(0).get());
if (resourceLocation.equals("entity")) {
// Add Y offset
particle.getArguments().add(2, new Particle.ParticleData(Type.FLOAT, 0F));
}
}
rewriteParticle(particle);
}
});
registerMetaTypeHandler(Types1_19.META_TYPES.itemType, Types1_19.META_TYPES.blockStateType, null, null);
filter().filterFamily(Entity1_19Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
// Convert to new block id
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
@@ -27,6 +28,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPacke
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider.AckSequenceProvider;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.util.Key;
public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_18, ServerboundPackets1_19, Protocol1_19To1_18_2> {
@@ -54,7 +56,20 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_18,
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(getSpawnParticleHandler(Type.VAR_INT, Type.FLAT_VAR_INT_ITEM));
handler(wrapper -> {
final int id = wrapper.get(Type.VAR_INT, 0);
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (id == particleMappings.id("vibration")) {
wrapper.read(Type.POSITION1_14); // Remove position
final String resourceLocation = Key.stripMinecraftNamespace(wrapper.passthrough(Type.STRING));
if (resourceLocation.equals("entity")) {
wrapper.passthrough(Type.VAR_INT); // Target entity
wrapper.write(Type.FLOAT, 0F); // Y offset
}
}
});
handler(getSpawnParticleHandler(Type.VAR_INT));
}
});
@@ -0,0 +1,290 @@
/*
* 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_20_2to1_20;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ServerboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.BlockItemPacketRewriter1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.EntityPacketRewriter1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState.BridgePhase;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.LastResourcePack;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPackets1_19_4, ClientboundPackets1_20_2, ServerboundPackets1_19_4, ServerboundPackets1_20_2> {
public static final MappingData MAPPINGS = new MappingDataBase("1.20", "1.20.2");
private final EntityPacketRewriter1_20_2 entityPacketRewriter = new EntityPacketRewriter1_20_2(this);
private final BlockItemPacketRewriter1_20_2 itemPacketRewriter = new BlockItemPacketRewriter1_20_2(this);
public Protocol1_20_2To1_20() {
super(ClientboundPackets1_19_4.class, ClientboundPackets1_20_2.class, ServerboundPackets1_19_4.class, ServerboundPackets1_20_2.class);
}
@Override
protected void registerPackets() {
// Close your eyes and turn around while you still can
super.registerPackets();
final SoundRewriter<ClientboundPackets1_19_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.SOUND);
soundRewriter.registerEntitySound(ClientboundPackets1_19_4.ENTITY_SOUND);
registerClientbound(ClientboundPackets1_19_4.RESOURCE_PACK, wrapper -> {
final String url = wrapper.passthrough(Type.STRING);
final String hash = wrapper.passthrough(Type.STRING);
final boolean required = wrapper.passthrough(Type.BOOLEAN);
final JsonElement prompt = wrapper.passthrough(Type.OPTIONAL_COMPONENT);
wrapper.user().put(new LastResourcePack(url, hash, required, prompt));
});
registerClientbound(ClientboundPackets1_19_4.DISPLAY_SCOREBOARD, wrapper -> {
final byte slot = wrapper.read(Type.BYTE);
wrapper.write(Type.VAR_INT, (int) slot);
});
registerServerbound(State.LOGIN, ServerboundLoginPackets.HELLO.getId(), ServerboundLoginPackets.HELLO.getId(), wrapper -> {
wrapper.passthrough(Type.STRING); // Name
final UUID uuid = wrapper.read(Type.UUID);
wrapper.write(Type.OPTIONAL_UUID, uuid);
});
// Deal with the new CONFIGURATION protocol state the client expects
// After the game profile is received by the client, it will send its login ack,
// switch to the configuration protocol state and send its brand.
// We need to wait for it send the login ack before actually sending the play login,
// hence packets are added to a queue. With the data from the login packet, we sent what is needed
// during the configuration phase before finally transitioning to the play state with the client as well.
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), wrapper -> {
wrapper.user().get(ConfigurationState.class).setBridgePhase(BridgePhase.PROFILE_SENT);
// Set the state according to what the server expects. All packets between now and when the client
// switches to PLAY as well will be discarded after being dealt with.
wrapper.user().getProtocolInfo().setState(State.PLAY);
});
registerServerbound(State.LOGIN, ServerboundLoginPackets.LOGIN_ACKNOWLEDGED.getId(), -1, wrapper -> {
wrapper.cancel();
final ConfigurationState configurationState = wrapper.user().get(ConfigurationState.class);
configurationState.setBridgePhase(BridgePhase.CONFIGURATION);
configurationState.sendQueuedPackets(wrapper.user());
});
cancelServerbound(State.LOGIN, ServerboundLoginPackets.CUSTOM_QUERY_ANSWER.getId());
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION.getId(), -1, wrapper -> {
wrapper.cancel();
final ConfigurationState configurationState = wrapper.user().get(ConfigurationState.class);
configurationState.setBridgePhase(BridgePhase.NONE);
configurationState.sendQueuedPackets(wrapper.user());
configurationState.clear();
});
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CLIENT_INFORMATION.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.CLIENT_SETTINGS));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PLUGIN_MESSAGE));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.KEEP_ALIVE));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PONG));
// Cancel this, as it will always just be the response to a re-sent pack from us
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), -1, PacketWrapper::cancel);
cancelClientbound(ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES); // TODO Sad emoji
registerServerbound(ServerboundPackets1_20_2.CONFIGURATION_ACKNOWLEDGED, null, wrapper -> {
wrapper.cancel();
final ConfigurationState configurationState = wrapper.user().get(ConfigurationState.class);
if (configurationState.bridgePhase() != BridgePhase.REENTERING_CONFIGURATION) {
return;
}
// Reenter the configuration state
configurationState.setBridgePhase(BridgePhase.CONFIGURATION);
final LastResourcePack lastResourcePack = wrapper.user().get(LastResourcePack.class);
sendConfigurationPackets(wrapper.user(), configurationState.lastDimensionRegistry(), lastResourcePack);
});
cancelServerbound(ServerboundPackets1_20_2.CHUNK_BATCH_RECEIVED);
registerServerbound(ServerboundPackets1_20_2.PING_REQUEST, null, wrapper -> {
wrapper.cancel();
final long time = wrapper.read(Type.LONG);
final PacketWrapper responsePacket = wrapper.create(ClientboundPackets1_20_2.PONG_RESPONSE);
responsePacket.write(Type.LONG, time);
responsePacket.sendFuture(Protocol1_20_2To1_20.class);
});
}
private PacketHandler queueServerboundPacket(final ServerboundPackets1_20_2 packetType) {
return wrapper -> {
wrapper.setPacketType(packetType);
wrapper.user().get(ConfigurationState.class).addPacketToQueue(wrapper, false);
wrapper.cancel();
};
}
@Override
public void transform(final Direction direction, final State state, final PacketWrapper packetWrapper) throws Exception {
final ConfigurationState configurationBridge = packetWrapper.user().get(ConfigurationState.class);
if (configurationBridge == null) {
// Bad state during an unexpected disconnect
return;
}
final BridgePhase phase = configurationBridge.bridgePhase();
if (phase == BridgePhase.NONE) {
super.transform(direction, state, packetWrapper);
return;
}
if (direction == Direction.SERVERBOUND) {
// Client and server will be on different protocol states, pick the right client protocol state
super.transform(direction, phase == BridgePhase.PROFILE_SENT ? State.LOGIN
: phase == BridgePhase.REENTERING_CONFIGURATION ? State.PLAY : State.CONFIGURATION, packetWrapper);
return;
}
if (phase == BridgePhase.PROFILE_SENT || phase == BridgePhase.REENTERING_CONFIGURATION) {
// Queue packets sent by the server while we wait for the client to transition to the configuration state
configurationBridge.addPacketToQueue(packetWrapper, true);
throw CancelException.generate();
}
if (packetWrapper.getPacketType() == null || packetWrapper.getPacketType().state() != State.CONFIGURATION) {
// Map some of them to their configuration state counterparts, but make sure to let join game through
final int unmappedId = packetWrapper.getId();
if (unmappedId == ClientboundPackets1_19_4.JOIN_GAME.getId()) {
super.transform(direction, state, packetWrapper);
return;
}
if (configurationBridge.queuedOrSentJoinGame()) {
if (!packetWrapper.user().isClientSide() && !Via.getPlatform().isProxy() && unmappedId == ClientboundPackets1_19_4.SYSTEM_CHAT.getId()) {
// Cancelling this on the Vanilla server will cause it to exceptionally resend a message
// Assume that we have already sent the login packet and just let it through
super.transform(direction, State.PLAY, packetWrapper);
return;
}
configurationBridge.addPacketToQueue(packetWrapper, true);
throw CancelException.generate();
}
if (unmappedId == ClientboundPackets1_19_4.PLUGIN_MESSAGE.getId()) {
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD);
} else if (unmappedId == ClientboundPackets1_19_4.DISCONNECT.getId()) {
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.DISCONNECT);
} else if (unmappedId == ClientboundPackets1_19_4.KEEP_ALIVE.getId()) {
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.KEEP_ALIVE);
} else if (unmappedId == ClientboundPackets1_19_4.PING.getId()) {
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.PING);
} else if (unmappedId == ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES.getId()) {
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES);
} else if (unmappedId == ClientboundPackets1_19_4.TAGS.getId()) {
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_TAGS);
} else {
// Not a packet that can be mapped to the configuration protocol
// Includes resource pack packets to make sure it is not applied sooner than the server expects
configurationBridge.addPacketToQueue(packetWrapper, true);
throw CancelException.generate();
}
return;
}
// Redirect packets during the fake configuration phase
// This might mess up people using Via API/other protocols down the line, but such is life. We can't have different states for server and client
super.transform(direction, State.CONFIGURATION, packetWrapper);
}
public static void sendConfigurationPackets(final UserConnection connection, final CompoundTag dimensionRegistry, @Nullable final LastResourcePack lastResourcePack) throws Exception {
final PacketWrapper registryDataPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.REGISTRY_DATA, connection);
registryDataPacket.write(Type.NAMELESS_NBT, dimensionRegistry);
registryDataPacket.send(Protocol1_20_2To1_20.class);
// Enabling features is only possible during the configuration phase
// TODO Sad emoji
final PacketWrapper enableFeaturesPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES, connection);
enableFeaturesPacket.write(Type.VAR_INT, 1);
enableFeaturesPacket.write(Type.STRING, "minecraft:vanilla");
enableFeaturesPacket.send(Protocol1_20_2To1_20.class);
if (lastResourcePack != null) {
// The client for some reason drops the resource pack when reentering the configuration state
final PacketWrapper resourcePackPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.RESOURCE_PACK, connection);
resourcePackPacket.write(Type.STRING, lastResourcePack.url());
resourcePackPacket.write(Type.STRING, lastResourcePack.hash());
resourcePackPacket.write(Type.BOOLEAN, lastResourcePack.required());
resourcePackPacket.write(Type.OPTIONAL_COMPONENT, lastResourcePack.prompt());
resourcePackPacket.send(Protocol1_20_2To1_20.class);
}
final PacketWrapper finishConfigurationPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION, connection);
finishConfigurationPacket.send(Protocol1_20_2To1_20.class);
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
@Override
protected @Nullable ServerboundPackets1_20_2 configurationAcknowledgedPacket() {
return null; // Don't handle it in the transitioning protocol
}
@Override
public void init(final UserConnection user) {
user.put(new ConfigurationState());
addEntityTracker(user, new EntityTrackerBase(user, Entity1_19_4Types.PLAYER));
}
@Override
public EntityRewriter<Protocol1_20_2To1_20> getEntityRewriter() {
return entityPacketRewriter;
}
@Override
public ItemRewriter<Protocol1_20_2To1_20> getItemRewriter() {
return itemPacketRewriter;
}
}
@@ -0,0 +1,49 @@
/*
* 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_20_2to1_20.packet;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.State;
public enum ClientboundConfigurationPackets1_20_2 implements ClientboundPacketType {
CUSTOM_PAYLOAD, // 0x00
DISCONNECT, // 0x01
FINISH_CONFIGURATION, // 0x02
KEEP_ALIVE, // 0x03
PING, // 0x04
REGISTRY_DATA, // 0x05
RESOURCE_PACK, // 0x06
UPDATE_ENABLED_FEATURES, // 0x07
UPDATE_TAGS; // 0x08
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
@Override
public State state() {
return State.CONFIGURATION;
}
}
@@ -0,0 +1,147 @@
/*
* 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_20_2to1_20.packet;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_20_2 implements ClientboundPacketType {
BUNDLE, // 0x00
SPAWN_ENTITY, // 0x01
SPAWN_EXPERIENCE_ORB, // 0x02
ENTITY_ANIMATION, // 0x03
STATISTICS, // 0x04
BLOCK_CHANGED_ACK, // 0x05
BLOCK_BREAK_ANIMATION, // 0x06
BLOCK_ENTITY_DATA, // 0x07
BLOCK_ACTION, // 0x08
BLOCK_CHANGE, // 0x09
BOSSBAR, // 0x0A
SERVER_DIFFICULTY, // 0x0B
CHUNK_BATCH_FINISHED, // 0x0C
CHUNK_BATCH_START, // 0x0D
CHUNK_BIOMES, // 0x0E
CLEAR_TITLES, // 0x0F
TAB_COMPLETE, // 0x10
DECLARE_COMMANDS, // 0x11
CLOSE_WINDOW, // 0x12
WINDOW_ITEMS, // 0x13
WINDOW_PROPERTY, // 0x14
SET_SLOT, // 0x15
COOLDOWN, // 0x16
CUSTOM_CHAT_COMPLETIONS, // 0x17
PLUGIN_MESSAGE, // 0x18
DAMAGE_EVENT, // 0x19
DELETE_CHAT_MESSAGE, // 0x1A
DISCONNECT, // 0x1B
DISGUISED_CHAT, // 0x1C
ENTITY_STATUS, // 0x1D
EXPLOSION, // 0x1E
UNLOAD_CHUNK, // 0x1F
GAME_EVENT, // 0x20
OPEN_HORSE_WINDOW, // 0x21
HIT_ANIMATION, // 0x22
WORLD_BORDER_INIT, // 0x23
KEEP_ALIVE, // 0x24
CHUNK_DATA, // 0x25
EFFECT, // 0x26
SPAWN_PARTICLE, // 0x27
UPDATE_LIGHT, // 0x28
JOIN_GAME, // 0x29
MAP_DATA, // 0x2A
TRADE_LIST, // 0x2B
ENTITY_POSITION, // 0x2C
ENTITY_POSITION_AND_ROTATION, // 0x2D
ENTITY_ROTATION, // 0x2E
VEHICLE_MOVE, // 0x2F
OPEN_BOOK, // 0x30
OPEN_WINDOW, // 0x31
OPEN_SIGN_EDITOR, // 0x32
PING, // 0x33
PONG_RESPONSE, // 0x34
CRAFT_RECIPE_RESPONSE, // 0x35
PLAYER_ABILITIES, // 0x36
PLAYER_CHAT, // 0x37
COMBAT_END, // 0x38
COMBAT_ENTER, // 0x39
COMBAT_KILL, // 0x3A
PLAYER_INFO_REMOVE, // 0x3B
PLAYER_INFO_UPDATE, // 0x3C
FACE_PLAYER, // 0x3D
PLAYER_POSITION, // 0x3E
UNLOCK_RECIPES, // 0x3F
REMOVE_ENTITIES, // 0x40
REMOVE_ENTITY_EFFECT, // 0x41
RESOURCE_PACK, // 0x42
RESPAWN, // 0x43
ENTITY_HEAD_LOOK, // 0x44
MULTI_BLOCK_CHANGE, // 0x45
SELECT_ADVANCEMENTS_TAB, // 0x46
SERVER_DATA, // 0x47
ACTIONBAR, // 0x48
WORLD_BORDER_CENTER, // 0x49
WORLD_BORDER_LERP_SIZE, // 0x4A
WORLD_BORDER_SIZE, // 0x4B
WORLD_BORDER_WARNING_DELAY, // 0x4C
WORLD_BORDER_WARNING_DISTANCE, // 0x4D
CAMERA, // 0x4E
HELD_ITEM_CHANGE, // 0x4F
UPDATE_VIEW_POSITION, // 0x50
UPDATE_VIEW_DISTANCE, // 0x51
SPAWN_POSITION, // 0x52
DISPLAY_SCOREBOARD, // 0x53
ENTITY_METADATA, // 0x54
ATTACH_ENTITY, // 0x55
ENTITY_VELOCITY, // 0x56
ENTITY_EQUIPMENT, // 0x57
SET_EXPERIENCE, // 0x58
UPDATE_HEALTH, // 0x59
SCOREBOARD_OBJECTIVE, // 0x5A
SET_PASSENGERS, // 0x5B
TEAMS, // 0x5C
UPDATE_SCORE, // 0x5D
SET_SIMULATION_DISTANCE, // 0x5E
TITLE_SUBTITLE, // 0x5F
TIME_UPDATE, // 0x60
TITLE_TEXT, // 0x61
TITLE_TIMES, // 0x62
ENTITY_SOUND, // 0x63
SOUND, // 0x64
START_CONFIGURATION, // 0x65
STOP_SOUND, // 0x66
SYSTEM_CHAT, // 0x67
TAB_LIST, // 0x68
NBT_QUERY, // 0x69
COLLECT_ITEM, // 0x6A
ENTITY_TELEPORT, // 0x6B
ADVANCEMENTS, // 0x6C
ENTITY_PROPERTIES, // 0x6D
ENTITY_EFFECT, // 0x6E
DECLARE_RECIPES, // 0x6F
TAGS; // 0x70
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
Loaded 100 of 157 files, more files were not shown because too many files have changed in this diff. Show more