forked from Upstream/Velocitab
Implement native packets handling and remove Protocolize dependency (#44)
This commit is contained in:
parent
4d586d28c3
commit
d3d67cb613
@ -22,18 +22,17 @@ repositories {
|
||||
maven { url = 'https://repo.papermc.io/repository/maven-public/' }
|
||||
maven { url = 'https://jitpack.io/' }
|
||||
maven { url = 'https://repo.minebench.de/' }
|
||||
maven { url = 'https://mvn.exceptionflug.de/repository/exceptionflug-public/' }
|
||||
maven { url = "https://maven.elytrium.net/repo/" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'com.velocitypowered:velocity-api:3.1.1'
|
||||
compileOnly 'com.velocitypowered:velocity-api:3.2.0-SNAPSHOT'
|
||||
compileOnly 'com.velocitypowered:velocity-proxy:3.2.0-SNAPSHOT'
|
||||
compileOnly 'net.luckperms:api:5.4'
|
||||
compileOnly 'dev.simplix:protocolize-api:2.2.6'
|
||||
compileOnly 'io.netty:netty-codec-http:4.1.91.Final'
|
||||
compileOnly 'io.github.miniplaceholders:miniplaceholders-api:2.0.0'
|
||||
compileOnly 'net.william278:PAPIProxyBridge:1.2'
|
||||
compileOnly 'org.projectlombok:lombok:1.18.26'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.13.1'
|
||||
|
||||
implementation 'org.apache.commons:commons-text:1.10.0'
|
||||
implementation 'net.william278:Annotaml:2.0.1'
|
||||
|
@ -132,10 +132,6 @@ public class Velocitab {
|
||||
|
||||
private void prepareScoreboardManager() {
|
||||
if (settings.isSortPlayers()) {
|
||||
if (!Hook.isPluginAvailable(this, "protocolize")) {
|
||||
log("Protocolize is required to sort players by weight, but was not found. Disabling sorting.");
|
||||
return;
|
||||
}
|
||||
this.scoreboardManager = new ScoreboardManager(this);
|
||||
scoreboardManager.registerPacket();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ public class Settings {
|
||||
|
||||
@Getter
|
||||
@YamlKey("sort_players")
|
||||
@YamlComment("Whether to sort players in the TAB list. Requires Protocolize to be installed.")
|
||||
@YamlComment("Whether to sort players in the TAB list.")
|
||||
private boolean sortPlayers = true;
|
||||
|
||||
@YamlKey("sort_players_by")
|
||||
|
@ -70,7 +70,7 @@ public abstract class Hook {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public static boolean isPluginAvailable(@NotNull Velocitab plugin, @NotNull String id) {
|
||||
private static boolean isPluginAvailable(@NotNull Velocitab plugin, @NotNull String id) {
|
||||
return plugin.getServer().getPluginManager().getPlugin(id).isPresent();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* This file is part of Velocitab, licensed under the Apache License 2.0.
|
||||
*
|
||||
* Copyright (c) William278 <will27528@gmail.com>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.william278.velocitab.packet;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
// Based on VPacketEvents PacketRegistration API
|
||||
public final class PacketRegistration<P extends MinecraftPacket> {
|
||||
|
||||
private final Class<P> packetClass;
|
||||
private Supplier<P> packetSupplier;
|
||||
private ProtocolUtils.Direction direction;
|
||||
private StateRegistry stateRegistry;
|
||||
private final List<StateRegistry.PacketMapping> mappings = new ArrayList<>();
|
||||
|
||||
public PacketRegistration<P> packetSupplier(final @NotNull Supplier<P> packetSupplier) {
|
||||
this.packetSupplier = packetSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketRegistration<P> direction(final ProtocolUtils.Direction direction) {
|
||||
this.direction = direction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketRegistration<P> stateRegistry(final @NotNull StateRegistry stateRegistry) {
|
||||
this.stateRegistry = stateRegistry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketRegistration<P> mapping(
|
||||
final int id,
|
||||
final ProtocolVersion version,
|
||||
final boolean encodeOnly
|
||||
) {
|
||||
try {
|
||||
final StateRegistry.PacketMapping mapping = (StateRegistry.PacketMapping) PACKET_MAPPING$map.invoke(
|
||||
id, version, encodeOnly);
|
||||
this.mappings.add(mapping);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
try {
|
||||
final StateRegistry.PacketRegistry packetRegistry = direction == ProtocolUtils.Direction.CLIENTBOUND
|
||||
? (StateRegistry.PacketRegistry) STATE_REGISTRY$clientBound.invoke(stateRegistry)
|
||||
: (StateRegistry.PacketRegistry) STATE_REGISTRY$serverBound.invoke(stateRegistry);
|
||||
PACKET_REGISTRY$register.invoke(
|
||||
packetRegistry,
|
||||
packetClass,
|
||||
packetSupplier,
|
||||
mappings.toArray(StateRegistry.PacketMapping[]::new)
|
||||
);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
||||
public static <P extends MinecraftPacket> PacketRegistration<P> of(Class<P> packetClass) {
|
||||
return new PacketRegistration<>(packetClass);
|
||||
}
|
||||
|
||||
private PacketRegistration(final @NotNull Class<P> packetClass) {
|
||||
this.packetClass = packetClass;
|
||||
}
|
||||
|
||||
private static final MethodHandle STATE_REGISTRY$clientBound;
|
||||
private static final MethodHandle STATE_REGISTRY$serverBound;
|
||||
private static final MethodHandle PACKET_REGISTRY$register;
|
||||
private static final MethodHandle PACKET_MAPPING$map;
|
||||
|
||||
static {
|
||||
final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
try {
|
||||
final MethodHandles.Lookup stateRegistryLookup = MethodHandles.privateLookupIn(StateRegistry.class, lookup);
|
||||
STATE_REGISTRY$clientBound = stateRegistryLookup.findGetter(StateRegistry.class, "clientbound", StateRegistry.PacketRegistry.class);
|
||||
STATE_REGISTRY$serverBound = stateRegistryLookup.findGetter(StateRegistry.class, "serverbound", StateRegistry.PacketRegistry.class);
|
||||
|
||||
final MethodType mapType = MethodType.methodType(StateRegistry.PacketMapping.class, Integer.TYPE, ProtocolVersion.class, Boolean.TYPE);
|
||||
PACKET_MAPPING$map = stateRegistryLookup.findStatic(StateRegistry.class, "map", mapType);
|
||||
|
||||
final MethodHandles.Lookup packetRegistryLookup = MethodHandles.privateLookupIn(StateRegistry.PacketRegistry.class, lookup);
|
||||
final MethodType registerType = MethodType.methodType(void.class, Class.class, Supplier.class, StateRegistry.PacketMapping[].class);
|
||||
PACKET_REGISTRY$register = packetRegistryLookup.findVirtual(StateRegistry.PacketRegistry.class, "register", registerType);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -20,16 +20,16 @@
|
||||
package net.william278.velocitab.packet;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import dev.simplix.protocolize.api.PacketDirection;
|
||||
import dev.simplix.protocolize.api.Protocol;
|
||||
import dev.simplix.protocolize.api.Protocolize;
|
||||
import dev.simplix.protocolize.api.player.ProtocolizePlayer;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.*;
|
||||
public class ScoreboardManager {
|
||||
|
||||
private final Velocitab plugin;
|
||||
@ -85,13 +85,10 @@ public class ScoreboardManager {
|
||||
plugin.getTabList().removeOfflinePlayer(player);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ProtocolizePlayer protocolizePlayer = Protocolize.playerProvider().player(player.getUniqueId());
|
||||
if (protocolizePlayer != null) {
|
||||
protocolizePlayer.sendPacket(packet);
|
||||
} else {
|
||||
plugin.log("Failed to get ProtocolizePlayer for player " + player.getUsername() + " (UUID: " + player.getUniqueId() + ")");
|
||||
}
|
||||
final ConnectedPlayer connectedPlayer = (ConnectedPlayer) player;
|
||||
connectedPlayer.getConnection().write(packet);
|
||||
} catch (Exception e) {
|
||||
plugin.log("Failed to dispatch packet (is the client or server modded or using an illegal version?)", e);
|
||||
}
|
||||
@ -99,13 +96,19 @@ public class ScoreboardManager {
|
||||
|
||||
public void registerPacket() {
|
||||
try {
|
||||
Protocolize.protocolRegistration().registerPacket(
|
||||
UpdateTeamsPacket.MAPPINGS,
|
||||
Protocol.PLAY,
|
||||
PacketDirection.CLIENTBOUND,
|
||||
UpdateTeamsPacket.class
|
||||
);
|
||||
} catch (Exception e) {
|
||||
PacketRegistration.of(UpdateTeamsPacket.class)
|
||||
.direction(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.packetSupplier(UpdateTeamsPacket::new)
|
||||
.stateRegistry(StateRegistry.PLAY)
|
||||
.mapping(0x47, MINECRAFT_1_13, false)
|
||||
.mapping(0x4B, MINECRAFT_1_14, false)
|
||||
.mapping(0x4C, MINECRAFT_1_15, false)
|
||||
.mapping(0x55, MINECRAFT_1_17, false)
|
||||
.mapping(0x58, MINECRAFT_1_19_1, false)
|
||||
.mapping(0x56, MINECRAFT_1_19_3, false)
|
||||
.mapping(0x5A, MINECRAFT_1_19_4, false)
|
||||
.register();
|
||||
} catch (Throwable e) {
|
||||
plugin.log("Failed to register UpdateTeamsPacket", e);
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,10 @@
|
||||
|
||||
package net.william278.velocitab.packet;
|
||||
|
||||
import dev.simplix.protocolize.api.PacketDirection;
|
||||
import dev.simplix.protocolize.api.mapping.AbstractProtocolMapping;
|
||||
import dev.simplix.protocolize.api.mapping.ProtocolIdMapping;
|
||||
import dev.simplix.protocolize.api.packet.AbstractPacket;
|
||||
import dev.simplix.protocolize.api.util.ProtocolUtil;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
@ -36,8 +35,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.simplix.protocolize.api.util.ProtocolVersions.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@ -45,17 +42,7 @@ import static dev.simplix.protocolize.api.util.ProtocolVersions.*;
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(fluent = true)
|
||||
public class UpdateTeamsPacket extends AbstractPacket {
|
||||
|
||||
protected static final List<ProtocolIdMapping> MAPPINGS = List.of(
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_13, MINECRAFT_1_13_2, 0x47),
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_14, MINECRAFT_1_14_4, 0x4B),
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_15, MINECRAFT_1_16_5, 0x4C),
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_17, MINECRAFT_1_19, 0x55),
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_19_1, MINECRAFT_1_19_2, 0x58),
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x56),
|
||||
AbstractProtocolMapping.rangedIdMapping(MINECRAFT_1_19_4, MINECRAFT_LATEST, 0x5A)
|
||||
);
|
||||
public class UpdateTeamsPacket implements MinecraftPacket {
|
||||
|
||||
private String teamName;
|
||||
private UpdateMode mode;
|
||||
@ -99,58 +86,63 @@ public class UpdateTeamsPacket extends AbstractPacket {
|
||||
.entities(Arrays.asList(teamMembers));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getChatString(@NotNull String string) {
|
||||
return "{\"text\":\"" + StringEscapeUtils.escapeJson(string) + "\"}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf byteBuf, PacketDirection packetDirection, int i) {
|
||||
teamName = ProtocolUtil.readString(byteBuf);
|
||||
public void decode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
|
||||
teamName = ProtocolUtils.readString(byteBuf);
|
||||
mode = UpdateMode.byId(byteBuf.readByte());
|
||||
if (mode == UpdateMode.REMOVE_TEAM) {
|
||||
return;
|
||||
}
|
||||
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.UPDATE_INFO) {
|
||||
displayName = ProtocolUtil.readString(byteBuf);
|
||||
displayName = ProtocolUtils.readString(byteBuf);
|
||||
friendlyFlags = FriendlyFlag.fromBitMask(byteBuf.readByte());
|
||||
nameTagVisibility = NameTagVisibility.byId(ProtocolUtil.readString(byteBuf));
|
||||
collisionRule = CollisionRule.byId(ProtocolUtil.readString(byteBuf));
|
||||
nameTagVisibility = NameTagVisibility.byId(ProtocolUtils.readString(byteBuf));
|
||||
collisionRule = CollisionRule.byId(ProtocolUtils.readString(byteBuf));
|
||||
color = byteBuf.readByte();
|
||||
prefix = ProtocolUtil.readString(byteBuf);
|
||||
suffix = ProtocolUtil.readString(byteBuf);
|
||||
prefix = ProtocolUtils.readString(byteBuf);
|
||||
suffix = ProtocolUtils.readString(byteBuf);
|
||||
}
|
||||
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.ADD_PLAYERS || mode == UpdateMode.REMOVE_PLAYERS) {
|
||||
int entityCount = ProtocolUtil.readVarInt(byteBuf);
|
||||
int entityCount = ProtocolUtils.readVarInt(byteBuf);
|
||||
entities = new ArrayList<>(entityCount);
|
||||
for (int j = 0; j < entityCount; j++) {
|
||||
entities.add(ProtocolUtil.readString(byteBuf));
|
||||
entities.add(ProtocolUtils.readString(byteBuf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf byteBuf, PacketDirection packetDirection, int i) {
|
||||
ProtocolUtil.writeString(byteBuf, teamName);
|
||||
public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
|
||||
ProtocolUtils.writeString(byteBuf, teamName);
|
||||
byteBuf.writeByte(mode.id());
|
||||
if (mode == UpdateMode.REMOVE_TEAM) {
|
||||
return;
|
||||
}
|
||||
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.UPDATE_INFO) {
|
||||
ProtocolUtil.writeString(byteBuf, displayName);
|
||||
ProtocolUtils.writeString(byteBuf, displayName);
|
||||
byteBuf.writeByte(FriendlyFlag.toBitMask(friendlyFlags));
|
||||
ProtocolUtil.writeString(byteBuf, nameTagVisibility.id());
|
||||
ProtocolUtil.writeString(byteBuf, collisionRule.id());
|
||||
ProtocolUtils.writeString(byteBuf, nameTagVisibility.id());
|
||||
ProtocolUtils.writeString(byteBuf, collisionRule.id());
|
||||
byteBuf.writeByte(color);
|
||||
ProtocolUtil.writeString(byteBuf, prefix);
|
||||
ProtocolUtil.writeString(byteBuf, suffix);
|
||||
ProtocolUtils.writeString(byteBuf, prefix);
|
||||
ProtocolUtils.writeString(byteBuf, suffix);
|
||||
}
|
||||
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.ADD_PLAYERS || mode == UpdateMode.REMOVE_PLAYERS) {
|
||||
ProtocolUtil.writeVarInt(byteBuf, entities != null ? entities.size() : 0);
|
||||
ProtocolUtils.writeVarInt(byteBuf, entities != null ? entities.size() : 0);
|
||||
for (String entity : entities != null ? entities : new ArrayList<String>()) {
|
||||
ProtocolUtil.writeString(byteBuf, entity);
|
||||
ProtocolUtils.writeString(byteBuf, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getChatString(@NotNull String string) {
|
||||
return "{\"text\":\"" + StringEscapeUtils.escapeJson(string) + "\"}";
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler minecraftSessionHandler) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public enum UpdateMode {
|
||||
|
@ -8,10 +8,6 @@
|
||||
"William278"
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "protocolize",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "luckperms",
|
||||
"optional": true
|
||||
|
Loading…
Reference in New Issue
Block a user