Config for protocol versions

Also make config concurrent
This commit is contained in:
Myles 2016-10-02 19:40:38 +01:00
parent 3fe25f68b1
commit 21c957b8d5
12 changed files with 209 additions and 40 deletions

View File

@ -8,9 +8,10 @@ import us.myles.ViaVersion.util.Config;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class BukkitConfigAPI extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList();
private static List<String> UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers");
public BukkitConfigAPI() {
super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml"));
@ -166,6 +167,11 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig {
return getString("reload-disconnect-msg", "Server reload, please rejoin!");
}
@Override
protected void handleConfig(Map<String, Object> config) {
// Nothing currently
}
@Override
public List<String> getUnsupportedOptions() {
return UNSUPPORTED;

View File

@ -58,8 +58,6 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
.loader(new BungeeViaLoader(this))
.commandHandler(commandHandler)
.build());
getProxy().getPluginManager().registerListener(this, this);
}
@Override
@ -137,7 +135,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
}
@Override
public ViaVersionConfig getConf() {
public BungeeConfigAPI getConf() {
return config;
}
@ -160,7 +158,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
plugins.add(new PluginInfo(true, p.getDescription().getName(), p.getDescription().getVersion(), p.getDescription().getMain(), Arrays.asList(p.getDescription().getAuthor())));
platformSpecific.add("plugins", GsonUtil.getGson().toJsonTree(plugins));
platformSpecific.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getProtocolIds()));
platformSpecific.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds()));
return platformSpecific;
}

View File

@ -102,12 +102,6 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
storage.setCurrentServer(serverName);
// TODO HANDLE
if (!ProtocolDetectorService.hasProtocolId(serverName)) {
Via.getPlatform().getLogger().severe("Could not find the protocol id for server " + serverName);
return;
}
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
UserConnection viaConnection = Via.getManager().getConnection(player.getUniqueId());
@ -124,7 +118,6 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
pipeline.add(prot.getValue());
}
viaConnection.put(info);
viaConnection.put(storage);
@ -137,7 +130,6 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
Object wrapper = ReflectionUtil.get(player, "ch", Object.class);
wrapper.getClass().getDeclaredMethod("setVersion", int.class).invoke(wrapper, protocolId);
// ReflectionUtil.invoke(player, "init");
Object entityMap = Class.forName("net.md_5.bungee.entitymap.EntityMap").getDeclaredMethod("getEntityMap", int.class).invoke(null, protocolId);
ReflectionUtil.set(player, "entityRewrite", entityMap);

View File

@ -1,11 +1,12 @@
package us.myles.ViaVersion.bungee.platform;
import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
import us.myles.ViaVersion.util.Config;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.*;
public class BungeeConfigAPI extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch");
@ -14,6 +15,38 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig {
super(new File(configFile, "config.yml"));
}
@Override
protected void handleConfig(Map<String, Object> config) {
// Parse servers
Map<String, Object> servers;
if (!(config.get("bungee-servers") instanceof Map)) {
servers = new HashMap<>();
} else {
servers = (Map) config.get("bungee-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")) {
servers.put("default", BungeeVersionProvider.getLowestSupportedVersion());
}
// Put back
config.put("bungee-servers", servers);
}
@Override
public List<String> getUnsupportedOptions() {
return UNSUPPORTED;
@ -167,4 +200,33 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig {
public String getReloadDisconnectMsg() {
return getString("reload-disconnect-msg", "Server reload, please rejoin!");
}
/**
* What is the interval for checking servers via ping
* -1 for disabled
*
* @return Ping interval in seconds
*/
public int getBungeePingInterval() {
return getInt("bungee-ping-interval", 60);
}
/**
* Should the bungee ping be saved to the config on change.
*
* @return True if it should save
*/
public boolean isBungeePingSave() {
return getBoolean("bungee-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> getBungeeServerProtocols() {
return get("bungee-servers", Map.class, new HashMap<>());
}
}

View File

@ -1,6 +1,7 @@
package us.myles.ViaVersion.bungee.platform;
import lombok.AllArgsConstructor;
import net.md_5.bungee.api.ProxyServer;
import us.myles.ViaVersion.BungeePlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
@ -18,9 +19,13 @@ public class BungeeViaLoader implements ViaPlatformLoader {
@Override
public void load() {
// Listeners
ProxyServer.getInstance().getPluginManager().registerListener(plugin, plugin);
// Providers
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider());
plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, 1, TimeUnit.MINUTES);
if (plugin.getConf().getBungeePingInterval() > 0) {
plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, plugin.getConf().getBungeePingInterval(), TimeUnit.SECONDS);
}
}
}

View File

@ -1,6 +1,7 @@
package us.myles.ViaVersion.bungee.providers;
import com.google.common.collect.Lists;
import net.md_5.bungee.api.ProxyServer;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.base.VersionProvider;
@ -11,7 +12,7 @@ import java.util.List;
public class BungeeVersionProvider extends VersionProvider {
private static Class<?> ref;
public BungeeVersionProvider() {
static {
try {
ref = Class.forName("net.md_5.bungee.protocol.ProtocolConstants");
} catch (Exception e) {
@ -35,7 +36,7 @@ public class BungeeVersionProvider extends VersionProvider {
// Older than bungee supports, get the lowest version
if (info.getProtocolVersion() < list.get(0)) {
return list.get(0);
return getLowestSupportedVersion();
}
// Loop through all protocols to get the closest protocol id that bungee supports
@ -47,4 +48,18 @@ public class BungeeVersionProvider extends VersionProvider {
System.out.println("Panic, no protocol id found for " + info.getProtocolVersion());
return info.getProtocolVersion();
}
public static int getLowestSupportedVersion() {
List<Integer> list;
try {
list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSION_IDS", List.class);
return list.get(0);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// Fallback
return ProxyServer.getInstance().getProtocolVersion();
}
}

View File

@ -2,16 +2,22 @@ package us.myles.ViaVersion.bungee.service;
import lombok.Getter;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.config.ServerInfo;
import us.myles.ViaVersion.BungeePlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI;
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ProtocolDetectorService implements Runnable {
private static final Map<String, Integer> protocolIds = new ConcurrentHashMap<>();
private static final Map<String, Integer> detectedProtocolIds = new ConcurrentHashMap<>();
private BungeePlugin plugin;
@Getter
private static ProtocolDetectorService instance;
@ -22,13 +28,21 @@ public class ProtocolDetectorService implements Runnable {
}
public static Integer getProtocolId(String serverName) {
if (!hasProtocolId(serverName))
return -1;
return protocolIds.get(serverName);
}
public static boolean hasProtocolId(String serverName) {
return protocolIds.containsKey(serverName);
// Step 1. Check Config
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
if (servers.containsKey(serverName)) {
return servers.get(serverName);
}
// Step 2. Check Detected
if (detectedProtocolIds.containsKey(serverName)) {
return detectedProtocolIds.get(serverName);
}
// Step 3. Use Default
if (servers.containsKey("default")) {
return servers.get("default");
}
// Step 4: Use bungee lowest supported... *cries*
return BungeeVersionProvider.getLowestSupportedVersion();
}
@Override
@ -42,14 +56,27 @@ public class ProtocolDetectorService implements Runnable {
value.ping(new Callback<ServerPing>() {
@Override
public void done(ServerPing serverPing, Throwable throwable) {
if (throwable == null)
protocolIds.put(key, serverPing.getVersion().getProtocol());
if (throwable == null) {
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) {
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
if (servers.containsKey(key)) {
if (servers.get(key) == serverPing.getVersion().getProtocol()) {
return;
}
}
// Save Server
servers.put(key, serverPing.getVersion().getProtocol());
// Save
Via.getPlatform().getConfigurationProvider().saveConfig();
}
}
}
});
}
public static Map<String, Integer> getProtocolIds() {
return new HashMap<>(protocolIds);
public static Map<String, Integer> getDetectedIds() {
return new HashMap<>(detectedProtocolIds);
}
}

View File

@ -51,7 +51,8 @@ public class ProtocolVersion {
register(v1_9_2 = new ProtocolVersion(109, "1.9.2"));
register(v1_9_3 = new ProtocolVersion(110, "1.9.3/4"));
register(v1_10 = new ProtocolVersion(210, "1.10"));
register(vSNAPSHOT = new ProtocolVersion(309, "1.11-SNAPSHOT"));
// Snapshot uses colon as dashes are used other places...
register(vSNAPSHOT = new ProtocolVersion(309, "1.11:SNAPSHOT"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
}
@ -80,6 +81,24 @@ public class ProtocolVersion {
return Collections.unmodifiableList(new ArrayList<>(versions.values()));
}
public static ProtocolVersion getClosest(String protocol) {
for (ProtocolVersion version : versions.values()) {
if (version.getName().equals(protocol))
return version;
if (version.getName().equals(protocol + ".x"))
return version;
String[] parts = version.getName().split("-");
for (String part : parts) {
if (part.equalsIgnoreCase(protocol)) {
return version;
}
if (part.equals(protocol + ".x"))
return version;
}
}
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@ -1,5 +1,6 @@
package us.myles.ViaVersion.util;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
@ -9,17 +10,21 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class Config implements ConfigurationProvider {
private static ThreadLocal<Yaml> yaml = new ThreadLocal<Yaml>() {
@Override
protected Yaml initialValue() {
return new Yaml();
DumperOptions options = new DumperOptions();
// options.setPrettyFlow(true);
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
return new Yaml(options);
}
};
private CommentStore commentStore = new CommentStore('.', 2);
private final File configFile;
private Map<String, Object> config;
private ConcurrentHashMap<String, Object> config;
public Config(File configFile) {
this.configFile = configFile;
@ -70,12 +75,16 @@ public abstract class Config implements ConfigurationProvider {
} catch (IOException e) {
e.printStackTrace();
}
// Call Handler
handleConfig(defaults);
// Save
saveConfig(location, defaults);
return defaults;
}
protected abstract void handleConfig(Map<String, Object> config);
public void saveConfig(File location, Map<String, Object> config) {
try {
commentStore.writeComments(yaml.get().dump(config), location);
@ -100,7 +109,7 @@ public abstract class Config implements ConfigurationProvider {
@Override
public void reloadConfig() {
this.configFile.getParentFile().mkdirs();
this.config = loadConfig(this.configFile);
this.config = new ConcurrentHashMap<>(loadConfig(this.configFile));
}
@Override
@ -108,6 +117,14 @@ public abstract class Config implements ConfigurationProvider {
return this.config;
}
public <T> T get(String key, Class<T> clazz, T def) {
if (this.config.containsKey(key)) {
return (T) this.config.get(key);
} else {
return def;
}
}
public boolean getBoolean(String key, boolean def) {
if (this.config.containsKey(key)) {
return (boolean) this.config.get(key);

View File

@ -3,9 +3,10 @@
# If you need help:
# viaversion.com - Discussion tab
# IRC - https://elmer.spi.gt/iris/?nick=&channels=viaversion #viaversion on irc.spi.gt
# Docs - https://docs.viaversion.com/display/VIAVERSION/Configuration
#
#----------------------------------------------------------#
# GLOBAL OPTIONS #
# GLOBAL OPTIONS #
#----------------------------------------------------------#
#
# Should ViaVersion check for updates?
@ -23,7 +24,29 @@ block-disconnect-msg: "You are using an unsupported Minecraft version!"
reload-disconnect-msg: "Server reload, please rejoin!"
#
#----------------------------------------------------------#
# GLOBAL PACKET LIMITER #
# BUNGEE OPTIONS #
#----------------------------------------------------------#
#
# BungeeCord 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.
bungee-ping-interval: 60
# If the above is enabled, should we save the info to the config (in the section below)
bungee-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 bungee-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.
bungee-servers: {}
#
#----------------------------------------------------------#
# GLOBAL PACKET LIMITER #
#----------------------------------------------------------#
#
#

View File

@ -13,7 +13,6 @@ import org.spongepowered.api.scheduler.SpongeExecutorService;
import org.spongepowered.api.text.serializer.TextSerializers;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.ViaAPI;
import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
import us.myles.ViaVersion.api.platform.TaskId;
@ -162,7 +161,7 @@ public class SpongePlugin implements ViaPlatform {
}
@Override
public ViaVersionConfig getConf() {
public SpongeConfigAPI getConf() {
return conf;
}

View File

@ -6,14 +6,20 @@ import us.myles.ViaVersion.util.Config;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class SpongeConfigAPI extends Config implements ViaVersionConfig {
private static List<String> UNSUPPORTED = Arrays.asList("anti-xray-patch");
private static List<String> UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers");
public SpongeConfigAPI(File configFile) {
super(new File(configFile, "config.yml"));
}
@Override
protected void handleConfig(Map<String, Object> config) {
// Nothing Currently
}
@Override
public List<String> getUnsupportedOptions() {
return UNSUPPORTED;