3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-12-24 23:30:26 +01:00

Initial 1.13 support

Still kind of wonky but mostly works
Dieser Commit ist enthalten in:
Andrew Steinborn 2018-07-30 22:19:27 -04:00
Ursprung 8c4d710725
Commit ed8a279cd1
12 geänderte Dateien mit 175 neuen und 69 gelöschten Zeilen

Datei anzeigen

@ -55,6 +55,11 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
newPacket = PluginMessageUtil.rewriteMCBrand(pm);
}
if (newPacket == pm) {
// we'll decrement this thrice: once when writing to the server, once just below this block,
// and once in the MinecraftConnection (since this is a slice)
pm.getData().retain();
}
connection.getProxyPlayer().getConnection().write(newPacket);
} finally {
ReferenceCountUtil.release(pm.getData());
@ -85,10 +90,14 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
}
private boolean canForwardPluginMessage(PluginMessage message) {
// TODO: Update for 1.13
ClientPlaySessionHandler playerHandler =
(ClientPlaySessionHandler) connection.getProxyPlayer().getConnection().getSessionHandler();
return message.getChannel().startsWith("MC|") ||
playerHandler.getClientPluginMsgChannels().contains(message.getChannel());
if (connection.getChannel().getProtocolVersion() <= ProtocolConstants.MINECRAFT_1_12_2) {
return message.getChannel().startsWith("MC|") ||
playerHandler.getClientPluginMsgChannels().contains(message.getChannel());
} else {
return message.getChannel().startsWith("minecraft:") ||
playerHandler.getClientPluginMsgChannels().contains(message.getChannel());
}
}
}

Datei anzeigen

@ -167,8 +167,10 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
// Tell the server about this client's plugin messages. Velocity will forward them on to the client.
if (!clientPluginMsgChannels.isEmpty()) {
String channel = player.getConnection().getProtocolVersion() >= ProtocolConstants.MINECRAFT_1_13 ?
"minecraft:register" : "REGISTER";
player.getConnectedServer().getChannel().delayedWrite(
PluginMessageUtil.constructChannelsPacket("REGISTER", clientPluginMsgChannels));
PluginMessageUtil.constructChannelsPacket(channel, clientPluginMsgChannels));
}
// Tell the server the client's brand
@ -195,7 +197,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
PluginMessage original = packet;
try {
if (packet.getChannel().equals("REGISTER")) {
if (packet.getChannel().equals("REGISTER") || packet.getChannel().equals("minecraft:register")) {
List<String> actuallyRegistered = new ArrayList<>();
List<String> channels = PluginMessageUtil.getChannels(packet);
for (String channel : channels) {
@ -210,19 +212,19 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
if (actuallyRegistered.size() > 0) {
logger.info("Rewritten register packet: {}", actuallyRegistered);
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket("REGISTER", actuallyRegistered);
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket(packet.getChannel(), actuallyRegistered);
player.getConnectedServer().getChannel().write(newRegisterPacket);
}
return;
}
if (packet.getChannel().equals("UNREGISTER")) {
if (packet.getChannel().equals("UNREGISTER") || packet.getChannel().equals("minecraft:unregister")) {
List<String> channels = PluginMessageUtil.getChannels(packet);
clientPluginMsgChannels.removeAll(channels);
}
if (packet.getChannel().equals("MC|Brand")) {
if (packet.getChannel().equals("MC|Brand") || packet.getChannel().equals("minecraft:brand")) {
if (this.brandMessage != null) {
// Rewrite this packet to indicate that Velocity is running. Hurrah!
packet = PluginMessageUtil.rewriteMCBrand(packet);

Datei anzeigen

@ -1,5 +1,7 @@
package com.velocitypowered.proxy.data.scoreboard;
import net.kyori.text.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -7,8 +9,8 @@ import java.util.Map;
public class Objective {
private final String id;
private String displayName;
private String type;
private Component displayName;
private ObjectiveMode type;
private final List<Team> teams = new ArrayList<>();
private final Map<String, Score> scores = new HashMap<>();
@ -20,14 +22,22 @@ public class Objective {
return id;
}
public String getDisplayName() {
public Component getDisplayName() {
return displayName;
}
public String getType() {
public void setDisplayName(Component displayName) {
this.displayName = displayName;
}
public ObjectiveMode getType() {
return type;
}
public void setType(ObjectiveMode type) {
this.type = type;
}
public List<Team> getTeams() {
return teams;
}
@ -36,14 +46,6 @@ public class Objective {
return scores;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "Objective{" +

Datei anzeigen

@ -0,0 +1,6 @@
package com.velocitypowered.proxy.data.scoreboard;
public enum ObjectiveMode {
INTEGER,
HEARTS
}

Datei anzeigen

@ -13,6 +13,7 @@ public enum ProtocolConstants { ;
public static final int MINECRAFT_1_12 = 335;
public static final int MINECRAFT_1_12_1 = 338;
public static final int MINECRAFT_1_12_2 = 340;
public static final int MINECRAFT_1_13 = 393;
public static final int MINIMUM_GENERIC_VERSION = MINECRAFT_1_9;
@ -26,7 +27,8 @@ public enum ProtocolConstants { ;
MINECRAFT_1_11_1,
MINECRAFT_1_12,
MINECRAFT_1_12_1,
MINECRAFT_1_12_2
MINECRAFT_1_12_2,
MINECRAFT_1_13
};
public static boolean isSupported(int version) {

Datei anzeigen

@ -3,6 +3,9 @@ package com.velocitypowered.proxy.protocol;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import net.kyori.text.Component;
import net.kyori.text.serializer.ComponentSerializer;
import net.kyori.text.serializer.ComponentSerializers;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@ -79,4 +82,17 @@ public enum ProtocolUtils { ;
buf.writeLong(uuid.getMostSignificantBits());
buf.writeLong(uuid.getLeastSignificantBits());
}
public static Component readScoreboardTextComponent(ByteBuf buf, int protocolVersion) {
String toDeserialize = readString(buf);
ComponentSerializer<Component, ? extends Component, String> serializer =
protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ? ComponentSerializers.JSON : ComponentSerializers.LEGACY;
return serializer.deserialize(toDeserialize);
}
public static void writeScoreboardTextComponent(ByteBuf buf, int protocolVersion, Component component) {
ComponentSerializer<Component, ? extends Component, String> serializer =
protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ? ComponentSerializers.JSON : ComponentSerializers.LEGACY;
writeString(buf, serializer.serialize(component));
}
}

Datei anzeigen

@ -34,58 +34,72 @@ public enum StateRegistry {
SERVERBOUND.register(Chat.class, Chat::new,
map(0x02, MINECRAFT_1_9),
map(0x03, MINECRAFT_1_12),
map(0x02, MINECRAFT_1_12_2));
map(0x02, MINECRAFT_1_12_2),
map(0x02, MINECRAFT_1_13));
SERVERBOUND.register(ClientSettings.class, ClientSettings::new,
map(0x04, MINECRAFT_1_9),
map(0x05, MINECRAFT_1_12),
map(0x04, MINECRAFT_1_12_1));
map(0x04, MINECRAFT_1_12_1),
map(0x04, MINECRAFT_1_13));
SERVERBOUND.register(PluginMessage.class, PluginMessage::new,
map(0x09, MINECRAFT_1_9),
map(0x0A, MINECRAFT_1_12),
map(0x09, MINECRAFT_1_12_1));
map(0x09, MINECRAFT_1_12_1),
map(0x0A, MINECRAFT_1_13));
SERVERBOUND.register(KeepAlive.class, KeepAlive::new,
map(0x0B, MINECRAFT_1_9),
map(0x0C, MINECRAFT_1_12),
map(0x0B, MINECRAFT_1_12_1));
map(0x0B, MINECRAFT_1_12_1),
map(0x0E, MINECRAFT_1_13));
CLIENTBOUND.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9),
map(0x0C, MINECRAFT_1_12));
CLIENTBOUND.register(Chat.class, Chat::new,
map(0x0F, MINECRAFT_1_9),
map(0x0F, MINECRAFT_1_12));
map(0x0F, MINECRAFT_1_12),
map(0x0E, MINECRAFT_1_13));
CLIENTBOUND.register(PluginMessage.class, PluginMessage::new,
map(0x18, MINECRAFT_1_9),
map(0x18, MINECRAFT_1_12));
map(0x18, MINECRAFT_1_12),
map(0x19, MINECRAFT_1_13));
CLIENTBOUND.register(Disconnect.class, Disconnect::new,
map(0x1A, MINECRAFT_1_9),
map(0x1A, MINECRAFT_1_12));
map(0x1A, MINECRAFT_1_12),
map(0x1B, MINECRAFT_1_13));
CLIENTBOUND.register(KeepAlive.class, KeepAlive::new,
map(0x1F, MINECRAFT_1_9),
map(0x1F, MINECRAFT_1_12));
map(0x1F, MINECRAFT_1_12),
map(0x21, MINECRAFT_1_13));
CLIENTBOUND.register(JoinGame.class, JoinGame::new,
map(0x23, MINECRAFT_1_9),
map(0x23, MINECRAFT_1_12));
map(0x23, MINECRAFT_1_12),
map(0x25, MINECRAFT_1_13));
CLIENTBOUND.register(Respawn.class, Respawn::new,
map(0x33, MINECRAFT_1_9),
map(0x34, MINECRAFT_1_12),
map(0x35, MINECRAFT_1_12_2));
map(0x35, MINECRAFT_1_12_2),
map(0x38, MINECRAFT_1_13));
CLIENTBOUND.register(ScoreboardDisplay.class, ScoreboardDisplay::new,
map(0x38, MINECRAFT_1_9),
map(0x3A, MINECRAFT_1_12),
map(0x3B, MINECRAFT_1_12_1));
map(0x3B, MINECRAFT_1_12_1),
map(0x3E, MINECRAFT_1_13));
CLIENTBOUND.register(ScoreboardObjective.class, ScoreboardObjective::new,
map(0x3F, MINECRAFT_1_9),
map(0x41, MINECRAFT_1_12),
map(0x42, MINECRAFT_1_12_1));
map(0x42, MINECRAFT_1_12_1),
map(0x45, MINECRAFT_1_13));
CLIENTBOUND.register(ScoreboardTeam.class, ScoreboardTeam::new,
map(0x41, MINECRAFT_1_9),
map(0x43, MINECRAFT_1_12),
map(0x44, MINECRAFT_1_12_1));
map(0x44, MINECRAFT_1_12_1),
map(0x47, MINECRAFT_1_13));
CLIENTBOUND.register(ScoreboardSetScore.class, ScoreboardSetScore::new,
map(0x42, MINECRAFT_1_9),
map(0x44, MINECRAFT_1_12),
map(0x45, MINECRAFT_1_12_1));
map(0x45, MINECRAFT_1_12_1),
map(0x48, MINECRAFT_1_13));
}
},
LOGIN {
@ -247,7 +261,8 @@ public enum StateRegistry {
private static PacketMapping[] genericMappings(int id) {
return new PacketMapping[]{
map(id, MINECRAFT_1_9),
map(id, MINECRAFT_1_12)
map(id, MINECRAFT_1_12),
map(id, MINECRAFT_1_13)
};
}
}

Datei anzeigen

@ -36,7 +36,7 @@ public class PluginMessage implements MinecraftPacket {
@Override
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
this.channel = ProtocolUtils.readString(buf, 20);
this.channel = ProtocolUtils.readString(buf);
this.data = buf.readRetainedSlice(buf.readableBytes());
}

Datei anzeigen

@ -1,15 +1,18 @@
package com.velocitypowered.proxy.protocol.packets;
import com.velocitypowered.proxy.data.scoreboard.ObjectiveMode;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolConstants;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.util.ScoreboardProtocolUtil;
import io.netty.buffer.ByteBuf;
import net.kyori.text.Component;
public class ScoreboardObjective implements MinecraftPacket {
private String id;
private byte mode;
private String displayName;
private String type;
private Component displayName;
private ObjectiveMode type;
public String getId() {
return id;
@ -27,19 +30,19 @@ public class ScoreboardObjective implements MinecraftPacket {
this.mode = mode;
}
public String getDisplayName() {
public Component getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
public void setDisplayName(Component displayName) {
this.displayName = displayName;
}
public String getType() {
public ObjectiveMode getType() {
return type;
}
public void setType(String type) {
public void setType(ObjectiveMode type) {
this.type = type;
}
@ -58,8 +61,12 @@ public class ScoreboardObjective implements MinecraftPacket {
this.id = ProtocolUtils.readString(buf, 16);
this.mode = buf.readByte();
if (this.mode != 1) {
this.displayName = ProtocolUtils.readString(buf);
this.type = ProtocolUtils.readString(buf);
this.displayName = ProtocolUtils.readScoreboardTextComponent(buf, protocolVersion);
if (protocolVersion >= ProtocolConstants.MINECRAFT_1_13) {
this.type = ScoreboardProtocolUtil.getMode(ProtocolUtils.readVarInt(buf));
} else {
this.type = ScoreboardProtocolUtil.getMode(ProtocolUtils.readString(buf));
}
}
}
@ -68,8 +75,12 @@ public class ScoreboardObjective implements MinecraftPacket {
ProtocolUtils.writeString(buf, id);
buf.writeByte(mode);
if (this.mode != 1) {
ProtocolUtils.writeString(buf, displayName);
ProtocolUtils.writeString(buf, type);
ProtocolUtils.writeScoreboardTextComponent(buf, protocolVersion, displayName);
if (protocolVersion >= ProtocolConstants.MINECRAFT_1_13) {
ProtocolUtils.writeVarInt(buf, type.ordinal());
} else {
ProtocolUtils.writeString(buf, type.name().toLowerCase());
}
}
}
}

Datei anzeigen

@ -4,6 +4,7 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolConstants;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import net.kyori.text.Component;
import java.util.ArrayList;
import java.util.List;
@ -12,13 +13,13 @@ public class ScoreboardTeam implements MinecraftPacket {
private String id;
private byte mode;
private String displayName;
private String prefix;
private String suffix;
private Component displayName;
private Component prefix;
private Component suffix;
private byte flags;
private String nameTagVisibility;
private String collisionRule;
private byte color;
private int color;
private List<String> entities;
public String getId() {
@ -37,27 +38,27 @@ public class ScoreboardTeam implements MinecraftPacket {
this.mode = mode;
}
public String getDisplayName() {
public Component getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
public void setDisplayName(Component displayName) {
this.displayName = displayName;
}
public String getPrefix() {
public Component getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
public void setPrefix(Component prefix) {
this.prefix = prefix;
}
public String getSuffix() {
public Component getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
public void setSuffix(Component suffix) {
this.suffix = suffix;
}
@ -85,11 +86,11 @@ public class ScoreboardTeam implements MinecraftPacket {
this.collisionRule = collisionRule;
}
public byte getColor() {
public int getColor() {
return color;
}
public void setColor(byte color) {
public void setColor(int color) {
this.color = color;
}
@ -125,13 +126,20 @@ public class ScoreboardTeam implements MinecraftPacket {
switch (mode) {
case 0: // create
case 2: // update
this.displayName = ProtocolUtils.readString(buf);
this.prefix = ProtocolUtils.readString(buf);
this.suffix = ProtocolUtils.readString(buf);
this.displayName = ProtocolUtils.readScoreboardTextComponent(buf, protocolVersion);
if (protocolVersion <= ProtocolConstants.MINECRAFT_1_12_2) {
this.prefix = ProtocolUtils.readScoreboardTextComponent(buf, protocolVersion);
this.suffix = ProtocolUtils.readScoreboardTextComponent(buf, protocolVersion);
}
this.flags = buf.readByte();
this.nameTagVisibility = ProtocolUtils.readString(buf, 32);
this.collisionRule = ProtocolUtils.readString(buf, 32);
this.color = buf.readByte();
this.color = protocolVersion <= ProtocolConstants.MINECRAFT_1_12_2 ? buf.readByte() :
ProtocolUtils.readVarInt(buf);
if (protocolVersion >= ProtocolConstants.MINECRAFT_1_13) {
this.prefix = ProtocolUtils.readScoreboardTextComponent(buf, protocolVersion);
this.suffix = ProtocolUtils.readScoreboardTextComponent(buf, protocolVersion);
}
if (mode == 0) {
this.entities = readEntities(buf);
}
@ -152,13 +160,22 @@ public class ScoreboardTeam implements MinecraftPacket {
switch (mode) {
case 0: // create
case 2: // update
ProtocolUtils.writeString(buf, displayName);
ProtocolUtils.writeString(buf, prefix);
ProtocolUtils.writeString(buf, suffix);
ProtocolUtils.writeScoreboardTextComponent(buf, protocolVersion, displayName);
if (protocolVersion <= ProtocolConstants.MINECRAFT_1_12_2) {
ProtocolUtils.writeScoreboardTextComponent(buf, protocolVersion, prefix);
ProtocolUtils.writeScoreboardTextComponent(buf, protocolVersion, suffix);
}
buf.writeByte(flags);
ProtocolUtils.writeString(buf, nameTagVisibility);
ProtocolUtils.writeString(buf, collisionRule);
buf.writeByte(color);
if (protocolVersion >= ProtocolConstants.MINECRAFT_1_13) {
ProtocolUtils.writeVarInt(buf, color);
ProtocolUtils.writeScoreboardTextComponent(buf, protocolVersion, prefix);
ProtocolUtils.writeScoreboardTextComponent(buf, protocolVersion, suffix);
} else {
buf.writeByte(color);
}
if (mode == 0) {
writeEntities(buf, entities);
}

Datei anzeigen

@ -1,6 +1,5 @@
package com.velocitypowered.proxy.protocol.util;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
@ -18,7 +17,10 @@ public enum PluginMessageUtil {
public static List<String> getChannels(PluginMessage message) {
Preconditions.checkArgument(message.getChannel().equals("REGISTER") ||
message.getChannel().equals("UNREGISTER"), "Unknown channel type " + message.getChannel());
message.getChannel().equals("UNREGISTER") ||
message.getChannel().equals("minecraft:register") ||
message.getChannel().equals("minecraft:unregister"),
"Unknown channel type " + message.getChannel());
String channels = message.getData().toString(StandardCharsets.UTF_8);
return ImmutableList.copyOf(channels.split("\0"));
}
@ -44,7 +46,7 @@ public enum PluginMessageUtil {
ProtocolUtils.writeString(rewrittenBuf, currentBrand + " (Velocity)");
PluginMessage newMsg = new PluginMessage();
newMsg.setChannel("MC|Brand");
newMsg.setChannel(message.getChannel());
newMsg.setData(rewrittenBuf);
return newMsg;
}

Datei anzeigen

@ -0,0 +1,24 @@
package com.velocitypowered.proxy.protocol.util;
import com.velocitypowered.proxy.data.scoreboard.ObjectiveMode;
public class ScoreboardProtocolUtil {
private ScoreboardProtocolUtil() {
throw new AssertionError();
}
public static ObjectiveMode getMode(String mode) {
return ObjectiveMode.valueOf(mode.toUpperCase());
}
public static ObjectiveMode getMode(int enumVal) {
switch (enumVal) {
case 0:
return ObjectiveMode.INTEGER;
case 1:
return ObjectiveMode.HEARTS;
default:
throw new IllegalStateException("Unknown mode " + enumVal);
}
}
}