mirror of
https://git.zelz.net/catfoolyou/Project164.git
synced 2025-12-14 18:17:41 +00:00
Bungee added
This commit is contained in:
44
eaglerbungee/src/main/java/net/md_5/bungee/Bootstrap.java
Normal file
44
eaglerbungee/src/main/java/net/md_5/bungee/Bootstrap.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||
|
||||
public class Bootstrap
|
||||
{
|
||||
|
||||
private static List<String> list(String... params)
|
||||
{
|
||||
return Arrays.asList( params );
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new instance of BungeeCord.
|
||||
*
|
||||
* @param args command line arguments, currently none are used
|
||||
* @throws Exception when the server cannot be started
|
||||
*/
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
System.setProperty( "java.net.preferIPv4Stack", "true" );
|
||||
|
||||
BungeeCord bungee = new BungeeCord();
|
||||
ProxyServer.setInstance( bungee );
|
||||
bungee.getLogger().info( "Enabled BungeeCord version " + bungee.getVersion() );
|
||||
bungee.start();
|
||||
|
||||
while ( bungee.isRunning )
|
||||
{
|
||||
String line = bungee.getConsoleReader().readLine( ">" );
|
||||
if ( line != null )
|
||||
{
|
||||
if ( !bungee.getPluginManager().dispatchCommand( ConsoleCommandSender.getInstance(), line ) )
|
||||
{
|
||||
bungee.getConsole().sendMessage( ChatColor.RED + "Command not found" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
574
eaglerbungee/src/main/java/net/md_5/bungee/BungeeCord.java
Normal file
574
eaglerbungee/src/main/java/net/md_5/bungee/BungeeCord.java
Normal file
@@ -0,0 +1,574 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.MultithreadEventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import jline.UnsupportedTerminal;
|
||||
import jline.console.ConsoleReader;
|
||||
import jline.internal.Log;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.ReconnectHandler;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.plugin.PluginManager;
|
||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
||||
import net.md_5.bungee.api.tab.CustomTabList;
|
||||
import net.md_5.bungee.command.CommandAlert;
|
||||
import net.md_5.bungee.command.CommandBungee;
|
||||
import net.md_5.bungee.command.CommandChangePassword;
|
||||
import net.md_5.bungee.command.CommandClearRatelimit;
|
||||
import net.md_5.bungee.command.CommandConfirmCode;
|
||||
import net.md_5.bungee.command.CommandDomain;
|
||||
import net.md_5.bungee.command.CommandDomainBlock;
|
||||
import net.md_5.bungee.command.CommandDomainBlockDomain;
|
||||
import net.md_5.bungee.command.CommandDomainUnblock;
|
||||
import net.md_5.bungee.command.CommandEnd;
|
||||
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.CommandIP;
|
||||
import net.md_5.bungee.command.CommandList;
|
||||
import net.md_5.bungee.command.CommandPerms;
|
||||
import net.md_5.bungee.command.CommandReload;
|
||||
import net.md_5.bungee.command.CommandSend;
|
||||
import net.md_5.bungee.command.CommandServer;
|
||||
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.YamlConfig;
|
||||
import net.md_5.bungee.eaglercraft.AuthHandler;
|
||||
import net.md_5.bungee.eaglercraft.AuthSystem;
|
||||
import net.md_5.bungee.eaglercraft.BanList;
|
||||
import net.md_5.bungee.eaglercraft.DomainBlacklist;
|
||||
import net.md_5.bungee.eaglercraft.PluginEaglerSkins;
|
||||
import net.md_5.bungee.eaglercraft.PluginEaglerVoice;
|
||||
import net.md_5.bungee.eaglercraft.WebSocketListener;
|
||||
import net.md_5.bungee.log.BungeeLogger;
|
||||
import net.md_5.bungee.log.LoggingOutputStream;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.reconnect.SQLReconnectHandler;
|
||||
import net.md_5.bungee.scheduler.BungeeScheduler;
|
||||
import net.md_5.bungee.scheduler.BungeeThreadPool;
|
||||
import net.md_5.bungee.tab.Custom;
|
||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||
|
||||
public class BungeeCord extends ProxyServer {
|
||||
public volatile boolean isRunning;
|
||||
public final Configuration config;
|
||||
public final ResourceBundle bundle;
|
||||
public final ScheduledThreadPoolExecutor executors;
|
||||
public final MultithreadEventLoopGroup eventLoops;
|
||||
private final Timer saveThread;
|
||||
private final Timer reloadBanThread;
|
||||
private final Timer closeInactiveSockets;
|
||||
private final Timer authTimeoutTimer;
|
||||
private Collection<Channel> listeners;
|
||||
private Collection<WebSocketListener> wsListeners;
|
||||
private final Map<String, UserConnection> connections;
|
||||
private final ReadWriteLock connectionLock;
|
||||
public final PluginManager pluginManager;
|
||||
private ReconnectHandler reconnectHandler;
|
||||
private ConfigurationAdapter configurationAdapter;
|
||||
private final Collection<String> pluginChannels;
|
||||
private final File pluginsFolder;
|
||||
private final TaskScheduler scheduler;
|
||||
private ConsoleReader consoleReader;
|
||||
private final Logger logger;
|
||||
private Collection<Command> banCommands;
|
||||
public AuthSystem authSystem;
|
||||
public String tokenVerify;
|
||||
|
||||
public static BungeeCord getInstance() {
|
||||
return (BungeeCord) ProxyServer.getInstance();
|
||||
}
|
||||
|
||||
public BungeeCord() throws IOException {
|
||||
this.config = new Configuration();
|
||||
this.bundle = ResourceBundle.getBundle("messages_en");
|
||||
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.authTimeoutTimer = new Timer("Auth Timeout");
|
||||
this.listeners = new HashSet<Channel>();
|
||||
this.wsListeners = new HashSet<WebSocketListener>();
|
||||
this.connections = (Map<String, UserConnection>) new CaseInsensitiveMap();
|
||||
this.connectionLock = new ReentrantReadWriteLock();
|
||||
this.pluginManager = new PluginManager(this);
|
||||
this.configurationAdapter = new YamlConfig();
|
||||
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());
|
||||
this.getPluginManager().registerCommand(null, new CommandServer());
|
||||
this.getPluginManager().registerCommand(null, new CommandIP());
|
||||
this.getPluginManager().registerCommand(null, new CommandAlert());
|
||||
this.getPluginManager().registerCommand(null, new CommandBungee());
|
||||
this.getPluginManager().registerCommand(null, new CommandPerms());
|
||||
this.getPluginManager().registerCommand(null, new CommandSend());
|
||||
this.getPluginManager().registerCommand(null, new CommandFind());
|
||||
this.getPluginManager().registerCommand(null, new CommandClearRatelimit());
|
||||
this.getPluginManager().registerCommand(null, new CommandConfirmCode());
|
||||
this.getPluginManager().registerCommand(null, new CommandDomain());
|
||||
this.getPluginManager().registerCommand(null, new CommandDomainBlock());
|
||||
this.getPluginManager().registerCommand(null, new CommandDomainBlockDomain());
|
||||
this.getPluginManager().registerCommand(null, new CommandDomainUnblock());
|
||||
this.registerChannel("BungeeCord");
|
||||
Log.setOutput(new PrintStream(ByteStreams.nullOutputStream()));
|
||||
AnsiConsole.systemInstall();
|
||||
this.consoleReader = new ConsoleReader();
|
||||
this.logger = new BungeeLogger(this);
|
||||
System.setErr(new PrintStream(new LoggingOutputStream(this.logger, Level.SEVERE), true));
|
||||
System.setOut(new PrintStream(new LoggingOutputStream(this.logger, Level.INFO), true));
|
||||
if (this.consoleReader.getTerminal() instanceof UnsupportedTerminal) {
|
||||
this.logger.info("Unable to initialize fancy terminal. To fix this on Windows, install the correct Microsoft Visual C++ 2008 Runtime");
|
||||
this.logger.info("NOTE: This error is non crucial, and BungeeCord will still function correctly! Do not bug the author about it unless you are still unable to get it working");
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
bungee.getLogger().info("Enabled BungeeCord version " + bungee.getVersion());
|
||||
bungee.start();
|
||||
while (bungee.isRunning) {
|
||||
final String line = bungee.getConsoleReader().readLine(">");
|
||||
if (line != null && !bungee.getPluginManager().dispatchCommand(ConsoleCommandSender.getInstance(), line)) {
|
||||
bungee.getConsole().sendMessage(ChatColor.RED + "Command not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
this.pluginsFolder.mkdir();
|
||||
this.config.load();
|
||||
this.pluginManager.detectPlugins(this.pluginsFolder);
|
||||
this.pluginManager.addInternalPlugin(new PluginEaglerSkins());
|
||||
this.pluginManager.addInternalPlugin(new PluginEaglerVoice(this.config.getVoiceEnabled()));
|
||||
if (this.config.getAuthInfo().isEnabled()) {
|
||||
this.authSystem = new AuthSystem(this.config.getAuthInfo());
|
||||
this.getPluginManager().registerCommand(null, new CommandChangePassword(this.authSystem));
|
||||
}
|
||||
this.tokenVerify = Optional.ofNullable(System.getenv("YEEISH_TOKEN")).orElse(this.config.getTokenVerify());
|
||||
if (this.reconnectHandler == null) {
|
||||
this.reconnectHandler = new SQLReconnectHandler();
|
||||
}
|
||||
this.isRunning = true;
|
||||
this.pluginManager.loadAndEnablePlugins();
|
||||
this.startListeners();
|
||||
this.saveThread.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
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));
|
||||
DomainBlacklist.init(this);
|
||||
this.closeInactiveSockets.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
DomainBlacklist.update();
|
||||
for(WebSocketListener lst : BungeeCord.this.wsListeners) {
|
||||
lst.closeInactiveSockets();
|
||||
ListenerInfo info = lst.getInfo();
|
||||
if(info.getRateLimitIP() != null) info.getRateLimitIP().deleteClearLimiters();
|
||||
if(info.getRateLimitLogin() != null) info.getRateLimitLogin().deleteClearLimiters();
|
||||
if(info.getRateLimitMOTD() != null) info.getRateLimitMOTD().deleteClearLimiters();
|
||||
if(info.getRateLimitQuery() != null) info.getRateLimitQuery().deleteClearLimiters();
|
||||
}
|
||||
}
|
||||
}, 0L, TimeUnit.SECONDS.toMillis(10L));
|
||||
final int authTimeout = this.config.getAuthInfo().getLoginTimeout();
|
||||
this.authTimeoutTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
AuthHandler.closeInactive(authTimeout);
|
||||
}
|
||||
}, 0L, TimeUnit.SECONDS.toMillis(2L));
|
||||
}
|
||||
|
||||
public void startListeners() {
|
||||
for (final ListenerInfo info : this.config.getListeners()) {
|
||||
InetSocketAddress sock = info.getHost();
|
||||
if(info.isWebsocket()) {
|
||||
sock = info.getJavaHost();
|
||||
if(sock == null) {
|
||||
try {
|
||||
ServerSocket s = new ServerSocket(0, 0, InetAddress.getByName("127.11.0.1"));
|
||||
sock = new InetSocketAddress("127.11.0.1", s.getLocalPort());
|
||||
s.close();
|
||||
} catch(IOException e) {
|
||||
sock = new InetSocketAddress("127.11.0.1",(int) (System.nanoTime() % 64000L + 1025L));
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.wsListeners.add(new WebSocketListener(info, sock, this));
|
||||
BungeeCord.this.getLogger().info("Listening websockets on " + info.getHost());
|
||||
}catch(Throwable t) {
|
||||
BungeeCord.this.getLogger().log(Level.WARNING, "Could not bind websocket listener to host " + info.getHost(), t);
|
||||
}
|
||||
}
|
||||
final InetSocketAddress sock2 = sock;
|
||||
final ChannelFutureListener listener = (ChannelFutureListener) new ChannelFutureListener() {
|
||||
public void operationComplete(final ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
BungeeCord.this.listeners.add(future.channel());
|
||||
BungeeCord.this.getLogger().info("Listening on " + sock2);
|
||||
} else {
|
||||
BungeeCord.this.getLogger().log(Level.WARNING, "Could not bind to host " + sock2, future.cause());
|
||||
}
|
||||
}
|
||||
};
|
||||
((ServerBootstrap) ((ServerBootstrap) new ServerBootstrap().channel((Class) NioServerSocketChannel.class)).childAttr((AttributeKey) PipelineUtils.LISTENER, (Object) info).childHandler((ChannelHandler) PipelineUtils.SERVER_CHILD)
|
||||
.group((EventLoopGroup) this.eventLoops).localAddress((SocketAddress) sock)).bind().addListener((GenericFutureListener) listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopListeners() {
|
||||
for (final Channel listener : this.listeners) {
|
||||
this.getLogger().log(Level.INFO, "Closing listener {0}", listener);
|
||||
try {
|
||||
listener.close().syncUninterruptibly();
|
||||
} catch (ChannelException ex) {
|
||||
this.getLogger().severe("Could not close listen thread");
|
||||
}
|
||||
}
|
||||
for (final WebSocketListener listener : this.wsListeners) {
|
||||
this.getLogger().log(Level.INFO, "Closing websocket listener {0}", listener.getAddress());
|
||||
try {
|
||||
listener.stop();
|
||||
}catch (IOException e) {
|
||||
this.getLogger().severe("Could not close listen thread");
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
this.getLogger().severe("Could not close listen thread");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
new Thread("Shutdown Thread") {
|
||||
@Override
|
||||
public void run() {
|
||||
BungeeCord.this.isRunning = false;
|
||||
BungeeCord.this.executors.shutdown();
|
||||
BungeeCord.this.stopListeners();
|
||||
BungeeCord.this.getLogger().info("Closing pending connections");
|
||||
BungeeCord.this.connectionLock.readLock().lock();
|
||||
try {
|
||||
BungeeCord.this.getLogger().info("Disconnecting " + BungeeCord.this.connections.size() + " connections");
|
||||
for (final UserConnection user : BungeeCord.this.connections.values()) {
|
||||
user.disconnect(BungeeCord.this.getTranslation("restart"));
|
||||
}
|
||||
} finally {
|
||||
BungeeCord.this.connectionLock.readLock().unlock();
|
||||
}
|
||||
BungeeCord.this.getLogger().info("Closing IO threads");
|
||||
BungeeCord.this.eventLoops.shutdownGracefully();
|
||||
try {
|
||||
BungeeCord.this.eventLoops.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
BungeeCord.this.getLogger().info("Saving reconnect locations");
|
||||
BungeeCord.this.reconnectHandler.save();
|
||||
BungeeCord.this.reconnectHandler.close();
|
||||
BungeeCord.this.saveThread.cancel();
|
||||
BungeeCord.this.reloadBanThread.cancel();
|
||||
BungeeCord.this.closeInactiveSockets.cancel();
|
||||
BungeeCord.this.authTimeoutTimer.cancel();
|
||||
BungeeCord.this.getLogger().info("Disabling plugins");
|
||||
for (final Plugin plugin : BungeeCord.this.pluginManager.getPlugins()) {
|
||||
plugin.onDisable();
|
||||
BungeeCord.this.getScheduler().cancel(plugin);
|
||||
}
|
||||
BungeeCord.this.getLogger().info("Thankyou and goodbye");
|
||||
System.exit(0);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public void broadcast(final DefinedPacket packet) {
|
||||
this.connectionLock.readLock().lock();
|
||||
try {
|
||||
for (final UserConnection con : this.connections.values()) {
|
||||
con.unsafe().sendPacket(packet);
|
||||
}
|
||||
} finally {
|
||||
this.connectionLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "BungeeCord";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return (BungeeCord.class.getPackage().getImplementationVersion() == null) ? "unknown" : BungeeCord.class.getPackage().getImplementationVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslation(final String name, Object... args) {
|
||||
String translation = "<translation '" + name + "' missing>";
|
||||
try {
|
||||
translation = this.bundle.getString(name);
|
||||
} catch (MissingResourceException ex) {
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProxiedPlayer> getPlayers() {
|
||||
this.connectionLock.readLock().lock();
|
||||
try {
|
||||
return new HashSet<ProxiedPlayer>(this.connections.values());
|
||||
} finally {
|
||||
this.connectionLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOnlineCount() {
|
||||
return this.connections.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxiedPlayer getPlayer(final String name) {
|
||||
this.connectionLock.readLock().lock();
|
||||
try {
|
||||
return this.connections.get(name);
|
||||
} finally {
|
||||
this.connectionLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ServerInfo> getServers() {
|
||||
return (Map<String, ServerInfo>) this.config.getServers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerInfo getServerInfo(final String name) {
|
||||
return this.getServers().get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerChannel(final String channel) {
|
||||
synchronized (this.pluginChannels) {
|
||||
this.pluginChannels.add(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterChannel(final String channel) {
|
||||
synchronized (this.pluginChannels) {
|
||||
this.pluginChannels.remove(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getChannels() {
|
||||
synchronized (this.pluginChannels) {
|
||||
return Collections.unmodifiableCollection((Collection<? extends String>) this.pluginChannels);
|
||||
}
|
||||
}
|
||||
|
||||
public PacketFAPluginMessage registerChannels() {
|
||||
return new PacketFAPluginMessage("REGISTER", Util.format(this.pluginChannels, "\u0000").getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getProtocolVersion() {
|
||||
return 78;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGameVersion() {
|
||||
return "1.6.4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerInfo constructServerInfo(final String name, final InetSocketAddress address, final boolean restricted) {
|
||||
return new BungeeServerInfo(name, address, restricted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSender getConsole() {
|
||||
return ConsoleCommandSender.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcast(final String message) {
|
||||
this.getConsole().sendMessage(message);
|
||||
this.broadcast(new Packet3Chat(message));
|
||||
}
|
||||
|
||||
public void addConnection(final UserConnection con) {
|
||||
this.connectionLock.writeLock().lock();
|
||||
try {
|
||||
this.connections.put(con.getName(), con);
|
||||
} finally {
|
||||
this.connectionLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeConnection(final UserConnection con) {
|
||||
this.connectionLock.writeLock().lock();
|
||||
try {
|
||||
this.connections.remove(con.getName());
|
||||
} finally {
|
||||
this.connectionLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomTabList customTabList(final ProxiedPlayer player) {
|
||||
return new Custom(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getDisabledCommands() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginManager getPluginManager() {
|
||||
return this.pluginManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReconnectHandler getReconnectHandler() {
|
||||
return this.reconnectHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReconnectHandler(final ReconnectHandler reconnectHandler) {
|
||||
this.reconnectHandler = reconnectHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationAdapter getConfigurationAdapter() {
|
||||
return this.configurationAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigurationAdapter(final ConfigurationAdapter configurationAdapter) {
|
||||
this.configurationAdapter = configurationAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getPluginsFolder() {
|
||||
return this.pluginsFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskScheduler getScheduler() {
|
||||
return this.scheduler;
|
||||
}
|
||||
|
||||
public ConsoleReader getConsoleReader() {
|
||||
return this.consoleReader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return this.logger;
|
||||
}
|
||||
}
|
||||
142
eaglerbungee/src/main/java/net/md_5/bungee/BungeeServerInfo.java
Normal file
142
eaglerbungee/src/main/java/net/md_5/bungee/BungeeServerInfo.java
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
import net.md_5.bungee.connection.PingHandler;
|
||||
import net.md_5.bungee.netty.HandlerBoss;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
|
||||
public class BungeeServerInfo implements ServerInfo {
|
||||
private final String name;
|
||||
private final InetSocketAddress address;
|
||||
private final Collection<ProxiedPlayer> players;
|
||||
private final boolean restricted;
|
||||
private final Queue<DefinedPacket> packetQueue;
|
||||
|
||||
public void addPlayer(final ProxiedPlayer player) {
|
||||
synchronized (this.players) {
|
||||
this.players.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void removePlayer(final ProxiedPlayer player) {
|
||||
synchronized (this.players) {
|
||||
this.players.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProxiedPlayer> getPlayers() {
|
||||
synchronized (this.players) {
|
||||
return Collections.unmodifiableCollection((Collection<? extends ProxiedPlayer>) this.players);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccess(final CommandSender player) {
|
||||
Preconditions.checkNotNull((Object) player, (Object) "player");
|
||||
return !this.restricted || player.hasPermission("bungeecord.server." + this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return obj instanceof ServerInfo && Objects.equals(this.getAddress(), ((ServerInfo) obj).getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.address.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(final String channel, final byte[] data) {
|
||||
Preconditions.checkNotNull((Object) channel, (Object) "channel");
|
||||
Preconditions.checkNotNull((Object) data, (Object) "data");
|
||||
final Server server = this.players.isEmpty() ? null : this.players.iterator().next().getServer();
|
||||
if (server != null) {
|
||||
server.sendData(channel, data);
|
||||
} else {
|
||||
synchronized (this.packetQueue) {
|
||||
this.packetQueue.add(new PacketFAPluginMessage(channel, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping(final Callback<ServerPing> callback) {
|
||||
Preconditions.checkNotNull((Object) callback, (Object) "callback");
|
||||
final ChannelFutureListener listener = (ChannelFutureListener) new ChannelFutureListener() {
|
||||
public void operationComplete(final ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
((HandlerBoss) future.channel().pipeline().get((Class) HandlerBoss.class)).setHandler(new PingHandler(BungeeServerInfo.this, callback));
|
||||
} else {
|
||||
callback.done(null, future.cause());
|
||||
}
|
||||
}
|
||||
};
|
||||
((Bootstrap) ((Bootstrap) ((Bootstrap) ((Bootstrap) new Bootstrap().channel((Class) NioSocketChannel.class)).group((EventLoopGroup) BungeeCord.getInstance().eventLoops)).handler((ChannelHandler) PipelineUtils.BASE))
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Integer.valueOf(5000))).remoteAddress((SocketAddress) this.getAddress()).connect().addListener((GenericFutureListener) listener);
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "name", "address", "restricted" })
|
||||
public BungeeServerInfo(final String name, final InetSocketAddress address, final boolean restricted) {
|
||||
this.players = new ArrayList<ProxiedPlayer>();
|
||||
this.packetQueue = new LinkedList<DefinedPacket>();
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.restricted = restricted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
|
||||
public boolean isRestricted() {
|
||||
return this.restricted;
|
||||
}
|
||||
|
||||
public Queue<DefinedPacket> getPacketQueue() {
|
||||
return this.packetQueue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRedirect() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConnectionThrottle
|
||||
{
|
||||
|
||||
private final Map<InetAddress, Long> throttle = new HashMap<>();
|
||||
private final int throttleTime;
|
||||
|
||||
public ConnectionThrottle(int throttleTime) {
|
||||
this.throttleTime = throttleTime;
|
||||
}
|
||||
|
||||
public void unthrottle(InetAddress address)
|
||||
{
|
||||
throttle.remove( address );
|
||||
}
|
||||
|
||||
public boolean throttle(InetAddress address)
|
||||
{
|
||||
Long value = throttle.get( address );
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
throttle.put( address, currentTime );
|
||||
return value != null && currentTime - value < throttleTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse;
|
||||
import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest;
|
||||
|
||||
/**
|
||||
* Class containing all encryption related methods for the proxy.
|
||||
*/
|
||||
public class EncryptionUtil
|
||||
{
|
||||
|
||||
private static final Random random = new Random();
|
||||
public static KeyPair keys;
|
||||
private static SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" );
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
keys = KeyPairGenerator.getInstance( "RSA" ).generateKeyPair();
|
||||
} catch ( NoSuchAlgorithmException ex )
|
||||
{
|
||||
throw new ExceptionInInitializerError( ex );
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketFDEncryptionRequest encryptRequest()
|
||||
{
|
||||
String hash = "-";
|
||||
byte[] pubKey = keys.getPublic().getEncoded();
|
||||
byte[] verify = new byte[ 4 ];
|
||||
random.nextBytes( verify );
|
||||
return new PacketFDEncryptionRequest( hash, pubKey, verify );
|
||||
}
|
||||
|
||||
public static SecretKey getSecret() {
|
||||
return EncryptionUtil.secret;
|
||||
}
|
||||
|
||||
public static SecretKey getSecret(PacketFCEncryptionResponse resp, PacketFDEncryptionRequest request) throws GeneralSecurityException
|
||||
{
|
||||
Cipher cipher = Cipher.getInstance( "RSA" );
|
||||
cipher.init( Cipher.DECRYPT_MODE, keys.getPrivate() );
|
||||
byte[] decrypted = cipher.doFinal( resp.getVerifyToken() );
|
||||
|
||||
if ( !Arrays.equals( request.getVerifyToken(), decrypted ) )
|
||||
{
|
||||
throw new IllegalStateException( "Key pairs do not match!" );
|
||||
}
|
||||
|
||||
cipher.init( Cipher.DECRYPT_MODE, keys.getPrivate() );
|
||||
return new SecretKeySpec( cipher.doFinal( resp.getSharedSecret() ), "AES" );
|
||||
}
|
||||
|
||||
public static Cipher getCipher(int opMode, Key shared) throws GeneralSecurityException
|
||||
{
|
||||
Cipher cip = Cipher.getInstance( "AES/CFB8/NoPadding" );
|
||||
cip.init( opMode, shared, new IvParameterSpec( shared.getEncoded() ) );
|
||||
return cip;
|
||||
}
|
||||
|
||||
public static PublicKey getPubkey(PacketFDEncryptionRequest request) throws GeneralSecurityException
|
||||
{
|
||||
return KeyFactory.getInstance( "RSA" ).generatePublic( new X509EncodedKeySpec( request.getPublicKey() ) );
|
||||
}
|
||||
|
||||
public static byte[] encrypt(Key key, byte[] b) throws GeneralSecurityException
|
||||
{
|
||||
Cipher hasher = Cipher.getInstance( "RSA" );
|
||||
hasher.init( Cipher.ENCRYPT_MODE, key );
|
||||
return hasher.doFinal( b );
|
||||
}
|
||||
}
|
||||
169
eaglerbungee/src/main/java/net/md_5/bungee/EntityMap.java
Normal file
169
eaglerbungee/src/main/java/net/md_5/bungee/EntityMap.java
Normal file
@@ -0,0 +1,169 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* Class to rewrite integers within packets.
|
||||
*/
|
||||
public class EntityMap
|
||||
{
|
||||
|
||||
public final static int[][] entityIds = new int[ 256 ][];
|
||||
|
||||
static
|
||||
{
|
||||
entityIds[0x05] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x07] = new int[]
|
||||
{
|
||||
1, 5
|
||||
};
|
||||
entityIds[0x11] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x12] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x13] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x14] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x16] = new int[]
|
||||
{
|
||||
1, 5
|
||||
};
|
||||
entityIds[0x17] = new int[]
|
||||
{
|
||||
1 //, 20
|
||||
};
|
||||
entityIds[0x18] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x19] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x1A] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x1C] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x1E] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x1F] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x20] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x21] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x22] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x23] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x26] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x27] = new int[]
|
||||
{
|
||||
1, 5
|
||||
};
|
||||
entityIds[0x28] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x29] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x2A] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x2C] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
entityIds[0x37] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
|
||||
entityIds[0x47] = new int[]
|
||||
{
|
||||
1
|
||||
};
|
||||
}
|
||||
|
||||
public static void rewrite(ByteBuf packet, int oldId, int newId)
|
||||
{
|
||||
int packetId = packet.getUnsignedByte( 0 );
|
||||
if ( packetId == 0x1D )
|
||||
{ // bulk entity
|
||||
for ( int pos = 2; pos < packet.readableBytes(); pos += 4 )
|
||||
{
|
||||
int readId = packet.getInt( pos );
|
||||
if ( readId == oldId )
|
||||
{
|
||||
packet.setInt( pos, newId );
|
||||
} else if ( readId == newId )
|
||||
{
|
||||
packet.setInt( pos, oldId );
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
int[] idArray = entityIds[packetId];
|
||||
if ( idArray != null )
|
||||
{
|
||||
for ( int pos : idArray )
|
||||
{
|
||||
int readId = packet.getInt( pos );
|
||||
if ( readId == oldId )
|
||||
{
|
||||
packet.setInt( pos, newId );
|
||||
} else if ( readId == newId )
|
||||
{
|
||||
packet.setInt( pos, oldId );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( packetId == 0x17 )
|
||||
{
|
||||
int type = packet.getUnsignedByte( 5 );
|
||||
if ( type == 60 || type == 90 )
|
||||
{
|
||||
int index20 = packet.getInt( 20 );
|
||||
if ( packet.readableBytes() > 24 && index20 == oldId )
|
||||
{
|
||||
packet.setInt( 20, newId );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import net.md_5.bungee.protocol.packet.Packet9Respawn;
|
||||
import net.md_5.bungee.protocol.packet.PacketCDClientStatus;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
|
||||
public class PacketConstants
|
||||
{
|
||||
|
||||
public static final Packet9Respawn DIM1_SWITCH = new Packet9Respawn( (byte) 1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" );
|
||||
public static final Packet9Respawn DIM2_SWITCH = new Packet9Respawn( (byte) -1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" );
|
||||
public static final PacketCDClientStatus CLIENT_LOGIN = new PacketCDClientStatus( (byte) 0 );
|
||||
public static final PacketFAPluginMessage FORGE_MOD_REQUEST = new PacketFAPluginMessage( "FML", new byte[]
|
||||
{
|
||||
0, 0, 0, 0, 0, 2
|
||||
} );
|
||||
public static final PacketFAPluginMessage I_AM_BUNGEE = new PacketFAPluginMessage( "BungeeCord", new byte[ 0 ] );
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||
|
||||
public class ServerConnection implements Server
|
||||
{
|
||||
|
||||
private final ChannelWrapper ch;
|
||||
private final BungeeServerInfo info;
|
||||
private boolean isObsolete;
|
||||
|
||||
private Unsafe unsafe = new Unsafe()
|
||||
{
|
||||
@Override
|
||||
public void sendPacket(DefinedPacket packet)
|
||||
{
|
||||
ch.write( packet );
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void sendData(String channel, byte[] data)
|
||||
{
|
||||
unsafe().sendPacket( new PacketFAPluginMessage( channel, data ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void disconnect(String reason)
|
||||
{
|
||||
if ( !ch.isClosed() )
|
||||
{
|
||||
// TODO: Can we just use a future here?
|
||||
unsafe().sendPacket( new PacketFFKick( reason ) );
|
||||
ch.getHandle().eventLoop().schedule( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
ch.getHandle().close();
|
||||
}
|
||||
}, 100, TimeUnit.MILLISECONDS );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getAddress()
|
||||
{
|
||||
return getInfo().getAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Unsafe unsafe()
|
||||
{
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "ch", "info" })
|
||||
public ServerConnection(final ChannelWrapper ch, final BungeeServerInfo info) {
|
||||
this.unsafe = new Connection.Unsafe() {
|
||||
@Override
|
||||
public void sendPacket(final DefinedPacket packet) {
|
||||
if (ServerConnection.this.ch != null) ServerConnection.this.ch.write(packet);
|
||||
}
|
||||
};
|
||||
this.ch = ch;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public ChannelWrapper getCh() {
|
||||
return this.ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BungeeServerInfo getInfo() {
|
||||
return this.info;
|
||||
}
|
||||
|
||||
public boolean isObsolete() {
|
||||
return this.isObsolete;
|
||||
}
|
||||
|
||||
public void setObsolete(final boolean isObsolete) {
|
||||
this.isObsolete = isObsolete;
|
||||
}
|
||||
}
|
||||
309
eaglerbungee/src/main/java/net/md_5/bungee/ServerConnector.java
Normal file
309
eaglerbungee/src/main/java/net/md_5/bungee/ServerConnector.java
Normal file
@@ -0,0 +1,309 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import java.io.DataInput;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||
import net.md_5.bungee.api.event.ServerKickEvent;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.api.score.Objective;
|
||||
import net.md_5.bungee.api.score.Scoreboard;
|
||||
import net.md_5.bungee.api.score.Team;
|
||||
import net.md_5.bungee.connection.CancelSendSignal;
|
||||
import net.md_5.bungee.connection.DownstreamBridge;
|
||||
import net.md_5.bungee.netty.HandlerBoss;
|
||||
import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.netty.CipherDecoder;
|
||||
import net.md_5.bungee.netty.CipherEncoder;
|
||||
import net.md_5.bungee.netty.PacketDecoder;
|
||||
import net.md_5.bungee.netty.PacketHandler;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
import net.md_5.bungee.protocol.Forge;
|
||||
import net.md_5.bungee.protocol.MinecraftOutput;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.Packet1Login;
|
||||
import net.md_5.bungee.protocol.packet.Packet9Respawn;
|
||||
import net.md_5.bungee.protocol.packet.PacketCEScoreboardObjective;
|
||||
import net.md_5.bungee.protocol.packet.PacketD1Team;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse;
|
||||
import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest;
|
||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||
import net.md_5.bungee.protocol.packet.forge.Forge1Login;
|
||||
|
||||
public class ServerConnector extends PacketHandler
|
||||
{
|
||||
private final ProxyServer bungee;
|
||||
private ChannelWrapper ch;
|
||||
private final UserConnection user;
|
||||
private final BungeeServerInfo target;
|
||||
private State thisState = State.ENCRYPT_REQUEST;
|
||||
private SecretKey secretkey;
|
||||
private boolean sentMessages;
|
||||
|
||||
public ServerConnector(ProxyServer bungee, UserConnection user, BungeeServerInfo target){
|
||||
this.bungee = bungee;
|
||||
this.user = user;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
private enum State
|
||||
{
|
||||
|
||||
ENCRYPT_REQUEST, ENCRYPT_RESPONSE, LOGIN, FINISHED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exception(Throwable t) throws Exception
|
||||
{
|
||||
String message = "Exception Connecting:" + Util.exception( t );
|
||||
if ( user.getServer() == null )
|
||||
{
|
||||
user.disconnect( message );
|
||||
} else
|
||||
{
|
||||
user.sendMessage( ChatColor.RED + message );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(ChannelWrapper channel) throws Exception
|
||||
{
|
||||
this.ch = channel;
|
||||
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF( "Login" );
|
||||
out.writeUTF( user.getAddress().getHostString() );
|
||||
out.writeInt( user.getAddress().getPort() );
|
||||
channel.write( new PacketFAPluginMessage( "BungeeCord", out.toByteArray() ) );
|
||||
|
||||
channel.write( user.getPendingConnection().getHandshake() );
|
||||
|
||||
// Skip encryption if we are not using Forge
|
||||
if ( user.getPendingConnection().getForgeLogin() == null )
|
||||
{
|
||||
channel.write( PacketConstants.CLIENT_LOGIN );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(ChannelWrapper channel) throws Exception
|
||||
{
|
||||
user.getPendingConnects().remove( target );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Packet1Login login) throws Exception
|
||||
{
|
||||
Preconditions.checkState( thisState == State.LOGIN, "Not exepcting LOGIN" );
|
||||
|
||||
ServerConnection server = new ServerConnection( ch, target );
|
||||
ServerConnectedEvent event = new ServerConnectedEvent( user, server );
|
||||
bungee.getPluginManager().callEvent( event );
|
||||
|
||||
ch.write( BungeeCord.getInstance().registerChannels() );
|
||||
Queue<DefinedPacket> packetQueue = target.getPacketQueue();
|
||||
synchronized ( packetQueue )
|
||||
{
|
||||
while ( !packetQueue.isEmpty() )
|
||||
{
|
||||
ch.write( packetQueue.poll() );
|
||||
}
|
||||
}
|
||||
|
||||
for ( PacketFAPluginMessage message : user.getPendingConnection().getRegisterMessages() )
|
||||
{
|
||||
ch.write( message );
|
||||
}
|
||||
if ( !sentMessages )
|
||||
{
|
||||
for ( PacketFAPluginMessage message : user.getPendingConnection().getLoginMessages() )
|
||||
{
|
||||
ch.write( message );
|
||||
}
|
||||
}
|
||||
|
||||
if ( user.getSettings() != null )
|
||||
{
|
||||
ch.write( user.getSettings() );
|
||||
}
|
||||
|
||||
synchronized ( user.getSwitchMutex() )
|
||||
{
|
||||
if ( user.getServer() == null )
|
||||
{
|
||||
// Once again, first connection
|
||||
user.setClientEntityId( login.getEntityId() );
|
||||
user.setServerEntityId( login.getEntityId() );
|
||||
|
||||
// Set tab list size, this sucks balls, TODO: what shall we do about packet mutability
|
||||
Packet1Login modLogin;
|
||||
if ( ch.getHandle().pipeline().get( PacketDecoder.class ).getProtocol() == Forge.getInstance() )
|
||||
{
|
||||
modLogin = new Forge1Login( login.getEntityId(), login.getLevelType(), login.getGameMode(), login.getDimension(), login.getDifficulty(), login.getUnused(),
|
||||
(byte) user.getPendingConnection().getListener().getTabListSize() );
|
||||
} else
|
||||
{
|
||||
modLogin = new Packet1Login( login.getEntityId(), login.getLevelType(), login.getGameMode(), (byte) login.getDimension(), login.getDifficulty(), login.getUnused(),
|
||||
(byte) user.getPendingConnection().getListener().getTabListSize() );
|
||||
}
|
||||
user.unsafe().sendPacket( modLogin );
|
||||
|
||||
MinecraftOutput out = new MinecraftOutput();
|
||||
out.writeStringUTF8WithoutLengthHeaderBecauseDinnerboneStuffedUpTheMCBrandPacket( ProxyServer.getInstance().getName() + " (" + ProxyServer.getInstance().getVersion() + ")" );
|
||||
user.unsafe().sendPacket( new PacketFAPluginMessage( "MC|Brand", out.toArray() ) );
|
||||
} else
|
||||
{
|
||||
user.getTabList().onServerChange();
|
||||
|
||||
Scoreboard serverScoreboard = user.getServerSentScoreboard();
|
||||
for ( Objective objective : serverScoreboard.getObjectives() )
|
||||
{
|
||||
user.unsafe().sendPacket( new PacketCEScoreboardObjective( objective.getName(), objective.getValue(), (byte) 1 ) );
|
||||
}
|
||||
for ( Team team : serverScoreboard.getTeams() )
|
||||
{
|
||||
user.unsafe().sendPacket( new PacketD1Team( team.getName() ) );
|
||||
}
|
||||
serverScoreboard.clear();
|
||||
|
||||
user.sendDimensionSwitch();
|
||||
|
||||
user.setServerEntityId( login.getEntityId() );
|
||||
user.unsafe().sendPacket( new Packet9Respawn( login.getDimension(), login.getDifficulty(), login.getGameMode(), (short) 256, login.getLevelType() ) );
|
||||
|
||||
// Remove from old servers
|
||||
user.getServer().setObsolete( true );
|
||||
user.getServer().disconnect( "Quitting" );
|
||||
}
|
||||
|
||||
// TODO: Fix this?
|
||||
if ( !user.isActive() )
|
||||
{
|
||||
server.disconnect( "Quitting" );
|
||||
// Silly server admins see stack trace and die
|
||||
bungee.getLogger().warning( "No client connected for pending server!" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to new server
|
||||
// TODO: Move this to the connected() method of DownstreamBridge
|
||||
target.addPlayer( user );
|
||||
user.getPendingConnects().remove( target );
|
||||
|
||||
user.setServer( server );
|
||||
ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new DownstreamBridge( bungee, user, server ) );
|
||||
}
|
||||
|
||||
bungee.getPluginManager().callEvent( new ServerSwitchEvent( user ) );
|
||||
|
||||
thisState = State.FINISHED;
|
||||
|
||||
throw new CancelSendSignal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketFDEncryptionRequest encryptRequest) throws Exception
|
||||
{
|
||||
Preconditions.checkState( thisState == State.ENCRYPT_REQUEST, "Not expecting ENCRYPT_REQUEST" );
|
||||
|
||||
// Only need to handle this if we want to use encryption
|
||||
if ( user.getPendingConnection().getForgeLogin() != null )
|
||||
{
|
||||
PublicKey publickey = EncryptionUtil.getPubkey( encryptRequest );
|
||||
this.secretkey = EncryptionUtil.getSecret();
|
||||
|
||||
byte[] shared = EncryptionUtil.encrypt( publickey, secretkey.getEncoded() );
|
||||
byte[] token = EncryptionUtil.encrypt( publickey, encryptRequest.getVerifyToken() );
|
||||
|
||||
ch.write( new PacketFCEncryptionResponse( shared, token ) );
|
||||
|
||||
Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, secretkey );
|
||||
ch.addBefore( PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.ENCRYPT_HANDLER, new CipherEncoder( encrypt ) );
|
||||
|
||||
thisState = State.ENCRYPT_RESPONSE;
|
||||
} else
|
||||
{
|
||||
thisState = State.LOGIN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketFCEncryptionResponse encryptResponse) throws Exception
|
||||
{
|
||||
Preconditions.checkState( thisState == State.ENCRYPT_RESPONSE, "Not expecting ENCRYPT_RESPONSE" );
|
||||
|
||||
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, secretkey );
|
||||
ch.addBefore( PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) );
|
||||
|
||||
ch.write( user.getPendingConnection().getForgeLogin() );
|
||||
|
||||
ch.write( PacketConstants.CLIENT_LOGIN );
|
||||
thisState = State.LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketFFKick kick) throws Exception
|
||||
{
|
||||
ServerInfo def = bungee.getServerInfo( user.getPendingConnection().getListener().getFallbackServer() );
|
||||
if ( Objects.equals( target, def ) )
|
||||
{
|
||||
def = null;
|
||||
}
|
||||
ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( user, kick.getMessage(), def, ServerKickEvent.State.CONNECTING ) );
|
||||
if ( event.isCancelled() && event.getCancelServer() != null )
|
||||
{
|
||||
user.connect( event.getCancelServer() );
|
||||
return;
|
||||
}
|
||||
|
||||
String message = bungee.getTranslation( "connect_kick" ) + target.getName() + ": " + event.getKickReason();
|
||||
if ( user.getServer() == null )
|
||||
{
|
||||
user.disconnect( message );
|
||||
} else
|
||||
{
|
||||
user.sendMessage( message );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final PacketFAPluginMessage pluginMessage) throws Exception {
|
||||
if (pluginMessage.equals(PacketConstants.I_AM_BUNGEE) && !BungeeCord.getInstance().config.allowBungeeOnBungee()) {
|
||||
throw new IllegalStateException("May not connect to another BungeeCord!");
|
||||
}
|
||||
if (pluginMessage.getTag().equals("FML") && (pluginMessage.getData()[0] & 0xFF) == 0x0) {
|
||||
final ByteArrayDataInput in = ByteStreams.newDataInput(pluginMessage.getData());
|
||||
in.readUnsignedByte();
|
||||
for (int count = in.readInt(), i = 0; i < count; ++i) {
|
||||
in.readUTF();
|
||||
}
|
||||
if (in.readByte() != 0) {
|
||||
((PacketDecoder)this.ch.getHandle().pipeline().get((Class)PacketDecoder.class)).setProtocol(Forge.getInstance());
|
||||
}
|
||||
}
|
||||
this.user.unsafe().sendPacket(pluginMessage);
|
||||
if (!this.sentMessages && this.user.getPendingConnection().getForgeLogin() != null) {
|
||||
for (final PacketFAPluginMessage message : this.user.getPendingConnection().getLoginMessages()) {
|
||||
this.ch.write(message);
|
||||
}
|
||||
this.sentMessages = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "[" + user.getName() + "] <-> ServerConnector [" + target.getName() + "]";
|
||||
}
|
||||
}
|
||||
447
eaglerbungee/src/main/java/net/md_5/bungee/UserConnection.java
Normal file
447
eaglerbungee/src/main/java/net/md_5/bungee/UserConnection.java
Normal file
@@ -0,0 +1,447 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PermissionCheckEvent;
|
||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||
import net.md_5.bungee.api.score.Scoreboard;
|
||||
import net.md_5.bungee.api.tab.TabListHandler;
|
||||
import net.md_5.bungee.connection.InitialHandler;
|
||||
import net.md_5.bungee.eaglercraft.RedirectServerInfo;
|
||||
import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.netty.HandlerBoss;
|
||||
import net.md_5.bungee.netty.PacketWrapper;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
||||
import net.md_5.bungee.protocol.packet.PacketCCSettings;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||
import net.md_5.bungee.util.CaseInsensitiveSet;
|
||||
|
||||
public final class UserConnection implements ProxiedPlayer
|
||||
{
|
||||
|
||||
/*========================================================================*/
|
||||
private final ProxyServer bungee;
|
||||
private final ChannelWrapper ch;
|
||||
private final String name;
|
||||
private final InitialHandler pendingConnection;
|
||||
/*========================================================================*/
|
||||
private ServerConnection server;
|
||||
private Object switchMutex = new Object();
|
||||
private Collection<ServerInfo> pendingConnects = new HashSet<>();
|
||||
/*========================================================================*/
|
||||
private TabListHandler tabList;
|
||||
private int sentPingId;
|
||||
|
||||
private long sentPingTime;
|
||||
private int ping = 100;
|
||||
private ServerInfo reconnectServer;
|
||||
/*========================================================================*/
|
||||
private Collection<String> groups = new CaseInsensitiveSet();
|
||||
private Collection<String> permissions = new CaseInsensitiveSet();
|
||||
/*========================================================================*/
|
||||
|
||||
|
||||
private int serverEntityId;
|
||||
private PacketCCSettings settings;
|
||||
|
||||
private Scoreboard serverSentScoreboard = new Scoreboard();
|
||||
/*========================================================================*/
|
||||
|
||||
private String displayName;
|
||||
/*========================================================================*/
|
||||
|
||||
private int clientEntityId;
|
||||
|
||||
public void setServer(ServerConnection server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void setSettings(PacketCCSettings settings){
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void setServerEntityId(int serverEntityId) {
|
||||
this.serverEntityId = serverEntityId;
|
||||
}
|
||||
|
||||
public void setSentPingId(int sentPingId) {
|
||||
this.sentPingId = sentPingId;
|
||||
}
|
||||
|
||||
public void setSentPingTime(long sentPingTime) {
|
||||
this.sentPingTime = sentPingTime;
|
||||
}
|
||||
|
||||
public void setPing(int ping) {
|
||||
this.ping = ping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReconnectServer(ServerInfo reconnectServer) {
|
||||
this.reconnectServer = reconnectServer;
|
||||
}
|
||||
|
||||
public void setClientEntityId(int clientEntityId) {
|
||||
this.clientEntityId = clientEntityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InitialHandler getPendingConnection() {
|
||||
return pendingConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabListHandler getTabList() {
|
||||
return tabList;
|
||||
}
|
||||
|
||||
public Collection<ServerInfo> getPendingConnects() {
|
||||
return pendingConnects;
|
||||
}
|
||||
|
||||
public Object getSwitchMutex() {
|
||||
return switchMutex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerConnection getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public int getSentPingId() {
|
||||
return sentPingId;
|
||||
}
|
||||
|
||||
public long getSentPingTime() {
|
||||
return sentPingTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPing() {
|
||||
return ping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerInfo getReconnectServer() {
|
||||
return reconnectServer;
|
||||
}
|
||||
|
||||
public Collection<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public int getClientEntityId() {
|
||||
return clientEntityId;
|
||||
}
|
||||
|
||||
public int getServerEntityId() {
|
||||
return serverEntityId;
|
||||
}
|
||||
|
||||
public PacketCCSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public Scoreboard getServerSentScoreboard() {
|
||||
return serverSentScoreboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
private Unsafe unsafe = new Unsafe()
|
||||
{
|
||||
@Override
|
||||
public void sendPacket(DefinedPacket packet)
|
||||
{
|
||||
ch.write( packet );
|
||||
}
|
||||
};
|
||||
|
||||
@ConstructorProperties({ "bungee", "ch", "name", "pendingConnection" })
|
||||
public UserConnection(final ProxyServer bungee, final ChannelWrapper ch, final String name, final InitialHandler pendingConnection) {
|
||||
this.switchMutex = new Object();
|
||||
this.pendingConnects = new HashSet<ServerInfo>();
|
||||
this.ping = 100;
|
||||
this.groups = (Collection<String>) new CaseInsensitiveSet();
|
||||
this.permissions = (Collection<String>) new CaseInsensitiveSet();
|
||||
this.serverSentScoreboard = new Scoreboard();
|
||||
this.unsafe = new Connection.Unsafe() {
|
||||
@Override
|
||||
public void sendPacket(final DefinedPacket packet) {
|
||||
UserConnection.this.ch.write(packet);
|
||||
}
|
||||
};
|
||||
if (bungee == null) {
|
||||
throw new NullPointerException("bungee");
|
||||
}
|
||||
if (ch == null) {
|
||||
throw new NullPointerException("ch");
|
||||
}
|
||||
if (name == null) {
|
||||
throw new NullPointerException("name");
|
||||
}
|
||||
this.bungee = bungee;
|
||||
this.ch = ch;
|
||||
this.name = name;
|
||||
this.pendingConnection = pendingConnection;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
this.displayName = name;
|
||||
try
|
||||
{
|
||||
this.tabList = getPendingConnection().getListener().getTabList().getDeclaredConstructor().newInstance();
|
||||
} catch ( ReflectiveOperationException ex )
|
||||
{
|
||||
throw new RuntimeException( ex );
|
||||
}
|
||||
this.tabList.init( this );
|
||||
|
||||
Collection<String> g = bungee.getConfigurationAdapter().getGroups( name );
|
||||
for ( String s : g )
|
||||
{
|
||||
addGroups( s );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTabList(TabListHandler tabList)
|
||||
{
|
||||
tabList.init( this );
|
||||
this.tabList = tabList;
|
||||
}
|
||||
|
||||
public void sendPacket(PacketWrapper packet)
|
||||
{
|
||||
ch.write( packet );
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isActive()
|
||||
{
|
||||
return !ch.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayName(String name)
|
||||
{
|
||||
Preconditions.checkNotNull( name, "displayName" );
|
||||
Preconditions.checkArgument( name.length() <= 16, "Display name cannot be longer than 16 characters" );
|
||||
getTabList().onDisconnect();
|
||||
displayName = name;
|
||||
getTabList().onConnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(ServerInfo target)
|
||||
{
|
||||
connect( target, false );
|
||||
}
|
||||
|
||||
void sendDimensionSwitch()
|
||||
{
|
||||
unsafe().sendPacket( PacketConstants.DIM1_SWITCH );
|
||||
unsafe().sendPacket( PacketConstants.DIM2_SWITCH );
|
||||
}
|
||||
|
||||
public void connectNow(ServerInfo target)
|
||||
{
|
||||
sendDimensionSwitch();
|
||||
connect( target );
|
||||
}
|
||||
|
||||
public void connect(final ServerInfo info, final boolean retry) {
|
||||
if(info instanceof RedirectServerInfo) {
|
||||
sendData("EAG|Reconnect", ((RedirectServerInfo)info).getRedirect().getBytes(StandardCharsets.UTF_8));
|
||||
return;
|
||||
}
|
||||
final ServerConnectEvent event = new ServerConnectEvent(this, info);
|
||||
if (this.bungee.getPluginManager().callEvent(event).isCancelled()) {
|
||||
return;
|
||||
}
|
||||
final BungeeServerInfo target = (BungeeServerInfo) event.getTarget();
|
||||
if (this.getServer() != null && this.getServer().getInfo() != null && Objects.equals(this.getServer().getInfo(), target)) {
|
||||
//this.sendMessage(ChatColor.RED + "Cannot connect to server you are already on!");
|
||||
return;
|
||||
}
|
||||
if (this.pendingConnects.contains(target)) {
|
||||
this.sendMessage(ChatColor.RED + "Already connecting to this server!");
|
||||
return;
|
||||
}
|
||||
this.pendingConnects.add(target);
|
||||
final ChannelInitializer initializer = new ChannelInitializer() {
|
||||
protected void initChannel(final Channel ch) throws Exception {
|
||||
PipelineUtils.BASE.initChannel(ch);
|
||||
((HandlerBoss) ch.pipeline().get((Class) HandlerBoss.class)).setHandler(new ServerConnector(UserConnection.this.bungee, UserConnection.this, target));
|
||||
}
|
||||
};
|
||||
final ChannelFutureListener listener = (ChannelFutureListener) new ChannelFutureListener() {
|
||||
public void operationComplete(final ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
future.channel().close();
|
||||
UserConnection.this.pendingConnects.remove(target);
|
||||
final ServerInfo def = ProxyServer.getInstance().getServers().get(UserConnection.this.getPendingConnection().getListener().getFallbackServer());
|
||||
if ((retry & target != def) && ((UserConnection.this.getServer() == null || UserConnection.this.getServer().getInfo() == null) || def != UserConnection.this.getServer().getInfo())) {
|
||||
UserConnection.this.sendMessage(UserConnection.this.bungee.getTranslation("fallback_lobby"));
|
||||
UserConnection.this.connect(def, false);
|
||||
} else if (UserConnection.this.getServer() == null || UserConnection.this.getServer().getInfo() == null) {
|
||||
UserConnection.this.disconnect(UserConnection.this.bungee.getTranslation("fallback_kick") + future.cause().getClass().getName());
|
||||
} else {
|
||||
UserConnection.this.sendMessage(UserConnection.this.bungee.getTranslation("fallback_kick") + future.cause().getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
final Bootstrap b = ((Bootstrap) ((Bootstrap) ((Bootstrap) ((Bootstrap) new Bootstrap().channel((Class) NioSocketChannel.class)).group((EventLoopGroup) BungeeCord.getInstance().eventLoops)).handler((ChannelHandler) initializer))
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Integer.valueOf(5000))).remoteAddress((SocketAddress) target.getAddress());
|
||||
if (!PlatformDependent.isWindows()) {
|
||||
b.localAddress(this.getPendingConnection().getListener().getHost().getHostString(), 0);
|
||||
}
|
||||
b.connect().addListener((GenericFutureListener) listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void disconnect(String reason)
|
||||
{
|
||||
if ( ch.getHandle().isActive() )
|
||||
{
|
||||
bungee.getLogger().log( Level.INFO, "[" + getName() + "] disconnected with: " + reason );
|
||||
unsafe().sendPacket( new PacketFFKick( reason ) );
|
||||
ch.close();
|
||||
if ( server != null )
|
||||
{
|
||||
server.disconnect( "Quitting" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chat(String message)
|
||||
{
|
||||
Preconditions.checkState( server != null, "Not connected to server" );
|
||||
server.getCh().write( new Packet3Chat( message ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message)
|
||||
{
|
||||
this.unsafe().sendPacket(new Packet3Chat(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessages(String... messages)
|
||||
{
|
||||
for ( String message : messages )
|
||||
{
|
||||
sendMessage( message );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendData(String channel, byte[] data)
|
||||
{
|
||||
unsafe().sendPacket( new PacketFAPluginMessage( channel, data ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getAddress()
|
||||
{
|
||||
return (InetSocketAddress) ch.getHandle().remoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getGroups()
|
||||
{
|
||||
return Collections.unmodifiableCollection( groups );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroups(String... groups)
|
||||
{
|
||||
for ( String group : groups )
|
||||
{
|
||||
this.groups.add( group );
|
||||
for ( String permission : bungee.getConfigurationAdapter().getPermissions( group ) )
|
||||
{
|
||||
setPermission( permission, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroups(String... groups)
|
||||
{
|
||||
for ( String group : groups )
|
||||
{
|
||||
this.groups.remove( group );
|
||||
for ( String permission : bungee.getConfigurationAdapter().getPermissions( group ) )
|
||||
{
|
||||
setPermission( permission, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission)
|
||||
{
|
||||
return bungee.getPluginManager().callEvent( new PermissionCheckEvent( this, permission, permissions.contains( permission ) ) ).hasPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermission(String permission, boolean value)
|
||||
{
|
||||
if ( value )
|
||||
{
|
||||
permissions.add( permission );
|
||||
} else
|
||||
{
|
||||
permissions.remove( permission );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttachment() { // fix this (maybe)
|
||||
System.out.println("This might be a problem");
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Unsafe unsafe()
|
||||
{
|
||||
return unsafe;
|
||||
}
|
||||
}
|
||||
73
eaglerbungee/src/main/java/net/md_5/bungee/Util.java
Normal file
73
eaglerbungee/src/main/java/net/md_5/bungee/Util.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Series of utility classes to perform various operations.
|
||||
*/
|
||||
public class Util
|
||||
{
|
||||
|
||||
private static final int DEFAULT_PORT = 25565;
|
||||
|
||||
/**
|
||||
* Method to transform human readable addresses into usable address objects.
|
||||
*
|
||||
* @param hostline in the format of 'host:port'
|
||||
* @return the constructed hostname + port.
|
||||
*/
|
||||
public static InetSocketAddress getAddr(String hostline)
|
||||
{
|
||||
String[] split = hostline.split( ":" );
|
||||
int port = DEFAULT_PORT;
|
||||
if ( split.length > 1 )
|
||||
{
|
||||
port = Integer.parseInt( split[1] );
|
||||
}
|
||||
return new InetSocketAddress( split[0], port );
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an integer as a hex value.
|
||||
*
|
||||
* @param i the integer to format
|
||||
* @return the hex representation of the integer
|
||||
*/
|
||||
public static String hex(int i)
|
||||
{
|
||||
return String.format( "0x%02X", i );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a pretty one line version of a {@link Throwable}. Useful for
|
||||
* debugging.
|
||||
*
|
||||
* @param t the {@link Throwable} to format.
|
||||
* @return a string representing information about the {@link Throwable}
|
||||
*/
|
||||
public static String exception(Throwable t)
|
||||
{
|
||||
// TODO: We should use clear manually written exceptions
|
||||
StackTraceElement[] trace = t.getStackTrace();
|
||||
return t.getClass().getSimpleName() + " : " + t.getMessage()
|
||||
+ ( ( trace.length > 0 ) ? " @ " + t.getStackTrace()[0].getClassName() + ":" + t.getStackTrace()[0].getLineNumber() : "" );
|
||||
}
|
||||
|
||||
public static String csv(Iterable<?> objects)
|
||||
{
|
||||
return format( objects, ", " );
|
||||
}
|
||||
|
||||
public static String format(Iterable<?> objects, String separators)
|
||||
{
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for ( Object o : objects )
|
||||
{
|
||||
ret.append( o );
|
||||
ret.append( separators );
|
||||
}
|
||||
|
||||
return ( ret.length() == 0 ) ? "" : ret.substring( 0, ret.length() - separators.length() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public abstract class AbstractReconnectHandler implements ReconnectHandler
|
||||
{
|
||||
|
||||
@Override
|
||||
public ServerInfo getServer(ProxiedPlayer player)
|
||||
{
|
||||
ServerInfo server = getForcedHost( player.getPendingConnection() );
|
||||
if ( server == null )
|
||||
{
|
||||
server = getStoredServer( player );
|
||||
if ( server == null )
|
||||
{
|
||||
server = ProxyServer.getInstance().getServerInfo( player.getPendingConnection().getListener().getDefaultServer() );
|
||||
}
|
||||
|
||||
Preconditions.checkState( server != null, "Default server not defined" );
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
public static ServerInfo getForcedHost(PendingConnection con)
|
||||
{
|
||||
if ( con.getVirtualHost() == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
|
||||
|
||||
if ( forced == null && con.getListener().isForceDefault() )
|
||||
{
|
||||
forced = con.getListener().getDefaultServer();
|
||||
}
|
||||
return ProxyServer.getInstance().getServerInfo( forced );
|
||||
}
|
||||
|
||||
protected abstract ServerInfo getStoredServer(ProxiedPlayer player);
|
||||
}
|
||||
19
eaglerbungee/src/main/java/net/md_5/bungee/api/Callback.java
Normal file
19
eaglerbungee/src/main/java/net/md_5/bungee/api/Callback.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
/**
|
||||
* Represents a method which may be called once a result has been computed
|
||||
* asynchronously.
|
||||
*
|
||||
* @param <V> the type of result
|
||||
*/
|
||||
public interface Callback<V>
|
||||
{
|
||||
|
||||
/**
|
||||
* Called when the result is done.
|
||||
*
|
||||
* @param result the result of the computation
|
||||
* @param error the error(s) that occurred, if any
|
||||
*/
|
||||
public void done(V result, Throwable error);
|
||||
}
|
||||
186
eaglerbungee/src/main/java/net/md_5/bungee/api/ChatColor.java
Normal file
186
eaglerbungee/src/main/java/net/md_5/bungee/api/ChatColor.java
Normal file
@@ -0,0 +1,186 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Simplistic enumeration of all supported color values for chat.
|
||||
*/
|
||||
public enum ChatColor
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents black.
|
||||
*/
|
||||
BLACK( '0' ),
|
||||
/**
|
||||
* Represents dark blue.
|
||||
*/
|
||||
DARK_BLUE( '1' ),
|
||||
/**
|
||||
* Represents dark green.
|
||||
*/
|
||||
DARK_GREEN( '2' ),
|
||||
/**
|
||||
* Represents dark blue (aqua).
|
||||
*/
|
||||
DARK_AQUA( '3' ),
|
||||
/**
|
||||
* Represents dark red.
|
||||
*/
|
||||
DARK_RED( '4' ),
|
||||
/**
|
||||
* Represents dark purple.
|
||||
*/
|
||||
DARK_PURPLE( '5' ),
|
||||
/**
|
||||
* Represents gold.
|
||||
*/
|
||||
GOLD( '6' ),
|
||||
/**
|
||||
* Represents gray.
|
||||
*/
|
||||
GRAY( '7' ),
|
||||
/**
|
||||
* Represents dark gray.
|
||||
*/
|
||||
DARK_GRAY( '8' ),
|
||||
/**
|
||||
* Represents blue.
|
||||
*/
|
||||
BLUE( '9' ),
|
||||
/**
|
||||
* Represents green.
|
||||
*/
|
||||
GREEN( 'a' ),
|
||||
/**
|
||||
* Represents aqua.
|
||||
*/
|
||||
AQUA( 'b' ),
|
||||
/**
|
||||
* Represents red.
|
||||
*/
|
||||
RED( 'c' ),
|
||||
/**
|
||||
* Represents light purple.
|
||||
*/
|
||||
LIGHT_PURPLE( 'd' ),
|
||||
/**
|
||||
* Represents yellow.
|
||||
*/
|
||||
YELLOW( 'e' ),
|
||||
/**
|
||||
* Represents white.
|
||||
*/
|
||||
WHITE( 'f' ),
|
||||
/**
|
||||
* Represents magical characters that change around randomly.
|
||||
*/
|
||||
MAGIC( 'k' ),
|
||||
/**
|
||||
* Makes the text bold.
|
||||
*/
|
||||
BOLD( 'l' ),
|
||||
/**
|
||||
* Makes a line appear through the text.
|
||||
*/
|
||||
STRIKETHROUGH( 'm' ),
|
||||
/**
|
||||
* Makes the text appear underlined.
|
||||
*/
|
||||
UNDERLINE( 'n' ),
|
||||
/**
|
||||
* Makes the text italic.
|
||||
*/
|
||||
ITALIC( 'o' ),
|
||||
/**
|
||||
* Resets all previous chat colors or formats.
|
||||
*/
|
||||
RESET( 'r' );
|
||||
/**
|
||||
* The special character which prefixes all chat colour codes. Use this if
|
||||
* you need to dynamically convert colour codes from your custom format.
|
||||
*/
|
||||
public static final char COLOR_CHAR = '\u00A7';
|
||||
/**
|
||||
* Pattern to remove all colour codes.
|
||||
*/
|
||||
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile( "(?i)" + String.valueOf( COLOR_CHAR ) + "[0-9A-FK-OR]" );
|
||||
/**
|
||||
* Colour instances keyed by their active character.
|
||||
*/
|
||||
private static final Map<Character, ChatColor> BY_CHAR = new HashMap<>();
|
||||
/**
|
||||
* The code appended to {@link #COLOR_CHAR} to make usable colour.
|
||||
*/
|
||||
private final char code;
|
||||
/**
|
||||
* This colour's colour char prefixed by the {@link #COLOR_CHAR}.
|
||||
*/
|
||||
private final String toString;
|
||||
|
||||
static
|
||||
{
|
||||
for ( ChatColor colour : values() )
|
||||
{
|
||||
BY_CHAR.put( colour.code, colour );
|
||||
}
|
||||
}
|
||||
|
||||
private ChatColor(char code)
|
||||
{
|
||||
this.code = code;
|
||||
this.toString = new String( new char[]
|
||||
{
|
||||
COLOR_CHAR, code
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the given message of all color codes
|
||||
*
|
||||
* @param input String to strip of color
|
||||
* @return A copy of the input string, without any coloring
|
||||
*/
|
||||
public static String stripColor(final String input)
|
||||
{
|
||||
if ( input == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return STRIP_COLOR_PATTERN.matcher( input ).replaceAll( "" );
|
||||
}
|
||||
|
||||
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate)
|
||||
{
|
||||
char[] b = textToTranslate.toCharArray();
|
||||
for ( int i = 0; i < b.length - 1; i++ )
|
||||
{
|
||||
if ( b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf( b[i + 1] ) > -1 )
|
||||
{
|
||||
b[i] = ChatColor.COLOR_CHAR;
|
||||
b[i + 1] = Character.toLowerCase( b[i + 1] );
|
||||
}
|
||||
}
|
||||
return new String( b );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the colour represented by the specified code.
|
||||
*
|
||||
* @param code the code to search for
|
||||
* @return the mapped colour, or null if non exists
|
||||
*/
|
||||
public static ChatColor getByChar(char code)
|
||||
{
|
||||
return BY_CHAR.get( code );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
public interface CommandSender
|
||||
{
|
||||
|
||||
/**
|
||||
* Get the unique name of this command sender.
|
||||
*
|
||||
* @return the senders username
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Send a message to this sender.
|
||||
*
|
||||
* @param message the message to send
|
||||
*/
|
||||
public void sendMessage(String message);
|
||||
|
||||
/**
|
||||
* Send several messages to this sender. Each message will be sent
|
||||
* separately.
|
||||
*
|
||||
* @param messages the messages to send
|
||||
*/
|
||||
public void sendMessages(String... messages);
|
||||
|
||||
/**
|
||||
* Get all groups this user is part of. This returns an unmodifiable
|
||||
* collection.
|
||||
*
|
||||
* @return the users groups
|
||||
*/
|
||||
public Collection<String> getGroups();
|
||||
|
||||
/**
|
||||
* Adds groups to a this user for the current session only.
|
||||
*
|
||||
* @param groups the groups to add
|
||||
*/
|
||||
public void addGroups(String... groups);
|
||||
|
||||
/**
|
||||
* Remove groups from this user for the current session only.
|
||||
*
|
||||
* @param groups the groups to remove
|
||||
*/
|
||||
public void removeGroups(String... groups);
|
||||
|
||||
/**
|
||||
* Checks if this user has the specified permission node.
|
||||
*
|
||||
* @param permission the node to check
|
||||
* @return whether they have this node
|
||||
*/
|
||||
public boolean hasPermission(String permission);
|
||||
|
||||
/**
|
||||
* Set a permission node for this user.
|
||||
*
|
||||
* @param permission the node to set
|
||||
* @param value the value of the node
|
||||
*/
|
||||
public void setPermission(String permission, boolean value);
|
||||
|
||||
Map<String, Object> getAttachment();
|
||||
}
|
||||
25
eaglerbungee/src/main/java/net/md_5/bungee/api/MOTD.java
Normal file
25
eaglerbungee/src/main/java/net/md_5/bungee/api/MOTD.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface MOTD extends QueryConnection {
|
||||
|
||||
public void sendToUser();
|
||||
|
||||
public String getLine1();
|
||||
public String getLine2();
|
||||
public List<String> getPlayerList();
|
||||
public int[] getBitmap();
|
||||
public int getOnlinePlayers();
|
||||
public int getMaxPlayers();
|
||||
public String getSubType();
|
||||
|
||||
public void setLine1(String p);
|
||||
public void setLine2(String p);
|
||||
public void setPlayerList(List<String> p);
|
||||
public void setPlayerList(String... p);
|
||||
public void setBitmap(int[] p);
|
||||
public void setOnlinePlayers(int i);
|
||||
public void setMaxPlayers(int i);
|
||||
|
||||
}
|
||||
251
eaglerbungee/src/main/java/net/md_5/bungee/api/ProxyServer.java
Normal file
251
eaglerbungee/src/main/java/net/md_5/bungee/api/ProxyServer.java
Normal file
@@ -0,0 +1,251 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import net.md_5.bungee.api.plugin.PluginManager;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
||||
import net.md_5.bungee.api.tab.CustomTabList;
|
||||
|
||||
public abstract class ProxyServer
|
||||
{
|
||||
|
||||
private static ProxyServer instance;
|
||||
|
||||
public static ProxyServer getInstance(){
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the proxy instance. This method may only be called once per an
|
||||
* application.
|
||||
*
|
||||
* @param instance the new instance to set
|
||||
*/
|
||||
public static void setInstance(ProxyServer instance)
|
||||
{
|
||||
Preconditions.checkNotNull( instance, "instance" );
|
||||
Preconditions.checkArgument( ProxyServer.instance == null, "Instance already set" );
|
||||
ProxyServer.instance = instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the currently running proxy software.
|
||||
*
|
||||
* @return the name of this instance
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Gets the version of the currently running proxy software.
|
||||
*
|
||||
* @return the version of this instance
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* Gets a localized string from the .properties file.
|
||||
*
|
||||
* @return the localized string
|
||||
*/
|
||||
public abstract String getTranslation(String name, Object... args);
|
||||
|
||||
/**
|
||||
* Gets the main logger which can be used as a suitable replacement for
|
||||
* {@link System#out} and {@link System#err}.
|
||||
*
|
||||
* @return the {@link Logger} instance
|
||||
*/
|
||||
public abstract Logger getLogger();
|
||||
|
||||
/**
|
||||
* Return all players currently connected.
|
||||
*
|
||||
* @return all connected players
|
||||
*/
|
||||
public abstract Collection<ProxiedPlayer> getPlayers();
|
||||
|
||||
/**
|
||||
* Gets a connected player via their unique username.
|
||||
*
|
||||
* @param name of the player
|
||||
* @return their player instance
|
||||
*/
|
||||
public abstract ProxiedPlayer getPlayer(String name);
|
||||
|
||||
/**
|
||||
* Return all servers registered to this proxy, keyed by name. Unlike the
|
||||
* methods in {@link ConfigurationAdapter#getServers()}, this will not
|
||||
* return a fresh map each time.
|
||||
*
|
||||
* @return all registered remote server destinations
|
||||
*/
|
||||
public abstract Map<String, ServerInfo> getServers();
|
||||
|
||||
/**
|
||||
* Gets the server info of a server.
|
||||
*
|
||||
* @param name the name of the configured server
|
||||
* @return the server info belonging to the specified server
|
||||
*/
|
||||
public abstract ServerInfo getServerInfo(String name);
|
||||
|
||||
/**
|
||||
* Get the {@link PluginManager} associated with loading plugins and
|
||||
* dispatching events. It is recommended that implementations use the
|
||||
* provided PluginManager class.
|
||||
*
|
||||
* @return the plugin manager
|
||||
*/
|
||||
public abstract PluginManager getPluginManager();
|
||||
|
||||
/**
|
||||
* Returns the currently in use configuration adapter.
|
||||
*
|
||||
* @return the used configuration adapter
|
||||
*/
|
||||
public abstract ConfigurationAdapter getConfigurationAdapter();
|
||||
|
||||
/**
|
||||
* Set the configuration adapter to be used. Must be called from
|
||||
* {@link Plugin#onLoad()}.
|
||||
*
|
||||
* @param adapter the adapter to use
|
||||
*/
|
||||
public abstract void setConfigurationAdapter(ConfigurationAdapter adapter);
|
||||
|
||||
/**
|
||||
* Get the currently in use reconnect handler.
|
||||
*
|
||||
* @return the in use reconnect handler
|
||||
*/
|
||||
public abstract ReconnectHandler getReconnectHandler();
|
||||
|
||||
/**
|
||||
* Sets the reconnect handler to be used for subsequent connections.
|
||||
*
|
||||
* @param handler the new handler
|
||||
*/
|
||||
public abstract void setReconnectHandler(ReconnectHandler handler);
|
||||
|
||||
/**
|
||||
* Gracefully mark this instance for shutdown.
|
||||
*/
|
||||
public abstract void stop();
|
||||
|
||||
/**
|
||||
* Start this instance so that it may accept connections.
|
||||
*
|
||||
* @throws Exception any exception thrown during startup causing the
|
||||
* instance to fail to boot
|
||||
*/
|
||||
public abstract void start() throws Exception;
|
||||
|
||||
/**
|
||||
* Register a channel for use with plugin messages. This is required by some
|
||||
* server / client implementations.
|
||||
*
|
||||
* @param channel the channel to register
|
||||
*/
|
||||
public abstract void registerChannel(String channel);
|
||||
|
||||
/**
|
||||
* Unregister a previously registered channel.
|
||||
*
|
||||
* @param channel the channel to unregister
|
||||
*/
|
||||
public abstract void unregisterChannel(String channel);
|
||||
|
||||
/**
|
||||
* Get an immutable set of all registered plugin channels.
|
||||
*
|
||||
* @return registered plugin channels
|
||||
*/
|
||||
public abstract Collection<String> getChannels();
|
||||
|
||||
/**
|
||||
* Get the Minecraft version supported by this proxy.
|
||||
*
|
||||
* @return the supported Minecraft version
|
||||
*/
|
||||
public abstract String getGameVersion();
|
||||
|
||||
/**
|
||||
* Get the Minecraft protocol version supported by this proxy.
|
||||
*
|
||||
* @return the Minecraft protocol version
|
||||
*/
|
||||
public abstract byte getProtocolVersion();
|
||||
|
||||
/**
|
||||
* Factory method to construct an implementation specific server info
|
||||
* instance.
|
||||
*
|
||||
* @param name name of the server
|
||||
* @param address connectable Minecraft address + port of the server
|
||||
* @param restricted whether the server info restricted property will be set
|
||||
* @return the constructed instance
|
||||
*/
|
||||
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, boolean restricted);
|
||||
|
||||
/**
|
||||
* Returns the console overlord for this proxy. Being the console, this
|
||||
* command server cannot have permissions or groups, and will be able to
|
||||
* execute anything.
|
||||
*
|
||||
* @return the console command sender of this proxy
|
||||
*/
|
||||
public abstract CommandSender getConsole();
|
||||
|
||||
/**
|
||||
* Return the folder used to load plugins from.
|
||||
*
|
||||
* @return the folder used to load plugin
|
||||
*/
|
||||
public abstract File getPluginsFolder();
|
||||
|
||||
/**
|
||||
* Get the scheduler instance for this proxy.
|
||||
*
|
||||
* @return the in use scheduler
|
||||
*/
|
||||
public abstract TaskScheduler getScheduler();
|
||||
|
||||
/**
|
||||
* Get the current number of connected users. The default implementation is
|
||||
* more efficient than {@link #getPlayers()} as it does not take a lock or
|
||||
* make a copy.
|
||||
*
|
||||
* @return the current number of connected players
|
||||
*/
|
||||
public abstract int getOnlineCount();
|
||||
|
||||
/**
|
||||
* Send the specified message to the console and all connected players.
|
||||
*
|
||||
* @param message the message to broadcast
|
||||
*/
|
||||
public abstract void broadcast(String message);
|
||||
|
||||
/**
|
||||
* Gets a new instance of this proxies custom tab list.
|
||||
*
|
||||
* @param player the player to generate this list in the context of
|
||||
* @return a new {@link CustomTabList} instance
|
||||
*/
|
||||
public abstract CustomTabList customTabList(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Gets the commands which are disabled and will not be run on this proxy.
|
||||
*
|
||||
* @return the set of disabled commands
|
||||
*/
|
||||
public abstract Collection<String> getDisabledCommands();
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.eaglercraft.EaglercraftBungee;
|
||||
|
||||
public interface QueryConnection {
|
||||
|
||||
public InetAddress getRemoteAddress();
|
||||
public ListenerInfo getListener();
|
||||
|
||||
public String getAccept();
|
||||
public void setReturnType(String type);
|
||||
public String getReturnType();
|
||||
|
||||
public int availableRequests();
|
||||
|
||||
public default JSONObject readRequestData() {
|
||||
String s = readRequestString();
|
||||
return s == null ? null : new JSONObject(s);
|
||||
}
|
||||
|
||||
public String readRequestString();
|
||||
public long getConnectionTimestamp();
|
||||
|
||||
public default long getConnectionAge() {
|
||||
return System.currentTimeMillis() - getConnectionTimestamp();
|
||||
}
|
||||
|
||||
public default void writeResponse(JSONObject msg) {
|
||||
JSONObject toSend = new JSONObject();
|
||||
toSend.put("type", getReturnType());
|
||||
toSend.put("name", BungeeCord.getInstance().config.getServerName());
|
||||
toSend.put("brand", EaglercraftBungee.brand);
|
||||
toSend.put("vers", EaglercraftBungee.version);
|
||||
toSend.put("cracked", EaglercraftBungee.cracked);
|
||||
toSend.put("secure", false);
|
||||
toSend.put("time", System.currentTimeMillis());
|
||||
toSend.put("uuid", BungeeCord.getInstance().config.getUuid());
|
||||
toSend.put("data", msg);
|
||||
writeResponseRaw(toSend.toString());
|
||||
}
|
||||
|
||||
public default void writeResponse(String msg) {
|
||||
JSONObject toSend = new JSONObject();
|
||||
toSend.put("type", getReturnType());
|
||||
toSend.put("name", BungeeCord.getInstance().config.getServerName());
|
||||
toSend.put("brand", EaglercraftBungee.brand);
|
||||
toSend.put("vers", EaglercraftBungee.version);
|
||||
toSend.put("cracked", EaglercraftBungee.cracked);
|
||||
toSend.put("secure", false);
|
||||
toSend.put("time", System.currentTimeMillis());
|
||||
toSend.put("uuid", BungeeCord.getInstance().config.getUuid());
|
||||
toSend.put("data", msg);
|
||||
writeResponseRaw(toSend.toString());
|
||||
}
|
||||
|
||||
public void writeResponseRaw(String msg);
|
||||
public void writeResponseBinary(byte[] blob);
|
||||
|
||||
public void keepAlive(boolean yes);
|
||||
public boolean shouldKeepAlive();
|
||||
public boolean isClosed();
|
||||
public void close();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public interface ReconnectHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the initial server name for a connecting player.
|
||||
*
|
||||
* @param player the connecting player
|
||||
* @return the server to connect to
|
||||
*/
|
||||
ServerInfo getServer(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Save the server of this player before they disconnect so it can be
|
||||
* retrieved later.
|
||||
*
|
||||
* @param player the player to save
|
||||
*/
|
||||
void setServer(ProxiedPlayer player); // TOOD: String + String arguments?
|
||||
|
||||
/**
|
||||
* Save all pending reconnect locations. Whilst not used for database
|
||||
* connections, this method will be called at a predefined interval to allow
|
||||
* the saving of reconnect files.
|
||||
*/
|
||||
void save();
|
||||
|
||||
/**
|
||||
* Close all connections indicating that the proxy is about to shutdown and
|
||||
* all data should be saved. No new requests will be made after this method
|
||||
* has been called.
|
||||
*
|
||||
*/
|
||||
void close();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class ServerIcon {
|
||||
|
||||
public static int[] createServerIcon(BufferedImage awtIcon) {
|
||||
BufferedImage icon = awtIcon;
|
||||
boolean gotScaled = false;
|
||||
if(icon.getWidth() != 64 || icon.getHeight() != 64) {
|
||||
icon = new BufferedImage(64, 64, awtIcon.getType());
|
||||
Graphics2D g = (Graphics2D) icon.getGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, (awtIcon.getWidth() < 64 || awtIcon.getHeight() < 64) ?
|
||||
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR : RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
g.setBackground(new Color(0, true));
|
||||
g.clearRect(0, 0, 64, 64);
|
||||
int ow = awtIcon.getWidth();
|
||||
int oh = awtIcon.getHeight();
|
||||
int nw, nh;
|
||||
float aspectRatio = (float)oh / (float)ow;
|
||||
if(aspectRatio >= 1.0f) {
|
||||
nw = (int)(64 / aspectRatio);
|
||||
nh = 64;
|
||||
}else {
|
||||
nw = 64;
|
||||
nh = (int)(64 * aspectRatio);
|
||||
}
|
||||
g.drawImage(awtIcon, (64 - nw) / 2, (64 - nh) / 2, (64 - nw) / 2 + nw, (64 - nh) / 2 + nh, 0, 0, awtIcon.getWidth(), awtIcon.getHeight(), null);
|
||||
g.dispose();
|
||||
gotScaled = true;
|
||||
}
|
||||
int[] pxls = icon.getRGB(0, 0, 64, 64, new int[4096], 0, 64);
|
||||
if(gotScaled) {
|
||||
for(int i = 0; i < pxls.length; ++i) {
|
||||
if((pxls[i] & 0xFFFFFF) == 0) {
|
||||
pxls[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pxls;
|
||||
}
|
||||
|
||||
public static int[] createServerIcon(InputStream f) {
|
||||
try {
|
||||
return createServerIcon(ImageIO.read(f));
|
||||
}catch(Throwable t) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] createServerIcon(File f) {
|
||||
try {
|
||||
return createServerIcon(ImageIO.read(f));
|
||||
}catch(Throwable t) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
107
eaglerbungee/src/main/java/net/md_5/bungee/api/ServerPing.java
Normal file
107
eaglerbungee/src/main/java/net/md_5/bungee/api/ServerPing.java
Normal file
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
public class ServerPing {
|
||||
private final byte protocolVersion;
|
||||
private final String gameVersion;
|
||||
private final String motd;
|
||||
private final int currentPlayers;
|
||||
private final int maxPlayers;
|
||||
|
||||
@ConstructorProperties({ "protocolVersion", "gameVersion", "motd", "currentPlayers", "maxPlayers" })
|
||||
public ServerPing(final byte protocolVersion, final String gameVersion, final String motd, final int currentPlayers, final int maxPlayers) {
|
||||
this.protocolVersion = protocolVersion;
|
||||
this.gameVersion = gameVersion;
|
||||
this.motd = motd;
|
||||
this.currentPlayers = currentPlayers;
|
||||
this.maxPlayers = maxPlayers;
|
||||
}
|
||||
|
||||
public byte getProtocolVersion() {
|
||||
return this.protocolVersion;
|
||||
}
|
||||
|
||||
public String getGameVersion() {
|
||||
return this.gameVersion;
|
||||
}
|
||||
|
||||
public String getMotd() {
|
||||
return this.motd;
|
||||
}
|
||||
|
||||
public int getCurrentPlayers() {
|
||||
return this.currentPlayers;
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return this.maxPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ServerPing)) {
|
||||
return false;
|
||||
}
|
||||
final ServerPing other = (ServerPing) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (this.getProtocolVersion() != other.getProtocolVersion()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$gameVersion = this.getGameVersion();
|
||||
final Object other$gameVersion = other.getGameVersion();
|
||||
Label_0078: {
|
||||
if (this$gameVersion == null) {
|
||||
if (other$gameVersion == null) {
|
||||
break Label_0078;
|
||||
}
|
||||
} else if (this$gameVersion.equals(other$gameVersion)) {
|
||||
break Label_0078;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$motd = this.getMotd();
|
||||
final Object other$motd = other.getMotd();
|
||||
if (this$motd == null) {
|
||||
if (other$motd == null) {
|
||||
return this.getCurrentPlayers() == other.getCurrentPlayers() && this.getMaxPlayers() == other.getMaxPlayers();
|
||||
}
|
||||
} else if (this$motd.equals(other$motd)) {
|
||||
return this.getCurrentPlayers() == other.getCurrentPlayers() && this.getMaxPlayers() == other.getMaxPlayers();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ServerPing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = result * 31 + this.getProtocolVersion();
|
||||
final Object $gameVersion = this.getGameVersion();
|
||||
result = result * 31 + (($gameVersion == null) ? 0 : $gameVersion.hashCode());
|
||||
final Object $motd = this.getMotd();
|
||||
result = result * 31 + (($motd == null) ? 0 : $motd.hashCode());
|
||||
result = result * 31 + this.getCurrentPlayers();
|
||||
result = result * 31 + this.getMaxPlayers();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServerPing(protocolVersion=" + this.getProtocolVersion() + ", gameVersion=" + this.getGameVersion() + ", motd=" + this.getMotd() + ", currentPlayers=" + this.getCurrentPlayers() + ", maxPlayers=" + this.getMaxPlayers()
|
||||
+ ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AuthServiceInfo {
|
||||
|
||||
private final boolean enabled;
|
||||
private final boolean registerEnabled;
|
||||
private final String authfile;
|
||||
private final int ipLimit;
|
||||
private final List<String> joinMessages;
|
||||
private final int loginTimeout;
|
||||
|
||||
public AuthServiceInfo(boolean enabled, boolean registerEnabled, String authfile,
|
||||
int timeout, List<String> joinMessages, int loginTimeout) {
|
||||
this.enabled = enabled;
|
||||
this.registerEnabled = registerEnabled;
|
||||
this.authfile = authfile;
|
||||
this.ipLimit = timeout;
|
||||
this.joinMessages = joinMessages;
|
||||
this.loginTimeout = loginTimeout;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public boolean isRegisterEnabled() {
|
||||
return registerEnabled;
|
||||
}
|
||||
|
||||
public String getAuthfile() {
|
||||
return authfile;
|
||||
}
|
||||
|
||||
public int getIpLimit() {
|
||||
return ipLimit;
|
||||
}
|
||||
|
||||
public List<String> getJoinMessages() {
|
||||
return joinMessages;
|
||||
}
|
||||
|
||||
public int getLoginTimeout() {
|
||||
return loginTimeout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ConfigurationAdapter {
|
||||
void load();
|
||||
|
||||
int getInt(final String p0, final int p1);
|
||||
|
||||
String getString(final String p0, final String p1);
|
||||
|
||||
boolean getBoolean(final String p0, final boolean p1);
|
||||
|
||||
Map<String, ServerInfo> getServers();
|
||||
|
||||
Collection<ListenerInfo> getListeners();
|
||||
|
||||
Collection<String> getGroups(final String p0);
|
||||
|
||||
Collection<String> getPermissions(final String p0);
|
||||
|
||||
Collection<String> getBlacklistURLs();
|
||||
|
||||
Collection<String> getBlacklistSimpleWhitelist();
|
||||
|
||||
Collection<String> getDisabledCommands();
|
||||
|
||||
Collection<String> getICEServers();
|
||||
|
||||
AuthServiceInfo getAuthSettings();
|
||||
|
||||
Map<String, Object> getMap();
|
||||
|
||||
void forceSave();
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
|
||||
import net.md_5.bungee.api.ServerIcon;
|
||||
import net.md_5.bungee.api.tab.TabListHandler;
|
||||
import net.md_5.bungee.eaglercraft.WebSocketRateLimiter;
|
||||
|
||||
public class ListenerInfo {
|
||||
private final String hostString;
|
||||
private final InetSocketAddress host;
|
||||
private final InetSocketAddress javaHost;
|
||||
private final String motd;
|
||||
private final int maxPlayers;
|
||||
private final int tabListSize;
|
||||
private final String defaultServer;
|
||||
private final String fallbackServer;
|
||||
private final boolean forceDefault;
|
||||
private final boolean websocket;
|
||||
private final boolean forwardIp;
|
||||
private final String forwardIpHeader;
|
||||
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;
|
||||
private final boolean allowMOTD;
|
||||
private final boolean allowQuery;
|
||||
private final MOTDCacheConfiguration cacheConfig;
|
||||
private final WebSocketRateLimiter rateLimitIP;
|
||||
private final WebSocketRateLimiter rateLimitLogin;
|
||||
private final WebSocketRateLimiter rateLimitMOTD;
|
||||
private final WebSocketRateLimiter rateLimitQuery;
|
||||
|
||||
|
||||
public ListenerInfo(final String hostString, final InetSocketAddress host, final InetSocketAddress javaHost,
|
||||
final String forwardIpHeader, final String motd, final int maxPlayers, final int tabListSize,
|
||||
final String defaultServer, final String fallbackServer, final boolean forceDefault,
|
||||
final boolean websocket, final boolean forwardIp, final Map<String, String> forcedHosts,
|
||||
final TexturePackInfo texturePack, final Class<? extends TabListHandler> tabList, final String serverIcon,
|
||||
final MOTDCacheConfiguration cacheConfig, final boolean allowMOTD, final boolean allowQuery,
|
||||
final WebSocketRateLimiter rateLimitIP, final WebSocketRateLimiter rateLimitLogin,
|
||||
final WebSocketRateLimiter rateLimitMOTD, final WebSocketRateLimiter rateLimitQuery) {
|
||||
this.hostString = hostString;
|
||||
this.host = host;
|
||||
this.javaHost = javaHost;
|
||||
this.motd = motd;
|
||||
this.maxPlayers = maxPlayers;
|
||||
this.tabListSize = tabListSize;
|
||||
this.defaultServer = defaultServer;
|
||||
this.fallbackServer = fallbackServer;
|
||||
this.forceDefault = forceDefault;
|
||||
this.websocket = websocket;
|
||||
this.forwardIp = forwardIp;
|
||||
this.forwardIpHeader = forwardIpHeader;
|
||||
this.forcedHosts = forcedHosts;
|
||||
this.texturePack = texturePack;
|
||||
this.tabList = tabList;
|
||||
this.serverIcon = serverIcon;
|
||||
this.serverIconCache = new int[4096];
|
||||
this.serverIconLoaded = false;
|
||||
this.serverIconSet = false;
|
||||
this.allowMOTD = allowMOTD;
|
||||
this.allowQuery = allowQuery;
|
||||
this.cacheConfig = cacheConfig;
|
||||
this.rateLimitIP = rateLimitIP;
|
||||
this.rateLimitLogin = rateLimitLogin;
|
||||
this.rateLimitMOTD = rateLimitMOTD;
|
||||
this.rateLimitQuery = rateLimitQuery;
|
||||
}
|
||||
|
||||
public String getHostString() {
|
||||
return this.hostString;
|
||||
}
|
||||
|
||||
public InetSocketAddress getHost() {
|
||||
return this.host;
|
||||
}
|
||||
|
||||
public InetSocketAddress getJavaHost() {
|
||||
return this.javaHost;
|
||||
}
|
||||
|
||||
public String getMotd() {
|
||||
return this.motd;
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return this.maxPlayers;
|
||||
}
|
||||
|
||||
public int getTabListSize() {
|
||||
return this.tabListSize;
|
||||
}
|
||||
|
||||
public String getDefaultServer() {
|
||||
return this.defaultServer;
|
||||
}
|
||||
|
||||
public String getFallbackServer() {
|
||||
return this.fallbackServer;
|
||||
}
|
||||
|
||||
public boolean isForceDefault() {
|
||||
return this.forceDefault;
|
||||
}
|
||||
|
||||
public Map<String, String> getForcedHosts() {
|
||||
return this.forcedHosts;
|
||||
}
|
||||
|
||||
public TexturePackInfo getTexturePack() {
|
||||
return this.texturePack;
|
||||
}
|
||||
|
||||
public Class<? extends TabListHandler> getTabList() {
|
||||
return this.tabList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ListenerInfo)) {
|
||||
return false;
|
||||
}
|
||||
final ListenerInfo other = (ListenerInfo) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$host = this.getHost();
|
||||
final Object other$host = other.getHost();
|
||||
Label_0065: {
|
||||
if (this$host == null) {
|
||||
if (other$host == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$host.equals(other$host)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$motd = this.getMotd();
|
||||
final Object other$motd = other.getMotd();
|
||||
Label_0102: {
|
||||
if (this$motd == null) {
|
||||
if (other$motd == null) {
|
||||
break Label_0102;
|
||||
}
|
||||
} else if (this$motd.equals(other$motd)) {
|
||||
break Label_0102;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (this.getMaxPlayers() != other.getMaxPlayers()) {
|
||||
return false;
|
||||
}
|
||||
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: {
|
||||
if (this$defaultServer == null) {
|
||||
if (other$defaultServer == null) {
|
||||
break Label_0165;
|
||||
}
|
||||
} else if (this$defaultServer.equals(other$defaultServer)) {
|
||||
break Label_0165;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$fallbackServer = this.getFallbackServer();
|
||||
final Object other$fallbackServer = other.getFallbackServer();
|
||||
Label_0202: {
|
||||
if (this$fallbackServer == null) {
|
||||
if (other$fallbackServer == null) {
|
||||
break Label_0202;
|
||||
}
|
||||
} else if (this$fallbackServer.equals(other$fallbackServer)) {
|
||||
break Label_0202;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (this.isForceDefault() != other.isForceDefault()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$forcedHosts = this.getForcedHosts();
|
||||
final Object other$forcedHosts = other.getForcedHosts();
|
||||
Label_0252: {
|
||||
if (this$forcedHosts == null) {
|
||||
if (other$forcedHosts == null) {
|
||||
break Label_0252;
|
||||
}
|
||||
} else if (this$forcedHosts.equals(other$forcedHosts)) {
|
||||
break Label_0252;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$texturePack = this.getTexturePack();
|
||||
final Object other$texturePack = other.getTexturePack();
|
||||
Label_0289: {
|
||||
if (this$texturePack == null) {
|
||||
if (other$texturePack == null) {
|
||||
break Label_0289;
|
||||
}
|
||||
} else if (this$texturePack.equals(other$texturePack)) {
|
||||
break Label_0289;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$tabList = this.getTabList();
|
||||
final Object other$tabList = other.getTabList();
|
||||
if (this$tabList == null) {
|
||||
if (other$tabList == null) {
|
||||
return true;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ListenerInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $host = this.getHost();
|
||||
result = result * 31 + (($host == null) ? 0 : $host.hashCode());
|
||||
final Object $motd = this.getMotd();
|
||||
result = result * 31 + (($motd == null) ? 0 : $motd.hashCode());
|
||||
result = result * 31 + this.getMaxPlayers();
|
||||
result = result * 31 + this.getTabListSize();
|
||||
final Object $defaultServer = this.getDefaultServer();
|
||||
result = result * 31 + (($defaultServer == null) ? 0 : $defaultServer.hashCode());
|
||||
final Object $fallbackServer = this.getFallbackServer();
|
||||
result = result * 31 + (($fallbackServer == null) ? 0 : $fallbackServer.hashCode());
|
||||
result = result * 31 + (this.isForceDefault() ? 1231 : 1237);
|
||||
final Object $forcedHosts = this.getForcedHosts();
|
||||
result = result * 31 + (($forcedHosts == null) ? 0 : $forcedHosts.hashCode());
|
||||
final Object $texturePack = this.getTexturePack();
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ListenerInfo(host=" + this.getHost() + ", motd=" + this.getMotd() + ", maxPlayers=" + this.getMaxPlayers() + ", tabListSize=" + this.getTabListSize() + ", defaultServer=" + this.getDefaultServer() + ", fallbackServer="
|
||||
+ this.getFallbackServer() + ", forceDefault=" + this.isForceDefault() + ", websocket=" + this.isWebsocket() + ", forcedHosts=" + this.getForcedHosts() + ", texturePack=" + this.getTexturePack() + ", tabList=" + this.getTabList() + ")";
|
||||
}
|
||||
|
||||
public boolean isWebsocket() {
|
||||
return websocket;
|
||||
}
|
||||
|
||||
public boolean hasForwardedHeaders() {
|
||||
return forwardIp;
|
||||
}
|
||||
|
||||
public String getForwardedIPHeader() {
|
||||
return forwardIpHeader;
|
||||
}
|
||||
|
||||
public String getServerIcon() {
|
||||
return serverIcon;
|
||||
}
|
||||
|
||||
public int[] getServerIconCache() {
|
||||
if(!serverIconLoaded) {
|
||||
if(serverIcon != null) {
|
||||
int[] img = ServerIcon.createServerIcon(new File(serverIcon));
|
||||
if(img != null) {
|
||||
System.arraycopy(img, 0, serverIconCache, 0, img.length);
|
||||
serverIconSet = true;
|
||||
}else {
|
||||
serverIconSet = false;
|
||||
}
|
||||
}else {
|
||||
serverIconSet = false;
|
||||
}
|
||||
serverIconLoaded = true;
|
||||
}
|
||||
return serverIconCache;
|
||||
}
|
||||
|
||||
public boolean isIconSet() {
|
||||
getServerIconCache();
|
||||
return serverIconSet;
|
||||
}
|
||||
|
||||
public boolean isForwardIp() {
|
||||
return forwardIp;
|
||||
}
|
||||
|
||||
public boolean isServerIconLoaded() {
|
||||
return serverIconLoaded;
|
||||
}
|
||||
|
||||
public boolean isServerIconSet() {
|
||||
return serverIconSet;
|
||||
}
|
||||
|
||||
public boolean isAllowMOTD() {
|
||||
return allowMOTD;
|
||||
}
|
||||
|
||||
public boolean isAllowQuery() {
|
||||
return allowQuery;
|
||||
}
|
||||
|
||||
public MOTDCacheConfiguration getCacheConfig() {
|
||||
return cacheConfig;
|
||||
}
|
||||
|
||||
public WebSocketRateLimiter getRateLimitIP() {
|
||||
return rateLimitIP;
|
||||
}
|
||||
|
||||
public WebSocketRateLimiter getRateLimitLogin() {
|
||||
return rateLimitLogin;
|
||||
}
|
||||
|
||||
public WebSocketRateLimiter getRateLimitMOTD() {
|
||||
return rateLimitMOTD;
|
||||
}
|
||||
|
||||
public WebSocketRateLimiter getRateLimitQuery() {
|
||||
return rateLimitQuery;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
public class MOTDCacheConfiguration {
|
||||
|
||||
public final int cacheTTL;
|
||||
public final boolean cacheServerListAnimation;
|
||||
public final boolean cacheServerListResults;
|
||||
public final boolean cacheServerListTrending;
|
||||
public final boolean cacheServerListPortfolios;
|
||||
|
||||
public MOTDCacheConfiguration(int cacheTTL, boolean cacheServerListAnimation, boolean cacheServerListResults,
|
||||
boolean cacheServerListTrending, boolean cacheServerListPortfolios) {
|
||||
this.cacheTTL = cacheTTL;
|
||||
this.cacheServerListAnimation = cacheServerListAnimation;
|
||||
this.cacheServerListResults = cacheServerListResults;
|
||||
this.cacheServerListTrending = cacheServerListTrending;
|
||||
this.cacheServerListPortfolios = cacheServerListPortfolios;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
/**
|
||||
* Class used to represent a server to connect to.
|
||||
*/
|
||||
public interface ServerInfo
|
||||
{
|
||||
|
||||
/**
|
||||
* Get the name of this server.
|
||||
*
|
||||
* @return the configured name for this server address
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Gets the connectable host + port pair for this server. Implementations
|
||||
* expect this to be used as the unique identifier per each instance of this
|
||||
* class.
|
||||
*
|
||||
* @return the IP and port pair for this server
|
||||
*/
|
||||
InetSocketAddress getAddress();
|
||||
|
||||
/**
|
||||
* Get the set of all players on this server.
|
||||
*
|
||||
* @return an unmodifiable collection of all players on this server
|
||||
*/
|
||||
Collection<ProxiedPlayer> getPlayers();
|
||||
|
||||
/**
|
||||
* Returns the MOTD which should be used when this server is a forced host.
|
||||
*
|
||||
* @return the motd
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the player can access this server. It will only return false when
|
||||
* the player has no permission and this server is restricted.
|
||||
*
|
||||
* @param sender the player to check access for
|
||||
* @return whether access is granted to this server
|
||||
*/
|
||||
boolean canAccess(CommandSender sender);
|
||||
|
||||
/**
|
||||
* Send data by any available means to this server.
|
||||
*
|
||||
* @param channel the channel to send this data via
|
||||
* @param data the data to send
|
||||
*/
|
||||
void sendData(String channel, byte[] data);
|
||||
|
||||
/**
|
||||
* Asynchronously gets the current player count on this server.
|
||||
*
|
||||
* @param callback the callback to call when the count has been retrieved.
|
||||
*/
|
||||
void ping(Callback<ServerPing> callback);
|
||||
|
||||
String getRedirect();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
public class TexturePackInfo {
|
||||
private final String url;
|
||||
private final int size;
|
||||
|
||||
@ConstructorProperties({ "url", "size" })
|
||||
public TexturePackInfo(final String url, final int size) {
|
||||
this.url = url;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof TexturePackInfo)) {
|
||||
return false;
|
||||
}
|
||||
final TexturePackInfo other = (TexturePackInfo) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$url = this.getUrl();
|
||||
final Object other$url = other.getUrl();
|
||||
if (this$url == null) {
|
||||
if (other$url == null) {
|
||||
return this.getSize() == other.getSize();
|
||||
}
|
||||
} else if (this$url.equals(other$url)) {
|
||||
return this.getSize() == other.getSize();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof TexturePackInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $url = this.getUrl();
|
||||
result = result * 31 + (($url == null) ? 0 : $url.hashCode());
|
||||
result = result * 31 + this.getSize();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TexturePackInfo(url=" + this.getUrl() + ", size=" + this.getSize() + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
/**
|
||||
* Represents a player physically connected to the world hosted on this server.
|
||||
*/
|
||||
public interface ConnectedPlayer extends ProxiedPlayer
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
|
||||
/**
|
||||
* A proxy connection is defined as a connection directly connected to a socket.
|
||||
* It should expose information about the remote peer, however not be specific
|
||||
* to a type of connection, whether server or player.
|
||||
*/
|
||||
public interface Connection
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the remote address of this connection.
|
||||
*
|
||||
* @return the remote address
|
||||
*/
|
||||
InetSocketAddress getAddress();
|
||||
|
||||
/**
|
||||
* Disconnects this end of the connection for the specified reason. If this
|
||||
* is an {@link ProxiedPlayer} the respective server connection will be
|
||||
* closed too.
|
||||
*
|
||||
* @param reason the reason shown to the player / sent to the server on
|
||||
* disconnect
|
||||
*/
|
||||
void disconnect(String reason);
|
||||
|
||||
/**
|
||||
* Get the unsafe methods of this class.
|
||||
*
|
||||
* @return the unsafe method interface
|
||||
*/
|
||||
Unsafe unsafe();
|
||||
|
||||
interface Unsafe
|
||||
{
|
||||
|
||||
/**
|
||||
* Send a packet to this connection.
|
||||
*
|
||||
* @param packet the packet to send
|
||||
*/
|
||||
void sendPacket(DefinedPacket packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
|
||||
/**
|
||||
* Represents a user attempting to log into the proxy.
|
||||
*/
|
||||
public interface PendingConnection extends Connection
|
||||
{
|
||||
|
||||
/**
|
||||
* Get the requested username.
|
||||
*
|
||||
* @return the requested username, or null if not set
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Get the numerical client version of the player attempting to log in.
|
||||
*
|
||||
* @return the protocol version of the remote client
|
||||
*/
|
||||
byte getVersion();
|
||||
|
||||
/**
|
||||
* Get the requested virtual host that the client tried to connect to.
|
||||
*
|
||||
* @return request virtual host or null if invalid / not specified.
|
||||
*/
|
||||
InetSocketAddress getVirtualHost();
|
||||
|
||||
/**
|
||||
* Get the listener that accepted this connection.
|
||||
*
|
||||
* @return the accepting listener
|
||||
*/
|
||||
ListenerInfo getListener();
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.tab.TabListHandler;
|
||||
|
||||
/**
|
||||
* Represents a player who's connection is being connected to somewhere else,
|
||||
* whether it be a remote or embedded server.
|
||||
*/
|
||||
public interface ProxiedPlayer extends Connection, CommandSender
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets this player's display name.
|
||||
*
|
||||
* @return the players current display name
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
/**
|
||||
* Sets this players display name to be used as their nametag and tab list
|
||||
* name.
|
||||
*
|
||||
* @param name the name to set
|
||||
*/
|
||||
void setDisplayName(String name);
|
||||
|
||||
/**
|
||||
* Connects / transfers this user to the specified connection, gracefully
|
||||
* closing the current one. Depending on the implementation, this method
|
||||
* might return before the user has been connected.
|
||||
*
|
||||
* @param target the new server to connect to
|
||||
*/
|
||||
void connect(ServerInfo target);
|
||||
|
||||
/**
|
||||
* Gets the server this player is connected to.
|
||||
*
|
||||
* @return the server this player is connected to
|
||||
*/
|
||||
Server getServer();
|
||||
|
||||
/**
|
||||
* Gets the ping time between the proxy and this connection.
|
||||
*
|
||||
* @return the current ping time
|
||||
*/
|
||||
int getPing();
|
||||
|
||||
/**
|
||||
* Send a plugin message to this player.
|
||||
*
|
||||
* @param channel the channel to send this data via
|
||||
* @param data the data to send
|
||||
*/
|
||||
void sendData(String channel, byte[] data);
|
||||
|
||||
/**
|
||||
* Get the pending connection that belongs to this player.
|
||||
*
|
||||
* @return the pending connection that this player used
|
||||
*/
|
||||
PendingConnection getPendingConnection();
|
||||
|
||||
/**
|
||||
* Make this player chat (say something), to the server he is currently on.
|
||||
*
|
||||
* @param message the message to say
|
||||
*/
|
||||
void chat(String message);
|
||||
|
||||
/**
|
||||
* Sets the new tab list for the user. At this stage it is not advisable to
|
||||
* change after the user has logged in!
|
||||
*
|
||||
* @param list the new list
|
||||
*/
|
||||
void setTabList(TabListHandler list);
|
||||
|
||||
/**
|
||||
* Get the current tab list.
|
||||
*
|
||||
* @return the tab list in use by this user
|
||||
*/
|
||||
TabListHandler getTabList();
|
||||
|
||||
/**
|
||||
* Get the server which this player will be sent to next time the log in.
|
||||
*
|
||||
* @return the server, or null if default
|
||||
*/
|
||||
ServerInfo getReconnectServer();
|
||||
|
||||
/**
|
||||
* Set the server which this player will be sent to next time the log in.
|
||||
*
|
||||
* @param server the server to set
|
||||
*/
|
||||
void setReconnectServer(ServerInfo server);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
/**
|
||||
* Represents a destination which this proxy might connect to.
|
||||
*/
|
||||
public interface Server extends Connection
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the basic information about this server.
|
||||
*
|
||||
* @return the {@link ServerInfo} for this server
|
||||
*/
|
||||
public ServerInfo getInfo();
|
||||
|
||||
/**
|
||||
* Send data by any available means to this server.
|
||||
*
|
||||
* @param channel the channel to send this data via
|
||||
* @param data the data to send
|
||||
*/
|
||||
public abstract void sendData(String channel, byte[] data);
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
public class AsyncEvent<T> extends Event {
|
||||
private final Callback<T> done;
|
||||
private final Set<Plugin> intents;
|
||||
private final AtomicBoolean fired;
|
||||
private final AtomicInteger latch;
|
||||
|
||||
@Override
|
||||
public void postCall() {
|
||||
this.fired.set(true);
|
||||
if (this.latch.get() == 0) {
|
||||
this.done.done((T) this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerIntent(final Plugin plugin) {
|
||||
Preconditions.checkState(!this.fired.get(), "Event %s has already been fired", new Object[] { this });
|
||||
Preconditions.checkState(!this.intents.contains(plugin), "Plugin %s already registered intent for event %s", new Object[] { plugin, this });
|
||||
this.intents.add(plugin);
|
||||
this.latch.incrementAndGet();
|
||||
}
|
||||
|
||||
public void completeIntent(final Plugin plugin) {
|
||||
Preconditions.checkState(this.intents.contains(plugin), "Plugin %s has not registered intent for event %s", new Object[] { plugin, this });
|
||||
this.intents.remove(plugin);
|
||||
if (this.latch.decrementAndGet() == 0 && this.fired.get()) {
|
||||
this.done.done((T) this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "done" })
|
||||
public AsyncEvent(final Callback<T> done) {
|
||||
this.intents = Collections.newSetFromMap(new ConcurrentHashMap<Plugin, Boolean>());
|
||||
this.fired = new AtomicBoolean();
|
||||
this.latch = new AtomicInteger();
|
||||
this.done = done;
|
||||
}
|
||||
|
||||
public Callback<T> getDone() {
|
||||
return this.done;
|
||||
}
|
||||
|
||||
public Set<Plugin> getIntents() {
|
||||
return this.intents;
|
||||
}
|
||||
|
||||
public AtomicBoolean getFired() {
|
||||
return this.fired;
|
||||
}
|
||||
|
||||
public AtomicInteger getLatch() {
|
||||
return this.latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AsyncEvent(super=" + super.toString() + ", done=" + this.getDone() + ", intents=" + this.getIntents() + ", fired=" + this.getFired() + ", latch=" + this.getLatch() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof AsyncEvent)) {
|
||||
return false;
|
||||
}
|
||||
final AsyncEvent<?> other = (AsyncEvent<?>) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$done = this.getDone();
|
||||
final Object other$done = other.getDone();
|
||||
Label_0075: {
|
||||
if (this$done == null) {
|
||||
if (other$done == null) {
|
||||
break Label_0075;
|
||||
}
|
||||
} else if (this$done.equals(other$done)) {
|
||||
break Label_0075;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$intents = this.getIntents();
|
||||
final Object other$intents = other.getIntents();
|
||||
Label_0112: {
|
||||
if (this$intents == null) {
|
||||
if (other$intents == null) {
|
||||
break Label_0112;
|
||||
}
|
||||
} else if (this$intents.equals(other$intents)) {
|
||||
break Label_0112;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$fired = this.getFired();
|
||||
final Object other$fired = other.getFired();
|
||||
Label_0149: {
|
||||
if (this$fired == null) {
|
||||
if (other$fired == null) {
|
||||
break Label_0149;
|
||||
}
|
||||
} else if (this$fired.equals(other$fired)) {
|
||||
break Label_0149;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$latch = this.getLatch();
|
||||
final Object other$latch = other.getLatch();
|
||||
if (this$latch == null) {
|
||||
if (other$latch == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$latch.equals(other$latch)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof AsyncEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = result * 31 + super.hashCode();
|
||||
final Object $done = this.getDone();
|
||||
result = result * 31 + (($done == null) ? 0 : $done.hashCode());
|
||||
final Object $intents = this.getIntents();
|
||||
result = result * 31 + (($intents == null) ? 0 : $intents.hashCode());
|
||||
final Object $fired = this.getFired();
|
||||
result = result * 31 + (($fired == null) ? 0 : $fired.hashCode());
|
||||
final Object $latch = this.getLatch();
|
||||
result = result * 31 + (($latch == null) ? 0 : $latch.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
|
||||
public class ChatEvent extends TargetedEvent implements Cancellable {
|
||||
private boolean cancelled;
|
||||
private String message;
|
||||
|
||||
public ChatEvent(final Connection sender, final Connection receiver, final String message) {
|
||||
super(sender, receiver);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public boolean isCommand() {
|
||||
return this.message.length() > 0 && this.message.charAt(0) == '/';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public void setMessage(final String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatEvent(super=" + super.toString() + ", cancelled=" + this.isCancelled() + ", message=" + this.getMessage() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ChatEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ChatEvent other = (ChatEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
if (this.isCancelled() != other.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$message = this.getMessage();
|
||||
final Object other$message = other.getMessage();
|
||||
if (this$message == null) {
|
||||
if (other$message == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$message.equals(other$message)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ChatEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = result * 31 + super.hashCode();
|
||||
result = result * 31 + (this.isCancelled() ? 1231 : 1237);
|
||||
final Object $message = this.getMessage();
|
||||
result = result * 31 + (($message == null) ? 0 : $message.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
|
||||
public class LoginEvent extends AsyncEvent<LoginEvent> implements Cancellable {
|
||||
private boolean cancelled;
|
||||
private String cancelReason;
|
||||
private final PendingConnection connection;
|
||||
|
||||
public LoginEvent(final PendingConnection connection, final Callback<LoginEvent> done) {
|
||||
super(done);
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public String getCancelReason() {
|
||||
return this.cancelReason;
|
||||
}
|
||||
|
||||
public PendingConnection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public void setCancelReason(final String cancelReason) {
|
||||
this.cancelReason = cancelReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LoginEvent(cancelled=" + this.isCancelled() + ", cancelReason=" + this.getCancelReason() + ", connection=" + this.getConnection() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof LoginEvent)) {
|
||||
return false;
|
||||
}
|
||||
final LoginEvent other = (LoginEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (this.isCancelled() != other.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$cancelReason = this.getCancelReason();
|
||||
final Object other$cancelReason = other.getCancelReason();
|
||||
Label_0078: {
|
||||
if (this$cancelReason == null) {
|
||||
if (other$cancelReason == null) {
|
||||
break Label_0078;
|
||||
}
|
||||
} else if (this$cancelReason.equals(other$cancelReason)) {
|
||||
break Label_0078;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$connection = this.getConnection();
|
||||
final Object other$connection = other.getConnection();
|
||||
if (this$connection == null) {
|
||||
if (other$connection == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$connection.equals(other$connection)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof LoginEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = result * 31 + (this.isCancelled() ? 1231 : 1237);
|
||||
final Object $cancelReason = this.getCancelReason();
|
||||
result = result * 31 + (($cancelReason == null) ? 0 : $cancelReason.hashCode());
|
||||
final Object $connection = this.getConnection();
|
||||
result = result * 31 + (($connection == null) ? 0 : $connection.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class PermissionCheckEvent extends Event {
|
||||
private final CommandSender sender;
|
||||
private final String permission;
|
||||
private boolean hasPermission;
|
||||
|
||||
public boolean hasPermission() {
|
||||
return this.hasPermission;
|
||||
}
|
||||
|
||||
public CommandSender getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
public String getPermission() {
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
public void setHasPermission(final boolean hasPermission) {
|
||||
this.hasPermission = hasPermission;
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "sender", "permission", "hasPermission" })
|
||||
public PermissionCheckEvent(final CommandSender sender, final String permission, final boolean hasPermission) {
|
||||
this.sender = sender;
|
||||
this.permission = permission;
|
||||
this.hasPermission = hasPermission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PermissionCheckEvent(sender=" + this.getSender() + ", permission=" + this.getPermission() + ", hasPermission=" + this.hasPermission + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PermissionCheckEvent)) {
|
||||
return false;
|
||||
}
|
||||
final PermissionCheckEvent other = (PermissionCheckEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$sender = this.getSender();
|
||||
final Object other$sender = other.getSender();
|
||||
Label_0065: {
|
||||
if (this$sender == null) {
|
||||
if (other$sender == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$sender.equals(other$sender)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$permission = this.getPermission();
|
||||
final Object other$permission = other.getPermission();
|
||||
if (this$permission == null) {
|
||||
if (other$permission == null) {
|
||||
return this.hasPermission == other.hasPermission;
|
||||
}
|
||||
} else if (this$permission.equals(other$permission)) {
|
||||
return this.hasPermission == other.hasPermission;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof PermissionCheckEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $sender = this.getSender();
|
||||
result = result * 31 + (($sender == null) ? 0 : $sender.hashCode());
|
||||
final Object $permission = this.getPermission();
|
||||
result = result * 31 + (($permission == null) ? 0 : $permission.hashCode());
|
||||
result = result * 31 + (this.hasPermission ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class PlayerDisconnectEvent extends Event {
|
||||
private final ProxiedPlayer player;
|
||||
|
||||
@ConstructorProperties({ "player" })
|
||||
public PlayerDisconnectEvent(final ProxiedPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlayerDisconnectEvent(player=" + this.getPlayer() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PlayerDisconnectEvent)) {
|
||||
return false;
|
||||
}
|
||||
final PlayerDisconnectEvent other = (PlayerDisconnectEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$player = this.getPlayer();
|
||||
final Object other$player = other.getPlayer();
|
||||
if (this$player == null) {
|
||||
if (other$player == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$player.equals(other$player)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof PlayerDisconnectEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $player = this.getPlayer();
|
||||
result = result * 31 + (($player == null) ? 0 : $player.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.protocol.packet.Packet2Handshake;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Event called to represent a player first making their presence and username
|
||||
* known.
|
||||
*/
|
||||
public class PlayerHandshakeEvent extends Event
|
||||
{
|
||||
|
||||
/**
|
||||
* Connection attempting to login.
|
||||
*/
|
||||
private final PendingConnection connection;
|
||||
/**
|
||||
* The handshake.
|
||||
*/
|
||||
private final Packet2Handshake handshake;
|
||||
|
||||
public PlayerHandshakeEvent(PendingConnection connection, Packet2Handshake handshake)
|
||||
{
|
||||
this.connection = connection;
|
||||
this.handshake = handshake;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
|
||||
public class PluginMessageEvent extends TargetedEvent implements Cancellable {
|
||||
private boolean cancelled;
|
||||
private final String tag;
|
||||
private final byte[] data;
|
||||
|
||||
public PluginMessageEvent(final Connection sender, final Connection receiver, final String tag, final byte[] data) {
|
||||
super(sender, receiver);
|
||||
this.tag = tag;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return this.tag;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PluginMessageEvent(super=" + super.toString() + ", cancelled=" + this.isCancelled() + ", tag=" + this.getTag() + ", data=" + Arrays.toString(this.getData()) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PluginMessageEvent)) {
|
||||
return false;
|
||||
}
|
||||
final PluginMessageEvent other = (PluginMessageEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
if (this.isCancelled() != other.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$tag = this.getTag();
|
||||
final Object other$tag = other.getTag();
|
||||
if (this$tag == null) {
|
||||
if (other$tag == null) {
|
||||
return Arrays.equals(this.getData(), other.getData());
|
||||
}
|
||||
} else if (this$tag.equals(other$tag)) {
|
||||
return Arrays.equals(this.getData(), other.getData());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof PluginMessageEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = result * 31 + super.hashCode();
|
||||
result = result * 31 + (this.isCancelled() ? 1231 : 1237);
|
||||
final Object $tag = this.getTag();
|
||||
result = result * 31 + (($tag == null) ? 0 : $tag.hashCode());
|
||||
result = result * 31 + Arrays.hashCode(this.getData());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class PostLoginEvent extends Event {
|
||||
private final ProxiedPlayer player;
|
||||
|
||||
@ConstructorProperties({ "player" })
|
||||
public PostLoginEvent(final ProxiedPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PostLoginEvent(player=" + this.getPlayer() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PostLoginEvent)) {
|
||||
return false;
|
||||
}
|
||||
final PostLoginEvent other = (PostLoginEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$player = this.getPlayer();
|
||||
final Object other$player = other.getPlayer();
|
||||
if (this$player == null) {
|
||||
if (other$player == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$player.equals(other$player)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof PostLoginEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $player = this.getPlayer();
|
||||
result = result * 31 + (($player == null) ? 0 : $player.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class ProxyPingEvent extends Event {
|
||||
private final PendingConnection connection;
|
||||
private ServerPing response;
|
||||
|
||||
public PendingConnection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
public ServerPing getResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
public void setResponse(final ServerPing response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "connection", "response" })
|
||||
public ProxyPingEvent(final PendingConnection connection, final ServerPing response) {
|
||||
this.connection = connection;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProxyPingEvent(connection=" + this.getConnection() + ", response=" + this.getResponse() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ProxyPingEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ProxyPingEvent other = (ProxyPingEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$connection = this.getConnection();
|
||||
final Object other$connection = other.getConnection();
|
||||
Label_0065: {
|
||||
if (this$connection == null) {
|
||||
if (other$connection == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$connection.equals(other$connection)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$response = this.getResponse();
|
||||
final Object other$response = other.getResponse();
|
||||
if (this$response == null) {
|
||||
if (other$response == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$response.equals(other$response)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ProxyPingEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $connection = this.getConnection();
|
||||
result = result * 31 + (($connection == null) ? 0 : $connection.hashCode());
|
||||
final Object $response = this.getResponse();
|
||||
result = result * 31 + (($response == null) ? 0 : $response.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class ServerConnectEvent extends Event implements Cancellable {
|
||||
private final ProxiedPlayer player;
|
||||
private ServerInfo target;
|
||||
private boolean cancelled;
|
||||
|
||||
public ServerConnectEvent(final ProxiedPlayer player, final ServerInfo target) {
|
||||
this.player = player;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public ServerInfo getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public void setTarget(final ServerInfo target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServerConnectEvent(player=" + this.getPlayer() + ", target=" + this.getTarget() + ", cancelled=" + this.isCancelled() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ServerConnectEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ServerConnectEvent other = (ServerConnectEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$player = this.getPlayer();
|
||||
final Object other$player = other.getPlayer();
|
||||
Label_0065: {
|
||||
if (this$player == null) {
|
||||
if (other$player == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$player.equals(other$player)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$target = this.getTarget();
|
||||
final Object other$target = other.getTarget();
|
||||
if (this$target == null) {
|
||||
if (other$target == null) {
|
||||
return this.isCancelled() == other.isCancelled();
|
||||
}
|
||||
} else if (this$target.equals(other$target)) {
|
||||
return this.isCancelled() == other.isCancelled();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ServerConnectEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $player = this.getPlayer();
|
||||
result = result * 31 + (($player == null) ? 0 : $player.hashCode());
|
||||
final Object $target = this.getTarget();
|
||||
result = result * 31 + (($target == null) ? 0 : $target.hashCode());
|
||||
result = result * 31 + (this.isCancelled() ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class ServerConnectedEvent extends Event {
|
||||
private final ProxiedPlayer player;
|
||||
private final Server server;
|
||||
|
||||
@ConstructorProperties({ "player", "server" })
|
||||
public ServerConnectedEvent(final ProxiedPlayer player, final Server server) {
|
||||
this.player = player;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServerConnectedEvent(player=" + this.getPlayer() + ", server=" + this.getServer() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ServerConnectedEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ServerConnectedEvent other = (ServerConnectedEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$player = this.getPlayer();
|
||||
final Object other$player = other.getPlayer();
|
||||
Label_0065: {
|
||||
if (this$player == null) {
|
||||
if (other$player == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$player.equals(other$player)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$server = this.getServer();
|
||||
final Object other$server = other.getServer();
|
||||
if (this$server == null) {
|
||||
if (other$server == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$server.equals(other$server)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ServerConnectedEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $player = this.getPlayer();
|
||||
result = result * 31 + (($player == null) ? 0 : $player.hashCode());
|
||||
final Object $server = this.getServer();
|
||||
result = result * 31 + (($server == null) ? 0 : $server.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Represents a player getting kicked from a server.
|
||||
*/
|
||||
|
||||
public class ServerKickEvent extends Event implements Cancellable
|
||||
{
|
||||
|
||||
private boolean cancelled;
|
||||
private final ProxiedPlayer player;
|
||||
private String kickReason;
|
||||
private ServerInfo cancelServer;
|
||||
private State state;
|
||||
|
||||
public enum State
|
||||
{
|
||||
|
||||
CONNECTING, CONNECTED, UNKNOWN;
|
||||
}
|
||||
|
||||
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer)
|
||||
{
|
||||
this( player, kickReason, cancelServer, State.UNKNOWN );
|
||||
}
|
||||
|
||||
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer, State state)
|
||||
{
|
||||
this.player = player;
|
||||
this.kickReason = kickReason;
|
||||
this.cancelServer = cancelServer;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public String getKickReason() {
|
||||
return this.kickReason;
|
||||
}
|
||||
|
||||
public ServerInfo getCancelServer() {
|
||||
return this.cancelServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public void setKickReason(final String kickReason) {
|
||||
this.kickReason = kickReason;
|
||||
}
|
||||
|
||||
public void setCancelServer(final ServerInfo cancelServer) {
|
||||
this.cancelServer = cancelServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServerKickEvent(cancelled=" + this.isCancelled() + ", player=" + this.getPlayer() + ", kickReason=" + this.getKickReason() + ", cancelServer=" + this.getCancelServer() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ServerKickEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ServerKickEvent other = (ServerKickEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (this.isCancelled() != other.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$player = this.getPlayer();
|
||||
final Object other$player = other.getPlayer();
|
||||
Label_0078: {
|
||||
if (this$player == null) {
|
||||
if (other$player == null) {
|
||||
break Label_0078;
|
||||
}
|
||||
} else if (this$player.equals(other$player)) {
|
||||
break Label_0078;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$kickReason = this.getKickReason();
|
||||
final Object other$kickReason = other.getKickReason();
|
||||
Label_0115: {
|
||||
if (this$kickReason == null) {
|
||||
if (other$kickReason == null) {
|
||||
break Label_0115;
|
||||
}
|
||||
} else if (this$kickReason.equals(other$kickReason)) {
|
||||
break Label_0115;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$cancelServer = this.getCancelServer();
|
||||
final Object other$cancelServer = other.getCancelServer();
|
||||
if (this$cancelServer == null) {
|
||||
if (other$cancelServer == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$cancelServer.equals(other$cancelServer)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ServerKickEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = result * 31 + (this.isCancelled() ? 1231 : 1237);
|
||||
final Object $player = this.getPlayer();
|
||||
result = result * 31 + (($player == null) ? 0 : $player.hashCode());
|
||||
final Object $kickReason = this.getKickReason();
|
||||
result = result * 31 + (($kickReason == null) ? 0 : $kickReason.hashCode());
|
||||
final Object $cancelServer = this.getCancelServer();
|
||||
result = result * 31 + (($cancelServer == null) ? 0 : $cancelServer.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class ServerSwitchEvent extends Event {
|
||||
private final ProxiedPlayer player;
|
||||
|
||||
@ConstructorProperties({ "player" })
|
||||
public ServerSwitchEvent(final ProxiedPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServerSwitchEvent(player=" + this.getPlayer() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ServerSwitchEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ServerSwitchEvent other = (ServerSwitchEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$player = this.getPlayer();
|
||||
final Object other$player = other.getPlayer();
|
||||
if (this$player == null) {
|
||||
if (other$player == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$player.equals(other$player)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof ServerSwitchEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $player = this.getPlayer();
|
||||
result = result * 31 + (($player == null) ? 0 : $player.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public abstract class TargetedEvent extends Event {
|
||||
private final Connection sender;
|
||||
private final Connection receiver;
|
||||
|
||||
public Connection getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
public Connection getReceiver() {
|
||||
return this.receiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TargetedEvent(sender=" + this.getSender() + ", receiver=" + this.getReceiver() + ")";
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "sender", "receiver" })
|
||||
public TargetedEvent(final Connection sender, final Connection receiver) {
|
||||
this.sender = sender;
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof TargetedEvent)) {
|
||||
return false;
|
||||
}
|
||||
final TargetedEvent other = (TargetedEvent) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$sender = this.getSender();
|
||||
final Object other$sender = other.getSender();
|
||||
Label_0065: {
|
||||
if (this$sender == null) {
|
||||
if (other$sender == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$sender.equals(other$sender)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$receiver = this.getReceiver();
|
||||
final Object other$receiver = other.getReceiver();
|
||||
if (this$receiver == null) {
|
||||
if (other$receiver == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$receiver.equals(other$receiver)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof TargetedEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $sender = this.getSender();
|
||||
result = result * 31 + (($sender == null) ? 0 : $sender.hashCode());
|
||||
final Object $receiver = this.getReceiver();
|
||||
result = result * 31 + (($receiver == null) ? 0 : $receiver.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import net.md_5.bungee.api.MOTD;
|
||||
|
||||
public class WebsocketMOTDEvent extends WebsocketQueryEvent {
|
||||
|
||||
public WebsocketMOTDEvent(MOTD connection) {
|
||||
super(connection);
|
||||
}
|
||||
|
||||
public MOTD getMOTD() {
|
||||
return (MOTD)connection;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import net.md_5.bungee.api.QueryConnection;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
public class WebsocketQueryEvent extends Event {
|
||||
|
||||
protected final QueryConnection connection;
|
||||
|
||||
public WebsocketQueryEvent(QueryConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public InetAddress getRemoteAddress() {
|
||||
return connection.getRemoteAddress();
|
||||
}
|
||||
|
||||
public ListenerInfo getListener() {
|
||||
return connection.getListener();
|
||||
}
|
||||
|
||||
public String getAccept() {
|
||||
return connection.getAccept();
|
||||
}
|
||||
|
||||
public QueryConnection getQuery() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
/**
|
||||
* Events that implement this indicate that they may be cancelled and thus
|
||||
* prevented from happening.
|
||||
*/
|
||||
public interface Cancellable
|
||||
{
|
||||
|
||||
/**
|
||||
* Get whether or not this event is cancelled.
|
||||
*
|
||||
* @return the cancelled state of this event
|
||||
*/
|
||||
public boolean isCancelled();
|
||||
|
||||
/**
|
||||
* Sets the cancelled state of this event.
|
||||
*
|
||||
* @param cancel the state to set
|
||||
*/
|
||||
public void setCancelled(boolean cancel);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
public abstract class Command {
|
||||
private final String name;
|
||||
private final String permission;
|
||||
private final String[] aliases;
|
||||
|
||||
public Command(final String name) {
|
||||
this(name, null, new String[0]);
|
||||
}
|
||||
|
||||
public Command(final String name, final String permission, final String... aliases) {
|
||||
Preconditions.checkArgument(name != null, (Object) "name");
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
public abstract void execute(final CommandSender p0, final String[] p1);
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getPermission() {
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
public String[] getAliases() {
|
||||
return this.aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Command)) {
|
||||
return false;
|
||||
}
|
||||
final Command other = (Command) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$name = this.getName();
|
||||
final Object other$name = other.getName();
|
||||
Label_0065: {
|
||||
if (this$name == null) {
|
||||
if (other$name == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$name.equals(other$name)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$permission = this.getPermission();
|
||||
final Object other$permission = other.getPermission();
|
||||
if (this$permission == null) {
|
||||
if (other$permission == null) {
|
||||
return Arrays.deepEquals(this.getAliases(), other.getAliases());
|
||||
}
|
||||
} else if (this$permission.equals(other$permission)) {
|
||||
return Arrays.deepEquals(this.getAliases(), other.getAliases());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof Command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $name = this.getName();
|
||||
result = result * 31 + (($name == null) ? 0 : $name.hashCode());
|
||||
final Object $permission = this.getPermission();
|
||||
result = result * 31 + (($permission == null) ? 0 : $permission.hashCode());
|
||||
result = result * 31 + Arrays.deepHashCode(this.getAliases());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Command(name=" + this.getName() + ", permission=" + this.getPermission() + ", aliases=" + Arrays.deepToString(this.getAliases()) + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
/**
|
||||
* Dummy class which all callable events must extend.
|
||||
*/
|
||||
public abstract class Event
|
||||
{
|
||||
|
||||
/**
|
||||
* Method called after this event has been dispatched to all handlers.
|
||||
*/
|
||||
public void postCall()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
/**
|
||||
* Dummy interface which all event subscribers and listeners must implement.
|
||||
*/
|
||||
public interface Listener
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Logger;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
|
||||
/**
|
||||
* Represents any Plugin that may be loaded at runtime to enhance existing
|
||||
* functionality.
|
||||
*/
|
||||
public class Plugin
|
||||
{
|
||||
private PluginDescription description;
|
||||
private ProxyServer proxy;
|
||||
private File file;
|
||||
private Logger logger;
|
||||
|
||||
protected Plugin() {
|
||||
}
|
||||
|
||||
protected Plugin(PluginDescription forceDesc) {
|
||||
this.description = forceDesc;
|
||||
}
|
||||
|
||||
public PluginDescription getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public ProxyServer getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the plugin has just been loaded. Most of the proxy will not
|
||||
* be initialized, so only use it for registering
|
||||
* {@link ConfigurationAdapter}'s and other predefined behavior.
|
||||
*/
|
||||
public void onLoad()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this plugin is enabled.
|
||||
*/
|
||||
public void onEnable()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this plugin is disabled.
|
||||
*/
|
||||
public void onDisable()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data folder where this plugin may store arbitrary data. It will
|
||||
* be a child of {@link ProxyServer#getPluginsFolder()}.
|
||||
*
|
||||
* @return the data folder of this plugin
|
||||
*/
|
||||
public final File getDataFolder()
|
||||
{
|
||||
return new File( getProxy().getPluginsFolder(), getDescription().getName() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a resource from within this plugins jar or container. Care must be
|
||||
* taken to close the returned stream.
|
||||
*
|
||||
* @param name the full path name of this resource
|
||||
* @return the stream for getting this resource, or null if it does not
|
||||
* exist
|
||||
*/
|
||||
public final InputStream getResourceAsStream(String name)
|
||||
{
|
||||
return getClass().getClassLoader().getResourceAsStream( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the loader to initialize the fields in this plugin.
|
||||
*
|
||||
*/
|
||||
final void init(ProxyServer proxy, PluginDescription description)
|
||||
{
|
||||
this.proxy = proxy;
|
||||
this.description = description;
|
||||
this.file = description.getFile();
|
||||
this.logger = new PluginLogger( this );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class PluginClassloader extends URLClassLoader
|
||||
{
|
||||
|
||||
private static final Set<PluginClassloader> allLoaders = new CopyOnWriteArraySet<>();
|
||||
|
||||
static
|
||||
{
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
public PluginClassloader(URL[] urls)
|
||||
{
|
||||
super( urls );
|
||||
allLoaders.add( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
|
||||
{
|
||||
return loadClass0( name, resolve, true );
|
||||
}
|
||||
|
||||
private Class<?> loadClass0(String name, boolean resolve, boolean checkOther) throws ClassNotFoundException
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.loadClass( name, resolve );
|
||||
} catch ( ClassNotFoundException ex )
|
||||
{
|
||||
}
|
||||
if ( checkOther )
|
||||
{
|
||||
for ( PluginClassloader loader : allLoaders )
|
||||
{
|
||||
if ( loader != this )
|
||||
{
|
||||
try
|
||||
{
|
||||
return loader.loadClass0( name, resolve, false );
|
||||
} catch ( ClassNotFoundException ex )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ClassNotFoundException( name );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
/**
|
||||
* POJO representing the plugin.yml file.
|
||||
*/
|
||||
|
||||
//@Data
|
||||
|
||||
public class PluginDescription
|
||||
{
|
||||
public PluginDescription(){
|
||||
|
||||
}
|
||||
|
||||
public PluginDescription(String name, String main, String version, String author, Set<String> depends, File file) {
|
||||
this.name = name;
|
||||
this.main = main;
|
||||
this.version = version;
|
||||
this.author = author;
|
||||
this.depends = depends;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getMain() {
|
||||
return main;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Set<String> getDepends() {
|
||||
return depends;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setMain(String main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public void setDepends(Set<String> depends) {
|
||||
this.depends = depends;
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Friendly name of the plugin.
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* Plugin main class. Needs to extend {@link Plugin}.
|
||||
*/
|
||||
private String main;
|
||||
/**
|
||||
* Plugin version.
|
||||
*/
|
||||
private String version;
|
||||
/**
|
||||
* Plugin author.
|
||||
*/
|
||||
private String author;
|
||||
/**
|
||||
* Plugin hard dependencies.
|
||||
*/
|
||||
private Set<String> depends = new HashSet<>();
|
||||
/**
|
||||
* File we were loaded from.
|
||||
*/
|
||||
private File file = null;
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
public class PluginLogger extends Logger
|
||||
{
|
||||
|
||||
private String pluginName;
|
||||
|
||||
protected PluginLogger(Plugin plugin)
|
||||
{
|
||||
super( plugin.getClass().getCanonicalName(), null );
|
||||
pluginName = "[" + plugin.getDescription().getName() + "] ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(LogRecord logRecord)
|
||||
{
|
||||
logRecord.setMessage( pluginName + logRecord.getMessage() );
|
||||
ProxyServer.getInstance().getLogger().log( logRecord );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.event.EventBus;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Class to manage bridging between plugin duties and implementation duties, for
|
||||
* example event handling and plugin management.
|
||||
*/
|
||||
public class PluginManager
|
||||
{
|
||||
|
||||
private static final Pattern argsSplit = Pattern.compile( " " );
|
||||
/*========================================================================*/
|
||||
private final ProxyServer proxy;
|
||||
/*========================================================================*/
|
||||
private final Yaml yaml = new Yaml();
|
||||
private final EventBus eventBus;
|
||||
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
||||
private final Map<String, Command> commandMap = new HashMap<>();
|
||||
private Map<String, PluginDescription> toLoad = new HashMap<>();
|
||||
private Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create();
|
||||
private Multimap<Plugin, Listener> listenersByPlugin = ArrayListMultimap.create();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public PluginManager(ProxyServer proxy)
|
||||
{
|
||||
this.proxy = proxy;
|
||||
eventBus = new EventBus( proxy.getLogger() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command so that it may be executed.
|
||||
*
|
||||
* @param plugin the plugin owning this command
|
||||
* @param command the command to register
|
||||
*/
|
||||
public void registerCommand(Plugin plugin, Command command)
|
||||
{
|
||||
commandMap.put( command.getName().toLowerCase(), command );
|
||||
for ( String alias : command.getAliases() )
|
||||
{
|
||||
commandMap.put( alias.toLowerCase(), command );
|
||||
}
|
||||
commandsByPlugin.put( plugin, command );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a command so it will no longer be executed.
|
||||
*
|
||||
* @param command the command to unregister
|
||||
*/
|
||||
public void unregisterCommand(Command command)
|
||||
{
|
||||
commandMap.values().remove( command );
|
||||
commandsByPlugin.values().remove( command );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all commands owned by a {@link Plugin}
|
||||
*
|
||||
* @param plugin the plugin to register the commands of
|
||||
*/
|
||||
public void unregisterCommands(Plugin plugin)
|
||||
{
|
||||
for ( Iterator<Command> it = commandsByPlugin.get( plugin ).iterator(); it.hasNext(); )
|
||||
{
|
||||
commandMap.values().remove( it.next() );
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean dispatchCommand(CommandSender sender, String commandLine)
|
||||
{
|
||||
return dispatchCommand( sender, commandLine, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command if it is registered, else return false.
|
||||
*
|
||||
* @param sender the sender executing the command
|
||||
* @param commandLine the complete command line including command name and
|
||||
* arguments
|
||||
* @return whether the command was handled
|
||||
*/
|
||||
public boolean dispatchCommand(CommandSender sender, String commandLine, List<String> tabResults)
|
||||
{
|
||||
String[] split = argsSplit.split( commandLine );
|
||||
// Check for chat that only contains " "
|
||||
if ( split.length == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String commandName = split[0].toLowerCase();
|
||||
if ( proxy.getDisabledCommands().contains( commandName ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Command command = commandMap.get( commandName );
|
||||
if ( command == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String permission = command.getPermission();
|
||||
if ( permission != null && !permission.isEmpty() && !sender.hasPermission( permission ) )
|
||||
{
|
||||
sender.sendMessage( proxy.getTranslation( "no_permission" ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
String[] args = Arrays.copyOfRange( split, 1, split.length );
|
||||
try
|
||||
{
|
||||
if ( tabResults == null )
|
||||
{
|
||||
command.execute( sender, args );
|
||||
} else if ( command instanceof TabExecutor )
|
||||
{
|
||||
for ( String s : ( (TabExecutor) command ).onTabComplete( sender, args ) )
|
||||
{
|
||||
tabResults.add( s );
|
||||
}
|
||||
}
|
||||
} catch ( Exception ex )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details." );
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Error in dispatching command", ex );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Plugin} objects corresponding to all loaded plugins.
|
||||
*
|
||||
* @return the set of loaded plugins
|
||||
*/
|
||||
public Collection<Plugin> getPlugins()
|
||||
{
|
||||
return plugins.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a loaded plugin identified by the specified name.
|
||||
*
|
||||
* @param name of the plugin to retrieve
|
||||
* @return the retrieved plugin or null if not loaded
|
||||
*/
|
||||
public Plugin getPlugin(String name)
|
||||
{
|
||||
return plugins.get( name );
|
||||
}
|
||||
|
||||
public void loadAndEnablePlugins()
|
||||
{
|
||||
Map<PluginDescription, Boolean> pluginStatuses = new HashMap<>();
|
||||
for ( Map.Entry<String, PluginDescription> entry : toLoad.entrySet() )
|
||||
{
|
||||
PluginDescription plugin = entry.getValue();
|
||||
if ( !enablePlugin( pluginStatuses, new Stack<PluginDescription>(), plugin ) )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().warning( "Failed to enable " + entry.getKey() );
|
||||
}
|
||||
}
|
||||
toLoad.clear();
|
||||
toLoad = null;
|
||||
|
||||
for ( Plugin plugin : plugins.values() )
|
||||
{
|
||||
try
|
||||
{
|
||||
plugin.onEnable();
|
||||
ProxyServer.getInstance().getLogger().log( Level.INFO, "Enabled plugin {0} version {1} by {2}", new Object[]
|
||||
{
|
||||
plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getAuthor()
|
||||
} );
|
||||
} catch ( Throwable t )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Exception encountered when loading plugin: " + plugin.getDescription().getName(), t );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean enablePlugin(Map<PluginDescription, Boolean> pluginStatuses, Stack<PluginDescription> dependStack, PluginDescription plugin)
|
||||
{
|
||||
if ( pluginStatuses.containsKey( plugin ) )
|
||||
{
|
||||
return pluginStatuses.get( plugin );
|
||||
}
|
||||
|
||||
// success status
|
||||
boolean status = true;
|
||||
|
||||
// try to load dependencies first
|
||||
for ( String dependName : plugin.getDepends() )
|
||||
{
|
||||
PluginDescription depend = toLoad.get( dependName );
|
||||
Boolean dependStatus = ( depend != null ) ? pluginStatuses.get( depend ) : Boolean.FALSE;
|
||||
|
||||
if ( dependStatus == null )
|
||||
{
|
||||
if ( dependStack.contains( depend ) )
|
||||
{
|
||||
StringBuilder dependencyGraph = new StringBuilder();
|
||||
for ( PluginDescription element : dependStack )
|
||||
{
|
||||
dependencyGraph.append( element.getName() ).append( " -> " );
|
||||
}
|
||||
dependencyGraph.append( plugin.getName() ).append( " -> " ).append( dependName );
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Circular dependency detected: " + dependencyGraph );
|
||||
status = false;
|
||||
} else
|
||||
{
|
||||
dependStack.push( plugin );
|
||||
dependStatus = this.enablePlugin( pluginStatuses, dependStack, depend );
|
||||
dependStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if ( dependStatus == Boolean.FALSE )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} (required by {1}) is unavailable", new Object[]
|
||||
{
|
||||
String.valueOf( depend.getName() ), plugin.getName()
|
||||
} );
|
||||
status = false;
|
||||
}
|
||||
|
||||
if ( !status )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do actual loading
|
||||
if ( status )
|
||||
{
|
||||
try
|
||||
{
|
||||
URLClassLoader loader = new PluginClassloader( new URL[]
|
||||
{
|
||||
plugin.getFile().toURI().toURL()
|
||||
} );
|
||||
Class<?> main = loader.loadClass( plugin.getMain() );
|
||||
Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance();
|
||||
|
||||
clazz.init( proxy, plugin );
|
||||
plugins.put( plugin.getName(), clazz );
|
||||
clazz.onLoad();
|
||||
ProxyServer.getInstance().getLogger().log( Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[]
|
||||
{
|
||||
plugin.getName(), plugin.getVersion(), plugin.getAuthor()
|
||||
} );
|
||||
} catch ( Throwable t )
|
||||
{
|
||||
proxy.getLogger().log( Level.WARNING, "Error enabling plugin " + plugin.getName(), t );
|
||||
}
|
||||
}
|
||||
|
||||
pluginStatuses.put( plugin, status );
|
||||
return status;
|
||||
}
|
||||
|
||||
public void addInternalPlugin(Plugin plug) {
|
||||
this.plugins.put(plug.getDescription().getName(), plug);
|
||||
plug.init(proxy, plug.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all plugins from the specified folder.
|
||||
*
|
||||
* @param folder the folder to search for plugins in
|
||||
*/
|
||||
public void detectPlugins(File folder)
|
||||
{
|
||||
Preconditions.checkNotNull( folder, "folder" );
|
||||
Preconditions.checkArgument( folder.isDirectory(), "Must load from a directory" );
|
||||
|
||||
for ( File file : folder.listFiles() )
|
||||
{
|
||||
if ( file.isFile() && file.getName().endsWith( ".jar" ) )
|
||||
{
|
||||
try ( JarFile jar = new JarFile( file ) )
|
||||
{
|
||||
JarEntry pdf = jar.getJarEntry( "plugin.yml" );
|
||||
Preconditions.checkNotNull( pdf, "Plugin must have a plugin.yml" );
|
||||
|
||||
try ( InputStream in = jar.getInputStream( pdf ) )
|
||||
{
|
||||
PluginDescription desc = yaml.loadAs( in, PluginDescription.class );
|
||||
desc.setFile( file );
|
||||
toLoad.put( desc.getName(), desc );
|
||||
}
|
||||
} catch ( Exception ex )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load plugin from file " + file, ex );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch an event to all subscribed listeners and return the event once
|
||||
* it has been handled by these listeners.
|
||||
*
|
||||
* @param <T> the type bounds, must be a class which extends event
|
||||
* @param event the event to call
|
||||
* @return the called event
|
||||
*/
|
||||
public <T extends Event> T callEvent(T event)
|
||||
{
|
||||
Preconditions.checkNotNull( event, "event" );
|
||||
|
||||
long start = System.nanoTime();
|
||||
eventBus.post( event );
|
||||
event.postCall();
|
||||
|
||||
long elapsed = start - System.nanoTime();
|
||||
if ( elapsed > 250000 )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Event {0} took more {1}ns to process!", new Object[]
|
||||
{
|
||||
event, elapsed
|
||||
} );
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link Listener} for receiving called events. Methods in this
|
||||
* Object which wish to receive events must be annotated with the
|
||||
* {@link EventHandler} annotation.
|
||||
*
|
||||
* @param plugin the owning plugin
|
||||
* @param listener the listener to register events for
|
||||
*/
|
||||
public void registerListener(Plugin plugin, Listener listener)
|
||||
{
|
||||
for ( Method method : listener.getClass().getDeclaredMethods() )
|
||||
{
|
||||
Preconditions.checkArgument( !method.isAnnotationPresent( Subscribe.class ),
|
||||
"Listener %s has registered using deprecated subscribe annotation! Please update to @EventHandler.", listener );
|
||||
}
|
||||
eventBus.register( listener );
|
||||
listenersByPlugin.put( plugin, listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a {@link Listener} so that the events do not reach it anymore.
|
||||
*
|
||||
* @param listener the listener to unregister
|
||||
*/
|
||||
public void unregisterListener(Listener listener)
|
||||
{
|
||||
eventBus.unregister( listener );
|
||||
listenersByPlugin.values().remove( listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all of a Plugin's listener.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public void unregisterListeners(Plugin plugin)
|
||||
{
|
||||
for ( Iterator<Listener> it = listenersByPlugin.get( plugin ).iterator(); it.hasNext(); )
|
||||
{
|
||||
eventBus.unregister( it.next() );
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
|
||||
public interface TabExecutor
|
||||
{
|
||||
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package net.md_5.bungee.api.scheduler;
|
||||
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents a task scheduled for execution by the {@link TaskScheduler}.
|
||||
*/
|
||||
public interface ScheduledTask
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the unique ID of this task.
|
||||
*
|
||||
* @return this tasks ID
|
||||
*/
|
||||
int getId();
|
||||
|
||||
/**
|
||||
* Return the plugin which scheduled this task for execution.
|
||||
*
|
||||
* @return the owning plugin
|
||||
*/
|
||||
Plugin getOwner();
|
||||
|
||||
/**
|
||||
* Get the actual method which will be executed by this task.
|
||||
*
|
||||
* @return the {@link Runnable} behind this task
|
||||
*/
|
||||
Runnable getTask();
|
||||
|
||||
/**
|
||||
* Cancel this task to suppress subsequent executions.
|
||||
*/
|
||||
void cancel();
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package net.md_5.bungee.api.scheduler;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* This interface represents a scheduler which may be used to queue, delay and
|
||||
* execute tasks in an asynchronous fashion.
|
||||
*/
|
||||
public interface TaskScheduler
|
||||
{
|
||||
|
||||
/**
|
||||
* Cancel a task to prevent it from executing, or if its a repeating task,
|
||||
* prevent its further execution.
|
||||
*
|
||||
* @param id the id of the task to cancel
|
||||
*/
|
||||
void cancel(int id);
|
||||
|
||||
/**
|
||||
* Cancel a task to prevent it from executing, or if its a repeating task,
|
||||
* prevent its further execution.
|
||||
*
|
||||
* @param task the task to cancel
|
||||
*/
|
||||
void cancel(ScheduledTask task);
|
||||
|
||||
/**
|
||||
* Cancel all tasks owned by this plugin, this preventing them from being
|
||||
* executed hereon in.
|
||||
*
|
||||
* @param plugin the plugin owning the tasks to be cancelled
|
||||
* @return the number of tasks cancelled by this method
|
||||
*/
|
||||
int cancel(Plugin plugin);
|
||||
|
||||
/**
|
||||
* Schedule a task to be executed asynchronously. The task will commence
|
||||
* running as soon as this method returns.
|
||||
*
|
||||
* @param owner the plugin owning this task
|
||||
* @param task the task to run
|
||||
* @return the scheduled task
|
||||
*/
|
||||
ScheduledTask runAsync(Plugin owner, Runnable task);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed asynchronously after the specified delay
|
||||
* is up.
|
||||
*
|
||||
* @param owner the plugin owning this task
|
||||
* @param task the task to run
|
||||
* @param delay the delay before this task will be executed
|
||||
* @param unit the unit in which the delay will be measured
|
||||
* @return the scheduled task
|
||||
*/
|
||||
ScheduledTask schedule(Plugin owner, Runnable task, long delay, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed asynchronously after the specified delay
|
||||
* is up. The scheduled task will continue running at the specified
|
||||
* interval. The interval will not begin to count down until the last task
|
||||
* invocation is complete.
|
||||
*
|
||||
* @param owner the plugin owning this task
|
||||
* @param task the task to run
|
||||
* @param delay the delay in milliseconds before this task will be executed
|
||||
* @param period the interval before subsequent executions of this task
|
||||
* @param unit the unit in which the delay and period will be measured
|
||||
* @return the scheduled task
|
||||
*/
|
||||
ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
/**
|
||||
* Represents an objective entry.
|
||||
*/
|
||||
public class Objective
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of the objective.
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* Value of the objective.
|
||||
*/
|
||||
private final String value; // displayName
|
||||
|
||||
@ConstructorProperties({ "name", "value" })
|
||||
public Objective(final String name, final String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Objective)) {
|
||||
return false;
|
||||
}
|
||||
final Objective other = (Objective) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$name = this.getName();
|
||||
final Object other$name = other.getName();
|
||||
Label_0065: {
|
||||
if (this$name == null) {
|
||||
if (other$name == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$name.equals(other$name)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$value = this.getValue();
|
||||
final Object other$value = other.getValue();
|
||||
if (this$value == null) {
|
||||
if (other$value == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$value.equals(other$value)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof Objective;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $name = this.getName();
|
||||
result = result * 31 + (($name == null) ? 0 : $name.hashCode());
|
||||
final Object $value = this.getValue();
|
||||
result = result * 31 + (($value == null) ? 0 : $value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Objective(name=" + this.getName() + ", value=" + this.getValue() + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
/**
|
||||
* Represents locations for a scoreboard to be displayed.
|
||||
*/
|
||||
public enum Position
|
||||
{
|
||||
|
||||
LIST, SIDEBAR, BELOW;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
/**
|
||||
* Represents a scoreboard score entry.
|
||||
*/
|
||||
public class Score
|
||||
{
|
||||
|
||||
/**
|
||||
* Name to be displayed in the list.
|
||||
*/
|
||||
private final String itemName; // Player
|
||||
/**
|
||||
* Unique name of the score.
|
||||
*/
|
||||
private final String scoreName; // Score
|
||||
/**
|
||||
* Value of the score.
|
||||
*/
|
||||
private final int value;
|
||||
|
||||
@ConstructorProperties({ "itemName", "scoreName", "value" })
|
||||
public Score(final String itemName, final String scoreName, final int value) {
|
||||
this.itemName = itemName;
|
||||
this.scoreName = scoreName;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return this.itemName;
|
||||
}
|
||||
|
||||
public String getScoreName() {
|
||||
return this.scoreName;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Score)) {
|
||||
return false;
|
||||
}
|
||||
final Score other = (Score) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$itemName = this.getItemName();
|
||||
final Object other$itemName = other.getItemName();
|
||||
Label_0065: {
|
||||
if (this$itemName == null) {
|
||||
if (other$itemName == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$itemName.equals(other$itemName)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$scoreName = this.getScoreName();
|
||||
final Object other$scoreName = other.getScoreName();
|
||||
if (this$scoreName == null) {
|
||||
if (other$scoreName == null) {
|
||||
return this.getValue() == other.getValue();
|
||||
}
|
||||
} else if (this$scoreName.equals(other$scoreName)) {
|
||||
return this.getValue() == other.getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof Score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $itemName = this.getItemName();
|
||||
result = result * 31 + (($itemName == null) ? 0 : $itemName.hashCode());
|
||||
final Object $scoreName = this.getScoreName();
|
||||
result = result * 31 + (($scoreName == null) ? 0 : $scoreName.hashCode());
|
||||
result = result * 31 + this.getValue();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Score(itemName=" + this.getItemName() + ", scoreName=" + this.getScoreName() + ", value=" + this.getValue() + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public class Scoreboard {
|
||||
private String name;
|
||||
private Position position;
|
||||
private final Map<String, Objective> objectives;
|
||||
private final Map<String, Score> scores;
|
||||
private final Map<String, Team> teams;
|
||||
|
||||
public Collection<Objective> getObjectives() {
|
||||
return Collections.unmodifiableCollection((Collection<? extends Objective>) this.objectives.values());
|
||||
}
|
||||
|
||||
public Collection<Score> getScores() {
|
||||
return Collections.unmodifiableCollection((Collection<? extends Score>) this.scores.values());
|
||||
}
|
||||
|
||||
public Collection<Team> getTeams() {
|
||||
return Collections.unmodifiableCollection((Collection<? extends Team>) this.teams.values());
|
||||
}
|
||||
|
||||
public void addObjective(final Objective objective) {
|
||||
Preconditions.checkNotNull((Object) objective, (Object) "objective");
|
||||
Preconditions.checkArgument(!this.objectives.containsKey(objective.getName()), "Objective %s already exists in this scoreboard", new Object[] { objective.getName() });
|
||||
this.objectives.put(objective.getName(), objective);
|
||||
}
|
||||
|
||||
public void addScore(final Score score) {
|
||||
Preconditions.checkNotNull((Object) score, (Object) "score");
|
||||
this.scores.put(score.getItemName(), score);
|
||||
}
|
||||
|
||||
public void addTeam(final Team team) {
|
||||
Preconditions.checkNotNull((Object) team, (Object) "team");
|
||||
Preconditions.checkArgument(!this.teams.containsKey(team.getName()), "Team %s already exists in this scoreboard", new Object[] { team.getName() });
|
||||
this.teams.put(team.getName(), team);
|
||||
}
|
||||
|
||||
public Team getTeam(final String name) {
|
||||
return this.teams.get(name);
|
||||
}
|
||||
|
||||
public void removeObjective(final String objectiveName) {
|
||||
this.objectives.remove(objectiveName);
|
||||
}
|
||||
|
||||
public void removeScore(final String scoreName) {
|
||||
this.scores.remove(scoreName);
|
||||
}
|
||||
|
||||
public void removeTeam(final String teamName) {
|
||||
this.teams.remove(teamName);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.name = null;
|
||||
this.position = null;
|
||||
this.objectives.clear();
|
||||
this.scores.clear();
|
||||
this.teams.clear();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setPosition(final Position position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Scoreboard)) {
|
||||
return false;
|
||||
}
|
||||
final Scoreboard other = (Scoreboard) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$name = this.getName();
|
||||
final Object other$name = other.getName();
|
||||
Label_0065: {
|
||||
if (this$name == null) {
|
||||
if (other$name == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$name.equals(other$name)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$position = this.getPosition();
|
||||
final Object other$position = other.getPosition();
|
||||
Label_0102: {
|
||||
if (this$position == null) {
|
||||
if (other$position == null) {
|
||||
break Label_0102;
|
||||
}
|
||||
} else if (this$position.equals(other$position)) {
|
||||
break Label_0102;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$objectives = this.getObjectives();
|
||||
final Object other$objectives = other.getObjectives();
|
||||
Label_0139: {
|
||||
if (this$objectives == null) {
|
||||
if (other$objectives == null) {
|
||||
break Label_0139;
|
||||
}
|
||||
} else if (this$objectives.equals(other$objectives)) {
|
||||
break Label_0139;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$scores = this.getScores();
|
||||
final Object other$scores = other.getScores();
|
||||
Label_0176: {
|
||||
if (this$scores == null) {
|
||||
if (other$scores == null) {
|
||||
break Label_0176;
|
||||
}
|
||||
} else if (this$scores.equals(other$scores)) {
|
||||
break Label_0176;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$teams = this.getTeams();
|
||||
final Object other$teams = other.getTeams();
|
||||
if (this$teams == null) {
|
||||
if (other$teams == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$teams.equals(other$teams)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof Scoreboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $name = this.getName();
|
||||
result = result * 31 + (($name == null) ? 0 : $name.hashCode());
|
||||
final Object $position = this.getPosition();
|
||||
result = result * 31 + (($position == null) ? 0 : $position.hashCode());
|
||||
final Object $objectives = this.getObjectives();
|
||||
result = result * 31 + (($objectives == null) ? 0 : $objectives.hashCode());
|
||||
final Object $scores = this.getScores();
|
||||
result = result * 31 + (($scores == null) ? 0 : $scores.hashCode());
|
||||
final Object $teams = this.getTeams();
|
||||
result = result * 31 + (($teams == null) ? 0 : $teams.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Scoreboard(name=" + this.getName() + ", position=" + this.getPosition() + ", objectives=" + this.getObjectives() + ", scores=" + this.getScores() + ", teams=" + this.getTeams() + ")";
|
||||
}
|
||||
|
||||
public Scoreboard() {
|
||||
this.objectives = new HashMap<String, Objective>();
|
||||
this.scores = new HashMap<String, Score>();
|
||||
this.teams = new HashMap<String, Team>();
|
||||
}
|
||||
}
|
||||
183
eaglerbungee/src/main/java/net/md_5/bungee/api/score/Team.java
Normal file
183
eaglerbungee/src/main/java/net/md_5/bungee/api/score/Team.java
Normal file
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Team {
|
||||
private final String name;
|
||||
private String displayName;
|
||||
private String prefix;
|
||||
private String suffix;
|
||||
private boolean friendlyFire;
|
||||
private Set<String> players;
|
||||
|
||||
public Collection<String> getPlayers() {
|
||||
return (Collection<String>) (Collection<?>) Collections.unmodifiableSet((Set<?>) this.players);
|
||||
}
|
||||
|
||||
public void addPlayer(final String name) {
|
||||
this.players.add(name);
|
||||
}
|
||||
|
||||
public void removePlayer(final String name) {
|
||||
this.players.remove(name);
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "name" })
|
||||
public Team(final String name) {
|
||||
this.players = new HashSet<String>();
|
||||
if (name == null) {
|
||||
throw new NullPointerException("name");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return this.suffix;
|
||||
}
|
||||
|
||||
public boolean isFriendlyFire() {
|
||||
return this.friendlyFire;
|
||||
}
|
||||
|
||||
public void setDisplayName(final String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public void setPrefix(final String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public void setSuffix(final String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public void setFriendlyFire(final boolean friendlyFire) {
|
||||
this.friendlyFire = friendlyFire;
|
||||
}
|
||||
|
||||
public void setPlayers(final Set<String> players) {
|
||||
this.players = players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Team)) {
|
||||
return false;
|
||||
}
|
||||
final Team other = (Team) o;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$name = this.getName();
|
||||
final Object other$name = other.getName();
|
||||
Label_0065: {
|
||||
if (this$name == null) {
|
||||
if (other$name == null) {
|
||||
break Label_0065;
|
||||
}
|
||||
} else if (this$name.equals(other$name)) {
|
||||
break Label_0065;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$displayName = this.getDisplayName();
|
||||
final Object other$displayName = other.getDisplayName();
|
||||
Label_0102: {
|
||||
if (this$displayName == null) {
|
||||
if (other$displayName == null) {
|
||||
break Label_0102;
|
||||
}
|
||||
} else if (this$displayName.equals(other$displayName)) {
|
||||
break Label_0102;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$prefix = this.getPrefix();
|
||||
final Object other$prefix = other.getPrefix();
|
||||
Label_0139: {
|
||||
if (this$prefix == null) {
|
||||
if (other$prefix == null) {
|
||||
break Label_0139;
|
||||
}
|
||||
} else if (this$prefix.equals(other$prefix)) {
|
||||
break Label_0139;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final Object this$suffix = this.getSuffix();
|
||||
final Object other$suffix = other.getSuffix();
|
||||
Label_0176: {
|
||||
if (this$suffix == null) {
|
||||
if (other$suffix == null) {
|
||||
break Label_0176;
|
||||
}
|
||||
} else if (this$suffix.equals(other$suffix)) {
|
||||
break Label_0176;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (this.isFriendlyFire() != other.isFriendlyFire()) {
|
||||
return false;
|
||||
}
|
||||
final Object this$players = this.getPlayers();
|
||||
final Object other$players = other.getPlayers();
|
||||
if (this$players == null) {
|
||||
if (other$players == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (this$players.equals(other$players)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object other) {
|
||||
return other instanceof Team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
final Object $name = this.getName();
|
||||
result = result * 31 + (($name == null) ? 0 : $name.hashCode());
|
||||
final Object $displayName = this.getDisplayName();
|
||||
result = result * 31 + (($displayName == null) ? 0 : $displayName.hashCode());
|
||||
final Object $prefix = this.getPrefix();
|
||||
result = result * 31 + (($prefix == null) ? 0 : $prefix.hashCode());
|
||||
final Object $suffix = this.getSuffix();
|
||||
result = result * 31 + (($suffix == null) ? 0 : $suffix.hashCode());
|
||||
result = result * 31 + (this.isFriendlyFire() ? 1231 : 1237);
|
||||
final Object $players = this.getPlayers();
|
||||
result = result * 31 + (($players == null) ? 0 : $players.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Team(name=" + this.getName() + ", displayName=" + this.getDisplayName() + ", prefix=" + this.getPrefix() + ", suffix=" + this.getSuffix() + ", friendlyFire=" + this.isFriendlyFire() + ", players=" + this.getPlayers() + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package net.md_5.bungee.api.tab;
|
||||
|
||||
/**
|
||||
* Represents a custom tab list, which may have slots manipulated.
|
||||
*/
|
||||
public interface CustomTabList extends TabListHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Blank out this tab list and update immediately.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Gets the columns in this list.
|
||||
*
|
||||
* @return the width of this list
|
||||
*/
|
||||
int getColumns();
|
||||
|
||||
/**
|
||||
* Gets the rows in this list.
|
||||
*
|
||||
* @return the height of this list
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Get the total size of this list.
|
||||
*
|
||||
* @return {@link #getRows()} * {@link #getColumns()}
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
/**
|
||||
* Set the text in the specified slot and update immediately.
|
||||
*
|
||||
* @param row the row to set
|
||||
* @param column the column to set
|
||||
* @param text the text to set
|
||||
* @return the padded text
|
||||
*/
|
||||
String setSlot(int row, int column, String text);
|
||||
|
||||
/**
|
||||
* Set the text in the specified slot.
|
||||
*
|
||||
* @param row the row to set
|
||||
* @param column the column to set
|
||||
* @param text the text to set
|
||||
* @param update whether or not to invoke {@link #update()} upon completion
|
||||
* @return the padded text
|
||||
*/
|
||||
String setSlot(int row, int column, String text, boolean update);
|
||||
|
||||
/**
|
||||
* Flush all queued changes to the user.
|
||||
*/
|
||||
void update();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.api.tab;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public abstract class TabListAdapter implements TabListHandler {
|
||||
private ProxiedPlayer player;
|
||||
|
||||
@Override
|
||||
public void init(final ProxiedPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerChange() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingChange(final int ping) {
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.md_5.bungee.api.tab;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public interface TabListHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Called so that this class may set member fields to keep track of its
|
||||
* internal state. You should not do any packet sending or manipulation of
|
||||
* the passed player, other than storing it.
|
||||
*
|
||||
* @param player the player to be associated with this list
|
||||
*/
|
||||
void init(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Called when this player first connects to the proxy.
|
||||
*/
|
||||
void onConnect();
|
||||
|
||||
/**
|
||||
* Called when a player first connects to the proxy.
|
||||
*
|
||||
* @param player the connecting player
|
||||
*/
|
||||
void onServerChange();
|
||||
|
||||
/**
|
||||
* Called when a players ping changes. The new ping will have not updated in
|
||||
* the player instance until this method returns.
|
||||
*
|
||||
* @param player the player who's ping changed
|
||||
* @param ping the player's new ping.
|
||||
*/
|
||||
void onPingChange(int ping);
|
||||
|
||||
/**
|
||||
* Called when a player disconnects.
|
||||
*
|
||||
* @param player the disconnected player
|
||||
*/
|
||||
void onDisconnect();
|
||||
|
||||
/**
|
||||
* Called when a list update packet is sent from server to client.
|
||||
*
|
||||
* @param player receiving this packet
|
||||
* @param name the player which this packet is relevant to
|
||||
* @param online whether the subject player is online
|
||||
* @param ping ping of the subject player
|
||||
* @return whether to send the packet to the client
|
||||
*/
|
||||
boolean onListUpdate(String name, boolean online, int ping);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
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.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandAlert extends Command
|
||||
{
|
||||
|
||||
public CommandAlert()
|
||||
{
|
||||
super( "alert", "bungeecord.command.alert" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
if ( args.length == 0 )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "You must supply a message." );
|
||||
} else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if ( args[0].startsWith( "&h" ) )
|
||||
{
|
||||
// Remove &h
|
||||
args[0] = args[0].substring( 2, args[0].length() );
|
||||
} else
|
||||
{
|
||||
builder.append( ProxyServer.getInstance().getTranslation( "alert" ) );
|
||||
}
|
||||
|
||||
for ( String s : args )
|
||||
{
|
||||
builder.append( ChatColor.translateAlternateColorCodes( '&', s ) );
|
||||
builder.append( " " );
|
||||
}
|
||||
|
||||
String message = builder.substring( 0, builder.length() - 1 );
|
||||
|
||||
ProxyServer.getInstance().broadcast( message );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.ProxyServer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandBungee extends Command
|
||||
{
|
||||
|
||||
public CommandBungee()
|
||||
{
|
||||
super( "bungee" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
sender.sendMessage( ChatColor.BLUE + "This server is running BungeeCord version " + ProxyServer.getInstance().getVersion() + " by md_5" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
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.AuthSystem;
|
||||
|
||||
public class CommandChangePassword extends Command {
|
||||
private final AuthSystem authSystem;
|
||||
|
||||
public CommandChangePassword(AuthSystem authSystem) {
|
||||
super("changepassword", "bungeecord.command.eag.changepassword",
|
||||
new String[] { "changepwd", "changepasswd", "changepass" });
|
||||
this.authSystem = authSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final CommandSender sender, final String[] args) {
|
||||
if (!(sender instanceof ProxiedPlayer)) {
|
||||
return;
|
||||
}
|
||||
String username = sender.getName();
|
||||
if (args.length == 0 || args.length == 1) {
|
||||
sender.sendMessage("\u00A7cUsage: /changepassword <oldPassword> <newPassword>");
|
||||
} else if (this.authSystem.login(username, args[0])) {
|
||||
if (this.authSystem.changePass(username, args[1])) {
|
||||
sender.sendMessage("\u00A7cPassword changed successfully!");
|
||||
} else {
|
||||
sender.sendMessage("\u00A7cUnable to change your password...");
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage("\u00A7cThe old password specified is incorrect!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
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.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandClearRatelimit extends Command {
|
||||
|
||||
public CommandClearRatelimit() {
|
||||
super("eag-ratelimit", "bungeecord.command.eag.ratelimit", "e-ratelimit", "gratelimit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender p0, String[] p1) {
|
||||
if(p1.length >= 1 && ("clear".equalsIgnoreCase(p1[0]) || "reset".equalsIgnoreCase(p1[0]))) {
|
||||
if(p1.length == 1 || (p1.length == 2 && "all".equalsIgnoreCase(p1[1]))) {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getRateLimitIP() != null) l.getRateLimitIP().resetLimiters();
|
||||
if(l.getRateLimitLogin() != null) l.getRateLimitLogin().resetLimiters();
|
||||
if(l.getRateLimitMOTD() != null) l.getRateLimitMOTD().resetLimiters();
|
||||
if(l.getRateLimitQuery() != null) l.getRateLimitQuery().resetLimiters();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all ratelimits");
|
||||
return;
|
||||
}else if(p1.length == 2 || p1.length == 3) {
|
||||
ListenerInfo ll = null;
|
||||
if(p1.length == 3) {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getHostString().equalsIgnoreCase(p1[2])) {
|
||||
ll = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ll == null) {
|
||||
p0.sendMessage(ChatColor.RED + "Listener does not exist: " + ChatColor.WHITE + p1[2]);
|
||||
String accum = "";
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(accum.length() > 0) {
|
||||
accum += ", ";
|
||||
}
|
||||
accum += l.getHostString();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Listeners Available: " + ChatColor.WHITE + accum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if("all".equalsIgnoreCase(p1[1])) {
|
||||
if(ll != null) {
|
||||
if(ll.getRateLimitIP() != null) ll.getRateLimitIP().resetLimiters();
|
||||
if(ll.getRateLimitLogin() != null) ll.getRateLimitLogin().resetLimiters();
|
||||
if(ll.getRateLimitMOTD() != null) ll.getRateLimitMOTD().resetLimiters();
|
||||
if(ll.getRateLimitQuery() != null) ll.getRateLimitQuery().resetLimiters();
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all ratelimits on listener: " + ChatColor.WHITE + ll.getHostString());
|
||||
}else {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getRateLimitIP() != null) l.getRateLimitIP().resetLimiters();
|
||||
if(l.getRateLimitLogin() != null) l.getRateLimitLogin().resetLimiters();
|
||||
if(l.getRateLimitMOTD() != null) l.getRateLimitMOTD().resetLimiters();
|
||||
if(l.getRateLimitQuery() != null) l.getRateLimitQuery().resetLimiters();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all ratelimits");
|
||||
}
|
||||
return;
|
||||
}else if("ip".equalsIgnoreCase(p1[1])) {
|
||||
if(ll != null) {
|
||||
if(ll.getRateLimitIP() != null) ll.getRateLimitIP().resetLimiters();
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all IP ratelimits on listener: " + ChatColor.WHITE + ll.getHostString());
|
||||
}else {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getRateLimitIP() != null) l.getRateLimitIP().resetLimiters();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all IP ratelimits.");
|
||||
}
|
||||
return;
|
||||
}else if("login".equalsIgnoreCase(p1[1])) {
|
||||
if(ll != null) {
|
||||
if(ll.getRateLimitLogin() != null) ll.getRateLimitLogin().resetLimiters();
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all login ratelimits on listener: " + ChatColor.WHITE + ll.getHostString());
|
||||
}else {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getRateLimitLogin() != null) l.getRateLimitLogin().resetLimiters();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all login ratelimits.");
|
||||
}
|
||||
return;
|
||||
}else if("motd".equalsIgnoreCase(p1[1])) {
|
||||
if(ll != null) {
|
||||
if(ll.getRateLimitMOTD() != null) ll.getRateLimitMOTD().resetLimiters();
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all MOTD ratelimits on listener: " + ChatColor.WHITE + ll.getHostString());
|
||||
}else {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getRateLimitMOTD() != null) l.getRateLimitMOTD().resetLimiters();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all MOTD ratelimits.");
|
||||
}
|
||||
return;
|
||||
}else if("query".equalsIgnoreCase(p1[1])) {
|
||||
if(ll != null) {
|
||||
if(ll.getRateLimitMOTD() != null) ll.getRateLimitMOTD().resetLimiters();
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all query ratelimits on listener: " + ChatColor.WHITE + ll.getHostString());
|
||||
}else {
|
||||
for(ListenerInfo l : BungeeCord.getInstance().config.getListeners()) {
|
||||
if(l.getRateLimitMOTD() != null) l.getRateLimitMOTD().resetLimiters();
|
||||
}
|
||||
p0.sendMessage(ChatColor.GREEN + "Reset all query ratelimits.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
p0.sendMessage(ChatColor.RED + "How to reset all rate limits: " + ChatColor.WHITE + "/eag-ratelimit reset");
|
||||
p0.sendMessage(ChatColor.RED + "How to reset a specific rate limit: " + ChatColor.WHITE + "/eag-ratelimit reset <ip|login|motd|query>");
|
||||
p0.sendMessage(ChatColor.RED + "How to reset a specific listener: " + ChatColor.WHITE + "/eag-ratelimit reset <all|ip|login|motd|query> <host>");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
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.QueryConnectionImpl;
|
||||
import net.md_5.bungee.eaglercraft.SHA1Digest;
|
||||
|
||||
public class CommandConfirmCode extends Command {
|
||||
|
||||
public CommandConfirmCode() {
|
||||
super("confirm-code", "bungeecord.command.eag.confirmcode", "confirmcode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender p0, String[] p1) {
|
||||
if(p1.length != 1) {
|
||||
p0.sendMessage(ChatColor.RED + "How to use: " + ChatColor.WHITE + "/confirm-code <code>");
|
||||
}else {
|
||||
p0.sendMessage(ChatColor.YELLOW + "Server list 2FA code has been set to: " + ChatColor.GREEN + p1[0]);
|
||||
p0.sendMessage(ChatColor.YELLOW + "You can now return to the server list site and continue");
|
||||
byte[] bts = p1[0].getBytes(StandardCharsets.US_ASCII);
|
||||
SHA1Digest dg = new SHA1Digest();
|
||||
dg.update(bts, 0, bts.length);
|
||||
byte[] f = new byte[20];
|
||||
dg.doFinal(f, 0);
|
||||
QueryConnectionImpl.confirmHash = SHA1Digest.hash2string(f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
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.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandDomain extends Command {
|
||||
|
||||
public CommandDomain() {
|
||||
super("domain", "bungeecord.command.eag.domain");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender p0, String[] p1) {
|
||||
if (p1.length < 1) {
|
||||
p0.sendMessage(ChatColor.RED + "Please follow this command by a user name");
|
||||
return;
|
||||
}
|
||||
final ProxiedPlayer user = ProxyServer.getInstance().getPlayer(p1[0]);
|
||||
if (user == null) {
|
||||
p0.sendMessage(ChatColor.RED + "That user is not online");
|
||||
} else {
|
||||
Object o = user.getAttachment().get("origin");
|
||||
if(o != null) {
|
||||
p0.sendMessage(ChatColor.BLUE + "Domain of " + p1[0] + " is " + o);
|
||||
if(p0.hasPermission("bungeecord.command.eag.blockdomain")) {
|
||||
p0.sendMessage(ChatColor.BLUE + "Type " + ChatColor.WHITE + "/block-domain " + p1[0] + ChatColor.BLUE + " to block this person");
|
||||
}
|
||||
}else {
|
||||
p0.sendMessage(ChatColor.RED + "Domain of " + p1[0] + " is unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
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.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.eaglercraft.DomainBlacklist;
|
||||
|
||||
public class CommandDomainBlock extends Command {
|
||||
|
||||
public CommandDomainBlock() {
|
||||
super("block-domain", "bungeecord.command.eag.blockdomain");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender p0, String[] p1) {
|
||||
if (p1.length < 1) {
|
||||
p0.sendMessage(ChatColor.RED + "Please follow this command by a username");
|
||||
return;
|
||||
}
|
||||
final ProxiedPlayer user = ProxyServer.getInstance().getPlayer(p1[0]);
|
||||
if (user == null) {
|
||||
p0.sendMessage(ChatColor.RED + "That user is not online");
|
||||
}else {
|
||||
Object o = user.getAttachment().get("origin");
|
||||
if(o != null) {
|
||||
DomainBlacklist.addLocal((String)o);
|
||||
p0.sendMessage(ChatColor.RED + "Domain of " + ChatColor.WHITE + p1[0] + ChatColor.RED + " is " + ChatColor.WHITE + o);
|
||||
p0.sendMessage(ChatColor.RED + "It was added to the local block list.");
|
||||
user.disconnect("client blocked");
|
||||
}else {
|
||||
p0.sendMessage(ChatColor.RED + "Domain of " + p1[0] + " is unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
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.DomainBlacklist;
|
||||
|
||||
public class CommandDomainBlockDomain extends Command {
|
||||
|
||||
public CommandDomainBlockDomain() {
|
||||
super("block-domain-name", "bungeecord.command.eag.blockdomainname");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender p0, String[] p1) {
|
||||
if (p1.length < 1) {
|
||||
p0.sendMessage(ChatColor.RED + "Please follow this command by a domain");
|
||||
return;
|
||||
}
|
||||
DomainBlacklist.addLocal(p1[0]);
|
||||
p0.sendMessage(ChatColor.GREEN + "The domain '" + ChatColor.WHITE + p1[0] + ChatColor.GREEN + "' was added to the block list");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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.DomainBlacklist;
|
||||
|
||||
public class CommandDomainUnblock extends Command {
|
||||
|
||||
public CommandDomainUnblock() {
|
||||
super("unblock-domain", "bungeecord.command.eag.unblockdomain", "unblock-domain-name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender p0, String[] p1) {
|
||||
if (p1.length < 1) {
|
||||
p0.sendMessage(ChatColor.RED + "Please follow this command by a domain");
|
||||
return;
|
||||
}
|
||||
if(DomainBlacklist.removeLocal(p1[0])) {
|
||||
p0.sendMessage(ChatColor.GREEN + "The domain '" + p1[0] + "' was removed from the local block list");
|
||||
}else {
|
||||
p0.sendMessage(ChatColor.RED + "The domain was not removed, is it on the block list? Check '" + DomainBlacklist.localBlacklist.getName() + "' in your bungeecord directory");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
/**
|
||||
* Command to terminate the proxy instance. May only be used by the console.
|
||||
*/
|
||||
public class CommandEnd extends Command
|
||||
{
|
||||
|
||||
public CommandEnd()
|
||||
{
|
||||
super( "end", "bungeecord.command.end" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
BungeeCord.getInstance().stop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.util.Collections;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class CommandFind extends PlayerCommand
|
||||
{
|
||||
|
||||
public CommandFind()
|
||||
{
|
||||
super( "find", "bungeecord.command.find" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
if ( args.length != 1 )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "Please follow this command by a user name" );
|
||||
} else
|
||||
{
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] );
|
||||
if ( player == null || player.getServer() == null )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "That user is not online" );
|
||||
} else
|
||||
{
|
||||
sender.sendMessage( ChatColor.BLUE + args[0] + " is online at " + player.getServer().getInfo().getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,147 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.net.InetAddress;
|
||||
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,64 @@
|
||||
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 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandIP extends Command
|
||||
{
|
||||
|
||||
public CommandIP()
|
||||
{
|
||||
super( "ip", "bungeecord.command.ip" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
if ( args.length < 1 )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "Please follow this command by a user name" );
|
||||
return;
|
||||
}
|
||||
ProxiedPlayer user = ProxyServer.getInstance().getPlayer( args[0] );
|
||||
if ( user == null )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "That user is not online" );
|
||||
} else
|
||||
{
|
||||
sender.sendMessage( ChatColor.BLUE + "IP of " + args[0] + " is " + user.getAddress() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.md_5.bungee.Util;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
/**
|
||||
* Command to list all players connected to the proxy.
|
||||
*/
|
||||
public class CommandList extends Command
|
||||
{
|
||||
|
||||
public CommandList()
|
||||
{
|
||||
super( "glist", "bungeecord.command.list" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
for ( ServerInfo server : ProxyServer.getInstance().getServers().values() )
|
||||
{
|
||||
if ( !server.canAccess( sender ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> players = new ArrayList<>();
|
||||
for ( ProxiedPlayer player : server.getPlayers() )
|
||||
{
|
||||
players.add( player.getDisplayName() );
|
||||
}
|
||||
Collections.sort( players, String.CASE_INSENSITIVE_ORDER );
|
||||
|
||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), server.getPlayers().size(), Util.format( players, ChatColor.RESET + ", " ) ) );
|
||||
}
|
||||
|
||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players", ProxyServer.getInstance().getOnlineCount() ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.md_5.bungee.Util;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandPerms extends Command
|
||||
{
|
||||
|
||||
public CommandPerms()
|
||||
{
|
||||
super( "perms" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
Set<String> permissions = new HashSet<>();
|
||||
for ( String group : sender.getGroups() )
|
||||
{
|
||||
permissions.addAll( ProxyServer.getInstance().getConfigurationAdapter().getPermissions( group ) );
|
||||
}
|
||||
sender.sendMessage( ChatColor.GOLD + "You have the following groups: " + Util.csv( sender.getGroups() ) );
|
||||
|
||||
for ( String permission : permissions )
|
||||
{
|
||||
sender.sendMessage( ChatColor.BLUE + "- " + permission );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
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.plugin.Command;
|
||||
|
||||
public class CommandReload extends Command
|
||||
{
|
||||
|
||||
public CommandReload()
|
||||
{
|
||||
super( "greload", "bungeecord.command.reload" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
BungeeCord.getInstance().config.load();
|
||||
BungeeCord.getInstance().stopListeners();
|
||||
BungeeCord.getInstance().startListeners();
|
||||
sender.sendMessage( ChatColor.BOLD.toString() + ChatColor.RED.toString() + "BungeeCord has been reloaded."
|
||||
+ " This is NOT advisable and you will not be supported with any issues that arise! Please restart BungeeCord ASAP." );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
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.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
public class CommandSend extends Command
|
||||
{
|
||||
|
||||
public CommandSend()
|
||||
{
|
||||
super( "send", "bungeecord.command.send" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
if ( args.length != 2 )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "Not enough arguments, usage: /send <player|all|current> <target>" );
|
||||
return;
|
||||
}
|
||||
ServerInfo target = ProxyServer.getInstance().getServerInfo( args[1] );
|
||||
if ( target == null )
|
||||
{
|
||||
sender.sendMessage( ProxyServer.getInstance().getTranslation( "no_server" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( args[0].equalsIgnoreCase( "all" ) )
|
||||
{
|
||||
for ( ProxiedPlayer p : ProxyServer.getInstance().getPlayers() )
|
||||
{
|
||||
summon( p, target, sender );
|
||||
}
|
||||
} else if ( args[0].equalsIgnoreCase( "current" ) )
|
||||
{
|
||||
if ( !( sender instanceof ProxiedPlayer ) )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "Only in game players can use this command" );
|
||||
return;
|
||||
}
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
for ( ProxiedPlayer p : player.getServer().getInfo().getPlayers() )
|
||||
{
|
||||
summon( p, target, sender );
|
||||
}
|
||||
} else
|
||||
{
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] );
|
||||
if ( player == null )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "That player is not online" );
|
||||
return;
|
||||
}
|
||||
summon( player, target, sender );
|
||||
}
|
||||
sender.sendMessage( ChatColor.GREEN + "Successfully summoned player(s)" );
|
||||
}
|
||||
|
||||
private void summon(ProxiedPlayer player, ServerInfo target, CommandSender sender)
|
||||
{
|
||||
if ( player.getServer() != null && !player.getServer().getInfo().equals( target ) )
|
||||
{
|
||||
player.connect( target );
|
||||
player.sendMessage( ChatColor.GOLD + "Summoned to " + target.getName() + " by " + sender.getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
|
||||
/**
|
||||
* Command to list and switch a player between available servers.
|
||||
*/
|
||||
public class CommandServer extends Command implements TabExecutor
|
||||
{
|
||||
|
||||
public CommandServer()
|
||||
{
|
||||
super( "server", "bungeecord.command.server" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args)
|
||||
{
|
||||
if ( !( sender instanceof ProxiedPlayer ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
Map<String, ServerInfo> servers = ProxyServer.getInstance().getServers();
|
||||
if ( args.length == 0 )
|
||||
{
|
||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "current_server" ) + player.getServer().getInfo().getName() );
|
||||
|
||||
StringBuilder serverList = new StringBuilder();
|
||||
for ( ServerInfo server : servers.values() )
|
||||
{
|
||||
if ( server.canAccess( player ) )
|
||||
{
|
||||
serverList.append( server.getName() );
|
||||
serverList.append( ", " );
|
||||
}
|
||||
}
|
||||
if ( serverList.length() != 0 )
|
||||
{
|
||||
serverList.setLength( serverList.length() - 2 );
|
||||
}
|
||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "server_list" ) + serverList.toString() );
|
||||
} else
|
||||
{
|
||||
ServerInfo server = servers.get( args[0] );
|
||||
if ( server == null )
|
||||
{
|
||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "no_server" ) );
|
||||
} else if ( !server.canAccess( player ) )
|
||||
{
|
||||
player.sendMessage( ProxyServer.getInstance().getTranslation( "no_server_permission" ) );
|
||||
} else
|
||||
{
|
||||
player.connect( server );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(final CommandSender sender, String[] args)
|
||||
{
|
||||
return ( args.length != 0 ) ? Collections.EMPTY_LIST : Iterables.transform( Iterables.filter( ProxyServer.getInstance().getServers().values(), new Predicate<ServerInfo>()
|
||||
{
|
||||
@Override
|
||||
public boolean apply(ServerInfo input)
|
||||
{
|
||||
return input.canAccess( sender );
|
||||
}
|
||||
} ), new Function<ServerInfo, String>()
|
||||
{
|
||||
@Override
|
||||
public String apply(ServerInfo input)
|
||||
{
|
||||
return input.getName();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
/**
|
||||
* Command sender representing the proxy console.
|
||||
*/
|
||||
public class ConsoleCommandSender implements CommandSender
|
||||
{
|
||||
private static final Map<String, Object> attachment = new WeakHashMap();
|
||||
|
||||
private static final ConsoleCommandSender instance = new ConsoleCommandSender();
|
||||
|
||||
private ConsoleCommandSender()
|
||||
{
|
||||
}
|
||||
|
||||
public static ConsoleCommandSender getInstance(){
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message)
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().info( message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessages(String... messages)
|
||||
{
|
||||
for ( String message : messages )
|
||||
{
|
||||
sendMessage( message );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getGroups()
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroups(String... groups)
|
||||
{
|
||||
throw new UnsupportedOperationException( "Console may not have groups" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroups(String... groups)
|
||||
{
|
||||
throw new UnsupportedOperationException( "Console may not have groups" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermission(String permission, boolean value)
|
||||
{
|
||||
throw new UnsupportedOperationException( "Console has all permissions" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
|
||||
public abstract class PlayerCommand extends Command implements TabExecutor
|
||||
{
|
||||
|
||||
public PlayerCommand(String name)
|
||||
{
|
||||
super( name );
|
||||
}
|
||||
|
||||
public PlayerCommand(String name, String permission, String... aliases)
|
||||
{
|
||||
super( name, permission, aliases );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args)
|
||||
{
|
||||
final String lastArg = ( args.length > 0 ) ? args[args.length - 1] : "";
|
||||
return Iterables.transform( Iterables.filter( ProxyServer.getInstance().getPlayers(), new Predicate<ProxiedPlayer>()
|
||||
{
|
||||
@Override
|
||||
public boolean apply(ProxiedPlayer player)
|
||||
{
|
||||
return player.getName().startsWith( lastArg );
|
||||
}
|
||||
} ), new Function<ProxiedPlayer, String>()
|
||||
{
|
||||
@Override
|
||||
public String apply(ProxiedPlayer player)
|
||||
{
|
||||
return player.getName();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import gnu.trove.map.TMap;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.AuthServiceInfo;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.eaglercraft.EaglercraftBungee;
|
||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||
|
||||
public class Configuration {
|
||||
private int timeout;
|
||||
private String uuid;
|
||||
private Collection<ListenerInfo> listeners;
|
||||
private TMap<String, ServerInfo> servers;
|
||||
private AuthServiceInfo authInfo;
|
||||
private boolean onlineMode;
|
||||
private boolean voiceEnabled;
|
||||
private boolean protocolSupport;
|
||||
private String tokenVerify;
|
||||
private int playerLimit;
|
||||
private String name;
|
||||
private boolean showBanType;
|
||||
private boolean blacklistOfflineDownload;
|
||||
private boolean blacklistReplits;
|
||||
private boolean blacklistOriginless;
|
||||
private boolean simpleWhitelistEnabled;
|
||||
private boolean acceptBukkitConsoleCommandPacket;
|
||||
private Collection<String> disabledCommands;
|
||||
private Collection<String> iceServers;
|
||||
private boolean bungeeOnBungee;
|
||||
|
||||
public Configuration() {
|
||||
this.timeout = 30000;
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.onlineMode = true;
|
||||
this.playerLimit = -1;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
final ConfigurationAdapter adapter = ProxyServer.getInstance().getConfigurationAdapter();
|
||||
adapter.load();
|
||||
this.listeners = adapter.getListeners();
|
||||
this.timeout = adapter.getInt("timeout", this.timeout);
|
||||
this.uuid = adapter.getString("stats", this.uuid);
|
||||
if(this.uuid.equalsIgnoreCase("595698b3-9c36-4e86-b1ee-cb3027038f41")) {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
System.err.println("Notice: this server has the stats UUID \"595698b3-9c36-4e86-b1ee-cb3027038f41\" which is a known duplicate");
|
||||
System.err.println("It has been updated to \"" + this.uuid + "\". This is not an error");
|
||||
adapter.getMap().put("stats", this.uuid);
|
||||
adapter.forceSave();
|
||||
}
|
||||
this.authInfo = adapter.getAuthSettings();
|
||||
this.onlineMode = false;
|
||||
this.voiceEnabled = adapter.getBoolean("voice_enabled", true);
|
||||
this.protocolSupport = adapter.getBoolean("protocol_support_fix", false);
|
||||
this.tokenVerify = adapter.getString("token_verify", "");
|
||||
this.playerLimit = adapter.getInt("player_limit", this.playerLimit);
|
||||
this.name = adapter.getString("server_name", EaglercraftBungee.name + " Server");
|
||||
this.showBanType = adapter.getBoolean("display_ban_type_on_kick", false);
|
||||
this.blacklistOfflineDownload = adapter.getBoolean("origin_blacklist_block_offline_download", false);
|
||||
this.blacklistReplits = adapter.getBoolean("origin_blacklist_block_replit_clients", false);
|
||||
adapter.getMap().remove("origin_blacklist_block_missing_origin_header");
|
||||
this.blacklistOriginless = adapter.getBoolean("origin_blacklist_block_invalid_origin_header", true);
|
||||
this.simpleWhitelistEnabled = adapter.getBoolean("origin_blacklist_use_simple_whitelist", false);
|
||||
this.acceptBukkitConsoleCommandPacket = adapter.getBoolean("accept_bukkit_console_command_packets", false);
|
||||
this.bungeeOnBungee = adapter.getBoolean("bungee_on_bungee", false);
|
||||
this.disabledCommands = adapter.getDisabledCommands();
|
||||
this.iceServers = adapter.getICEServers();
|
||||
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");
|
||||
if (this.servers == null) {
|
||||
this.servers = (TMap<String, ServerInfo>) new CaseInsensitiveMap(newServers);
|
||||
} else {
|
||||
for (final ServerInfo oldServer : this.servers.values()) {
|
||||
Preconditions.checkArgument(newServers.containsValue(oldServer), "Server %s removed on reload!", new Object[] { oldServer.getName() });
|
||||
}
|
||||
for (final Map.Entry<String, ServerInfo> newServer : newServers.entrySet()) {
|
||||
if (!this.servers.containsValue(newServer.getValue())) {
|
||||
this.servers.put(newServer.getKey(), newServer.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final ListenerInfo listener : this.listeners) {
|
||||
Preconditions.checkArgument(this.servers.containsKey((Object) listener.getDefaultServer()), "Default server %s is not defined", new Object[] { listener.getDefaultServer() });
|
||||
}
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
public Collection<ListenerInfo> getListeners() {
|
||||
return this.listeners;
|
||||
}
|
||||
|
||||
public TMap<String, ServerInfo> getServers() {
|
||||
return this.servers;
|
||||
}
|
||||
|
||||
public boolean isOnlineMode() {
|
||||
return this.onlineMode;
|
||||
}
|
||||
|
||||
public int getPlayerLimit() {
|
||||
return this.playerLimit;
|
||||
}
|
||||
|
||||
public AuthServiceInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
|
||||
public boolean getVoiceEnabled() {
|
||||
return voiceEnabled;
|
||||
}
|
||||
|
||||
public boolean getProtocolSupport() {
|
||||
return protocolSupport;
|
||||
}
|
||||
|
||||
public String getTokenVerify() {
|
||||
return tokenVerify;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean shouldShowBanType() {
|
||||
return this.showBanType;
|
||||
}
|
||||
|
||||
public boolean shouldBlacklistOfflineDownload() {
|
||||
return blacklistOfflineDownload;
|
||||
}
|
||||
|
||||
public boolean shouldBlacklistReplits() {
|
||||
return blacklistReplits;
|
||||
}
|
||||
|
||||
public boolean shouldBlacklistOriginless() {
|
||||
return blacklistOriginless;
|
||||
}
|
||||
|
||||
public boolean isSimpleWhitelistEnabled() {
|
||||
return simpleWhitelistEnabled;
|
||||
}
|
||||
|
||||
public boolean shouldAcceptBukkitConsoleCommandPacket() {
|
||||
return acceptBukkitConsoleCommandPacket;
|
||||
}
|
||||
|
||||
public Collection<String> getDisabledCommands() {
|
||||
return disabledCommands;
|
||||
}
|
||||
|
||||
public Collection<String> getICEServers() {
|
||||
return iceServers;
|
||||
}
|
||||
|
||||
public boolean allowBungeeOnBungee() {
|
||||
return bungeeOnBungee;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Writer;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.Util;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.AuthServiceInfo;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.config.MOTDCacheConfiguration;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.config.TexturePackInfo;
|
||||
import net.md_5.bungee.api.tab.TabListHandler;
|
||||
import net.md_5.bungee.eaglercraft.RedirectServerInfo;
|
||||
import net.md_5.bungee.eaglercraft.WebSocketRateLimiter;
|
||||
import net.md_5.bungee.tab.Global;
|
||||
import net.md_5.bungee.tab.GlobalPing;
|
||||
import net.md_5.bungee.tab.ServerUnique;
|
||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||
|
||||
public class YamlConfig implements ConfigurationAdapter {
|
||||
private Yaml yaml;
|
||||
private Map config;
|
||||
private final File file;
|
||||
|
||||
public YamlConfig() {
|
||||
this.file = new File("config.yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try {
|
||||
this.file.createNewFile();
|
||||
final DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
this.yaml = new Yaml(options);
|
||||
try (final InputStream is = new FileInputStream(this.file)) {
|
||||
this.config = (Map) this.yaml.load(is);
|
||||
}
|
||||
if (this.config == null) {
|
||||
this.config = (Map) new CaseInsensitiveMap();
|
||||
} else {
|
||||
this.config = (Map) new CaseInsensitiveMap(this.config);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Could not load configuration!", ex);
|
||||
}
|
||||
final Map<String, List<String>> permissions = this.get("permissions", new HashMap<String, List<String>>());
|
||||
if (permissions.isEmpty()) {
|
||||
permissions.put("default", Arrays.asList("bungeecord.command.server", "bungeecord.command.list", "bungeecord.command.eag.domain", "bungeecord.command.eag.changepassword"));
|
||||
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", "bungeecord.command.eag.ratelimit",
|
||||
"bungeecord.command.eag.blockdomain", "bungeecord.command.eag.blockdomainname", "bungeecord.command.eag.unblockdomain"));
|
||||
} else if (this.get("authservice", new HashMap<String, Object>()).isEmpty() && permissions.containsKey("default") && !permissions.get("default").contains("bungeecord.command.eag.changepassword")) {
|
||||
permissions.get("default").add("bungeecord.command.eag.changepassword");
|
||||
}
|
||||
this.get("groups", new HashMap<String, Object>());
|
||||
}
|
||||
|
||||
private <T> T get(final String path, final T def) {
|
||||
return this.get(path, def, this.config);
|
||||
}
|
||||
|
||||
private <T> T get(final String path, final T def, final Map submap) {
|
||||
final int index = path.indexOf(46);
|
||||
if (index == -1) {
|
||||
Object val = submap.get(path);
|
||||
if (val == null && def != null) {
|
||||
val = def;
|
||||
submap.put(path, def);
|
||||
this.save();
|
||||
}
|
||||
return (T) val;
|
||||
}
|
||||
final String first = path.substring(0, index);
|
||||
final String second = path.substring(index + 1, path.length());
|
||||
Map sub = (Map) submap.get(first);
|
||||
if (sub == null) {
|
||||
sub = new LinkedHashMap();
|
||||
submap.put(first, sub);
|
||||
}
|
||||
return (T) this.get(second, (Object) def, sub);
|
||||
}
|
||||
|
||||
private void save() {
|
||||
try (final FileWriter wr = new FileWriter(this.file)) {
|
||||
this.yaml.dump((Object) this.config, (Writer) wr);
|
||||
} catch (IOException ex) {
|
||||
ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not save config", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final String path, final int def) {
|
||||
return this.get(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final String path, final String def) {
|
||||
return this.get(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final String path, final boolean def) {
|
||||
return this.get(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ServerInfo> getServers() {
|
||||
final Map<String, HashMap> base = this.get("servers", (Map<String, HashMap>) Collections.singletonMap("lobby", new HashMap()));
|
||||
final Map<String, ServerInfo> ret = new HashMap<String, ServerInfo>();
|
||||
for (final Map.Entry<String, HashMap> entry : base.entrySet()) {
|
||||
final Map<String, Object> val = entry.getValue();
|
||||
final String name = entry.getKey();
|
||||
if(val.containsKey("redirect")) {
|
||||
final String addr = this.get("redirect", "ws://someOtherServer/", val);
|
||||
final boolean restricted = this.get("restricted", false, val);
|
||||
final ServerInfo info = new RedirectServerInfo(name, addr, restricted);
|
||||
ret.put(name, info);
|
||||
}else {
|
||||
final String addr = this.get("address", "localhost:25501", val);
|
||||
final boolean restricted = this.get("restricted", false, val);
|
||||
final InetSocketAddress address = Util.getAddr(addr);
|
||||
final ServerInfo info = ProxyServer.getInstance().constructServerInfo(name, address, restricted);
|
||||
ret.put(name, info);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ListenerInfo> getListeners() {
|
||||
final Collection<HashMap> base = this.get("listeners", (Collection<HashMap>) Arrays.asList(new HashMap()));
|
||||
final Map<String, String> forcedDef = new HashMap<String, String>();
|
||||
//forcedDef.put("pvp.md-5.net", "pvp");
|
||||
final Collection<ListenerInfo> ret = new HashSet<ListenerInfo>();
|
||||
for (final Map<String, Object> val : base) {
|
||||
String motd = this.get("motd", null, val);
|
||||
if(motd != null) {
|
||||
val.remove("motd");
|
||||
}
|
||||
motd = this.get("motd1", motd, val);
|
||||
if(motd == null) {
|
||||
motd = this.get("motd1", "&6An Eaglercraft server", val);
|
||||
}
|
||||
motd = ChatColor.translateAlternateColorCodes('&', motd);
|
||||
String motd2 = this.get("motd2", null, val);
|
||||
if(motd2 != null && motd2.length() > 0) {
|
||||
motd = motd + "\n" + ChatColor.translateAlternateColorCodes('&', motd2);
|
||||
}
|
||||
final int maxPlayers = this.get("max_players", 60, val);
|
||||
final String defaultServer = this.get("default_server", "lobby", val);
|
||||
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 forwardIpHeader = this.get("forward_ip_header", "X-Real-IP", val);
|
||||
final String host = this.get("host", "0.0.0.0:25565", val);
|
||||
final String javaHost = this.get("java_host", "null", val);
|
||||
final int tabListSize = this.get("tab_size", 60, val);
|
||||
final InetSocketAddress address = Util.getAddr(host);
|
||||
final InetSocketAddress javaAddress = (javaHost.equalsIgnoreCase("null") || javaHost == null) ? null : Util.getAddr(javaHost);
|
||||
final Map<String, String> forced = (Map<String, String>) new CaseInsensitiveMap(this.get("forced_hosts", forcedDef, val));
|
||||
final String textureURL = this.get("texture_url", (String) null, val);
|
||||
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);
|
||||
final boolean allowMOTD = this.get("allow_motd", true, val);
|
||||
final boolean allowQuery = this.get("allow_query", true, val);
|
||||
final MOTDCacheConfiguration cacheConfig = readCacheConfiguration(this.get("request_motd_cache", new HashMap<String, Object>(), val));
|
||||
|
||||
WebSocketRateLimiter ratelimitIP = null;
|
||||
WebSocketRateLimiter ratelimitLogin = null;
|
||||
WebSocketRateLimiter ratelimitMOTD = null;
|
||||
WebSocketRateLimiter ratelimitQuery = null;
|
||||
final Map<String, Object> rateLimits = this.get("ratelimit", new HashMap<String, Object>(), val);
|
||||
final Map<String, Object> ratelimitIPConfig = this.get("ip", new HashMap<String, Object>(), rateLimits);
|
||||
final Map<String, Object> ratelimitLoginConfig = this.get("login", new HashMap<String, Object>(), rateLimits);
|
||||
final Map<String, Object> ratelimitMOTDConfig = this.get("motd", new HashMap<String, Object>(), rateLimits);
|
||||
final Map<String, Object> ratelimitQueryConfig = this.get("query", new HashMap<String, Object>(), rateLimits);
|
||||
|
||||
if(this.get("enable", true, ratelimitIPConfig)) {
|
||||
ratelimitIP = new WebSocketRateLimiter(
|
||||
this.get("period", 90, ratelimitIPConfig),
|
||||
this.get("limit", 60, ratelimitIPConfig),
|
||||
this.get("limit_lockout", 80, ratelimitIPConfig),
|
||||
this.get("lockout_duration", 1200, ratelimitIPConfig),
|
||||
this.get("exceptions", new ArrayList<String>(), ratelimitIPConfig)
|
||||
);
|
||||
}
|
||||
if(this.get("enable", true, ratelimitLoginConfig)) {
|
||||
ratelimitLogin = new WebSocketRateLimiter(
|
||||
this.get("period", 50, ratelimitLoginConfig),
|
||||
this.get("limit", 5, ratelimitLoginConfig),
|
||||
this.get("limit_lockout", 10, ratelimitLoginConfig),
|
||||
this.get("lockout_duration", 300, ratelimitLoginConfig),
|
||||
this.get("exceptions", new ArrayList<String>(), ratelimitLoginConfig)
|
||||
);
|
||||
}
|
||||
if(this.get("enable", true, ratelimitMOTDConfig)) {
|
||||
ratelimitMOTD = new WebSocketRateLimiter(
|
||||
this.get("period", 30, ratelimitMOTDConfig),
|
||||
this.get("limit", 5, ratelimitMOTDConfig),
|
||||
this.get("limit_lockout", 15, ratelimitMOTDConfig),
|
||||
this.get("lockout_duration", 1200, ratelimitMOTDConfig),
|
||||
this.get("exceptions", new ArrayList<String>(), ratelimitMOTDConfig)
|
||||
);
|
||||
}
|
||||
if(this.get("enable", true, ratelimitQueryConfig)) {
|
||||
ratelimitQuery = new WebSocketRateLimiter(
|
||||
this.get("period", 90, ratelimitQueryConfig),
|
||||
this.get("limit", 60, ratelimitQueryConfig),
|
||||
this.get("limit_lockout", 80, ratelimitQueryConfig),
|
||||
this.get("lockout_duration", 1200, ratelimitQueryConfig),
|
||||
this.get("exceptions", new ArrayList<String>(), ratelimitQueryConfig)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
DefaultTabList value = DefaultTabList.valueOf(tabListName.toUpperCase());
|
||||
if (value == null) {
|
||||
value = DefaultTabList.GLOBAL_PING;
|
||||
}
|
||||
ret.add(new ListenerInfo(host, address, javaAddress, forwardIpHeader, motd, maxPlayers, tabListSize, defaultServer,
|
||||
fallbackServer, forceDefault, websocket, forwardIp, forced, texture, value.clazz, serverIcon, cacheConfig,
|
||||
allowMOTD, allowQuery, ratelimitIP, ratelimitLogin, ratelimitMOTD, ratelimitQuery));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private MOTDCacheConfiguration readCacheConfiguration(Map<String, Object> val) {
|
||||
final int ttl = this.get("cache_ttl", 7200, val);
|
||||
final boolean anim = this.get("online_server_list_animation", false, val);
|
||||
final boolean results = this.get("online_server_list_results", true, val);
|
||||
final boolean trending = this.get("online_server_list_trending", true, val);
|
||||
final boolean portfolios = this.get("online_server_list_portfolios", false, val);
|
||||
return new MOTDCacheConfiguration(ttl, anim, results, trending, portfolios);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getGroups(final String player) {
|
||||
final Collection<String> groups = this.get("groups." + player, (Collection<String>) null);
|
||||
final Collection<String> ret = (groups == null) ? new HashSet<String>() : new HashSet<String>(groups);
|
||||
ret.add("default");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getPermissions(final String group) {
|
||||
return this.get("permissions." + group, (Collection<String>) Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
private enum DefaultTabList {
|
||||
GLOBAL((Class<? extends TabListHandler>) Global.class), GLOBAL_PING((Class<? extends TabListHandler>) GlobalPing.class), SERVER((Class<? extends TabListHandler>) ServerUnique.class);
|
||||
|
||||
private final Class<? extends TabListHandler> clazz;
|
||||
|
||||
private DefaultTabList(final Class<? extends TabListHandler> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
}
|
||||
|
||||
public AuthServiceInfo getAuthSettings() {
|
||||
final Map<String, Object> auth = this.get("authservice", new HashMap<String, Object>());
|
||||
final List<String> defaultJoinMessages = new ArrayList<String>();
|
||||
defaultJoinMessages.add("&3Welcome to my &aEaglercraftBungee &3server!");
|
||||
return new AuthServiceInfo(this.get("enabled", false, auth), this.get("register_enabled", true, auth), this.get("authfile", "auths.db", auth),
|
||||
this.get("ip_limit", 0, auth), this.get("join_messages", defaultJoinMessages, auth), this.get("login_timeout", 30, auth));
|
||||
}
|
||||
|
||||
public Map<String, Object> getMap() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void forceSave() {
|
||||
this.save();
|
||||
}
|
||||
|
||||
public Collection<String> getBlacklistURLs() {
|
||||
boolean blacklistEnable = this.getBoolean("enable_web_origin_blacklist", true);
|
||||
if(!blacklistEnable) {
|
||||
return null;
|
||||
}
|
||||
Collection<String> c = this.get("origin_blacklist_subscriptions", null);
|
||||
if(c == null) {
|
||||
c = new ArrayList();
|
||||
c.add("https://g.lax1dude.net/eaglercraft/origin_blacklist.txt");
|
||||
c.add("https://raw.githubusercontent.com/LAX1DUDE/eaglercraft/main/stable-download/origin_blacklist.txt");
|
||||
c = this.get("origin_blacklist_subscriptions", c);
|
||||
}else {
|
||||
if(c.remove("https://g.eags.us/eaglercraft/origin_blacklist.txt")) {
|
||||
c.add("https://g.lax1dude.net/eaglercraft/origin_blacklist.txt");
|
||||
this.save();
|
||||
BungeeCord.getInstance().getLogger().warning("Your origin blacklist has been patched to use g.lax1dude.net instead");
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public Collection<String> getBlacklistSimpleWhitelist() {
|
||||
Collection<String> c = this.get("origin_blacklist_simple_whitelist", null);
|
||||
if(c == null) {
|
||||
c = new ArrayList();
|
||||
c.add("type the name of your client's domain here");
|
||||
c.add("(if 'origin_blacklist_use_simple_whitelist' is true)");
|
||||
c.add("g.lax1dude.net");
|
||||
c = this.get("origin_blacklist_simple_whitelist", c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public Collection<String> getDisabledCommands() {
|
||||
return this.get("disabled_commands", new ArrayList());
|
||||
}
|
||||
|
||||
public Collection<String> getICEServers() {
|
||||
Collection<String> ret = new ArrayList();
|
||||
|
||||
Collection<String> c = this.get("voice_stun_servers", null);
|
||||
if(c == null) {
|
||||
c = new ArrayList();
|
||||
c.add("stun:stun.l.google.com:19302");
|
||||
c.add("stun:stun1.l.google.com:19302");
|
||||
c.add("stun:stun2.l.google.com:19302");
|
||||
c.add("stun:stun3.l.google.com:19302");
|
||||
c.add("stun:stun4.l.google.com:19302");
|
||||
c.add("stun:openrelay.metered.ca:80");
|
||||
c = this.get("voice_stun_servers", c);
|
||||
}
|
||||
|
||||
ret.addAll(c);
|
||||
|
||||
Map<String, Object> turnServerList = this.get("voice_turn_servers", null);
|
||||
if(turnServerList == null) {
|
||||
turnServerList = new HashMap();
|
||||
HashMap<String, Object> n = new HashMap();
|
||||
n.put("url", "turn:openrelay.metered.ca:80");
|
||||
n.put("username", "openrelayproject");
|
||||
n.put("password", "openrelayproject");
|
||||
turnServerList.put("openrelay1", n);
|
||||
|
||||
n = new HashMap();
|
||||
n.put("url", "turn:openrelay.metered.ca:443");
|
||||
n.put("username", "openrelayproject");
|
||||
n.put("password", "openrelayproject");
|
||||
turnServerList.put("openrelay2", n);
|
||||
|
||||
n = new HashMap();
|
||||
n.put("url", "turn:openrelay.metered.ca:443?transport=tcp");
|
||||
n.put("username", "openrelayproject");
|
||||
n.put("password", "openrelayproject");
|
||||
turnServerList.put("openrelay3", n);
|
||||
turnServerList = this.get("voice_turn_servers", turnServerList);
|
||||
}
|
||||
|
||||
for(Entry<String, Object> trn : turnServerList.entrySet()) {
|
||||
Object o = trn.getValue();
|
||||
if(o instanceof Map) {
|
||||
Map<String, Object> o2 = (Map<String, Object>) o;
|
||||
ret.add("" + o2.get("url") + ";" + o2.get("username") + ";" + o2.get("password"));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public Collection<?> getList(String path, Collection<?> def)
|
||||
{
|
||||
return this.get(path, def);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.md_5.bungee.connection;
|
||||
|
||||
public class CancelSendSignal extends Error
|
||||
{
|
||||
|
||||
@Override
|
||||
public Throwable initCause(Throwable cause)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable fillInStackTrace()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
package net.md_5.bungee.connection;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.io.DataInput;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.md_5.bungee.*;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.event.ServerKickEvent;
|
||||
import net.md_5.bungee.api.score.Objective;
|
||||
import net.md_5.bungee.api.score.Position;
|
||||
import net.md_5.bungee.api.score.Score;
|
||||
import net.md_5.bungee.api.score.Scoreboard;
|
||||
import net.md_5.bungee.api.score.Team;
|
||||
import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.netty.PacketHandler;
|
||||
import net.md_5.bungee.netty.PacketWrapper;
|
||||
import net.md_5.bungee.protocol.packet.Packet0KeepAlive;
|
||||
import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem;
|
||||
import net.md_5.bungee.protocol.packet.PacketCEScoreboardObjective;
|
||||
import net.md_5.bungee.protocol.packet.PacketCFScoreboardScore;
|
||||
import net.md_5.bungee.protocol.packet.PacketD0DisplayScoreboard;
|
||||
import net.md_5.bungee.protocol.packet.PacketD1Team;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||
|
||||
public class DownstreamBridge extends PacketHandler
|
||||
{
|
||||
|
||||
private final ProxyServer bungee;
|
||||
private final UserConnection con;
|
||||
private final ServerConnection server;
|
||||
|
||||
@Override
|
||||
public void exception(Throwable t) throws Exception
|
||||
{
|
||||
ServerInfo def = bungee.getServerInfo( con.getPendingConnection().getListener().getFallbackServer() );
|
||||
if ( server.getInfo() != def )
|
||||
{
|
||||
server.setObsolete( true );
|
||||
con.connectNow( def );
|
||||
con.sendMessage( bungee.getTranslation( "server_went_down" ) );
|
||||
} else
|
||||
{
|
||||
con.disconnect( Util.exception( t ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(ChannelWrapper channel) throws Exception
|
||||
{
|
||||
// We lost connection to the server
|
||||
server.getInfo().removePlayer( con );
|
||||
if ( bungee.getReconnectHandler() != null )
|
||||
{
|
||||
bungee.getReconnectHandler().setServer( con );
|
||||
}
|
||||
|
||||
if ( !server.isObsolete() )
|
||||
{
|
||||
con.disconnect( bungee.getTranslation( "lost_connection" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketWrapper packet) throws Exception
|
||||
{
|
||||
if ( !server.isObsolete() )
|
||||
{
|
||||
EntityMap.rewrite( packet.buf, con.getServerEntityId(), con.getClientEntityId() );
|
||||
con.sendPacket( packet );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Packet0KeepAlive alive) throws Exception
|
||||
{
|
||||
con.setSentPingId( alive.getRandomId() );
|
||||
con.setSentPingTime( System.currentTimeMillis() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketC9PlayerListItem playerList) throws Exception
|
||||
{
|
||||
|
||||
if ( !con.getTabList().onListUpdate( playerList.getUsername(), playerList.isOnline(), playerList.getPing() ) )
|
||||
{
|
||||
throw new CancelSendSignal();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketCEScoreboardObjective objective) throws Exception
|
||||
{
|
||||
Scoreboard serverScoreboard = con.getServerSentScoreboard();
|
||||
switch ( objective.getAction() )
|
||||
{
|
||||
case 0:
|
||||
serverScoreboard.addObjective( new Objective( objective.getName(), objective.getText() ) );
|
||||
break;
|
||||
case 1:
|
||||
serverScoreboard.removeObjective( objective.getName() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketCFScoreboardScore score) throws Exception
|
||||
{
|
||||
Scoreboard serverScoreboard = con.getServerSentScoreboard();
|
||||
switch ( score.getAction() )
|
||||
{
|
||||
case 0:
|
||||
Score s = new Score( score.getItemName(), score.getScoreName(), score.getValue() );
|
||||
serverScoreboard.removeScore( score.getItemName() );
|
||||
serverScoreboard.addScore( s );
|
||||
break;
|
||||
case 1:
|
||||
serverScoreboard.removeScore( score.getItemName() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketD0DisplayScoreboard displayScoreboard) throws Exception
|
||||
{
|
||||
Scoreboard serverScoreboard = con.getServerSentScoreboard();
|
||||
serverScoreboard.setName( displayScoreboard.getName() );
|
||||
serverScoreboard.setPosition( Position.values()[displayScoreboard.getPosition()] );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketD1Team team) throws Exception
|
||||
{
|
||||
Scoreboard serverScoreboard = con.getServerSentScoreboard();
|
||||
// Remove team and move on
|
||||
if ( team.getMode() == 1 )
|
||||
{
|
||||
serverScoreboard.removeTeam( team.getName() );
|
||||
return;
|
||||
}
|
||||
|
||||
// Create or get old team
|
||||
Team t;
|
||||
if ( team.getMode() == 0 )
|
||||
{
|
||||
t = new Team( team.getName() );
|
||||
serverScoreboard.addTeam( t );
|
||||
} else
|
||||
{
|
||||
t = serverScoreboard.getTeam( team.getName() );
|
||||
}
|
||||
|
||||
if ( t != null )
|
||||
{
|
||||
if ( team.getMode() == 0 || team.getMode() == 2 )
|
||||
{
|
||||
t.setDisplayName( team.getDisplayName() );
|
||||
t.setPrefix( team.getPrefix() );
|
||||
t.setSuffix( team.getSuffix() );
|
||||
t.setFriendlyFire( team.isFriendlyFire() );
|
||||
}
|
||||
if ( team.getPlayers() != null )
|
||||
{
|
||||
for ( String s : team.getPlayers() )
|
||||
{
|
||||
if ( team.getMode() == 0 || team.getMode() == 3 )
|
||||
{
|
||||
t.addPlayer( s );
|
||||
} else
|
||||
{
|
||||
t.removePlayer( s );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final PacketFAPluginMessage pluginMessage) throws Exception {
|
||||
final ByteArrayDataInput in = ByteStreams.newDataInput(pluginMessage.getData());
|
||||
final PluginMessageEvent event = new PluginMessageEvent(this.con.getServer(), this.con, pluginMessage.getTag(), pluginMessage.getData().clone());
|
||||
if (this.bungee.getPluginManager().callEvent(event).isCancelled()) {
|
||||
throw new CancelSendSignal();
|
||||
}
|
||||
if (pluginMessage.getTag().equals("MC|TPack") && this.con.getPendingConnection().getListener().getTexturePack() != null) {
|
||||
throw new CancelSendSignal();
|
||||
}
|
||||
if (pluginMessage.getTag().equals("BungeeCord")) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
final String subChannel = in.readUTF();
|
||||
if (subChannel.equals("Forward")) {
|
||||
final String target = in.readUTF();
|
||||
final String channel = in.readUTF();
|
||||
final short len = in.readShort();
|
||||
final byte[] data = new byte[len];
|
||||
in.readFully(data);
|
||||
out.writeUTF(channel);
|
||||
out.writeShort(data.length);
|
||||
out.write(data);
|
||||
final byte[] payload = out.toByteArray();
|
||||
out = null;
|
||||
if (target.equals("ALL")) {
|
||||
for (final ServerInfo server : this.bungee.getServers().values()) {
|
||||
if (server != this.con.getServer().getInfo()) {
|
||||
server.sendData("BungeeCord", payload);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final ServerInfo server2 = this.bungee.getServerInfo(target);
|
||||
if (server2 != null) {
|
||||
server2.sendData("BungeeCord", payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("Connect")) {
|
||||
final ServerInfo server3 = this.bungee.getServerInfo(in.readUTF());
|
||||
if (server3 != null) {
|
||||
this.con.connect(server3);
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("IP")) {
|
||||
out.writeUTF("IP");
|
||||
Object ob = this.con.getAttachment().get("remoteAddr");
|
||||
if(ob != null && (ob instanceof InetAddress)) {
|
||||
out.writeUTF(((InetAddress)ob).getHostAddress());
|
||||
out.writeInt(this.con.getAddress().getPort());
|
||||
}else {
|
||||
out.writeUTF(this.con.getAddress().getHostString());
|
||||
out.writeInt(this.con.getAddress().getPort());
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("PlayerCount")) {
|
||||
final String target = in.readUTF();
|
||||
out.writeUTF("PlayerCount");
|
||||
if (target.equals("ALL")) {
|
||||
out.writeUTF("ALL");
|
||||
out.writeInt(this.bungee.getOnlineCount());
|
||||
} else {
|
||||
final ServerInfo server4 = this.bungee.getServerInfo(target);
|
||||
if (server4 != null) {
|
||||
out.writeUTF(server4.getName());
|
||||
out.writeInt(server4.getPlayers().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("PlayerList")) {
|
||||
final String target = in.readUTF();
|
||||
out.writeUTF("PlayerList");
|
||||
if (target.equals("ALL")) {
|
||||
out.writeUTF("ALL");
|
||||
out.writeUTF(Util.csv(this.bungee.getPlayers()));
|
||||
} else {
|
||||
final ServerInfo server4 = this.bungee.getServerInfo(target);
|
||||
if (server4 != null) {
|
||||
out.writeUTF(server4.getName());
|
||||
out.writeUTF(Util.csv(server4.getPlayers()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("GetServers")) {
|
||||
out.writeUTF("GetServers");
|
||||
out.writeUTF(Util.csv(this.bungee.getServers().keySet()));
|
||||
}
|
||||
if (subChannel.equals("Message")) {
|
||||
final ProxiedPlayer target2 = this.bungee.getPlayer(in.readUTF());
|
||||
if (target2 != null) {
|
||||
target2.sendMessage(in.readUTF());
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("GetServer")) {
|
||||
out.writeUTF("GetServer");
|
||||
out.writeUTF(this.server.getInfo().getName());
|
||||
}
|
||||
if (subChannel.equals("EAG|GetDomain")) {
|
||||
out.writeUTF("EAG|GetDomain");
|
||||
Object ob = this.con.getAttachment().get("origin");
|
||||
if(ob != null && (ob instanceof String)) {
|
||||
out.writeBoolean(true);
|
||||
out.writeUTF((String)ob);
|
||||
}else {
|
||||
out.writeBoolean(false);
|
||||
out.writeUTF("");
|
||||
}
|
||||
}
|
||||
if (subChannel.equals("EAG|ConsoleCommand")) {
|
||||
if(BungeeCord.getInstance().config.shouldAcceptBukkitConsoleCommandPacket()) {
|
||||
String cmd = in.readUTF();
|
||||
bungee.getLogger().info("Connection [" + this.con.getName() + "] <-> [" + this.server.getInfo().getName() + "] executed bungee console command: " + cmd);
|
||||
bungee.getPluginManager().dispatchCommand(bungee.getConsole(), cmd);
|
||||
}else {
|
||||
bungee.getLogger().info("Connection [" + this.con.getName() + "] <-> [" + this.server.getInfo().getName() + "] tried executing a bungee console command but \"accept_bukkit_console_command_packets\" is set to false in config.yml");
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
final byte[] b = out.toByteArray();
|
||||
if (b.length != 0) {
|
||||
this.con.getServer().sendData("BungeeCord", b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketFFKick kick) throws Exception
|
||||
{
|
||||
ServerInfo def = bungee.getServerInfo( con.getPendingConnection().getListener().getFallbackServer() );
|
||||
if ( Objects.equals( server.getInfo(), def ) )
|
||||
{
|
||||
def = null;
|
||||
}
|
||||
ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, kick.getMessage(), def, ServerKickEvent.State.CONNECTED ) );
|
||||
if ( event.isCancelled() && event.getCancelServer() != null )
|
||||
{
|
||||
con.connectNow( event.getCancelServer() );
|
||||
} else
|
||||
{
|
||||
con.disconnect( bungee.getTranslation( "server_kick" ) + event.getKickReason() );
|
||||
}
|
||||
server.setObsolete( true );
|
||||
throw new CancelSendSignal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "[" + con.getName() + "] <-> DownstreamBridge <-> [" + server.getInfo().getName() + "]";
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "bungee", "con", "server" })
|
||||
public DownstreamBridge(final ProxyServer bungee, final UserConnection con, final ServerConnection server) {
|
||||
this.bungee = bungee;
|
||||
this.con = con;
|
||||
this.server = server;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
//
|
||||
// Decompiled by Procyon v0.5.36
|
||||
//
|
||||
|
||||
package net.md_5.bungee.connection;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.EncryptionUtil;
|
||||
import net.md_5.bungee.PacketConstants;
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.Util;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.LoginEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||
import net.md_5.bungee.eaglercraft.AuthHandler;
|
||||
import net.md_5.bungee.eaglercraft.BanList;
|
||||
import net.md_5.bungee.eaglercraft.BanList.BanCheck;
|
||||
import net.md_5.bungee.eaglercraft.BanList.BanState;
|
||||
import net.md_5.bungee.eaglercraft.WebSocketProxy;
|
||||
import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.netty.CipherDecoder;
|
||||
import net.md_5.bungee.netty.CipherEncoder;
|
||||
import net.md_5.bungee.netty.HandlerBoss;
|
||||
import net.md_5.bungee.netty.PacketDecoder;
|
||||
import net.md_5.bungee.netty.PacketHandler;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
import net.md_5.bungee.protocol.Forge;
|
||||
import net.md_5.bungee.protocol.packet.*;
|
||||
|
||||
public class InitialHandler extends PacketHandler implements PendingConnection {
|
||||
private final ProxyServer bungee;
|
||||
private ChannelWrapper ch;
|
||||
private final ListenerInfo listener;
|
||||
private Packet1Login forgeLogin;
|
||||
private Packet2Handshake handshake;
|
||||
private PacketFDEncryptionRequest request;
|
||||
private List<PacketFAPluginMessage> loginMessages;
|
||||
private List<PacketFAPluginMessage> registerMessages;
|
||||
private State thisState;
|
||||
private SecretKey sharedKey;
|
||||
private final Connection.Unsafe unsafe;
|
||||
|
||||
@Override
|
||||
public void connected(final ChannelWrapper channel) throws Exception {
|
||||
this.ch = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exception(final Throwable t) throws Exception {
|
||||
this.disconnect(ChatColor.RED + Util.exception(t));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final PacketFAPluginMessage pluginMessage) throws Exception {
|
||||
if (pluginMessage.getTag().equals("REGISTER")) {
|
||||
this.registerMessages.add(pluginMessage);
|
||||
} else {
|
||||
this.loginMessages.add(pluginMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final PacketFEPing ping) throws Exception {
|
||||
ServerPing response = new ServerPing(this.bungee.getProtocolVersion(), this.bungee.getGameVersion(), this.listener.getMotd(), this.bungee.getOnlineCount(), this.listener.getMaxPlayers());
|
||||
response = this.bungee.getPluginManager().callEvent(new ProxyPingEvent(this, response)).getResponse();
|
||||
final String kickMessage = ChatColor.DARK_BLUE + "\u0000" + response.getProtocolVersion() + "\u0000" + response.getGameVersion() + "\u0000" + response.getMotd() + "\u0000" + response.getCurrentPlayers() + "\u0000"
|
||||
+ response.getMaxPlayers();
|
||||
this.disconnect(kickMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final Packet1Login login) throws Exception {
|
||||
Preconditions.checkState(this.thisState == State.LOGIN, (Object) "Not expecting FORGE LOGIN");
|
||||
Preconditions.checkState(this.forgeLogin == null, (Object) "Already received FORGE LOGIN");
|
||||
this.forgeLogin = login;
|
||||
((PacketDecoder) this.ch.getHandle().pipeline().get((Class) PacketDecoder.class)).setProtocol(Forge.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final Packet2Handshake handshake) throws Exception {
|
||||
Preconditions.checkState(this.thisState == State.HANDSHAKE, (Object) "Not expecting HANDSHAKE");
|
||||
this.handshake = handshake;
|
||||
this.bungee.getLogger().log(Level.INFO, "{0} has connected", this);
|
||||
boolean skipEncryption = false;
|
||||
if (handshake.getProcolVersion() == 69) {
|
||||
skipEncryption = true;
|
||||
this.handshake.swapProtocol((byte) 78);
|
||||
}else if(handshake.getProcolVersion() > 78) {
|
||||
this.disconnect("this server does not support microsoft accounts");
|
||||
return;
|
||||
}else if(handshake.getProcolVersion() != 78) {
|
||||
this.disconnect("minecraft 1.5.2 required for eaglercraft backdoor access");
|
||||
return;
|
||||
}
|
||||
String un = handshake.getUsername();
|
||||
if (un.length() < 3) {
|
||||
this.disconnect("Username must be at least 3 characters");
|
||||
return;
|
||||
}
|
||||
if (un.length() > 16) {
|
||||
this.disconnect("Cannot have username longer than 16 characters");
|
||||
return;
|
||||
}
|
||||
if(!un.equals(un.replaceAll("[^A-Za-z0-9\\-_]", "_").trim())) {
|
||||
this.disconnect("Go fuck yourself");
|
||||
return;
|
||||
}
|
||||
if (BungeeCord.getInstance().tokenVerify.isEmpty()) {
|
||||
String hostname = handshake.getHost();
|
||||
if (hostname.contains(":")) {
|
||||
handshake.setHost(hostname.substring(0, hostname.indexOf(':')));
|
||||
}
|
||||
} else {
|
||||
handshake.setHost(BungeeCord.getInstance().tokenVerify);
|
||||
handshake.setPort(0);
|
||||
}
|
||||
InetAddress sc;
|
||||
synchronized(WebSocketProxy.localToRemote) {
|
||||
sc = WebSocketProxy.localToRemote.get(this.ch.getHandle().remoteAddress());
|
||||
}
|
||||
if(sc == null) {
|
||||
this.bungee.getLogger().log(Level.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()) {
|
||||
this.bungee.getLogger().log(Level.SEVERE, "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 {
|
||||
this.bungee.getLogger().log(Level.INFO, "Player '" + un + "' [" + sc.toString() + "] has remote websocket IP: " + sc.getHostAddress());
|
||||
}
|
||||
}
|
||||
String dnm;
|
||||
synchronized(WebSocketProxy.localToRemote) {
|
||||
dnm = WebSocketProxy.origins.get(this.ch.getHandle().remoteAddress());
|
||||
}
|
||||
if(dnm != null) {
|
||||
if(dnm.equalsIgnoreCase("null")) {
|
||||
this.bungee.getLogger().log(Level.INFO, "Player '" + un + "' [" + sc.toString() + "] is using an offline download");
|
||||
}else {
|
||||
this.bungee.getLogger().log(Level.INFO, "Player '" + un + "' [" + sc.toString() + "] is using a client at: " + dnm);
|
||||
}
|
||||
}
|
||||
BanCheck bc = BanList.checkBanned(un);
|
||||
if(bc.isBanned()) {
|
||||
switch(bc.reason) {
|
||||
case USER_BANNED:
|
||||
this.bungee.getLogger().log(Level.SEVERE, "Player '" + un + "' is banned by username, because '" + bc.string + "'");
|
||||
break;
|
||||
case WILDCARD_BANNED:
|
||||
this.bungee.getLogger().log(Level.SEVERE, "Player '" + un + "' is banned by wildcard: " + bc.match);
|
||||
break;
|
||||
case REGEX_BANNED:
|
||||
this.bungee.getLogger().log(Level.SEVERE, "Player '" + un + "' is banned by regex: " + bc.match);
|
||||
break;
|
||||
default:
|
||||
this.bungee.getLogger().log(Level.SEVERE, "Player '" + un + "' is banned: " + bc.string);
|
||||
}
|
||||
if(bc.reason == BanState.USER_BANNED || ((BungeeCord)bungee).config.shouldShowBanType()) {
|
||||
this.disconnect("" + ChatColor.RED + "You are banned.\n" + ChatColor.DARK_GRAY + "Reason: " + bc.string);
|
||||
}else {
|
||||
this.disconnect("" + ChatColor.RED + "You are banned.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int limit = BungeeCord.getInstance().config.getPlayerLimit();
|
||||
if (limit > 0 && this.bungee.getOnlineCount() > limit) {
|
||||
this.disconnect(this.bungee.getTranslation("proxy_full"));
|
||||
return;
|
||||
}
|
||||
if (!BungeeCord.getInstance().config.isOnlineMode() && this.bungee.getPlayer(un) != null) {
|
||||
this.disconnect(this.bungee.getTranslation("already_connected"));
|
||||
return;
|
||||
}
|
||||
this.unsafe().sendPacket(PacketConstants.I_AM_BUNGEE);
|
||||
this.unsafe().sendPacket(PacketConstants.FORGE_MOD_REQUEST);
|
||||
if(skipEncryption) {
|
||||
InitialHandler.this.thisState = State.LOGIN;
|
||||
handle((PacketCDClientStatus)null);
|
||||
}else {
|
||||
this.unsafe().sendPacket(this.request = EncryptionUtil.encryptRequest());
|
||||
this.thisState = State.ENCRYPT;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(final PacketFCEncryptionResponse encryptResponse) throws Exception {
|
||||
Preconditions.checkState(this.thisState == State.ENCRYPT, (Object) "Not expecting ENCRYPT");
|
||||
this.sharedKey = EncryptionUtil.getSecret(encryptResponse, this.request);
|
||||
final Cipher decrypt = EncryptionUtil.getCipher(2, this.sharedKey);
|
||||
this.ch.getHandle().pipeline().addBefore(PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, (ChannelHandler)new CipherDecoder(decrypt));
|
||||
this.finish();
|
||||
}
|
||||
|
||||
private void finish() throws GeneralSecurityException {
|
||||
final ProxiedPlayer old = this.bungee.getPlayer(this.handshake.getUsername());
|
||||
if (old != null) {
|
||||
old.disconnect(this.bungee.getTranslation("already_connected"));
|
||||
}
|
||||
final Callback<LoginEvent> complete = new Callback<LoginEvent>() {
|
||||
@Override
|
||||
public void done(final LoginEvent result, final Throwable error) {
|
||||
if (result.isCancelled()) {
|
||||
InitialHandler.this.disconnect(result.getCancelReason());
|
||||
}
|
||||
if (InitialHandler.this.ch.isClosed()) {
|
||||
return;
|
||||
}
|
||||
InitialHandler.this.thisState = State.LOGIN;
|
||||
InitialHandler.this.ch.getHandle().eventLoop().execute((Runnable)new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
InitialHandler.this.unsafe().sendPacket(new PacketFCEncryptionResponse(new byte[0], new byte[0]));
|
||||
try {
|
||||
final Cipher encrypt = EncryptionUtil.getCipher(1, InitialHandler.this.sharedKey);
|
||||
InitialHandler.this.ch.getHandle().pipeline().addBefore(PipelineUtils.DECRYPT_HANDLER, PipelineUtils.ENCRYPT_HANDLER, (ChannelHandler)new CipherEncoder(encrypt));
|
||||
}
|
||||
catch (GeneralSecurityException ex) {
|
||||
InitialHandler.this.disconnect("Cipher error: " + Util.exception(ex));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
this.bungee.getPluginManager().callEvent(new LoginEvent(this, complete));
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
String origin = WebSocketProxy.origins.get(this.ch.getHandle().remoteAddress());
|
||||
if(origin != null) {
|
||||
userCon.getAttachment().put("origin", origin);
|
||||
}
|
||||
userCon.init();
|
||||
HandlerBoss handlerBoss = ((HandlerBoss) this.ch.getHandle().pipeline().get((Class) HandlerBoss.class));
|
||||
if (BungeeCord.getInstance().config.getAuthInfo().isEnabled()) {
|
||||
handlerBoss.setHandler(new AuthHandler(this.bungee, userCon, handlerBoss));
|
||||
} else {
|
||||
this.bungee.getPluginManager().callEvent(new PostLoginEvent(userCon));
|
||||
handlerBoss.setHandler(new UpstreamBridge(this.bungee, userCon));
|
||||
final ServerInfo server = this.bungee.getReconnectHandler().getServer(userCon);
|
||||
userCon.connect(server, true);
|
||||
}
|
||||
this.thisState = State.FINISHED;
|
||||
throw new CancelSendSignal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void disconnect(final String reason) {
|
||||
if (!this.ch.isClosed()) {
|
||||
this.unsafe().sendPacket(new PacketFFKick(reason));
|
||||
this.ch.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return (this.handshake == null) ? null : this.handshake.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getVersion() {
|
||||
return (byte) ((this.handshake == null) ? -1 : this.handshake.getProcolVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getVirtualHost() {
|
||||
return (this.handshake == null) ? null : new InetSocketAddress(this.handshake.getHost(), this.handshake.getPort() & 0xFFFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getAddress() {
|
||||
return (InetSocketAddress) this.ch.getHandle().remoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection.Unsafe unsafe() {
|
||||
return this.unsafe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + ((this.getName() != null) ? this.getName() : this.getAddress()) + "] <-> InitialHandler";
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "bungee", "listener" })
|
||||
public InitialHandler(final ProxyServer bungee, final ListenerInfo listener) {
|
||||
this.loginMessages = new ArrayList<PacketFAPluginMessage>();
|
||||
this.registerMessages = new ArrayList<PacketFAPluginMessage>();
|
||||
this.thisState = State.HANDSHAKE;
|
||||
this.unsafe = new Connection.Unsafe() {
|
||||
@Override
|
||||
public void sendPacket(final DefinedPacket packet) {
|
||||
InitialHandler.this.ch.write(packet);
|
||||
}
|
||||
};
|
||||
this.bungee = bungee;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenerInfo getListener() {
|
||||
return this.listener;
|
||||
}
|
||||
|
||||
public Packet1Login getForgeLogin() {
|
||||
return this.forgeLogin;
|
||||
}
|
||||
|
||||
public Packet2Handshake getHandshake() {
|
||||
return this.handshake;
|
||||
}
|
||||
|
||||
public List<PacketFAPluginMessage> getLoginMessages() {
|
||||
return this.loginMessages;
|
||||
}
|
||||
|
||||
public List<PacketFAPluginMessage> getRegisterMessages() {
|
||||
return this.registerMessages;
|
||||
}
|
||||
|
||||
private enum State {
|
||||
HANDSHAKE, ENCRYPT, LOGIN, FINISHED;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user