Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
489b28e520 | ||
|
|
d23e743550 | ||
|
|
16f89f2638 | ||
|
|
fe5646a68c | ||
|
|
53aca791dd | ||
|
|
1f0a4c26db | ||
|
|
4c34ced240 | ||
|
|
18c4f90cb0 | ||
|
|
9c90445c9c | ||
|
|
494e6ffc05 | ||
|
|
a196dbc16b | ||
|
|
8934bbdfc3 | ||
|
|
8316c59010 | ||
|
|
5ea1c1ec95 | ||
|
|
cc7c571a3c | ||
|
|
06b4678b2d | ||
|
|
a109118a97 | ||
|
|
a135a1414c | ||
|
|
f50751ed48 | ||
|
|
4b7998b4ea | ||
|
|
6db1a2a614 | ||
|
|
625373827c | ||
|
|
a9288ebd3a | ||
|
|
01bbb2c1c2 | ||
|
|
8dbc8e8eba | ||
|
|
0c9f3aa080 | ||
|
|
00625be890 | ||
|
|
e112f81ec8 | ||
|
|
23f776a6ee | ||
|
|
0050872950 | ||
|
|
7e53f55509 | ||
|
|
1bf7962dc3 | ||
|
|
50176dc317 | ||
|
|
9ed074d0d5 | ||
|
|
8bad8a10be | ||
|
|
34509e86c0 | ||
|
|
ef75bd567d | ||
|
|
7ed3e50e93 | ||
|
|
a45eceaf1d | ||
|
|
573cdfb3ac | ||
|
|
28787340d1 | ||
|
|
c358245c0b | ||
|
|
cb073405b7 | ||
|
|
f618f6a7d6 | ||
|
|
c5e066e050 | ||
|
|
d954e1745d | ||
|
|
9c92ccea77 | ||
|
|
2b9e0cec5c | ||
|
|
c1cd8bc03e | ||
|
|
39efc5262e | ||
|
|
6e5e115c3b | ||
|
|
fbcbd33c66 | ||
|
|
7bea3142bc | ||
|
|
fb472c3454 | ||
|
|
ac10bb3fd0 | ||
|
|
1bc3d407d1 | ||
|
|
62c0ef360f | ||
|
|
8c6d104faa | ||
|
|
f6b8c4a8c8 | ||
|
|
6586fc1436 | ||
|
|
6dfd4747ee | ||
|
|
6377721ebd | ||
|
|
2ec6185c46 | ||
|
|
b22907748a | ||
|
|
1aee8a7a6c | ||
|
|
7edb43844c | ||
|
|
f28aac5eb3 | ||
|
|
4971eeab6a | ||
|
|
0bb940e42d | ||
|
|
e32933ada9 | ||
|
|
a817746edc | ||
|
|
408392e796 | ||
|
|
20a4ae3e4b | ||
|
|
08b2d78165 | ||
|
|
17eb7b676a | ||
|
|
9a1598b9ed | ||
|
|
9e7cd151bc | ||
|
|
2a14f9a0cd | ||
|
|
bf825d5ef6 | ||
|
|
28ba4afc27 | ||
|
|
7f347231bb |
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -1,61 +1,49 @@
|
||||
# ViaVersion - Spigot, Sponge, BungeeCord, Velocity
|
||||
# ViaVersion
|
||||
|
||||
[](https://viaversion.com)
|
||||
[](https://github.com/ViaVersion/ViaVersion/actions)
|
||||
[](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:
|
||||
|
||||

|
||||
|
||||
On Paper you may also use ProtocolSupport, but ensure you have the right build for your server version.
|
||||

|
||||
|
||||
**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>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
```
|
||||
|
||||
**API-artifact:**
|
||||
|
||||
```xml
|
||||
|
||||
<dependency>
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>viaversion-api</artifactId>
|
||||
@@ -64,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).
|
||||
@@ -73,8 +71,7 @@ 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.
|
||||
of the `build/libs` directory.
|
||||
|
||||
|
||||
Mapping Files
|
||||
@@ -82,13 +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
|
||||
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,10 +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");
|
||||
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
@@ -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 {
|
||||
|
||||
+10
-1
@@ -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() {
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+5
@@ -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);
|
||||
|
||||
+86
-10
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+64
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+3
-1
@@ -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;
|
||||
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -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;
|
||||
|
||||
|
||||
+2
-1
@@ -83,7 +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");
|
||||
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;
|
||||
|
||||
+45
@@ -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());
|
||||
}
|
||||
}
|
||||
+60
@@ -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);
|
||||
}
|
||||
}
|
||||
+44
@@ -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);
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -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> {
|
||||
|
||||
+53
@@ -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,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);
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -103,6 +103,12 @@ 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 RegionizedServerInitEvent to run code after the server has loaded
|
||||
final Class<? extends Event> serverInitEventClass;
|
||||
|
||||
+6
-2
@@ -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");
|
||||
|
||||
|
||||
+4
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-7
@@ -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());
|
||||
}
|
||||
|
||||
-53
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
+8
-140
@@ -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,18 +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_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_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_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;
|
||||
@@ -102,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();
|
||||
@@ -140,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);
|
||||
@@ -183,6 +181,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-1
@@ -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() {
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+17
-4
@@ -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);
|
||||
}
|
||||
|
||||
+14
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
+30
-2
@@ -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) {
|
||||
|
||||
+29
-5
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -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
|
||||
}
|
||||
|
||||
+33
-9
@@ -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 -> {
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_18,
|
||||
}
|
||||
}
|
||||
});
|
||||
handler(getSpawnParticleHandler(Type.VAR_INT, Type.FLAT_VAR_INT_ITEM));
|
||||
handler(getSpawnParticleHandler(Type.VAR_INT));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+290
@@ -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;
|
||||
}
|
||||
}
|
||||
+49
@@ -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;
|
||||
}
|
||||
}
|
||||
+147
@@ -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();
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
|
||||
public enum ServerboundConfigurationPackets1_20_2 implements ServerboundPacketType {
|
||||
|
||||
CLIENT_INFORMATION, // 0x00
|
||||
CUSTOM_PAYLOAD, // 0x01
|
||||
FINISH_CONFIGURATION, // 0x02
|
||||
KEEP_ALIVE, // 0x03
|
||||
PONG, // 0x04
|
||||
RESOURCE_PACK; // 0x05
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public State state() {
|
||||
return State.CONFIGURATION;
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.ServerboundPacketType;
|
||||
|
||||
public enum ServerboundPackets1_20_2 implements ServerboundPacketType {
|
||||
|
||||
TELEPORT_CONFIRM, // 0x00
|
||||
QUERY_BLOCK_NBT, // 0x01
|
||||
SET_DIFFICULTY, // 0x02
|
||||
CHAT_ACK, // 0x03
|
||||
CHAT_COMMAND, // 0x04
|
||||
CHAT_MESSAGE, // 0x05
|
||||
CHAT_SESSION_UPDATE, // 0x06
|
||||
CHUNK_BATCH_RECEIVED, // 0x07
|
||||
CLIENT_STATUS, // 0x08
|
||||
CLIENT_SETTINGS, // 0x09
|
||||
TAB_COMPLETE, // 0x0A
|
||||
CONFIGURATION_ACKNOWLEDGED, // 0x0B
|
||||
CLICK_WINDOW_BUTTON, // 0x0C
|
||||
CLICK_WINDOW, // 0x0D
|
||||
CLOSE_WINDOW, // 0x0E
|
||||
PLUGIN_MESSAGE, // 0x0F
|
||||
EDIT_BOOK, // 0x10
|
||||
ENTITY_NBT_REQUEST, // 0x11
|
||||
INTERACT_ENTITY, // 0x12
|
||||
GENERATE_JIGSAW, // 0x13
|
||||
KEEP_ALIVE, // 0x14
|
||||
LOCK_DIFFICULTY, // 0x15
|
||||
PLAYER_POSITION, // 0x16
|
||||
PLAYER_POSITION_AND_ROTATION, // 0x17
|
||||
PLAYER_ROTATION, // 0x18
|
||||
PLAYER_MOVEMENT, // 0x19
|
||||
VEHICLE_MOVE, // 0x1A
|
||||
STEER_BOAT, // 0x1B
|
||||
PICK_ITEM, // 0x1C
|
||||
PING_REQUEST, // 0x1D
|
||||
CRAFT_RECIPE_REQUEST, // 0x1E
|
||||
PLAYER_ABILITIES, // 0x1F
|
||||
PLAYER_DIGGING, // 0x20
|
||||
ENTITY_ACTION, // 0x21
|
||||
STEER_VEHICLE, // 0x22
|
||||
PONG, // 0x23
|
||||
RECIPE_BOOK_DATA, // 0x24
|
||||
SEEN_RECIPE, // 0x25
|
||||
RENAME_ITEM, // 0x26
|
||||
RESOURCE_PACK_STATUS, // 0x27
|
||||
ADVANCEMENT_TAB, // 0x28
|
||||
SELECT_TRADE, // 0x29
|
||||
SET_BEACON_EFFECT, // 0x2A
|
||||
HELD_ITEM_CHANGE, // 0x2B
|
||||
UPDATE_COMMAND_BLOCK, // 0x2C
|
||||
UPDATE_COMMAND_BLOCK_MINECART, // 0x2D
|
||||
CREATIVE_INVENTORY_ACTION, // 0x2E
|
||||
UPDATE_JIGSAW_BLOCK, // 0x2F
|
||||
UPDATE_STRUCTURE_BLOCK, // 0x30
|
||||
UPDATE_SIGN, // 0x31
|
||||
ANIMATION, // 0x32
|
||||
SPECTATE, // 0x33
|
||||
PLAYER_BLOCK_PLACEMENT, // 0x34
|
||||
USE_ITEM; // 0x35
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
+393
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* 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.rewriter;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.viaversion.viaversion.api.data.ParticleMappings;
|
||||
import com.viaversion.viaversion.api.data.entity.EntityTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.metadata.ChunkPosition;
|
||||
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.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.type.ChunkType1_20_2;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.MathUtil;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_20_2, Protocol1_20_2To1_20> {
|
||||
|
||||
public static final String[] POTION_EFFECTS = {
|
||||
"", // No effect
|
||||
"speed",
|
||||
"slowness",
|
||||
"haste",
|
||||
"mining_fatigue",
|
||||
"strength",
|
||||
"instant_health",
|
||||
"instant_damage",
|
||||
"jump_boost",
|
||||
"nausea",
|
||||
"regeneration",
|
||||
"resistance",
|
||||
"fire_resistance",
|
||||
"water_breathing",
|
||||
"invisibility",
|
||||
"blindness",
|
||||
"night_vision",
|
||||
"hunger",
|
||||
"weakness",
|
||||
"poison",
|
||||
"wither",
|
||||
"health_boost",
|
||||
"absorption",
|
||||
"saturation",
|
||||
"glowing",
|
||||
"levitation",
|
||||
"luck",
|
||||
"unluck",
|
||||
"slow_falling",
|
||||
"conduit_power",
|
||||
"dolphins_grace",
|
||||
"bad_omen",
|
||||
"hero_of_the_village",
|
||||
"darkness"
|
||||
};
|
||||
|
||||
public BlockItemPacketRewriter1_20_2(final Protocol1_20_2To1_20 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
final BlockRewriter<ClientboundPackets1_19_4> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
|
||||
blockRewriter.registerBlockAction(ClientboundPackets1_19_4.BLOCK_ACTION);
|
||||
blockRewriter.registerBlockChange(ClientboundPackets1_19_4.BLOCK_CHANGE);
|
||||
blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_19_4.MULTI_BLOCK_CHANGE);
|
||||
blockRewriter.registerEffect(ClientboundPackets1_19_4.EFFECT, 1010, 2001);
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_20_2.SET_BEACON_EFFECT, wrapper -> {
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) {
|
||||
// Effects start at 1 before 1.20.2
|
||||
wrapper.write(Type.VAR_INT, wrapper.read(Type.VAR_INT) + 1);
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.UNLOAD_CHUNK, wrapper -> {
|
||||
final int x = wrapper.read(Type.INT);
|
||||
final int z = wrapper.read(Type.INT);
|
||||
wrapper.write(Type.CHUNK_POSITION, new ChunkPosition(x, z));
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.NBT_QUERY, wrapper -> {
|
||||
wrapper.passthrough(Type.VAR_INT); // Transaction id
|
||||
wrapper.write(Type.NAMELESS_NBT, wrapper.read(Type.NBT));
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.BLOCK_ENTITY_DATA, wrapper -> {
|
||||
wrapper.passthrough(Type.POSITION1_14); // Position
|
||||
wrapper.passthrough(Type.VAR_INT); // Type
|
||||
wrapper.write(Type.NAMELESS_NBT, handleBlockEntity(wrapper.read(Type.NBT)));
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.CHUNK_DATA, wrapper -> {
|
||||
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
|
||||
final Type<Chunk> chunkType = new Chunk1_18Type(tracker.currentWorldSectionHeight(),
|
||||
MathUtil.ceilLog2(protocol.getMappingData().getBlockStateMappings().size()),
|
||||
MathUtil.ceilLog2(tracker.biomesSent()));
|
||||
final Chunk chunk = wrapper.read(chunkType);
|
||||
|
||||
final Type<Chunk> newChunkType = new ChunkType1_20_2(tracker.currentWorldSectionHeight(),
|
||||
MathUtil.ceilLog2(protocol.getMappingData().getBlockStateMappings().mappedSize()),
|
||||
MathUtil.ceilLog2(tracker.biomesSent()));
|
||||
wrapper.write(newChunkType, chunk);
|
||||
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
final DataPalette blockPalette = section.palette(PaletteType.BLOCKS);
|
||||
for (int i = 0; i < blockPalette.size(); i++) {
|
||||
final int id = blockPalette.idByIndex(i);
|
||||
blockPalette.setIdByIndex(i, protocol.getMappingData().getNewBlockStateId(id));
|
||||
}
|
||||
}
|
||||
|
||||
for (final BlockEntity blockEntity : chunk.blockEntities()) {
|
||||
handleBlockEntity(blockEntity.tag());
|
||||
}
|
||||
});
|
||||
|
||||
// Replace the NBT type everywhere
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.WINDOW_ITEMS, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.UNSIGNED_BYTE); // Window id
|
||||
map(Type.VAR_INT); // State id
|
||||
handler(wrapper -> {
|
||||
wrapper.write(Type.ITEM1_20_2_VAR_INT_ARRAY, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT)); // Items
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Carried item
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.SET_SLOT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.UNSIGNED_BYTE); // Window id
|
||||
map(Type.VAR_INT); // State id
|
||||
map(Type.SHORT); // Slot id
|
||||
map(Type.FLAT_VAR_INT_ITEM, Type.ITEM1_20_2); // Item
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.ADVANCEMENTS, wrapper -> {
|
||||
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
|
||||
final int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.passthrough(Type.STRING); // Identifier
|
||||
|
||||
// Parent
|
||||
if (wrapper.passthrough(Type.BOOLEAN))
|
||||
wrapper.passthrough(Type.STRING);
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) {
|
||||
wrapper.passthrough(Type.COMPONENT); // Title
|
||||
wrapper.passthrough(Type.COMPONENT); // Description
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Icon
|
||||
wrapper.passthrough(Type.VAR_INT); // Frame type
|
||||
final int flags = wrapper.passthrough(Type.INT); // Flags
|
||||
if ((flags & 1) != 0) {
|
||||
wrapper.passthrough(Type.STRING); // Background texture
|
||||
}
|
||||
wrapper.passthrough(Type.FLOAT); // X
|
||||
wrapper.passthrough(Type.FLOAT); // Y
|
||||
}
|
||||
|
||||
// Remove criterion triggers
|
||||
wrapper.read(Type.STRING_ARRAY); // Criteria
|
||||
|
||||
final int requirements = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int array = 0; array < requirements; array++) {
|
||||
wrapper.passthrough(Type.STRING_ARRAY);
|
||||
}
|
||||
|
||||
wrapper.passthrough(Type.BOOLEAN); // Send telemetry
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_EQUIPMENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.VAR_INT); // 0 - Entity ID
|
||||
handler(wrapper -> {
|
||||
byte slot;
|
||||
do {
|
||||
slot = wrapper.passthrough(Type.BYTE);
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM));
|
||||
} while ((slot & 0xFFFFFF80) != 0);
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_20_2.CLICK_WINDOW, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.UNSIGNED_BYTE); // Window Id
|
||||
map(Type.VAR_INT); // State id
|
||||
map(Type.SHORT); // Slot
|
||||
map(Type.BYTE); // Button
|
||||
map(Type.VAR_INT); // Mode
|
||||
|
||||
handler(wrapper -> {
|
||||
// Affected items
|
||||
final int length = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
wrapper.passthrough(Type.SHORT); // Slot
|
||||
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2));
|
||||
}
|
||||
|
||||
// Carried item
|
||||
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2));
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.TRADE_LIST, wrapper -> {
|
||||
wrapper.passthrough(Type.VAR_INT); // Container id
|
||||
final int size = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Input
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Output
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM)); // Second Item
|
||||
|
||||
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
|
||||
wrapper.passthrough(Type.INT); // Number of tools uses
|
||||
wrapper.passthrough(Type.INT); // Maximum number of trade uses
|
||||
|
||||
wrapper.passthrough(Type.INT); // XP
|
||||
wrapper.passthrough(Type.INT); // Special price
|
||||
wrapper.passthrough(Type.FLOAT); // Price multiplier
|
||||
wrapper.passthrough(Type.INT); // Demand
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_20_2.CREATIVE_INVENTORY_ACTION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.SHORT); // 0 - Slot
|
||||
map(Type.ITEM1_20_2, Type.FLAT_VAR_INT_ITEM); // 1 - Clicked Item
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.SPAWN_PARTICLE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.VAR_INT); // 0 - Particle ID
|
||||
map(Type.BOOLEAN); // 1 - Long Distance
|
||||
map(Type.DOUBLE); // 2 - X
|
||||
map(Type.DOUBLE); // 3 - Y
|
||||
map(Type.DOUBLE); // 4 - Z
|
||||
map(Type.FLOAT); // 5 - Offset X
|
||||
map(Type.FLOAT); // 6 - Offset Y
|
||||
map(Type.FLOAT); // 7 - Offset Z
|
||||
map(Type.FLOAT); // 8 - Particle Data
|
||||
map(Type.INT); // 9 - Particle Count
|
||||
handler(wrapper -> {
|
||||
final int id = wrapper.get(Type.VAR_INT, 0);
|
||||
final ParticleMappings mappings = Protocol1_20_2To1_20.MAPPINGS.getParticleMappings();
|
||||
if (mappings.isBlockParticle(id)) {
|
||||
final int data = wrapper.read(Type.VAR_INT);
|
||||
wrapper.write(Type.VAR_INT, protocol.getMappingData().getNewBlockStateId(data));
|
||||
} else if (mappings.isItemParticle(id)) {
|
||||
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
new RecipeRewriter1_19_4<ClientboundPackets1_19_4>(protocol) {
|
||||
@Override
|
||||
public void handleCraftingShapeless(final PacketWrapper wrapper) throws Exception {
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
wrapper.passthrough(Type.VAR_INT); // Crafting book category
|
||||
handleIngredients(wrapper);
|
||||
|
||||
final Item result = wrapper.read(itemType());
|
||||
rewrite(result);
|
||||
wrapper.write(Type.ITEM1_20_2, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSmelting(final PacketWrapper wrapper) throws Exception {
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
wrapper.passthrough(Type.VAR_INT); // Crafting book category
|
||||
handleIngredient(wrapper);
|
||||
|
||||
final Item result = wrapper.read(itemType());
|
||||
rewrite(result);
|
||||
wrapper.write(Type.ITEM1_20_2, result);
|
||||
|
||||
wrapper.passthrough(Type.FLOAT); // EXP
|
||||
wrapper.passthrough(Type.VAR_INT); // Cooking time
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCraftingShaped(final PacketWrapper wrapper) throws Exception {
|
||||
final int ingredients = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT);
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
wrapper.passthrough(Type.VAR_INT); // Crafting book category
|
||||
for (int i = 0; i < ingredients; i++) {
|
||||
handleIngredient(wrapper);
|
||||
}
|
||||
|
||||
final Item result = wrapper.read(itemType());
|
||||
rewrite(result);
|
||||
wrapper.write(Type.ITEM1_20_2, result);
|
||||
|
||||
wrapper.passthrough(Type.BOOLEAN); // Show notification
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStonecutting(final PacketWrapper wrapper) throws Exception {
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
handleIngredient(wrapper);
|
||||
|
||||
final Item result = wrapper.read(itemType());
|
||||
rewrite(result);
|
||||
wrapper.write(Type.ITEM1_20_2, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSmithing(final PacketWrapper wrapper) throws Exception {
|
||||
handleIngredient(wrapper); // Base
|
||||
handleIngredient(wrapper); // Addition
|
||||
|
||||
final Item result = wrapper.read(itemType());
|
||||
rewrite(result);
|
||||
wrapper.write(Type.ITEM1_20_2, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSmithingTransform(final PacketWrapper wrapper) throws Exception {
|
||||
handleIngredient(wrapper); // Template
|
||||
handleIngredient(wrapper); // Base
|
||||
handleIngredient(wrapper); // Additions
|
||||
|
||||
final Item result = wrapper.read(itemType());
|
||||
rewrite(result);
|
||||
wrapper.write(Type.ITEM1_20_2, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleIngredient(final PacketWrapper wrapper) throws Exception {
|
||||
final Item[] items = wrapper.read(itemArrayType());
|
||||
wrapper.write(Type.ITEM1_20_2_VAR_INT_ARRAY, items);
|
||||
for (final Item item : items) {
|
||||
rewrite(item);
|
||||
}
|
||||
}
|
||||
}.register(ClientboundPackets1_19_4.DECLARE_RECIPES);
|
||||
}
|
||||
|
||||
private @Nullable CompoundTag handleBlockEntity(@Nullable final CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final IntTag primaryEffect = tag.remove("Primary");
|
||||
if (primaryEffect != null && primaryEffect.asInt() != 0) {
|
||||
tag.put("primary_effect", new StringTag(effect(primaryEffect.asInt())));
|
||||
}
|
||||
|
||||
final IntTag secondaryEffect = tag.remove("Secondary");
|
||||
if (secondaryEffect != null && secondaryEffect.asInt() != 0) {
|
||||
tag.put("secondary_effect", new StringTag(effect(secondaryEffect.asInt())));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
private String effect(final int id) {
|
||||
return id >= 1 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.rewriter;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
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_20;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_2;
|
||||
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
|
||||
public final class EntityPacketRewriter1_20_2 extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_20_2To1_20> {
|
||||
|
||||
public EntityPacketRewriter1_20_2(final Protocol1_20_2To1_20 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
registerTrackerWithData1_19(ClientboundPackets1_19_4.SPAWN_ENTITY, Entity1_19_4Types.FALLING_BLOCK);
|
||||
registerMetadataRewriter(ClientboundPackets1_19_4.ENTITY_METADATA, Types1_20.METADATA_LIST, Types1_20_2.METADATA_LIST);
|
||||
registerRemoveEntities(ClientboundPackets1_19_4.REMOVE_ENTITIES);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.SPAWN_PLAYER, ClientboundPackets1_20_2.SPAWN_ENTITY, wrapper -> {
|
||||
wrapper.passthrough(Type.VAR_INT); // Entity id
|
||||
wrapper.passthrough(Type.UUID); // UUID
|
||||
|
||||
wrapper.write(Type.VAR_INT, Entity1_19_4Types.PLAYER.getId()); // Entity type id
|
||||
|
||||
wrapper.passthrough(Type.DOUBLE); // X
|
||||
wrapper.passthrough(Type.DOUBLE); // Y
|
||||
wrapper.passthrough(Type.DOUBLE); // Z
|
||||
|
||||
final byte yaw = wrapper.read(Type.BYTE); // Yaw
|
||||
wrapper.passthrough(Type.BYTE); // Pitch
|
||||
wrapper.write(Type.BYTE, yaw);
|
||||
wrapper.write(Type.BYTE, yaw); // Head yaw
|
||||
wrapper.write(Type.VAR_INT, 0); // Data
|
||||
wrapper.write(Type.SHORT, (short) 0); // Velocity X
|
||||
wrapper.write(Type.SHORT, (short) 0); // Velocity Y
|
||||
wrapper.write(Type.SHORT, (short) 0); // Velocity Z
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.JOIN_GAME, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
// Just reorder written data, move dimension data to configuration phase
|
||||
wrapper.passthrough(Type.INT); // Entity id
|
||||
wrapper.passthrough(Type.BOOLEAN); // Hardcore
|
||||
|
||||
final byte gamemode = wrapper.read(Type.UNSIGNED_BYTE).byteValue();
|
||||
final byte previousGamemode = wrapper.read(Type.BYTE);
|
||||
|
||||
wrapper.passthrough(Type.STRING_ARRAY); // World List
|
||||
|
||||
final CompoundTag dimensionRegistry = wrapper.read(Type.NBT);
|
||||
final String dimensionType = wrapper.read(Type.STRING);
|
||||
final String world = wrapper.read(Type.STRING);
|
||||
final long seed = wrapper.read(Type.LONG);
|
||||
trackBiomeSize(wrapper.user(), dimensionRegistry); // Caches dimensions to access data like height later
|
||||
cacheDimensionData(wrapper.user(), dimensionRegistry); // Tracks the amount of biomes sent for chunk data
|
||||
|
||||
wrapper.passthrough(Type.VAR_INT); // Max players
|
||||
wrapper.passthrough(Type.VAR_INT); // View distance
|
||||
wrapper.passthrough(Type.VAR_INT); // Simulation distance
|
||||
wrapper.passthrough(Type.BOOLEAN); // Reduced debug info
|
||||
wrapper.passthrough(Type.BOOLEAN); // Show death screen
|
||||
|
||||
wrapper.write(Type.BOOLEAN, false); // Limited crafting
|
||||
wrapper.write(Type.STRING, dimensionType);
|
||||
wrapper.write(Type.STRING, world);
|
||||
wrapper.write(Type.LONG, seed);
|
||||
wrapper.write(Type.BYTE, gamemode);
|
||||
wrapper.write(Type.BYTE, previousGamemode);
|
||||
|
||||
// Debug, flat, last death pos, and portal cooldown at the end unchanged
|
||||
|
||||
final ConfigurationState configurationBridge = wrapper.user().get(ConfigurationState.class);
|
||||
if (!configurationBridge.setLastDimensionRegistry(dimensionRegistry)) {
|
||||
// No change, so no need to re-enter the configuration state - just let this one through
|
||||
return;
|
||||
}
|
||||
|
||||
if (configurationBridge.bridgePhase() == ConfigurationState.BridgePhase.NONE) {
|
||||
// Reenter the configuration state
|
||||
final PacketWrapper configurationPacket = wrapper.create(ClientboundPackets1_20_2.START_CONFIGURATION);
|
||||
configurationPacket.send(Protocol1_20_2To1_20.class);
|
||||
|
||||
configurationBridge.setBridgePhase(ConfigurationState.BridgePhase.REENTERING_CONFIGURATION);
|
||||
configurationBridge.setJoinGamePacket(wrapper);
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
Protocol1_20_2To1_20.sendConfigurationPackets(wrapper.user(), dimensionRegistry, null);
|
||||
|
||||
// Manually send it at the end and hope nothing breaks
|
||||
configurationBridge.setJoinGamePacket(wrapper);
|
||||
wrapper.cancel();
|
||||
});
|
||||
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.RESPAWN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
wrapper.passthrough(Type.STRING); // Dimension type
|
||||
wrapper.passthrough(Type.STRING); // World
|
||||
wrapper.passthrough(Type.LONG); // Seed
|
||||
wrapper.write(Type.BYTE, wrapper.read(Type.UNSIGNED_BYTE).byteValue()); // Gamemode
|
||||
wrapper.passthrough(Type.BYTE); // Previous gamemode
|
||||
wrapper.passthrough(Type.BOOLEAN); // Debug
|
||||
wrapper.passthrough(Type.BOOLEAN); // Flat
|
||||
|
||||
// Move this to the end
|
||||
final byte dataToKeep = wrapper.read(Type.BYTE);
|
||||
|
||||
wrapper.passthrough(Type.OPTIONAL_GLOBAL_POSITION); // Last death position
|
||||
wrapper.passthrough(Type.VAR_INT); // Portal cooldown
|
||||
|
||||
wrapper.write(Type.BYTE, dataToKeep);
|
||||
});
|
||||
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_EFFECT, wrapper -> {
|
||||
wrapper.passthrough(Type.VAR_INT); // Entity id
|
||||
wrapper.write(Type.VAR_INT, wrapper.read(Type.VAR_INT) - 1); // Effect id
|
||||
wrapper.passthrough(Type.BYTE); // Amplifier
|
||||
wrapper.passthrough(Type.VAR_INT); // Duration
|
||||
wrapper.passthrough(Type.BYTE); // Flags
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) {
|
||||
wrapper.write(Type.NAMELESS_NBT, wrapper.read(Type.NBT)); // Factor data
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.REMOVE_ENTITY_EFFECT, wrapper -> {
|
||||
wrapper.passthrough(Type.VAR_INT); // Entity id
|
||||
wrapper.write(Type.VAR_INT, wrapper.read(Type.VAR_INT) - 1); // Effect id
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
filter().handler((event, meta) -> meta.setMetaType(Types1_20_2.META_TYPES.byId(meta.metaType().typeId())));
|
||||
registerMetaTypeHandler(null, Types1_20_2.META_TYPES.blockStateType, Types1_20_2.META_TYPES.optionalBlockStateType, Types1_20_2.META_TYPES.particleType);
|
||||
|
||||
filter().filterFamily(Entity1_19_4Types.DISPLAY).addIndex(10);
|
||||
|
||||
filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
|
||||
final int blockState = meta.value();
|
||||
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType typeFromId(final int type) {
|
||||
return Entity1_19_4Types.getTypeFromId(type);
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4;
|
||||
|
||||
public class RecipeRewriter1_20_2<C extends ClientboundPacketType> extends RecipeRewriter1_19_4<C> {
|
||||
|
||||
public RecipeRewriter1_20_2(final Protocol<C, ?, ?, ?> protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Type<Item> itemType() {
|
||||
return Type.ITEM1_20_2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Type<Item[]> itemArrayType() {
|
||||
return Type.ITEM1_20_2_VAR_INT_ARRAY;
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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.storage;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class ConfigurationState implements StorableObject {
|
||||
|
||||
private final List<QueuedPacket> packetQueue = new ArrayList<>();
|
||||
private BridgePhase bridgePhase = BridgePhase.NONE;
|
||||
private QueuedPacket joinGamePacket;
|
||||
private boolean queuedJoinGame;
|
||||
private CompoundTag lastDimensionRegistry;
|
||||
|
||||
public BridgePhase bridgePhase() {
|
||||
return bridgePhase;
|
||||
}
|
||||
|
||||
public void setBridgePhase(final BridgePhase bridgePhase) {
|
||||
this.bridgePhase = bridgePhase;
|
||||
}
|
||||
|
||||
public @Nullable CompoundTag lastDimensionRegistry() {
|
||||
return lastDimensionRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last dimension registry and returns whether it differs from the previously stored one.
|
||||
*
|
||||
* @param dimensionRegistry dimension registry to set
|
||||
* @return whether the dimension registry differs from the previously stored one
|
||||
*/
|
||||
public boolean setLastDimensionRegistry(final CompoundTag dimensionRegistry) {
|
||||
final boolean equals = Objects.equals(this.lastDimensionRegistry, dimensionRegistry);
|
||||
this.lastDimensionRegistry = dimensionRegistry;
|
||||
return !equals;
|
||||
}
|
||||
|
||||
public void addPacketToQueue(final PacketWrapper wrapper, final boolean clientbound) throws Exception {
|
||||
packetQueue.add(toQueuedPacket(wrapper, clientbound, false));
|
||||
}
|
||||
|
||||
private QueuedPacket toQueuedPacket(final PacketWrapper wrapper, final boolean clientbound, final boolean skipCurrentPipeline) throws Exception {
|
||||
// Caching packet buffers is cursed, copy to heap buffers to make sure we don't start leaking in dumb cases
|
||||
final ByteBuf copy = Unpooled.buffer();
|
||||
final PacketType packetType = wrapper.getPacketType();
|
||||
final int packetId = wrapper.getId();
|
||||
// Don't write the packet id to the buffer
|
||||
//noinspection deprecation
|
||||
wrapper.setId(-1);
|
||||
wrapper.writeToBuffer(copy);
|
||||
return new QueuedPacket(copy, clientbound, packetType, packetId, skipCurrentPipeline);
|
||||
}
|
||||
|
||||
public void setJoinGamePacket(final PacketWrapper wrapper) throws Exception {
|
||||
this.joinGamePacket = toQueuedPacket(wrapper, true, true);
|
||||
queuedJoinGame = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOnServerSwitch() {
|
||||
return false; // This might be bad
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove() {
|
||||
for (final QueuedPacket packet : packetQueue) {
|
||||
packet.buf().release();
|
||||
}
|
||||
if (joinGamePacket != null) {
|
||||
joinGamePacket.buf().release();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendQueuedPackets(final UserConnection connection) throws Exception {
|
||||
if (joinGamePacket != null) {
|
||||
packetQueue.add(0, joinGamePacket);
|
||||
joinGamePacket = null;
|
||||
}
|
||||
|
||||
final ConfigurationState.QueuedPacket[] queuedPackets = packetQueue.toArray(new ConfigurationState.QueuedPacket[0]);
|
||||
packetQueue.clear();
|
||||
|
||||
for (final ConfigurationState.QueuedPacket packet : queuedPackets) {
|
||||
final PacketWrapper queuedWrapper;
|
||||
try {
|
||||
if (packet.packetType() != null) {
|
||||
queuedWrapper = PacketWrapper.create(packet.packetType(), packet.buf(), connection);
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
queuedWrapper = PacketWrapper.create(packet.packetId(), packet.buf(), connection);
|
||||
}
|
||||
|
||||
if (packet.clientbound()) {
|
||||
queuedWrapper.send(Protocol1_20_2To1_20.class, packet.skipCurrentPipeline());
|
||||
} else {
|
||||
queuedWrapper.sendToServer(Protocol1_20_2To1_20.class, packet.skipCurrentPipeline());
|
||||
}
|
||||
} finally {
|
||||
packet.buf().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
packetQueue.clear();
|
||||
bridgePhase = BridgePhase.NONE;
|
||||
queuedJoinGame = false;
|
||||
}
|
||||
|
||||
public boolean queuedOrSentJoinGame() {
|
||||
return queuedJoinGame;
|
||||
}
|
||||
|
||||
public enum BridgePhase {
|
||||
NONE, PROFILE_SENT, CONFIGURATION, REENTERING_CONFIGURATION
|
||||
}
|
||||
|
||||
public static final class QueuedPacket {
|
||||
private final ByteBuf buf;
|
||||
private final boolean clientbound;
|
||||
private final PacketType packetType;
|
||||
private final int packetId;
|
||||
private final boolean skipCurrentPipeline;
|
||||
|
||||
private QueuedPacket(final ByteBuf buf, final boolean clientbound, final PacketType packetType,
|
||||
final int packetId, final boolean skipCurrentPipeline) {
|
||||
this.buf = buf;
|
||||
this.clientbound = clientbound;
|
||||
this.packetType = packetType;
|
||||
this.packetId = packetId;
|
||||
this.skipCurrentPipeline = skipCurrentPipeline;
|
||||
}
|
||||
|
||||
public ByteBuf buf() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
public boolean clientbound() {
|
||||
return clientbound;
|
||||
}
|
||||
|
||||
public int packetId() {
|
||||
return packetId;
|
||||
}
|
||||
|
||||
public @Nullable PacketType packetType() {
|
||||
return packetType;
|
||||
}
|
||||
|
||||
public boolean skipCurrentPipeline() {
|
||||
return skipCurrentPipeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueuedPacket{" +
|
||||
"buf=" + buf +
|
||||
", clientbound=" + clientbound +
|
||||
", packetType=" + packetType +
|
||||
", packetId=" + packetId +
|
||||
", skipCurrentPipeline=" + skipCurrentPipeline +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.storage;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class LastResourcePack implements StorableObject {
|
||||
|
||||
private final String url;
|
||||
private final String hash;
|
||||
private final boolean required;
|
||||
private final JsonElement prompt;
|
||||
|
||||
public LastResourcePack(final String url, final String hash, final boolean required, @Nullable final JsonElement prompt) {
|
||||
this.url = url;
|
||||
this.hash = hash;
|
||||
this.required = required;
|
||||
this.prompt = prompt;
|
||||
}
|
||||
|
||||
public String url() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String hash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public boolean required() {
|
||||
return required;
|
||||
}
|
||||
|
||||
public @Nullable JsonElement prompt() {
|
||||
return prompt;
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.minecraft.BaseChunkType;
|
||||
import com.viaversion.viaversion.api.type.types.version.ChunkSectionType1_18;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_2;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ChunkType1_20_2 extends Type<Chunk> {
|
||||
private final ChunkSectionType1_18 sectionType;
|
||||
private final int ySectionCount;
|
||||
|
||||
public ChunkType1_20_2(final int ySectionCount, final int globalPaletteBlockBits, final int globalPaletteBiomeBits) {
|
||||
super(Chunk.class);
|
||||
Preconditions.checkArgument(ySectionCount > 0);
|
||||
this.sectionType = new ChunkSectionType1_18(globalPaletteBlockBits, globalPaletteBiomeBits);
|
||||
this.ySectionCount = ySectionCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk read(final ByteBuf buffer) throws Exception {
|
||||
final int chunkX = buffer.readInt();
|
||||
final int chunkZ = buffer.readInt();
|
||||
final CompoundTag heightMap = Type.NAMELESS_NBT.read(buffer);
|
||||
|
||||
// Read sections
|
||||
final ByteBuf sectionsBuf = buffer.readBytes(Type.VAR_INT.readPrimitive(buffer));
|
||||
final ChunkSection[] sections = new ChunkSection[ySectionCount];
|
||||
try {
|
||||
for (int i = 0; i < ySectionCount; i++) {
|
||||
sections[i] = sectionType.read(sectionsBuf);
|
||||
}
|
||||
} finally {
|
||||
sectionsBuf.release();
|
||||
}
|
||||
|
||||
final int blockEntitiesLength = Type.VAR_INT.readPrimitive(buffer);
|
||||
final List<BlockEntity> blockEntities = new ArrayList<>(blockEntitiesLength);
|
||||
for (int i = 0; i < blockEntitiesLength; i++) {
|
||||
blockEntities.add(Types1_20_2.BLOCK_ENTITY.read(buffer));
|
||||
}
|
||||
|
||||
return new Chunk1_18(chunkX, chunkZ, sections, heightMap, blockEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Chunk chunk) throws Exception {
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
|
||||
Type.NAMELESS_NBT.write(buffer, chunk.getHeightMap());
|
||||
|
||||
final ByteBuf sectionBuffer = buffer.alloc().buffer();
|
||||
try {
|
||||
for (final ChunkSection section : chunk.getSections()) {
|
||||
sectionType.write(sectionBuffer, section);
|
||||
}
|
||||
sectionBuffer.readerIndex(0);
|
||||
Type.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
|
||||
buffer.writeBytes(sectionBuffer);
|
||||
} finally {
|
||||
sectionBuffer.release(); // release buffer
|
||||
}
|
||||
|
||||
Type.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size());
|
||||
for (final BlockEntity blockEntity : chunk.blockEntities()) {
|
||||
Types1_20_2.BLOCK_ENTITY.write(buffer, blockEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Type> getBaseClass() {
|
||||
return BaseChunkType.class;
|
||||
}
|
||||
}
|
||||
+23
@@ -23,8 +23,10 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.Quaternion;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_19_4;
|
||||
@@ -35,6 +37,8 @@ import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
|
||||
public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_20To1_19_4> {
|
||||
|
||||
private static final Quaternion Y_FLIPPED_ROTATION = new Quaternion(0, 1, 0, 0);
|
||||
|
||||
public EntityPackets(final Protocol1_20To1_19_4 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
@@ -127,6 +131,21 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4
|
||||
filter().handler((event, meta) -> meta.setMetaType(Types1_20.META_TYPES.byId(meta.metaType().typeId())));
|
||||
registerMetaTypeHandler(Types1_20.META_TYPES.itemType, Types1_20.META_TYPES.blockStateType, Types1_20.META_TYPES.optionalBlockStateType, Types1_20.META_TYPES.particleType);
|
||||
|
||||
// Rotate item display by 180 degrees around the Y axis
|
||||
filter().filterFamily(Entity1_19_4Types.ITEM_DISPLAY).handler((event, meta) -> {
|
||||
if (event.trackedEntity().hasSentMetadata() || event.hasExtraMeta()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.metaAtIndex(12) == null) {
|
||||
event.createExtraMeta(new Metadata(12, Types1_20.META_TYPES.quaternionType, Y_FLIPPED_ROTATION));
|
||||
}
|
||||
});
|
||||
filter().filterFamily(Entity1_19_4Types.ITEM_DISPLAY).index(12).handler((event, meta) -> {
|
||||
final Quaternion quaternion = meta.value();
|
||||
meta.setValue(rotateY180(quaternion));
|
||||
});
|
||||
|
||||
filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
|
||||
final int blockState = meta.value();
|
||||
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
|
||||
@@ -137,4 +156,8 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4
|
||||
public EntityType typeFromId(final int type) {
|
||||
return Entity1_19_4Types.getTypeFromId(type);
|
||||
}
|
||||
|
||||
private Quaternion rotateY180(final Quaternion quaternion) {
|
||||
return new Quaternion(-quaternion.z(), quaternion.w(), quaternion.x(), -quaternion.y());
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -67,9 +67,9 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_19_
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.passthrough(Type.STRING); // Identifier
|
||||
|
||||
// Parent
|
||||
if (wrapper.passthrough(Type.BOOLEAN))
|
||||
wrapper.passthrough(Type.STRING);
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) {
|
||||
wrapper.passthrough(Type.STRING); // Parent
|
||||
}
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) {
|
||||
@@ -85,11 +85,11 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_19_
|
||||
wrapper.passthrough(Type.FLOAT); // Y
|
||||
}
|
||||
|
||||
wrapper.passthrough(Type.STRING_ARRAY); // Criteria
|
||||
wrapper.passthrough(Type.STRING_ARRAY); // Critereon triggers
|
||||
|
||||
int arrayLength = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int array = 0; array < arrayLength; array++) {
|
||||
wrapper.passthrough(Type.STRING_ARRAY); // String array
|
||||
int requirements = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int array = 0; array < requirements; array++) {
|
||||
wrapper.passthrough(Type.STRING_ARRAY);
|
||||
}
|
||||
|
||||
wrapper.write(Type.BOOLEAN, false); // Sends telemetry
|
||||
|
||||
-121
@@ -1,121 +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.protocols.protocol1_9_1_2to1_9_3_4;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.Position;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.chunks.BlockEntity;
|
||||
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.storage.ClientWorld;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_1_2Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||
|
||||
// Goes BACKWARDS from 1.9.3/4 to 1.9.1/2
|
||||
public class Protocol1_9_1_2To1_9_3_4 extends AbstractProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9, ServerboundPackets1_9_3, ServerboundPackets1_9> {
|
||||
|
||||
public Protocol1_9_1_2To1_9_3_4() {
|
||||
super(ClientboundPackets1_9_3.class, ClientboundPackets1_9.class, ServerboundPackets1_9_3.class, ServerboundPackets1_9.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
registerClientbound(ClientboundPackets1_9_3.BLOCK_ENTITY_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.POSITION); //Position
|
||||
map(Type.UNSIGNED_BYTE); //Type
|
||||
map(Type.NBT); //NBT
|
||||
handler(wrapper -> {
|
||||
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 9) {
|
||||
Position position = wrapper.get(Type.POSITION, 0);
|
||||
CompoundTag tag = wrapper.get(Type.NBT, 0);
|
||||
|
||||
wrapper.clearPacket(); //Clear the packet
|
||||
|
||||
wrapper.setPacketType(ClientboundPackets1_9.UPDATE_SIGN);
|
||||
wrapper.write(Type.POSITION, position); // Position
|
||||
for (int i = 1; i < 5; i++) {
|
||||
// Should technically be written as COMPONENT, but left as String for simplification/to remove redundant wrapping for VR
|
||||
Tag textTag = tag.get("Text" + i);
|
||||
String line = textTag instanceof StringTag ? ((StringTag) textTag).getValue() : "";
|
||||
wrapper.write(Type.STRING, line); // Sign line
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_9_3.CHUNK_DATA, wrapper -> {
|
||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
Chunk1_9_3_4Type newType = new Chunk1_9_3_4Type(clientWorld);
|
||||
Chunk1_9_1_2Type oldType = new Chunk1_9_1_2Type(clientWorld); // Get the old type to not write Block Entities
|
||||
|
||||
Chunk chunk = wrapper.read(newType);
|
||||
wrapper.write(oldType, chunk);
|
||||
BlockEntity.handle(chunk.getBlockEntities(), wrapper.user());
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_9_3.JOIN_GAME, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.INT); // 0 - Entity ID
|
||||
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
|
||||
map(Type.INT); // 2 - Dimension
|
||||
|
||||
handler(wrapper -> {
|
||||
ClientWorld clientChunks = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
int dimensionId = wrapper.get(Type.INT, 1);
|
||||
clientChunks.setEnvironment(dimensionId);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_9_3.RESPAWN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.INT); // 0 - Dimension ID
|
||||
|
||||
handler(wrapper -> {
|
||||
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
|
||||
|
||||
int dimensionId = wrapper.get(Type.INT, 0);
|
||||
clientWorld.setEnvironment(dimensionId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(UserConnection userConnection) {
|
||||
if (!userConnection.has(ClientWorld.class)) {
|
||||
userConnection.put(new ClientWorld(userConnection));
|
||||
}
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +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.protocols.protocol1_9_1_2to1_9_3_4.chunks;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
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_9_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_4;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BlockEntity {
|
||||
private static final Map<String, Integer> types = new HashMap<>();
|
||||
|
||||
static {
|
||||
types.put("MobSpawner", 1);
|
||||
types.put("Control", 2);
|
||||
types.put("Beacon", 3);
|
||||
types.put("Skull", 4);
|
||||
types.put("FlowerPot", 5);
|
||||
types.put("Banner", 6);
|
||||
types.put("UNKNOWN", 7);
|
||||
types.put("EndGateway", 8);
|
||||
types.put("Sign", 9);
|
||||
}
|
||||
|
||||
public static void handle(List<CompoundTag> tags, UserConnection connection) {
|
||||
for (CompoundTag tag : tags) {
|
||||
try {
|
||||
if (!tag.contains("id"))
|
||||
throw new Exception("NBT tag not handled because the id key is missing");
|
||||
|
||||
String id = (String) tag.get("id").getValue();
|
||||
if (!types.containsKey(id))
|
||||
throw new Exception("Not handled id: " + id);
|
||||
|
||||
int newId = types.get(id);
|
||||
if (newId == -1)
|
||||
continue;
|
||||
|
||||
int x = ((NumberTag) tag.get("x")).asInt();
|
||||
int y = ((NumberTag) tag.get("y")).asInt();
|
||||
int z = ((NumberTag) tag.get("z")).asInt();
|
||||
|
||||
Position pos = new Position(x, (short) y, z);
|
||||
|
||||
updateBlockEntity(pos, (short) newId, tag, connection);
|
||||
} catch (Exception e) {
|
||||
if (Via.getManager().isDebug()) {
|
||||
Via.getPlatform().getLogger().warning("Block Entity: " + e.getMessage() + ": " + tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateBlockEntity(Position pos, short id, CompoundTag tag, UserConnection connection) throws Exception {
|
||||
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9_3.BLOCK_ENTITY_DATA, null, connection);
|
||||
wrapper.write(Type.POSITION, pos);
|
||||
wrapper.write(Type.UNSIGNED_BYTE, id);
|
||||
wrapper.write(Type.NBT, tag);
|
||||
wrapper.scheduleSend(Protocol1_9_1_2To1_9_3_4.class, false);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* 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_9_3to1_9_1_2.types;
|
||||
package com.viaversion.viaversion.protocols.protocol1_9_1to1_9.types;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.Environment;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.BaseChunk;
|
||||
+2
-2
@@ -32,10 +32,10 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
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.chunks.FakeTileEntity;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_1_2Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_1to1_9.types.Chunk1_9_1_2Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||
import java.util.List;
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
* 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_9_1_2to1_9_3_4.types;
|
||||
package com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
@@ -122,4 +122,4 @@ public class Chunk1_9_3_4Type extends PartialType<Chunk, ClientWorld> {
|
||||
public Class<? extends Type> getBaseClass() {
|
||||
return BaseChunkType.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-8
@@ -37,13 +37,7 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.InventoryPac
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.PlayerPackets;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.SpawnPackets;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.WorldPackets;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.CommandBlockProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.CompressionProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MainHandProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.*;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.CommandBlockStorage;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.EntityTracker1_9;
|
||||
@@ -137,7 +131,7 @@ public class Protocol1_9To1_8 extends AbstractProtocol<ClientboundPackets1_8, Cl
|
||||
providers.register(BossBarProvider.class, new BossBarProvider());
|
||||
providers.register(MainHandProvider.class, new MainHandProvider());
|
||||
providers.register(CompressionProvider.class, new CompressionProvider());
|
||||
providers.require(MovementTransmitterProvider.class);
|
||||
providers.register(MovementTransmitterProvider.class, new MovementTransmitterProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_1_2Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9_1to1_9.types.Chunk1_9_1_2Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ItemRewriter;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
|
||||
+21
-14
@@ -17,27 +17,34 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.protocol1_9to1_8.providers;
|
||||
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.platform.providers.Provider;
|
||||
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.storage.MovementTracker;
|
||||
import com.viaversion.viaversion.util.PipelineUtil;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
public abstract class MovementTransmitterProvider implements Provider {
|
||||
public abstract Object getFlyingPacket();
|
||||
import java.util.logging.Level;
|
||||
|
||||
public abstract Object getGroundPacket();
|
||||
public class MovementTransmitterProvider implements Provider {
|
||||
|
||||
public void sendPlayer(UserConnection userConnection) {
|
||||
// Old method using packets.
|
||||
ChannelHandlerContext context = PipelineUtil.getContextBefore("decoder", userConnection.getChannel().pipeline());
|
||||
if (context != null) {
|
||||
if (userConnection.get(MovementTracker.class).isGround()) {
|
||||
context.fireChannelRead(getGroundPacket());
|
||||
} else {
|
||||
context.fireChannelRead(getFlyingPacket());
|
||||
}
|
||||
userConnection.get(MovementTracker.class).incrementIdlePacket();
|
||||
if (userConnection.getProtocolInfo().getState() != State.PLAY || userConnection.getEntityTracker(Protocol1_9To1_8.class).clientEntityId() == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MovementTracker movementTracker = userConnection.get(MovementTracker.class);
|
||||
movementTracker.incrementIdlePacket();
|
||||
|
||||
try {
|
||||
final PacketWrapper playerMovement = PacketWrapper.create(ServerboundPackets1_8.PLAYER_MOVEMENT, userConnection);
|
||||
playerMovement.write(Type.BOOLEAN, movementTracker.isGround()); // on ground
|
||||
playerMovement.scheduleSendToServer(Protocol1_9To1_8.class);
|
||||
} catch (Throwable e) {
|
||||
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to send player movement packet", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -42,8 +42,8 @@ public class Effect {
|
||||
addRewrite(1020, 1029); //Anvil break
|
||||
addRewrite(1021, 1030); //Anvil use
|
||||
addRewrite(1022, 1031); //Anvil land
|
||||
addRewrite(1013, 1023);
|
||||
addRewrite(1018, 1028);
|
||||
addRewrite(1013, 1023); //Wither spawn
|
||||
addRewrite(1018, 1028); //EnderDragon end
|
||||
}
|
||||
|
||||
public static int getNewId(int id) {
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ public class MovementTracker implements StorableObject {
|
||||
private static final long IDLE_PACKET_DELAY = 50L; // Update every 50ms (20tps)
|
||||
private static final long IDLE_PACKET_LIMIT = 20; // Max 20 ticks behind
|
||||
private long nextIdlePacket = 0L;
|
||||
private boolean ground = true;
|
||||
private boolean ground = false;
|
||||
|
||||
public void incrementIdlePacket() {
|
||||
// Notify of next update
|
||||
|
||||
-64
@@ -1,64 +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.protocols.protocol1_9to1_9_1;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
|
||||
|
||||
public class Protocol1_9To1_9_1 extends AbstractProtocol<ClientboundPackets1_9, ClientboundPackets1_9, ServerboundPackets1_9, ServerboundPackets1_9> {
|
||||
|
||||
public Protocol1_9To1_9_1() {
|
||||
super(ClientboundPackets1_9.class, ClientboundPackets1_9.class, ServerboundPackets1_9.class, ServerboundPackets1_9.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
registerClientbound(ClientboundPackets1_9.JOIN_GAME, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.INT); // 0 - Player ID
|
||||
map(Type.UNSIGNED_BYTE); // 1 - Player Gamemode
|
||||
// 1.9.1 PRE 2 Changed this
|
||||
map(Type.INT, Type.BYTE); // 2 - Player Dimension
|
||||
map(Type.UNSIGNED_BYTE); // 3 - World Difficulty
|
||||
map(Type.UNSIGNED_BYTE); // 4 - Max Players (Tab)
|
||||
map(Type.STRING); // 5 - Level Type
|
||||
map(Type.BOOLEAN); // 6 - Reduced Debug info
|
||||
}
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_9.SOUND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.VAR_INT); // 0 - Sound ID
|
||||
|
||||
handler(wrapper -> {
|
||||
int sound = wrapper.get(Type.VAR_INT, 0);
|
||||
|
||||
if (sound == 415) // Stop the Elytra sound for 1.9 (It's introduced in 1.9.2)
|
||||
wrapper.cancel();
|
||||
else if (sound >= 416) // Act like the Elytra sound never existed
|
||||
wrapper.set(Type.VAR_INT, 0, sound - 1);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -42,10 +42,16 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
public class BlockRewriter<C extends ClientboundPacketType> {
|
||||
private final Protocol<C, ?, ?, ?> protocol;
|
||||
private final Type<Position> positionType;
|
||||
private final Type<CompoundTag> nbtType;
|
||||
|
||||
public BlockRewriter(Protocol<C, ?, ?, ?> protocol, Type<Position> positionType) {
|
||||
this(protocol, positionType, Type.NBT);
|
||||
}
|
||||
|
||||
public BlockRewriter(Protocol<C, ?, ?, ?> protocol, Type<Position> positionType, Type<CompoundTag> nbtType) {
|
||||
this.protocol = protocol;
|
||||
this.positionType = positionType;
|
||||
this.nbtType = nbtType;
|
||||
}
|
||||
|
||||
public void registerBlockAction(C packetType) {
|
||||
@@ -145,9 +151,9 @@ public class BlockRewriter<C extends ClientboundPacketType> {
|
||||
handler(wrapper -> {
|
||||
int id = wrapper.get(Type.INT, 0);
|
||||
int data = wrapper.get(Type.INT, 1);
|
||||
if (id == playRecordId) { // Play record
|
||||
if (id == playRecordId && protocol.getMappingData().getItemMappings() != null) {
|
||||
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewItemId(data));
|
||||
} else if (id == blockBreakId) { // Block break + block break sound
|
||||
} else if (id == blockBreakId && protocol.getMappingData().getBlockStateMappings() != null) {
|
||||
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewBlockStateId(data));
|
||||
}
|
||||
});
|
||||
@@ -203,7 +209,7 @@ public class BlockRewriter<C extends ClientboundPacketType> {
|
||||
|
||||
public void registerBlockEntityData(C packetType, @Nullable Consumer<BlockEntity> blockEntityHandler) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
final Position position = wrapper.passthrough(Type.POSITION1_14);
|
||||
final Position position = wrapper.passthrough(positionType);
|
||||
|
||||
final int blockEntityId = wrapper.read(Type.VAR_INT);
|
||||
final Mappings mappings = protocol.getMappingData().getBlockEntityMappings();
|
||||
@@ -214,7 +220,7 @@ public class BlockRewriter<C extends ClientboundPacketType> {
|
||||
}
|
||||
|
||||
final CompoundTag tag;
|
||||
if (blockEntityHandler != null && (tag = wrapper.passthrough(Type.NBT)) != null) {
|
||||
if (blockEntityHandler != null && (tag = wrapper.passthrough(nbtType)) != null) {
|
||||
final BlockEntity blockEntity = new BlockEntityImpl(BlockEntity.pack(position.x(), position.z()), (short) position.y(), blockEntityId, tag);
|
||||
blockEntityHandler.accept(blockEntity);
|
||||
}
|
||||
|
||||
@@ -101,11 +101,11 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMetadata(int entityId, List<Metadata> metadataList, UserConnection connection) {
|
||||
public void handleMetadata(final int entityId, final List<Metadata> metadataList, final UserConnection connection) {
|
||||
final TrackedEntity entity = tracker(connection).entity(entityId);
|
||||
final EntityType type = entity != null ? entity.entityType() : null;
|
||||
int i = 0; // Count index for fast removal
|
||||
for (Metadata metadata : metadataList.toArray(EMPTY_ARRAY)) { // Copy the list to allow mutation
|
||||
for (final Metadata metadata : metadataList.toArray(EMPTY_ARRAY)) { // Copy the list to allow mutation
|
||||
// Call handlers implementing the old handleMetadata
|
||||
if (!callOldMetaHandler(entityId, type, metadata, metadataList, connection)) {
|
||||
metadataList.remove(i--);
|
||||
@@ -113,18 +113,18 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
}
|
||||
|
||||
MetaHandlerEvent event = null;
|
||||
for (MetaFilter filter : metadataFilters) {
|
||||
for (final MetaFilter filter : metadataFilters) {
|
||||
if (!filter.isFiltered(type, metadata)) {
|
||||
continue;
|
||||
}
|
||||
if (event == null) {
|
||||
// Only initialize when needed and share event instance
|
||||
event = new MetaHandlerEventImpl(connection, type, entityId, metadata, metadataList);
|
||||
event = new MetaHandlerEventImpl(connection, entity, entityId, metadata, metadataList);
|
||||
}
|
||||
|
||||
try {
|
||||
filter.handler().handle(event, metadata);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
logException(e, type, metadataList, metadata);
|
||||
metadataList.remove(i--);
|
||||
break;
|
||||
@@ -311,6 +311,10 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
map(Type.VAR_INT); // Data
|
||||
handler(trackerHandler());
|
||||
handler(wrapper -> {
|
||||
if (protocol.getMappingData() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int entityId = wrapper.get(Type.VAR_INT, 0);
|
||||
EntityType entityType = tracker(wrapper.user()).entityType(entityId);
|
||||
if (entityType == fallingBlockType) {
|
||||
@@ -468,32 +472,32 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
}
|
||||
|
||||
public PacketHandler biomeSizeTracker() {
|
||||
return wrapper -> {
|
||||
final CompoundTag registry = wrapper.get(Type.NBT, 0);
|
||||
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
|
||||
final ListTag biomes = biomeRegistry.get("value");
|
||||
tracker(wrapper.user()).setBiomesSent(biomes.size());
|
||||
};
|
||||
return wrapper -> trackBiomeSize(wrapper.user(), wrapper.get(Type.NBT, 0));
|
||||
}
|
||||
|
||||
public void trackBiomeSize(final UserConnection connection, final CompoundTag registry) {
|
||||
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
|
||||
final ListTag biomes = biomeRegistry.get("value");
|
||||
tracker(connection).setBiomesSent(biomes.size());
|
||||
}
|
||||
|
||||
public PacketHandler dimensionDataHandler() {
|
||||
return wrapper -> cacheDimensionData(wrapper.user(), wrapper.get(Type.NBT, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler to cache dimension data, later used to get height values and other important info.
|
||||
*
|
||||
* @return handler to cache dimension data
|
||||
* Caches dimension data, later used to get height values and other important info.
|
||||
*/
|
||||
public PacketHandler dimensionDataHandler() {
|
||||
return wrapper -> {
|
||||
final CompoundTag tag = wrapper.get(Type.NBT, 0);
|
||||
final ListTag dimensions = ((CompoundTag) tag.get("minecraft:dimension_type")).get("value");
|
||||
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(dimensions.size());
|
||||
for (final Tag dimension : dimensions) {
|
||||
final CompoundTag dimensionCompound = (CompoundTag) dimension;
|
||||
final CompoundTag element = dimensionCompound.get("element");
|
||||
final String name = (String) dimensionCompound.get("name").getValue();
|
||||
dimensionDataMap.put(name, new DimensionDataImpl(element));
|
||||
}
|
||||
tracker(wrapper.user()).setDimensions(dimensionDataMap);
|
||||
};
|
||||
public void cacheDimensionData(final UserConnection connection, final CompoundTag registry) {
|
||||
final ListTag dimensions = ((CompoundTag) registry.get("minecraft:dimension_type")).get("value");
|
||||
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(dimensions.size());
|
||||
for (final Tag dimension : dimensions) {
|
||||
final CompoundTag dimensionCompound = (CompoundTag) dimension;
|
||||
final CompoundTag element = dimensionCompound.get("element");
|
||||
final String name = (String) dimensionCompound.get("name").getValue();
|
||||
dimensionDataMap.put(name, new DimensionDataImpl(element));
|
||||
}
|
||||
tracker(connection).setDimensions(dimensionDataMap);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -31,9 +31,17 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public abstract class ItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
||||
T extends Protocol<C, ?, ?, S>> extends RewriterBase<T> implements com.viaversion.viaversion.api.rewriter.ItemRewriter<T> {
|
||||
private final Type<Item> itemType;
|
||||
private final Type<Item[]> itemArrayType;
|
||||
|
||||
protected ItemRewriter(T protocol) {
|
||||
this(protocol, Type.FLAT_VAR_INT_ITEM, Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT);
|
||||
}
|
||||
|
||||
public ItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType) {
|
||||
super(protocol);
|
||||
this.itemType = itemType;
|
||||
this.itemArrayType = itemArrayType;
|
||||
}
|
||||
|
||||
// These two methods always return the same item instance *for now*
|
||||
@@ -62,7 +70,7 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
public void register() {
|
||||
map(Type.UNSIGNED_BYTE); // Window id
|
||||
map(type); // Items
|
||||
handler(itemArrayHandler(type));
|
||||
handler(itemArrayToClientHandler(type));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -74,12 +82,12 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
map(Type.UNSIGNED_BYTE); // Window id
|
||||
map(Type.VAR_INT); // State id
|
||||
handler(wrapper -> {
|
||||
Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT);
|
||||
Item[] items = wrapper.passthrough(itemArrayType);
|
||||
for (Item item : items) {
|
||||
handleItemToClient(item);
|
||||
}
|
||||
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Carried item
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Carried item
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -123,8 +131,8 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
map(Type.UNSIGNED_BYTE); // Window id
|
||||
map(Type.VAR_INT); // State id
|
||||
map(Type.SHORT); // Slot id
|
||||
map(Type.FLAT_VAR_INT_ITEM); // Item
|
||||
handler(itemToClientHandler(Type.FLAT_VAR_INT_ITEM));
|
||||
map(itemType); // Item
|
||||
handler(itemToClientHandler(itemType));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -155,7 +163,7 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
do {
|
||||
slot = wrapper.passthrough(Type.BYTE);
|
||||
// & 0x7F into an extra variable if slot is needed
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
|
||||
handleItemToClient(wrapper.passthrough(itemType));
|
||||
} while ((slot & 0xFFFFFF80) != 0);
|
||||
});
|
||||
}
|
||||
@@ -168,7 +176,6 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
public void register() {
|
||||
map(Type.SHORT); // 0 - Slot
|
||||
map(type); // 1 - Clicked Item
|
||||
|
||||
handler(itemToServerHandler(type));
|
||||
}
|
||||
});
|
||||
@@ -205,11 +212,11 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
int length = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
wrapper.passthrough(Type.SHORT); // Slot
|
||||
handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
|
||||
handleItemToServer(wrapper.passthrough(itemType));
|
||||
}
|
||||
|
||||
// Carried item
|
||||
handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
|
||||
handleItemToServer(wrapper.passthrough(itemType));
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -228,11 +235,11 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
wrapper.passthrough(Type.VAR_INT);
|
||||
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
|
||||
for (int i = 0; i < size; i++) {
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Input
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Output
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Input
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Output
|
||||
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) { // Has second item
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Second Item
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Second Item
|
||||
}
|
||||
|
||||
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
|
||||
@@ -253,9 +260,9 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
wrapper.passthrough(Type.VAR_INT); // Container id
|
||||
int size = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Input
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Output
|
||||
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Second Item
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Input
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Output
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Second Item
|
||||
|
||||
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
|
||||
wrapper.passthrough(Type.INT); // Number of tools uses
|
||||
@@ -304,6 +311,41 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
});
|
||||
}
|
||||
|
||||
public void registerAdvancements1_20_2(C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
|
||||
int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.passthrough(Type.STRING); // Identifier
|
||||
|
||||
// Parent
|
||||
if (wrapper.passthrough(Type.BOOLEAN))
|
||||
wrapper.passthrough(Type.STRING);
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Type.BOOLEAN)) {
|
||||
wrapper.passthrough(Type.COMPONENT); // Title
|
||||
wrapper.passthrough(Type.COMPONENT); // Description
|
||||
handleItemToClient(wrapper.passthrough(itemType)); // Icon
|
||||
wrapper.passthrough(Type.VAR_INT); // Frame type
|
||||
int flags = wrapper.passthrough(Type.INT); // Flags
|
||||
if ((flags & 1) != 0) {
|
||||
wrapper.passthrough(Type.STRING); // Background texture
|
||||
}
|
||||
wrapper.passthrough(Type.FLOAT); // X
|
||||
wrapper.passthrough(Type.FLOAT); // Y
|
||||
}
|
||||
|
||||
int requirements = wrapper.passthrough(Type.VAR_INT);
|
||||
for (int array = 0; array < requirements; array++) {
|
||||
wrapper.passthrough(Type.STRING_ARRAY);
|
||||
}
|
||||
|
||||
wrapper.passthrough(Type.BOOLEAN); // Send telemetry
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerWindowPropertyEnchantmentHandler(C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
@@ -340,7 +382,7 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
map(Type.FLOAT); // 7 - Offset Z
|
||||
map(Type.FLOAT); // 8 - Particle Data
|
||||
map(Type.INT); // 9 - Particle Count
|
||||
handler(getSpawnParticleHandler(itemType));
|
||||
handler(getSpawnParticleHandler());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -359,16 +401,16 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
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(getSpawnParticleHandler(Type.VAR_INT));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public PacketHandler getSpawnParticleHandler(Type<Item> itemType) {
|
||||
return getSpawnParticleHandler(Type.INT, itemType);
|
||||
public PacketHandler getSpawnParticleHandler() {
|
||||
return getSpawnParticleHandler(Type.INT);
|
||||
}
|
||||
|
||||
public PacketHandler getSpawnParticleHandler(Type<Integer> idType, Type<Item> itemType) {
|
||||
public PacketHandler getSpawnParticleHandler(Type<Integer> idType) {
|
||||
return wrapper -> {
|
||||
int id = wrapper.get(idType, 0);
|
||||
if (id == -1) {
|
||||
@@ -390,8 +432,7 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
};
|
||||
}
|
||||
|
||||
// Only sent to the client
|
||||
public PacketHandler itemArrayHandler(Type<Item[]> type) {
|
||||
public PacketHandler itemArrayToClientHandler(Type<Item[]> type) {
|
||||
return wrapper -> {
|
||||
Item[] items = wrapper.get(type, 0);
|
||||
for (Item item : items) {
|
||||
|
||||
@@ -82,19 +82,19 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
for (int i = 0; i < ingredientsNo; i++) {
|
||||
handleIngredient(wrapper);
|
||||
}
|
||||
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
|
||||
rewrite(wrapper.passthrough(itemType())); // Result
|
||||
}
|
||||
|
||||
public void handleCraftingShapeless(PacketWrapper wrapper) throws Exception {
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
handleIngredients(wrapper);
|
||||
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
|
||||
rewrite(wrapper.passthrough(itemType())); // Result
|
||||
}
|
||||
|
||||
public void handleSmelting(PacketWrapper wrapper) throws Exception {
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
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
|
||||
}
|
||||
@@ -102,13 +102,13 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
public void handleStonecutting(PacketWrapper wrapper) throws Exception {
|
||||
wrapper.passthrough(Type.STRING); // Group
|
||||
handleIngredient(wrapper);
|
||||
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
|
||||
rewrite(wrapper.passthrough(itemType())); // Result
|
||||
}
|
||||
|
||||
public void handleSmithing(PacketWrapper wrapper) throws Exception {
|
||||
handleIngredient(wrapper); // Base
|
||||
handleIngredient(wrapper); // Addition
|
||||
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
|
||||
rewrite(wrapper.passthrough(itemType())); // Result
|
||||
}
|
||||
|
||||
public void handleSimpleRecipe(final PacketWrapper wrapper) throws Exception {
|
||||
@@ -119,7 +119,7 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
handleIngredient(wrapper); // Template
|
||||
handleIngredient(wrapper); // Base
|
||||
handleIngredient(wrapper); // Additions
|
||||
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
|
||||
rewrite(wrapper.passthrough(itemType())); // Result
|
||||
}
|
||||
|
||||
public void handleSmithingTrim(final PacketWrapper wrapper) throws Exception {
|
||||
@@ -135,7 +135,7 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
}
|
||||
|
||||
protected void handleIngredient(final PacketWrapper wrapper) throws Exception {
|
||||
final Item[] items = wrapper.passthrough(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT);
|
||||
final Item[] items = wrapper.passthrough(itemArrayType());
|
||||
for (final Item item : items) {
|
||||
rewrite(item);
|
||||
}
|
||||
@@ -153,4 +153,12 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
|
||||
void accept(PacketWrapper wrapper) throws Exception;
|
||||
}
|
||||
|
||||
protected Type<Item> itemType() {
|
||||
return Type.FLAT_VAR_INT_ITEM;
|
||||
}
|
||||
|
||||
protected Type<Item[]> itemArrayType() {
|
||||
return Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT;
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ public class SoundRewriter<C extends ClientboundPacketType> {
|
||||
this.idRewriter = idRewriter;
|
||||
}
|
||||
|
||||
// The same for entity sound
|
||||
public void registerSound(C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
@@ -48,6 +47,10 @@ public class SoundRewriter<C extends ClientboundPacketType> {
|
||||
});
|
||||
}
|
||||
|
||||
public void registerEntitySound(C packetType) {
|
||||
this.registerSound(packetType);
|
||||
}
|
||||
|
||||
// Not for entity sounds
|
||||
public void register1_19_3Sound(C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
|
||||
@@ -18,11 +18,13 @@
|
||||
package com.viaversion.viaversion.rewriter.meta;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface MetaHandlerEvent {
|
||||
|
||||
/**
|
||||
@@ -39,12 +41,21 @@ public interface MetaHandlerEvent {
|
||||
*/
|
||||
int entityId();
|
||||
|
||||
/**
|
||||
* Returns the tracked entity if present.
|
||||
*
|
||||
* @return tracked entity if present, else null
|
||||
*/
|
||||
@Nullable TrackedEntity trackedEntity();
|
||||
|
||||
/**
|
||||
* Returns the entity type of the entity the metadata belongs to if tracked.
|
||||
*
|
||||
* @return entity type of the entity if tracked, else null
|
||||
*/
|
||||
@Nullable EntityType entityType();
|
||||
default @Nullable EntityType entityType() {
|
||||
return trackedEntity() != null ? trackedEntity().entityType() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the metadata index.
|
||||
@@ -110,6 +121,15 @@ public interface MetaHandlerEvent {
|
||||
*/
|
||||
@Nullable List<Metadata> extraMeta();
|
||||
|
||||
/**
|
||||
* Returns whether additionally created metadata will be added.
|
||||
*
|
||||
* @return true if additionally created metadata is present
|
||||
*/
|
||||
default boolean hasExtraMeta() {
|
||||
return extraMeta() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given metadata to the metadata list.
|
||||
* This metadata will not be passed through handlers of the current loop.
|
||||
|
||||
+8
-7
@@ -19,25 +19,26 @@
|
||||
package com.viaversion.viaversion.rewriter.meta;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
|
||||
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class MetaHandlerEventImpl implements MetaHandlerEvent {
|
||||
private final UserConnection connection;
|
||||
private final EntityType entityType;
|
||||
private final TrackedEntity trackedEntity;
|
||||
private final int entityId;
|
||||
private final List<Metadata> metadataList;
|
||||
private final Metadata meta;
|
||||
private List<Metadata> extraData;
|
||||
private boolean cancel;
|
||||
|
||||
public MetaHandlerEventImpl(UserConnection connection, @Nullable EntityType entityType, int entityId, Metadata meta, List<Metadata> metadataList) {
|
||||
public MetaHandlerEventImpl(UserConnection connection, @Nullable TrackedEntity trackedEntity, int entityId, Metadata meta, List<Metadata> metadataList) {
|
||||
this.connection = connection;
|
||||
this.entityType = entityType;
|
||||
this.trackedEntity = trackedEntity;
|
||||
this.entityId = entityId;
|
||||
this.meta = meta;
|
||||
this.metadataList = metadataList;
|
||||
@@ -54,8 +55,8 @@ public class MetaHandlerEventImpl implements MetaHandlerEvent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable EntityType entityType() {
|
||||
return entityType;
|
||||
public @Nullable TrackedEntity trackedEntity() {
|
||||
return trackedEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
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.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import com.viaversion.viaversion.dump.DumpTemplate;
|
||||
import com.viaversion.viaversion.dump.VersionInfo;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
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.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class DumpUtil {
|
||||
|
||||
/**
|
||||
* Creates a platform dump and posts it to ViaVersion's dump server asychronously.
|
||||
* May complete exceptionally with {@link DumpException}.
|
||||
*
|
||||
* @param playerToSample uuid of the player to include the pipeline of
|
||||
* @return completable future that completes with the url of the dump
|
||||
*/
|
||||
public static CompletableFuture<String> postDump(@Nullable final UUID playerToSample) {
|
||||
final 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(),
|
||||
com.viaversion.viaversion.util.VersionInfo.getImplementationVersion(),
|
||||
Via.getManager().getSubPlatforms()
|
||||
);
|
||||
final Map<String, Object> configuration = Via.getPlatform().getConfigurationProvider().getValues();
|
||||
final DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump(), Via.getManager().getInjector().getDump(), getPlayerSample(playerToSample));
|
||||
final CompletableFuture<String> result = new CompletableFuture<>();
|
||||
Via.getPlatform().runAsync(() -> {
|
||||
final HttpURLConnection con;
|
||||
try {
|
||||
con = (HttpURLConnection) new URL("https://dump.viaversion.com/documents").openConnection();
|
||||
} catch (final IOException e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error when opening connection to ViaVersion dump service", e);
|
||||
result.completeExceptionally(new DumpException(DumpErrorType.CONNECTION, e));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
con.addRequestProperty("User-Agent", "ViaVersion-" + Via.getPlatform().getPlatformName() + "/" + version.getPluginVersion());
|
||||
con.setRequestMethod("POST");
|
||||
con.setDoOutput(true);
|
||||
|
||||
try (final OutputStream out = con.getOutputStream()) {
|
||||
out.write(new GsonBuilder().setPrettyPrinting().create().toJson(template).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
if (con.getResponseCode() == 429) {
|
||||
result.completeExceptionally(new DumpException(DumpErrorType.RATE_LIMITED));
|
||||
return;
|
||||
}
|
||||
|
||||
final String rawOutput;
|
||||
try (final InputStream inputStream = con.getInputStream()) {
|
||||
rawOutput = CharStreams.toString(new InputStreamReader(inputStream));
|
||||
}
|
||||
|
||||
final JsonObject output = GsonUtil.getGson().fromJson(rawOutput, JsonObject.class);
|
||||
if (!output.has("key")) {
|
||||
throw new InvalidObjectException("Key is not given in Hastebin output");
|
||||
}
|
||||
|
||||
result.complete(urlForId(output.get("key").getAsString()));
|
||||
} catch (final Exception e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error when posting ViaVersion dump", e);
|
||||
result.completeExceptionally(new DumpException(DumpErrorType.POST, e));
|
||||
printFailureInfo(con);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void printFailureInfo(final HttpURLConnection connection) {
|
||||
try {
|
||||
if (connection.getResponseCode() < 200 || connection.getResponseCode() > 400) {
|
||||
try (final InputStream errorStream = connection.getErrorStream()) {
|
||||
final String rawOutput = CharStreams.toString(new InputStreamReader(errorStream));
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Page returned: " + rawOutput);
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Failed to capture further info", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String urlForId(final String id) {
|
||||
return String.format("https://dump.viaversion.com/%s", id);
|
||||
}
|
||||
|
||||
private static JsonObject getPlayerSample(@Nullable final UUID uuid) {
|
||||
final JsonObject playerSample = new JsonObject();
|
||||
// Player versions
|
||||
final JsonObject versions = new JsonObject();
|
||||
playerSample.add("versions", versions);
|
||||
final Map<ProtocolVersion, Integer> playerVersions = new TreeMap<>((o1, o2) -> ProtocolVersion.getIndex(o2) - ProtocolVersion.getIndex(o1));
|
||||
for (final UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
||||
final ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(connection.getProtocolInfo().getProtocolVersion());
|
||||
playerVersions.compute(protocolVersion, (v, num) -> num != null ? num + 1 : 1);
|
||||
}
|
||||
for (final Map.Entry<ProtocolVersion, Integer> entry : playerVersions.entrySet()) {
|
||||
versions.addProperty(entry.getKey().getName(), entry.getValue());
|
||||
}
|
||||
|
||||
final Set<List<String>> pipelines = new HashSet<>();
|
||||
if (uuid != null) {
|
||||
// Pipeline of sender
|
||||
final UserConnection senderConnection = Via.getAPI().getConnection(uuid);
|
||||
if (senderConnection != null && senderConnection.getChannel() != null) {
|
||||
pipelines.add(senderConnection.getChannel().pipeline().names());
|
||||
}
|
||||
}
|
||||
|
||||
// Other pipelines if different ones are found (3 max)
|
||||
for (final UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
||||
if (connection.getChannel() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final List<String> names = connection.getChannel().pipeline().names();
|
||||
if (pipelines.add(names) && pipelines.size() == 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (final List<String> pipeline : pipelines) {
|
||||
final JsonArray senderPipeline = new JsonArray(pipeline.size());
|
||||
for (final String name : pipeline) {
|
||||
senderPipeline.add(name);
|
||||
}
|
||||
|
||||
playerSample.add("pipeline-" + i++, senderPipeline);
|
||||
}
|
||||
|
||||
return playerSample;
|
||||
}
|
||||
|
||||
public static final class DumpException extends RuntimeException {
|
||||
private final DumpErrorType errorType;
|
||||
|
||||
private DumpException(final DumpErrorType errorType, final Throwable cause) {
|
||||
super(errorType.message(), cause);
|
||||
this.errorType = errorType;
|
||||
}
|
||||
|
||||
private DumpException(final DumpErrorType errorType) {
|
||||
super(errorType.message());
|
||||
this.errorType = errorType;
|
||||
}
|
||||
|
||||
public DumpErrorType errorType() {
|
||||
return errorType;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DumpErrorType {
|
||||
|
||||
CONNECTION("Failed to dump, please check the console for more information"),
|
||||
RATE_LIMITED("Please wait before creating another dump"),
|
||||
POST("Failed to dump, please check the console for more information");
|
||||
|
||||
private final String message;
|
||||
|
||||
DumpErrorType(final String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ send-supported-versions: false
|
||||
# You can use both this and the block-protocols option at the same time as well.
|
||||
block-versions: []
|
||||
# Block specific Minecraft protocol version numbers.
|
||||
# List of all Minecraft protocol versions: http://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com
|
||||
# List of all Minecraft protocol versions: https://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com
|
||||
block-protocols: []
|
||||
# Change the blocked disconnect message
|
||||
block-disconnect-msg: "You are using an unsupported Minecraft version!"
|
||||
@@ -47,7 +47,7 @@ bungee-ping-save: true
|
||||
#
|
||||
# The format for the following is:
|
||||
# servername: protocolversion
|
||||
# You can find protocol ids on http://wiki.vg/Protocol_version_numbers
|
||||
# You can find protocol ids on https://wiki.vg/Protocol_version_numbers
|
||||
# It will fallback to the default option if none found.
|
||||
bungee-servers: {}
|
||||
#
|
||||
@@ -69,7 +69,7 @@ velocity-ping-save: true
|
||||
#
|
||||
# The format for the following is:
|
||||
# servername: protocolversion
|
||||
# You can find protocol ids on http://wiki.vg/Protocol_version_numbers
|
||||
# You can find protocol ids on https://wiki.vg/Protocol_version_numbers
|
||||
# It will fallback to the default option if none found.
|
||||
velocity-servers: {}
|
||||
#
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7
-1
@@ -1,5 +1,11 @@
|
||||
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
|
||||
projectVersion=4.7.0
|
||||
projectVersion=4.8.0
|
||||
|
||||
# Smile emoji
|
||||
mcVersions=1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
|
||||
mcVersionRange=1.8-1.20.2
|
||||
waterfallVersion=1.20
|
||||
velocityVersion=3.2
|
||||
|
||||
# Gradle properties
|
||||
org.gradle.daemon=true
|
||||
|
||||
@@ -2,7 +2,7 @@ metadata.format.version = "1.1"
|
||||
|
||||
[versions]
|
||||
|
||||
adventure = "4.13.1"
|
||||
adventure = "4.14.0"
|
||||
gson = "2.10.1"
|
||||
fastutil = "8.5.12"
|
||||
flare = "2.0.1"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-1
@@ -1,6 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -83,7 +83,8 @@ done
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -130,10 +131,13 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
|
||||
Vendored
+92
-92
@@ -1,92 +1,92 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user