3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-11-20 06:50:08 +01:00

Merge branch 'master' into dev

Dieser Commit ist enthalten in:
Myles 2018-11-17 14:11:04 +00:00
Commit 9ba5cc1f98
56 geänderte Dateien mit 4868 neuen und 149 gelöschten Zeilen

26
.github/ISSUE_TEMPLATE/bug_report.md vendored Normale Datei
Datei anzeigen

@ -0,0 +1,26 @@
---
name: Bug report
about: Create a bug report so we can fix it
---
**Describe the bug, provide any errors**
A clear and concise description of what the bug is. Can you https://hastebin.com the error?
**How can we reproduce it?**
Steps to reproduce the behavior:
1. Login on 1.12'
2. Click on '....'
3. The '....' is displayed wrong
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**ViaVersion Dump:**
- Type /viaversion dump, and put the link here.
**Additional server info**
Do you use a proxy (eg. BungeeCord)? What software do you use and what plugins?

17
.github/ISSUE_TEMPLATE/feature_request.md vendored Normale Datei
Datei anzeigen

@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for ViaVersion
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Which versions is this for?**
Does the feature apply to any specific versions? If so put them here.

Datei anzeigen

@ -1,11 +0,0 @@
### What is the output link of /viaversion dump?
### Are you using any additional software like BungeeCord? If so, what software and version? (Please list your plugins as well)
### How does this error happen? login? Using an item?
### Is there an error in the console? Use pastebin.com. Is there a kick message?

Datei anzeigen

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

Datei anzeigen

@ -34,7 +34,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
private boolean lateBind = false; private boolean lateBind = false;
private boolean protocolSupport = false; private boolean protocolSupport = false;
@Getter @Getter
private BukkitConfigAPI conf; private BukkitViaConfig conf;
@Getter @Getter
private ViaAPI<Player> api = new BukkitViaAPI(this); private ViaAPI<Player> api = new BukkitViaAPI(this);
private List<Runnable> queuedTasks = new ArrayList<>(); private List<Runnable> queuedTasks = new ArrayList<>();
@ -51,7 +51,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
.loader(new BukkitViaLoader(this)) .loader(new BukkitViaLoader(this))
.build()); .build());
// Config magic // Config magic
conf = new BukkitConfigAPI(); conf = new BukkitViaConfig();
// For compatibility // For compatibility
ViaVersion.setInstance(this); ViaVersion.setInstance(this);

Datei anzeigen

@ -11,10 +11,10 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class BukkitConfigAPI extends Config implements ViaVersionConfig { public class BukkitViaConfig extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers"); private static List<String> UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers");
public BukkitConfigAPI() { public BukkitViaConfig() {
super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml")); super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml"));
// Load config // Load config
reloadConfig(); reloadConfig();
@ -192,7 +192,7 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig {
@Override @Override
public URL getDefaultConfigURL() { public URL getDefaultConfigURL() {
return BukkitConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml"); return BukkitViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml");
} }
@Override @Override

Datei anzeigen

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

Datei anzeigen

@ -31,13 +31,13 @@ import java.util.concurrent.TimeUnit;
public class BungeePlugin extends Plugin implements ViaPlatform, Listener { public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
private BungeeViaAPI api; private BungeeViaAPI api;
private BungeeConfigAPI config; private BungeeViaConfig config;
private BungeeCommandHandler commandHandler; private BungeeCommandHandler commandHandler;
@Override @Override
public void onLoad() { public void onLoad() {
api = new BungeeViaAPI(); api = new BungeeViaAPI();
config = new BungeeConfigAPI(getDataFolder()); config = new BungeeViaConfig(getDataFolder());
commandHandler = new BungeeCommandHandler(); commandHandler = new BungeeCommandHandler();
ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler)); ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler));
// Init platform // Init platform
@ -134,7 +134,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
} }
@Override @Override
public BungeeConfigAPI getConf() { public BungeeViaConfig getConf() {
return config; return config;
} }

Datei anzeigen

@ -3,7 +3,7 @@ package us.myles.ViaVersion.bungee.commands.subs;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.command.ViaCommandSender; import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand; import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI; import us.myles.ViaVersion.bungee.platform.BungeeViaConfig;
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService; import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
public class ProbeSubCmd extends ViaSubCommand { public class ProbeSubCmd extends ViaSubCommand {
@ -15,7 +15,7 @@ public class ProbeSubCmd extends ViaSubCommand {
@Override @Override
public String description() { public String description() {
return "Forces ViaVersion to scan server protocol versions " + return "Forces ViaVersion to scan server protocol versions " +
(((BungeeConfigAPI) Via.getConfig()).getBungeePingInterval() == -1 ? (((BungeeViaConfig) Via.getConfig()).getBungeePingInterval() == -1 ?
"" : "(Also happens at an interval)"); "" : "(Also happens at an interval)");
} }

Datei anzeigen

@ -9,10 +9,10 @@ import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.*;
public class BungeeConfigAPI extends Config implements ViaVersionConfig { public class BungeeViaConfig extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix"); private static List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers");
public BungeeConfigAPI(File configFile) { public BungeeViaConfig(File configFile) {
super(new File(configFile, "config.yml")); super(new File(configFile, "config.yml"));
// Load config // Load config
reloadConfig(); reloadConfig();
@ -20,7 +20,7 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig {
@Override @Override
public URL getDefaultConfigURL() { public URL getDefaultConfigURL() {
return BungeeConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml"); return BungeeViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml");
} }
@Override @Override

Datei anzeigen

@ -6,7 +6,7 @@ import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
import us.myles.ViaVersion.BungeePlugin; import us.myles.ViaVersion.BungeePlugin;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI; import us.myles.ViaVersion.bungee.platform.BungeeViaConfig;
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider; import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
import java.util.HashMap; import java.util.HashMap;
@ -26,7 +26,7 @@ public class ProtocolDetectorService implements Runnable {
public static Integer getProtocolId(String serverName) { public static Integer getProtocolId(String serverName) {
// Step 1. Check Config // Step 1. Check Config
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
Integer protocol = servers.get(serverName); Integer protocol = servers.get(serverName);
if (protocol != null) { if (protocol != null) {
return protocol; return protocol;
@ -58,9 +58,11 @@ public class ProtocolDetectorService implements Runnable {
@Override @Override
public void done(ServerPing serverPing, Throwable throwable) { public void done(ServerPing serverPing, Throwable throwable) {
if (throwable == null && serverPing != null && serverPing.getVersion() != null) { if (throwable == null && serverPing != null && serverPing.getVersion() != null) {
// Ensure protocol is positive, some services will return -1
if (serverPing.getVersion().getProtocol() > 0) {
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) { if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) {
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
Integer protocol = servers.get(key); Integer protocol = servers.get(key);
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
return; return;
@ -74,6 +76,7 @@ public class ProtocolDetectorService implements Runnable {
} }
} }
} }
}
}); });
} }

Datei anzeigen

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -17,7 +17,7 @@
<groupId>org.yaml</groupId> <groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId> <artifactId>snakeyaml</artifactId>
<version>1.18</version> <version>1.18</version>
<scope>provided</scope> <scope>compile</scope> <!-- Velocity doesn't have snakeyaml -->
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

Datei anzeigen

@ -18,6 +18,8 @@ import us.myles.ViaVersion.util.PipelineUtil;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Data @Data
public class UserConnection { public class UserConnection {
@ -36,7 +38,7 @@ public class UserConnection {
// Used for handling warnings (over time) // Used for handling warnings (over time)
private int secondsObserved = 0; private int secondsObserved = 0;
private int warnings = 0; private int warnings = 0;
private ReadWriteLock velocityLock = new ReentrantReadWriteLock();
public UserConnection(Channel channel) { public UserConnection(Channel channel) {
this.channel = channel; this.channel = channel;
@ -108,7 +110,8 @@ public class UserConnection {
*/ */
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) { public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName()); final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
return channel.pipeline().context(handler).writeAndFlush(packet); ChannelFuture future = channel.pipeline().context(handler).writeAndFlush(packet);
return future;
} }
/** /**
@ -218,7 +221,8 @@ public class UserConnection {
} }
buf.writeBytes(packet); buf.writeBytes(packet);
packet.release(); packet.release();
final ChannelHandlerContext context = PipelineUtil.getPreviousContext(Via.getManager().getInjector().getDecoderName(), getChannel().pipeline()); final ChannelHandlerContext context = PipelineUtil
.getPreviousContext(Via.getManager().getInjector().getDecoderName(), getChannel().pipeline());
if (currentThread) { if (currentThread) {
if (context != null) { if (context != null) {
context.fireChannelRead(buf); context.fireChannelRead(buf);

Datei anzeigen

@ -74,7 +74,7 @@ public abstract class ViaCommandHandler implements ViaVersionCommand {
//SubCommands tabcomplete //SubCommands tabcomplete
if (args.length == 1) { if (args.length == 1) {
if (!args[0].equals("")) { if (!args[0].isEmpty()) {
for (ViaSubCommand sub : allowed) for (ViaSubCommand sub : allowed)
if (sub.name().toLowerCase().startsWith(args[0].toLowerCase())) if (sub.name().toLowerCase().startsWith(args[0].toLowerCase()))
output.add(sub.name()); output.add(sub.name());

Datei anzeigen

@ -90,6 +90,22 @@ public class Protocol1_13_1To1_13 extends Protocol {
} }
}); });
// Set cooldown
registerOutgoing(State.PLAY, 0x18, 0x18, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.VAR_INT, 0,
InventoryPackets.getNewItemId(wrapper.get(Type.VAR_INT, 0))
);
}
});
}
});
// Boss bar // Boss bar
registerOutgoing(State.PLAY, 0x0C, 0x0C, new PacketRemapper() { registerOutgoing(State.PLAY, 0x0C, 0x0C, new PacketRemapper() {
@Override @Override

Datei anzeigen

@ -26,8 +26,7 @@ public class Protocol1_13_2To1_13_1 extends Protocol {
registerIncoming(State.PLAY, 0x0B, 0x0B, new PacketRemapper() { registerIncoming(State.PLAY, 0x0B, 0x0B, new PacketRemapper() {
@Override @Override
public void registerMap() { public void registerMap() {
map(Type.FLAT_ITEM, Type.FLAT_VAR_INT_ITEM); map(Type.FLAT_VAR_INT_ITEM, Type.FLAT_ITEM);
map(Type.BOOLEAN);
} }
}); });

Datei anzeigen

@ -4,7 +4,9 @@ import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -115,4 +117,43 @@ public class ChatRewriter {
public static String jsonTextToLegacy(String value) { public static String jsonTextToLegacy(String value) {
return TextComponent.toLegacyText(ComponentSerializer.parse(value)); return TextComponent.toLegacyText(ComponentSerializer.parse(value));
} }
public static String processTranslate(String value) {
BaseComponent[] components = ComponentSerializer.parse(value);
for (BaseComponent component : components) {
processTranslate(component);
}
if (components.length == 1) {
return ComponentSerializer.toString(components[0]);
} else {
return ComponentSerializer.toString(components);
}
}
private static void processTranslate(BaseComponent component) {
if (component instanceof TranslatableComponent) {
String oldTranslate = ((TranslatableComponent) component).getTranslate();
String newTranslate;
newTranslate = MappingData.translateMapping.get(oldTranslate);
if (newTranslate == null) MappingData.mojangTranslation.get(oldTranslate);
if (newTranslate != null) {
((TranslatableComponent) component).setTranslate(newTranslate);
}
if (((TranslatableComponent) component).getWith() != null) {
for (BaseComponent baseComponent : ((TranslatableComponent) component).getWith()) {
processTranslate(baseComponent);
}
}
}
if (component.getHoverEvent() != null) {
for (BaseComponent baseComponent : component.getHoverEvent().getValue()) {
processTranslate(baseComponent);
}
}
if (component.getExtra() != null) {
for (BaseComponent baseComponent : component.getExtra()) {
processTranslate(baseComponent);
}
}
}
} }

Datei anzeigen

@ -47,7 +47,8 @@ public class Protocol1_13To1_12_2 extends Protocol {
} }
}; };
public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS = new PacketHandler() { // *insert here a good name* public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS =
new PacketHandler() { // *insert here a good name*
@Override @Override
public void handle(PacketWrapper w) throws Exception { public void handle(PacketWrapper w) throws Exception {
// Send fake declare commands // Send fake declare commands
@ -98,26 +99,26 @@ public class Protocol1_13To1_12_2 extends Protocol {
}; };
// These are arbitrary rewrite values, it just needs an invalid color code character. // These are arbitrary rewrite values, it just needs an invalid color code character.
protected static EnumMap<ChatColor, String> SCOREBOARD_TEAM_NAME_REWRITE = new EnumMap<ChatColor, String>(ChatColor.class) {{ protected static EnumMap<ChatColor, Character> SCOREBOARD_TEAM_NAME_REWRITE = new EnumMap<>(ChatColor.class);
put(ChatColor.BLACK, ChatColor.COLOR_CHAR + "g"); // @formatter:on
put(ChatColor.DARK_BLUE, ChatColor.COLOR_CHAR + "h");
put(ChatColor.DARK_GREEN, ChatColor.COLOR_CHAR + "i");
put(ChatColor.DARK_AQUA, ChatColor.COLOR_CHAR + "j");
put(ChatColor.DARK_RED, ChatColor.COLOR_CHAR + "p");
put(ChatColor.DARK_PURPLE, ChatColor.COLOR_CHAR + "q");
put(ChatColor.GOLD, ChatColor.COLOR_CHAR + "s");
put(ChatColor.GRAY, ChatColor.COLOR_CHAR + "t");
put(ChatColor.DARK_GRAY, ChatColor.COLOR_CHAR + "u");
put(ChatColor.BLUE, ChatColor.COLOR_CHAR + "v");
put(ChatColor.GREEN, ChatColor.COLOR_CHAR + "w");
put(ChatColor.AQUA, ChatColor.COLOR_CHAR + "x");
put(ChatColor.RED, ChatColor.COLOR_CHAR + "y");
put(ChatColor.LIGHT_PURPLE, ChatColor.COLOR_CHAR + "z");
put(ChatColor.YELLOW, ChatColor.COLOR_CHAR + "!");
put(ChatColor.WHITE, ChatColor.COLOR_CHAR + "?");
}};
static { static {
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.BLACK, 'g');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_BLUE, 'h');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_GREEN, 'i');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_AQUA, 'j');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_RED, 'p');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_PURPLE, 'q');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.GOLD, 's');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.GRAY, 't');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.DARK_GRAY, 'u');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.BLUE, 'v');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.GREEN, 'w');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.AQUA, 'x');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.RED, 'y');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.LIGHT_PURPLE, 'z');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.YELLOW, '!');
SCOREBOARD_TEAM_NAME_REWRITE.put(ChatColor.WHITE, '?');
MappingData.init(); MappingData.init();
} }
@ -130,6 +131,19 @@ public class Protocol1_13To1_12_2 extends Protocol {
// Outgoing packets // Outgoing packets
registerOutgoing(State.LOGIN, 0x0, 0x0, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0)));
}
});
}
});
registerOutgoing(State.STATUS, 0x00, 0x00, new PacketRemapper() { registerOutgoing(State.STATUS, 0x00, 0x00, new PacketRemapper() {
@Override @Override
public void registerMap() { public void registerMap() {
@ -169,7 +183,36 @@ public class Protocol1_13To1_12_2 extends Protocol {
} }
}); });
registerOutgoing(State.PLAY, 0xF, 0xE); // Boss bar
registerOutgoing(State.PLAY, 0xC, 0xC, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UUID);
map(Type.VAR_INT);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int action = wrapper.get(Type.VAR_INT, 0);
if (action == 0 || action == 3) {
wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING)));
}
}
});
}
});
// Chat message
registerOutgoing(State.PLAY, 0xF, 0xE, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0)));
}
});
}
});
// WorldPackets 0x10 -> 0x0F // WorldPackets 0x10 -> 0x0F
// Tab-Complete // Tab-Complete
@ -217,13 +260,77 @@ public class Protocol1_13To1_12_2 extends Protocol {
// New packet 0x11, declare commands // New packet 0x11, declare commands
registerOutgoing(State.PLAY, 0x11, 0x12); registerOutgoing(State.PLAY, 0x11, 0x12);
registerOutgoing(State.PLAY, 0x12, 0x13); registerOutgoing(State.PLAY, 0x12, 0x13);
registerOutgoing(State.PLAY, 0x13, 0x14); // Open window
registerOutgoing(State.PLAY, 0x13, 0x14, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // Id
map(Type.STRING); // Window type
map(Type.STRING); // Title
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.STRING, 1, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 1)));
}
});
}
});
// InventoryPackets 0x14 -> 0x15 // InventoryPackets 0x14 -> 0x15
// InventoryPackets 0x15 -> 0x16 // InventoryPackets 0x15 -> 0x16
// InventoryPackets 0x16 -> 0x17 // InventoryPackets 0x16 -> 0x17
registerOutgoing(State.PLAY, 0x17, 0x18); // Set cooldown
registerOutgoing(State.PLAY, 0x17, 0x18, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int item = wrapper.read(Type.VAR_INT);
int ticks = wrapper.read(Type.VAR_INT);
wrapper.cancel();
if (item == 383) { // Spawn egg
for (int i = 0; i < 44; i++) {
Integer newItem = MappingData.oldToNewItems.get(item << 16 | i);
if (newItem != null) {
PacketWrapper packet = wrapper.create(0x18);
packet.write(Type.VAR_INT, newItem);
packet.write(Type.VAR_INT, ticks);
packet.send(Protocol1_13To1_12_2.class);
} else {
break;
}
}
} else {
for (int i = 0; i < 16; i++) {
Integer newItem = MappingData.oldToNewItems.get(item << 4 | i);
if (newItem != null) {
PacketWrapper packet = wrapper.create(0x18);
packet.write(Type.VAR_INT, newItem);
packet.write(Type.VAR_INT, ticks);
packet.send(Protocol1_13To1_12_2.class);
} else {
break;
}
}
}
}
});
}
});
// WorldPackets 0x18 -> 0x19 // WorldPackets 0x18 -> 0x19
registerOutgoing(State.PLAY, 0x1A, 0x1B); // Disconnect
registerOutgoing(State.PLAY, 0x1A, 0x1B, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0)));
}
});
}
});
registerOutgoing(State.PLAY, 0x1B, 0x1C); registerOutgoing(State.PLAY, 0x1B, 0x1C);
// New packet 0x1D - NBT Query // New packet 0x1D - NBT Query
registerOutgoing(State.PLAY, 0x1C, 0x1E); registerOutgoing(State.PLAY, 0x1C, 0x1E);
@ -326,7 +433,23 @@ public class Protocol1_13To1_12_2 extends Protocol {
} }
}); });
registerOutgoing(State.PLAY, 0x2C, 0x2E); registerOutgoing(State.PLAY, 0x2C, 0x2E);
registerOutgoing(State.PLAY, 0x2D, 0x2F); // Combat event
registerOutgoing(State.PLAY, 0x2D, 0x2F, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Event
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (wrapper.get(Type.VAR_INT, 0) == 2) { // Entity dead
wrapper.passthrough(Type.VAR_INT); // Player id
wrapper.passthrough(Type.INT); // Entity id
wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING)));
}
}
});
}
});
registerOutgoing(State.PLAY, 0x2E, 0x30); registerOutgoing(State.PLAY, 0x2E, 0x30);
// New 0x31 - Face Player // New 0x31 - Face Player
registerOutgoing(State.PLAY, 0x2F, 0x32); registerOutgoing(State.PLAY, 0x2F, 0x32);
@ -480,7 +603,22 @@ public class Protocol1_13To1_12_2 extends Protocol {
}); });
registerOutgoing(State.PLAY, 0x46, 0x49); registerOutgoing(State.PLAY, 0x46, 0x49);
registerOutgoing(State.PLAY, 0x47, 0x4A); registerOutgoing(State.PLAY, 0x47, 0x4A);
registerOutgoing(State.PLAY, 0x48, 0x4B); // Title
registerOutgoing(State.PLAY, 0x48, 0x4B, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // Action
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int action = wrapper.get(Type.VAR_INT, 0);
if (action >= 0 && action <= 2) {
wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING)));
}
}
});
}
});
// New 0x4C - Stop Sound // New 0x4C - Stop Sound
// Sound Effect packet // Sound Effect packet
@ -498,7 +636,21 @@ public class Protocol1_13To1_12_2 extends Protocol {
}); });
} }
}); });
registerOutgoing(State.PLAY, 0x4A, 0x4E); // Player list header and footer
registerOutgoing(State.PLAY, 0x4A, 0x4E, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
map(Type.STRING);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.STRING, 0, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 0)));
wrapper.set(Type.STRING, 1, ChatRewriter.processTranslate(wrapper.get(Type.STRING, 1)));
}
});
}
});
registerOutgoing(State.PLAY, 0x4B, 0x4F); registerOutgoing(State.PLAY, 0x4B, 0x4F);
registerOutgoing(State.PLAY, 0x4C, 0x50); registerOutgoing(State.PLAY, 0x4C, 0x50);
// Advancements // Advancements
@ -520,8 +672,8 @@ public class Protocol1_13To1_12_2 extends Protocol {
// Display data // Display data
if (wrapper.passthrough(Type.BOOLEAN)) { if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.STRING); // Title wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); // Title
wrapper.passthrough(Type.STRING); // Description wrapper.write(Type.STRING, ChatRewriter.processTranslate(wrapper.read(Type.STRING))); // Description
Item icon = wrapper.read(Type.ITEM); Item icon = wrapper.read(Type.ITEM);
InventoryPackets.toClient(icon); InventoryPackets.toClient(icon);
wrapper.write(Type.FLAT_ITEM, icon); // Translate item to flat item wrapper.write(Type.FLAT_ITEM, icon); // Translate item to flat item
@ -931,14 +1083,13 @@ public class Protocol1_13To1_12_2 extends Protocol {
// will just send colour as 'invisible' character // will just send colour as 'invisible' character
if (ChatColor.stripColor(name).length() == 0) { if (ChatColor.stripColor(name).length() == 0) {
StringBuilder newName = new StringBuilder(); StringBuilder newName = new StringBuilder();
for (int i = 0; i < name.length() / 2; i++) { for (int i = 1; i < name.length(); i += 2) {
ChatColor color = ChatColor.getByChar(name.charAt(i * 2 + 1)); char colorChar = name.charAt(i);
String rewrite = SCOREBOARD_TEAM_NAME_REWRITE.get(color); Character rewrite = SCOREBOARD_TEAM_NAME_REWRITE.get(ChatColor.getByChar(colorChar));
if (rewrite != null) { // just in case, should never happen if (rewrite == null) {
newName.append(rewrite); rewrite = colorChar;
} else {
newName.append(name);
} }
newName.append(ChatColor.COLOR_CHAR).append(rewrite);
} }
name = newName.toString(); name = newName.toString();
} }

Datei anzeigen

@ -2,15 +2,19 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.google.common.io.CharStreams;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.util.GsonUtil; import us.myles.ViaVersion.util.GsonUtil;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -21,6 +25,8 @@ public class MappingData {
public static Map<String, Integer[]> itemTags = new HashMap<>(); public static Map<String, Integer[]> itemTags = new HashMap<>();
public static Map<String, Integer[]> fluidTags = new HashMap<>(); public static Map<String, Integer[]> fluidTags = new HashMap<>();
public static BiMap<Short, String> oldEnchantmentsIds = HashBiMap.create(); public static BiMap<Short, String> oldEnchantmentsIds = HashBiMap.create();
public static Map<String, String> translateMapping = new HashMap<>();
public static Map<String, String> mojangTranslation = new HashMap<>();
public static EnchantmentMappings enchantmentMappings; public static EnchantmentMappings enchantmentMappings;
public static SoundMappings soundMappings; public static SoundMappings soundMappings;
public static BlockMappings blockMappings; public static BlockMappings blockMappings;
@ -42,6 +48,38 @@ public class MappingData {
enchantmentMappings = new EnchantmentMappingByteArray(mapping1_12.getAsJsonObject("enchantments"), mapping1_13.getAsJsonObject("enchantments")); enchantmentMappings = new EnchantmentMappingByteArray(mapping1_12.getAsJsonObject("enchantments"), mapping1_13.getAsJsonObject("enchantments"));
Via.getPlatform().getLogger().info("Loading 1.12.2 -> 1.13 sound mapping..."); Via.getPlatform().getLogger().info("Loading 1.12.2 -> 1.13 sound mapping...");
soundMappings = new SoundMappingShortArray(mapping1_12.getAsJsonArray("sounds"), mapping1_13.getAsJsonArray("sounds")); soundMappings = new SoundMappingShortArray(mapping1_12.getAsJsonArray("sounds"), mapping1_13.getAsJsonArray("sounds"));
Via.getPlatform().getLogger().info("Loading translation mappping");
translateMapping = new HashMap<>();
Map<String, String> translateData = GsonUtil.getGson().fromJson(
new InputStreamReader(
MappingData.class.getClassLoader()
.getResourceAsStream("assets/viaversion/data/mapping-lang-1.12-1.13.json")
),
(new TypeToken<Map<String, String>>(){}).getType());
try {
String[] lines;
try (Reader reader = new InputStreamReader(MappingData.class.getClassLoader()
.getResourceAsStream("mojang-translations/en_US.properties"), StandardCharsets.UTF_8)) {
lines = CharStreams.toString(reader).split("\n");
}
for (String line : lines) {
if (line.isEmpty()) continue;
String[] keyAndTranslation = line.split("=", 2);
if (keyAndTranslation.length != 2) continue;
String key = keyAndTranslation[0];
String translation = keyAndTranslation[1];
if (!translateData.containsKey(key)) {
translateMapping.put(key, translation);
} else {
String dataValue = translateData.get(keyAndTranslation[0]);
if (dataValue != null) {
translateMapping.put(key, dataValue);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
} }
public static JsonObject loadData(String name) { public static JsonObject loadData(String name) {

Datei anzeigen

@ -447,7 +447,7 @@ public class InventoryPackets {
case "WDL|REQUEST": case "WDL|REQUEST":
return "wdl:request"; return "wdl:request";
default: default:
return old.matches("[0-9a-z_-]+:[0-9a-z_/.-]+") // Identifier regex return old.matches("([0-9a-z_-]*:)?[0-9a-z_/.-]*") // Identifier regex
? old ? old
: "viaversion:legacy/" + BaseEncoding.base32().lowerCase().withPadChar('-').encode( : "viaversion:legacy/" + BaseEncoding.base32().lowerCase().withPadChar('-').encode(
old.getBytes(StandardCharsets.UTF_8)); old.getBytes(StandardCharsets.UTF_8));

Datei anzeigen

@ -17,6 +17,7 @@ import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter; import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.CommandBlockProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.CommandBlockProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect; import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect;
@ -121,16 +122,20 @@ public class WorldPackets {
@Override @Override
public void handle(PacketWrapper wrapper) throws Exception { public void handle(PacketWrapper wrapper) throws Exception {
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class); ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
Chunk1_8 chunk = (Chunk1_8) wrapper.passthrough(new Chunk1_9to1_8Type(clientChunks)); Chunk1_9to1_8Type type = new Chunk1_9to1_8Type(clientChunks);
Chunk1_8 chunk = (Chunk1_8) wrapper.read(type);
if (chunk.isUnloadPacket()) { if (chunk.isUnloadPacket()) {
wrapper.setId(0x1D); wrapper.setId(0x1D);
wrapper.write(Type.INT, chunk.getX());
wrapper.write(Type.INT, chunk.getZ());
// Remove commandBlocks on chunk unload // Remove commandBlocks on chunk unload
CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class); CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class);
provider.unloadChunk(wrapper.user(), chunk.getX(), chunk.getZ()); provider.unloadChunk(wrapper.user(), chunk.getX(), chunk.getZ());
} } else {
wrapper.write(type, chunk);
// eat any other data (Usually happens with unload packets) // eat any other data (Usually happens with unload packets)
}
wrapper.read(Type.REMAINING_BYTES); wrapper.read(Type.REMAINING_BYTES);
} }
}); });

Datei anzeigen

@ -4,7 +4,6 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk1_8;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.type.PartialType; import us.myles.ViaVersion.api.type.PartialType;
import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.Type;
@ -13,6 +12,7 @@ import us.myles.ViaVersion.api.type.types.version.Types1_8;
import us.myles.ViaVersion.api.type.types.version.Types1_9; import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4; import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
import java.util.ArrayList; import java.util.ArrayList;

Datei anzeigen

@ -5,6 +5,8 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder; 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.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -14,6 +16,7 @@ import java.util.List;
public class PipelineUtil { public class PipelineUtil {
private static Method DECODE_METHOD; private static Method DECODE_METHOD;
private static Method ENCODE_METHOD; private static Method ENCODE_METHOD;
private static Method MTM_DECODE;
static { static {
try { try {
@ -28,6 +31,12 @@ public class PipelineUtil {
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
e.printStackTrace(); e.printStackTrace();
} }
try {
MTM_DECODE = MessageToMessageDecoder.class.getDeclaredMethod("decode", ChannelHandlerContext.class, Object.class, List.class);
MTM_DECODE.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} }
/** /**
@ -66,6 +75,16 @@ public class PipelineUtil {
} }
} }
public static List<Object> callDecode(MessageToMessageDecoder decoder, ChannelHandlerContext ctx, Object msg) throws InvocationTargetException {
List<Object> output = new ArrayList<>();
try {
MTM_DECODE.invoke(decoder, ctx, msg, output);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return output;
}
/** /**
* Check if a stack trace contains a certain exception * Check if a stack trace contains a certain exception
* *

Datei anzeigen

@ -46,6 +46,28 @@ bungee-ping-save: true
bungee-servers: {} bungee-servers: {}
# #
#----------------------------------------------------------# #----------------------------------------------------------#
# VELOCITY OPTIONS #
#----------------------------------------------------------#
#
# Velocity allows you to have different server versions inside.
# Instead of you entering all the versions of these servers, we can ping them.
#
# What interval would you like us to ping at? (in seconds)
# Use -1 to disable.
velocity-ping-interval: 60
# If the above is enabled, should we save the info to the config (in the section below)
velocity-ping-save: true
# To get a servers protocol, ViaVersion will do the following:
# Look for the server in the following section, then look for the last ping if velocity-ping is enabled
# otherwise use default.
#
# The format for the following is:
# servername: protocolversion
# You can find protocol ids on http://wiki.vg/Protocol_version_numbers
# It will fallback to the default option if none found.
velocity-servers: {}
#
#----------------------------------------------------------#
# GLOBAL PACKET LIMITER # # GLOBAL PACKET LIMITER #
#----------------------------------------------------------# #----------------------------------------------------------#
# #

Datei-Diff unterdrückt, da er zu groß ist Diff laden

Datei anzeigen

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<name>viaversion-jar</name> <name>viaversion-jar</name>
@ -57,6 +57,10 @@
<pattern>org.javassist</pattern> <pattern>org.javassist</pattern>
<shadedPattern>us.myles.viaversion.libs.javassist</shadedPattern> <shadedPattern>us.myles.viaversion.libs.javassist</shadedPattern>
</relocation> </relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>us.myles.viaversion.libs.snakeyaml</shadedPattern>
</relocation>
</relocations> </relocations>
</configuration> </configuration>
<executions> <executions>
@ -92,6 +96,11 @@
<artifactId>viaversion-sponge</artifactId> <artifactId>viaversion-sponge</artifactId>
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
</dependency> </dependency>
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion-velocity</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

Datei anzeigen

@ -6,7 +6,7 @@
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>viaversion-parent</name> <name>viaversion-parent</name>
@ -21,6 +21,7 @@
<module>bungee</module> <module>bungee</module>
<module>sponge</module> <module>sponge</module>
<module>sponge-legacy</module> <module>sponge-legacy</module>
<module>velocity</module>
<module>jar</module> <module>jar</module>
</modules> </modules>

Datei anzeigen

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

Datei anzeigen

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>viaversion-parent</artifactId> <artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId> <groupId>us.myles</groupId>
<version>1.6.1-18w46a</version> <version>2.0.0-18w46a</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

Datei anzeigen

@ -55,7 +55,7 @@ public class SpongePlugin implements ViaPlatform {
@Getter @Getter
private SpongeViaAPI api = new SpongeViaAPI(); private SpongeViaAPI api = new SpongeViaAPI();
@Getter @Getter
private SpongeConfigAPI conf; private SpongeViaConfig conf;
@Getter @Getter
private Logger logger; private Logger logger;
@ -65,7 +65,7 @@ public class SpongePlugin implements ViaPlatform {
// Setup Logger // Setup Logger
logger = new LoggerWrapper(container.getLogger()); logger = new LoggerWrapper(container.getLogger());
// Setup Plugin // Setup Plugin
conf = new SpongeConfigAPI(container, defaultConfig.getParentFile()); conf = new SpongeViaConfig(container, defaultConfig.getParentFile());
SpongeCommandHandler commandHandler = new SpongeCommandHandler(); SpongeCommandHandler commandHandler = new SpongeCommandHandler();
game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge"); game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge");
getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!"); getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!");

Datei anzeigen

@ -12,11 +12,11 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
public class SpongeConfigAPI extends Config implements ViaVersionConfig { public class SpongeViaConfig extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "quick-move-action-fix"); private static List<String> UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix");
private final PluginContainer pluginContainer; private final PluginContainer pluginContainer;
public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) { public SpongeViaConfig(PluginContainer pluginContainer, File configFile) {
super(new File(configFile, "config.yml")); super(new File(configFile, "config.yml"));
this.pluginContainer = pluginContainer; this.pluginContainer = pluginContainer;
// Load config // Load config

62
velocity/pom.xml Normale Datei
Datei anzeigen

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>2.0.0-18w46a</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>viaversion-velocity</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>velocity</id>
<url>https://repo.velocitypowered.com/snapshots</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Common Module -->
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion-common</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<!-- Velocity API 1.0 -->
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

Datei anzeigen

@ -0,0 +1,5 @@
package us.myles.ViaVersion.velocity;
public class VersionInfo {
public static final String VERSION = "${project.version}";
}

Datei anzeigen

@ -0,0 +1,206 @@
package us.myles.ViaVersion;
import com.google.gson.JsonObject;
import com.google.inject.Inject;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.Getter;
import net.kyori.text.serializer.ComponentSerializers;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.slf4j.Logger;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.TaskId;
import us.myles.ViaVersion.api.platform.ViaPlatform;
import us.myles.ViaVersion.dump.PluginInfo;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.ViaVersion.velocity.VersionInfo;
import us.myles.ViaVersion.velocity.command.VelocityCommandHandler;
import us.myles.ViaVersion.velocity.command.VelocityCommandSender;
import us.myles.ViaVersion.velocity.platform.*;
import us.myles.ViaVersion.velocity.service.ProtocolDetectorService;
import us.myles.ViaVersion.velocity.util.LoggerWrapper;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Plugin(
id = "viaversion",
name = "ViaVersion",
version = VersionInfo.VERSION,
authors = {"_MylesC", "Matsv"},
description = "Allow newer Minecraft versions to connect to an older server version.",
url = "https://viaversion.com"
)
@Getter
public class VelocityPlugin implements ViaPlatform<Player> {
@Inject
private ProxyServer proxy;
@Inject
public static ProxyServer PROXY;
@Inject
private Logger loggerslf4j;
private java.util.logging.Logger logger;
@Inject
@DataDirectory
private Path configDir;
private VelocityViaAPI api;
private VelocityViaConfig conf;
@Subscribe
public void onProxyInit(ProxyInitializeEvent e) {
PROXY = proxy;
VelocityCommandHandler commandHandler = new VelocityCommandHandler();
PROXY.getCommandManager().register(commandHandler, "viaver", "vvvelocity", "viaversion");
api = new VelocityViaAPI();
conf = new VelocityViaConfig(configDir.toFile());
logger = new LoggerWrapper(loggerslf4j);
Via.init(ViaManager.builder()
.platform(this)
.commandHandler(commandHandler)
.loader(new VelocityViaLoader())
.injector(new VelocityViaInjector()).build());
Via.getManager().init();
}
@Subscribe
public void onQuit(DisconnectEvent e) {
UserConnection userConnection = Via.getManager().getPortedPlayers().get(e.getPlayer().getUniqueId());
if (userConnection != null) {
// Only remove if the connection is disconnected (eg. relogin)
if (userConnection.getChannel() == null || !userConnection.getChannel().isOpen()) {
Via.getManager().removePortedClient(e.getPlayer().getUniqueId());
}
}
}
@Override
public String getPlatformName() {
String proxyImpl = ProxyServer.class.getPackage().getImplementationTitle();
return (proxyImpl != null) ? proxyImpl : "Velocity";
}
@Override
public String getPlatformVersion() {
String version = ProxyServer.class.getPackage().getImplementationVersion();
return (version != null) ? version : "Unknown";
}
@Override
public String getPluginVersion() {
return VersionInfo.VERSION;
}
@Override
public TaskId runAsync(Runnable runnable) {
return runSync(runnable);
}
@Override
public TaskId runSync(Runnable runnable) {
return runSync(runnable, 0L);
}
@Override
public TaskId runSync(Runnable runnable, Long ticks) {
return new VelocityTaskId(
PROXY.getScheduler()
.buildTask(this, runnable)
.delay(ticks * 50, TimeUnit.MILLISECONDS).schedule()
);
}
@Override
public TaskId runRepeatingSync(Runnable runnable, Long ticks) {
return new VelocityTaskId(
PROXY.getScheduler()
.buildTask(this, runnable)
.repeat(ticks * 50, TimeUnit.MILLISECONDS).schedule()
);
}
@Override
public void cancelTask(TaskId taskId) {
if (taskId instanceof VelocityTaskId) {
((VelocityTaskId) taskId).getObject().cancel();
}
}
@Override
public ViaCommandSender[] getOnlinePlayers() {
return PROXY.getAllPlayers().stream()
.map(VelocityCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
@Override
public void sendMessage(UUID uuid, String message) {
PROXY.getPlayer(uuid).ifPresent(it -> it.sendMessage(
ComponentSerializers.JSON.deserialize(
ComponentSerializer.toString(TextComponent.fromLegacyText(message)) // Fixes links
)
));
}
@Override
public boolean kickPlayer(UUID uuid, String message) {
return PROXY.getPlayer(uuid).map(it -> {
it.disconnect(
ComponentSerializers.JSON.deserialize(
ComponentSerializer.toString(TextComponent.fromLegacyText(message)) // ComponentSerializers.LEGACY is deprecated
)
);
return true;
}).orElse(false);
}
@Override
public boolean isPluginEnabled() {
return true;
}
@Override
public ConfigurationProvider getConfigurationProvider() {
return conf;
}
@Override
public void onReload() {
}
@Override
public JsonObject getDump() {
JsonObject extra = new JsonObject();
List<PluginInfo> plugins = new ArrayList<>();
for (PluginContainer p : PROXY.getPluginManager().getPlugins()) {
plugins.add(new PluginInfo(
true,
p.getDescription().getName().orElse(p.getDescription().getId()),
p.getDescription().getVersion().orElse("Unknown Version"),
p.getInstance().isPresent() ? p.getInstance().get().getClass().getCanonicalName() : "Unknown",
p.getDescription().getAuthors()
));
}
extra.add("plugins", GsonUtil.getGson().toJsonTree(plugins));
extra.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds()));
return extra;
}
@Override
public boolean isOldClientsAllowed() {
return true;
}
}

Datei anzeigen

@ -0,0 +1,29 @@
package us.myles.ViaVersion.velocity.command;
import com.velocitypowered.api.command.Command;
import com.velocitypowered.api.command.CommandSource;
import org.checkerframework.checker.nullness.qual.NonNull;
import us.myles.ViaVersion.commands.ViaCommandHandler;
import us.myles.ViaVersion.velocity.command.subs.ProbeSubCmd;
import java.util.List;
public class VelocityCommandHandler extends ViaCommandHandler implements Command {
public VelocityCommandHandler() {
try {
registerSubCommand(new ProbeSubCmd());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void execute(@NonNull CommandSource source, String[] args) {
onCommand(new VelocityCommandSender(source), args);
}
@Override
public List<String> suggest(@NonNull CommandSource source, String[] currentArgs) {
return onTabComplete(new VelocityCommandSender(source), currentArgs);
}
}

Datei anzeigen

@ -0,0 +1,46 @@
package us.myles.ViaVersion.velocity.command;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import lombok.AllArgsConstructor;
import net.kyori.text.serializer.ComponentSerializers;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import us.myles.ViaVersion.api.command.ViaCommandSender;
import java.util.UUID;
@AllArgsConstructor
public class VelocityCommandSender implements ViaCommandSender {
private CommandSource source;
@Override
public boolean hasPermission(String permission) {
return source.hasPermission(permission);
}
@Override
public void sendMessage(String msg) {
source.sendMessage(
ComponentSerializers.JSON.deserialize(
ComponentSerializer.toString(TextComponent.fromLegacyText(msg)) // Fixes links
)
);
}
@Override
public UUID getUUID() {
if (source instanceof Player) {
return ((Player) source).getUniqueId();
}
return UUID.fromString(getName());
}
@Override
public String getName() {
if (source instanceof Player) {
return ((Player) source).getUsername();
}
return "?"; // :(
}
}

Datei anzeigen

@ -0,0 +1,28 @@
package us.myles.ViaVersion.velocity.command.subs;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.velocity.platform.VelocityViaConfig;
import us.myles.ViaVersion.velocity.service.ProtocolDetectorService;
public class ProbeSubCmd extends ViaSubCommand {
@Override
public String name() {
return "probe";
}
@Override
public String description() {
return "Forces ViaVersion to scan server protocol versions " +
(((VelocityViaConfig) Via.getConfig()).getVelocityPingInterval() == -1 ?
"" : "(Also happens at an interval)");
}
@Override
public boolean execute(ViaCommandSender sender, String[] args) {
ProtocolDetectorService.getInstance().run();
sendMessage(sender, "&6Started searching for protocol versions");
return true;
}
}

Datei anzeigen

@ -0,0 +1,38 @@
package us.myles.ViaVersion.velocity.handlers;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import java.lang.reflect.Method;
@RequiredArgsConstructor
public class VelocityChannelInitializer extends ChannelInitializer {
@NonNull
private ChannelInitializer original;
private Method initChannel;
{
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);
UserConnection user = new UserConnection(channel);
new ProtocolPipeline(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));
}
}

Datei anzeigen

@ -0,0 +1,78 @@
package us.myles.ViaVersion.velocity.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import lombok.AllArgsConstructor;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.util.PipelineUtil;
import java.util.List;
@ChannelHandler.Sharable
@AllArgsConstructor
public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
private final UserConnection info;
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
// use transformers
if (bytebuf.readableBytes() > 0) {
// Ignore if pending disconnect
if (info.isPendingDisconnect()) {
return;
}
// Increment received
boolean second = info.incrementReceived();
// Check PPS
if (second) {
if (info.handlePPS())
return;
}
info.getVelocityLock().readLock().lock();
if (info.isActive()) {
// Handle ID
int id = Type.VAR_INT.read(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
if (id == PacketWrapper.PASSTHROUGH_ID) {
newPacket.writeBytes(bytebuf);
} else {
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
wrapper.writeToBuffer(newPacket);
}
bytebuf.clear();
bytebuf = newPacket;
} catch (Exception e) {
// Clear Buffer
bytebuf.clear();
// Release Packet, be free!
newPacket.release();
info.getVelocityLock().readLock().unlock();
throw e;
}
} else {
bytebuf.retain();
}
info.getVelocityLock().readLock().unlock();
out.add(bytebuf);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
super.exceptionCaught(ctx, cause);
}
}

Datei anzeigen

@ -0,0 +1,90 @@
package us.myles.ViaVersion.velocity.handlers;
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 lombok.NonNull;
import lombok.RequiredArgsConstructor;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.util.PipelineUtil;
import java.util.List;
@ChannelHandler.Sharable
@RequiredArgsConstructor
public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
@NonNull
private final UserConnection info;
private boolean handledCompression = false;
@Override
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
if (bytebuf.readableBytes() == 0) {
throw new CancelException();
}
boolean needsCompress = false;
if (!handledCompression
&& ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) {
// Need to decompress this packet due to bad order
bytebuf = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder) ctx.pipeline().get("compression-decoder"), ctx, bytebuf).get(0);
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);
needsCompress = true;
handledCompression = true;
} else {
bytebuf.retain();
}
// Increment sent
info.incrementSent();
if (info.isActive()) {
// Handle ID
int id = Type.VAR_INT.read(bytebuf);
// Transform
ByteBuf newPacket = bytebuf.alloc().buffer();
try {
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
wrapper.writeToBuffer(newPacket);
bytebuf.clear();
bytebuf.release();
bytebuf = newPacket;
} catch (Exception e) {
bytebuf.clear();
bytebuf.release();
newPacket.release();
throw e;
}
}
if (needsCompress) {
ByteBuf old = bytebuf;
bytebuf = ctx.alloc().buffer();
PipelineUtil.callEncode((MessageToByteEncoder) ctx.pipeline().get("compression-encoder"), ctx, old, bytebuf);
old.release();
}
out.add(bytebuf);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
super.exceptionCaught(ctx, cause);
}
}

Datei anzeigen

@ -0,0 +1,138 @@
package us.myles.ViaVersion.velocity.handlers;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
import us.myles.ViaVersion.util.ReflectionUtil;
import us.myles.ViaVersion.velocity.service.ProtocolDetectorService;
import us.myles.ViaVersion.velocity.storage.VelocityStorage;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.Semaphore;
public class VelocityServerHandler {
private static Method setProtocolVersion;
private static Method setNextProtocolVersion;
static {
try {
setProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getDeclaredMethod("setProtocolVersion", int.class);
setNextProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getDeclaredMethod("setNextProtocolVersion", int.class);
} catch (NoSuchMethodException | ClassNotFoundException e) {
e.printStackTrace();
}
}
@Subscribe
public void preServerConnect(ServerPreConnectEvent e) {
try {
UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId());
if (user == null) return;
if (!user.has(VelocityStorage.class)) {
user.put(new VelocityStorage(user, e.getPlayer()));
}
int protocolId = ProtocolDetectorService.getProtocolId(e.getOriginalServer().getServerInfo().getName());
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId);
// Check if ViaVersion can support that version
Object connection = ReflectionUtil.invoke(e.getPlayer(), "getConnection");
setNextProtocolVersion.invoke(connection, protocols == null ? user.get(ProtocolInfo.class).getProtocolVersion() : protocolId);
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e1) {
e1.printStackTrace();
}
}
@Subscribe(order = PostOrder.LATE)
public void connectedEvent(ServerConnectedEvent e) {
UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId());
try {
checkServerChange(e, Via.getManager().getConnection(e.getPlayer().getUniqueId()));
} catch (Exception e1) {
e1.printStackTrace();
}
}
public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception {
if (user == null) return;
// Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666)
if (user.has(EntityTracker.class)) {
EntityTracker tracker = user.get(EntityTracker.class);
if (tracker.getBossBarMap() != null)
for (BossBar bar : tracker.getBossBarMap().values())
bar.hide();
}
// Handle server/version change
if (user.has(VelocityStorage.class)) {
// Wait all the scheduled packets be sent
Semaphore semaphore = new Semaphore(1);
semaphore.acquireUninterruptibly();
user.getChannel().eventLoop().submit((Runnable) semaphore::release);
semaphore.acquireUninterruptibly();
semaphore.release();
user.getVelocityLock().writeLock().lock();
VelocityStorage storage = user.get(VelocityStorage.class);
if (e.getServer() != null) {
if (!e.getServer().getServerInfo().getName().equals(storage.getCurrentServer())) {
String serverName = e.getServer().getServerInfo().getName();
storage.setCurrentServer(serverName);
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
ProtocolInfo info = user.get(ProtocolInfo.class);
// Refresh the pipes
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
ProtocolPipeline pipeline = user.get(ProtocolInfo.class).getPipeline();
user.clearStoredObjects();
pipeline.cleanPipes();
if (protocols == null) {
// TODO Check Bungee Supported Protocols? *shrugs*
protocolId = info.getProtocolVersion();
} else {
for (Pair<Integer, Protocol> prot : protocols) {
pipeline.add(prot.getValue());
}
}
info.setServerProtocolVersion(protocolId);
// Add version-specific base Protocol
pipeline.add(ProtocolRegistry.getBaseProtocol(protocolId));
user.put(info);
user.put(storage);
user.setActive(protocols != null);
// Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist.
for (Protocol protocol : pipeline.pipes()) {
protocol.init(user);
}
Object connection = ReflectionUtil.invoke(e.getPlayer(), "getConnection");
int version = (int) ReflectionUtil.invoke(connection,"getNextProtocolVersion");
setProtocolVersion.invoke(ReflectionUtil.invoke(e.getPlayer(), "getConnection"), version);
}
}
user.getVelocityLock().writeLock().unlock();
}
}
}

Datei anzeigen

@ -0,0 +1,44 @@
package us.myles.ViaVersion.velocity.listeners;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
import java.util.Collections;
/*
* This patches https://github.com/MylesIsCool/ViaVersion/issues/555
*/
public class ElytraPatch {
@Subscribe(order = PostOrder.LAST)
public void onServerConnected(ServerConnectedEvent event) {
UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId());
if (user == null) return;
try {
if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) {
int entityId = user.get(EntityTracker.class).getProvidedEntityId();
PacketWrapper wrapper = new PacketWrapper(0x39, null, user);
wrapper.write(Type.VAR_INT, entityId);
wrapper.write(Types1_9.METADATA_LIST, Collections.singletonList(new Metadata(0, MetaType1_9.Byte, (byte) 0)));
wrapper.send(Protocol1_9TO1_8.class);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Datei anzeigen

@ -0,0 +1,49 @@
package us.myles.ViaVersion.velocity.listeners;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.proxy.player.PlayerSettings;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Method;
/*
This solves the wrong mainhand issue when you join with BungeeCord on a 1.8 server, and switch to a 1.9 or higher.
*/
public class MainHandPatch {
private static Method setSettings;
static {
try {
Class clientSettings = Class.forName("com.velocitypowered.proxy.protocol.packet.ClientSettings");
setSettings = Class.forName("com.velocitypowered.proxy.connection.client.ConnectedPlayer").getDeclaredMethod("setPlayerSettings", clientSettings);
setSettings.setAccessible(true);
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
}
}
@Subscribe
public void onServerConnect(ServerConnectedEvent event) {
UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId());
if (user == null || setSettings == null) return;
try {
if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) {
PlayerSettings settings = event.getPlayer().getPlayerSettings();
if (user.has(EntityTracker.class)) {
Object clientSettings = ReflectionUtil.get(settings, "settings", Object.class);
ReflectionUtil.set(clientSettings, "mainHand", user.get(EntityTracker.class).getMainHand());
setSettings.invoke(event.getPlayer(), clientSettings);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Datei anzeigen

@ -0,0 +1,16 @@
package us.myles.ViaVersion.velocity.listeners;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PostLoginEvent;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.update.UpdateUtil;
public class UpdateListener {
@Subscribe
public void onJoin(PostLoginEvent e) {
if (e.getPlayer().hasPermission("viaversion.update")
&& Via.getConfig().isCheckForUpdates()) {
UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId());
}
}
}

Datei anzeigen

@ -0,0 +1,13 @@
package us.myles.ViaVersion.velocity.platform;
import com.velocitypowered.api.proxy.Player;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.boss.CommonBoss;
public class VelocityBossBar extends CommonBoss<Player> {
public VelocityBossBar(String title, float health, BossColor color, BossStyle style) {
super(title, health, color, style);
}
}

Datei anzeigen

@ -0,0 +1,12 @@
package us.myles.ViaVersion.velocity.platform;
import com.velocitypowered.api.scheduler.ScheduledTask;
import lombok.AllArgsConstructor;
import lombok.Getter;
import us.myles.ViaVersion.api.platform.TaskId;
@Getter
@AllArgsConstructor
public class VelocityTaskId implements TaskId {
private ScheduledTask object;
}

Datei anzeigen

@ -0,0 +1,78 @@
package us.myles.ViaVersion.velocity.platform;
import com.velocitypowered.api.proxy.Player;
import io.netty.buffer.ByteBuf;
import lombok.NonNull;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.ViaAPI;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
public class VelocityViaAPI implements ViaAPI<Player> {
@Override
public int getPlayerVersion(@NonNull Player player) {
if (!isPorted(player.getUniqueId()))
return ProtocolRegistry.SERVER_PROTOCOL;
return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
}
@Override
public int getPlayerVersion(@NonNull UUID uuid) {
if (!isPorted(uuid))
return ProtocolRegistry.SERVER_PROTOCOL;
return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
}
@Override
public boolean isPorted(UUID playerUUID) {
return getPortedPlayers().containsKey(playerUUID);
}
@Override
public String getVersion() {
return Via.getPlatform().getPluginVersion();
}
@Override
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
UserConnection ci = getPortedPlayers().get(uuid);
ci.sendRawPacket(packet);
}
@Override
public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException {
sendRawPacket(player.getUniqueId(), packet);
}
@Override
public BossBar createBossBar(String title, BossColor color, BossStyle style) {
return new VelocityBossBar(title, 1F, color, style);
}
@Override
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
return new VelocityBossBar(title, health, color, style);
}
@Override
public SortedSet<Integer> getSupportedVersions() {
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
return outputSet;
}
public Map<UUID, UserConnection> getPortedPlayers() {
return Via.getManager().getPortedPlayers();
}
}

Datei anzeigen

@ -0,0 +1,280 @@
package us.myles.ViaVersion.velocity.platform;
import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.util.Config;
import java.io.File;
import java.net.URL;
import java.util.*;
public class VelocityViaConfig extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "bungee-ping-interval", "bungee-ping-save", "bungee-servers");
public VelocityViaConfig(File configFile) {
super(new File(configFile, "config.yml"));
// Load config
reloadConfig();
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viaversion/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> config) {
// Parse servers
Map<String, Object> servers;
if (!(config.get("velocity-servers") instanceof Map)) {
servers = new HashMap<>();
} else {
servers = (Map) config.get("velocity-servers");
}
// Convert any bad Protocol Ids
for (Map.Entry<String, Object> entry : new HashSet<>(servers.entrySet())) {
if (!(entry.getValue() instanceof Integer)) {
if (entry.getValue() instanceof String) {
ProtocolVersion found = ProtocolVersion.getClosest((String) entry.getValue());
if (found != null) {
servers.put(entry.getKey(), found.getId());
} else {
servers.remove(entry.getKey()); // Remove!
}
} else {
servers.remove(entry.getKey()); // Remove!
}
}
}
// Ensure default exists
if (!servers.containsKey("default")) {
// Side note: This doesn't use ProtocolRegistry as it doesn't know the protocol version at boot.
try {
servers.put("default", VelocityViaInjector.getLowestSupportedProtocolVersion());
} catch (Exception e) {
// Something went very wrong
e.printStackTrace();
}
}
// Put back
config.put("velocity-servers", servers);
}
@Override
public List<String> getUnsupportedOptions() {
return UNSUPPORTED;
}
public boolean isCheckForUpdates() {
return getBoolean("checkforupdates", true);
}
@Override
public boolean isPreventCollision() {
return getBoolean("prevent-collision", true);
}
@Override
public boolean isNewEffectIndicator() {
return getBoolean("use-new-effect-indicator", true);
}
@Override
public boolean isShowNewDeathMessages() {
return getBoolean("use-new-deathmessages", true);
}
@Override
public boolean isSuppressMetadataErrors() {
return getBoolean("suppress-metadata-errors", false);
}
@Override
public boolean isShieldBlocking() {
return getBoolean("shield-blocking", true);
}
@Override
public boolean isHologramPatch() {
return getBoolean("hologram-patch", false);
}
@Override
public boolean isPistonAnimationPatch() {
return getBoolean("piston-animation-patch", false);
}
@Override
public boolean isBossbarPatch() {
return getBoolean("bossbar-patch", true);
}
@Override
public boolean isBossbarAntiflicker() {
return getBoolean("bossbar-anti-flicker", false);
}
@Override
public boolean isUnknownEntitiesSuppressed() {
return false;
}
@Override
public double getHologramYOffset() {
return getDouble("hologram-y", -0.96D);
}
@Override
public boolean isBlockBreakPatch() {
return false;
}
@Override
public int getMaxPPS() {
return getInt("max-pps", 800);
}
@Override
public String getMaxPPSKickMessage() {
return getString("max-pps-kick-msg", "Sending packets too fast? lag?");
}
@Override
public int getTrackingPeriod() {
return getInt("tracking-period", 6);
}
@Override
public int getWarningPPS() {
return getInt("tracking-warning-pps", 120);
}
@Override
public int getMaxWarnings() {
return getInt("tracking-max-warnings", 3);
}
@Override
public String getMaxWarningsKickMessage() {
return getString("tracking-max-kick-msg", "You are sending too many packets, :(");
}
@Override
public boolean isAntiXRay() {
return false;
}
@Override
public boolean isSendSupportedVersions() {
return getBoolean("send-supported-versions", false);
}
@Override
public boolean isStimulatePlayerTick() {
return getBoolean("simulate-pt", true);
}
@Override
public boolean isItemCache() {
return false;
}
@Override
public boolean isNMSPlayerTicking() {
return false;
}
@Override
public boolean isReplacePistons() {
return getBoolean("replace-pistons", false);
}
@Override
public int getPistonReplacementId() {
return getInt("replacement-piston-id", 0);
}
public boolean isAutoTeam() {
// Collision has to be enabled first
return isPreventCollision() && getBoolean("auto-team", true);
}
@Override
public boolean isForceJsonTransform() {
return getBoolean("force-json-transform", false);
}
@Override
public boolean is1_12NBTArrayFix() {
return getBoolean("chat-nbt-fix", true);
}
@Override
public boolean is1_12QuickMoveActionFix() {
return false;
}
@Override
public List<Integer> getBlockedProtocols() {
return getIntegerList("block-protocols");
}
@Override
public String getBlockedDisconnectMsg() {
return getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
}
@Override
public String getReloadDisconnectMsg() {
return getString("reload-disconnect-msg", "Server reload, please rejoin!");
}
@Override
public boolean isMinimizeCooldown() {
return getBoolean("minimize-cooldown", true);
}
/**
* What is the interval for checking servers via ping
* -1 for disabled
*
* @return Ping interval in seconds
*/
public int getVelocityPingInterval() {
return getInt("velocity-ping-interval", 60);
}
/**
* Should the velocity ping be saved to the config on change.
*
* @return True if it should save
*/
public boolean isVelocityPingSave() {
return getBoolean("velocity-ping-save", true);
}
/**
* Get the listed server protocols in the config.
* default will be listed as default.
*
* @return Map of String, Integer
*/
public Map<String, Integer> getVelocityServerProtocols() {
return get("velocity-servers", Map.class, new HashMap<>());
}
@Override
public boolean is1_13TeamColourFix() {
return getBoolean("team-colour-fix", true);
}
@Override
public boolean isSuppress1_13ConversionErrors() {
return getBoolean("suppress-1_13-conversion-errors", false);
}
@Override
public boolean isDisable1_13AutoComplete() {
return getBoolean("disable-1_13-auto-complete", false);
}
}

Datei anzeigen

@ -0,0 +1,45 @@
package us.myles.ViaVersion.velocity.platform;
import io.netty.channel.ChannelInitializer;
import us.myles.ViaVersion.VelocityPlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.platform.ViaInjector;
import us.myles.ViaVersion.util.ReflectionUtil;
import us.myles.ViaVersion.velocity.handlers.VelocityChannelInitializer;
public class VelocityViaInjector implements ViaInjector {
@Override
public void inject() throws Exception {
Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class);
Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer");
ChannelInitializer originalIntializer = (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get");
channelInitializerHolder.getClass().getMethod("set", ChannelInitializer.class)
.invoke(channelInitializerHolder, new VelocityChannelInitializer(originalIntializer));
}
@Override
public void uninject() {
Via.getPlatform().getLogger().severe("ViaVersion cannot remove itself from Velocity without a reboot!");
}
@Override
public int getServerProtocolVersion() throws Exception {
return getLowestSupportedProtocolVersion();
}
public static int getLowestSupportedProtocolVersion() throws Exception {
return ReflectionUtil.getStatic(Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), "MINIMUM_GENERIC_VERSION", int.class);
}
@Override
public String getEncoderName() {
return "via-encoder";
}
@Override
public String getDecoderName() {
return "via-decoder";
}
}

Datei anzeigen

@ -0,0 +1,47 @@
package us.myles.ViaVersion.velocity.platform;
import com.velocitypowered.api.plugin.PluginContainer;
import us.myles.ViaVersion.VelocityPlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
import us.myles.ViaVersion.protocols.base.VersionProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import us.myles.ViaVersion.velocity.handlers.VelocityServerHandler;
import us.myles.ViaVersion.velocity.listeners.ElytraPatch;
import us.myles.ViaVersion.velocity.listeners.MainHandPatch;
import us.myles.ViaVersion.velocity.listeners.UpdateListener;
import us.myles.ViaVersion.velocity.providers.VelocityBossBarProvider;
import us.myles.ViaVersion.velocity.providers.VelocityMovementTransmitter;
import us.myles.ViaVersion.velocity.providers.VelocityVersionProvider;
import us.myles.ViaVersion.velocity.service.ProtocolDetectorService;
public class VelocityViaLoader implements ViaPlatformLoader {
@Override
public void load() {
Object plugin = VelocityPlugin.PROXY.getPluginManager()
.getPlugin("viaversion").flatMap(PluginContainer::getInstance).get();
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new VelocityMovementTransmitter());
Via.getManager().getProviders().use(BossBarProvider.class, new VelocityBossBarProvider());
Via.getManager().getProviders().use(VersionProvider.class, new VelocityVersionProvider());
// We probably don't need a EntityIdProvider because velocity sends a Join packet on server change
VelocityPlugin.PROXY.getEventManager().register(plugin, new UpdateListener());
VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler());
VelocityPlugin.PROXY.getEventManager().register(plugin, new MainHandPatch());
VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch());
int pingInterval = ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval();
if (pingInterval > 0) {
Via.getPlatform().runRepeatingSync(
new ProtocolDetectorService(),
pingInterval * 20L);
}
}
@Override
public void unload() {
// Probably not useful, there's no ProxyReloadEvent
}
}

Datei anzeigen

@ -0,0 +1,30 @@
package us.myles.ViaVersion.velocity.providers;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import us.myles.ViaVersion.velocity.storage.VelocityStorage;
import java.util.UUID;
public class VelocityBossBarProvider extends BossBarProvider {
@Override
public void handleAdd(UserConnection user, UUID barUUID) {
if (user.has(VelocityStorage.class)) {
VelocityStorage storage = user.get(VelocityStorage.class);
// Check if bossbars are supported by bungee, static maybe
if (storage.getBossbar() != null) {
storage.getBossbar().add(barUUID);
}
}
}
@Override
public void handleRemove(UserConnection user, UUID barUUID) {
if (user.has(VelocityStorage.class)) {
VelocityStorage storage = user.get(VelocityStorage.class);
if (storage.getBossbar() != null) {
storage.getBossbar().remove(barUUID);
}
}
}
}

Datei anzeigen

@ -0,0 +1,35 @@
package us.myles.ViaVersion.velocity.providers;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
public class VelocityMovementTransmitter extends MovementTransmitterProvider {
@Override
public Object getFlyingPacket() {
return null;
}
@Override
public Object getGroundPacket() {
return null;
}
public void sendPlayer(UserConnection userConnection) {
if (userConnection.get(ProtocolInfo.class).getState() == State.PLAY) {
PacketWrapper wrapper = new PacketWrapper(0x03, null, userConnection);
wrapper.write(Type.BOOLEAN, userConnection.get(MovementTracker.class).isGround());
try {
wrapper.sendToServer(Protocol1_9TO1_8.class);
} catch (Exception e) {
e.printStackTrace();
}
// PlayerPackets will increment idle
}
}
}

Datei anzeigen

@ -0,0 +1,73 @@
package us.myles.ViaVersion.velocity.providers;
import com.google.common.collect.Lists;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.base.VersionProvider;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class VelocityVersionProvider extends VersionProvider {
private static Class<?> ref ;
static {
try {
ref = Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants");
} catch (Exception e) {
Via.getPlatform().getLogger().severe("Could not detect the ProtocolConstants class");
e.printStackTrace();
}
}
@Override
public int getServerProtocol(UserConnection user) throws Exception {
if (ref == null)
return super.getServerProtocol(user);
// TODO Have one constant list forever until restart? (Might limit plugins if they change this)
Object list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSIONS", Object.class);
List<Integer> sorted = new ArrayList<Integer>((List) ReflectionUtil.invoke(list, "asList"));
Collections.sort(sorted);
ProtocolInfo info = user.get(ProtocolInfo.class);
// Bungee supports it
if (sorted.contains(info.getProtocolVersion()))
return info.getProtocolVersion();
// Older than bungee supports, get the lowest version
if (info.getProtocolVersion() < sorted.get(0)) {
return getLowestSupportedVersion();
}
// Loop through all protocols to get the closest protocol id that bungee supports (and that viaversion does too)
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
// This is more of a workaround for snapshot support by bungee.
for (Integer protocol : Lists.reverse(sorted)) {
if (info.getProtocolVersion() > protocol && ProtocolVersion.isRegistered(protocol))
return protocol;
}
Via.getPlatform().getLogger().severe("Panic, no protocol id found for " + info.getProtocolVersion());
return info.getProtocolVersion();
}
public static int getLowestSupportedVersion() {
List<Integer> list;
try {
return ReflectionUtil.getStatic(
Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"),
"MINIMUM_GENERIC_VERSION",
int.class);
} catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
// Fallback
return -1;
}
}

Datei anzeigen

@ -0,0 +1,82 @@
package us.myles.ViaVersion.velocity.service;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import lombok.Getter;
import us.myles.ViaVersion.VelocityPlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.velocity.platform.VelocityViaConfig;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ProtocolDetectorService implements Runnable {
private static final Map<String, Integer> detectedProtocolIds = new ConcurrentHashMap<>();
@Getter
private static ProtocolDetectorService instance;
public ProtocolDetectorService() {
instance = this;
}
public static Integer getProtocolId(String serverName) {
// Step 1. Check Config
Map<String, Integer> servers = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols();
Integer protocol = servers.get(serverName);
if (protocol != null) {
return protocol;
}
// Step 2. Check Detected
Integer detectedProtocol = detectedProtocolIds.get(serverName);
if (detectedProtocol != null) {
return detectedProtocol;
}
// Step 3. Use Default
Integer defaultProtocol = servers.get("default");
if (defaultProtocol != null) {
return defaultProtocol;
}
// Step 4: Use bungee lowest supported... *cries*
try {
return Via.getManager().getInjector().getServerProtocolVersion();
} catch (Exception e) {
e.printStackTrace();
return ProtocolVersion.v1_8.getId();
}
}
@Override
public void run() {
for (final RegisteredServer serv : VelocityPlugin.PROXY.getAllServers()) {
probeServer(serv);
}
}
public static void probeServer(final RegisteredServer serverInfo) {
final String key = serverInfo.getServerInfo().getName();
serverInfo.ping().thenAccept((serverPing) -> {
if (serverPing != null && serverPing.getVersion() != null) {
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
if (((VelocityViaConfig) Via.getConfig()).isVelocityPingSave()) {
Map<String, Integer> servers = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols();
Integer protocol = servers.get(key);
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
return;
}
// Ensure we're the only ones writing to the config
synchronized (Via.getPlatform().getConfigurationProvider()) {
servers.put(key, serverPing.getVersion().getProtocol());
}
// Save
Via.getPlatform().getConfigurationProvider().saveConfig();
}
}
});
}
public static Map<String, Integer> getDetectedIds() {
return new HashMap<>(detectedProtocolIds);
}
}

Datei anzeigen

@ -0,0 +1,38 @@
package us.myles.ViaVersion.velocity.storage;
import com.velocitypowered.api.proxy.Player;
import lombok.Data;
import lombok.EqualsAndHashCode;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import java.util.UUID;
@Data
@EqualsAndHashCode(callSuper = true)
public class VelocityStorage extends StoredObject {
private Player player;
private String currentServer;
private Set<UUID> bossbar;
public VelocityStorage(UserConnection user, Player player) {
super(user);
this.player = player;
this.currentServer = "";
// Get bossbar list if it's supported
try {
Object connection = ReflectionUtil.invoke(player, "getConnection");
Object sessionHandler = ReflectionUtil.invoke(connection, "getSessionHandler");
if (sessionHandler.getClass().getSimpleName().contains("Play")) {
bossbar = (Set<UUID>) ReflectionUtil.invoke(sessionHandler, "getServerBossBars");
// TODO make this work
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

Datei anzeigen

@ -0,0 +1,69 @@
package us.myles.ViaVersion.velocity.util;
import org.slf4j.Logger;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class LoggerWrapper extends java.util.logging.Logger {
private final Logger base;
public LoggerWrapper(Logger logger) {
super("logger", null);
this.base = logger;
}
@Override
public void log(LogRecord record) {
log(record.getLevel(), record.getMessage());
}
@Override
public void log(Level level, String msg) {
if (level == Level.FINE)
base.debug(msg);
else if (level == Level.WARNING)
base.warn(msg);
else if (level == Level.SEVERE)
base.error(msg);
else if (level == Level.INFO)
base.info(msg);
else
base.trace(msg);
}
@Override
public void log(Level level, String msg, Object param1) {
if (level == Level.FINE)
base.debug(msg, param1);
else if (level == Level.WARNING)
base.warn(msg, param1);
else if (level == Level.SEVERE)
base.error(msg, param1);
else if (level == Level.INFO)
base.info(msg, param1);
else
base.trace(msg, param1);
}
@Override
public void log(Level level, String msg, Object[] params) {
log(level, MessageFormat.format(msg, params)); // workaround not formatting correctly
}
@Override
public void log(Level level, String msg, Throwable params) {
if (level == Level.FINE)
base.debug(msg, params);
else if (level == Level.WARNING)
base.warn(msg, params);
else if (level == Level.SEVERE)
base.error(msg, params);
else if (level == Level.INFO)
base.info(msg, params);
else
base.trace(msg, params);
}
}