mirror of
https://e.coding.net/circlecloud/Yum.git
synced 2024-12-23 05:08:47 +00:00
feat: 添加安全管理工具
This commit is contained in:
parent
776820e4b7
commit
d298c2c6a6
@ -11,8 +11,10 @@ import cn.citycraft.PluginHelper.config.FileConfig;
|
||||
import cn.citycraft.PluginHelper.utils.VersionChecker;
|
||||
import pw.yumc.Yum.api.YumAPI;
|
||||
import pw.yumc.Yum.commands.FileCommand;
|
||||
import pw.yumc.Yum.commands.NetCommand;
|
||||
import pw.yumc.Yum.commands.YumCommand;
|
||||
import pw.yumc.Yum.manager.NetworkManager;
|
||||
import pw.yumc.Yum.manager.SecurityManager;
|
||||
|
||||
/**
|
||||
* MC插件仓库
|
||||
@ -21,7 +23,7 @@ import pw.yumc.Yum.manager.NetworkManager;
|
||||
* @since 2015年8月21日下午5:14:39
|
||||
*/
|
||||
public class Yum extends JavaPlugin {
|
||||
public FileConfig config;
|
||||
FileConfig config;
|
||||
NetworkManager netmgr;
|
||||
|
||||
@Override
|
||||
@ -38,7 +40,9 @@ public class Yum extends JavaPlugin {
|
||||
public void onEnable() {
|
||||
new YumAPI(this);
|
||||
new YumCommand(this);
|
||||
new NetCommand(this);
|
||||
new FileCommand(this);
|
||||
new SecurityManager(this);
|
||||
new VersionChecker(this);
|
||||
YumAPI.updaterepo(Bukkit.getConsoleSender());
|
||||
YumAPI.updatecheck(Bukkit.getConsoleSender());
|
||||
|
@ -28,7 +28,7 @@ public class FileCommand implements HandlerCommands {
|
||||
plugin = yum;
|
||||
dl = YumAPI.getDownload();
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file");
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyFileCommandConsole", true));
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true));
|
||||
cmdhandler.registerCommands(this);
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ public class FileCommand implements HandlerCommands {
|
||||
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c是一个文件 请使用file delete!");
|
||||
return;
|
||||
}
|
||||
for (final String name : plugin.config.getStringList("blacklist")) {
|
||||
for (final String name : plugin.getConfig().getStringList("blacklist")) {
|
||||
if (file.getAbsolutePath().toLowerCase().endsWith(name)) {
|
||||
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c不允许被删除!");
|
||||
return;
|
||||
|
@ -7,9 +7,10 @@ import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
|
||||
import pw.yumc.Yum.Yum;
|
||||
|
||||
public class NetCommand implements HandlerCommands {
|
||||
|
||||
public NetCommand(final Yum yum) {
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net");
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyNetCommandConsole", false));
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyNetCommandConsole", false));
|
||||
cmdhandler.registerCommands(this);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class YumCommand implements HandlerCommands, Listener {
|
||||
plugman = YumAPI.getPlugman();
|
||||
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum");
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyCommandConsole", false));
|
||||
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false));
|
||||
cmdhandler.registerCommands(this);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ 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;
|
||||
@ -13,6 +12,7 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
import cn.citycraft.PluginHelper.config.FileConfig;
|
||||
import cn.citycraft.PluginHelper.kit.ExceptionKit;
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import pw.yumc.Yum.Yum;
|
||||
|
||||
/**
|
||||
@ -24,7 +24,7 @@ import pw.yumc.Yum.Yum;
|
||||
public class NetworkManager {
|
||||
|
||||
public NetworkManager register(final Yum plugin) {
|
||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum-网络管理§6] §a注入网络管理系统 将托管服务器网络!");
|
||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §a注入网络管理系统 将托管服务器网络!");
|
||||
ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin));
|
||||
return this;
|
||||
}
|
||||
@ -41,7 +41,6 @@ public class NetworkManager {
|
||||
private final boolean allowPrimaryThread;
|
||||
private final FileConfig config;
|
||||
private final ProxySelector defaultSelector;
|
||||
private final HashMap<ClassLoader, Plugin> pluginMap = new HashMap<>();
|
||||
|
||||
public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) {
|
||||
this.config = plugin.getConfig();
|
||||
@ -61,19 +60,17 @@ public class NetworkManager {
|
||||
|
||||
@Override
|
||||
public List<Proxy> select(final URI uri) {
|
||||
if (debug || Bukkit.isPrimaryThread()) {
|
||||
final Plugin plugin = this.getRequestingPlugin();
|
||||
final boolean isPrimaryThread = Bukkit.isPrimaryThread();
|
||||
if (debug || isPrimaryThread) {
|
||||
final Plugin plugin = PluginKit.getOperatePlugin();
|
||||
final String urlinfo = uri.toString();
|
||||
if (!urlinfo.startsWith("socket") && !urlinfo.toLowerCase().contains("yumc") && !urlinfo.toLowerCase().contains("pom.xml")) {
|
||||
final String str = debug ? "§6[§bYum-网络监控§6] §c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!" : "§6[§bYum-网络管理§6] §c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!";
|
||||
if (plugin == null) {
|
||||
Bukkit.getConsoleSender().sendMessage(String.format(str, "未知(请查看堆栈)", urlinfo));
|
||||
Thread.dumpStack();
|
||||
} else if (!plugin.getName().equalsIgnoreCase("Yum")) {
|
||||
if (!urlinfo.startsWith("socket") && !urlinfo.toLowerCase().contains("yumc") && !urlinfo.toLowerCase().contains("pom.xml") && !urlinfo.toLowerCase().contains("502647092")) {
|
||||
final String str = isPrimaryThread ? "§6[§bYum §a网络管理§6] §c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!" : "§6[§bYum §a网络监控§6] §c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!";
|
||||
if (plugin != null) {
|
||||
Bukkit.getConsoleSender().sendMessage(String.format(str, plugin.getName(), urlinfo));
|
||||
if (!allowPrimaryThread) {
|
||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum-网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!");
|
||||
ExceptionKit.throwException(new IOException("[Yum-网络管理] 已开启网络防护 不允许在主线程访问网络!"));
|
||||
if (!allowPrimaryThread && isPrimaryThread) {
|
||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!");
|
||||
ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 不允许在主线程访问网络!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,32 +78,6 @@ public class NetworkManager {
|
||||
return defaultSelector.select(uri);
|
||||
}
|
||||
|
||||
private void collectPlugin() {
|
||||
if (Bukkit.getPluginManager().getPlugins().length != pluginMap.keySet().size() - 1) {
|
||||
pluginMap.clear();
|
||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
pluginMap.put(plugin.getClass().getClassLoader(), plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Plugin getRequestingPlugin() {
|
||||
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)) {
|
||||
final Plugin p = pluginMap.get(loader);
|
||||
if (element.getClassName().contains("pw.yumc.Yum.utils.") || !p.getName().equalsIgnoreCase("Yum")) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
} catch (final ClassNotFoundException ex) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -30,6 +31,7 @@ import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginLoader;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.UnknownDependencyException;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
@ -536,8 +538,7 @@ public class PluginsManager {
|
||||
List<Plugin> plugins = null;
|
||||
Map<String, Plugin> lookupNames = null;
|
||||
Map<String, Command> knownCommands = null;
|
||||
// ###移除类加载器后会导致插件无法载入###
|
||||
// Map<Pattern, PluginLoader> fileAssociations = null;
|
||||
final Map<Pattern, JavaPluginLoader> fileAssociations = null;
|
||||
if (pluginManager == null) {
|
||||
sender.sendMessage("§4异常: §c插件管理类反射获取失败!");
|
||||
return false;
|
||||
@ -558,11 +559,11 @@ public class PluginsManager {
|
||||
final Field knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands");
|
||||
knownCommandsField.setAccessible(true);
|
||||
knownCommands = (Map<String, Command>) knownCommandsField.get(commandMap);
|
||||
|
||||
// ###移除类加载器后会导致插件无法载入###
|
||||
// XXX 暂时用不到
|
||||
// final Field fileAssociationsField = pluginManager.getClass().getDeclaredField("fileAssociations");
|
||||
// fileAssociationsField.setAccessible(true);
|
||||
// fileAssociations = (Map<Pattern, PluginLoader>) fileAssociationsField.get(pluginManager);
|
||||
// fileAssociations = (Map<Pattern, JavaPluginLoader>) fileAssociationsField.get(pluginManager);
|
||||
|
||||
} catch (final Exception e) {
|
||||
sender.sendMessage("§4异常: §c" + e.getMessage() + " 插件 §b" + name + " §c卸载失败!");
|
||||
return false;
|
||||
@ -592,16 +593,39 @@ public class PluginsManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
// try {
|
||||
// if (fileAssociations != null) {
|
||||
// // XXX 不能移除 会导致无法加载
|
||||
// for (final Iterator<Entry<Pattern, JavaPluginLoader>> filter = fileAssociations.entrySet().iterator(); filter.hasNext();) {
|
||||
// final Entry<Pattern, JavaPluginLoader> entry = filter.next();
|
||||
// final Matcher match = entry.getKey().matcher(getPluginFile(next).getName());
|
||||
// if (match.find()) {
|
||||
// final JavaPluginLoader pluginLoader = entry.getValue();
|
||||
// final Field loadersField = pluginLoader.getClass().getDeclaredField("loaders");
|
||||
// loadersField.setAccessible(true);
|
||||
// final Map<String, URLClassLoader> loaders = (Map<String, URLClassLoader>) loadersField.get(pluginLoader);
|
||||
// // XXX 不能移除 会导致无法调用其他插件
|
||||
// loaders.clear();
|
||||
// sender.sendMessage("§6卸载: §a移除插件 §b" + name + " §a的类实例缓存!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (final Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
sender.sendMessage("§6卸载: §a注销插件 §b" + name + " §a的所有命令!");
|
||||
final ClassLoader cl = next.getClass().getClassLoader();
|
||||
try {
|
||||
((URLClassLoader) cl).close();
|
||||
} catch (final IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
if (!pluginVersion.isEmpty()) {
|
||||
if (!pluginVersion.isEmpty())
|
||||
|
||||
{
|
||||
sender.sendMessage("§6卸载: §a插件 §b" + name + " §a版本 §d" + pluginVersion + " §a已成功卸载!");
|
||||
return true;
|
||||
}
|
||||
|
36
src/main/java/pw/yumc/Yum/manager/SecurityManager.java
Normal file
36
src/main/java/pw/yumc/Yum/manager/SecurityManager.java
Normal file
@ -0,0 +1,36 @@
|
||||
package pw.yumc.Yum.manager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||
import pw.yumc.Yum.Yum;
|
||||
import pw.yumc.injected.event.SetOpEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 2016年3月31日 下午3:01:22
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class SecurityManager implements Listener {
|
||||
public String warn = "§6[§bYum §a安全系统§6] §c插件 §e%s §c已设置玩家 §a%s §c为OP §4请注意服务器安全!";
|
||||
public String prevent = "§6[§bYum §a安全系统§6] §c黑名单插件 §e%s §c尝试设置玩家 §a%s §c为OP §a安全系统已成功拦截!";
|
||||
|
||||
public SecurityManager(final Yum yum) {
|
||||
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void setop(final SetOpEvent event) {
|
||||
final Plugin plugin = PluginKit.getOperatePlugin();
|
||||
if (plugin != null) {
|
||||
if (plugin.getName().equalsIgnoreCase("BukkitInjectedTools")) {
|
||||
Bukkit.getConsoleSender().sendMessage(String.format(prevent, plugin, event.getOfflinePlayer().getName()));
|
||||
} else {
|
||||
Bukkit.getConsoleSender().sendMessage(String.format(warn, plugin, event.getOfflinePlayer().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ name: ${project.artifactId}
|
||||
description: ${project.description}
|
||||
main: ${project.groupId}.${project.artifactId}.${project.artifactId}
|
||||
version: ${project.version}-git-${env.GIT_COMMIT}
|
||||
load: STARTUP
|
||||
author: 喵♂呜
|
||||
website: ${ciManagement.url}
|
||||
commands:
|
||||
@ -23,6 +24,12 @@ commands:
|
||||
usage: §6使用§a/file help§6查看帮助!
|
||||
permission: file.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
security:
|
||||
description: MC安全管理命令
|
||||
aliases: [f]
|
||||
usage: §6使用§a/security help§6查看帮助!
|
||||
permission: file.use
|
||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||
permissions:
|
||||
yum.use:
|
||||
description: 插件管理系统使用权限!
|
||||
|
Loading…
Reference in New Issue
Block a user