Added user/ip/wildcard/regex ban commands

This commit is contained in:
LAX1DUDE 2022-03-30 16:46:54 -07:00
parent 94a8c3f6e9
commit 09fdd00900
23 changed files with 2116 additions and 36 deletions

View file

@ -19,7 +19,6 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.MissingResourceException;
import net.md_5.bungee.protocol.packet.DefinedPacket;
import io.netty.channel.ChannelException;
import java.util.Iterator;
import io.netty.util.concurrent.GenericFutureListener;
import java.net.SocketAddress;
import io.netty.channel.EventLoopGroup;
@ -28,7 +27,6 @@ import io.netty.util.AttributeKey;
import net.md_5.bungee.netty.PipelineUtils;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.util.concurrent.Future;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
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.command.ConsoleCommandSender;
import java.util.concurrent.TimeUnit;
import java.util.Calendar;
import java.util.ArrayList;
import java.io.IOException;
import jline.UnsupportedTerminal;
import java.io.OutputStream;
@ -50,6 +48,14 @@ import jline.internal.Log;
import java.io.PrintStream;
import com.google.common.io.ByteStreams;
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.CommandPerms;
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.Plugin;
import net.md_5.bungee.command.CommandReload;
import java.util.concurrent.ExecutorService;
import net.md_5.bungee.scheduler.BungeeScheduler;
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.WebSocketListener;
@ -99,6 +104,8 @@ public class BungeeCord extends ProxyServer {
public final ScheduledThreadPoolExecutor executors;
public final MultithreadEventLoopGroup eventLoops;
private final Timer saveThread;
private final Timer reloadBanThread;
private final Timer closeInactiveSockets;
private Collection<Channel> listeners;
private Collection<WebSocketListener> wsListeners;
private final Map<String, UserConnection> connections;
@ -111,6 +118,7 @@ public class BungeeCord extends ProxyServer {
private final TaskScheduler scheduler;
private ConsoleReader consoleReader;
private final Logger logger;
private Collection<Command> banCommands;
public static BungeeCord 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.eventLoops = (MultithreadEventLoopGroup) new NioEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setNameFormat("Netty IO Thread #%1$d").build());
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.wsListeners = new HashSet<WebSocketListener>();
this.connections = (Map<String, UserConnection>) new CaseInsensitiveMap();
@ -131,6 +141,7 @@ public class BungeeCord extends ProxyServer {
this.pluginChannels = new HashSet<String>();
this.pluginsFolder = new File("plugins");
this.scheduler = new BungeeScheduler();
this.banCommands = new ArrayList();
this.getPluginManager().registerCommand(null, new CommandReload());
this.getPluginManager().registerCommand(null, new CommandEnd());
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 {
final BungeeCord bungee = new BungeeCord();
ProxyServer.setInstance(bungee);
@ -186,6 +233,20 @@ public class BungeeCord extends ProxyServer {
BungeeCord.this.getReconnectHandler().save();
}
}, 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() {

View file

@ -4,13 +4,10 @@
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 net.md_5.bungee.util.CaseInsensitiveSet;
import java.util.HashSet;
import net.md_5.bungee.api.config.TexturePackInfo;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.event.PermissionCheckEvent;
import java.util.Collections;
import java.net.InetSocketAddress;
@ -36,10 +33,14 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import net.md_5.bungee.api.ChatColor;
import java.util.Objects;
import java.util.WeakHashMap;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.protocol.packet.DefinedPacket;
import com.google.common.base.Preconditions;
import java.util.Iterator;
import java.util.Map;
import net.md_5.bungee.api.connection.Connection;
import net.md_5.bungee.api.score.Scoreboard;
import net.md_5.bungee.protocol.packet.PacketCCSettings;
@ -71,6 +72,7 @@ public final class UserConnection implements ProxiedPlayer {
private final Scoreboard serverSentScoreboard;
private String displayName;
private final Connection.Unsafe unsafe;
private final Map<String, Object> attachment = new WeakHashMap();
public void init() {
this.displayName = this.name;
@ -383,4 +385,9 @@ public final class UserConnection implements ProxiedPlayer {
public String getDisplayName() {
return this.displayName;
}
@Override
public Map<String, Object> getAttachment() {
return attachment;
}
}

View file

@ -5,6 +5,7 @@
package net.md_5.bungee.api;
import java.util.Collection;
import java.util.Map;
public interface CommandSender {
String getName();
@ -22,4 +23,6 @@ public interface CommandSender {
boolean hasPermission(final String p0);
void setPermission(final String p0, final boolean p1);
Map<String, Object> getAttachment();
}

View file

@ -5,6 +5,9 @@
package net.md_5.bungee.api.config;
import java.beans.ConstructorProperties;
import java.io.File;
import net.md_5.bungee.api.ServerIcon;
import net.md_5.bungee.api.tab.TabListHandler;
import java.util.Map;
import java.net.InetSocketAddress;
@ -18,13 +21,18 @@ public class ListenerInfo {
private final String fallbackServer;
private final boolean forceDefault;
private final boolean websocket;
private final boolean forwardIp;
private final Map<String, String> forcedHosts;
private final TexturePackInfo texturePack;
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,
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.motd = motd;
this.maxPlayers = maxPlayers;
@ -33,9 +41,14 @@ public class ListenerInfo {
this.fallbackServer = fallbackServer;
this.forceDefault = forceDefault;
this.websocket = websocket;
this.forwardIp = forwardIp;
this.forcedHosts = forcedHosts;
this.texturePack = texturePack;
this.tabList = tabList;
this.serverIcon = serverIcon;
this.serverIconCache = new int[4096];
this.serverIconLoaded = false;
this.serverIconSet = false;
}
public InetSocketAddress getHost() {
@ -120,6 +133,9 @@ public class ListenerInfo {
if (this.getTabListSize() != other.getTabListSize()) {
return false;
}
if (this.isWebsocket() != other.isWebsocket()) {
return false;
}
final Object this$defaultServer = this.getDefaultServer();
final Object other$defaultServer = other.getDefaultServer();
Label_0165: {
@ -180,6 +196,15 @@ public class ListenerInfo {
} else if (this$tabList.equals(other$tabList)) {
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;
}
@ -208,6 +233,8 @@ public class ListenerInfo {
result = result * 31 + (($texturePack == null) ? 0 : $texturePack.hashCode());
final Object $tabList = this.getTabList();
result = result * 31 + (($tabList == null) ? 0 : $tabList.hashCode());
final Object $serverIconCache = this.getTabList();
result = result * 31 + (($serverIconCache == null) ? 0 : $serverIconCache.hashCode());
return result;
}
@ -220,4 +247,9 @@ public class ListenerInfo {
public boolean isWebsocket() {
return websocket;
}
public boolean hasForwardedHeaders() {
return forwardIp;
}
}

View file

@ -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]");
}
}
}

View file

@ -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;
}
}
}
}

View file

@ -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");
}
}
}
}

View file

@ -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");
}
}

View file

@ -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");
}
}
}
}

View file

@ -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 + "\"");
}
}
}
}
}

View file

@ -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;
}
}

View file

@ -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");
}
}
}
}

View file

@ -6,6 +6,9 @@ package net.md_5.bungee.command;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.ProxyServer;
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;
@ -24,8 +27,13 @@ public class CommandIP extends Command {
final ProxiedPlayer user = ProxyServer.getInstance().getPlayer(args[0]);
if (user == null) {
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 {
sender.sendMessage(ChatColor.BLUE + "IP of " + args[0] + " is " + user.getAddress());
}
}
}
}

View file

@ -4,14 +4,16 @@
package net.md_5.bungee.command;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.Collection;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.CommandSender;
public class ConsoleCommandSender implements CommandSender {
private static final ConsoleCommandSender instance;
private static final Map<String, Object> attachment = new WeakHashMap();
private ConsoleCommandSender() {
}
@ -65,4 +67,9 @@ public class ConsoleCommandSender implements CommandSender {
static {
instance = new ConsoleCommandSender();
}
@Override
public Map<String, Object> getAttachment() {
return attachment;
}
}

View file

@ -12,6 +12,7 @@ import com.google.common.base.Preconditions;
import net.md_5.bungee.api.ProxyServer;
import java.util.UUID;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.eaglercraft.EaglercraftBungee;
import gnu.trove.map.TMap;
import net.md_5.bungee.api.config.ListenerInfo;
import java.util.Collection;
@ -24,6 +25,7 @@ public class Configuration {
private AuthServiceInfo authInfo;
private boolean onlineMode;
private int playerLimit;
private String name;
public Configuration() {
this.timeout = 30000;
@ -41,6 +43,7 @@ public class Configuration {
this.authInfo = adapter.getAuthSettings();
this.onlineMode = false;
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.");
final Map<String, ServerInfo> newServers = adapter.getServers();
Preconditions.checkArgument(newServers != null && !newServers.isEmpty(), (Object) "No servers defined");
@ -88,4 +91,8 @@ public class Configuration {
public AuthServiceInfo getAuthInfo() {
return authInfo;
}
public String getServerName() {
return name;
}
}

View file

@ -67,18 +67,11 @@ public class YamlConfig implements ConfigurationAdapter {
final Map<String, Object> permissions = this.get("permissions", new HashMap<String, Object>());
if (permissions.isEmpty()) {
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>());
/*
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) {
@ -159,6 +152,7 @@ public class YamlConfig implements ConfigurationAdapter {
final String fallbackServer = this.get("fallback_server", defaultServer, val);
final boolean forceDefault = this.get("force_default_server", 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 int tabListSize = this.get("tab_size", 60, val);
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 TexturePackInfo texture = (textureURL == null) ? null : new TexturePackInfo(textureURL, textureSize);
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());
if (value == null) {
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);
}
return ret;

View file

@ -6,6 +6,7 @@ package net.md_5.bungee.connection;
import java.beans.ConstructorProperties;
import java.util.ArrayList;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import net.md_5.bungee.protocol.packet.PacketFFKick;
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 com.google.common.base.Preconditions;
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.protocol.packet.PacketFEPing;
import net.md_5.bungee.Util;
@ -112,8 +116,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection {
if (handshake.getProcolVersion() == 69) {
skipEncryption = true;
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) {
this.disconnect("minecraft 1.5.2 required for eaglercraft backdoor access");
return;
}
String un = handshake.getUsername();
if (un.length() < 3) {
@ -128,6 +136,37 @@ public class InitialHandler extends PacketHandler implements PendingConnection {
this.disconnect("Go fuck yourself");
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();
if (limit > 0 && this.bungee.getOnlineCount() > limit) {
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 {
Preconditions.checkState(this.thisState == State.LOGIN, (Object) "Not expecting LOGIN");
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();
this.bungee.getPluginManager().callEvent(new PostLoginEvent(userCon));
((HandlerBoss) this.ch.getHandle().pipeline().get((Class) HandlerBoss.class)).setHandler(new UpstreamBridge(this.bungee, userCon));

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -1,34 +1,51 @@
package net.md_5.bungee.eaglercraft;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
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.config.ListenerInfo;
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 ProxyServer bungeeCord;
private ListenerInfo info;
public WebSocketListener(ListenerInfo info, InetSocketAddress sock, ProxyServer bungeeCord) {
super(info.getHost());
this.setTcpNoDelay(true);
this.setConnectionLostTimeout(5);
this.start();
this.info = info;
this.bungeeProxy = sock;
this.bungeeCord = bungeeCord;
}
@Override
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();
}
}
System.out.println("websocket closed - " + arg0.getRemoteSocketAddress());
}
@ -43,24 +60,73 @@ public class WebSocketListener extends WebSocketServer {
@Override
public void onMessage(WebSocket arg0, ByteBuffer arg1) {
if(arg0.getAttachment() != null) {
((WebSocketProxy)arg0.getAttachment()).sendPacket(arg1);
Object o = arg0.getAttachment();
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
public void onOpen(WebSocket arg0, ClientHandshake arg1) {
System.out.println("websocket opened - " + arg0.getRemoteSocketAddress());
WebSocketProxy proxyObj = new WebSocketProxy(arg0, bungeeProxy);
arg0.setAttachment(proxyObj);
if(!proxyObj.connect()) {
if(info.hasForwardedHeaders()) {
String s = arg1.getFieldValue("X-Real-IP");
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();
}
}else {
arg0.setAttachment(new PendingSocket(System.currentTimeMillis(), arg0.getRemoteSocketAddress().getAddress()));
}
}else {
arg0.setAttachment(new PendingSocket(System.currentTimeMillis(), arg0.getRemoteSocketAddress().getAddress()));
}
}
@Override
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();
}
}
}
}
}

View file

@ -1,7 +1,9 @@
package net.md_5.bungee.eaglercraft;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.HashMap;
import org.java_websocket.WebSocket;
@ -16,6 +18,8 @@ import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
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
@ -25,20 +29,22 @@ public class WebSocketProxy extends SimpleChannelInboundHandler<ByteBuf> {
private WebSocket client;
private InetSocketAddress tcpListener;
private InetSocketAddress localAddress;
private InetAddress realRemoteAddr;
private NioSocketChannel tcpChannel;
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;
realRemoteAddr = remoteAddr;
tcpListener = addr;
tcpChannel = null;
}
public void killConnection() {
if(client.isOpen()) {
client.close();
}
localToRemote.remove(localAddress);
if(tcpChannel != null && tcpChannel.isOpen()) {
try {
tcpChannel.disconnect().sync();
@ -59,9 +65,16 @@ public class WebSocketProxy extends SimpleChannelInboundHandler<ByteBuf> {
clientBootstrap.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
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();
localToRemote.put(localAddress = tcpChannel.localAddress(), realRemoteAddr);
return true;
}
}catch(Throwable t) {
@ -89,4 +102,8 @@ public class WebSocketProxy extends SimpleChannelInboundHandler<ByteBuf> {
}
}
public void finalize() {
localToRemote.remove(localAddress);
}
}

View file

@ -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;
}
}