geforkt von Mirrors/Velocity
Major improvements to tab complete support.
- Removed half-baked 1.13 support that didn't even work anyway. Perhaps in the future we could restore it by rewriting the available commands packet. - Proxy commands now show up in tab complete responses where possible.
Dieser Commit ist enthalten in:
Ursprung
e577d6b6f5
Commit
8763573ae6
@ -66,6 +66,7 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
if (split.length == 1) {
|
if (split.length == 1) {
|
||||||
return Optional.of(commands.keySet().stream()
|
return Optional.of(commands.keySet().stream()
|
||||||
.filter(cmd -> cmd.regionMatches(true, 0, command, 0, command.length()))
|
.filter(cmd -> cmd.regionMatches(true, 0, command, 0, command.length()))
|
||||||
|
.map(cmd -> "/" + cmd)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
}, connection.getMinecraftConnection().getChannel().eventLoop());
|
}, connection.getMinecraftConnection().getChannel().eventLoop());
|
||||||
}
|
}
|
||||||
|
} else if (packet instanceof TabCompleteResponse) {
|
||||||
|
playerHandler.handleTabCompleteResponse((TabCompleteResponse) packet);
|
||||||
} else if (connection.hasCompletedJoin()) {
|
} else if (connection.hasCompletedJoin()) {
|
||||||
// Just forward the packet on. We don't have anything to handle at this time.
|
// Just forward the packet on. We don't have anything to handle at this time.
|
||||||
connection.getPlayer().getConnection().write(packet);
|
connection.getPlayer().getConnection().write(packet);
|
||||||
|
@ -36,6 +36,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
private final Set<String> clientPluginMsgChannels = new HashSet<>();
|
private final Set<String> clientPluginMsgChannels = new HashSet<>();
|
||||||
private final Queue<PluginMessage> loginPluginMessages = new ArrayDeque<>();
|
private final Queue<PluginMessage> loginPluginMessages = new ArrayDeque<>();
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
|
private TabCompleteRequest outstandingTabComplete;
|
||||||
|
|
||||||
public ClientPlaySessionHandler(VelocityServer server, ConnectedPlayer player) {
|
public ClientPlaySessionHandler(VelocityServer server, ConnectedPlayer player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -100,32 +101,10 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet instanceof TabCompleteRequest) {
|
if (packet instanceof TabCompleteRequest) {
|
||||||
TabCompleteRequest req = (TabCompleteRequest) packet;
|
// Record the request so that the outstanding request can be augmented later.
|
||||||
int lastSpace = req.getCommand().indexOf(' ');
|
outstandingTabComplete = (TabCompleteRequest) packet;
|
||||||
if (!req.isAssumeCommand() && lastSpace != -1) {
|
|
||||||
String command = req.getCommand().substring(1);
|
|
||||||
try {
|
|
||||||
Optional<List<String>> offers = server.getCommandManager().offerSuggestions(player, command);
|
|
||||||
if (offers.isPresent()) {
|
|
||||||
TabCompleteResponse response = new TabCompleteResponse();
|
|
||||||
response.setTransactionId(req.getTransactionId());
|
|
||||||
response.setStart(lastSpace);
|
|
||||||
response.setLength(req.getCommand().length() - lastSpace);
|
|
||||||
|
|
||||||
for (String s : offers.get()) {
|
|
||||||
response.getOffers().add(new TabCompleteResponse.Offer(s, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
player.getConnection().write(response);
|
|
||||||
} else {
|
|
||||||
serverConnection.getMinecraftConnection().write(packet);
|
serverConnection.getMinecraftConnection().write(packet);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Unable to provide tab list completions for " + player.getUsername() + " for command '" + req.getCommand() + "'", e);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packet instanceof PluginMessage) {
|
if (packet instanceof PluginMessage) {
|
||||||
handleClientPluginMessage((PluginMessage) packet);
|
handleClientPluginMessage((PluginMessage) packet);
|
||||||
@ -327,4 +306,21 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
this.lastPingID = -1;
|
this.lastPingID = -1;
|
||||||
this.lastPingSent = -1;
|
this.lastPingSent = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleTabCompleteResponse(TabCompleteResponse response) {
|
||||||
|
if (outstandingTabComplete != null) {
|
||||||
|
if (!outstandingTabComplete.isAssumeCommand()) {
|
||||||
|
String command = outstandingTabComplete.getCommand().substring(1);
|
||||||
|
try {
|
||||||
|
Optional<List<String>> offers = server.getCommandManager().offerSuggestions(player, command);
|
||||||
|
offers.ifPresent(strings -> response.getOffers().addAll(strings));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Unable to provide tab list completions for {} for command '{}'", player.getUsername(),
|
||||||
|
command, e);
|
||||||
|
}
|
||||||
|
outstandingTabComplete = null;
|
||||||
|
}
|
||||||
|
player.getConnection().write(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,7 @@ public enum StateRegistry {
|
|||||||
map(0x14, MINECRAFT_1_8, false),
|
map(0x14, MINECRAFT_1_8, false),
|
||||||
map(0x01, MINECRAFT_1_9, false),
|
map(0x01, MINECRAFT_1_9, false),
|
||||||
map(0x02, MINECRAFT_1_12, false),
|
map(0x02, MINECRAFT_1_12, false),
|
||||||
map(0x01, MINECRAFT_1_12_1, false),
|
map(0x01, MINECRAFT_1_12_1, false));
|
||||||
map(0x05, MINECRAFT_1_13, false));
|
|
||||||
SERVERBOUND.register(Chat.class, Chat::new,
|
SERVERBOUND.register(Chat.class, Chat::new,
|
||||||
map(0x01, MINECRAFT_1_8, false),
|
map(0x01, MINECRAFT_1_8, false),
|
||||||
map(0x02, MINECRAFT_1_9, false),
|
map(0x02, MINECRAFT_1_9, false),
|
||||||
@ -77,10 +76,9 @@ public enum StateRegistry {
|
|||||||
map(0x0F, MINECRAFT_1_12, true),
|
map(0x0F, MINECRAFT_1_12, true),
|
||||||
map(0x0E, MINECRAFT_1_13, true));
|
map(0x0E, MINECRAFT_1_13, true));
|
||||||
CLIENTBOUND.register(TabCompleteResponse.class, TabCompleteResponse::new,
|
CLIENTBOUND.register(TabCompleteResponse.class, TabCompleteResponse::new,
|
||||||
map(0x3A, MINECRAFT_1_8, true),
|
map(0x3A, MINECRAFT_1_8, false),
|
||||||
map(0x0E, MINECRAFT_1_9, true),
|
map(0x0E, MINECRAFT_1_9, false),
|
||||||
map(0x0E, MINECRAFT_1_12, true),
|
map(0x0E, MINECRAFT_1_12, false));
|
||||||
map(0x10, MINECRAFT_1_13, true));
|
|
||||||
CLIENTBOUND.register(PluginMessage.class, PluginMessage::new,
|
CLIENTBOUND.register(PluginMessage.class, PluginMessage::new,
|
||||||
map(0x3F, MINECRAFT_1_8, false),
|
map(0x3F, MINECRAFT_1_8, false),
|
||||||
map(0x18, MINECRAFT_1_9, false),
|
map(0x18, MINECRAFT_1_9, false),
|
||||||
|
@ -9,20 +9,11 @@ import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_1
|
|||||||
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_9;
|
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_9;
|
||||||
|
|
||||||
public class TabCompleteRequest implements MinecraftPacket {
|
public class TabCompleteRequest implements MinecraftPacket {
|
||||||
private int transactionId;
|
|
||||||
private String command;
|
private String command;
|
||||||
private boolean assumeCommand;
|
private boolean assumeCommand;
|
||||||
private boolean hasPosition;
|
private boolean hasPosition;
|
||||||
private long position;
|
private long position;
|
||||||
|
|
||||||
public int getTransactionId() {
|
|
||||||
return transactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactionId(int transactionId) {
|
|
||||||
this.transactionId = transactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCommand() {
|
public String getCommand() {
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
@ -58,8 +49,7 @@ public class TabCompleteRequest implements MinecraftPacket {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TabCompleteRequest{" +
|
return "TabCompleteRequest{" +
|
||||||
"transactionId=" + transactionId +
|
"command='" + command + '\'' +
|
||||||
", command='" + command + '\'' +
|
|
||||||
", assumeCommand=" + assumeCommand +
|
", assumeCommand=" + assumeCommand +
|
||||||
", hasPosition=" + hasPosition +
|
", hasPosition=" + hasPosition +
|
||||||
", position=" + position +
|
", position=" + position +
|
||||||
@ -68,10 +58,6 @@ public class TabCompleteRequest implements MinecraftPacket {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
if (protocolVersion >= MINECRAFT_1_13) {
|
|
||||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
|
||||||
this.command = ProtocolUtils.readString(buf);
|
|
||||||
} else {
|
|
||||||
this.command = ProtocolUtils.readString(buf);
|
this.command = ProtocolUtils.readString(buf);
|
||||||
if (protocolVersion >= MINECRAFT_1_9) {
|
if (protocolVersion >= MINECRAFT_1_9) {
|
||||||
this.assumeCommand = buf.readBoolean();
|
this.assumeCommand = buf.readBoolean();
|
||||||
@ -81,14 +67,9 @@ public class TabCompleteRequest implements MinecraftPacket {
|
|||||||
this.position = buf.readLong();
|
this.position = buf.readLong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
if (protocolVersion >= MINECRAFT_1_13) {
|
|
||||||
ProtocolUtils.writeVarInt(buf, transactionId);
|
|
||||||
ProtocolUtils.writeString(buf, command);
|
|
||||||
} else {
|
|
||||||
ProtocolUtils.writeString(buf, command);
|
ProtocolUtils.writeString(buf, command);
|
||||||
if (protocolVersion >= MINECRAFT_1_9) {
|
if (protocolVersion >= MINECRAFT_1_9) {
|
||||||
buf.writeBoolean(assumeCommand);
|
buf.writeBoolean(assumeCommand);
|
||||||
@ -98,5 +79,4 @@ public class TabCompleteRequest implements MinecraftPacket {
|
|||||||
buf.writeLong(position);
|
buf.writeLong(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,125 +4,37 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
|||||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.kyori.text.Component;
|
|
||||||
import net.kyori.text.serializer.ComponentSerializers;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.velocitypowered.proxy.protocol.ProtocolConstants.MINECRAFT_1_13;
|
|
||||||
|
|
||||||
public class TabCompleteResponse implements MinecraftPacket {
|
public class TabCompleteResponse implements MinecraftPacket {
|
||||||
private int transactionId;
|
private final List<String> offers = new ArrayList<>();
|
||||||
private int start;
|
|
||||||
private int length;
|
|
||||||
private final List<Offer> offers = new ArrayList<>();
|
|
||||||
|
|
||||||
public int getTransactionId() {
|
public List<String> getOffers() {
|
||||||
return transactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactionId(int transactionId) {
|
|
||||||
this.transactionId = transactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStart(int start) {
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLength() {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLength(int length) {
|
|
||||||
this.length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Offer> getOffers() {
|
|
||||||
return offers;
|
return offers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TabCompleteResponse{" +
|
return "TabCompleteResponse{" +
|
||||||
"transactionId=" + transactionId +
|
"offers=" + offers +
|
||||||
", start=" + start +
|
|
||||||
", length=" + length +
|
|
||||||
", offers=" + offers +
|
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
if (protocolVersion >= MINECRAFT_1_13) {
|
|
||||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
|
||||||
this.start = ProtocolUtils.readVarInt(buf);
|
|
||||||
this.length = ProtocolUtils.readVarInt(buf);
|
|
||||||
int offersAvailable = ProtocolUtils.readVarInt(buf);
|
int offersAvailable = ProtocolUtils.readVarInt(buf);
|
||||||
for (int i = 0; i < offersAvailable; i++) {
|
for (int i = 0; i < offersAvailable; i++) {
|
||||||
String entry = ProtocolUtils.readString(buf);
|
offers.add(ProtocolUtils.readString(buf));
|
||||||
Component component = buf.readBoolean() ? ComponentSerializers.JSON.deserialize(ProtocolUtils.readString(buf)) :
|
|
||||||
null;
|
|
||||||
offers.add(new Offer(entry, component));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int offersAvailable = ProtocolUtils.readVarInt(buf);
|
|
||||||
for (int i = 0; i < offersAvailable; i++) {
|
|
||||||
offers.add(new Offer(ProtocolUtils.readString(buf), null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
if (protocolVersion >= MINECRAFT_1_13) {
|
|
||||||
ProtocolUtils.writeVarInt(buf, transactionId);
|
|
||||||
ProtocolUtils.writeVarInt(buf, start);
|
|
||||||
ProtocolUtils.writeVarInt(buf, length);
|
|
||||||
ProtocolUtils.writeVarInt(buf, offers.size());
|
ProtocolUtils.writeVarInt(buf, offers.size());
|
||||||
for (Offer offer : offers) {
|
for (String offer : offers) {
|
||||||
ProtocolUtils.writeString(buf, offer.entry);
|
ProtocolUtils.writeString(buf, offer);
|
||||||
buf.writeBoolean(offer.tooltip != null);
|
|
||||||
if (offer.tooltip != null) {
|
|
||||||
ProtocolUtils.writeString(buf, ComponentSerializers.JSON.serialize(offer.tooltip));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ProtocolUtils.writeVarInt(buf, offers.size());
|
|
||||||
for (Offer offer : offers) {
|
|
||||||
ProtocolUtils.writeString(buf, offer.entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Offer {
|
|
||||||
private final String entry;
|
|
||||||
private final Component tooltip;
|
|
||||||
|
|
||||||
public Offer(String entry, @Nullable Component tooltip) {
|
|
||||||
this.entry = entry;
|
|
||||||
this.tooltip = tooltip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEntry() {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable Component getTooltip() {
|
|
||||||
return tooltip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Offer{" +
|
|
||||||
"entry='" + entry + '\'' +
|
|
||||||
", tooltip=" + tooltip +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren