diff --git a/src/main/java/pw/yumc/Yum/Yum.java b/src/main/java/pw/yumc/Yum/Yum.java index abff9ac..574c6e7 100644 --- a/src/main/java/pw/yumc/Yum/Yum.java +++ b/src/main/java/pw/yumc/Yum/Yum.java @@ -28,6 +28,7 @@ public class Yum extends JavaPlugin { new YumCommand(this); new FileCommand(this); new VersionChecker(this); + // new NetworkManager(this).setDebug(true).register(); YumAPI.updaterepo(Bukkit.getConsoleSender()); YumAPI.updatecheck(Bukkit.getConsoleSender()); } diff --git a/src/main/java/pw/yumc/Yum/manager/NetworkManager.java b/src/main/java/pw/yumc/Yum/manager/NetworkManager.java new file mode 100644 index 0000000..813c6ac --- /dev/null +++ b/src/main/java/pw/yumc/Yum/manager/NetworkManager.java @@ -0,0 +1,105 @@ +package pw.yumc.Yum.manager; + +import java.io.IOException; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import pw.yumc.Yum.Yum; + +/** + * 网络代理处理类 + * + * @since 2016年3月26日 下午4:24:09 + * @author 喵♂呜 + */ +public class NetworkManager { + private static boolean debug; + + private static HashMap pluginMap = new HashMap<>(); + + private final Yum main; + + public NetworkManager(final Yum plugin) { + this.main = plugin; + } + + public void register() { + ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault())); + } + + public NetworkManager setDebug(final boolean debug) { + NetworkManager.debug = debug; + return this; + } + + public void unregister() { + final ProxySelector cur = ProxySelector.getDefault(); + if (cur instanceof YumProxySelector) { + ProxySelector.setDefault(((YumProxySelector) cur).getDefaultSelector()); + } + } + + class YumProxySelector extends ProxySelector { + private final ProxySelector defaultSelector; + + public YumProxySelector(final ProxySelector defaultSelector) { + this.defaultSelector = defaultSelector; + } + + @Override + public void connectFailed(final URI uri, final SocketAddress sa, final IOException ioe) { + this.defaultSelector.connectFailed(uri, sa, ioe); + } + + public ProxySelector getDefaultSelector() { + return this.defaultSelector; + } + + @Override + public List select(final URI uri) { + if (NetworkManager.debug || Bukkit.isPrimaryThread()) { + final Plugin plugin = this.getRequestingPlugin(); + final String urlinfo = uri.getHost() + ":" + uri.getPort() + "/" + uri.getPath(); + final String str = debug ? "[NetDebug] 插件 %s 尝试访问 %s 请注意服务器网络安全!" : "[NetManager] 插件 %s 尝试在主线程访问 %s 可能会导致服务器卡顿或无响应!"; + if (plugin == null) { + main.getLogger().warning(String.format(str, "未知(请查看堆栈)", urlinfo)); + Thread.dumpStack(); + } else if (!plugin.getName().equalsIgnoreCase("Yum")) { + main.getLogger().warning(String.format(str, plugin.getName(), urlinfo)); + } + } + return this.defaultSelector.select(uri); + } + + private void collectPlugin() { + for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + pluginMap.put(plugin.getClass().getClassLoader(), plugin); + } + } + + private Plugin getRequestingPlugin() { + if (Bukkit.getPluginManager().getPlugins().length != pluginMap.keySet().size() - 1) { + collectPlugin(); + } + final StackTraceElement[] stacktrace = new Exception().getStackTrace(); + for (final StackTraceElement element : stacktrace) { + try { + final ClassLoader loader = Class.forName(element.getClassName(), false, getClass().getClassLoader()).getClassLoader(); + if (pluginMap.containsKey(loader)) { + return pluginMap.get(loader); + } + } catch (final ClassNotFoundException ex) { + } + } + return null; + } + } + +}