Compare commits

...
33 Commits
Author SHA1 Message Date
KennyTV b28f743306 4.0.1 Release 2021-07-06 10:31:03 +02:00
KennyTV 9f97a09942 1.17.1-rc2 2021-07-05 14:52:13 +02:00
KennyTV 4f7e655613 1.17.1-rc1 2021-07-01 19:58:34 +02:00
KennyTV a7d94c2f8f 1.17.1-pre3 2021-06-30 18:19:19 +02:00
KennyTV c2172821fd Merge remote-tracking branch 'origin/master' into dev 2021-06-29 18:12:36 +02:00
KennyTV 24393d4ef4 1.17.1-pre2 2021-06-29 18:11:51 +02:00
KennyTV 622ea91648 Ignore bad 1.8 wither meta
Fixes #2570
2021-06-22 11:28:09 +02:00
KennyTV aed1a63a77 Merge remote-tracking branch 'origin/master' into dev 2021-06-21 14:58:38 +02:00
LemonCaramel 14cd568e46 Add Resource pack prompt message option (1.17+) (#2544) 2021-06-21 14:55:49 +02:00
KennyTV 44d836e2e7 Clear entity trackers on server switch
Fixes #5930
2021-06-21 14:33:23 +02:00
_tomcraft f9af6947f7 Improve arm-swing cancel by resetting cursor item (#2528) 2021-06-20 22:50:37 +02:00
_tomcraft 8e1da82793 Use a more fork-proof approach to enable Paper block place patch (#2561) 2021-06-20 22:49:59 +02:00
KennyTV 860aca974b Read unsigned byte in set slot 2021-06-20 16:16:08 +02:00
KennyTV 6a66d7653f Fix writable book id 2021-06-20 16:16:07 +02:00
KennyTV d32a4541a9 1.17.1-pre1 2021-06-20 16:16:07 +02:00
KennyTV 26719169ee Fix 1.8 special inventory tracking 2021-06-20 16:15:48 +02:00
KennyTV eae145543e Fix 1.8 set slot write type
Fixes #2558
2021-06-19 15:35:43 +02:00
KennyTV 48f1300908 Read set slot inv id as unsigned byte for consistency 2021-06-18 16:59:34 +02:00
KennyTV 5cdaabeaec Handle particle id change in 1.16 metadata
Fixes #2551
2021-06-17 11:55:22 +02:00
KennyTV 40f87e9472 Update Gradle wrapper to 7.1 2021-06-16 09:12:23 +02:00
KennyTV 7f385d4762 Create concurrent hashmap with weak values with Guava
This could use Guava's Cache, but that's just the MapMaker but more
2021-06-15 09:59:23 +02:00
KennyTV 389c5adaa3 Half revert back to storing uuids in CommonBoss
Fixes #2547
2021-06-14 22:47:13 +02:00
KennyTV 7a82ded94b Fix Velocity compatibility (requires Velocity 3.0.0)
This finally removes the hacky reorder fix on Velocity; it added a few more events that could benefit us, but this is the most important right now.
2021-06-14 21:09:47 +02:00
Myles 86278e837a Fix 1.17 BungeeCord support 2021-06-14 19:46:25 +01:00
KennyTV 34a0499152 Update bug_report.yml 2021-06-14 10:59:01 +02:00
Myles 68ccc6634d Spigot 1.17 compatibility 2021-06-11 20:19:06 +01:00
Jo0001 317af7ebc5 Use the correct content-type header (#2527) 2021-06-10 22:15:14 +02:00
KennyTV 206368b777 Fix 1.12->1.13 entity tracking
Fixes #2526
2021-06-10 22:10:22 +02:00
KennyTV 204a81b0ea Add 1.17 to legacy api package ProtocolVersion 2021-06-10 10:50:07 +02:00
KennyTV b940ecab9c Fix meta warning 2021-06-10 08:42:52 +02:00
KennyTV 15cbc96697 Shorten metadata error message 2021-06-09 18:59:48 +02:00
KennyTV b5e5b46f77 Update adventure to 4.8.0 release 2021-06-08 19:07:09 +02:00
KennyTV 42b6a1378c Bump to 4.0.1-SNAPSHOT 2021-06-08 19:06:08 +02:00
69 changed files with 822 additions and 570 deletions

No files matched your search

+1
View File
@@ -1,5 +1,6 @@
name: Bug Report
description: Report a bug or console error
labels: [Unconfirmed]
body:
- type: markdown
@@ -79,6 +79,8 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_16_2 = register(751, "1.16.2");
public static final ProtocolVersion v1_16_3 = register(753, "1.16.3");
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/5", new VersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_17 = register(755, "1.17");
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.configuration;
import com.google.gson.JsonElement;
import it.unimi.dsi.fastutil.ints.IntSet;
public interface ViaVersionConfig {
@@ -414,4 +415,11 @@ public interface ViaVersionConfig {
* @return true if enabled
*/
boolean isForcedUse1_17ResourcePack();
/**
* Get the message that is sent when a user displays a resource pack prompt.
*
* @return cached serialized component
*/
JsonElement get1_17ResourcePackPrompt();
}
@@ -90,8 +90,8 @@ public interface UserConnection {
void addEntityTracker(Class<? extends Protocol> protocolClass, EntityTracker tracker);
/**
* Clear all the stored objects.
* Used for bungee when switching servers.
* Clear stored objects and entity trackers.
* Used for Bungee when switching servers.
*/
void clearStoredObjects();
@@ -58,7 +58,7 @@ public class BlockChangeRecord1_16_2 implements BlockChangeRecord {
@Override
public short getY(int chunkSectionY) {
Preconditions.checkArgument(chunkSectionY >= 0 && chunkSectionY < 16, "Invalid chunkSectionY: " + chunkSectionY);
Preconditions.checkArgument(chunkSectionY >= 0, "Invalid chunkSectionY: " + chunkSectionY);
return (short) ((chunkSectionY << 4) + sectionY);
}
@@ -0,0 +1,72 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.version.Types1_16;
public enum MetaType1_16 implements MetaType {
BYTE(0, Type.BYTE),
VAR_INT(1, Type.VAR_INT),
FLOAT(2, Type.FLOAT),
STRING(3, Type.STRING),
COMPONENT(4, Type.COMPONENT),
OPT_COMPONENT(5, Type.OPTIONAL_COMPONENT),
ITEM(6, Type.FLAT_VAR_INT_ITEM),
BOOLEAN(7, Type.BOOLEAN),
ROTATION(8, Type.ROTATION),
POSITION(9, Type.POSITION1_14),
OPT_POSITION(10, Type.OPTIONAL_POSITION_1_14),
DIRECTION(11, Type.VAR_INT),
OPT_UUID(12, Type.OPTIONAL_UUID),
BLOCK_STATE(13, Type.VAR_INT),
NBT(14, Type.NBT),
PARTICLE(15, Types1_16.PARTICLE),
VILLAGER_DATA(16, Type.VILLAGER_DATA),
OPT_VAR_INT(17, Type.OPTIONAL_VAR_INT),
POSE(18, Type.VAR_INT);
private static final MetaType1_16[] VALUES = values();
private final int typeId;
private final Type type;
MetaType1_16(int typeId, Type type) {
this.typeId = typeId;
this.type = type;
}
public static MetaType1_16 byId(int id) {
return VALUES[id];
}
@Override
public int typeId() {
return typeId;
}
@Override
public Type type() {
return type;
}
}
@@ -77,6 +77,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_16_3 = register(753, "1.16.3");
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/5", new VersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_17 = register(755, "1.17");
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -32,17 +32,22 @@ public abstract class PartialType<T, X> extends Type<T> {
this.param = param;
}
protected PartialType(X param, String name, Class<T> type) {
super(name, type);
this.param = param;
}
public abstract T read(ByteBuf buffer, X param) throws Exception;
public abstract void write(ByteBuf buffer, X param, T object) throws Exception;
@Override
public T read(ByteBuf buffer) throws Exception {
public final T read(ByteBuf buffer) throws Exception {
return read(buffer, this.param);
}
@Override
public void write(ByteBuf buffer, T object) throws Exception {
public final void write(ByteBuf buffer, T object) throws Exception {
write(buffer, this.param, object);
}
}
@@ -0,0 +1,115 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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.Via;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public abstract class AbstractParticleType extends Type<Particle> {
protected final Int2ObjectMap<ParticleReader> readers = new Int2ObjectOpenHashMap<>();
protected AbstractParticleType() {
super("Particle", Particle.class);
}
@Override
public void write(ByteBuf buffer, Particle object) throws Exception {
Type.VAR_INT.writePrimitive(buffer, object.getId());
for (Particle.ParticleData data : object.getArguments()) {
data.getType().write(buffer, data.getValue());
}
}
@Override
public Particle read(ByteBuf buffer) throws Exception {
int type = Type.VAR_INT.readPrimitive(buffer);
Particle particle = new Particle(type);
ParticleReader reader = readers.get(type);
if (reader != null) {
reader.read(buffer, particle);
}
return particle;
}
protected ParticleReader blockHandler() {
return (buf, particle) -> {
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf))); // Flat Block
};
}
protected ParticleReader itemHandler(Type<Item> itemType) {
return (buf, particle) -> {
particle.getArguments().add(new Particle.ParticleData(itemType, itemType.read(buf))); // Flat item;
};
}
protected ParticleReader dustHandler() {
return (buf, particle) -> {
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Red 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Green 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Blue 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Scale 0.01 - 4
};
}
protected ParticleReader dustTransitionHandler() {
return (buf, particle) -> {
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Red 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Green 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Blue 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Scale 0.01 - 4
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Red
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Green
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buf))); // Blue
};
}
protected ParticleReader vibrationHandler(Type<Position> positionType) {
return (buf, particle) -> {
particle.getArguments().add(new Particle.ParticleData(positionType, positionType.read(buf))); // From block pos
String resourceLocation = Type.STRING.read(buf);
if (resourceLocation.equals("block")) {
particle.getArguments().add(new Particle.ParticleData(positionType, positionType.read(buf))); // Target block pos
} else if (resourceLocation.equals("entity")) {
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf))); // Target entity
} else {
Via.getPlatform().getLogger().warning("Unknown vibration path position source type: " + resourceLocation);
}
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf))); // Arrival in ticks
};
}
@FunctionalInterface
public interface ParticleReader {
void read(ByteBuf buf, Particle particle) throws Exception;
}
}
@@ -20,15 +20,22 @@
* 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;
package com.viaversion.viaversion.api.type.types.minecraft;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaListType;
public class MetadataList1_13_2Type extends ModernMetaListType {
public final class MetaListType extends ModernMetaListType {
private final Type<Metadata> type;
public MetaListType(Type<Metadata> type) {
Preconditions.checkNotNull(type);
this.type = type;
}
@Override
protected Type<Metadata> getType() {
return Types1_13_2.METADATA;
return type;
}
}
@@ -26,7 +26,7 @@ import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
public abstract class MetaTypeTemplate extends Type<Metadata> {
public MetaTypeTemplate() {
protected MetaTypeTemplate() {
super("Metadata type", Metadata.class);
}
@@ -23,45 +23,13 @@
package com.viaversion.viaversion.api.type.types.minecraft;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import io.netty.buffer.ByteBuf;
public class Particle1_13Type extends Type<Particle> {
public class Particle1_13Type extends AbstractParticleType {
public Particle1_13Type() {
super("Particle", Particle.class);
}
@Override
public void write(ByteBuf buffer, Particle object) throws Exception {
Type.VAR_INT.writePrimitive(buffer, object.getId());
for (Particle.ParticleData data : object.getArguments())
data.getType().write(buffer, data.getValue());
}
@Override
public Particle read(ByteBuf buffer) throws Exception {
int type = Type.VAR_INT.readPrimitive(buffer);
Particle particle = new Particle(type);
switch (type) {
// Block / Falling Dust /
case 3:
case 20:
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buffer))); // Flat Block
break;
// Dust
case 11:
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Red 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Green 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Blue 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer)));// Scale 0.01 - 4
break;
// Item
case 27:
particle.getArguments().add(new Particle.ParticleData(Type.FLAT_ITEM, Type.FLAT_ITEM.read(buffer))); // Flat item
break;
}
return particle;
readers.put(3, blockHandler());
readers.put(20, blockHandler());
readers.put(11, dustHandler());
readers.put(27, itemHandler(Type.FLAT_ITEM));
}
}
@@ -23,46 +23,13 @@
package com.viaversion.viaversion.api.type.types.minecraft;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import io.netty.buffer.ByteBuf;
public class Particle1_14Type extends Type<Particle> {
public class Particle1_14Type extends AbstractParticleType {
public Particle1_14Type() {
super("Particle", Particle.class);
}
@Override
public void write(ByteBuf buffer, Particle object) throws Exception {
Type.VAR_INT.writePrimitive(buffer, object.getId());
for (Particle.ParticleData data : object.getArguments())
data.getType().write(buffer, data.getValue());
}
@Override
public Particle read(ByteBuf buffer) throws Exception {
int type = Type.VAR_INT.readPrimitive(buffer);
Particle particle = new Particle(type);
switch (type) {
// Block / Falling Dust /
case 3:
case 23:
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buffer))); // Flat Block
break;
// Dust
case 14:
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Red 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Green 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Blue 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer)));// Scale 0.01 - 4
break;
// Item
case 32:
particle.getArguments().add(new Particle.ParticleData(Type.FLAT_VAR_INT_ITEM, Type.FLAT_VAR_INT_ITEM.read(buffer))); // Flat item
break;
}
return particle;
readers.put(3, blockHandler());
readers.put(23, blockHandler());
readers.put(14, dustHandler());
readers.put(32, itemHandler(Type.FLAT_VAR_INT_ITEM));
}
}
@@ -20,15 +20,16 @@
* 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;
package com.viaversion.viaversion.api.type.types.minecraft;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaListType;
public class MetadataList1_9Type extends ModernMetaListType {
@Override
protected Type<Metadata> getType() {
return Types1_9.METADATA;
public class Particle1_16Type extends AbstractParticleType {
public Particle1_16Type() {
readers.put(3, blockHandler());
readers.put(23, blockHandler());
readers.put(14, dustHandler());
readers.put(34, itemHandler(Type.FLAT_VAR_INT_ITEM));
}
}
@@ -22,64 +22,17 @@
*/
package com.viaversion.viaversion.api.type.types.minecraft;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import io.netty.buffer.ByteBuf;
public class Particle1_17Type extends Type<Particle> {
public class Particle1_17Type extends AbstractParticleType {
public Particle1_17Type() {
super("Particle", Particle.class);
}
@Override
public void write(ByteBuf buffer, Particle object) throws Exception {
Type.VAR_INT.writePrimitive(buffer, object.getId());
for (Particle.ParticleData data : object.getArguments()) {
data.getType().write(buffer, data.getValue());
}
}
@Override
public Particle read(ByteBuf buffer) throws Exception {
int type = Type.VAR_INT.readPrimitive(buffer);
Particle particle = new Particle(type);
switch (type) {
case 3: // Block
case 24: // Falling dust
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buffer))); // Flat Block
break;
case 14: // Dust
case 15: // Dust transition
particle.getArguments().add(new Particle.ParticleData(Type.DOUBLE, Type.DOUBLE.readPrimitive(buffer))); // Red 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.DOUBLE, Type.DOUBLE.readPrimitive(buffer))); // Green 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.DOUBLE, Type.DOUBLE.readPrimitive(buffer))); // Blue 0 - 1
particle.getArguments().add(new Particle.ParticleData(Type.FLOAT, Type.FLOAT.readPrimitive(buffer))); // Scale 0.01 - 4
if (type == 15) {
// Transition to color
particle.getArguments().add(new Particle.ParticleData(Type.DOUBLE, Type.DOUBLE.readPrimitive(buffer))); // Red
particle.getArguments().add(new Particle.ParticleData(Type.DOUBLE, Type.DOUBLE.readPrimitive(buffer))); // Green
particle.getArguments().add(new Particle.ParticleData(Type.DOUBLE, Type.DOUBLE.readPrimitive(buffer))); // Blue
}
break;
case 33: // Item
particle.getArguments().add(new Particle.ParticleData(Type.FLAT_VAR_INT_ITEM, Type.FLAT_VAR_INT_ITEM.read(buffer))); // Flat item
break;
case 36: // Vibration path
particle.getArguments().add(new Particle.ParticleData(Type.POSITION1_14, Type.POSITION1_14.read(buffer))); // From block pos
String resourceLocation = Type.STRING.read(buffer);
if (resourceLocation.equals("block")) {
particle.getArguments().add(new Particle.ParticleData(Type.POSITION1_14, Type.POSITION1_14.read(buffer))); // Target block pos
} else if (resourceLocation.equals("entity")) {
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buffer))); // Target entity
} else {
Via.getPlatform().getLogger().warning("Unknown vibration path position source type: " + resourceLocation);
}
particle.getArguments().add(new Particle.ParticleData(Type.VAR_INT, Type.VAR_INT.readPrimitive(buffer))); // Arrival in ticks
}
return particle;
readers.put(4, blockHandler());
readers.put(25, blockHandler());
readers.put(15, dustHandler());
readers.put(16, dustTransitionHandler());
readers.put(36, itemHandler(Type.FLAT_VAR_INT_ITEM));
readers.put(37, vibrationHandler(Type.POSITION1_14));
}
}
@@ -22,14 +22,14 @@
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaListType;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_16;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaType;
public class MetadataList1_17Type extends ModernMetaListType {
public class Metadata1_16Type extends ModernMetaType {
@Override
protected Type<Metadata> getType() {
return Types1_17.METADATA;
protected MetaType getType(final int index) {
return MetaType1_16.byId(index);
}
}
@@ -1,34 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaListType;
public class MetadataList1_12Type extends ModernMetaListType {
@Override
protected Type<Metadata> getType() {
return Types1_12.METADATA;
}
}
@@ -1,34 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaListType;
public class MetadataList1_13Type extends ModernMetaListType {
@Override
protected Type<Metadata> getType() {
return Types1_13.METADATA;
}
}
@@ -1,34 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ModernMetaListType;
public class MetadataList1_14Type extends ModernMetaListType {
@Override
protected Type<Metadata> getType() {
return Types1_14.METADATA;
}
}
@@ -24,17 +24,18 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import java.util.List;
public class Types1_12 {
/**
* Metadata list type for 1.12
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_12Type();
/**
* Metadata type for 1.12
*/
public static final Type<Metadata> METADATA = new Metadata1_12Type();
/**
* Metadata list type for 1.12
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
}
@@ -26,20 +26,20 @@ import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.Particle1_13Type;
import java.util.List;
public class Types1_13 {
/**
* Metadata list type for 1.13
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_13Type();
/**
* Metadata type for 1.13
*/
public static final Type<Metadata> METADATA = new Metadata1_13Type();
/**
* Metadata list type for 1.13
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_13();
@@ -25,20 +25,21 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.Particle1_13_2Type;
import java.util.List;
public class Types1_13_2 {
/**
* Metadata list type for 1.13
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_13_2Type();
/**
* Metadata type for 1.13
*/
public static final Type<Metadata> METADATA = new Metadata1_13_2Type();
/**
* Metadata list type for 1.13
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
/**
* Particle type for 1.13.2
@@ -25,20 +25,21 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.Particle1_14Type;
import java.util.List;
public class Types1_14 {
/**
* Metadata list type for 1.14
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_14Type();
public final class Types1_14 {
/**
* Metadata type for 1.14
*/
public static final Type<Metadata> METADATA = new Metadata1_14Type();
/**
* Metadata list type for 1.14
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
/**
* Particle type for 1.14
@@ -23,12 +23,22 @@
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.Particle1_16Type;
public class Types1_16 {
import java.util.List;
public final class Types1_16 {
/**
* Chunk section type for 1.16
*/
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_16();
public static final Type<Metadata> METADATA = new Metadata1_16Type();
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
public static final Type<Particle> PARTICLE = new Particle1_16Type();
}
@@ -25,13 +25,14 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.Particle1_17Type;
import java.util.List;
public class Types1_17 {
public final class Types1_17 {
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_17Type();
public static final Type<Metadata> METADATA = new Metadata1_17Type();
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
public static final Type<Particle> PARTICLE = new Particle1_17Type();
}
@@ -29,15 +29,15 @@ import com.viaversion.viaversion.api.type.Type;
import java.util.List;
public class Types1_8 {
/**
* Metadata list type for 1.8
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_8Type();
/**
* Metadata type for 1.8
*/
public static final Type<Metadata> METADATA = new Metadata1_8Type();
/**
* Metadata list type for 1.8
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_8Type();
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_8();
}
@@ -25,19 +25,19 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import java.util.List;
public class Types1_9 {
/**
* Metadata list type for 1.9
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetadataList1_9Type();
/**
* Metadata type for 1.9
*/
public static final Type<Metadata> METADATA = new Metadata1_9Type();
/**
* Metadata list type for 1.9
*/
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
public static final Type<ChunkSection> CHUNK_SECTION = new ChunkSectionType1_9();
}
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -43,18 +44,20 @@ public class PaperPatch extends ViaBukkitListener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlace(BlockPlaceEvent e) {
if (isOnPipe(e.getPlayer())) {
Location location = e.getPlayer().getLocation();
Location diff = location.clone().subtract(e.getBlock().getLocation().add(0.5D, 0, 0.5D));
Material block = e.getBlockPlaced().getType();
if (isPlacable(block)) {
return;
}
if (location.getBlock().equals(e.getBlock())) {
Location location = e.getPlayer().getLocation();
Block locationBlock = location.getBlock();
if (locationBlock.equals(e.getBlock())) {
e.setCancelled(true);
} else {
if (location.getBlock().getRelative(BlockFace.UP).equals(e.getBlock())) {
if (locationBlock.getRelative(BlockFace.UP).equals(e.getBlock())) {
e.setCancelled(true);
} else {
Location diff = location.clone().subtract(e.getBlock().getLocation().add(0.5D, 0, 0.5D));
// Within radius of block
if (Math.abs(diff.getX()) <= 0.8 && Math.abs(diff.getZ()) <= 0.8D) {
// Are they on the edge / shifting ish
@@ -109,7 +109,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
// Check if it's a spigot build with a protocol mod
try {
NMSUtil.nms("PacketEncoder").getDeclaredField("version");
NMSUtil.nms(
"PacketEncoder",
"net.minecraft.network.PacketEncoder"
).getDeclaredField("version");
compatSpigotBuild = true;
} catch (Exception e) {
compatSpigotBuild = false;
@@ -65,8 +65,8 @@ public class ClassGenerator {
}
if (ViaVersionPlugin.getInstance().isCompatSpigotBuild()) {
Class decodeSuper = NMSUtil.nms("PacketDecoder");
Class encodeSuper = NMSUtil.nms("PacketEncoder");
Class decodeSuper = NMSUtil.nms("PacketDecoder", "net.minecraft.network.PacketDecoder");
Class encodeSuper = NMSUtil.nms("PacketEncoder", "net.minecraft.network.PacketEncoder");
// Generate the classes
addSpigotCompatibility(pool, BukkitDecodeHandler.class, decodeSuper);
addSpigotCompatibility(pool, BukkitEncodeHandler.class, encodeSuper);
@@ -209,7 +209,10 @@ public class ClassGenerator {
pool.importPackage("protocolsupport.api.Connection.PacketListener");
pool.importPackage("protocolsupport.api.Connection.PacketListener.PacketEvent");
pool.importPackage("protocolsupport.protocol.ConnectionImpl");
pool.importPackage(NMSUtil.nms("PacketHandshakingInSetProtocol").getName());
pool.importPackage(NMSUtil.nms(
"PacketHandshakingInSetProtocol",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol"
).getName());
// Add connection reference field
connectListenerClazz.addField(CtField.make("private ConnectionImpl connection;", connectListenerClazz));
// Bake constructor
@@ -303,7 +306,10 @@ public class ClassGenerator {
public static boolean shouldUseNewHandshakeVersionMethod() {
try {
NMSUtil.nms("PacketHandshakingInSetProtocol").getMethod("getProtocolVersion");
NMSUtil.nms(
"PacketHandshakingInSetProtocol",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol"
).getMethod("getProtocolVersion");
return true;
} catch (Exception e) {
return false;
@@ -39,7 +39,12 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaCode
static {
try {
versionField = NMSUtil.nms("PacketEncoder").getDeclaredField("version");
// Attempt to get any version info from the handler
versionField = NMSUtil.nms(
"PacketEncoder",
"net.minecraft.network.PacketEncoder"
).getDeclaredField("version");
versionField.setAccessible(true);
} catch (Exception e) {
// Not compat version
@@ -204,9 +204,15 @@ public class BukkitViaInjector implements ViaInjector {
}
try {
Class<?> serverClazz = NMSUtil.nms("MinecraftServer");
// Grab a static instance of the server
Class<?> serverClazz = NMSUtil.nms("MinecraftServer", "net.minecraft.server.MinecraftServer");
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
Class<?> pingClazz = NMSUtil.nms("ServerPing");
// Grab the ping class and find the field to access it
Class<?> pingClazz = NMSUtil.nms(
"ServerPing",
"net.minecraft.network.protocol.status.ServerPing"
);
Object ping = null;
// Search for ping method
for (Field f : serverClazz.getDeclaredFields()) {
@@ -259,7 +265,10 @@ public class BukkitViaInjector implements ViaInjector {
}
public static Object getServerConnection() throws Exception {
Class<?> serverClazz = NMSUtil.nms("MinecraftServer");
Class<?> serverClazz = NMSUtil.nms(
"MinecraftServer",
"net.minecraft.server.MinecraftServer"
);
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
Object connection = null;
for (Method m : serverClazz.getDeclaredMethods()) {
@@ -117,11 +117,20 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
}
if ((Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("paper")
|| Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("taco")
|| Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("torch"))
&& serverProtocolVersion < ProtocolVersion.v1_12.getVersion()) {
storeListener(new PaperPatch(plugin)).register();
if (serverProtocolVersion < ProtocolVersion.v1_12.getVersion() && !Boolean.getBoolean("com.viaversion.ignorePaperBlockPlacePatch")) {
boolean paper = true;
try {
Class.forName("org.github.paperspigot.PaperSpigotConfig"); // Paper 1.8 ?
} catch (ClassNotFoundException ignored) {
try {
Class.forName("com.destroystokyo.paper.PaperConfig"); // Paper 1.9+ ?
} catch (ClassNotFoundException alsoIgnored) {
paper = false; // Definitely not Paper
}
}
if (paper) {
storeListener(new PaperPatch(plugin)).register();
}
}
/* Providers */
@@ -26,7 +26,10 @@ public class NMSUtil {
private static boolean loadDebugProperty() {
try {
Class<?> serverClass = nms("MinecraftServer");
Class<?> serverClass = nms(
"MinecraftServer",
"net.minecraft.server.MinecraftServer"
);
Object server = serverClass.getDeclaredMethod("getServer").invoke(null);
return (boolean) serverClass.getMethod("isDebugging").invoke(server);
} catch (ReflectiveOperationException e) {
@@ -38,6 +41,14 @@ public class NMSUtil {
return Class.forName(NMS + "." + className);
}
public static Class<?> nms(String className, String fallbackFullClassName) throws ClassNotFoundException {
try {
return Class.forName(NMS + "." + className);
} catch (ClassNotFoundException ignored) {
return Class.forName(fallbackFullClassName);
}
}
public static Class<?> obc(String className) throws ClassNotFoundException {
return Class.forName(BASE + "." + className);
}
@@ -56,7 +56,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
@Override
public void onLoad() {
try {
ProtocolConstants.class.getField("MINECRAFT_1_16_4");
ProtocolConstants.class.getField("MINECRAFT_1_17");
} catch (NoSuchFieldException e) {
getLogger().warning(" / \\");
getLogger().warning(" / \\");
@@ -70,11 +70,17 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
// Need to decompress this packet due to bad order
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, buf);
try {
buf.clear().writeBytes(decompressed);
} finally {
decompressed.release();
// Ensure the buffer wasn't reused
if (buf != decompressed) {
try {
buf.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
}
// Reorder the pipeline
ChannelHandler dec = ctx.pipeline().get("via-decoder");
ChannelHandler enc = ctx.pipeline().get("via-encoder");
ctx.pipeline().remove(dec);
@@ -80,7 +80,7 @@ public class DumpSubCmd extends ViaSubCommand {
return;
}
try {
con.setRequestProperty("Content-Type", "text/plain");
con.setRequestProperty("Content-Type", "application/json");
con.addRequestProperty("User-Agent", "ViaVersion/" + version.getPluginVersion());
con.setRequestMethod("POST");
con.setDoOutput(true);
@@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.configuration;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.util.Config;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
@@ -75,6 +76,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
private boolean instantRespawn;
private boolean ignoreLongChannelNames;
private boolean forcedUse1_17ResourcePack;
private JsonElement resourcePack1_17PromptMessage;
protected AbstractViaConfig(File configFile) {
super(configFile);
@@ -136,6 +138,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
instantRespawn = getBoolean("use-1_15-instant-respawn", false);
ignoreLongChannelNames = getBoolean("ignore-long-1_16-channel-names", true);
forcedUse1_17ResourcePack = getBoolean("forced-use-1_17-resource-pack", false);
resourcePack1_17PromptMessage = getSerializedComponent("resource-pack-1_17-prompt");
}
@Override
@@ -414,4 +417,9 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
public boolean isForcedUse1_17ResourcePack() {
return forcedUse1_17ResourcePack;
}
@Override
public JsonElement get1_17ResourcePackPrompt() {
return resourcePack1_17PromptMessage;
}
}
@@ -114,6 +114,7 @@ public class UserConnectionImpl implements UserConnection {
@Override
public void clearStoredObjects() {
storedObjects.clear();
entityTrackers.clear();
}
@Override
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.legacy.bossbar;
import com.google.common.base.Preconditions;
import com.google.common.collect.MapMaker;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.legacy.bossbar.BossBar;
@@ -32,15 +33,13 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.stream.Collectors;
public class CommonBoss implements BossBar {
private final UUID uuid;
private final Set<UserConnection> connections;
private final Map<UUID, UserConnection> connections;
private final Set<BossFlag> flags;
private String title;
private float health;
@@ -57,9 +56,9 @@ public class CommonBoss implements BossBar {
this.health = health;
this.color = color == null ? BossColor.PURPLE : color;
this.style = style == null ? BossStyle.SOLID : style;
this.connections = Collections.newSetFromMap(new WeakHashMap<>());
this.connections = new MapMaker().weakValues().makeMap();
this.flags = new HashSet<>();
visible = true;
this.visible = true;
}
@Override
@@ -101,12 +100,16 @@ public class CommonBoss implements BossBar {
@Override
public BossBar addPlayer(UUID player) {
return addConnection(Via.getManager().getConnectionManager().getConnectedClient(player));
UserConnection client = Via.getManager().getConnectionManager().getConnectedClient(player);
if (client != null) {
addConnection(client);
}
return this;
}
@Override
public BossBar addConnection(UserConnection conn) {
if (connections.add(conn) && visible) {
if (connections.put(conn.getProtocolInfo().getUuid(), conn) == null && visible) {
sendPacketConnection(conn, getPacket(CommonBoss.UpdateAction.ADD, conn));
}
return this;
@@ -114,14 +117,16 @@ public class CommonBoss implements BossBar {
@Override
public BossBar removePlayer(UUID uuid) {
return removeConnection(Via.getManager().getConnectionManager().getConnectedClient(uuid));
UserConnection client = connections.remove(uuid);
if (client != null) {
sendPacketConnection(client, getPacket(UpdateAction.REMOVE, client));
}
return this;
}
@Override
public BossBar removeConnection(UserConnection conn) {
if (connections.remove(conn)) {
sendPacketConnection(conn, getPacket(UpdateAction.REMOVE, conn));
}
removePlayer(conn.getProtocolInfo().getUuid());
return this;
}
@@ -153,13 +158,12 @@ public class CommonBoss implements BossBar {
@Override
public Set<UUID> getPlayers() {
return connections.stream().map(conn -> Via.getManager().getConnectionManager().getConnectedClientId(conn)).filter(Objects::nonNull)
.collect(Collectors.toSet());
return Collections.unmodifiableSet(connections.keySet());
}
@Override
public Set<UserConnection> getConnections() {
return Collections.unmodifiableSet(connections);
return Collections.unmodifiableSet(new HashSet<>(connections.values()));
}
@Override
@@ -215,7 +219,7 @@ public class CommonBoss implements BossBar {
}
private void sendPacket(UpdateAction action) {
for (UserConnection conn : new ArrayList<>(connections)) {
for (UserConnection conn : new ArrayList<>(connections.values())) {
PacketWrapper wrapper = getPacket(action, conn);
sendPacketConnection(conn, wrapper);
}
@@ -223,7 +227,7 @@ public class CommonBoss implements BossBar {
private void sendPacketConnection(UserConnection conn, PacketWrapper wrapper) {
if (conn.getProtocolInfo() == null || !conn.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
connections.remove(conn);
connections.remove(conn.getProtocolInfo().getUuid());
return;
}
try {
@@ -57,6 +57,7 @@ import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2
import com.viaversion.viaversion.protocols.protocol1_16_3to1_16_2.Protocol1_16_3To1_16_2;
import com.viaversion.viaversion.protocols.protocol1_16_4to1_16_3.Protocol1_16_4To1_16_3;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.Protocol1_17_1To1_17;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_16_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;
@@ -160,6 +161,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_16_4To1_16_3(), ProtocolVersion.v1_16_4, ProtocolVersion.v1_16_3);
registerProtocol(new Protocol1_17To1_16_4(), ProtocolVersion.v1_17, ProtocolVersion.v1_16_4);
registerProtocol(new Protocol1_17_1To1_17(), ProtocolVersion.v1_17_1, ProtocolVersion.v1_17);
}
@Override
@@ -31,7 +31,7 @@ public class InventoryPackets {
protocol.registerClientbound(ClientboundPackets1_13.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); // 2 - Slot Value
}
@@ -53,39 +53,38 @@ public class EntityPackets {
int entityId = wrapper.get(Type.VAR_INT, 0);
byte type = wrapper.get(Type.BYTE, 0);
Entity1_13Types.EntityType entType = Entity1_13Types.getTypeFromId(type, true);
if (entType == null) return;
if (entType != null) {
if (entType.is(Entity1_13Types.EntityType.FALLING_BLOCK)) {
int oldId = wrapper.get(Type.INT, 0);
int combined = (((oldId & 4095) << 4) | (oldId >> 12 & 15));
wrapper.set(Type.INT, 0, WorldPackets.toNewId(combined));
// Register Type ID
wrapper.user().getEntityTracker(Protocol1_13To1_12_2.class).addEntity(entityId, entType);
if (entType.is(Entity1_13Types.EntityType.FALLING_BLOCK)) {
int oldId = wrapper.get(Type.INT, 0);
int combined = (((oldId & 4095) << 4) | (oldId >> 12 & 15));
wrapper.set(Type.INT, 0, WorldPackets.toNewId(combined));
}
// Fix ItemFrame hitbox
if (entType.is(Entity1_13Types.EntityType.ITEM_FRAME)) {
int data = wrapper.get(Type.INT, 0);
switch (data) {
// South
case 0:
data = 3;
break;
// West
case 1:
data = 4;
break;
// North is the same
// East
case 3:
data = 5;
break;
}
// Fix ItemFrame hitbox
if (entType.is(Entity1_13Types.EntityType.ITEM_FRAME)) {
int data = wrapper.get(Type.INT, 0);
switch (data) {
// South
case 0:
data = 3;
break;
// West
case 1:
data = 4;
break;
// North is the same
// East
case 3:
data = 5;
break;
}
wrapper.set(Type.INT, 0, data);
// Register Type ID
wrapper.user().getEntityTracker(Protocol1_13To1_12_2.class).addEntity(entityId, entType);
}
wrapper.set(Type.INT, 0, data);
}
}
});
@@ -61,7 +61,7 @@ public class InventoryPackets extends ItemRewriter<Protocol1_13To1_12_2> {
protocol.registerClientbound(ClientboundPackets1_12_1.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM, Type.FLAT_ITEM); // 2 - Slot Value
@@ -22,7 +22,7 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_16_2Types;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.api.type.types.version.Types1_16;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.metadata.MetadataRewriter1_16_2To1_16_1;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
@@ -34,7 +34,7 @@ public class EntityPackets {
metadataRewriter.registerTrackerWithData(ClientboundPackets1_16.SPAWN_ENTITY, Entity1_16_2Types.FALLING_BLOCK);
metadataRewriter.registerTracker(ClientboundPackets1_16.SPAWN_MOB);
metadataRewriter.registerTracker(ClientboundPackets1_16.SPAWN_PLAYER, Entity1_16_2Types.PLAYER);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_16.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_16.ENTITY_METADATA, Types1_16.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_16.DESTROY_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_16.JOIN_GAME, new PacketRemapper() {
@@ -39,7 +39,6 @@ import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.metadata.Metadat
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.rewriter.SoundRewriter;
@@ -276,7 +275,6 @@ public class Protocol1_16To1_15_2 extends AbstractProtocol<ClientboundPackets1_1
@Override
public void init(UserConnection userConnection) {
userConnection.addEntityTracker(this.getClass(), new EntityTrackerBase(userConnection, Entity1_16Types.PLAYER));
userConnection.put(new InventoryTracker1_16());
}
@Override
@@ -26,16 +26,16 @@ import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_16Types;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.api.type.types.version.Types1_16;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ServerboundPackets1_16;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.metadata.MetadataRewriter1_16To1_15_2;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
import java.util.UUID;
@@ -174,7 +174,7 @@ public class EntityPackets {
metadataRewriter.registerTrackerWithData(ClientboundPackets1_15.SPAWN_ENTITY, Entity1_16Types.FALLING_BLOCK);
metadataRewriter.registerTracker(ClientboundPackets1_15.SPAWN_MOB);
metadataRewriter.registerTracker(ClientboundPackets1_15.SPAWN_PLAYER, Entity1_16Types.PLAYER);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_15.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_15.ENTITY_METADATA, Types1_14.METADATA_LIST, Types1_16.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_15.DESTROY_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_15.RESPAWN, new PacketRemapper() {
@@ -266,18 +266,5 @@ public class EntityPackets {
});
}
});
protocol.registerServerbound(ServerboundPackets1_16.ANIMATION, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
// Don't send an arm swing if the player is switching between inventories.
if (inventoryTracker.getInventory() != -1) {
wrapper.cancel();
}
});
}
});
}
}
@@ -25,14 +25,16 @@ import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.UUIDIntArrayType;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.data.RecipeRewriter1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ServerboundPackets1_16;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import java.util.UUID;
@@ -45,6 +47,15 @@ public class InventoryPackets extends ItemRewriter<Protocol1_16To1_15_2> {
@Override
public void registerPackets() {
// clear cursor item to prevent client to try dropping it during navigation between multiple inventories causing arm swing
PacketHandler cursorRemapper = wrapper -> {
PacketWrapper clearPacket = wrapper.create(ClientboundPackets1_16.SET_SLOT);
clearPacket.write(Type.UNSIGNED_BYTE, (short)-1);
clearPacket.write(Type.SHORT, (short)-1);
clearPacket.write(Type.FLAT_VAR_INT_ITEM, null);
clearPacket.send(Protocol1_16To1_15_2.class);
};
protocol.registerClientbound(ClientboundPackets1_15.OPEN_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
@@ -53,26 +64,19 @@ public class InventoryPackets extends ItemRewriter<Protocol1_16To1_15_2> {
map(Type.COMPONENT); // Window Title
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
int windowId = wrapper.get(Type.VAR_INT, 0);
int windowType = wrapper.get(Type.VAR_INT, 1);
if (windowType >= 20) { // smithing added with id 20
wrapper.set(Type.VAR_INT, 1, ++windowType);
}
inventoryTracker.setInventory((short) windowId);
});
handler(cursorRemapper);
}
});
protocol.registerClientbound(ClientboundPackets1_15.CLOSE_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventory((short) -1);
});
handler(cursorRemapper);
}
});
@@ -119,18 +123,6 @@ public class InventoryPackets extends ItemRewriter<Protocol1_16To1_15_2> {
registerClickWindow(ServerboundPackets1_16.CLICK_WINDOW, Type.FLAT_VAR_INT_ITEM);
registerCreativeInvAction(ServerboundPackets1_16.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
protocol.registerServerbound(ServerboundPackets1_16.CLOSE_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventory((short) -1);
});
}
});
protocol.registerServerbound(ServerboundPackets1_16.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
@@ -1,32 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public class InventoryTracker1_16 implements StorableObject {
private short inventory = -1;
public short getInventory() {
return this.inventory;
}
public void setInventory(short inventory) {
this.inventory = inventory;
}
}
@@ -0,0 +1,137 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_17_1to1_17;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_17_1 implements ClientboundPacketType {
SPAWN_ENTITY, // 0x00
SPAWN_EXPERIENCE_ORB, // 0x01
SPAWN_MOB, // 0x02
SPAWN_PAINTING, // 0x03
SPAWN_PLAYER, // 0x04
ADD_VIBRATION_SIGNAL, // 0x05
ENTITY_ANIMATION, // 0x06
STATISTICS, // 0x07
ACKNOWLEDGE_PLAYER_DIGGING, // 0x08
BLOCK_BREAK_ANIMATION, // 0x09
BLOCK_ENTITY_DATA, // 0x0A
BLOCK_ACTION, // 0x0B
BLOCK_CHANGE, // 0x0C
BOSSBAR, // 0x0D
SERVER_DIFFICULTY, // 0x0E
CHAT_MESSAGE, // 0x0F
CLEAR_TITLES, // 0x10
TAB_COMPLETE, // 0x11
DECLARE_COMMANDS, // 0x12
CLOSE_WINDOW, // 0x13
WINDOW_ITEMS, // 0x14
WINDOW_PROPERTY, // 0x15
SET_SLOT, // 0x16
COOLDOWN, // 0x17
PLUGIN_MESSAGE, // 0x18
NAMED_SOUND, // 0x19
DISCONNECT, // 0x1A
ENTITY_STATUS, // 0x1B
EXPLOSION, // 0x1C
UNLOAD_CHUNK, // 0x1D
GAME_EVENT, // 0x1E
OPEN_HORSE_WINDOW, // 0x1F
WORLD_BORDER_INIT, // 0x20
KEEP_ALIVE, // 0x21
CHUNK_DATA, // 0x22
EFFECT, // 0x23
SPAWN_PARTICLE, // 0x24
UPDATE_LIGHT, // 0x25
JOIN_GAME, // 0x26
MAP_DATA, // 0x27
TRADE_LIST, // 0x28
ENTITY_POSITION, // 0x29
ENTITY_POSITION_AND_ROTATION, // 0x2A
ENTITY_ROTATION, // 0x2B
VEHICLE_MOVE, // 0x2C
OPEN_BOOK, // 0x2D
OPEN_WINDOW, // 0x2E
OPEN_SIGN_EDITOR, // 0x2F
PING, // 0x30
CRAFT_RECIPE_RESPONSE, // 0x31
PLAYER_ABILITIES, // 0x32
COMBAT_END, // 0x33
COMBAT_ENTER, // 0x34
COMBAT_KILL, // 0x35
PLAYER_INFO, // 0x36
FACE_PLAYER, // 0x37
PLAYER_POSITION, // 0x38
UNLOCK_RECIPES, // 0x39
REMOVE_ENTITIES, // 0x3A
REMOVE_ENTITY_EFFECT, // 0x3B
RESOURCE_PACK, // 0x3C
RESPAWN, // 0x3D
ENTITY_HEAD_LOOK, // 0x3E
MULTI_BLOCK_CHANGE, // 0x3F
SELECT_ADVANCEMENTS_TAB, // 0x40
ACTIONBAR, // 0x41
WORLD_BORDER_CENTER, // 0x42
WORLD_BORDER_LERP_SIZE, // 0x43
WORLD_BORDER_SIZE, // 0x44
WORLD_BORDER_WARNING_DELAY, // 0x45
WORLD_BORDER_WARNING_DISTANCE, // 0x46
CAMERA, // 0x47
HELD_ITEM_CHANGE, // 0x48
UPDATE_VIEW_POSITION, // 0x49
UPDATE_VIEW_DISTANCE, // 0x4A
SPAWN_POSITION, // 0x4B
DISPLAY_SCOREBOARD, // 0x4C
ENTITY_METADATA, // 0x4D
ATTACH_ENTITY, // 0x4E
ENTITY_VELOCITY, // 0x4F
ENTITY_EQUIPMENT, // 0x50
SET_EXPERIENCE, // 0x51
UPDATE_HEALTH, // 0x52
SCOREBOARD_OBJECTIVE, // 0x53
SET_PASSENGERS, // 0x54
TEAMS, // 0x55
UPDATE_SCORE, // 0x56
TITLE_SUBTITLE, // 0x57
TIME_UPDATE, // 0x58
TITLE_TEXT, // 0x59
TITLE_TIMES, // 0x5A
ENTITY_SOUND, // 0x5B
SOUND, // 0x5C
STOP_SOUND, // 0x5D
TAB_LIST, // 0x5E
NBT_QUERY, // 0x5F
COLLECT_ITEM, // 0x60
ENTITY_TELEPORT, // 0x61
ADVANCEMENTS, // 0x62
ENTITY_PROPERTIES, // 0x63
ENTITY_EFFECT, // 0x64
DECLARE_RECIPES, // 0x65
TAGS; // 0x66
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -0,0 +1,124 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 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_17_1to1_17;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.StringType;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ClientboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
public final class Protocol1_17_1To1_17 extends AbstractProtocol<ClientboundPackets1_17, ClientboundPackets1_17_1, ServerboundPackets1_17, ServerboundPackets1_17> {
private static final StringType PAGE_STRING_TYPE = new StringType(8192);
private static final StringType TITLE_STRING_TYPE = new StringType(128);
public Protocol1_17_1To1_17() {
super(ClientboundPackets1_17.class, ClientboundPackets1_17_1.class, ServerboundPackets1_17.class, ServerboundPackets1_17.class);
}
@Override
protected void registerPackets() {
registerClientbound(ClientboundPackets1_17.REMOVE_ENTITY, ClientboundPackets1_17_1.REMOVE_ENTITIES, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
// Aaaaand back to an array again!
int entityId = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{entityId});
});
}
});
registerClientbound(ClientboundPackets1_17.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Container id
create(Type.VAR_INT, 0); // Add arbitrary state id
}
});
registerClientbound(ClientboundPackets1_17.WINDOW_ITEMS, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Container id
create(Type.VAR_INT, 0); // Add arbitrary state id
handler(wrapper -> {
// Length encoded as var int now
wrapper.write(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY));
// Carried item - should work like this
wrapper.write(Type.FLAT_VAR_INT_ITEM, null);
});
}
});
registerServerbound(ServerboundPackets1_17.CLICK_WINDOW, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Container id
read(Type.VAR_INT); // Remove state id
}
});
registerServerbound(ServerboundPackets1_17.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
CompoundTag tag = new CompoundTag();
Item item = new DataItem(942, (byte) 1, (short) 0, tag); // Magic value for writable books
// Write the item, edit the tag down the line
wrapper.write(Type.FLAT_VAR_INT_ITEM, item);
int slot = wrapper.read(Type.VAR_INT);
// Save pages to tag
int pages = wrapper.read(Type.VAR_INT);
ListTag pagesTag = new ListTag(StringTag.class);
for (int i = 0; i < pages; i++) {
String page = wrapper.read(PAGE_STRING_TYPE);
pagesTag.add(new StringTag(page));
}
tag.put("pages", pagesTag);
if (wrapper.read(Type.BOOLEAN)) {
// Save the title to tag
String title = wrapper.read(TITLE_STRING_TYPE);
tag.put("title", new StringTag(title));
// Write signing
wrapper.write(Type.BOOLEAN, true);
} else {
wrapper.write(Type.BOOLEAN, false);
}
// Write the slot
wrapper.write(Type.VAR_INT, slot);
});
}
});
}
}
@@ -102,7 +102,7 @@ public final class Protocol1_17To1_16_4 extends AbstractProtocol<ClientboundPack
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.STRING);
wrapper.write(Type.BOOLEAN, Via.getConfig().isForcedUse1_17ResourcePack()); // Required
wrapper.write(Type.OPTIONAL_COMPONENT, null); // Prompt message
wrapper.write(Type.OPTIONAL_COMPONENT, Via.getConfig().get1_17ResourcePackPrompt()); // Prompt message
});
}
});
@@ -26,7 +26,7 @@ import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.api.type.types.version.Types1_16;
import com.viaversion.viaversion.api.type.types.version.Types1_17;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ClientboundPackets1_16_2;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ClientboundPackets1_17;
@@ -45,7 +45,7 @@ public final class EntityPackets extends EntityRewriter<Protocol1_17To1_16_4> {
registerTrackerWithData(ClientboundPackets1_16_2.SPAWN_ENTITY, Entity1_17Types.FALLING_BLOCK);
registerTracker(ClientboundPackets1_16_2.SPAWN_MOB);
registerTracker(ClientboundPackets1_16_2.SPAWN_PLAYER, Entity1_17Types.PLAYER);
registerMetadataRewriter(ClientboundPackets1_16_2.ENTITY_METADATA, Types1_14.METADATA_LIST, Types1_17.METADATA_LIST);
registerMetadataRewriter(ClientboundPackets1_16_2.ENTITY_METADATA, Types1_16.METADATA_LIST, Types1_17.METADATA_LIST);
protocol.registerClientbound(ClientboundPackets1_16_2.DESTROY_ENTITIES, null, new PacketRemapper() {
@Override
@@ -109,7 +109,7 @@ public final class WorldPackets {
private void writeLightArrays(PacketWrapper wrapper, int bitMask) throws Exception {
List<byte[]> light = new ArrayList<>();
for (int i = 0; i <= 17; i++) {
for (int i = 0; i < 18; i++) {
if (isSet(bitMask, i)) {
light.add(wrapper.read(Type.BYTE_ARRAY_PRIMITIVE));
}
@@ -117,8 +117,8 @@ public enum MetaIndex {
WITHER_TARGET2(WITHER, 18, MetaType1_8.Int, 12, MetaType1_9.VarInt),
WITHER_TARGET3(WITHER, 19, MetaType1_8.Int, 13, MetaType1_9.VarInt),
WITHER_INVULN_TIME(WITHER, 20, MetaType1_8.Int, 14, MetaType1_9.VarInt),
WITHER_PROPERTIES(WITHER, 10, MetaType1_8.Byte, MetaType1_9.Byte),
WITHER_UNKNOWN(WITHER, 11, MetaType1_8.Byte, null),
WITHER_PROPERTIES(WITHER, 10, MetaType1_8.Byte, null), // Thanks to plugins sending bad metadata
WITHER_UNKNOWN(WITHER, 11, MetaType1_8.NonExistent, null), // Thanks to plugins sending bad metadata
// wither skull
WITHERSKULL_INVULN(WITHER_SKULL, 10, MetaType1_8.Byte, 5, MetaType1_9.Boolean),
// guardian
@@ -25,6 +25,7 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
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;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
@@ -106,7 +107,7 @@ public class InventoryPackets {
protocol.registerClientbound(ClientboundPackets1_8.SET_SLOT, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM); // 2 - Slot Value
handler(new PacketHandler() {
@@ -123,7 +124,7 @@ public class InventoryPackets {
EntityTracker1_9 entityTracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
short slotID = wrapper.get(Type.SHORT, 0);
short windowId = wrapper.get(Type.BYTE, 0);
byte windowId = wrapper.get(Type.UNSIGNED_BYTE, 0).byteValue();
// Store item in slot
inventoryTracker.setItemId(windowId, slotID, stack == null ? 0 : stack.identifier());
@@ -286,10 +287,10 @@ public class InventoryPackets {
boolean throwItem = (slot == 45);
if (throwItem) {
// Send a packet wiping the slot
wrapper.create(0x16, new PacketHandler() {
wrapper.create(ClientboundPackets1_9.SET_SLOT, new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.BYTE, (byte) 0);
wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
wrapper.write(Type.SHORT, slot);
wrapper.write(Type.ITEM, null);
}
@@ -352,10 +353,10 @@ public class InventoryPackets {
if (throwItem) {
// Send a packet wiping the slot
wrapper.create(0x16, new PacketHandler() {
wrapper.create(ClientboundPackets1_9.SET_SLOT, new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.BYTE, (byte) windowID);
wrapper.write(Type.UNSIGNED_BYTE, (short) windowID);
wrapper.write(Type.SHORT, slot);
wrapper.write(Type.ITEM, null);
}
@@ -470,13 +470,10 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
private void logException(Exception e, @Nullable EntityType type, List<Metadata> metadataList, Metadata metadata) {
if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) {
Logger logger = Via.getPlatform().getLogger();
logger.warning("An error occurred with entity metadata handler");
logger.warning("This is most likely down to one of your plugins sending bad datawatchers. Please test if this occurs without any plugins except ViaVersion before reporting it on GitHub");
logger.warning("Also make sure that all your plugins are compatible with your server version.");
logger.warning("Entity type: " + type);
logger.warning("Indexed meta: " + metadata);
logger.warning(metadataList.stream().sorted(Comparator.comparingInt(Metadata::id))
.map(Metadata::toString).collect(Collectors.joining("\n", "Metadata: ", "")));
logger.severe("An error occurred in metadata handler " + this.getClass().getSimpleName()
+ " for " + (type != null ? type.name() : "untracked") + " entity type: " + metadata);
logger.severe(metadataList.stream().sorted(Comparator.comparingInt(Metadata::id))
.map(Metadata::toString).collect(Collectors.joining("\n", "Full metadata: ", "")));
e.printStackTrace();
}
}
@@ -70,7 +70,7 @@ public abstract class ItemRewriter<T extends Protocol> extends RewriterBase<T> i
protocol.registerClientbound(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(type); // 2 - Slot Value
@@ -17,7 +17,10 @@
*/
package com.viaversion.viaversion.util;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.configuration.ConfigurationProvider;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
@@ -207,4 +210,13 @@ public abstract class Config implements ConfigurationProvider {
return new ArrayList<>();
}
}
public @Nullable JsonElement getSerializedComponent(String key) {
final Object o = this.config.get(key);
if (o != null && !((String) o).isEmpty()) {
return GsonComponentSerializer.gson().serializeToTree(LegacyComponentSerializer.legacySection().deserialize((String) o));
} else {
return null;
}
}
}
@@ -153,6 +153,8 @@ ignore-long-1_16-channel-names: true
#
# Force 1.17+ client to accept the server resource pack; they will automatically disconnect if they decline.
forced-use-1_17-resource-pack: false
# The message to be displayed at the prompt when the 1.17+ client receives the server resource pack.
resource-pack-1_17-prompt: ''
#
#----------------------------------------------------------#
# 1.9+ CLIENTS ON 1.8 SERVERS OPTIONS #
+1 -1
View File
@@ -1,5 +1,5 @@
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
projectVersion=4.0.0
projectVersion=4.0.1
# Gradle properties
org.gradle.daemon=true
+1 -1
View File
@@ -2,7 +2,7 @@ metadata.format.version = "1.0"
[versions]
adventure = "4.8.0-SNAPSHOT"
adventure = "4.8.0"
gson = "2.8.7"
fastutil = "8.3.1"
openNBT = "2.0-SNAPSHOT"
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -39,11 +39,11 @@ import com.viaversion.viaversion.util.GsonUtil;
import com.viaversion.viaversion.util.VersionInfo;
import com.viaversion.viaversion.velocity.command.VelocityCommandHandler;
import com.viaversion.viaversion.velocity.command.VelocityCommandSender;
import com.viaversion.viaversion.velocity.platform.VelocityViaTask;
import com.viaversion.viaversion.velocity.platform.VelocityViaAPI;
import com.viaversion.viaversion.velocity.platform.VelocityViaConfig;
import com.viaversion.viaversion.velocity.platform.VelocityViaInjector;
import com.viaversion.viaversion.velocity.platform.VelocityViaLoader;
import com.viaversion.viaversion.velocity.platform.VelocityViaTask;
import com.viaversion.viaversion.velocity.service.ProtocolDetectorService;
import com.viaversion.viaversion.velocity.util.LoggerWrapper;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@@ -82,6 +82,18 @@ public class VelocityPlugin implements ViaPlatform<Player> {
@Subscribe
public void onProxyInit(ProxyInitializeEvent e) {
if (!hasConnectionEvent()) {
// No way to disable the plugin :(
Logger logger = this.loggerslf4j;
logger.error(" / \\");
logger.error(" / \\");
logger.error(" / | \\");
logger.error(" / | \\ VELOCITY 3.0.0 IS REQUIRED");
logger.error(" / \\ VIAVERSION WILL NOT WORK AS INTENDED");
logger.error(" / o \\");
logger.error("/_____________\\");
}
PROXY = proxy;
VelocityCommandHandler commandHandler = new VelocityCommandHandler();
PROXY.getCommandManager().register("viaver", commandHandler, "vvvelocity", "viaversion");
@@ -231,4 +243,13 @@ public class VelocityPlugin implements ViaPlatform<Player> {
public java.util.logging.Logger getLogger() {
return logger;
}
private boolean hasConnectionEvent() {
try {
Class.forName("com.velocitypowered.proxy.protocol.VelocityConnectionEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
}
@@ -26,33 +26,42 @@ import io.netty.channel.ChannelInitializer;
import java.lang.reflect.Method;
public class VelocityChannelInitializer extends ChannelInitializer<Channel> {
public static final String MINECRAFT_ENCODER = "minecraft-encoder";
public static final String MINECRAFT_DECODER = "minecraft-decoder";
public static final String VIA_ENCODER = "via-encoder";
public static final String VIA_DECODER = "via-decoder";
public static final Object COMPRESSION_ENABLED_EVENT;
private static final Method INIT_CHANNEL;
private final ChannelInitializer<?> original;
private final boolean clientSide;
private static Method initChannel;
static {
try {
INIT_CHANNEL = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
INIT_CHANNEL.setAccessible(true);
Class<?> eventClass = Class.forName("com.velocitypowered.proxy.protocol.VelocityConnectionEvent");
COMPRESSION_ENABLED_EVENT = eventClass.getDeclaredField("COMPRESSION_ENABLED").get(null);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public VelocityChannelInitializer(ChannelInitializer<?> original, boolean clientSide) {
this.original = original;
this.clientSide = clientSide;
}
static {
try {
initChannel = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
initChannel.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Override
protected void initChannel(Channel channel) throws Exception {
initChannel.invoke(original, channel);
INIT_CHANNEL.invoke(original, channel);
UserConnection user = new UserConnectionImpl(channel, clientSide);
new ProtocolPipelineImpl(user);
// We need to add a separated handler because Velocity uses pipeline().get(MINECRAFT_DECODER)
channel.pipeline().addBefore("minecraft-encoder", "via-encoder", new VelocityEncodeHandler(user));
channel.pipeline().addBefore("minecraft-decoder", "via-decoder", new VelocityDecodeHandler(user));
channel.pipeline().addBefore(MINECRAFT_ENCODER, VIA_ENCODER, new VelocityEncodeHandler(user));
channel.pipeline().addBefore(MINECRAFT_DECODER, VIA_DECODER, new VelocityDecodeHandler(user));
}
}
@@ -20,21 +20,17 @@ package com.viaversion.viaversion.velocity.handlers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.exception.CancelCodecException;
import com.viaversion.viaversion.exception.CancelDecoderException;
import com.viaversion.viaversion.util.PipelineUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@ChannelHandler.Sharable
public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
private final UserConnection info;
private boolean handledCompression;
private boolean skipDoubleTransform;
public VelocityDecodeHandler(UserConnection info) {
this.info = info;
@@ -42,12 +38,6 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
if (skipDoubleTransform) {
skipDoubleTransform = false;
out.add(bytebuf.retain());
return;
}
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null);
if (!info.shouldTransformPacket()) {
out.add(bytebuf.retain());
@@ -56,58 +46,39 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
try {
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
if (needsCompress) {
recompress(ctx, transformedBuf);
skipDoubleTransform = true;
}
out.add(transformedBuf.retain());
} finally {
transformedBuf.release();
}
}
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
if (handledCompression) return false;
int decoderIndex = ctx.pipeline().names().indexOf("compression-decoder");
if (decoderIndex == -1) return false;
handledCompression = true;
if (decoderIndex > ctx.pipeline().names().indexOf("via-decoder")) {
// Need to decompress this packet due to bad order
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, buf).get(0);
try {
buf.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
ChannelHandler encoder = ctx.pipeline().get("via-encoder");
ChannelHandler decoder = ctx.pipeline().get("via-decoder");
ctx.pipeline().remove(encoder);
ctx.pipeline().remove(decoder);
ctx.pipeline().addAfter("compression-encoder", "via-encoder", encoder);
ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder);
return true;
}
return false;
}
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
ByteBuf compressed = ctx.alloc().buffer();
try {
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, buf, compressed);
buf.clear().writeBytes(compressed);
} finally {
compressed.release();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (cause instanceof CancelCodecException) return;
super.exceptionCaught(ctx, cause);
}
// Abuse decoder handler to catch events
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object event) throws Exception {
if (event != VelocityChannelInitializer.COMPRESSION_ENABLED_EVENT) {
super.userEventTriggered(ctx, event);
return;
}
// When Velocity adds the compression handlers, the order becomes Minecraft Encoder -> Compressor -> Via Encoder
// Move Via codec handlers back to right position
ChannelPipeline pipeline = ctx.pipeline();
ChannelHandler encoder = pipeline.get(VelocityChannelInitializer.VIA_ENCODER);
pipeline.remove(encoder);
pipeline.addBefore(VelocityChannelInitializer.MINECRAFT_ENCODER, VelocityChannelInitializer.VIA_ENCODER, encoder);
ChannelHandler decoder = pipeline.get(VelocityChannelInitializer.VIA_DECODER);
pipeline.remove(decoder);
pipeline.addBefore(VelocityChannelInitializer.MINECRAFT_DECODER, VelocityChannelInitializer.VIA_DECODER, decoder);
super.userEventTriggered(ctx, event);
}
}
@@ -20,21 +20,16 @@ package com.viaversion.viaversion.velocity.handlers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.exception.CancelCodecException;
import com.viaversion.viaversion.exception.CancelEncoderException;
import com.viaversion.viaversion.util.PipelineUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@ChannelHandler.Sharable
public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
private final UserConnection info;
private boolean handledCompression;
public VelocityEncodeHandler(UserConnection info) {
this.info = info;
@@ -50,54 +45,13 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
try {
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
if (needsCompress) {
recompress(ctx, transformedBuf);
}
out.add(transformedBuf.retain());
} finally {
transformedBuf.release();
}
}
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
if (handledCompression) return false;
int encoderIndex = ctx.pipeline().names().indexOf("compression-encoder");
if (encoderIndex == -1) return false;
handledCompression = true;
if (encoderIndex > ctx.pipeline().names().indexOf("via-encoder")) {
// Need to decompress this packet due to bad order
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, buf).get(0);
try {
buf.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
ChannelHandler encoder = ctx.pipeline().get("via-encoder");
ChannelHandler decoder = ctx.pipeline().get("via-decoder");
ctx.pipeline().remove(encoder);
ctx.pipeline().remove(decoder);
ctx.pipeline().addAfter("compression-encoder", "via-encoder", encoder);
ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder);
return true;
}
return false;
}
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
ByteBuf compressed = ctx.alloc().buffer();
try {
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, buf, compressed);
buf.clear().writeBytes(compressed);
} finally {
compressed.release();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (cause instanceof CancelCodecException) return;
@@ -57,13 +57,14 @@ public class VelocityViaInjector implements ViaInjector {
@Override
public void inject() throws Exception {
Via.getPlatform().getLogger().info("Replacing channel initializers; you can safely ignore the following two warnings.");
Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class);
Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer");
ChannelInitializer originalInitializer = getInitializer();
channelInitializerHolder.getClass().getMethod("set", ChannelInitializer.class)
.invoke(channelInitializerHolder, new VelocityChannelInitializer(originalInitializer, false));
Object backendInitializerHolder = ReflectionUtil.invoke(connectionManager, "getBackendChannelInitializer");
ChannelInitializer backendInitializer = getBackendInitializer();
backendInitializerHolder.getClass().getMethod("set", ChannelInitializer.class)
@@ -75,7 +76,6 @@ public class VelocityViaInjector implements ViaInjector {
Via.getPlatform().getLogger().severe("ViaVersion cannot remove itself from Velocity without a reboot!");
}
@Override
public int getServerProtocolVersion() throws Exception {
return getLowestSupportedProtocolVersion();
@@ -48,6 +48,7 @@ public class VelocityVersionProvider extends BaseVersionProvider {
}
private int getBackProtocol(UserConnection user) throws Exception {
//TODO use newly added Velocity netty event
ChannelHandler mcHandler = user.getChannel().pipeline().get("handler");
return ProtocolDetectorService.getProtocolId(
((ServerConnection) getAssociation.invoke(mcHandler)).getServerInfo().getName());