Clean up proxy protocol detector service

This commit is contained in:
Nassim Jahnke 2022-08-11 19:04:22 +02:00
parent 9247e87bbf
commit ed196bdf99
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
18 changed files with 349 additions and 154 deletions

View File

@ -25,6 +25,7 @@ package com.viaversion.viaversion.api;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.api.platform.ViaPlatform;
import com.viaversion.viaversion.api.platform.ViaServerProxyPlatform;
public final class Via {
private static ViaManager manager;
@ -63,6 +64,11 @@ public final class Via {
return manager().getPlatform();
}
public static ViaServerProxyPlatform<?> proxyPlatform() {
Preconditions.checkArgument(manager().getPlatform() instanceof ViaServerProxyPlatform, "Platform is not proxying Minecraft servers!");
return (ViaServerProxyPlatform<?>) manager().getPlatform();
}
/**
* Register the ViaManager associated with the platform.
*

View File

@ -64,7 +64,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes
*/
default int apiVersion() {
return 14;
return 15;
}
/**

View File

@ -0,0 +1,65 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.platform;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
public interface ProtocolDetectorService {
/**
* Returns the protocol version of the proxied server, or -1 if unknown.
*
* @param serverName name of the proxied server
* @return protocol version of the proxied server, or -1 if unknown
*/
int serverProtocolVersion(String serverName);
/**
* Probes all registered proxied servers for their protocol version.
* This is executed automatically in the interval set in the ViaVersion config.
*/
void probeAllServers();
/**
* Sets the stored protocol version of a proxied server.
*
* @param serverName name of the proxied server
* @param protocolVersion protocol version of the server
*/
void setProtocolVersion(String serverName, int protocolVersion);
/**
* Uncaches and returns the previously stored protocol version of the proxied server. Returns -1 if none was stored.
*
* @param serverName name of the proxied server
* @return previously stored protocol version of the proxied server, or -1 if none was present
*/
int uncacheProtocolVersion(String serverName);
/**
* Returns an unmodifiable map of detected protocol versions.
*
* @return unmodifiable map of detected protocol versions
*/
Object2IntMap<String> detectedProtocolVersions();
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.platform;
import com.google.common.annotations.Beta;
/**
* Represents a platform that proxies a list of Minecraft servers (Velocity, Bungee).
* A platform might not be a proxy platform, even if {@link ViaPlatform#isProxy()} is true.
*
* @param <T> platform player type
*/
@Beta
public interface ViaServerProxyPlatform<T> extends ViaPlatform<T> {
/**
* Returns a service to get protocol versions for proxied servers.
*
* @return protocol detector service
*/
ProtocolDetectorService protocolDetectorService();
}

View File

@ -300,7 +300,7 @@ public interface Protocol<C1 extends ClientboundPacketType, C2 extends Clientbou
* <p>
* To be overridden if needed.
*
* @param userConnection The user to initialise
* @param connection user to initialise
*/
default void init(UserConnection connection) {
}

View File

@ -26,15 +26,15 @@ import com.viaversion.viaversion.api.configuration.ConfigurationProvider;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.platform.PlatformTask;
import com.viaversion.viaversion.api.platform.UnsupportedSoftware;
import com.viaversion.viaversion.api.platform.ViaPlatform;
import com.viaversion.viaversion.api.platform.ViaServerProxyPlatform;
import com.viaversion.viaversion.bungee.commands.BungeeCommand;
import com.viaversion.viaversion.bungee.commands.BungeeCommandHandler;
import com.viaversion.viaversion.bungee.commands.BungeeCommandSender;
import com.viaversion.viaversion.bungee.platform.BungeeViaTask;
import com.viaversion.viaversion.bungee.platform.BungeeViaAPI;
import com.viaversion.viaversion.bungee.platform.BungeeViaConfig;
import com.viaversion.viaversion.bungee.platform.BungeeViaInjector;
import com.viaversion.viaversion.bungee.platform.BungeeViaLoader;
import com.viaversion.viaversion.bungee.platform.BungeeViaTask;
import com.viaversion.viaversion.bungee.service.ProtocolDetectorService;
import com.viaversion.viaversion.dump.PluginInfo;
import com.viaversion.viaversion.unsupported.UnsupportedServerSoftware;
@ -52,7 +52,8 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>, Listener {
public class BungeePlugin extends Plugin implements ViaServerProxyPlatform<ProxiedPlayer>, Listener {
private final ProtocolDetectorService protocolDetectorService = new ProtocolDetectorService();
private BungeeViaAPI api;
private BungeeViaConfig config;
@ -200,7 +201,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
));
platformSpecific.add("plugins", GsonUtil.getGson().toJsonTree(plugins));
platformSpecific.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds()));
platformSpecific.add("servers", GsonUtil.getGson().toJsonTree(protocolDetectorService.detectedProtocolVersions()));
return platformSpecific;
}
@ -211,7 +212,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
@Override
public Collection<UnsupportedSoftware> getUnsupportedSoftwareClasses() {
final Collection<UnsupportedSoftware> list = new ArrayList<>(ViaPlatform.super.getUnsupportedSoftwareClasses());
final Collection<UnsupportedSoftware> list = new ArrayList<>(ViaServerProxyPlatform.super.getUnsupportedSoftwareClasses());
list.add(new UnsupportedServerSoftware.Builder()
.name("FlameCord")
.addClassName("dev._2lstudios.flamecord.FlameCord")
@ -224,4 +225,9 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
public boolean hasPlugin(final String name) {
return getProxy().getPluginManager().getPlugin(name) != null;
}
@Override
public ProtocolDetectorService protocolDetectorService() {
return protocolDetectorService;
}
}

View File

@ -21,7 +21,6 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.api.command.ViaSubCommand;
import com.viaversion.viaversion.bungee.platform.BungeeViaConfig;
import com.viaversion.viaversion.bungee.service.ProtocolDetectorService;
public class ProbeSubCmd extends ViaSubCommand {
@Override
@ -38,7 +37,7 @@ public class ProbeSubCmd extends ViaSubCommand {
@Override
public boolean execute(ViaCommandSender sender, String[] args) {
ProtocolDetectorService.getInstance().run();
Via.proxyPlatform().protocolDetectorService().probeAllServers();
sendMessage(sender, "&6Started searching for protocol versions");
return true;
}

View File

@ -29,7 +29,6 @@ import com.viaversion.viaversion.api.protocol.ProtocolPipeline;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.bungee.service.ProtocolDetectorService;
import com.viaversion.viaversion.bungee.storage.BungeeStorage;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
@ -96,7 +95,7 @@ public class BungeeServerHandler implements Listener {
user.put(new BungeeStorage(e.getPlayer()));
}
int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName());
int protocolId = Via.proxyPlatform().protocolDetectorService().serverProtocolVersion(e.getTarget().getName());
List<ProtocolPathEntry> protocols = Via.getManager().getProtocolManager().getProtocolPath(user.getProtocolInfo().getProtocolVersion(), protocolId);
// Check if ViaVersion can support that version
@ -164,7 +163,7 @@ public class BungeeServerHandler implements Listener {
storage.setCurrentServer(serverName);
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
int protocolId = Via.proxyPlatform().protocolDetectorService().serverProtocolVersion(serverName);
if (protocolId <= ProtocolVersion.v1_8.getVersion()) { // 1.8 doesn't have BossBar packet
if (storage.getBossbar() != null) {

View File

@ -18,6 +18,7 @@
package com.viaversion.viaversion.bungee.platform;
import com.viaversion.viaversion.ViaAPIBase;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.bungee.service.ProtocolDetectorService;
import io.netty.buffer.ByteBuf;
import net.md_5.bungee.api.config.ServerInfo;
@ -41,6 +42,6 @@ public class BungeeViaAPI extends ViaAPIBase<ProxiedPlayer> {
* @param serverInfo The serverinfo to probe
*/
public void probeServer(ServerInfo serverInfo) {
ProtocolDetectorService.probeServer(serverInfo);
((ProtocolDetectorService) Via.proxyPlatform().protocolDetectorService()).probeServer(serverInfo);
}
}

View File

@ -30,7 +30,6 @@ import com.viaversion.viaversion.bungee.providers.BungeeEntityIdProvider;
import com.viaversion.viaversion.bungee.providers.BungeeMainHandProvider;
import com.viaversion.viaversion.bungee.providers.BungeeMovementTransmitter;
import com.viaversion.viaversion.bungee.providers.BungeeVersionProvider;
import com.viaversion.viaversion.bungee.service.ProtocolDetectorService;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MainHandProvider;
@ -44,10 +43,9 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
public class BungeeViaLoader implements ViaPlatformLoader {
private final BungeePlugin plugin;
private final Set<Listener> listeners = new HashSet<>();
private final Set<ScheduledTask> tasks = new HashSet<>();
private final BungeePlugin plugin;
public BungeeViaLoader(BungeePlugin plugin) {
this.plugin = plugin;
@ -82,7 +80,7 @@ public class BungeeViaLoader implements ViaPlatformLoader {
if (plugin.getConf().getBungeePingInterval() > 0) {
tasks.add(plugin.getProxy().getScheduler().schedule(
plugin,
new ProtocolDetectorService(plugin),
() -> Via.proxyPlatform().protocolDetectorService().probeAllServers(),
0, plugin.getConf().getBungeePingInterval(),
TimeUnit.SECONDS
));

View File

@ -17,93 +17,77 @@
*/
package com.viaversion.viaversion.bungee.service;
import com.viaversion.viaversion.BungeePlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.bungee.platform.BungeeViaConfig;
import com.viaversion.viaversion.bungee.providers.BungeeVersionProvider;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ServerPing;
import com.viaversion.viaversion.platform.AbstractProtocolDetectorService;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import java.util.HashMap;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Set;
public class ProtocolDetectorService implements Runnable {
private static final Map<String, Integer> detectedProtocolIds = new ConcurrentHashMap<>();
private static ProtocolDetectorService instance;
private final BungeePlugin plugin;
public final class ProtocolDetectorService extends AbstractProtocolDetectorService {
public ProtocolDetectorService(BungeePlugin plugin) {
this.plugin = plugin;
instance = this;
}
public void probeServer(final ServerInfo serverInfo) {
final String serverName = serverInfo.getName();
serverInfo.ping((serverPing, throwable) -> {
// Ensure protocol is positive, some services will return -1
if (throwable != null || serverPing == null || serverPing.getVersion() == null || serverPing.getVersion().getProtocol() <= 0) {
return;
}
public static Integer getProtocolId(String serverName) {
// Step 1. Check Config
Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
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*
return BungeeVersionProvider.getLowestSupportedVersion();
}
final int oldProtocolVersion = serverProtocolVersion(serverName);
if (oldProtocolVersion == serverPing.getVersion().getProtocol()) {
// Same value as previously
return;
}
@Override
public void run() {
for (final Map.Entry<String, ServerInfo> lists : plugin.getProxy().getServers().entrySet()) {
probeServer(lists.getValue());
}
}
setProtocolVersion(serverName, serverPing.getVersion().getProtocol());
public static void probeServer(final ServerInfo serverInfo) {
final String key = serverInfo.getName();
serverInfo.ping(new Callback<ServerPing>() {
@Override
public void done(ServerPing serverPing, Throwable throwable) {
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());
if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) {
Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
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();
}
}
if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) {
final Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
final Integer protocol = servers.get(serverName);
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
return;
}
// Ensure we're the only ones writing to the config
synchronized (Via.getPlatform().getConfigurationProvider()) {
servers.put(serverName, serverPing.getVersion().getProtocol());
}
Via.getPlatform().getConfigurationProvider().saveConfig();
}
});
}
public static Map<String, Integer> getDetectedIds() {
return new HashMap<>(detectedProtocolIds);
@Override
public void probeAllServers() {
final Collection<ServerInfo> servers = ProxyServer.getInstance().getServers().values();
final Set<String> serverNames = new HashSet<>(servers.size());
for (final ServerInfo serverInfo : servers) {
probeServer(serverInfo);
serverNames.add(serverInfo.getName());
}
// Remove servers that aren't registered anymore
lock.writeLock().lock();
try {
detectedProtocolIds.keySet().retainAll(serverNames);
} finally {
lock.writeLock().unlock();
}
}
public static ProtocolDetectorService getInstance() {
return instance;
@Override
protected Map<String, Integer> configuredServers() {
return ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
}
public BungeePlugin getPlugin() {
return plugin;
@Override
protected int lowestSupportedProtocolVersion() {
return BungeeVersionProvider.getLowestSupportedVersion();
}
}

View File

@ -157,7 +157,7 @@ public class ViaManagerImpl implements ViaManager {
loader.load();
// Common tasks
mappingLoadingTask = Via.getPlatform().runRepeatingSync(() -> {
if (protocolManager.checkForMappingCompletion()) {
if (protocolManager.checkForMappingCompletion() && mappingLoadingTask != null) {
mappingLoadingTask.cancel();
mappingLoadingTask = null;
}

View File

@ -0,0 +1,94 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.platform;
import com.viaversion.viaversion.api.platform.ProtocolDetectorService;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public abstract class AbstractProtocolDetectorService implements ProtocolDetectorService {
protected final Object2IntMap<String> detectedProtocolIds = new Object2IntOpenHashMap<>();
protected final ReadWriteLock lock = new ReentrantReadWriteLock();
@Override
public int serverProtocolVersion(final String serverName) {
// Step 1. Check detected
lock.readLock().lock();
try {
final int detectedProtocol = detectedProtocolIds.getInt(serverName);
if (detectedProtocol != -1) {
return detectedProtocol;
}
} finally {
lock.readLock().unlock();
}
// Step 2. Check config (CME moment?)
final Map<String, Integer> servers = configuredServers();
final Integer protocol = servers.get(serverName);
if (protocol != null) {
return protocol;
}
// Step 3. Use Default (CME moment intensifies?)
final Integer defaultProtocol = servers.get("default");
if (defaultProtocol != null) {
return defaultProtocol;
}
// Step 4: Use the proxy's lowest supported... *cries*
return lowestSupportedProtocolVersion();
}
@Override
public void setProtocolVersion(final String serverName, final int protocolVersion) {
lock.writeLock().lock();
try {
detectedProtocolIds.put(serverName, protocolVersion);
} finally {
lock.writeLock().unlock();
}
}
@Override
public int uncacheProtocolVersion(final String serverName) {
lock.writeLock().lock();
try {
return detectedProtocolIds.removeInt(serverName);
} finally {
lock.writeLock().unlock();
}
}
@Override
public Object2IntMap<String> detectedProtocolVersions() {
try {
return new Object2IntOpenHashMap<>(detectedProtocolIds);
} finally {
lock.readLock().unlock();
}
}
protected abstract Map<String, Integer> configuredServers();
protected abstract int lowestSupportedProtocolVersion();
}

View File

@ -32,7 +32,7 @@ import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.api.configuration.ConfigurationProvider;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.platform.PlatformTask;
import com.viaversion.viaversion.api.platform.ViaPlatform;
import com.viaversion.viaversion.api.platform.ViaServerProxyPlatform;
import com.viaversion.viaversion.dump.PluginInfo;
import com.viaversion.viaversion.util.ChatColorUtil;
import com.viaversion.viaversion.util.GsonUtil;
@ -64,7 +64,7 @@ import java.util.concurrent.TimeUnit;
description = "Allow newer Minecraft versions to connect to an older server version.",
url = "https://viaversion.com"
)
public class VelocityPlugin implements ViaPlatform<Player> {
public class VelocityPlugin implements ViaServerProxyPlatform<Player> {
public static final LegacyComponentSerializer COMPONENT_SERIALIZER = LegacyComponentSerializer.builder().character(ChatColorUtil.COLOR_CHAR).extractUrls().build();
public static ProxyServer PROXY;
@ -76,6 +76,7 @@ public class VelocityPlugin implements ViaPlatform<Player> {
@DataDirectory
private Path configDir;
private final ProtocolDetectorService protocolDetectorService = new ProtocolDetectorService();
private VelocityViaAPI api;
private java.util.logging.Logger logger;
private VelocityViaConfig conf;
@ -230,7 +231,7 @@ public class VelocityPlugin implements ViaPlatform<Player> {
));
}
extra.add("plugins", GsonUtil.getGson().toJsonTree(plugins));
extra.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds()));
extra.add("servers", GsonUtil.getGson().toJsonTree(protocolDetectorService.detectedProtocolVersions()));
return extra;
}
@ -249,6 +250,11 @@ public class VelocityPlugin implements ViaPlatform<Player> {
return logger;
}
@Override
public ProtocolDetectorService protocolDetectorService() {
return protocolDetectorService;
}
private boolean hasConnectionEvent() {
try {
Class.forName("com.velocitypowered.proxy.protocol.VelocityConnectionEvent");

View File

@ -21,7 +21,6 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.api.command.ViaSubCommand;
import com.viaversion.viaversion.velocity.platform.VelocityViaConfig;
import com.viaversion.viaversion.velocity.service.ProtocolDetectorService;
public class ProbeSubCmd extends ViaSubCommand {
@Override
@ -38,7 +37,7 @@ public class ProbeSubCmd extends ViaSubCommand {
@Override
public boolean execute(ViaCommandSender sender, String[] args) {
ProtocolDetectorService.getInstance().run();
Via.proxyPlatform().protocolDetectorService().probeAllServers();
sendMessage(sender, "&6Started searching for protocol versions");
return true;
}

View File

@ -29,9 +29,9 @@ import com.viaversion.viaversion.velocity.listeners.UpdateListener;
import com.viaversion.viaversion.velocity.providers.VelocityBossBarProvider;
import com.viaversion.viaversion.velocity.providers.VelocityMovementTransmitter;
import com.viaversion.viaversion.velocity.providers.VelocityVersionProvider;
import com.viaversion.viaversion.velocity.service.ProtocolDetectorService;
public class VelocityViaLoader implements ViaPlatformLoader {
@Override
public void load() {
Object plugin = VelocityPlugin.PROXY.getPluginManager()
@ -51,7 +51,7 @@ public class VelocityViaLoader implements ViaPlatformLoader {
int pingInterval = ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval();
if (pingInterval > 0) {
Via.getPlatform().runRepeatingSync(
new ProtocolDetectorService(),
() -> Via.proxyPlatform().protocolDetectorService().probeAllServers(),
pingInterval * 20L);
}
}

View File

@ -24,7 +24,6 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocols.base.BaseVersionProvider;
import com.viaversion.viaversion.velocity.platform.VelocityViaInjector;
import com.viaversion.viaversion.velocity.service.ProtocolDetectorService;
import io.netty.channel.ChannelHandler;
import java.lang.reflect.Method;
@ -50,7 +49,7 @@ public class VelocityVersionProvider extends BaseVersionProvider {
private int getBackProtocol(UserConnection user) throws Exception {
//TODO use newly added Velocity netty event
ChannelHandler mcHandler = user.getChannel().pipeline().get("handler");
return ProtocolDetectorService.getProtocolId(
return Via.proxyPlatform().protocolDetectorService().serverProtocolVersion(
((ServerConnection) getAssociation.invoke(mcHandler)).getServerInfo().getName());
}

View File

@ -21,80 +21,77 @@ import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.viaversion.viaversion.VelocityPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.platform.AbstractProtocolDetectorService;
import com.viaversion.viaversion.velocity.platform.VelocityViaConfig;
import java.util.HashMap;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Set;
public class ProtocolDetectorService implements Runnable {
private static final Map<String, Integer> detectedProtocolIds = new ConcurrentHashMap<>();
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 ProtocolVersion.getProtocol(Via.getManager().getInjector().getServerProtocolVersion()).getVersion();
} catch (Exception e) {
e.printStackTrace();
return ProtocolVersion.v1_8.getVersion();
}
}
public final class ProtocolDetectorService extends AbstractProtocolDetectorService {
@Override
public void run() {
for (final RegisteredServer serv : VelocityPlugin.PROXY.getAllServers()) {
probeServer(serv);
public void probeAllServers() {
final Collection<RegisteredServer> servers = VelocityPlugin.PROXY.getAllServers();
final Set<String> serverNames = new HashSet<>(servers.size());
for (final RegisteredServer server : servers) {
probeServer(server);
serverNames.add(server.getServerInfo().getName());
}
// Remove servers that aren't registered anymore
lock.writeLock().lock();
try {
detectedProtocolIds.keySet().retainAll(serverNames);
} finally {
lock.writeLock().unlock();
}
}
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 void probeServer(final RegisteredServer server) {
final String serverName = server.getServerInfo().getName();
server.ping().thenAccept(serverPing -> {
if (serverPing == null || serverPing.getVersion() == null) {
return;
}
final int oldProtocolVersion = serverProtocolVersion(serverName);
if (oldProtocolVersion != -1 && oldProtocolVersion == serverPing.getVersion().getProtocol()) {
// Same value as previously
return;
}
setProtocolVersion(serverName, serverPing.getVersion().getProtocol());
if (((VelocityViaConfig) Via.getConfig()).isVelocityPingSave()) {
final Map<String, Integer> servers = configuredServers();
final Integer protocol = servers.get(serverName);
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
return;
}
// Ensure we're the only ones writing to the config
synchronized (Via.getPlatform().getConfigurationProvider()) {
servers.put(serverName, serverPing.getVersion().getProtocol());
}
Via.getPlatform().getConfigurationProvider().saveConfig();
}
});
}
public static Map<String, Integer> getDetectedIds() {
return new HashMap<>(detectedProtocolIds);
@Override
protected Map<String, Integer> configuredServers() {
return ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols();
}
public static ProtocolDetectorService getInstance() {
return instance;
@Override
protected int lowestSupportedProtocolVersion() {
try {
return ProtocolVersion.getProtocol(Via.getManager().getInjector().getServerProtocolVersion()).getVersion();
} catch (final Exception e) {
e.printStackTrace();
return ProtocolVersion.v1_8.getVersion();
}
}
}