Added user/ip/wildcard/regex ban commands
This commit is contained in:
parent
94a8c3f6e9
commit
09fdd00900
Binary file not shown.
|
@ -19,7 +19,6 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import java.util.Iterator;
|
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
@ -28,7 +27,6 @@ import io.netty.util.AttributeKey;
|
||||||
import net.md_5.bungee.netty.PipelineUtils;
|
import net.md_5.bungee.netty.PipelineUtils;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.util.concurrent.Future;
|
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
@ -38,7 +36,7 @@ import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.command.ConsoleCommandSender;
|
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.Calendar;
|
import java.util.ArrayList;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import jline.UnsupportedTerminal;
|
import jline.UnsupportedTerminal;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -50,6 +48,14 @@ import jline.internal.Log;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import net.md_5.bungee.command.CommandFind;
|
import net.md_5.bungee.command.CommandFind;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalBan;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalBanIP;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalBanRegex;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalBanReload;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalBanWildcard;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalCheckBan;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalListBan;
|
||||||
|
import net.md_5.bungee.command.CommandGlobalUnban;
|
||||||
import net.md_5.bungee.command.CommandSend;
|
import net.md_5.bungee.command.CommandSend;
|
||||||
import net.md_5.bungee.command.CommandPerms;
|
import net.md_5.bungee.command.CommandPerms;
|
||||||
import net.md_5.bungee.command.CommandBungee;
|
import net.md_5.bungee.command.CommandBungee;
|
||||||
|
@ -61,10 +67,9 @@ import net.md_5.bungee.command.CommandEnd;
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.command.CommandReload;
|
import net.md_5.bungee.command.CommandReload;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import net.md_5.bungee.scheduler.BungeeScheduler;
|
import net.md_5.bungee.scheduler.BungeeScheduler;
|
||||||
import net.md_5.bungee.config.YamlConfig;
|
import net.md_5.bungee.config.YamlConfig;
|
||||||
import net.md_5.bungee.eaglercraft.PluginEaglerAuth;
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
import net.md_5.bungee.eaglercraft.PluginEaglerSkins;
|
import net.md_5.bungee.eaglercraft.PluginEaglerSkins;
|
||||||
import net.md_5.bungee.eaglercraft.WebSocketListener;
|
import net.md_5.bungee.eaglercraft.WebSocketListener;
|
||||||
|
|
||||||
|
@ -99,6 +104,8 @@ public class BungeeCord extends ProxyServer {
|
||||||
public final ScheduledThreadPoolExecutor executors;
|
public final ScheduledThreadPoolExecutor executors;
|
||||||
public final MultithreadEventLoopGroup eventLoops;
|
public final MultithreadEventLoopGroup eventLoops;
|
||||||
private final Timer saveThread;
|
private final Timer saveThread;
|
||||||
|
private final Timer reloadBanThread;
|
||||||
|
private final Timer closeInactiveSockets;
|
||||||
private Collection<Channel> listeners;
|
private Collection<Channel> listeners;
|
||||||
private Collection<WebSocketListener> wsListeners;
|
private Collection<WebSocketListener> wsListeners;
|
||||||
private final Map<String, UserConnection> connections;
|
private final Map<String, UserConnection> connections;
|
||||||
|
@ -111,6 +118,7 @@ public class BungeeCord extends ProxyServer {
|
||||||
private final TaskScheduler scheduler;
|
private final TaskScheduler scheduler;
|
||||||
private ConsoleReader consoleReader;
|
private ConsoleReader consoleReader;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
|
private Collection<Command> banCommands;
|
||||||
|
|
||||||
public static BungeeCord getInstance() {
|
public static BungeeCord getInstance() {
|
||||||
return (BungeeCord) ProxyServer.getInstance();
|
return (BungeeCord) ProxyServer.getInstance();
|
||||||
|
@ -122,6 +130,8 @@ public class BungeeCord extends ProxyServer {
|
||||||
this.executors = new BungeeThreadPool(new ThreadFactoryBuilder().setNameFormat("Bungee Pool Thread #%1$d").build());
|
this.executors = new BungeeThreadPool(new ThreadFactoryBuilder().setNameFormat("Bungee Pool Thread #%1$d").build());
|
||||||
this.eventLoops = (MultithreadEventLoopGroup) new NioEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setNameFormat("Netty IO Thread #%1$d").build());
|
this.eventLoops = (MultithreadEventLoopGroup) new NioEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setNameFormat("Netty IO Thread #%1$d").build());
|
||||||
this.saveThread = new Timer("Reconnect Saver");
|
this.saveThread = new Timer("Reconnect Saver");
|
||||||
|
this.reloadBanThread = new Timer("Ban List Reload");
|
||||||
|
this.closeInactiveSockets = new Timer("close Inactive WebSockets");
|
||||||
this.listeners = new HashSet<Channel>();
|
this.listeners = new HashSet<Channel>();
|
||||||
this.wsListeners = new HashSet<WebSocketListener>();
|
this.wsListeners = new HashSet<WebSocketListener>();
|
||||||
this.connections = (Map<String, UserConnection>) new CaseInsensitiveMap();
|
this.connections = (Map<String, UserConnection>) new CaseInsensitiveMap();
|
||||||
|
@ -131,6 +141,7 @@ public class BungeeCord extends ProxyServer {
|
||||||
this.pluginChannels = new HashSet<String>();
|
this.pluginChannels = new HashSet<String>();
|
||||||
this.pluginsFolder = new File("plugins");
|
this.pluginsFolder = new File("plugins");
|
||||||
this.scheduler = new BungeeScheduler();
|
this.scheduler = new BungeeScheduler();
|
||||||
|
this.banCommands = new ArrayList();
|
||||||
this.getPluginManager().registerCommand(null, new CommandReload());
|
this.getPluginManager().registerCommand(null, new CommandReload());
|
||||||
this.getPluginManager().registerCommand(null, new CommandEnd());
|
this.getPluginManager().registerCommand(null, new CommandEnd());
|
||||||
this.getPluginManager().registerCommand(null, new CommandList());
|
this.getPluginManager().registerCommand(null, new CommandList());
|
||||||
|
@ -154,6 +165,42 @@ public class BungeeCord extends ProxyServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reconfigureBanCommands(boolean replaceBukkit) {
|
||||||
|
if(banCommands.size() > 0) {
|
||||||
|
for(Command c : banCommands) {
|
||||||
|
this.getPluginManager().unregisterCommand(c);
|
||||||
|
}
|
||||||
|
banCommands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Command cBan = new CommandGlobalBan(replaceBukkit);
|
||||||
|
Command cUnban = new CommandGlobalUnban(replaceBukkit);
|
||||||
|
Command cBanReload = new CommandGlobalBanReload(replaceBukkit);
|
||||||
|
Command cBanIP = new CommandGlobalBanIP(replaceBukkit);
|
||||||
|
Command cBanWildcard = new CommandGlobalBanWildcard(replaceBukkit);
|
||||||
|
Command cBanRegex = new CommandGlobalBanRegex(replaceBukkit);
|
||||||
|
Command cBanCheck = new CommandGlobalCheckBan(replaceBukkit);
|
||||||
|
Command cBanList = new CommandGlobalListBan(replaceBukkit);
|
||||||
|
|
||||||
|
banCommands.add(cBan);
|
||||||
|
banCommands.add(cUnban);
|
||||||
|
banCommands.add(cBanReload);
|
||||||
|
banCommands.add(cBanIP);
|
||||||
|
banCommands.add(cBanWildcard);
|
||||||
|
banCommands.add(cBanRegex);
|
||||||
|
banCommands.add(cBanCheck);
|
||||||
|
banCommands.add(cBanList);
|
||||||
|
|
||||||
|
this.getPluginManager().registerCommand(null, cBan);
|
||||||
|
this.getPluginManager().registerCommand(null, cUnban);
|
||||||
|
this.getPluginManager().registerCommand(null, cBanReload);
|
||||||
|
this.getPluginManager().registerCommand(null, cBanIP);
|
||||||
|
this.getPluginManager().registerCommand(null, cBanWildcard);
|
||||||
|
this.getPluginManager().registerCommand(null, cBanRegex);
|
||||||
|
this.getPluginManager().registerCommand(null, cBanCheck);
|
||||||
|
this.getPluginManager().registerCommand(null, cBanList);
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
final BungeeCord bungee = new BungeeCord();
|
final BungeeCord bungee = new BungeeCord();
|
||||||
ProxyServer.setInstance(bungee);
|
ProxyServer.setInstance(bungee);
|
||||||
|
@ -186,6 +233,20 @@ public class BungeeCord extends ProxyServer {
|
||||||
BungeeCord.this.getReconnectHandler().save();
|
BungeeCord.this.getReconnectHandler().save();
|
||||||
}
|
}
|
||||||
}, 0L, TimeUnit.MINUTES.toMillis(5L));
|
}, 0L, TimeUnit.MINUTES.toMillis(5L));
|
||||||
|
this.reloadBanThread.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
BanList.maybeReloadBans(null);
|
||||||
|
}
|
||||||
|
}, 0L, TimeUnit.SECONDS.toMillis(3L));
|
||||||
|
this.closeInactiveSockets.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for(WebSocketListener lst : BungeeCord.this.wsListeners) {
|
||||||
|
lst.closeInactiveSockets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0L, TimeUnit.SECONDS.toMillis(10L));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startListeners() {
|
public void startListeners() {
|
||||||
|
|
|
@ -4,13 +4,10 @@
|
||||||
|
|
||||||
package net.md_5.bungee;
|
package net.md_5.bungee;
|
||||||
|
|
||||||
import net.md_5.bungee.api.connection.Server;
|
|
||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
|
||||||
import java.beans.ConstructorProperties;
|
import java.beans.ConstructorProperties;
|
||||||
import net.md_5.bungee.util.CaseInsensitiveSet;
|
import net.md_5.bungee.util.CaseInsensitiveSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import net.md_5.bungee.api.config.TexturePackInfo;
|
import net.md_5.bungee.api.config.TexturePackInfo;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.event.PermissionCheckEvent;
|
import net.md_5.bungee.api.event.PermissionCheckEvent;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
@ -36,10 +33,14 @@ import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
import net.md_5.bungee.api.connection.Connection;
|
||||||
import net.md_5.bungee.api.score.Scoreboard;
|
import net.md_5.bungee.api.score.Scoreboard;
|
||||||
import net.md_5.bungee.protocol.packet.PacketCCSettings;
|
import net.md_5.bungee.protocol.packet.PacketCCSettings;
|
||||||
|
@ -71,6 +72,7 @@ public final class UserConnection implements ProxiedPlayer {
|
||||||
private final Scoreboard serverSentScoreboard;
|
private final Scoreboard serverSentScoreboard;
|
||||||
private String displayName;
|
private String displayName;
|
||||||
private final Connection.Unsafe unsafe;
|
private final Connection.Unsafe unsafe;
|
||||||
|
private final Map<String, Object> attachment = new WeakHashMap();
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
this.displayName = this.name;
|
this.displayName = this.name;
|
||||||
|
@ -383,4 +385,9 @@ public final class UserConnection implements ProxiedPlayer {
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return this.displayName;
|
return this.displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getAttachment() {
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package net.md_5.bungee.api;
|
package net.md_5.bungee.api;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface CommandSender {
|
public interface CommandSender {
|
||||||
String getName();
|
String getName();
|
||||||
|
@ -22,4 +23,6 @@ public interface CommandSender {
|
||||||
boolean hasPermission(final String p0);
|
boolean hasPermission(final String p0);
|
||||||
|
|
||||||
void setPermission(final String p0, final boolean p1);
|
void setPermission(final String p0, final boolean p1);
|
||||||
|
|
||||||
|
Map<String, Object> getAttachment();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
package net.md_5.bungee.api.config;
|
package net.md_5.bungee.api.config;
|
||||||
|
|
||||||
import java.beans.ConstructorProperties;
|
import java.beans.ConstructorProperties;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ServerIcon;
|
||||||
import net.md_5.bungee.api.tab.TabListHandler;
|
import net.md_5.bungee.api.tab.TabListHandler;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
@ -18,13 +21,18 @@ public class ListenerInfo {
|
||||||
private final String fallbackServer;
|
private final String fallbackServer;
|
||||||
private final boolean forceDefault;
|
private final boolean forceDefault;
|
||||||
private final boolean websocket;
|
private final boolean websocket;
|
||||||
|
private final boolean forwardIp;
|
||||||
private final Map<String, String> forcedHosts;
|
private final Map<String, String> forcedHosts;
|
||||||
private final TexturePackInfo texturePack;
|
private final TexturePackInfo texturePack;
|
||||||
private final Class<? extends TabListHandler> tabList;
|
private final Class<? extends TabListHandler> tabList;
|
||||||
|
private final String serverIcon;
|
||||||
|
private final int[] serverIconCache;
|
||||||
|
private boolean serverIconLoaded;
|
||||||
|
private boolean serverIconSet;
|
||||||
|
|
||||||
@ConstructorProperties({ "host", "motd", "maxPlayers", "tabListSize", "defaultServer", "fallbackServer", "forceDefault", "websocket", "forcedHosts", "texturePack", "tabList" })
|
@ConstructorProperties({ "host", "motd", "maxPlayers", "tabListSize", "defaultServer", "fallbackServer", "forceDefault", "websocket", "forwardIp", "forcedHosts", "texturePack", "tabList", "serverIcon" })
|
||||||
public ListenerInfo(final InetSocketAddress host, final String motd, final int maxPlayers, final int tabListSize, final String defaultServer, final String fallbackServer, final boolean forceDefault, final boolean websocket,
|
public ListenerInfo(final InetSocketAddress host, final String motd, final int maxPlayers, final int tabListSize, final String defaultServer, final String fallbackServer, final boolean forceDefault, final boolean websocket,
|
||||||
final Map<String, String> forcedHosts, final TexturePackInfo texturePack, final Class<? extends TabListHandler> tabList) {
|
final boolean forwardIp, final Map<String, String> forcedHosts, final TexturePackInfo texturePack, final Class<? extends TabListHandler> tabList, final String serverIcon) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.motd = motd;
|
this.motd = motd;
|
||||||
this.maxPlayers = maxPlayers;
|
this.maxPlayers = maxPlayers;
|
||||||
|
@ -33,9 +41,14 @@ public class ListenerInfo {
|
||||||
this.fallbackServer = fallbackServer;
|
this.fallbackServer = fallbackServer;
|
||||||
this.forceDefault = forceDefault;
|
this.forceDefault = forceDefault;
|
||||||
this.websocket = websocket;
|
this.websocket = websocket;
|
||||||
|
this.forwardIp = forwardIp;
|
||||||
this.forcedHosts = forcedHosts;
|
this.forcedHosts = forcedHosts;
|
||||||
this.texturePack = texturePack;
|
this.texturePack = texturePack;
|
||||||
this.tabList = tabList;
|
this.tabList = tabList;
|
||||||
|
this.serverIcon = serverIcon;
|
||||||
|
this.serverIconCache = new int[4096];
|
||||||
|
this.serverIconLoaded = false;
|
||||||
|
this.serverIconSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InetSocketAddress getHost() {
|
public InetSocketAddress getHost() {
|
||||||
|
@ -120,6 +133,9 @@ public class ListenerInfo {
|
||||||
if (this.getTabListSize() != other.getTabListSize()) {
|
if (this.getTabListSize() != other.getTabListSize()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (this.isWebsocket() != other.isWebsocket()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final Object this$defaultServer = this.getDefaultServer();
|
final Object this$defaultServer = this.getDefaultServer();
|
||||||
final Object other$defaultServer = other.getDefaultServer();
|
final Object other$defaultServer = other.getDefaultServer();
|
||||||
Label_0165: {
|
Label_0165: {
|
||||||
|
@ -180,6 +196,15 @@ public class ListenerInfo {
|
||||||
} else if (this$tabList.equals(other$tabList)) {
|
} else if (this$tabList.equals(other$tabList)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
final Object this$getServerIcon = this.getServerIcon();
|
||||||
|
final Object other$getServerIcon = other.getServerIcon();
|
||||||
|
if (this$getServerIcon == null) {
|
||||||
|
if (other$getServerIcon == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (this$getServerIcon.equals(other$getServerIcon)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +233,8 @@ public class ListenerInfo {
|
||||||
result = result * 31 + (($texturePack == null) ? 0 : $texturePack.hashCode());
|
result = result * 31 + (($texturePack == null) ? 0 : $texturePack.hashCode());
|
||||||
final Object $tabList = this.getTabList();
|
final Object $tabList = this.getTabList();
|
||||||
result = result * 31 + (($tabList == null) ? 0 : $tabList.hashCode());
|
result = result * 31 + (($tabList == null) ? 0 : $tabList.hashCode());
|
||||||
|
final Object $serverIconCache = this.getTabList();
|
||||||
|
result = result * 31 + (($serverIconCache == null) ? 0 : $serverIconCache.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,4 +247,9 @@ public class ListenerInfo {
|
||||||
public boolean isWebsocket() {
|
public boolean isWebsocket() {
|
||||||
return websocket;
|
return websocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasForwardedHeaders() {
|
||||||
|
return forwardIp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
|
||||||
|
public class CommandGlobalBan extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalBan(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "ban" : "eag-ban", "bungeecord.command.eag.ban", replaceBukkit ? new String[] { "kickban", "eag-ban", "e-ban", "gban" } : new String[] { "e-ban", "gban" });
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
if(p1.length >= 1) {
|
||||||
|
String p = p1[0].trim().toLowerCase();
|
||||||
|
if(p0.getName().equalsIgnoreCase(p)) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "You cannot ban yourself");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String reason = "The ban hammer has spoken!";
|
||||||
|
if(p1.length >= 2) {
|
||||||
|
reason = "";
|
||||||
|
for(int i = 1; i < p1.length; ++i) {
|
||||||
|
if(reason.length() > 0) {
|
||||||
|
reason += " ";
|
||||||
|
}
|
||||||
|
reason += p1[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String wasTheKick = null;
|
||||||
|
Collection<ProxiedPlayer> playerz = BungeeCord.getInstance().getPlayers();
|
||||||
|
for(ProxiedPlayer pp : playerz) {
|
||||||
|
if(pp.getName().equalsIgnoreCase(p)) {
|
||||||
|
wasTheKick = pp.getName();
|
||||||
|
pp.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: " + reason);
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.WHITE + "Kicked: " + pp.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(BanList.ban(p, reason)) {
|
||||||
|
if(wasTheKick == null) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Warning! '" + ChatColor.WHITE + p + ChatColor.YELLOW + "' is not currently on this server");
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Username '" + ChatColor.WHITE + (wasTheKick == null ? p : wasTheKick) + ChatColor.GREEN + "' was added to the ban list");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Username '" + ChatColor.WHITE + p + ChatColor.RED + "' is already banned");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To ban a player, use: " + ChatColor.WHITE + "/" + (replaceBukkit?"":"eag-") + "ban <player> [reason]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList.IPBan;
|
||||||
|
|
||||||
|
public class CommandGlobalBanIP extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalBanIP(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "ban-ip" : "eag-ban-ip", "bungeecord.command.eag.banip", (replaceBukkit ? new String[] {"eag-ban-ip", "banip", "e-ban-ip", "gban-ip"} :
|
||||||
|
new String[] {"gban-ip", "e-ban-ip", "gbanip", "e-banip"}) );
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
String w = (String) p0.getAttachment().get("banIPWaitingToAdd");
|
||||||
|
if(w != null) {
|
||||||
|
List<ProxiedPlayer> lst = (List<ProxiedPlayer>)p0.getAttachment().get("banIPWaitingToKick");
|
||||||
|
if(p1.length != 1 || (!p1[0].equalsIgnoreCase("confirm") && !p1[0].equalsIgnoreCase("cancel"))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-ip" : "/eag-ban-ip") + " confirm" + ChatColor.RED + " to add IP " + ChatColor.WHITE + w +
|
||||||
|
ChatColor.RED + " and ban " + ChatColor.WHITE + lst.size() + ChatColor.RED + " players");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-ip" : "/eag-ban-ip") + " cancel" + ChatColor.RED + " to cancel this operation");
|
||||||
|
}else {
|
||||||
|
if(p1[0].equalsIgnoreCase("confirm")) {
|
||||||
|
try {
|
||||||
|
if(BanList.banIP(w)) {
|
||||||
|
for(ProxiedPlayer pp : lst) {
|
||||||
|
pp.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: banned by IP");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Kicked: " + ChatColor.WHITE + pp.getName());
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Added IP '" + ChatColor.WHITE + w + ChatColor.GREEN + "' to the ban list");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "IP '" + ChatColor.WHITE + w + ChatColor.RED + "' is already on the ban list");
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "ERROR: address '" + ChatColor.WHITE + w + ChatColor.RED + "' is suddenly invalid for some reason");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Canceled ban");
|
||||||
|
}
|
||||||
|
p0.getAttachment().remove("banIPWaitingToAdd");
|
||||||
|
p0.getAttachment().remove("banIPWaitingToKick");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(p1.length != 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "How to use: " + ChatColor.WHITE + (replaceBukkit ? "/ban-ip" : "/eag-ban-ip") + " <addr|player>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean isPlayer = false;
|
||||||
|
IPBan p = null;
|
||||||
|
try {
|
||||||
|
p = BanList.constructIpBan(p1[0]);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
for(ProxiedPlayer pp : BungeeCord.getInstance().getPlayers()) {
|
||||||
|
if(pp.getName().equalsIgnoreCase(p1[0])) {
|
||||||
|
Object addr = pp.getAttachment().get("remoteAddr");
|
||||||
|
if(addr != null) {
|
||||||
|
String newAddr = ((InetAddress)addr).getHostAddress();
|
||||||
|
isPlayer = true;
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Player '" + ChatColor.WHITE + p1[0] + ChatColor.GREEN + "' has IP " + ChatColor.WHITE + newAddr);
|
||||||
|
p1[0] = newAddr;
|
||||||
|
try {
|
||||||
|
p = BanList.constructIpBan(p1[0]);
|
||||||
|
}catch(UnknownHostException ex) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Address '" + ChatColor.WHITE + p1[0] + "' is suddenly invalid: " + ChatColor.WHITE + p1[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!isPlayer) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Player '" + ChatColor.WHITE + p1[0] + "' is not on this server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean blocked = false;
|
||||||
|
for(IPBan b : BanList.blockedBans) {
|
||||||
|
if(b.checkBan(p.getBaseAddress()) || p.checkBan(b.getBaseAddress())) {
|
||||||
|
blocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(blocked) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Cannot ban '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "', it will ban local addresses that may break your game");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To force, add to the " + ChatColor.WHITE + "[IPs]" + ChatColor.RED + " section of " + ChatColor.WHITE + "bans.txt" + ChatColor.RED + " in your bungee directory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean isSenderGonnaGetKicked = false;
|
||||||
|
List<ProxiedPlayer> usersThatAreGonnaBeKicked = new ArrayList();
|
||||||
|
for(ProxiedPlayer pp : BungeeCord.getInstance().getPlayers()) {
|
||||||
|
Object addr = pp.getAttachment().get("remoteAddr");
|
||||||
|
if(addr != null) {
|
||||||
|
InetAddress addrr = (InetAddress)addr;
|
||||||
|
if(p.checkBan(addrr)) {
|
||||||
|
usersThatAreGonnaBeKicked.add(pp);
|
||||||
|
if(pp.getName().equalsIgnoreCase(p0.getName())) {
|
||||||
|
isSenderGonnaGetKicked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isSenderGonnaGetKicked) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "banning address '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' will ban you off of your own server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(usersThatAreGonnaBeKicked.size() > 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "WARNING: banning address '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is gonna ban " +
|
||||||
|
ChatColor.WHITE + usersThatAreGonnaBeKicked.size() + ChatColor.RED + " players off of your server");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-ip" : "/eag-ban-ip") + " confirm" + ChatColor.RED + " to continue, or type " +
|
||||||
|
ChatColor.WHITE + (replaceBukkit ? "/ban-ip" : "/eag-ban-ip") + " cancel" + ChatColor.RED + " to cancel");
|
||||||
|
p0.getAttachment().put("banIPWaitingToKick", usersThatAreGonnaBeKicked);
|
||||||
|
p0.getAttachment().put("banIPWaitingToAdd", p1[0]);
|
||||||
|
}else {
|
||||||
|
try {
|
||||||
|
if(BanList.banIP(p1[0])) {
|
||||||
|
if(usersThatAreGonnaBeKicked.size() > 0) {
|
||||||
|
usersThatAreGonnaBeKicked.get(0).disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: banned by IP");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Kicked: " + ChatColor.WHITE + usersThatAreGonnaBeKicked.get(0).getName());
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Added IP '" + ChatColor.WHITE + p1[0] + ChatColor.GREEN + "' to the ban list");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "IP '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is already on the ban list");
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "ERROR: address '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is suddenly invalid for some reason");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
|
||||||
|
public class CommandGlobalBanRegex extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalBanRegex(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "ban-regex" : "eag-ban-regex", "bungeecord.command.eag.banregex", replaceBukkit ? new String[] { "eag-ban-regex", "e-ban-regex",
|
||||||
|
"gban-regex", "eag-banregex", "e-banregex", "gbanregex", "banregex" } : new String[] { "e-ban-regex", "gban-regex",
|
||||||
|
"eag-banregex", "e-banregex", "gbanregex" });
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
String w = (String) p0.getAttachment().get("banRegexWaitingToAdd");
|
||||||
|
if(w != null) {
|
||||||
|
List<ProxiedPlayer> lst = (List<ProxiedPlayer>)p0.getAttachment().get("banRegexWaitingToKick");
|
||||||
|
if(p1.length != 1 || (!p1[0].equalsIgnoreCase("confirm") && !p1[0].equalsIgnoreCase("cancel"))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-regex" : "/eag-ban-regex") + " confirm" + ChatColor.RED + " to add regex " + ChatColor.WHITE + w +
|
||||||
|
ChatColor.RED + " and ban " + ChatColor.WHITE + lst.size() + ChatColor.RED + " players");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-regex" : "/eag-ban-regex") + " cancel" + ChatColor.RED + " to cancel this operation");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Note: all usernames are converted to lowercase before being matched");
|
||||||
|
}else {
|
||||||
|
if(p1[0].equalsIgnoreCase("confirm")) {
|
||||||
|
if(BanList.banRegex(w)) {
|
||||||
|
for(ProxiedPlayer pp : lst) {
|
||||||
|
pp.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: banned by regex");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Kicked: " + ChatColor.WHITE + pp.getName());
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Added regex '" + ChatColor.WHITE + w + ChatColor.GREEN + "' to the ban list");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Regex '" + ChatColor.WHITE + w + ChatColor.RED + "' is already banned");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Canceled ban");
|
||||||
|
}
|
||||||
|
p0.getAttachment().remove("banRegexWaitingToAdd");
|
||||||
|
p0.getAttachment().remove("banRegexWaitingToKick");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(p1.length != 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "How to use: " + ChatColor.WHITE + (replaceBukkit ? "/ban-regex" : "/eag-ban-regex") + " <pattern>");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Note: all usernames are converted to lowercase before being matched");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Pattern p;
|
||||||
|
try {
|
||||||
|
p = Pattern.compile(p1[0]);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Regex syntax error: " + t.getMessage());
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Note: all usernames are converted to lowercase before being matched");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean isSenderGonnaGetKicked = false;
|
||||||
|
List<ProxiedPlayer> usersThatAreGonnaBeKicked = new ArrayList();
|
||||||
|
for(ProxiedPlayer pp : BungeeCord.getInstance().getPlayers()) {
|
||||||
|
String n = pp.getName().toLowerCase();
|
||||||
|
if(p.matcher(n).matches()) {
|
||||||
|
usersThatAreGonnaBeKicked.add(pp);
|
||||||
|
if(n.equalsIgnoreCase(p0.getName())) {
|
||||||
|
isSenderGonnaGetKicked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isSenderGonnaGetKicked) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "banning regex '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is gonna ban your own username");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Note: all usernames are converted to lowercase before being matched");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(usersThatAreGonnaBeKicked.size() > 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "WARNING: banning regex '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is gonna ban " +
|
||||||
|
ChatColor.WHITE + usersThatAreGonnaBeKicked.size() + ChatColor.RED + " players off of your server");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-regex" : "/eag-ban-regex") + " confirm" + ChatColor.RED + " to continue, or type " +
|
||||||
|
ChatColor.WHITE + "/eag-ban-regex cancel" + ChatColor.RED + " to cancel");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Note: all usernames are converted to lowercase before being matched");
|
||||||
|
p0.getAttachment().put("banRegexWaitingToKick", usersThatAreGonnaBeKicked);
|
||||||
|
p0.getAttachment().put("banRegexWaitingToAdd", p1[0]);
|
||||||
|
}else {
|
||||||
|
if(BanList.banRegex(p1[0])) {
|
||||||
|
if(usersThatAreGonnaBeKicked.size() > 0) {
|
||||||
|
usersThatAreGonnaBeKicked.get(0).disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: banned by regex");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Kicked: " + ChatColor.WHITE + usersThatAreGonnaBeKicked.get(0).getName());
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Added regex '" + ChatColor.WHITE + p1[0] + ChatColor.GREEN + "' to the ban list");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Note: all usernames are converted to lowercase before being matched");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Regex '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is already banned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
|
||||||
|
public class CommandGlobalBanReload extends Command {
|
||||||
|
|
||||||
|
public CommandGlobalBanReload(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "reloadban" : "eag-reloadban", "bungeecord.command.eag.reloadban", replaceBukkit ? new String[] { "eag-reloadban", "banreload", "eag-banreload", "e-reloadban",
|
||||||
|
"e-banreload", "gbanreload", "greloadban"} : new String[] { "eag-banreload", "e-reloadban", "e-banreload", "gbanreload", "greloadban"});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
BanList.maybeReloadBans(p0);
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.WHITE + "Ban list reloaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
|
||||||
|
public class CommandGlobalBanWildcard extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalBanWildcard(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "ban-wildcard" : "eag-ban-wildcard", "bungeecord.command.eag.banwildcard", replaceBukkit ? new String[] { "eag-ban-wildcard", "e-ban-wildcard", "gban-wildcard",
|
||||||
|
"banwildcard", "eag-banwildcard", "banwildcard"} : new String[] { "e-ban-wildcard", "gban-wildcard", "eag-banwildcard"});
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
String w = (String) p0.getAttachment().get("banWildcardWaitingToAdd");
|
||||||
|
if(w != null) {
|
||||||
|
List<ProxiedPlayer> lst = (List<ProxiedPlayer>)p0.getAttachment().get("banWildcardWaitingToKick");
|
||||||
|
if(p1.length != 1 || (!p1[0].equalsIgnoreCase("confirm") && !p1[0].equalsIgnoreCase("cancel"))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-wildcard" : "/eag-ban-wildcard") + " confirm" + ChatColor.RED + " to add wildcard " + ChatColor.WHITE + w +
|
||||||
|
ChatColor.RED + " and ban " + ChatColor.WHITE + lst.size() + ChatColor.RED + " players");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-wildcard" : "/eag-ban-wildcard") + " cancel" + ChatColor.RED + " to cancel this operation");
|
||||||
|
}else {
|
||||||
|
if(p1[0].equalsIgnoreCase("confirm")) {
|
||||||
|
if(BanList.banWildcard(w)) {
|
||||||
|
for(ProxiedPlayer pp : lst) {
|
||||||
|
pp.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: banned by wildcard");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Kicked: " + ChatColor.WHITE + pp.getName());
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Added wildcard '" + ChatColor.WHITE + w + ChatColor.GREEN + "' to the ban list");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Wildcard '" + ChatColor.WHITE + w + ChatColor.RED + "' is already banned");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Canceled ban");
|
||||||
|
}
|
||||||
|
p0.getAttachment().remove("banWildcardWaitingToAdd");
|
||||||
|
p0.getAttachment().remove("banWildcardWaitingToKick");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(p1.length != 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "How to use: " + ChatColor.WHITE + (replaceBukkit ? "/ban-wildcard" : "/eag-ban-wildcard") + " <pattern>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p1[0] = p1[0].toLowerCase();
|
||||||
|
String s = p1[0];
|
||||||
|
boolean startStar = s.startsWith("*");
|
||||||
|
if(startStar) {
|
||||||
|
s = s.substring(1);
|
||||||
|
}
|
||||||
|
boolean endStar = s.endsWith("*");
|
||||||
|
if(endStar) {
|
||||||
|
s = s.substring(0, s.length() - 1);
|
||||||
|
}
|
||||||
|
if(!startStar && !endStar) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "'" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is not a wildcard, try '"
|
||||||
|
+ ChatColor.WHITE + "*" + p1[0] + ChatColor.RED + "' or '" + ChatColor.WHITE + p1[0] + "*" + ChatColor.RED + "' or '" + ChatColor.WHITE
|
||||||
|
+ "*" + p1[0] + "*" + ChatColor.RED + "' instead");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean isSenderGonnaGetKicked = false;
|
||||||
|
List<ProxiedPlayer> usersThatAreGonnaBeKicked = new ArrayList();
|
||||||
|
for(ProxiedPlayer pp : BungeeCord.getInstance().getPlayers()) {
|
||||||
|
String n = pp.getName().toLowerCase();
|
||||||
|
if(startStar && endStar) {
|
||||||
|
if(n.contains(s)) {
|
||||||
|
usersThatAreGonnaBeKicked.add(pp);
|
||||||
|
if(pp.getName().equalsIgnoreCase(p0.getName())) {
|
||||||
|
isSenderGonnaGetKicked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(startStar) {
|
||||||
|
if(n.endsWith(s)) {
|
||||||
|
usersThatAreGonnaBeKicked.add(pp);
|
||||||
|
if(pp.getName().equalsIgnoreCase(p0.getName())) {
|
||||||
|
isSenderGonnaGetKicked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(endStar) {
|
||||||
|
if(n.startsWith(s)) {
|
||||||
|
usersThatAreGonnaBeKicked.add(pp);
|
||||||
|
if(pp.getName().equalsIgnoreCase(p0.getName())) {
|
||||||
|
isSenderGonnaGetKicked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isSenderGonnaGetKicked) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "banning wildcard '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is gonna ban your own username");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(usersThatAreGonnaBeKicked.size() > 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "WARNING: banning wildcard '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is gonna ban " +
|
||||||
|
ChatColor.WHITE + usersThatAreGonnaBeKicked.size() + ChatColor.RED + " players off of your server");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Type " + ChatColor.WHITE + (replaceBukkit ? "/ban-wildcard" : "/eag-ban-wildcard") + " confirm" + ChatColor.RED + " to continue, or type " +
|
||||||
|
ChatColor.WHITE + (replaceBukkit ? "/ban-wildcard" : "/eag-ban-wildcard") + " cancel" + ChatColor.RED + " to cancel");
|
||||||
|
p0.getAttachment().put("banWildcardWaitingToKick", usersThatAreGonnaBeKicked);
|
||||||
|
p0.getAttachment().put("banWildcardWaitingToAdd", p1[0]);
|
||||||
|
}else {
|
||||||
|
if(BanList.banWildcard(p1[0])) {
|
||||||
|
if(usersThatAreGonnaBeKicked.size() > 0) {
|
||||||
|
usersThatAreGonnaBeKicked.get(0).disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: banned by wildcard");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Kicked: " + ChatColor.WHITE + usersThatAreGonnaBeKicked.get(0).getName());
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Added wildcard '" + ChatColor.WHITE + p1[0] + ChatColor.GREEN + "' to the ban list");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Wildcard '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is already banned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList.BanCheck;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList.BanState;
|
||||||
|
|
||||||
|
public class CommandGlobalCheckBan extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalCheckBan(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "banned" : "eag-bannned", "bungeecord.command.eag.banned", replaceBukkit ? new String[] { "eag-banned", "isbanned", "e-banned", "gbanned", "eag-isbanned", "e-isbanned", "gisbanned" } :
|
||||||
|
new String[] { "e-banned", "gbanned", "eag-isbanned", "e-isbanned", "gisbanned" });
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
if(p1.length != 1) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To check if a player or IP is banned, use: " + ChatColor.WHITE + (replaceBukkit ? "/banned" : "/eag-banned") + " <username|ip>");
|
||||||
|
}else {
|
||||||
|
BanCheck bc = BanList.checkBanned(p1[0]);
|
||||||
|
if(!bc.isBanned()) {
|
||||||
|
try {
|
||||||
|
InetAddress addr = InetAddress.getByName(p1[0]);
|
||||||
|
bc = BanList.checkIpBanned(addr);
|
||||||
|
if(bc.isBanned()) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "IP address '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is banned by: "
|
||||||
|
+ "'" + ChatColor.WHITE + bc.match + ChatColor.RED + "' " + ChatColor.YELLOW + "(" + bc.string + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}catch(Throwable t) {
|
||||||
|
// no
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Player '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' has not been banned");
|
||||||
|
}else {
|
||||||
|
if(bc.reason == BanState.USER_BANNED) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Player '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is banned by username, reason: "
|
||||||
|
+ ChatColor.YELLOW + "\"" + bc.string + "\"");
|
||||||
|
}else if(bc.reason == BanState.WILDCARD_BANNED) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Player '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is banned by wildcard: "
|
||||||
|
+ ChatColor.WHITE + "\"" + bc.match + "\"");
|
||||||
|
}else if(bc.reason == BanState.REGEX_BANNED) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Player '" + ChatColor.WHITE + p1[0] + ChatColor.RED + "' is banned by regex: "
|
||||||
|
+ ChatColor.WHITE + "\"" + bc.match + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
|
||||||
|
public class CommandGlobalListBan extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalListBan(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "banlist" : "eag-banlist", "bungeecord.command.eag.banlist", replaceBukkit ? new String[] { "eag-banlist", "gbanlist", "e-banlist",
|
||||||
|
"gbanlist" } : new String[] { "gbanlist", "e-banlist" });
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
if(p1.length == 0 || (p1.length == 1 && (p1[0].equalsIgnoreCase("user") || p1[0].equalsIgnoreCase("username")
|
||||||
|
|| p1[0].equalsIgnoreCase("users") || p1[0].equalsIgnoreCase("usernames")))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Players banned by username: " + ChatColor.WHITE + BanList.listAllBans());
|
||||||
|
return;
|
||||||
|
}else if(p1.length == 1) {
|
||||||
|
if(p1[0].equalsIgnoreCase("regex") || p1[0].equalsIgnoreCase("regexes")) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Regex ban list: " + ChatColor.WHITE + BanList.listAllRegexBans());
|
||||||
|
return;
|
||||||
|
}else if(p1[0].equalsIgnoreCase("wildcard") || p1[0].equalsIgnoreCase("wildcards")) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Wildcard ban list: " + ChatColor.WHITE + BanList.listAllWildcardBans());
|
||||||
|
return;
|
||||||
|
}else if(p1[0].equalsIgnoreCase("ip") || p1[0].equalsIgnoreCase("ips")) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To list IP bans, use: " + ChatColor.WHITE + (replaceBukkit ? "/banlist" : "/eag-banlist") + " ip <addr|netmask> [v4|v6]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}else if(p1.length > 1 && p1.length <= 3 && (p1[0].equalsIgnoreCase("ip") || p1[0].equalsIgnoreCase("ips"))) {
|
||||||
|
int addrOrNetmask = 0;
|
||||||
|
if(p1[1].equalsIgnoreCase("addr") || p1[1].equalsIgnoreCase("addrs")) {
|
||||||
|
addrOrNetmask = 1;
|
||||||
|
}else if(p1[1].equalsIgnoreCase("netmask") || p1[1].equalsIgnoreCase("netmasks")) {
|
||||||
|
addrOrNetmask = 2;
|
||||||
|
}
|
||||||
|
if(addrOrNetmask > 0) {
|
||||||
|
boolean yes = false;
|
||||||
|
if(p1.length == 2 || (p1.length == 3 && (p1[2].equalsIgnoreCase("v4") || p1[2].equals("4")))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "IPv4 " + (addrOrNetmask == 2 ? "netmask" : "address") + " ban list: " + ChatColor.WHITE + BanList.listAllIPBans(false, addrOrNetmask == 2));
|
||||||
|
yes = true;
|
||||||
|
}
|
||||||
|
if(p1.length == 2 || (p1.length == 3 && (p1[2].equalsIgnoreCase("v6") || p1[2].equals("6")))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "IPv6 " + (addrOrNetmask == 2 ? "netmask" : "address") + " ban list: " + ChatColor.WHITE + BanList.listAllIPBans(true, addrOrNetmask == 2));
|
||||||
|
yes = true;
|
||||||
|
}
|
||||||
|
if(yes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To list IP bans, use: " + ChatColor.WHITE + (replaceBukkit ? "/banlist" : "/eag-banlist") + " ip <addr|netmask> [v4|v6]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To list all user bans, use: " + ChatColor.WHITE + (replaceBukkit ? "/banlist" : "/eag-banlist"));
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To list ips, regexes, and wildcards, use: " + ChatColor.WHITE + (replaceBukkit ? "/banlist" : "/eag-banlist") + " <ip|regex|wildcard>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
|
||||||
|
public class CommandGlobalUnban extends Command {
|
||||||
|
|
||||||
|
private final boolean replaceBukkit;
|
||||||
|
|
||||||
|
public CommandGlobalUnban(boolean replaceBukkit) {
|
||||||
|
super(replaceBukkit ? "unban" : "eag-unban", "bungeecord.command.eag.unban", replaceBukkit ? new String[] {"eag-unban", "e-unban", "gunban"} :new String[] {"e-unban", "gunban"});
|
||||||
|
this.replaceBukkit = replaceBukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender p0, String[] p1) {
|
||||||
|
if(p1.length != 2 || (!p1[0].equalsIgnoreCase("user") && !p1[0].equalsIgnoreCase("username") && !p1[0].equalsIgnoreCase("player")
|
||||||
|
&& !p1[0].equalsIgnoreCase("wildcard") && !p1[0].equalsIgnoreCase("regex") && !p1[0].equalsIgnoreCase("ip"))) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To unban a player, use: " + ChatColor.WHITE + "/" + (replaceBukkit?"":"eag-") + "unban user <player>");
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "To unban an ip/wildcard/regex, use: " + ChatColor.WHITE + "/" + (replaceBukkit?"":"eag-") + "unban <ip|wildcard|regex> <value>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(p1[0].equalsIgnoreCase("user") || p1[0].equalsIgnoreCase("username") || p1[0].equalsIgnoreCase("player")) {
|
||||||
|
if(BanList.unban(p1[1])) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "User '" + ChatColor.WHITE + p1[1] + ChatColor.GREEN + "' was unbanned");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "User '" + ChatColor.WHITE + p1[1] + ChatColor.RED + "' is not banned");
|
||||||
|
}
|
||||||
|
}else if(p1[0].equalsIgnoreCase("ip")) {
|
||||||
|
try {
|
||||||
|
if(BanList.unbanIP(p1[1])) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "IP '" + ChatColor.WHITE + p1[1] + ChatColor.GREEN + "' was unbanned");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "IP '" + ChatColor.WHITE + p1[1] + ChatColor.RED + "' is not banned");
|
||||||
|
}
|
||||||
|
}catch(Throwable t) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "IP address '" + ChatColor.WHITE + p1[1] + ChatColor.RED + "' is invalid: " + t.getMessage());
|
||||||
|
}
|
||||||
|
}else if(p1[0].equalsIgnoreCase("wildcard")) {
|
||||||
|
if(BanList.unbanWildcard(p1[1])) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Wildcard '" + ChatColor.WHITE + p1[1] + ChatColor.GREEN + "' was unbanned");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Wildcard '" + ChatColor.WHITE + p1[1] + ChatColor.RED + "' is not banned");
|
||||||
|
}
|
||||||
|
}else if(p1[0].equalsIgnoreCase("regex")) {
|
||||||
|
if(BanList.unbanRegex(p1[1])) {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.GREEN + "Regex '" + ChatColor.WHITE + p1[1] + ChatColor.GREEN + "' was unbanned");
|
||||||
|
}else {
|
||||||
|
p0.sendMessage(BanList.banChatMessagePrefix + ChatColor.RED + "Regex '" + ChatColor.WHITE + p1[1] + ChatColor.RED + "' is not banned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,9 @@ package net.md_5.bungee.command;
|
||||||
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
@ -24,8 +27,13 @@ public class CommandIP extends Command {
|
||||||
final ProxiedPlayer user = ProxyServer.getInstance().getPlayer(args[0]);
|
final ProxiedPlayer user = ProxyServer.getInstance().getPlayer(args[0]);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
sender.sendMessage(ChatColor.RED + "That user is not online");
|
sender.sendMessage(ChatColor.RED + "That user is not online");
|
||||||
|
} else {
|
||||||
|
Object o = user.getAttachment().get("remoteAddr");
|
||||||
|
if(o != null) {
|
||||||
|
sender.sendMessage(ChatColor.BLUE + "IP of " + args[0] + " is " + (InetAddress)o);
|
||||||
}else {
|
}else {
|
||||||
sender.sendMessage(ChatColor.BLUE + "IP of " + args[0] + " is " + user.getAddress());
|
sender.sendMessage(ChatColor.BLUE + "IP of " + args[0] + " is " + user.getAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
|
|
||||||
package net.md_5.bungee.command;
|
package net.md_5.bungee.command;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
|
||||||
public class ConsoleCommandSender implements CommandSender {
|
public class ConsoleCommandSender implements CommandSender {
|
||||||
private static final ConsoleCommandSender instance;
|
private static final ConsoleCommandSender instance;
|
||||||
|
private static final Map<String, Object> attachment = new WeakHashMap();
|
||||||
|
|
||||||
private ConsoleCommandSender() {
|
private ConsoleCommandSender() {
|
||||||
}
|
}
|
||||||
|
@ -65,4 +67,9 @@ public class ConsoleCommandSender implements CommandSender {
|
||||||
static {
|
static {
|
||||||
instance = new ConsoleCommandSender();
|
instance = new ConsoleCommandSender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getAttachment() {
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.google.common.base.Preconditions;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.eaglercraft.EaglercraftBungee;
|
||||||
import gnu.trove.map.TMap;
|
import gnu.trove.map.TMap;
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -24,6 +25,7 @@ public class Configuration {
|
||||||
private AuthServiceInfo authInfo;
|
private AuthServiceInfo authInfo;
|
||||||
private boolean onlineMode;
|
private boolean onlineMode;
|
||||||
private int playerLimit;
|
private int playerLimit;
|
||||||
|
private String name;
|
||||||
|
|
||||||
public Configuration() {
|
public Configuration() {
|
||||||
this.timeout = 30000;
|
this.timeout = 30000;
|
||||||
|
@ -41,6 +43,7 @@ public class Configuration {
|
||||||
this.authInfo = adapter.getAuthSettings();
|
this.authInfo = adapter.getAuthSettings();
|
||||||
this.onlineMode = false;
|
this.onlineMode = false;
|
||||||
this.playerLimit = adapter.getInt("player_limit", this.playerLimit);
|
this.playerLimit = adapter.getInt("player_limit", this.playerLimit);
|
||||||
|
this.name = adapter.getString("server_name", EaglercraftBungee.brand + " Server");
|
||||||
Preconditions.checkArgument(this.listeners != null && !this.listeners.isEmpty(), (Object) "No listeners defined.");
|
Preconditions.checkArgument(this.listeners != null && !this.listeners.isEmpty(), (Object) "No listeners defined.");
|
||||||
final Map<String, ServerInfo> newServers = adapter.getServers();
|
final Map<String, ServerInfo> newServers = adapter.getServers();
|
||||||
Preconditions.checkArgument(newServers != null && !newServers.isEmpty(), (Object) "No servers defined");
|
Preconditions.checkArgument(newServers != null && !newServers.isEmpty(), (Object) "No servers defined");
|
||||||
|
@ -88,4 +91,8 @@ public class Configuration {
|
||||||
public AuthServiceInfo getAuthInfo() {
|
public AuthServiceInfo getAuthInfo() {
|
||||||
return authInfo;
|
return authInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getServerName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,18 +67,11 @@ public class YamlConfig implements ConfigurationAdapter {
|
||||||
final Map<String, Object> permissions = this.get("permissions", new HashMap<String, Object>());
|
final Map<String, Object> permissions = this.get("permissions", new HashMap<String, Object>());
|
||||||
if (permissions.isEmpty()) {
|
if (permissions.isEmpty()) {
|
||||||
permissions.put("default", Arrays.asList("bungeecord.command.server", "bungeecord.command.list"));
|
permissions.put("default", Arrays.asList("bungeecord.command.server", "bungeecord.command.list"));
|
||||||
permissions.put("admin", Arrays.asList("bungeecord.command.alert", "bungeecord.command.end", "bungeecord.command.ip", "bungeecord.command.reload"));
|
permissions.put("admin", Arrays.asList("bungeecord.command.alert", "bungeecord.command.end", "bungeecord.command.ip", "bungeecord.command.reload",
|
||||||
|
"bungeecord.command.eag.ban", "bungeecord.command.eag.banwildcard", "bungeecord.command.eag.banip", "bungeecord.command.eag.banregex",
|
||||||
|
"bungeecord.command.eag.reloadban", "bungeecord.command.eag.banned", "bungeecord.command.eag.banlist", "bungeecord.command.eag.unban"));
|
||||||
}
|
}
|
||||||
this.get("groups", new HashMap<String, Object>());
|
this.get("groups", new HashMap<String, Object>());
|
||||||
/*
|
|
||||||
final Map<String, Object> auth = this.get("authservice", new HashMap<String, Object>());
|
|
||||||
if(auth.isEmpty()) {
|
|
||||||
auth.put("enabled", false);
|
|
||||||
auth.put("limbo", "lobby");
|
|
||||||
auth.put("authfile", "passwords.yml");
|
|
||||||
auth.put("timeout", 30);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T get(final String path, final T def) {
|
private <T> T get(final String path, final T def) {
|
||||||
|
@ -159,6 +152,7 @@ public class YamlConfig implements ConfigurationAdapter {
|
||||||
final String fallbackServer = this.get("fallback_server", defaultServer, val);
|
final String fallbackServer = this.get("fallback_server", defaultServer, val);
|
||||||
final boolean forceDefault = this.get("force_default_server", true, val);
|
final boolean forceDefault = this.get("force_default_server", true, val);
|
||||||
final boolean websocket = this.get("websocket", true, val);
|
final boolean websocket = this.get("websocket", true, val);
|
||||||
|
final boolean forwardIp = this.get("forward_ip", false, val);
|
||||||
final String host = this.get("host", "0.0.0.0:25565", val);
|
final String host = this.get("host", "0.0.0.0:25565", val);
|
||||||
final int tabListSize = this.get("tab_size", 60, val);
|
final int tabListSize = this.get("tab_size", 60, val);
|
||||||
final InetSocketAddress address = Util.getAddr(host);
|
final InetSocketAddress address = Util.getAddr(host);
|
||||||
|
@ -167,11 +161,12 @@ public class YamlConfig implements ConfigurationAdapter {
|
||||||
final int textureSize = this.get("texture_size", 16, val);
|
final int textureSize = this.get("texture_size", 16, val);
|
||||||
final TexturePackInfo texture = (textureURL == null) ? null : new TexturePackInfo(textureURL, textureSize);
|
final TexturePackInfo texture = (textureURL == null) ? null : new TexturePackInfo(textureURL, textureSize);
|
||||||
final String tabListName = this.get("tab_list", "GLOBAL_PING", val);
|
final String tabListName = this.get("tab_list", "GLOBAL_PING", val);
|
||||||
|
final String serverIcon = this.get("server_icon", "server-icon.png", val);
|
||||||
DefaultTabList value = DefaultTabList.valueOf(tabListName.toUpperCase());
|
DefaultTabList value = DefaultTabList.valueOf(tabListName.toUpperCase());
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = DefaultTabList.GLOBAL_PING;
|
value = DefaultTabList.GLOBAL_PING;
|
||||||
}
|
}
|
||||||
final ListenerInfo info = new ListenerInfo(address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, websocket, forced, texture, value.clazz);
|
final ListenerInfo info = new ListenerInfo(address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, websocket, forwardIp, forced, texture, value.clazz, serverIcon);
|
||||||
ret.add(info);
|
ret.add(info);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -6,6 +6,7 @@ package net.md_5.bungee.connection;
|
||||||
|
|
||||||
import java.beans.ConstructorProperties;
|
import java.beans.ConstructorProperties;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
@ -37,6 +38,9 @@ import net.md_5.bungee.protocol.Forge;
|
||||||
import net.md_5.bungee.netty.PacketDecoder;
|
import net.md_5.bungee.netty.PacketDecoder;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList;
|
||||||
|
import net.md_5.bungee.eaglercraft.WebSocketProxy;
|
||||||
|
import net.md_5.bungee.eaglercraft.BanList.BanCheck;
|
||||||
import net.md_5.bungee.api.ServerPing;
|
import net.md_5.bungee.api.ServerPing;
|
||||||
import net.md_5.bungee.protocol.packet.PacketFEPing;
|
import net.md_5.bungee.protocol.packet.PacketFEPing;
|
||||||
import net.md_5.bungee.Util;
|
import net.md_5.bungee.Util;
|
||||||
|
@ -112,8 +116,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection {
|
||||||
if (handshake.getProcolVersion() == 69) {
|
if (handshake.getProcolVersion() == 69) {
|
||||||
skipEncryption = true;
|
skipEncryption = true;
|
||||||
this.handshake.swapProtocol((byte) 61);
|
this.handshake.swapProtocol((byte) 61);
|
||||||
|
}else if(handshake.getProcolVersion() == 71) {
|
||||||
|
this.disconnect("this server does not support microsoft accounts");
|
||||||
|
return;
|
||||||
}else if(handshake.getProcolVersion() != 61) {
|
}else if(handshake.getProcolVersion() != 61) {
|
||||||
this.disconnect("minecraft 1.5.2 required for eaglercraft backdoor access");
|
this.disconnect("minecraft 1.5.2 required for eaglercraft backdoor access");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
String un = handshake.getUsername();
|
String un = handshake.getUsername();
|
||||||
if (un.length() < 3) {
|
if (un.length() < 3) {
|
||||||
|
@ -128,6 +136,37 @@ public class InitialHandler extends PacketHandler implements PendingConnection {
|
||||||
this.disconnect("Go fuck yourself");
|
this.disconnect("Go fuck yourself");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
InetAddress sc = WebSocketProxy.localToRemote.get(this.ch.getHandle().remoteAddress());
|
||||||
|
if(sc == null) {
|
||||||
|
System.out.println("WARNING: player '" + un + "' doesn't have a websocket IP, remote address: " + this.ch.getHandle().remoteAddress().toString());
|
||||||
|
}else {
|
||||||
|
BanCheck bc = BanList.checkIpBanned(sc);
|
||||||
|
if(bc.isBanned()) {
|
||||||
|
System.err.println("Player '" + un + "' [" + sc.toString() + "] is banned by IP: " + bc.match + " (" + bc.string + ")");
|
||||||
|
this.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: " + bc.string);
|
||||||
|
return;
|
||||||
|
}else {
|
||||||
|
System.out.println("Player '" + un + "' [" + sc.toString() + "] has remote websocket IP: " + sc.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BanCheck bc = BanList.checkBanned(un);
|
||||||
|
if(bc.isBanned()) {
|
||||||
|
switch(bc.reason) {
|
||||||
|
case USER_BANNED:
|
||||||
|
System.err.println("Player '" + un + "' is banned by username, because '" + bc.string + "'");
|
||||||
|
break;
|
||||||
|
case WILDCARD_BANNED:
|
||||||
|
System.err.println("Player '" + un + "' is banned by wildcard: " + bc.match);
|
||||||
|
break;
|
||||||
|
case REGEX_BANNED:
|
||||||
|
System.err.println("Player '" + un + "' is banned by regex: " + bc.match);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.println("Player '" + un + "' is banned: " + bc.string);
|
||||||
|
}
|
||||||
|
this.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: " + bc.string);
|
||||||
|
return;
|
||||||
|
}
|
||||||
final int limit = BungeeCord.getInstance().config.getPlayerLimit();
|
final int limit = BungeeCord.getInstance().config.getPlayerLimit();
|
||||||
if (limit > 0 && this.bungee.getOnlineCount() > limit) {
|
if (limit > 0 && this.bungee.getOnlineCount() > limit) {
|
||||||
this.disconnect(this.bungee.getTranslation("proxy_full"));
|
this.disconnect(this.bungee.getTranslation("proxy_full"));
|
||||||
|
@ -194,6 +233,10 @@ public class InitialHandler extends PacketHandler implements PendingConnection {
|
||||||
public void handle(final PacketCDClientStatus clientStatus) throws Exception {
|
public void handle(final PacketCDClientStatus clientStatus) throws Exception {
|
||||||
Preconditions.checkState(this.thisState == State.LOGIN, (Object) "Not expecting LOGIN");
|
Preconditions.checkState(this.thisState == State.LOGIN, (Object) "Not expecting LOGIN");
|
||||||
final UserConnection userCon = new UserConnection(this.bungee, this.ch, this.getName(), this);
|
final UserConnection userCon = new UserConnection(this.bungee, this.ch, this.getName(), this);
|
||||||
|
InetAddress ins = WebSocketProxy.localToRemote.get(this.ch.getHandle().remoteAddress());
|
||||||
|
if(ins != null) {
|
||||||
|
userCon.getAttachment().put("remoteAddr", ins);
|
||||||
|
}
|
||||||
userCon.init();
|
userCon.init();
|
||||||
this.bungee.getPluginManager().callEvent(new PostLoginEvent(userCon));
|
this.bungee.getPluginManager().callEvent(new PostLoginEvent(userCon));
|
||||||
((HandlerBoss) this.ch.getHandle().pipeline().get((Class) HandlerBoss.class)).setHandler(new UpstreamBridge(this.bungee, userCon));
|
((HandlerBoss) this.ch.getHandle().pipeline().get((Class) HandlerBoss.class)).setHandler(new UpstreamBridge(this.bungee, userCon));
|
||||||
|
|
|
@ -0,0 +1,863 @@
|
||||||
|
package net.md_5.bungee.eaglercraft;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.eaglercraft.sun.net.util.IPAddressUtil;
|
||||||
|
|
||||||
|
public class BanList {
|
||||||
|
|
||||||
|
private static final Object banListMutex = new Object();
|
||||||
|
|
||||||
|
public static enum BanState {
|
||||||
|
NOT_BANNED, USER_BANNED, IP_BANNED, WILDCARD_BANNED, REGEX_BANNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BanCheck {
|
||||||
|
public final BanState reason;
|
||||||
|
public final String match;
|
||||||
|
public final String string;
|
||||||
|
private BanCheck(BanState reason, String match, String string) {
|
||||||
|
this.reason = reason;
|
||||||
|
this.match = match;
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
public boolean isBanned() {
|
||||||
|
return reason != BanState.NOT_BANNED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RegexBan {
|
||||||
|
public final String string;
|
||||||
|
public final Pattern compiled;
|
||||||
|
private RegexBan(String string, Pattern compiled) {
|
||||||
|
this.string = string;
|
||||||
|
this.compiled = compiled;
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
public int hashCode() {
|
||||||
|
return string.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface IPBan {
|
||||||
|
|
||||||
|
boolean checkBan(InetAddress addr);
|
||||||
|
InetAddress getBaseAddress();
|
||||||
|
boolean hasNetMask();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IPBan4 implements IPBan {
|
||||||
|
|
||||||
|
private final int addr;
|
||||||
|
private final InetAddress addrI;
|
||||||
|
private final int mask;
|
||||||
|
private final String string;
|
||||||
|
|
||||||
|
protected IPBan4(Inet4Address addr, String s, int mask) {
|
||||||
|
if(mask >= 32) {
|
||||||
|
this.mask = 0xFFFFFFFF;
|
||||||
|
}else {
|
||||||
|
this.mask = ~((1 << (32 - mask)) - 1);
|
||||||
|
}
|
||||||
|
this.string = s;
|
||||||
|
byte[] bits = addr.getAddress();
|
||||||
|
this.addr = this.mask & ((bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | (bits[3] & 0xFF));
|
||||||
|
this.addrI = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkBan(InetAddress addr4) {
|
||||||
|
if(addr4 instanceof Inet4Address) {
|
||||||
|
Inet4Address a = (Inet4Address)addr4;
|
||||||
|
byte[] bits = a.getAddress();
|
||||||
|
int addrBits = ((bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | (bits[3] & 0xFF));
|
||||||
|
return (mask & addrBits) == addr;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetAddress getBaseAddress() {
|
||||||
|
return addrI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return string.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o != null && o instanceof IPBan4 && ((IPBan4)o).addr == addr && ((IPBan4)o).mask == mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNetMask() {
|
||||||
|
return mask != 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IPBan6 implements IPBan {
|
||||||
|
|
||||||
|
private static final BigInteger mask128 = new BigInteger(1, new byte[] {
|
||||||
|
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
|
||||||
|
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
|
||||||
|
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
|
||||||
|
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
|
||||||
|
});
|
||||||
|
|
||||||
|
private final BigInteger addr;
|
||||||
|
private final InetAddress addrI;
|
||||||
|
private final BigInteger mask;
|
||||||
|
private final String string;
|
||||||
|
|
||||||
|
protected IPBan6(Inet6Address addr, String s, int mask) {
|
||||||
|
this.mask = BigInteger.valueOf(1l).shiftLeft(128 - mask).subtract(BigInteger.valueOf(1l)).xor(mask128);
|
||||||
|
this.string = s.toLowerCase();
|
||||||
|
this.addr = new BigInteger(1, addr.getAddress()).and(this.mask);
|
||||||
|
this.addrI = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkBan(InetAddress addr6) {
|
||||||
|
if(addr6 instanceof Inet6Address) {
|
||||||
|
Inet6Address a = (Inet6Address)addr6;
|
||||||
|
BigInteger addrBits = new BigInteger(1, a.getAddress()).and(this.mask);
|
||||||
|
return addr.equals(addrBits);
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InetAddress getBaseAddress() {
|
||||||
|
return addrI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return string.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o != null && o instanceof IPBan6 && ((IPBan6)o).addr.equals(addr) && ((IPBan6)o).mask.equals(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNetMask() {
|
||||||
|
return !mask.equals(mask128);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final File bansFile = new File("bans.txt");
|
||||||
|
|
||||||
|
public static final String banChatMessagePrefix = ChatColor.GOLD + "[BanList] ";
|
||||||
|
|
||||||
|
public static final Map<String,String> userBans = new HashMap();
|
||||||
|
public static final Set<IPBan> ipBans = new HashSet();
|
||||||
|
public static final Set<String> wildcardBans = new HashSet();
|
||||||
|
public static final Set<RegexBan> regexBans = new HashSet();
|
||||||
|
private static List<String> currentBanList = null;
|
||||||
|
|
||||||
|
public static final List<IPBan> blockedBans = new ArrayList();
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
blockedBans.add(constructIpBan("127.0.0.0/8"));
|
||||||
|
}catch(UnknownHostException e) {
|
||||||
|
System.err.println("Error: could not whitelist '127.0.0.0/8'");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
blockedBans.add(constructIpBan("10.0.0.0/8"));
|
||||||
|
}catch(UnknownHostException e) {
|
||||||
|
System.err.println("Error: could not whitelist '10.0.0.0/8'");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
blockedBans.add(constructIpBan("172.24.0.0/14"));
|
||||||
|
}catch(UnknownHostException e) {
|
||||||
|
System.err.println("Error: could not whitelist '172.24.0.0/14'");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
blockedBans.add(constructIpBan("192.168.0.0/16"));
|
||||||
|
}catch(UnknownHostException e) {
|
||||||
|
System.err.println("Error: could not whitelist '192.168.0.0/16'");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
blockedBans.add(constructIpBan("::1/128"));
|
||||||
|
}catch(UnknownHostException e) {
|
||||||
|
System.err.println("Error: could not whitelist '::1/128'");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long lastListTest = 0l;
|
||||||
|
private static long lastListLoad = 0l;
|
||||||
|
private static boolean fileIsBroken = false;
|
||||||
|
|
||||||
|
public static BanCheck checkIpBanned(InetAddress addr) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
for(IPBan b : ipBans) {
|
||||||
|
if(b.checkBan(addr)) {
|
||||||
|
return new BanCheck(BanState.IP_BANNED, b.toString(), b.hasNetMask() ? "Banned by Netmask" : "Banned by IP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new BanCheck(BanState.NOT_BANNED, "none", "not banned");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BanCheck checkBanned(String player) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
player = player.trim().toLowerCase();
|
||||||
|
String r = userBans.get(player);
|
||||||
|
if(r != null) {
|
||||||
|
if(r.length() <= 0) {
|
||||||
|
r = "The ban hammer has spoken";
|
||||||
|
}
|
||||||
|
return new BanCheck(BanState.USER_BANNED, player, r);
|
||||||
|
}
|
||||||
|
for(String ss : wildcardBans) {
|
||||||
|
String s = ss;
|
||||||
|
boolean startStar = s.startsWith("*");
|
||||||
|
if(startStar) {
|
||||||
|
s = s.substring(1);
|
||||||
|
}
|
||||||
|
boolean endStar = s.endsWith("*");
|
||||||
|
if(endStar) {
|
||||||
|
s = s.substring(0, s.length() - 1);
|
||||||
|
}
|
||||||
|
if(startStar && endStar) {
|
||||||
|
if(player.contains(s)) {
|
||||||
|
return new BanCheck(BanState.WILDCARD_BANNED, ss, "You've been banned via wildcard");
|
||||||
|
}
|
||||||
|
}else if(endStar) {
|
||||||
|
if(player.startsWith(s)) {
|
||||||
|
return new BanCheck(BanState.WILDCARD_BANNED, ss, "You've been banned via wildcard");
|
||||||
|
}
|
||||||
|
}else if(startStar) {
|
||||||
|
if(player.endsWith(s)) {
|
||||||
|
return new BanCheck(BanState.WILDCARD_BANNED, ss, "You've been banned via wildcard");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(player.equals(s)) {
|
||||||
|
return new BanCheck(BanState.WILDCARD_BANNED, ss, "You've been banned via wildcard");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(RegexBan p : regexBans) {
|
||||||
|
if(p.compiled.matcher(player).matches()) {
|
||||||
|
return new BanCheck(BanState.REGEX_BANNED, p.string, "You've been banned via regex");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new BanCheck(BanState.NOT_BANNED, "none", "not banned");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void saveCurrentBanListLines() {
|
||||||
|
try {
|
||||||
|
PrintWriter pf = new PrintWriter(new FileWriter(bansFile));
|
||||||
|
for(String s : currentBanList) {
|
||||||
|
pf.println(s);
|
||||||
|
}
|
||||||
|
pf.close();
|
||||||
|
lastListLoad = lastListTest = System.currentTimeMillis();
|
||||||
|
}catch(Throwable t) {
|
||||||
|
System.err.println("ERROR: the ban list could not be saved to file '" + bansFile.getName() + "', please fix this or you will lose all your bans next time this server restarts");
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean addEntryToFile(BanState b, String s) {
|
||||||
|
if(b == null || b == BanState.NOT_BANNED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String wantedHeader = b == BanState.USER_BANNED ? "[Usernames]" : (b == BanState.WILDCARD_BANNED ? "[Wildcards]" : (b == BanState.REGEX_BANNED ? "[Regex]" : (b == BanState.IP_BANNED ? "[IPs]" : "shit")));
|
||||||
|
int lastFullPart = -1;
|
||||||
|
boolean isFilePart = false;
|
||||||
|
boolean isPartStart = false;
|
||||||
|
for(int i = 0, l = currentBanList.size(); i < l; ++i) {
|
||||||
|
String ss = currentBanList.get(i).trim();
|
||||||
|
if(ss.length() <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(ss.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(ss.equalsIgnoreCase(wantedHeader)) {
|
||||||
|
isFilePart = true;
|
||||||
|
isPartStart = true;
|
||||||
|
lastFullPart = i;
|
||||||
|
}else if(ss.indexOf('[') != -1) {
|
||||||
|
if(isFilePart) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(isFilePart) {
|
||||||
|
lastFullPart = i;
|
||||||
|
isPartStart = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(lastFullPart != -1) {
|
||||||
|
if(isPartStart) {
|
||||||
|
lastFullPart += 1;
|
||||||
|
currentBanList.add(lastFullPart, "");
|
||||||
|
}
|
||||||
|
lastFullPart += 1;
|
||||||
|
currentBanList.add(lastFullPart, s);
|
||||||
|
lastFullPart += 1;
|
||||||
|
if(currentBanList.size() > lastFullPart && currentBanList.get(lastFullPart).trim().length() > 0) {
|
||||||
|
currentBanList.add(lastFullPart, "");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(currentBanList.size() > 0 && currentBanList.get(currentBanList.size() - 1).trim().length() > 0) {
|
||||||
|
currentBanList.add("");
|
||||||
|
}
|
||||||
|
currentBanList.add(wantedHeader);
|
||||||
|
currentBanList.add("");
|
||||||
|
currentBanList.add(s);
|
||||||
|
currentBanList.add("");
|
||||||
|
}
|
||||||
|
saveCurrentBanListLines();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean removeEntryFromFile(BanState b, String s, boolean ignoreCase) {
|
||||||
|
if(b == null || b == BanState.NOT_BANNED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String wantedHeader = b == BanState.USER_BANNED ? "[Usernames]" : (b == BanState.WILDCARD_BANNED ? "[Wildcards]" : (b == BanState.REGEX_BANNED ? "[Regex]" : (b == BanState.IP_BANNED ? "[IPs]" : "shit")));
|
||||||
|
Iterator<String> lns = currentBanList.iterator();
|
||||||
|
boolean isFilePart = false;
|
||||||
|
boolean wasRemoved = false;
|
||||||
|
while(lns.hasNext()) {
|
||||||
|
String ss = lns.next().trim();
|
||||||
|
if(ss.length() <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(ss.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(ss.equalsIgnoreCase(wantedHeader)) {
|
||||||
|
isFilePart = true;
|
||||||
|
}else if(ss.indexOf('[') != -1) {
|
||||||
|
isFilePart = false;
|
||||||
|
}else {
|
||||||
|
if(b == BanState.USER_BANNED && ss.contains(":")) {
|
||||||
|
ss = ss.substring(0, ss.indexOf(':')).trim();
|
||||||
|
}
|
||||||
|
if(isFilePart && (ignoreCase ? ss.equalsIgnoreCase(s) : ss.equals(s))) {
|
||||||
|
lns.remove();
|
||||||
|
wasRemoved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(wasRemoved) {
|
||||||
|
saveCurrentBanListLines();
|
||||||
|
}
|
||||||
|
return wasRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean unban(String player) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
String s = player.trim().toLowerCase();
|
||||||
|
if(userBans.remove(s) != null) {
|
||||||
|
removeEntryFromFile(BanState.USER_BANNED, player, true);
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean ban(String player, String reason) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
player = player.trim().toLowerCase();
|
||||||
|
if(userBans.put(player, reason) == null) {
|
||||||
|
addEntryToFile(BanState.USER_BANNED, player + (reason == null || reason.length() <= 0 ? "" : ": " + reason));
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean banWildcard(String wc) throws PatternSyntaxException {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
wc = wc.trim().toLowerCase();
|
||||||
|
boolean b = wc.contains("*");
|
||||||
|
if(!b || (b && !wc.startsWith("*") && !wc.endsWith("*"))) {
|
||||||
|
throw new PatternSyntaxException("Wildcard can only begin and/or end with *", wc, 0);
|
||||||
|
}
|
||||||
|
if(wildcardBans.add(wc)) {
|
||||||
|
addEntryToFile(BanState.WILDCARD_BANNED, wc);
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean unbanWildcard(String wc) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
wc = wc.trim().toLowerCase();
|
||||||
|
if(wildcardBans.remove(wc)) {
|
||||||
|
removeEntryFromFile(BanState.WILDCARD_BANNED, wc, true);
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean banRegex(String regex) throws PatternSyntaxException {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
regex = regex.trim();
|
||||||
|
Pattern p = Pattern.compile(regex);
|
||||||
|
if(regexBans.add(new RegexBan(regex, p))) {
|
||||||
|
addEntryToFile(BanState.REGEX_BANNED, regex);
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean unbanRegex(String regex) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
regex = regex.trim();
|
||||||
|
Iterator<RegexBan> banz = regexBans.iterator();
|
||||||
|
while(banz.hasNext()) {
|
||||||
|
if(banz.next().string.equals(regex)) {
|
||||||
|
banz.remove();
|
||||||
|
removeEntryFromFile(BanState.REGEX_BANNED, regex, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPBan constructIpBan(String ip) throws UnknownHostException {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
ip = ip.trim();
|
||||||
|
String s = ip;
|
||||||
|
int subnet = -1;
|
||||||
|
int i = s.indexOf('/');
|
||||||
|
if(i != -1) {
|
||||||
|
String s2 = s.substring(i + 1);
|
||||||
|
s = s.substring(0, i);
|
||||||
|
try {
|
||||||
|
subnet = Integer.parseInt(s2);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
throw new UnknownHostException("Invalid netmask: '" + s + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IPAddressUtil.isIPv4LiteralAddress(s) && !IPAddressUtil.isIPv6LiteralAddress(s)) {
|
||||||
|
throw new UnknownHostException("Invalid address: '" + s + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
InetAddress aa = InetAddress.getByName(s);
|
||||||
|
if(aa instanceof Inet4Address) {
|
||||||
|
if(subnet > 32 || subnet < -1) {
|
||||||
|
throw new UnknownHostException("IPv4 netmask '" + subnet + "' is invalid");
|
||||||
|
}
|
||||||
|
if(subnet == -1) {
|
||||||
|
subnet = 32;
|
||||||
|
}
|
||||||
|
return new IPBan4((Inet4Address)aa, ip, subnet);
|
||||||
|
}else if(aa instanceof Inet6Address) {
|
||||||
|
if(subnet > 128 || subnet < -1) {
|
||||||
|
throw new UnknownHostException("IPv6 netmask '" + subnet + "' is invalid");
|
||||||
|
}
|
||||||
|
if(subnet == -1) {
|
||||||
|
subnet = 128;
|
||||||
|
}
|
||||||
|
return new IPBan6((Inet6Address)aa, ip, subnet);
|
||||||
|
}else {
|
||||||
|
throw new UnknownHostException("Only ipv4 and ipv6 addresses allowed in Eaglercraft");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean banIP(String ip) throws UnknownHostException {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
ip = ip.trim();
|
||||||
|
IPBan b = constructIpBan(ip);
|
||||||
|
if(b != null) {
|
||||||
|
if(ipBans.add(b)) {
|
||||||
|
addEntryToFile(BanState.IP_BANNED, ip);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean unbanIP(String ip) throws UnknownHostException {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
ip = ip.trim();
|
||||||
|
IPBan b = constructIpBan(ip);
|
||||||
|
if(b != null) {
|
||||||
|
Iterator<IPBan> banz = ipBans.iterator();
|
||||||
|
while(banz.hasNext()) {
|
||||||
|
IPBan bb = banz.next();
|
||||||
|
if(bb.equals(b)) {
|
||||||
|
banz.remove();
|
||||||
|
removeEntryFromFile(BanState.IP_BANNED, bb.toString(), true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int MAX_CHAT_LENGTH = 118;
|
||||||
|
|
||||||
|
public static String listAllBans() {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
String ret = "";
|
||||||
|
for(String s : userBans.keySet()) {
|
||||||
|
if(ret.length() > 0) {
|
||||||
|
ret += ", ";
|
||||||
|
}
|
||||||
|
ret += s;
|
||||||
|
}
|
||||||
|
return ret.length() > 0 ? ret : "(none)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String listAllWildcardBans() {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
String ret = "";
|
||||||
|
for(String s : wildcardBans) {
|
||||||
|
if(ret.length() > 0) {
|
||||||
|
ret += ", ";
|
||||||
|
}
|
||||||
|
ret += s;
|
||||||
|
}
|
||||||
|
return ret.length() > 0 ? ret : "(none)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String listAllRegexBans() {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
String ret = "";
|
||||||
|
for(RegexBan s : regexBans) {
|
||||||
|
if(ret.length() > 0) {
|
||||||
|
ret += " | ";
|
||||||
|
}
|
||||||
|
ret += s.string;
|
||||||
|
}
|
||||||
|
return ret.length() > 0 ? ret : "(none)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String listAllIPBans(boolean v6, boolean netmask) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
String ret = "";
|
||||||
|
for(IPBan b : ipBans) {
|
||||||
|
if(v6) {
|
||||||
|
if(b instanceof IPBan6) {
|
||||||
|
IPBan6 b2 = (IPBan6)b;
|
||||||
|
if(netmask == b2.hasNetMask()) {
|
||||||
|
if(ret.length() > 0) {
|
||||||
|
ret += ", ";
|
||||||
|
}
|
||||||
|
ret += b2.string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(b instanceof IPBan4) {
|
||||||
|
IPBan4 b2 = (IPBan4)b;
|
||||||
|
if(netmask == b2.hasNetMask()) {
|
||||||
|
if(ret.length() > 0) {
|
||||||
|
ret += ", ";
|
||||||
|
}
|
||||||
|
ret += b2.string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ret.length() <= 0) {
|
||||||
|
ret = "(none)";
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void maybeReloadBans(CommandSender cs) {
|
||||||
|
synchronized(banListMutex) {
|
||||||
|
long st = System.currentTimeMillis();
|
||||||
|
if(cs == null && st - lastListTest < 1000l) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastListTest = st;
|
||||||
|
boolean ex = bansFile.exists();
|
||||||
|
if(!fileIsBroken && !ex) {
|
||||||
|
try {
|
||||||
|
PrintWriter p = new PrintWriter(new FileWriter(bansFile));
|
||||||
|
p.println();
|
||||||
|
p.println("#");
|
||||||
|
p.println("# This file allows you to configure bans for eaglercraftbungee");
|
||||||
|
p.println("# When it is saved, eaglercraft should reload it automatically");
|
||||||
|
p.println("# (check the console though to be safe)");
|
||||||
|
p.println("#");
|
||||||
|
p.println("# For a [Usernames] ban, just add the player's name. Use a colon ':' to put in a ban reason");
|
||||||
|
p.println("# For a [IPs] ban, just add the player's IP, or a subnet like 69.69.0.0/16 to ban all IPs beginning with 69.69.*");
|
||||||
|
p.println("# For a [Wildcards] ban, type a string and prefix and/or suffix it with * to define the wildcard");
|
||||||
|
p.println("# For a [Regex] ban, type a valid regular expression in the java.util.regex format");
|
||||||
|
p.println("#");
|
||||||
|
p.println("# All bans are case-insensitive, USERNAMES ARE CONVERTED TO LOWERCASE BEFORE BEING MATCHED VIA REGEX");
|
||||||
|
p.println("# Java regex syntax: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html");
|
||||||
|
p.println("#");
|
||||||
|
p.println();
|
||||||
|
p.println("# set this to false to use \"/eag-ban\" to ban on bungee instead of just \"/ban\"");
|
||||||
|
p.println("# (most likely needs a restart to take effect)");
|
||||||
|
p.println("replace-bukkit=true");
|
||||||
|
p.println();
|
||||||
|
p.println();
|
||||||
|
p.println("[Usernames]");
|
||||||
|
p.println();
|
||||||
|
p.println("# ban_test1: The ban hammer has spoken!");
|
||||||
|
p.println("# ban_test2: custom ban message here");
|
||||||
|
p.println("# ban_test3");
|
||||||
|
p.println();
|
||||||
|
p.println("# (remove the '#' before each line to enable)");
|
||||||
|
p.println();
|
||||||
|
p.println("[IPs]");
|
||||||
|
p.println();
|
||||||
|
p.println("# WARNING: if you're using nginx, banning any player's IP is gonna ban ALL PLAYERS on your server");
|
||||||
|
p.println("# For this reason, the ban IP command doesn't ban 127.0.0.1 or any other 'private' range IPs");
|
||||||
|
p.println();
|
||||||
|
p.println("# 101.202.69.11");
|
||||||
|
p.println("# 123.21.43.0/24");
|
||||||
|
p.println("# 2601:1062:69:418:BEEF::10");
|
||||||
|
p.println("# 2601:6090:420::/48");
|
||||||
|
p.println();
|
||||||
|
p.println();
|
||||||
|
p.println("[Wildcards]");
|
||||||
|
p.println();
|
||||||
|
p.println("# *fuck*");
|
||||||
|
p.println("# nigg*");
|
||||||
|
p.println();
|
||||||
|
p.println();
|
||||||
|
p.println("[Regex]");
|
||||||
|
p.println();
|
||||||
|
p.println("# you.+are.(a|the).+bitch");
|
||||||
|
p.println();
|
||||||
|
p.println();
|
||||||
|
p.println("# end of file");
|
||||||
|
p.println();
|
||||||
|
p.close();
|
||||||
|
System.out.println("Wrote a new bans.txt to: " + bansFile.getAbsolutePath());
|
||||||
|
lastListLoad = 0l;
|
||||||
|
}catch(Throwable t) {
|
||||||
|
fileIsBroken = true;
|
||||||
|
if(cs != null) {
|
||||||
|
cs.sendMessage(banChatMessagePrefix + ChatColor.RED + "Could not create blank 'bans.txt' list file");
|
||||||
|
cs.sendMessage(banChatMessagePrefix + ChatColor.RED + "(Reason: " + t.toString() + ")");
|
||||||
|
}
|
||||||
|
System.err.println("Could not create blank 'bans.txt' list file");
|
||||||
|
System.err.println("(Reason: " + t.toString() + ")");
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(fileIsBroken && ex) {
|
||||||
|
fileIsBroken = false;
|
||||||
|
lastListLoad = 0l;
|
||||||
|
}
|
||||||
|
if(fileIsBroken) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long lastEdit = bansFile.lastModified();
|
||||||
|
if(cs != null || lastEdit - lastListLoad > 400l) {
|
||||||
|
try {
|
||||||
|
BufferedReader r = new BufferedReader(new FileReader(bansFile));
|
||||||
|
currentBanList = new LinkedList();
|
||||||
|
String s;
|
||||||
|
while((s = r.readLine()) != null) {
|
||||||
|
currentBanList.add(s);
|
||||||
|
}
|
||||||
|
r.close();
|
||||||
|
lastListLoad = lastEdit;
|
||||||
|
System.out.println("Server bans.txt changed, it will be reloaded automatically");
|
||||||
|
if(cs == null) {
|
||||||
|
for(ProxiedPlayer pp : BungeeCord.getInstance().getPlayers()) {
|
||||||
|
if(pp.hasPermission("bungeecord.command.eag.reloadban")) {
|
||||||
|
pp.sendMessage(BanList.banChatMessagePrefix + ChatColor.WHITE + "Your Eaglercraftbungee bans.txt just got modified, it will be reloaded asap");
|
||||||
|
pp.sendMessage(BanList.banChatMessagePrefix + ChatColor.YELLOW + "Stop your server and check your config immediately if you don't know how this happened!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parseListFrom();
|
||||||
|
System.out.println("Reload complete");
|
||||||
|
}catch(Throwable t) {
|
||||||
|
if(cs != null) {
|
||||||
|
cs.sendMessage(banChatMessagePrefix + ChatColor.RED + "Could not reload 'bans.txt' list file");
|
||||||
|
cs.sendMessage(banChatMessagePrefix + ChatColor.RED + "(Reason: " + t.toString() + ")");
|
||||||
|
}
|
||||||
|
System.err.println("Could not reload 'bans.txt' list file");
|
||||||
|
System.err.println("(Reason: " + t.toString() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseListFrom() {
|
||||||
|
userBans.clear();
|
||||||
|
ipBans.clear();
|
||||||
|
wildcardBans.clear();
|
||||||
|
regexBans.clear();
|
||||||
|
|
||||||
|
int filePart = 0;
|
||||||
|
boolean replaceBukkit = false;
|
||||||
|
|
||||||
|
for(String s : currentBanList) {
|
||||||
|
s = s.trim();
|
||||||
|
if(s.length() <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(s.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(s.equals("[Usernames]")) {
|
||||||
|
filePart = 1;
|
||||||
|
}else if(s.equals("[Wildcards]")) {
|
||||||
|
filePart = 2;
|
||||||
|
}else if(s.equals("[Regex]")) {
|
||||||
|
filePart = 3;
|
||||||
|
}else if(s.equals("[IPs]")) {
|
||||||
|
filePart = 4;
|
||||||
|
}else if(s.equals("replace-bukkit=true")) {
|
||||||
|
replaceBukkit = true;
|
||||||
|
}else if(s.equals("replace-bukkit=false")) {
|
||||||
|
continue;
|
||||||
|
}else {
|
||||||
|
if(filePart == 1) {
|
||||||
|
int i = s.indexOf(':');
|
||||||
|
if(i == -1) {
|
||||||
|
userBans.put(s.toLowerCase(), "");
|
||||||
|
}else {
|
||||||
|
userBans.put(s.substring(0, i).trim().toLowerCase(), s.substring(i + 1).trim());
|
||||||
|
}
|
||||||
|
}else if(filePart == 2) {
|
||||||
|
boolean ws = s.startsWith("*");
|
||||||
|
boolean we = s.endsWith("*");
|
||||||
|
if(!ws && !we) {
|
||||||
|
if(s.contains("*")) {
|
||||||
|
System.err.println("Error: wildcard '" + s + "' contains a '*' not at the start/end of the string");
|
||||||
|
}else {
|
||||||
|
System.err.println("Error: wildcard '" + s + "' does not contain a '*' wildcard character");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
int total = (ws ? 1 : 0) + (we ? 1 : 0);
|
||||||
|
int t2 = 0;
|
||||||
|
for(char c : s.toCharArray()) {
|
||||||
|
if(c == '*') ++t2;
|
||||||
|
}
|
||||||
|
if(total != t2) {
|
||||||
|
System.err.println("Error: wildcard '" + s + "' contains a '*' not at the start/end of the string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wildcardBans.add(s.toLowerCase());
|
||||||
|
}else if(filePart == 3) {
|
||||||
|
Pattern p = null;
|
||||||
|
try {
|
||||||
|
p = Pattern.compile(s);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
System.err.println("Error: the regex " + s.toLowerCase() + " is invalid");
|
||||||
|
System.err.println("Reason: " + t.getClass().getSimpleName() + ": " + t.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
if(p != null) {
|
||||||
|
regexBans.add(new RegexBan(s, p));
|
||||||
|
}
|
||||||
|
}else if(filePart == 4) {
|
||||||
|
String ss = s;
|
||||||
|
int subnet = -1;
|
||||||
|
int i = s.indexOf('/');
|
||||||
|
if(i != -1) {
|
||||||
|
String s2 = s.substring(i + 1);
|
||||||
|
s = s.substring(0, i);
|
||||||
|
try {
|
||||||
|
subnet = Integer.parseInt(s2);
|
||||||
|
}catch(Throwable t) {
|
||||||
|
System.err.println("Error: the subnet '"+ s2 +"' for IP ban address " + s + " was invalid");
|
||||||
|
subnet = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(subnet >= -1) {
|
||||||
|
try {
|
||||||
|
InetAddress aa = InetAddress.getByName(s);
|
||||||
|
if(aa instanceof Inet4Address) {
|
||||||
|
if(subnet == -1) {
|
||||||
|
subnet = 32;
|
||||||
|
}
|
||||||
|
ipBans.add(new IPBan4((Inet4Address)aa, ss, subnet));
|
||||||
|
}else if(aa instanceof Inet6Address) {
|
||||||
|
if(subnet == -1) {
|
||||||
|
subnet = 128;
|
||||||
|
}
|
||||||
|
ipBans.add(new IPBan6((Inet6Address)aa, ss, subnet));
|
||||||
|
}else {
|
||||||
|
throw new UnknownHostException("Only ipv4 and ipv6 addresses allowed in Eaglercraft");
|
||||||
|
}
|
||||||
|
}catch(Throwable t) {
|
||||||
|
System.err.println("Error: the IP ban address " + s + " could not be parsed");
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BungeeCord.getInstance().reconfigureBanCommands(replaceBukkit);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package net.md_5.bungee.eaglercraft;
|
||||||
|
|
||||||
|
public class EaglercraftBungee {
|
||||||
|
|
||||||
|
public static final String brand = "Eagtek";
|
||||||
|
public static final String version = "0.1.0";
|
||||||
|
public static final boolean cracked = true;
|
||||||
|
|
||||||
|
}
|
|
@ -1,34 +1,51 @@
|
||||||
package net.md_5.bungee.eaglercraft;
|
package net.md_5.bungee.eaglercraft;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.java_websocket.WebSocket;
|
import org.java_websocket.WebSocket;
|
||||||
import org.java_websocket.handshake.ClientHandshake;
|
import org.java_websocket.handshake.ClientHandshake;
|
||||||
import org.java_websocket.server.WebSocketServer;
|
import org.java_websocket.server.WebSocketServer;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
|
||||||
public class WebSocketListener extends WebSocketServer {
|
public class WebSocketListener extends WebSocketServer {
|
||||||
|
|
||||||
|
public static class PendingSocket {
|
||||||
|
public long openTime;
|
||||||
|
public InetAddress realAddress;
|
||||||
|
protected PendingSocket(long openTime, InetAddress realAddress) {
|
||||||
|
this.openTime = openTime;
|
||||||
|
this.realAddress = realAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private InetSocketAddress bungeeProxy;
|
private InetSocketAddress bungeeProxy;
|
||||||
private ProxyServer bungeeCord;
|
private ProxyServer bungeeCord;
|
||||||
|
private ListenerInfo info;
|
||||||
|
|
||||||
public WebSocketListener(ListenerInfo info, InetSocketAddress sock, ProxyServer bungeeCord) {
|
public WebSocketListener(ListenerInfo info, InetSocketAddress sock, ProxyServer bungeeCord) {
|
||||||
super(info.getHost());
|
super(info.getHost());
|
||||||
this.setTcpNoDelay(true);
|
this.setTcpNoDelay(true);
|
||||||
this.setConnectionLostTimeout(5);
|
this.setConnectionLostTimeout(5);
|
||||||
this.start();
|
this.start();
|
||||||
|
this.info = info;
|
||||||
this.bungeeProxy = sock;
|
this.bungeeProxy = sock;
|
||||||
this.bungeeCord = bungeeCord;
|
this.bungeeCord = bungeeCord;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
|
public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
|
||||||
if(arg0.getAttachment() != null) {
|
Object o = arg0.getAttachment();
|
||||||
|
if(o != null) {
|
||||||
|
if(o instanceof WebSocketProxy) {
|
||||||
((WebSocketProxy)arg0.getAttachment()).killConnection();
|
((WebSocketProxy)arg0.getAttachment()).killConnection();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
System.out.println("websocket closed - " + arg0.getRemoteSocketAddress());
|
System.out.println("websocket closed - " + arg0.getRemoteSocketAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,24 +60,73 @@ public class WebSocketListener extends WebSocketServer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(WebSocket arg0, ByteBuffer arg1) {
|
public void onMessage(WebSocket arg0, ByteBuffer arg1) {
|
||||||
if(arg0.getAttachment() != null) {
|
Object o = arg0.getAttachment();
|
||||||
((WebSocketProxy)arg0.getAttachment()).sendPacket(arg1);
|
if(o == null || (o instanceof PendingSocket)) {
|
||||||
|
InetAddress realAddr;
|
||||||
|
if(o == null) {
|
||||||
|
realAddr = arg0.getRemoteSocketAddress().getAddress();
|
||||||
|
}else {
|
||||||
|
realAddr = ((PendingSocket)o).realAddress;
|
||||||
|
}
|
||||||
|
System.out.println("connection is binary - " + realAddr);
|
||||||
|
WebSocketProxy proxyObj = new WebSocketProxy(arg0, realAddr, bungeeProxy);
|
||||||
|
arg0.setAttachment(proxyObj);
|
||||||
|
if(!proxyObj.connect()) {
|
||||||
|
System.err.println("loopback to '" + bungeeProxy.toString() + "' failed - " + realAddr);
|
||||||
|
arg0.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
o = proxyObj;
|
||||||
|
}
|
||||||
|
if(o != null) {
|
||||||
|
if(o instanceof WebSocketProxy) {
|
||||||
|
((WebSocketProxy)o).sendPacket(arg1);
|
||||||
|
}else {
|
||||||
|
System.out.println("error: recieved binary data on text websocket - " + arg0.getRemoteSocketAddress());
|
||||||
|
arg0.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(WebSocket arg0, ClientHandshake arg1) {
|
public void onOpen(WebSocket arg0, ClientHandshake arg1) {
|
||||||
System.out.println("websocket opened - " + arg0.getRemoteSocketAddress());
|
System.out.println("websocket opened - " + arg0.getRemoteSocketAddress());
|
||||||
WebSocketProxy proxyObj = new WebSocketProxy(arg0, bungeeProxy);
|
if(info.hasForwardedHeaders()) {
|
||||||
arg0.setAttachment(proxyObj);
|
String s = arg1.getFieldValue("X-Real-IP");
|
||||||
if(!proxyObj.connect()) {
|
if(s != null) {
|
||||||
|
try {
|
||||||
|
InetAddress addr = InetAddress.getByName(s);
|
||||||
|
arg0.setAttachment(new PendingSocket(System.currentTimeMillis(), addr));
|
||||||
|
System.out.println("real IP of '" + arg0.getRemoteSocketAddress().toString() + "' is '" + addr.getHostAddress() + "'");
|
||||||
|
}catch(UnknownHostException e) {
|
||||||
|
System.out.println("invalid 'X-Real-IP' header - " + e.toString());
|
||||||
arg0.close();
|
arg0.close();
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
arg0.setAttachment(new PendingSocket(System.currentTimeMillis(), arg0.getRemoteSocketAddress().getAddress()));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
arg0.setAttachment(new PendingSocket(System.currentTimeMillis(), arg0.getRemoteSocketAddress().getAddress()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeInactiveSockets() {
|
||||||
|
for(WebSocket w : this.getConnections()) {
|
||||||
|
Object o = w.getAttachment();
|
||||||
|
if(o == null) {
|
||||||
|
System.out.println("close inactive websocket - " + w.getRemoteSocketAddress());
|
||||||
|
w.close();
|
||||||
|
}else if(o instanceof PendingSocket) {
|
||||||
|
if(System.currentTimeMillis() - ((PendingSocket)o).openTime > 5000l) {
|
||||||
|
System.out.println("close inactive websocket - " + ((PendingSocket)o).realAddress);
|
||||||
|
w.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package net.md_5.bungee.eaglercraft;
|
package net.md_5.bungee.eaglercraft;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.java_websocket.WebSocket;
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
|
@ -16,6 +18,8 @@ import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.util.concurrent.Future;
|
||||||
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not the ideal solution but what are we supposed to do
|
* Not the ideal solution but what are we supposed to do
|
||||||
|
@ -25,20 +29,22 @@ public class WebSocketProxy extends SimpleChannelInboundHandler<ByteBuf> {
|
||||||
|
|
||||||
private WebSocket client;
|
private WebSocket client;
|
||||||
private InetSocketAddress tcpListener;
|
private InetSocketAddress tcpListener;
|
||||||
|
private InetSocketAddress localAddress;
|
||||||
|
private InetAddress realRemoteAddr;
|
||||||
private NioSocketChannel tcpChannel;
|
private NioSocketChannel tcpChannel;
|
||||||
|
|
||||||
private static final EventLoopGroup group = new NioEventLoopGroup(4);
|
private static final EventLoopGroup group = new NioEventLoopGroup(4);
|
||||||
|
public static final HashMap<InetSocketAddress,InetAddress> localToRemote = new HashMap();
|
||||||
|
|
||||||
public WebSocketProxy(WebSocket w, InetSocketAddress addr) {
|
public WebSocketProxy(WebSocket w, InetAddress remoteAddr, InetSocketAddress addr) {
|
||||||
client = w;
|
client = w;
|
||||||
|
realRemoteAddr = remoteAddr;
|
||||||
tcpListener = addr;
|
tcpListener = addr;
|
||||||
tcpChannel = null;
|
tcpChannel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void killConnection() {
|
public void killConnection() {
|
||||||
if(client.isOpen()) {
|
localToRemote.remove(localAddress);
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
if(tcpChannel != null && tcpChannel.isOpen()) {
|
if(tcpChannel != null && tcpChannel.isOpen()) {
|
||||||
try {
|
try {
|
||||||
tcpChannel.disconnect().sync();
|
tcpChannel.disconnect().sync();
|
||||||
|
@ -59,9 +65,16 @@ public class WebSocketProxy extends SimpleChannelInboundHandler<ByteBuf> {
|
||||||
clientBootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
clientBootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||||
socketChannel.pipeline().addLast(WebSocketProxy.this);
|
socketChannel.pipeline().addLast(WebSocketProxy.this);
|
||||||
|
socketChannel.closeFuture().addListener(new GenericFutureListener<Future<? super Void>>() {
|
||||||
|
@Override
|
||||||
|
public void operationComplete(Future<? super Void> paramF) throws Exception {
|
||||||
|
localToRemote.remove(localAddress);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tcpChannel = (NioSocketChannel) clientBootstrap.connect().sync().channel();
|
tcpChannel = (NioSocketChannel) clientBootstrap.connect().sync().channel();
|
||||||
|
localToRemote.put(localAddress = tcpChannel.localAddress(), realRemoteAddr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}catch(Throwable t) {
|
}catch(Throwable t) {
|
||||||
|
@ -89,4 +102,8 @@ public class WebSocketProxy extends SimpleChannelInboundHandler<ByteBuf> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void finalize() {
|
||||||
|
localToRemote.remove(localAddress);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,323 @@
|
||||||
|
package net.md_5.bungee.eaglercraft.sun.net.util;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class IPAddressUtil {
|
||||||
|
private static final int INADDR4SZ = 4;
|
||||||
|
|
||||||
|
private static final int INADDR16SZ = 16;
|
||||||
|
|
||||||
|
private static final int INT16SZ = 2;
|
||||||
|
|
||||||
|
private static final long L_IPV6_DELIMS = 0L;
|
||||||
|
|
||||||
|
private static final long H_IPV6_DELIMS = 671088640L;
|
||||||
|
|
||||||
|
private static final long L_GEN_DELIMS = -8935000888854970368L;
|
||||||
|
|
||||||
|
private static final long H_GEN_DELIMS = 671088641L;
|
||||||
|
|
||||||
|
private static final long L_AUTH_DELIMS = 288230376151711744L;
|
||||||
|
|
||||||
|
private static final long H_AUTH_DELIMS = 671088641L;
|
||||||
|
|
||||||
|
private static final long L_COLON = 288230376151711744L;
|
||||||
|
|
||||||
|
private static final long H_COLON = 0L;
|
||||||
|
|
||||||
|
private static final long L_SLASH = 140737488355328L;
|
||||||
|
|
||||||
|
private static final long H_SLASH = 0L;
|
||||||
|
|
||||||
|
private static final long L_BACKSLASH = 0L;
|
||||||
|
|
||||||
|
private static final long H_BACKSLASH = 268435456L;
|
||||||
|
|
||||||
|
private static final long L_NON_PRINTABLE = 4294967295L;
|
||||||
|
|
||||||
|
private static final long H_NON_PRINTABLE = -9223372036854775808L;
|
||||||
|
|
||||||
|
private static final long L_EXCLUDE = -8935000884560003073L;
|
||||||
|
|
||||||
|
private static final long H_EXCLUDE = -9223372035915251711L;
|
||||||
|
|
||||||
|
public static byte[] textToNumericFormatV4(String paramString) {
|
||||||
|
byte[] arrayOfByte = new byte[4];
|
||||||
|
long l = 0L;
|
||||||
|
byte b1 = 0;
|
||||||
|
boolean bool = true;
|
||||||
|
int i = paramString.length();
|
||||||
|
if (i == 0 || i > 15)
|
||||||
|
return null;
|
||||||
|
for (byte b2 = 0; b2 < i; b2++) {
|
||||||
|
char c = paramString.charAt(b2);
|
||||||
|
if (c == '.') {
|
||||||
|
if (bool || l < 0L || l > 255L || b1 == 3)
|
||||||
|
return null;
|
||||||
|
arrayOfByte[b1++] = (byte) (int) (l & 0xFFL);
|
||||||
|
l = 0L;
|
||||||
|
bool = true;
|
||||||
|
} else {
|
||||||
|
int j = Character.digit(c, 10);
|
||||||
|
if (j < 0)
|
||||||
|
return null;
|
||||||
|
l *= 10L;
|
||||||
|
l += j;
|
||||||
|
bool = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bool || l < 0L || l >= 1L << (4 - b1) * 8)
|
||||||
|
return null;
|
||||||
|
switch (b1) {
|
||||||
|
case 0 :
|
||||||
|
arrayOfByte[0] = (byte) (int) (l >> 24L & 0xFFL);
|
||||||
|
case 1 :
|
||||||
|
arrayOfByte[1] = (byte) (int) (l >> 16L & 0xFFL);
|
||||||
|
case 2 :
|
||||||
|
arrayOfByte[2] = (byte) (int) (l >> 8L & 0xFFL);
|
||||||
|
case 3 :
|
||||||
|
arrayOfByte[3] = (byte) (int) (l >> 0L & 0xFFL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return arrayOfByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] textToNumericFormatV6(String paramString) {
|
||||||
|
if (paramString.length() < 2)
|
||||||
|
return null;
|
||||||
|
char[] arrayOfChar = paramString.toCharArray();
|
||||||
|
byte[] arrayOfByte1 = new byte[16];
|
||||||
|
int j = arrayOfChar.length;
|
||||||
|
int k = paramString.indexOf("%");
|
||||||
|
if (k == j - 1)
|
||||||
|
return null;
|
||||||
|
if (k != -1)
|
||||||
|
j = k;
|
||||||
|
byte b = -1;
|
||||||
|
byte b1 = 0, b2 = 0;
|
||||||
|
if (arrayOfChar[b1] == ':' && arrayOfChar[++b1] != ':')
|
||||||
|
return null;
|
||||||
|
byte b3 = b1;
|
||||||
|
boolean bool = false;
|
||||||
|
int i = 0;
|
||||||
|
while (b1 < j) {
|
||||||
|
char c = arrayOfChar[b1++];
|
||||||
|
int m = Character.digit(c, 16);
|
||||||
|
if (m != -1) {
|
||||||
|
i <<= 4;
|
||||||
|
i |= m;
|
||||||
|
if (i > 65535)
|
||||||
|
return null;
|
||||||
|
bool = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == ':') {
|
||||||
|
b3 = b1;
|
||||||
|
if (!bool) {
|
||||||
|
if (b != -1)
|
||||||
|
return null;
|
||||||
|
b = b2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (b1 == j)
|
||||||
|
return null;
|
||||||
|
if (b2 + 2 > 16)
|
||||||
|
return null;
|
||||||
|
arrayOfByte1[b2++] = (byte) (i >> 8 & 0xFF);
|
||||||
|
arrayOfByte1[b2++] = (byte) (i & 0xFF);
|
||||||
|
bool = false;
|
||||||
|
i = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '.' && b2 + 4 <= 16) {
|
||||||
|
String str = paramString.substring(b3, j);
|
||||||
|
byte b4 = 0;
|
||||||
|
int n = 0;
|
||||||
|
while ((n = str.indexOf('.', n)) != -1) {
|
||||||
|
b4++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if (b4 != 3)
|
||||||
|
return null;
|
||||||
|
byte[] arrayOfByte = textToNumericFormatV4(str);
|
||||||
|
if (arrayOfByte == null)
|
||||||
|
return null;
|
||||||
|
for (byte b5 = 0; b5 < 4; b5++)
|
||||||
|
arrayOfByte1[b2++] = arrayOfByte[b5];
|
||||||
|
bool = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (bool) {
|
||||||
|
if (b2 + 2 > 16)
|
||||||
|
return null;
|
||||||
|
arrayOfByte1[b2++] = (byte) (i >> 8 & 0xFF);
|
||||||
|
arrayOfByte1[b2++] = (byte) (i & 0xFF);
|
||||||
|
}
|
||||||
|
if (b != -1) {
|
||||||
|
int m = b2 - b;
|
||||||
|
if (b2 == 16)
|
||||||
|
return null;
|
||||||
|
for (b1 = 1; b1 <= m; b1++) {
|
||||||
|
arrayOfByte1[16 - b1] = arrayOfByte1[b + m - b1];
|
||||||
|
arrayOfByte1[b + m - b1] = 0;
|
||||||
|
}
|
||||||
|
b2 = 16;
|
||||||
|
}
|
||||||
|
if (b2 != 16)
|
||||||
|
return null;
|
||||||
|
byte[] arrayOfByte2 = convertFromIPv4MappedAddress(arrayOfByte1);
|
||||||
|
if (arrayOfByte2 != null)
|
||||||
|
return arrayOfByte2;
|
||||||
|
return arrayOfByte1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIPv4LiteralAddress(String paramString) {
|
||||||
|
return (textToNumericFormatV4(paramString) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIPv6LiteralAddress(String paramString) {
|
||||||
|
return (textToNumericFormatV6(paramString) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] convertFromIPv4MappedAddress(byte[] paramArrayOfbyte) {
|
||||||
|
if (isIPv4MappedAddress(paramArrayOfbyte)) {
|
||||||
|
byte[] arrayOfByte = new byte[4];
|
||||||
|
System.arraycopy(paramArrayOfbyte, 12, arrayOfByte, 0, 4);
|
||||||
|
return arrayOfByte;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isIPv4MappedAddress(byte[] paramArrayOfbyte) {
|
||||||
|
if (paramArrayOfbyte.length < 16)
|
||||||
|
return false;
|
||||||
|
if (paramArrayOfbyte[0] == 0 && paramArrayOfbyte[1] == 0 && paramArrayOfbyte[2] == 0 && paramArrayOfbyte[3] == 0
|
||||||
|
&& paramArrayOfbyte[4] == 0 && paramArrayOfbyte[5] == 0 && paramArrayOfbyte[6] == 0
|
||||||
|
&& paramArrayOfbyte[7] == 0 && paramArrayOfbyte[8] == 0 && paramArrayOfbyte[9] == 0
|
||||||
|
&& paramArrayOfbyte[10] == -1 && paramArrayOfbyte[11] == -1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean match(char paramChar, long paramLong1, long paramLong2) {
|
||||||
|
if (paramChar < '@')
|
||||||
|
return ((1L << paramChar & paramLong1) != 0L);
|
||||||
|
if (paramChar < '')
|
||||||
|
return ((1L << paramChar - 64 & paramLong2) != 0L);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int scan(String paramString, long paramLong1, long paramLong2) {
|
||||||
|
byte b = -1;
|
||||||
|
int i;
|
||||||
|
if (paramString == null || (i = paramString.length()) == 0)
|
||||||
|
return -1;
|
||||||
|
boolean bool = false;
|
||||||
|
while (++b < i && !(bool = match(paramString.charAt(b), paramLong1, paramLong2)));
|
||||||
|
if (bool)
|
||||||
|
return b;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int scan(String paramString, long paramLong1, long paramLong2, char[] paramArrayOfchar) {
|
||||||
|
byte b = -1;
|
||||||
|
int i;
|
||||||
|
if (paramString == null || (i = paramString.length()) == 0)
|
||||||
|
return -1;
|
||||||
|
boolean bool = false;
|
||||||
|
char c2 = paramArrayOfchar[0];
|
||||||
|
char c1;
|
||||||
|
while (++b < i && !(bool = match(c1 = paramString.charAt(b), paramLong1, paramLong2))) {
|
||||||
|
if (c1 >= c2 && Arrays.binarySearch(paramArrayOfchar, c1) > -1) {
|
||||||
|
bool = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bool)
|
||||||
|
return b;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String describeChar(char paramChar) {
|
||||||
|
if (paramChar < ' ' || paramChar == '') {
|
||||||
|
if (paramChar == '\n')
|
||||||
|
return "LF";
|
||||||
|
if (paramChar == '\r')
|
||||||
|
return "CR";
|
||||||
|
return "control char (code=" + paramChar + ")";
|
||||||
|
}
|
||||||
|
if (paramChar == '\\')
|
||||||
|
return "'\\'";
|
||||||
|
return "'" + paramChar + "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String checkUserInfo(String paramString) {
|
||||||
|
int i = scan(paramString, -9223231260711714817L, -9223372035915251711L);
|
||||||
|
if (i >= 0)
|
||||||
|
return "Illegal character found in user-info: " + describeChar(paramString.charAt(i));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String checkHost(String paramString) {
|
||||||
|
if (paramString.startsWith("[") && paramString.endsWith("]")) {
|
||||||
|
paramString = paramString.substring(1, paramString.length() - 1);
|
||||||
|
if (isIPv6LiteralAddress(paramString)) {
|
||||||
|
int j = paramString.indexOf('%');
|
||||||
|
if (j >= 0) {
|
||||||
|
j = scan(paramString = paramString.substring(j), 4294967295L, -9223372036183687168L);
|
||||||
|
if (j >= 0)
|
||||||
|
return "Illegal character found in IPv6 scoped address: " + describeChar(paramString.charAt(j));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return "Unrecognized IPv6 address format";
|
||||||
|
}
|
||||||
|
int i = scan(paramString, -8935000884560003073L, -9223372035915251711L);
|
||||||
|
if (i >= 0)
|
||||||
|
return "Illegal character found in host: " + describeChar(paramString.charAt(i));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String checkAuth(String paramString) {
|
||||||
|
int i = scan(paramString, -9223231260711714817L, -9223372036586340352L);
|
||||||
|
if (i >= 0)
|
||||||
|
return "Illegal character found in authority: " + describeChar(paramString.charAt(i));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String checkAuthority(URL paramURL) {
|
||||||
|
if (paramURL == null)
|
||||||
|
return null;
|
||||||
|
String str1;
|
||||||
|
String str2;
|
||||||
|
if ((str1 = checkUserInfo(str2 = paramURL.getUserInfo())) != null)
|
||||||
|
return str1;
|
||||||
|
String str3;
|
||||||
|
if ((str1 = checkHost(str3 = paramURL.getHost())) != null)
|
||||||
|
return str1;
|
||||||
|
if (str3 == null && str2 == null)
|
||||||
|
return checkAuth(paramURL.getAuthority());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String checkExternalForm(URL paramURL) {
|
||||||
|
if (paramURL == null)
|
||||||
|
return null;
|
||||||
|
String str;
|
||||||
|
int i = scan(str = paramURL.getUserInfo(), 140741783322623L, Long.MIN_VALUE);
|
||||||
|
if (i >= 0)
|
||||||
|
return "Illegal character found in authority: " + describeChar(str.charAt(i));
|
||||||
|
if ((str = checkHostString(paramURL.getHost())) != null)
|
||||||
|
return str;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String checkHostString(String paramString) {
|
||||||
|
if (paramString == null)
|
||||||
|
return null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user