├── native ├── src │ └── main │ │ ├── resources │ │ ├── native-cipher.so │ │ └── native-compress.so │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── jni │ │ │ ├── NativeCodeException.java │ │ │ ├── cipher │ │ │ ├── NativeCipherImpl.java │ │ │ └── BungeeCipher.java │ │ │ └── zlib │ │ │ ├── BungeeZlib.java │ │ │ ├── NativeCompressImpl.java │ │ │ ├── NativeZlib.java │ │ │ └── JavaZlib.java │ │ └── c │ │ ├── net_md_5_bungee_jni_cipher_NativeCipherImpl.h │ │ ├── net_md_5_bungee_jni_zlib_NativeCompressImpl.h │ │ └── NativeCipherImpl.cpp ├── compile-native.sh └── pom.xml ├── proxy └── src │ ├── main │ ├── resources │ │ └── yggdrasil_session_pubkey.der │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ ├── module │ │ ├── ModuleSource.java │ │ ├── ModuleSpec.java │ │ ├── ModuleVersion.java │ │ ├── TravisCiModuleSource.java │ │ └── JenkinsModuleSource.java │ │ ├── connection │ │ ├── LoginResult.java │ │ └── CancelSendSignal.java │ │ ├── util │ │ ├── BufUtil.java │ │ ├── QuietException.java │ │ ├── AddressUtil.java │ │ └── AllowedCharacters.java │ │ ├── compress │ │ ├── CompressFactory.java │ │ ├── PacketCompressor.java │ │ └── PacketDecompressor.java │ │ ├── command │ │ ├── CommandBungee.java │ │ ├── CommandEnd.java │ │ ├── CommandIP.java │ │ ├── CommandPerms.java │ │ ├── CommandReload.java │ │ └── ConsoleCommandCompleter.java │ │ ├── netty │ │ ├── cipher │ │ │ ├── CipherEncoder.java │ │ │ └── CipherDecoder.java │ │ └── PacketHandler.java │ │ ├── forge │ │ ├── IForgeClientPacketHandler.java │ │ ├── IForgeServerPacketHandler.java │ │ └── ForgeConstants.java │ │ ├── http │ │ └── HttpInitializer.java │ │ ├── PlayerSkinConfiguration.java │ │ └── PlayerInfoSerializer.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ ├── api │ └── plugin │ │ └── DummyPlugin.java │ ├── util │ └── AddressUtilTest.java │ └── ThrottleTest.java ├── module ├── cmd-find │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── plugin.yml │ │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── find │ │ │ ├── PluginFind.java │ │ │ └── CommandFind.java │ └── pom.xml ├── cmd-list │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── plugin.yml │ │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── list │ │ │ ├── PluginList.java │ │ │ └── CommandList.java │ └── pom.xml ├── cmd-send │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── plugin.yml │ │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── send │ │ │ └── PluginSend.java │ └── pom.xml ├── cmd-alert │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── plugin.yml │ │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── alert │ │ │ ├── PluginAlert.java │ │ │ ├── CommandAlert.java │ │ │ └── CommandAlertRaw.java │ └── pom.xml ├── cmd-server │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── plugin.yml │ │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── server │ │ │ └── PluginServer.java │ └── pom.xml ├── reconnect-yaml │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── plugin.yml │ │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── reconnect │ │ │ └── yaml │ │ │ └── PluginYaml.java │ └── pom.xml └── pom.xml ├── .gitmodules ├── api └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ ├── api │ │ ├── plugin │ │ │ ├── Listener.java │ │ │ ├── TabExecutor.java │ │ │ ├── Event.java │ │ │ ├── Cancellable.java │ │ │ ├── PluginLogger.java │ │ │ └── PluginDescription.java │ │ ├── connection │ │ │ ├── ConnectedPlayer.java │ │ │ └── Server.java │ │ ├── Callback.java │ │ ├── score │ │ │ ├── Score.java │ │ │ ├── Objective.java │ │ │ ├── Position.java │ │ │ └── Team.java │ │ ├── SkinConfiguration.java │ │ ├── event │ │ │ ├── ProxyReloadEvent.java │ │ │ ├── PostLoginEvent.java │ │ │ ├── PlayerDisconnectEvent.java │ │ │ ├── TargetedEvent.java │ │ │ ├── ServerSwitchEvent.java │ │ │ ├── ServerDisconnectEvent.java │ │ │ ├── SettingsChangedEvent.java │ │ │ ├── ServerConnectedEvent.java │ │ │ ├── PlayerHandshakeEvent.java │ │ │ ├── ProxyPingEvent.java │ │ │ ├── ClientConnectEvent.java │ │ │ ├── PluginMessageEvent.java │ │ │ ├── PermissionCheckEvent.java │ │ │ ├── TabCompleteEvent.java │ │ │ ├── TabCompleteResponseEvent.java │ │ │ ├── ChatEvent.java │ │ │ └── LoginEvent.java │ │ ├── scheduler │ │ │ ├── GroupedThreadFactory.java │ │ │ └── ScheduledTask.java │ │ ├── ReconnectHandler.java │ │ ├── AbstractReconnectHandler.java │ │ └── ServerConnectRequest.java │ │ ├── util │ │ ├── CaseInsensitiveMap.java │ │ ├── CaseInsensitiveSet.java │ │ └── CaseInsensitiveHashingStrategy.java │ │ └── command │ │ └── PlayerCommand.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ └── util │ ├── UUIDTest.java │ └── CaseInsensitiveTest.java ├── protocol └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── protocol │ │ ├── Location.java │ │ ├── OverflowPacketException.java │ │ ├── PlayerPublicKey.java │ │ ├── BadPacketException.java │ │ ├── Property.java │ │ ├── PacketWrapper.java │ │ ├── KickStringWriter.java │ │ ├── packet │ │ ├── StatusRequest.java │ │ ├── LegacyHandshake.java │ │ ├── PingPacket.java │ │ ├── Kick.java │ │ ├── ClientStatus.java │ │ ├── StatusResponse.java │ │ ├── ViewDistance.java │ │ ├── Subtitle.java │ │ ├── LegacyPing.java │ │ ├── GameState.java │ │ ├── ClearTitles.java │ │ ├── ScoreboardDisplay.java │ │ ├── SetCompression.java │ │ ├── EntityStatus.java │ │ ├── SystemChat.java │ │ ├── TitleTimes.java │ │ ├── PlayerListHeaderFooter.java │ │ ├── Handshake.java │ │ ├── LoginPayloadRequest.java │ │ ├── LoginRequest.java │ │ ├── ClientChat.java │ │ ├── LoginPayloadResponse.java │ │ ├── KeepAlive.java │ │ ├── EncryptionRequest.java │ │ └── ClientCommand.java │ │ ├── MinecraftInput.java │ │ ├── MinecraftEncoder.java │ │ ├── Varint21LengthFieldPrepender.java │ │ ├── MinecraftOutput.java │ │ ├── LegacyDecoder.java │ │ └── MinecraftDecoder.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ └── protocol │ └── packet │ └── PluginMessageTest.java ├── chat ├── src │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ ├── api │ │ │ ├── ChatMessageType.java │ │ │ └── chat │ │ │ │ ├── hover │ │ │ │ └── content │ │ │ │ │ ├── Item.java │ │ │ │ │ ├── Content.java │ │ │ │ │ ├── Entity.java │ │ │ │ │ ├── TextSerializer.java │ │ │ │ │ ├── Text.java │ │ │ │ │ └── EntitySerializer.java │ │ │ │ ├── ClickEvent.java │ │ │ │ ├── KeybindComponent.java │ │ │ │ ├── Keybinds.java │ │ │ │ ├── SelectorComponent.java │ │ │ │ └── ItemTag.java │ │ │ └── chat │ │ │ ├── TextComponentSerializer.java │ │ │ ├── SelectorComponentSerializer.java │ │ │ ├── KeybindComponentSerializer.java │ │ │ └── TranslatableComponentSerializer.java │ └── test │ │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── api │ │ └── chat │ │ └── TranslatableComponentTest.java └── pom.xml ├── ISSUE_TEMPLATE.md ├── .gitignore ├── bootstrap └── src │ └── main │ └── java │ └── net │ └── md_5 │ └── bungee │ └── Bootstrap.java ├── event ├── src │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── event │ │ │ ├── EventPriority.java │ │ │ ├── EventHandlerMethod.java │ │ │ └── EventHandler.java │ └── test │ │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── event │ │ ├── UnregisteringListenerTest.java │ │ ├── SubclassTest.java │ │ └── EventBusTest.java └── pom.xml ├── config ├── src │ ├── test │ │ └── java │ │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── config │ │ │ └── DefaultConfigurationTest.java │ └── main │ │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── config │ │ └── ConfigurationProvider.java └── pom.xml ├── log ├── src │ └── main │ │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── log │ │ ├── LoggingOutputStream.java │ │ ├── LogDispatcher.java │ │ ├── BungeeLogger.java │ │ └── ConciseFormatter.java └── pom.xml ├── query ├── src │ └── main │ │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── query │ │ └── RemoteQuery.java └── pom.xml ├── slf4j └── pom.xml ├── LICENSE ├── .travis.yml └── README.md /native/src/main/resources/native-cipher.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HexagonMC/BungeeCord/HEAD/native/src/main/resources/native-cipher.so -------------------------------------------------------------------------------- /native/src/main/resources/native-compress.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HexagonMC/BungeeCord/HEAD/native/src/main/resources/native-compress.so -------------------------------------------------------------------------------- /proxy/src/main/resources/yggdrasil_session_pubkey.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HexagonMC/BungeeCord/HEAD/proxy/src/main/resources/yggdrasil_session_pubkey.der -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/module/ModuleSource.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module; 2 | 3 | interface ModuleSource 4 | { 5 | 6 | void retrieve(ModuleSpec module, ModuleVersion version); 7 | } 8 | -------------------------------------------------------------------------------- /module/cmd-find/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.cmd.find.PluginFind 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /module/cmd-list/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.cmd.list.PluginList 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /module/cmd-send/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.cmd.send.PluginSend 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /module/cmd-alert/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.cmd.alert.PluginAlert 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "native/mbedtls"] 2 | path = native/mbedtls 3 | url = https://github.com/ARMmbed/mbedtls.git 4 | [submodule "native/zlib"] 5 | path = native/zlib 6 | url = https://github.com/cloudflare/zlib.git 7 | -------------------------------------------------------------------------------- /module/cmd-server/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.cmd.server.PluginServer 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /module/reconnect-yaml/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.reconnect.yaml.PluginYaml 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/plugin/Listener.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | /** 4 | * Dummy interface which all event subscribers and listeners must implement. 5 | */ 6 | public interface Listener 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/Location.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class Location 7 | { 8 | 9 | private final String dimension; 10 | private final long pos; 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/connection/ConnectedPlayer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.connection; 2 | 3 | /** 4 | * Represents a player physically connected to the world hosted on this server. 5 | */ 6 | public interface ConnectedPlayer extends ProxiedPlayer 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/ChatMessageType.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api; 2 | 3 | /** 4 | * Represents the position on the screen where a message will appear. 5 | */ 6 | public enum ChatMessageType 7 | { 8 | 9 | CHAT, 10 | SYSTEM, 11 | ACTION_BAR 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/plugin/TabExecutor.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | import net.md_5.bungee.api.CommandSender; 4 | 5 | public interface TabExecutor 6 | { 7 | 8 | public Iterable onTabComplete(CommandSender sender, String[] args); 9 | } 10 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/NativeCodeException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni; 2 | 3 | public class NativeCodeException extends Exception 4 | { 5 | 6 | public NativeCodeException(String message, int reason) 7 | { 8 | super( message + " : " + reason ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/OverflowPacketException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | public class OverflowPacketException extends RuntimeException 4 | { 5 | 6 | public OverflowPacketException(String message) 7 | { 8 | super( message ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/PlayerPublicKey.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class PlayerPublicKey 7 | { 8 | 9 | private final long expiry; 10 | private final byte[] key; 11 | private final byte[] signature; 12 | } 13 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/module/ModuleSpec.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module; 2 | 3 | import java.io.File; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class ModuleSpec 8 | { 9 | 10 | private final String name; 11 | private final File file; 12 | private final ModuleSource provider; 13 | } 14 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/cipher/NativeCipherImpl.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.cipher; 2 | 3 | class NativeCipherImpl 4 | { 5 | 6 | native long init(boolean forEncryption, byte[] key); 7 | 8 | native void free(long ctx); 9 | 10 | native void cipher(long ctx, long in, long out, int length); 11 | } 12 | -------------------------------------------------------------------------------- /proxy/src/test/java/net/md_5/bungee/api/plugin/DummyPlugin.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | public final class DummyPlugin extends Plugin 4 | { 5 | 6 | public static final DummyPlugin INSTANCE = new DummyPlugin(); 7 | 8 | private DummyPlugin() 9 | { 10 | super( null, null ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/plugin/Event.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | /** 4 | * Dummy class which all callable events must extend. 5 | */ 6 | public abstract class Event 7 | { 8 | 9 | /** 10 | * Method called after this event has been dispatched to all handlers. 11 | */ 12 | public void postCall() 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /module/cmd-find/src/main/java/net/md_5/bungee/module/cmd/find/PluginFind.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.find; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | public class PluginFind extends Plugin 6 | { 7 | 8 | @Override 9 | public void onEnable() 10 | { 11 | getProxy().getPluginManager().registerCommand( this, new CommandFind() ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /module/cmd-list/src/main/java/net/md_5/bungee/module/cmd/list/PluginList.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.list; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | public class PluginList extends Plugin 6 | { 7 | 8 | @Override 9 | public void onEnable() 10 | { 11 | getProxy().getPluginManager().registerCommand( this, new CommandList() ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /module/cmd-send/src/main/java/net/md_5/bungee/module/cmd/send/PluginSend.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.send; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | public class PluginSend extends Plugin 6 | { 7 | 8 | @Override 9 | public void onEnable() 10 | { 11 | getProxy().getPluginManager().registerCommand( this, new CommandSend() ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/zlib/BungeeZlib.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.zlib; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import java.util.zip.DataFormatException; 5 | 6 | public interface BungeeZlib 7 | { 8 | 9 | void init(boolean compress, int level); 10 | 11 | void free(); 12 | 13 | void process(ByteBuf in, ByteBuf out) throws DataFormatException; 14 | } 15 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/connection/LoginResult.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.connection; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import net.md_5.bungee.protocol.Property; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | public class LoginResult 10 | { 11 | 12 | private String id; 13 | private String name; 14 | private Property[] properties; 15 | } 16 | -------------------------------------------------------------------------------- /module/cmd-server/src/main/java/net/md_5/bungee/module/cmd/server/PluginServer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.server; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | public class PluginServer extends Plugin 6 | { 7 | 8 | @Override 9 | public void onEnable() 10 | { 11 | getProxy().getPluginManager().registerCommand( this, new CommandServer() ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/BadPacketException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | public class BadPacketException extends RuntimeException 4 | { 5 | 6 | public BadPacketException(String message) 7 | { 8 | super( message ); 9 | } 10 | 11 | public BadPacketException(String message, Throwable cause) 12 | { 13 | super( message, cause ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What Hexacord version are you using? Post the output of /bungee 2 | 3 | 4 | ### Are you using Bungee plugins? If yes, please list all of them + versionnumber 5 | 6 | 7 | ### How can we reproduce the error/bug? 8 | 9 | 10 | ### Is an error message (bungee/spigot/client)? If yes, use pastebin.com and share the link. 11 | 12 | 13 | ### In addidtion to that, please explain your issue as detailed as possible. 14 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/util/BufUtil.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.ByteBufUtil; 5 | import lombok.NoArgsConstructor; 6 | 7 | @NoArgsConstructor 8 | public class BufUtil 9 | { 10 | 11 | public static String dump(ByteBuf buf, int maxLen) 12 | { 13 | return ByteBufUtil.hexDump( buf, 0, Math.min( buf.writerIndex(), maxLen ) ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/Property.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | @Data 7 | @AllArgsConstructor 8 | public class Property 9 | { 10 | 11 | private String name; 12 | private String value; 13 | private String signature; 14 | 15 | public Property(String name, String value) 16 | { 17 | this( name, value, null ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/compress/CompressFactory.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.compress; 2 | 3 | import net.md_5.bungee.jni.NativeCode; 4 | import net.md_5.bungee.jni.zlib.BungeeZlib; 5 | import net.md_5.bungee.jni.zlib.JavaZlib; 6 | import net.md_5.bungee.jni.zlib.NativeZlib; 7 | 8 | public class CompressFactory 9 | { 10 | 11 | public static final NativeCode zlib = new NativeCode<>( "native-compress", JavaZlib::new, NativeZlib::new ); 12 | } 13 | -------------------------------------------------------------------------------- /module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/PluginAlert.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.alert; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | public class PluginAlert extends Plugin 6 | { 7 | 8 | @Override 9 | public void onEnable() 10 | { 11 | getProxy().getPluginManager().registerCommand( this, new CommandAlert() ); 12 | getProxy().getPluginManager().registerCommand( this, new CommandAlertRaw() ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/Callback.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api; 2 | 3 | /** 4 | * Represents a method which may be called once a result has been computed 5 | * asynchronously. 6 | * 7 | * @param the type of result 8 | */ 9 | public interface Callback 10 | { 11 | 12 | /** 13 | * Called when the result is done. 14 | * 15 | * @param result the result of the computation 16 | * @param error the error(s) that occurred, if any 17 | */ 18 | public void done(V result, Throwable error); 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse stuff 2 | .classpath 3 | .project 4 | .settings/ 5 | 6 | # netbeans 7 | nbproject/ 8 | nbactions.xml 9 | 10 | # we use maven! 11 | build.xml 12 | 13 | # maven 14 | target/ 15 | dependency-reduced-pom.xml 16 | 17 | # vim 18 | .*.sw[a-p] 19 | 20 | # various other potential build files 21 | build/ 22 | bin/ 23 | dist/ 24 | manifest.mf 25 | 26 | # Mac filesystem dust 27 | .DS_Store 28 | 29 | # intellij 30 | *.iml 31 | *.ipr 32 | *.iws 33 | .idea/ 34 | 35 | # other files 36 | *.log* 37 | 38 | # delombok 39 | */src/main/lombok 40 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import gnu.trove.map.hash.TCustomHashMap; 4 | import java.util.Map; 5 | 6 | public class CaseInsensitiveMap extends TCustomHashMap 7 | { 8 | 9 | public CaseInsensitiveMap() 10 | { 11 | super( CaseInsensitiveHashingStrategy.INSTANCE ); 12 | } 13 | 14 | public CaseInsensitiveMap(Map map) 15 | { 16 | super( CaseInsensitiveHashingStrategy.INSTANCE, map ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/score/Score.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.score; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * Represents a scoreboard score entry. 7 | */ 8 | @Data 9 | public class Score 10 | { 11 | 12 | /** 13 | * Name to be displayed in the list. 14 | */ 15 | private final String itemName; // Player 16 | /** 17 | * Unique name of the score. 18 | */ 19 | private final String scoreName; // Score 20 | /** 21 | * Value of the score. 22 | */ 23 | private final int value; 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/util/CaseInsensitiveSet.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import gnu.trove.set.hash.TCustomHashSet; 4 | import java.util.Collection; 5 | 6 | public class CaseInsensitiveSet extends TCustomHashSet 7 | { 8 | 9 | public CaseInsensitiveSet() 10 | { 11 | super( CaseInsensitiveHashingStrategy.INSTANCE ); 12 | } 13 | 14 | public CaseInsensitiveSet(Collection collection) 15 | { 16 | super( CaseInsensitiveHashingStrategy.INSTANCE, collection ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/SkinConfiguration.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api; 2 | 3 | /** 4 | * Represents a player's skin settings. These settings can be changed by the 5 | * player under Skin Configuration in the Options menu. 6 | */ 7 | public interface SkinConfiguration 8 | { 9 | 10 | boolean hasCape(); 11 | 12 | boolean hasJacket(); 13 | 14 | boolean hasLeftSleeve(); 15 | 16 | boolean hasRightSleeve(); 17 | 18 | boolean hasLeftPants(); 19 | 20 | boolean hasRightPants(); 21 | 22 | boolean hasHat(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /native/compile-native.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | echo "Compiling mbedtls" 6 | (cd mbedtls && make no_test) 7 | 8 | echo "Compiling zlib" 9 | (cd zlib && CFLAGS=-fPIC ./configure --static && make) 10 | 11 | CXX="g++ -shared -fPIC -Wl,--wrap=memcpy -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" 12 | 13 | $CXX -Imbedtls/include src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so mbedtls/library/libmbedcrypto.a 14 | $CXX -Izlib src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so zlib/libz.a 15 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/util/QuietException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | /** 4 | * Exception without a stack trace component. 5 | */ 6 | public class QuietException extends RuntimeException 7 | { 8 | 9 | public QuietException(String message) 10 | { 11 | super( message ); 12 | } 13 | 14 | @Override 15 | public Throwable initCause(Throwable cause) 16 | { 17 | return this; 18 | } 19 | 20 | @Override 21 | public Throwable fillInStackTrace() 22 | { 23 | return this; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/score/Objective.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.score; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | /** 7 | * Represents an objective entry. 8 | */ 9 | @Data 10 | @AllArgsConstructor 11 | public class Objective 12 | { 13 | 14 | /** 15 | * Name of the objective. 16 | */ 17 | private final String name; 18 | /** 19 | * Value of the objective. 20 | */ 21 | private String value; 22 | /** 23 | * Type; integer or hearts 24 | */ 25 | private String type; 26 | } 27 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @RequiredArgsConstructor 8 | public class PacketWrapper 9 | { 10 | 11 | public final DefinedPacket packet; 12 | public final ByteBuf buf; 13 | @Setter 14 | private boolean released; 15 | 16 | public void trySingleRelease() 17 | { 18 | if ( !released ) 19 | { 20 | buf.release(); 21 | released = true; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ProxyReloadEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.Getter; 6 | import net.md_5.bungee.api.CommandSender; 7 | import net.md_5.bungee.api.plugin.Event; 8 | 9 | /** 10 | * Called when somebody reloads BungeeCord 11 | */ 12 | @Getter 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class ProxyReloadEvent extends Event 16 | { 17 | 18 | /** 19 | * Creator of the action. 20 | */ 21 | private final CommandSender sender; 22 | } 23 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/connection/CancelSendSignal.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.connection; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | 6 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 7 | public class CancelSendSignal extends Error 8 | { 9 | 10 | public static final CancelSendSignal INSTANCE = new CancelSendSignal(); 11 | 12 | @Override 13 | public Throwable initCause(Throwable cause) 14 | { 15 | return this; 16 | } 17 | 18 | @Override 19 | public Throwable fillInStackTrace() 20 | { 21 | return this; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/zlib/NativeCompressImpl.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.zlib; 2 | 3 | public class NativeCompressImpl 4 | { 5 | 6 | int consumed; 7 | boolean finished; 8 | 9 | static 10 | { 11 | initFields(); 12 | } 13 | 14 | static native void initFields(); 15 | 16 | native void end(long ctx, boolean compress); 17 | 18 | native void reset(long ctx, boolean compress); 19 | 20 | native long init(boolean compress, int compressionLevel); 21 | 22 | native int process(long ctx, long in, int inLength, long out, int outLength, boolean compress); 23 | } 24 | -------------------------------------------------------------------------------- /bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee; 2 | 3 | public class Bootstrap 4 | { 5 | 6 | public static void main(String[] args) throws Exception 7 | { 8 | if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52.0 ) 9 | { 10 | System.err.println( "*** ERROR *** BungeeCord requires Java 8 or above to function! Please download and install it!" ); 11 | System.out.println( "You can check your Java version with the command: java -version" ); 12 | return; 13 | } 14 | 15 | BungeeCordLauncher.main( args ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /event/src/main/java/net/md_5/bungee/event/EventPriority.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | 6 | /** 7 | * Importance of the {@link EventHandler}. When executing an Event, the handlers 8 | * are called in order of their Priority. 9 | */ 10 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 11 | public class EventPriority 12 | { 13 | 14 | public static final byte LOWEST = -64; 15 | public static final byte LOW = -32; 16 | public static final byte NORMAL = 0; 17 | public static final byte HIGH = 32; 18 | public static final byte HIGHEST = 64; 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/plugin/Cancellable.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | /** 4 | * Events that implement this indicate that they may be cancelled and thus 5 | * prevented from happening. 6 | */ 7 | public interface Cancellable 8 | { 9 | 10 | /** 11 | * Get whether or not this event is cancelled. 12 | * 13 | * @return the cancelled state of this event 14 | */ 15 | public boolean isCancelled(); 16 | 17 | /** 18 | * Sets the cancelled state of this event. 19 | * 20 | * @param cancel the state to set 21 | */ 22 | public void setCancelled(boolean cancel); 23 | } 24 | -------------------------------------------------------------------------------- /event/src/main/java/net/md_5/bungee/event/EventHandlerMethod.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | 8 | @AllArgsConstructor 9 | public class EventHandlerMethod 10 | { 11 | 12 | @Getter 13 | private final Object listener; 14 | @Getter 15 | private final Method method; 16 | 17 | public void invoke(Object event) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException 18 | { 19 | method.invoke( listener, event ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/score/Position.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.score; 2 | 3 | /** 4 | * Represents locations for a scoreboard to be displayed. 5 | */ 6 | public enum Position 7 | { 8 | 9 | LIST, 10 | SIDEBAR, 11 | BELOW, 12 | SIDEBAR_BLACK, 13 | SIDEBAR_DARK_BLUE, 14 | SIDEBAR_DARK_GREEN, 15 | SIDEBAR_DARK_AQUA, 16 | SIDEBAR_DARK_RED, 17 | SIDEBAR_DARK_PURPLE, 18 | SIDEBAR_GOLD, 19 | SIDEBAR_GRAY, 20 | SIDEBAR_DARK_GRAY, 21 | SIDEBAR_BLUE, 22 | SIDEBAR_GREEN, 23 | SIDEBAR_AQUA, 24 | SIDEBAR_RED, 25 | SIDEBAR_LIGHT_PURPLE, 26 | SIDEBAR_YELLOW, 27 | SIDEBAR_WHITE; 28 | } 29 | -------------------------------------------------------------------------------- /proxy/src/test/java/net/md_5/bungee/util/AddressUtilTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import java.net.InetSocketAddress; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class AddressUtilTest 8 | { 9 | 10 | @Test 11 | public void testScope() 12 | { 13 | InetSocketAddress addr = new InetSocketAddress( "0:0:0:0:0:0:0:1%0", 25577 ); 14 | Assert.assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr ) ); 15 | 16 | InetSocketAddress addr2 = new InetSocketAddress( "0:0:0:0:0:0:0:1", 25577 ); 17 | Assert.assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr2 ) ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /event/src/test/java/net/md_5/bungee/event/UnregisteringListenerTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class UnregisteringListenerTest 7 | { 8 | 9 | private final EventBus bus = new EventBus(); 10 | 11 | @Test 12 | public void testPriority() 13 | { 14 | bus.register( this ); 15 | bus.unregister( this ); 16 | bus.post( new TestEvent() ); 17 | } 18 | 19 | @EventHandler 20 | public void onEvent(TestEvent evt) 21 | { 22 | Assert.fail( "Event listener wasn't unregistered" ); 23 | } 24 | 25 | public static class TestEvent 26 | { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /protocol/src/test/java/net/md_5/bungee/protocol/packet/PluginMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class PluginMessageTest 7 | { 8 | 9 | @Test 10 | public void testModerniseChannel() 11 | { 12 | Assert.assertEquals( "bungeecord:main", PluginMessage.MODERNISE.apply( "BungeeCord" ) ); 13 | Assert.assertEquals( "BungeeCord", PluginMessage.MODERNISE.apply( "bungeecord:main" ) ); 14 | Assert.assertEquals( "legacy:foo", PluginMessage.MODERNISE.apply( "FoO" ) ); 15 | Assert.assertEquals( "foo:bar", PluginMessage.MODERNISE.apply( "foo:bar" ) ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/PostLoginEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.connection.ProxiedPlayer; 7 | import net.md_5.bungee.api.plugin.Event; 8 | 9 | /** 10 | * Event called as soon as a connection has a {@link ProxiedPlayer} and is ready 11 | * to be connected to a server. 12 | */ 13 | @Data 14 | @ToString(callSuper = false) 15 | @EqualsAndHashCode(callSuper = false) 16 | public class PostLoginEvent extends Event 17 | { 18 | 19 | /** 20 | * The player involved with this event. 21 | */ 22 | private final ProxiedPlayer player; 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/PlayerDisconnectEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.connection.ProxiedPlayer; 7 | import net.md_5.bungee.api.plugin.Event; 8 | 9 | /** 10 | * Called when a player has left the proxy, it is not safe to call any methods 11 | * that perform an action on the passed player instance. 12 | */ 13 | @Data 14 | @ToString(callSuper = false) 15 | @EqualsAndHashCode(callSuper = false) 16 | public class PlayerDisconnectEvent extends Event 17 | { 18 | 19 | /** 20 | * Player disconnecting. 21 | */ 22 | private final ProxiedPlayer player; 23 | } 24 | -------------------------------------------------------------------------------- /event/src/test/java/net/md_5/bungee/event/SubclassTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class SubclassTest extends EventBusTest 8 | { 9 | 10 | private final CountDownLatch latch = new CountDownLatch( 1 ); 11 | 12 | @Test 13 | @Override 14 | public void testNestedEvents() 15 | { 16 | super.testNestedEvents(); 17 | Assert.assertEquals( 0, latch.getCount() ); 18 | } 19 | 20 | @EventHandler 21 | protected void extraListener(FirstEvent event) 22 | { 23 | Assert.assertEquals( 1, latch.getCount() ); 24 | latch.countDown(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/cipher/BungeeCipher.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.cipher; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import java.security.GeneralSecurityException; 6 | import javax.crypto.SecretKey; 7 | 8 | /** 9 | * Class to expose cipher methods from either native or fallback Java cipher. 10 | */ 11 | public interface BungeeCipher 12 | { 13 | 14 | void init(boolean forEncryption, SecretKey key) throws GeneralSecurityException; 15 | 16 | void free(); 17 | 18 | void cipher(ByteBuf in, ByteBuf out) throws GeneralSecurityException; 19 | 20 | ByteBuf cipher(ChannelHandlerContext ctx, ByteBuf in) throws GeneralSecurityException; 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import net.md_5.bungee.api.connection.Connection; 7 | import net.md_5.bungee.api.plugin.Event; 8 | 9 | /** 10 | * An event which occurs in the communication between two nodes. 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public abstract class TargetedEvent extends Event 16 | { 17 | 18 | /** 19 | * Creator of the action. 20 | */ 21 | private final Connection sender; 22 | /** 23 | * Receiver of the action. 24 | */ 25 | private final Connection receiver; 26 | } 27 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandler; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.MessageToByteEncoder; 7 | 8 | @ChannelHandler.Sharable 9 | public class KickStringWriter extends MessageToByteEncoder 10 | { 11 | 12 | @Override 13 | protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) throws Exception 14 | { 15 | out.writeByte( 0xFF ); 16 | out.writeShort( msg.length() ); 17 | for ( char c : msg.toCharArray() ) 18 | { 19 | out.writeChar( c ); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/plugin/PluginLogger.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | import java.util.logging.LogRecord; 4 | import java.util.logging.Logger; 5 | 6 | public class PluginLogger extends Logger 7 | { 8 | 9 | private final String pluginName; 10 | 11 | protected PluginLogger(Plugin plugin) 12 | { 13 | super( plugin.getClass().getCanonicalName(), null ); 14 | pluginName = "[" + plugin.getDescription().getName() + "] "; 15 | setParent( plugin.getProxy().getLogger() ); 16 | } 17 | 18 | @Override 19 | public void log(LogRecord logRecord) 20 | { 21 | logRecord.setMessage( pluginName + logRecord.getMessage() ); 22 | super.log( logRecord ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /module/reconnect-yaml/src/main/java/net/md_5/bungee/module/reconnect/yaml/PluginYaml.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.reconnect.yaml; 2 | 3 | import net.md_5.bungee.api.config.ListenerInfo; 4 | import net.md_5.bungee.api.plugin.Plugin; 5 | 6 | public class PluginYaml extends Plugin 7 | { 8 | 9 | @Override 10 | public void onEnable() 11 | { 12 | // TODO: Abstract this for other reconnect modules 13 | for ( ListenerInfo info : getProxy().getConfig().getListeners() ) 14 | { 15 | if ( !info.isForceDefault() && getProxy().getReconnectHandler() == null ) 16 | { 17 | getProxy().setReconnectHandler( new YamlReconnectHandler() ); 18 | break; 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/util/AddressUtil.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import java.net.Inet6Address; 4 | import java.net.InetSocketAddress; 5 | import lombok.AccessLevel; 6 | import lombok.NoArgsConstructor; 7 | 8 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 9 | public class AddressUtil 10 | { 11 | 12 | public static String sanitizeAddress(InetSocketAddress addr) 13 | { 14 | String string = addr.getHostString(); 15 | 16 | // Remove IPv6 scope if present 17 | if ( addr.getAddress() instanceof Inet6Address ) 18 | { 19 | int strip = string.indexOf( '%' ); 20 | return ( strip == -1 ) ? string : string.substring( 0, strip ); 21 | } else 22 | { 23 | return string; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /module/cmd-find/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-find 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | cmd_find 19 | Provides the find command 20 | 21 | -------------------------------------------------------------------------------- /module/cmd-list/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-list 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | cmd_list 19 | Provides the glist command 20 | 21 | -------------------------------------------------------------------------------- /module/cmd-send/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-send 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | cmd_send 19 | Provides the gsend command 20 | 21 | -------------------------------------------------------------------------------- /event/src/main/java/net/md_5/bungee/event/EventHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.METHOD) 10 | public @interface EventHandler 11 | { 12 | 13 | /** 14 | * Define the priority of the event handler. 15 | *

16 | * Event handlers are called in order of priority: 17 | *

    18 | *
  1. LOWEST
  2. 19 | *
  3. LOW
  4. 20 | *
  5. NORMAL
  6. 21 | *
  7. HIGH
  8. 22 | *
  9. HIGHEST
  10. 23 | *
24 | * 25 | * @return handler priority 26 | */ 27 | byte priority() default EventPriority.NORMAL; 28 | } 29 | -------------------------------------------------------------------------------- /module/cmd-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-server 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | cmd_server 19 | Provides the server command 20 | 21 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/util/CaseInsensitiveHashingStrategy.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import gnu.trove.strategy.HashingStrategy; 4 | import java.util.Locale; 5 | 6 | class CaseInsensitiveHashingStrategy implements HashingStrategy 7 | { 8 | 9 | static final CaseInsensitiveHashingStrategy INSTANCE = new CaseInsensitiveHashingStrategy(); 10 | 11 | @Override 12 | public int computeHashCode(Object object) 13 | { 14 | return ( (String) object ).toLowerCase( Locale.ROOT ).hashCode(); 15 | } 16 | 17 | @Override 18 | public boolean equals(Object o1, Object o2) 19 | { 20 | return o1.equals( o2 ) || ( o1 instanceof String && o2 instanceof String && ( (String) o1 ).toLowerCase( Locale.ROOT ).equals( ( (String) o2 ).toLowerCase( Locale.ROOT ) ) ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /module/cmd-alert/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-alert 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | cmd_alert 19 | Provides the alert and alertraw commands 20 | 21 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/StatusRequest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import net.md_5.bungee.protocol.AbstractPacketHandler; 8 | import net.md_5.bungee.protocol.DefinedPacket; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @EqualsAndHashCode(callSuper = false) 13 | public class StatusRequest extends DefinedPacket 14 | { 15 | 16 | @Override 17 | public void read(ByteBuf buf) 18 | { 19 | } 20 | 21 | @Override 22 | public void write(ByteBuf buf) 23 | { 24 | } 25 | 26 | @Override 27 | public void handle(AbstractPacketHandler handler) throws Exception 28 | { 29 | handler.handle( this ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import net.md_5.bungee.api.ChatColor; 4 | import net.md_5.bungee.api.CommandSender; 5 | import net.md_5.bungee.api.ProxyServer; 6 | import net.md_5.bungee.api.plugin.Command; 7 | 8 | public class CommandBungee extends Command 9 | { 10 | 11 | public CommandBungee() 12 | { 13 | super( "bungee" ); 14 | } 15 | 16 | @Override 17 | public void execute(CommandSender sender, String[] args) 18 | { 19 | sender.sendMessage( ChatColor.BLUE + "This server is running " + ProxyServer.getInstance().getName() + " version " + ProxyServer.getInstance().getVersion() + " by md_5" ); 20 | sender.sendMessage( ChatColor.BLUE + "Protocol support for 1.7.x by Zartec, ghac and I9hdkill" ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ServerSwitchEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.config.ServerInfo; 7 | import net.md_5.bungee.api.connection.ProxiedPlayer; 8 | import net.md_5.bungee.api.plugin.Event; 9 | 10 | /** 11 | * Called when a player has changed servers. 12 | */ 13 | @Data 14 | @ToString(callSuper = false) 15 | @EqualsAndHashCode(callSuper = false) 16 | public class ServerSwitchEvent extends Event 17 | { 18 | 19 | /** 20 | * Player whom the server is for. 21 | */ 22 | private final ProxiedPlayer player; 23 | /** 24 | * Server the player is switch from. May be null if initial proxy 25 | * connection. 26 | */ 27 | private final ServerInfo from; 28 | } 29 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/netty/cipher/CipherEncoder.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.netty.cipher; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | import lombok.RequiredArgsConstructor; 7 | import net.md_5.bungee.jni.cipher.BungeeCipher; 8 | 9 | @RequiredArgsConstructor 10 | public class CipherEncoder extends MessageToByteEncoder 11 | { 12 | 13 | private final BungeeCipher cipher; 14 | 15 | @Override 16 | protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception 17 | { 18 | cipher.cipher( in, out ); 19 | } 20 | 21 | @Override 22 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception 23 | { 24 | cipher.free(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /event/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-event 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Event 19 | Generic java event dispatching API intended for use with BungeeCord 20 | 21 | -------------------------------------------------------------------------------- /config/src/test/java/net/md_5/bungee/config/DefaultConfigurationTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.config; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class DefaultConfigurationTest 7 | { 8 | 9 | @Test 10 | public void testDefaultValues() 11 | { 12 | Configuration defaultConfig = new Configuration(); 13 | defaultConfig.set( "setting", 10 ); 14 | defaultConfig.set( "nested.setting", 11 ); 15 | defaultConfig.set( "double.nested.setting", 12 ); 16 | 17 | Configuration actualConfig = new Configuration( defaultConfig ); 18 | 19 | Assert.assertEquals( 10, actualConfig.getInt( "setting" ) ); 20 | Assert.assertEquals( 11, actualConfig.getInt( "nested.setting" ) ); 21 | Assert.assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /module/reconnect-yaml/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-reconnect-yaml 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | reconnect_yaml 19 | Provides reconnect location functionality in locations.yml 20 | 21 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ServerDisconnectEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NonNull; 7 | import lombok.ToString; 8 | import net.md_5.bungee.api.config.ServerInfo; 9 | import net.md_5.bungee.api.connection.ProxiedPlayer; 10 | import net.md_5.bungee.api.plugin.Event; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @ToString(callSuper = false) 15 | @EqualsAndHashCode(callSuper = false) 16 | public class ServerDisconnectEvent extends Event 17 | { 18 | 19 | /** 20 | * Player disconnecting from a server. 21 | */ 22 | @NonNull 23 | private final ProxiedPlayer player; 24 | /** 25 | * Server the player is disconnecting from. 26 | */ 27 | @NonNull 28 | private final ServerInfo target; 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/scheduler/GroupedThreadFactory.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.scheduler; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import lombok.Data; 5 | import net.md_5.bungee.api.plugin.Plugin; 6 | 7 | @Data 8 | @Deprecated 9 | public class GroupedThreadFactory implements ThreadFactory 10 | { 11 | 12 | private final ThreadGroup group; 13 | 14 | public static final class BungeeGroup extends ThreadGroup 15 | { 16 | 17 | private BungeeGroup(String name) 18 | { 19 | super( name ); 20 | } 21 | 22 | } 23 | 24 | public GroupedThreadFactory(Plugin plugin, String name) 25 | { 26 | this.group = new BungeeGroup( name ); 27 | } 28 | 29 | @Override 30 | public Thread newThread(Runnable r) 31 | { 32 | return new Thread( group, r ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/netty/cipher/CipherDecoder.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.netty.cipher; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToMessageDecoder; 6 | import java.util.List; 7 | import lombok.RequiredArgsConstructor; 8 | import net.md_5.bungee.jni.cipher.BungeeCipher; 9 | 10 | @RequiredArgsConstructor 11 | public class CipherDecoder extends MessageToMessageDecoder 12 | { 13 | 14 | private final BungeeCipher cipher; 15 | 16 | @Override 17 | protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception 18 | { 19 | out.add( cipher.cipher( ctx, msg ) ); 20 | } 21 | 22 | @Override 23 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception 24 | { 25 | cipher.free(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api/src/test/java/net/md_5/bungee/util/UUIDTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import java.util.UUID; 4 | import net.md_5.bungee.Util; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | public class UUIDTest 9 | { 10 | 11 | @Test 12 | public void testSingle() 13 | { 14 | UUID uuid = UUID.fromString( "af74a02d-19cb-445b-b07f-6866a861f783" ); 15 | UUID uuid1 = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" ); 16 | Assert.assertEquals( uuid, uuid1 ); 17 | } 18 | 19 | @Test 20 | public void testMany() 21 | { 22 | for ( int i = 0; i < 1000; i++ ) 23 | { 24 | UUID expected = UUID.randomUUID(); 25 | UUID actual = Util.getUUID( expected.toString().replace( "-", "" ) ); 26 | Assert.assertEquals( "Could not parse UUID " + expected, expected, actual ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/MinecraftInput.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | @RequiredArgsConstructor 7 | public class MinecraftInput 8 | { 9 | 10 | private final ByteBuf buf; 11 | 12 | public byte readByte() 13 | { 14 | return buf.readByte(); 15 | } 16 | 17 | public short readUnsignedByte() 18 | { 19 | return buf.readUnsignedByte(); 20 | } 21 | 22 | public int readInt() 23 | { 24 | return buf.readInt(); 25 | } 26 | 27 | public String readString() 28 | { 29 | short len = buf.readShort(); 30 | char[] c = new char[ len ]; 31 | for ( int i = 0; i < c.length; i++ ) 32 | { 33 | c[i] = buf.readChar(); 34 | } 35 | 36 | return new String( c ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/SettingsChangedEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.connection.ProxiedPlayer; 7 | import net.md_5.bungee.api.plugin.Event; 8 | 9 | /** 10 | * Called after a {@link ProxiedPlayer} changed one or more of the following 11 | * (client-side) settings: 12 | * 13 | *
    14 | *
  • View distance
  • 15 | *
  • Locale
  • 16 | *
  • Displayed skin parts
  • 17 | *
  • Chat visibility
  • 18 | *
  • Chat colors
  • 19 | *
  • Main hand side (left or right)
  • 20 | *
21 | */ 22 | @Data 23 | @ToString(callSuper = false) 24 | @EqualsAndHashCode(callSuper = false) 25 | public class SettingsChangedEvent extends Event 26 | { 27 | 28 | /** 29 | * Player who changed the settings. 30 | */ 31 | private final ProxiedPlayer player; 32 | } 33 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/scheduler/ScheduledTask.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.scheduler; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | /** 6 | * Represents a task scheduled for execution by the {@link TaskScheduler}. 7 | */ 8 | public interface ScheduledTask 9 | { 10 | 11 | /** 12 | * Gets the unique ID of this task. 13 | * 14 | * @return this tasks ID 15 | */ 16 | int getId(); 17 | 18 | /** 19 | * Return the plugin which scheduled this task for execution. 20 | * 21 | * @return the owning plugin 22 | */ 23 | Plugin getOwner(); 24 | 25 | /** 26 | * Get the actual method which will be executed by this task. 27 | * 28 | * @return the {@link Runnable} behind this task 29 | */ 30 | Runnable getTask(); 31 | 32 | /** 33 | * Cancel this task to suppress subsequent executions. 34 | */ 35 | void cancel(); 36 | } 37 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.netty; 2 | 3 | import net.md_5.bungee.protocol.PacketWrapper; 4 | 5 | public abstract class PacketHandler extends net.md_5.bungee.protocol.AbstractPacketHandler 6 | { 7 | 8 | @Override 9 | public abstract String toString(); 10 | 11 | public boolean shouldHandle(PacketWrapper packet) throws Exception 12 | { 13 | return true; 14 | } 15 | 16 | public void exception(Throwable t) throws Exception 17 | { 18 | } 19 | 20 | public void handle(PacketWrapper packet) throws Exception 21 | { 22 | } 23 | 24 | public void connected(ChannelWrapper channel) throws Exception 25 | { 26 | } 27 | 28 | public void disconnected(ChannelWrapper channel) throws Exception 29 | { 30 | } 31 | 32 | public void writabilityChanged(ChannelWrapper channel) throws Exception 33 | { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/hover/content/Item.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat.hover.content; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.ToString; 7 | import net.md_5.bungee.api.chat.HoverEvent; 8 | import net.md_5.bungee.api.chat.ItemTag; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @ToString 13 | @EqualsAndHashCode(callSuper = false) 14 | public class Item extends Content 15 | { 16 | 17 | /** 18 | * Namespaced item ID. Will use 'minecraft:air' if null. 19 | */ 20 | private String id; 21 | /** 22 | * Optional. Size of the item stack. 23 | */ 24 | private int count = -1; 25 | /** 26 | * Optional. Item tag. 27 | */ 28 | private ItemTag tag; 29 | 30 | @Override 31 | public HoverEvent.Action requiredAction() 32 | { 33 | return HoverEvent.Action.SHOW_ITEM; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Setter; 8 | 9 | @AllArgsConstructor 10 | public class MinecraftEncoder extends MessageToByteEncoder 11 | { 12 | 13 | @Setter 14 | private Protocol protocol; 15 | private boolean server; 16 | @Setter 17 | private int protocolVersion; 18 | 19 | @Override 20 | protected void encode(ChannelHandlerContext ctx, DefinedPacket msg, ByteBuf out) throws Exception 21 | { 22 | Protocol.DirectionData prot = ( server ) ? protocol.TO_CLIENT : protocol.TO_SERVER; 23 | DefinedPacket.writeVarInt( prot.getId( msg.getClass(), protocolVersion ), out ); 24 | msg.write( out, prot.getDirection(), protocolVersion ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/command/CommandEnd.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import com.google.common.base.Joiner; 4 | import net.md_5.bungee.BungeeCord; 5 | import net.md_5.bungee.api.ChatColor; 6 | import net.md_5.bungee.api.CommandSender; 7 | import net.md_5.bungee.api.plugin.Command; 8 | 9 | /** 10 | * Command to terminate the proxy instance. May only be used by the console by 11 | * default. 12 | */ 13 | public class CommandEnd extends Command 14 | { 15 | 16 | public CommandEnd() 17 | { 18 | super( "end", "bungeecord.command.end" ); 19 | } 20 | 21 | @Override 22 | public void execute(CommandSender sender, String[] args) 23 | { 24 | if ( args.length == 0 ) 25 | { 26 | BungeeCord.getInstance().stop(); 27 | } else 28 | { 29 | BungeeCord.getInstance().stop( ChatColor.translateAlternateColorCodes( '&', Joiner.on( ' ' ).join( args ) ) ); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/LegacyHandshake.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import net.md_5.bungee.protocol.AbstractPacketHandler; 8 | import net.md_5.bungee.protocol.DefinedPacket; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @EqualsAndHashCode(callSuper = false) 13 | public class LegacyHandshake extends DefinedPacket 14 | { 15 | 16 | @Override 17 | public void read(ByteBuf buf) 18 | { 19 | throw new UnsupportedOperationException( "Not supported yet." ); 20 | } 21 | 22 | @Override 23 | public void write(ByteBuf buf) 24 | { 25 | throw new UnsupportedOperationException( "Not supported yet." ); 26 | } 27 | 28 | @Override 29 | public void handle(AbstractPacketHandler handler) throws Exception 30 | { 31 | handler.handle( this ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/PingPacket.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class PingPacket extends DefinedPacket 16 | { 17 | 18 | private long time; 19 | 20 | @Override 21 | public void read(ByteBuf buf) 22 | { 23 | time = buf.readLong(); 24 | } 25 | 26 | @Override 27 | public void write(ByteBuf buf) 28 | { 29 | buf.writeLong( time ); 30 | } 31 | 32 | @Override 33 | public void handle(AbstractPacketHandler handler) throws Exception 34 | { 35 | handler.handle( this ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/Kick.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class Kick extends DefinedPacket 16 | { 17 | 18 | private String message; 19 | 20 | @Override 21 | public void read(ByteBuf buf) 22 | { 23 | message = readString( buf ); 24 | } 25 | 26 | @Override 27 | public void write(ByteBuf buf) 28 | { 29 | writeString( message, buf ); 30 | } 31 | 32 | @Override 33 | public void handle(AbstractPacketHandler handler) throws Exception 34 | { 35 | handler.handle( this ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientStatus.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class ClientStatus extends DefinedPacket 16 | { 17 | 18 | private byte payload; 19 | 20 | @Override 21 | public void read(ByteBuf buf) 22 | { 23 | payload = buf.readByte(); 24 | } 25 | 26 | @Override 27 | public void write(ByteBuf buf) 28 | { 29 | buf.writeByte( payload ); 30 | } 31 | 32 | @Override 33 | public void handle(AbstractPacketHandler handler) throws Exception 34 | { 35 | handler.handle( this ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/score/Team.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.score; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import lombok.Data; 8 | import lombok.NonNull; 9 | 10 | @Data 11 | public class Team 12 | { 13 | 14 | @NonNull 15 | private final String name; 16 | private String displayName; 17 | private String prefix; 18 | private String suffix; 19 | private byte friendlyFire; 20 | private String nameTagVisibility; 21 | private String collisionRule; 22 | private int color; 23 | private Set players = new HashSet<>(); 24 | 25 | public Collection getPlayers() 26 | { 27 | return Collections.unmodifiableSet( players ); 28 | } 29 | 30 | public void addPlayer(String name) 31 | { 32 | players.add( name ); 33 | } 34 | 35 | public void removePlayer(String name) 36 | { 37 | players.remove( name ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/hover/content/Content.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat.hover.content; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.ToString; 5 | import net.md_5.bungee.api.chat.HoverEvent; 6 | 7 | @ToString 8 | @EqualsAndHashCode 9 | public abstract class Content 10 | { 11 | 12 | /** 13 | * Required action for this content type. 14 | * 15 | * @return action 16 | */ 17 | public abstract HoverEvent.Action requiredAction(); 18 | 19 | /** 20 | * Tests this content against an action 21 | * 22 | * @param input input to test 23 | * @throws UnsupportedOperationException if action incompatible 24 | */ 25 | public void assertAction(HoverEvent.Action input) throws UnsupportedOperationException 26 | { 27 | if ( input != requiredAction() ) 28 | { 29 | throw new UnsupportedOperationException( "Action " + input + " not compatible! Expected " + requiredAction() ); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/StatusResponse.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class StatusResponse extends DefinedPacket 16 | { 17 | 18 | private String response; 19 | 20 | @Override 21 | public void read(ByteBuf buf) 22 | { 23 | response = readString( buf ); 24 | } 25 | 26 | @Override 27 | public void write(ByteBuf buf) 28 | { 29 | writeString( response, buf ); 30 | } 31 | 32 | @Override 33 | public void handle(AbstractPacketHandler handler) throws Exception 34 | { 35 | handler.handle( this ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/connection/Server.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.connection; 2 | 3 | import net.md_5.bungee.api.config.ServerInfo; 4 | 5 | /** 6 | * Represents a destination which this proxy might connect to. 7 | */ 8 | public interface Server extends Connection 9 | { 10 | 11 | /** 12 | * Returns the basic information about this server. 13 | * 14 | * @return the {@link ServerInfo} for this server 15 | */ 16 | public ServerInfo getInfo(); 17 | 18 | /** 19 | * Send data by any available means to this server. 20 | * 21 | * In recent Minecraft versions channel names must contain a colon separator 22 | * and consist of [a-z0-9/._-]. This will be enforced in a future version. 23 | * The "BungeeCord" channel is an exception and may only take this form. 24 | * 25 | * @param channel the channel to send this data via 26 | * @param data the data to send 27 | */ 28 | public abstract void sendData(String channel, byte[] data); 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ServerConnectedEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.connection.ProxiedPlayer; 7 | import net.md_5.bungee.api.connection.Server; 8 | import net.md_5.bungee.api.plugin.Event; 9 | 10 | /** 11 | * Not to be confused with {@link ServerConnectEvent}, this event is called once 12 | * a connection to a server is fully operational, and is about to hand over 13 | * control of the session to the player. It is useful if you wish to send 14 | * information to the server before the player logs in. 15 | */ 16 | @Data 17 | @ToString(callSuper = false) 18 | @EqualsAndHashCode(callSuper = false) 19 | public class ServerConnectedEvent extends Event 20 | { 21 | 22 | /** 23 | * Player whom the server is for. 24 | */ 25 | private final ProxiedPlayer player; 26 | /** 27 | * The server itself. 28 | */ 29 | private final Server server; 30 | } 31 | -------------------------------------------------------------------------------- /log/src/main/java/net/md_5/bungee/log/LoggingOutputStream.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.log; 2 | 3 | import com.google.common.base.Charsets; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | import lombok.RequiredArgsConstructor; 9 | 10 | @RequiredArgsConstructor 11 | public class LoggingOutputStream extends ByteArrayOutputStream 12 | { 13 | 14 | private static final String separator = System.getProperty( "line.separator" ); 15 | /*========================================================================*/ 16 | private final Logger logger; 17 | private final Level level; 18 | 19 | @Override 20 | public void flush() throws IOException 21 | { 22 | String contents = toString( Charsets.UTF_8.name() ); 23 | super.reset(); 24 | if ( !contents.isEmpty() && !contents.equals( separator ) ) 25 | { 26 | logger.logp( level, "", "", contents ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/PlayerHandshakeEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.connection.PendingConnection; 7 | import net.md_5.bungee.api.plugin.Event; 8 | import net.md_5.bungee.protocol.packet.Handshake; 9 | 10 | /** 11 | * Event called to represent a player first making their presence and username 12 | * known. 13 | */ 14 | @Data 15 | @ToString(callSuper = false) 16 | @EqualsAndHashCode(callSuper = false) 17 | public class PlayerHandshakeEvent extends Event 18 | { 19 | 20 | /** 21 | * Connection attempting to login. 22 | */ 23 | private final PendingConnection connection; 24 | /** 25 | * The handshake. 26 | */ 27 | private final Handshake handshake; 28 | 29 | public PlayerHandshakeEvent(PendingConnection connection, Handshake handshake) 30 | { 31 | this.connection = connection; 32 | this.handshake = handshake; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ViewDistance.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class ViewDistance extends DefinedPacket 16 | { 17 | 18 | private int distance; 19 | 20 | @Override 21 | public void read(ByteBuf buf) 22 | { 23 | distance = DefinedPacket.readVarInt( buf ); 24 | } 25 | 26 | @Override 27 | public void write(ByteBuf buf) 28 | { 29 | DefinedPacket.writeVarInt( distance, buf ); 30 | } 31 | 32 | @Override 33 | public void handle(AbstractPacketHandler handler) throws Exception 34 | { 35 | handler.handle( this ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /query/src/main/java/net/md_5/bungee/query/RemoteQuery.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.query; 2 | 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.Channel; 5 | import io.netty.channel.ChannelFutureListener; 6 | import io.netty.channel.EventLoopGroup; 7 | import java.net.InetSocketAddress; 8 | import lombok.RequiredArgsConstructor; 9 | import net.md_5.bungee.api.ProxyServer; 10 | import net.md_5.bungee.api.config.ListenerInfo; 11 | 12 | @RequiredArgsConstructor 13 | public class RemoteQuery 14 | { 15 | 16 | private final ProxyServer bungee; 17 | private final ListenerInfo listener; 18 | 19 | public void start(Class channel, InetSocketAddress address, EventLoopGroup eventLoop, ChannelFutureListener future) 20 | { 21 | new Bootstrap() 22 | .channel( channel ) 23 | .group( eventLoop ) 24 | .handler( new QueryHandler( bungee, listener ) ) 25 | .localAddress( address ) 26 | .bind().addListener( future ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ProxyPingEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.Callback; 7 | import net.md_5.bungee.api.ServerPing; 8 | import net.md_5.bungee.api.connection.PendingConnection; 9 | 10 | /** 11 | * Called when the proxy is pinged with packet 0xFE from the server list. 12 | */ 13 | @Data 14 | @ToString(callSuper = false) 15 | @EqualsAndHashCode(callSuper = false) 16 | public class ProxyPingEvent extends AsyncEvent 17 | { 18 | 19 | /** 20 | * The connection asking for a ping response. 21 | */ 22 | private final PendingConnection connection; 23 | /** 24 | * The data to respond with. 25 | */ 26 | private ServerPing response; 27 | 28 | public ProxyPingEvent(PendingConnection connection, ServerPing response, Callback done) 29 | { 30 | super( done ); 31 | this.connection = connection; 32 | this.response = response; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/forge/IForgeClientPacketHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.forge; 2 | 3 | import net.md_5.bungee.UserConnection; 4 | import net.md_5.bungee.protocol.packet.PluginMessage; 5 | 6 | /** 7 | * An interface that defines a Forge Handshake Client packet. 8 | * 9 | * @param The State to transition to. 10 | */ 11 | public interface IForgeClientPacketHandler 12 | { 13 | 14 | /** 15 | * Handles any {@link PluginMessage} packets. 16 | * 17 | * @param message The {@link PluginMessage} to handle. 18 | * @param con The {@link UserConnection} to send packets to. 19 | * @return The state to transition to. 20 | */ 21 | public S handle(PluginMessage message, UserConnection con); 22 | 23 | /** 24 | * Sends any {@link PluginMessage} packets. 25 | * 26 | * @param message The {@link PluginMessage} to send. 27 | * @param con The {@link UserConnection} to set data. 28 | * @return The state to transition to. 29 | */ 30 | public S send(PluginMessage message, UserConnection con); 31 | } 32 | -------------------------------------------------------------------------------- /event/src/test/java/net/md_5/bungee/event/EventBusTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class EventBusTest 8 | { 9 | 10 | private final EventBus bus = new EventBus(); 11 | private final CountDownLatch latch = new CountDownLatch( 2 ); 12 | 13 | @Test 14 | public void testNestedEvents() 15 | { 16 | bus.register( this ); 17 | bus.post( new FirstEvent() ); 18 | Assert.assertEquals( 0, latch.getCount() ); 19 | } 20 | 21 | @EventHandler 22 | public void firstListener(FirstEvent event) 23 | { 24 | bus.post( new SecondEvent() ); 25 | Assert.assertEquals( 1, latch.getCount() ); 26 | latch.countDown(); 27 | } 28 | 29 | @EventHandler 30 | public void secondListener(SecondEvent event) 31 | { 32 | latch.countDown(); 33 | } 34 | 35 | public static class FirstEvent 36 | { 37 | } 38 | 39 | public static class SecondEvent 40 | { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ClientConnectEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import java.net.SocketAddress; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.ToString; 7 | import net.md_5.bungee.api.config.ListenerInfo; 8 | import net.md_5.bungee.api.plugin.Cancellable; 9 | import net.md_5.bungee.api.plugin.Event; 10 | 11 | /** 12 | * Event called to represent an initial client connection. 13 | *
14 | * Note: This event is called at an early stage of every connection, handling 15 | * should be fast. 16 | */ 17 | @Data 18 | @ToString(callSuper = false) 19 | @EqualsAndHashCode(callSuper = false) 20 | public class ClientConnectEvent extends Event implements Cancellable 21 | { 22 | 23 | /** 24 | * Cancelled state. 25 | */ 26 | private boolean cancelled; 27 | /** 28 | * Remote address of connection. 29 | */ 30 | private final SocketAddress socketAddress; 31 | /** 32 | * Listener that accepted the connection. 33 | */ 34 | private final ListenerInfo listener; 35 | } 36 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/Subtitle.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import net.md_5.bungee.protocol.AbstractPacketHandler; 8 | import net.md_5.bungee.protocol.DefinedPacket; 9 | import net.md_5.bungee.protocol.ProtocolConstants; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @EqualsAndHashCode(callSuper = false) 14 | public class Subtitle extends DefinedPacket 15 | { 16 | 17 | private String text; 18 | 19 | @Override 20 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 21 | { 22 | text = readString( buf ); 23 | } 24 | 25 | @Override 26 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 27 | { 28 | writeString( text, buf ); 29 | } 30 | 31 | @Override 32 | public void handle(AbstractPacketHandler handler) throws Exception 33 | { 34 | handler.handle( this ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/command/CommandIP.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import net.md_5.bungee.api.CommandSender; 4 | import net.md_5.bungee.api.ProxyServer; 5 | import net.md_5.bungee.api.connection.ProxiedPlayer; 6 | 7 | public class CommandIP extends PlayerCommand 8 | { 9 | 10 | public CommandIP() 11 | { 12 | super( "ip", "bungeecord.command.ip" ); 13 | } 14 | 15 | @Override 16 | public void execute(CommandSender sender, String[] args) 17 | { 18 | if ( args.length < 1 ) 19 | { 20 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "username_needed" ) ); 21 | return; 22 | } 23 | ProxiedPlayer user = ProxyServer.getInstance().getPlayer( args[0] ); 24 | if ( user == null ) 25 | { 26 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) ); 27 | } else 28 | { 29 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_ip", args[0], user.getSocketAddress() ) ); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /chat/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-chat 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Chat 19 | Minecraft JSON chat API intended for use with BungeeCord 20 | 21 | 22 | 23 | com.google.code.gson 24 | gson 25 | 2.8.8 26 | compile 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.connection.Connection; 7 | import net.md_5.bungee.api.plugin.Cancellable; 8 | 9 | /** 10 | * Event called when a plugin message is sent to the client or server. 11 | */ 12 | @Data 13 | @ToString(callSuper = true, exclude = "data") 14 | @EqualsAndHashCode(callSuper = true) 15 | public class PluginMessageEvent extends TargetedEvent implements Cancellable 16 | { 17 | 18 | /** 19 | * Cancelled state. 20 | */ 21 | private boolean cancelled; 22 | /** 23 | * Tag specified for this plugin message. 24 | */ 25 | private final String tag; 26 | /** 27 | * Data contained in this plugin message. 28 | */ 29 | private final byte[] data; 30 | 31 | public PluginMessageEvent(Connection sender, Connection receiver, String tag, byte[] data) 32 | { 33 | super( sender, receiver ); 34 | this.tag = tag; 35 | this.data = data; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/PermissionCheckEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.Getter; 8 | import lombok.ToString; 9 | import net.md_5.bungee.api.CommandSender; 10 | import net.md_5.bungee.api.plugin.Event; 11 | 12 | /** 13 | * Called when the permission of a CommandSender is checked. 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @ToString(callSuper = false) 18 | @EqualsAndHashCode(callSuper = false) 19 | public class PermissionCheckEvent extends Event 20 | { 21 | 22 | /** 23 | * The command sender being checked for a permission. 24 | */ 25 | private final CommandSender sender; 26 | /** 27 | * The permission to check. 28 | */ 29 | private final String permission; 30 | /** 31 | * The outcome of this permission check. 32 | */ 33 | @Getter(AccessLevel.NONE) 34 | private boolean hasPermission; 35 | 36 | public boolean hasPermission() 37 | { 38 | return hasPermission; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/module/ModuleVersion.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Data; 5 | import lombok.RequiredArgsConstructor; 6 | 7 | @Data 8 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE) 9 | public class ModuleVersion 10 | { 11 | 12 | private final String build; 13 | private final String git; 14 | 15 | public static ModuleVersion parse(String version) 16 | { 17 | int lastColon = version.lastIndexOf( ':' ); 18 | int secondLastColon = version.lastIndexOf( ':', lastColon - 1 ); 19 | 20 | if ( lastColon == -1 || secondLastColon == -1 ) 21 | { 22 | return null; 23 | } 24 | 25 | String buildNumber = version.substring( lastColon + 1, version.length() ); 26 | String gitCommit = version.substring( secondLastColon + 1, lastColon ).replaceAll( "\"", "" ); 27 | 28 | if ( "unknown".equals( buildNumber ) || "unknown".equals( gitCommit ) ) 29 | { 30 | return null; 31 | } 32 | 33 | return new ModuleVersion( buildNumber, gitCommit ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /native/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-native 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Native 19 | Optional native code to speed up and enhance BungeeCord functionality. 20 | 21 | 22 | 23 | io.netty 24 | netty-transport 25 | ${netty.version} 26 | compile 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/LegacyPing.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.RequiredArgsConstructor; 7 | import net.md_5.bungee.protocol.AbstractPacketHandler; 8 | import net.md_5.bungee.protocol.DefinedPacket; 9 | 10 | @Data 11 | @RequiredArgsConstructor 12 | @EqualsAndHashCode(callSuper = false) 13 | public class LegacyPing extends DefinedPacket 14 | { 15 | 16 | private final boolean v1_5; 17 | 18 | @Override 19 | public void read(ByteBuf buf) 20 | { 21 | throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. 22 | } 23 | 24 | @Override 25 | public void write(ByteBuf buf) 26 | { 27 | throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. 28 | } 29 | 30 | @Override 31 | public void handle(AbstractPacketHandler handler) throws Exception 32 | { 33 | handler.handle( this ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/GameState.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class GameState extends DefinedPacket 16 | { 17 | 18 | public static final short IMMEDIATE_RESPAWN = 11; 19 | // 20 | private short state; 21 | private float value; 22 | 23 | @Override 24 | public void read(ByteBuf buf) 25 | { 26 | state = buf.readUnsignedByte(); 27 | value = buf.readFloat(); 28 | } 29 | 30 | @Override 31 | public void write(ByteBuf buf) 32 | { 33 | buf.writeByte( state ); 34 | buf.writeFloat( value ); 35 | } 36 | 37 | @Override 38 | public void handle(AbstractPacketHandler handler) throws Exception 39 | { 40 | handler.handle( this ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/command/CommandPerms.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import net.md_5.bungee.Util; 6 | import net.md_5.bungee.api.CommandSender; 7 | import net.md_5.bungee.api.ProxyServer; 8 | import net.md_5.bungee.api.plugin.Command; 9 | 10 | public class CommandPerms extends Command 11 | { 12 | 13 | public CommandPerms() 14 | { 15 | super( "perms" ); 16 | } 17 | 18 | @Override 19 | public void execute(CommandSender sender, String[] args) 20 | { 21 | Set permissions = new HashSet<>(); 22 | for ( String group : sender.getGroups() ) 23 | { 24 | permissions.addAll( ProxyServer.getInstance().getConfigurationAdapter().getPermissions( group ) ); 25 | } 26 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_perms_groups", Util.csv( sender.getGroups() ) ) ); 27 | 28 | for ( String permission : permissions ) 29 | { 30 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_perms_permission", permission ) ); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/hover/content/Entity.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat.hover.content; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NonNull; 7 | import lombok.ToString; 8 | import net.md_5.bungee.api.chat.BaseComponent; 9 | import net.md_5.bungee.api.chat.HoverEvent; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @ToString 14 | @EqualsAndHashCode(callSuper = true) 15 | public class Entity extends Content 16 | { 17 | 18 | /** 19 | * Namespaced entity ID. 20 | * 21 | * Will use 'minecraft:pig' if null. 22 | */ 23 | private String type; 24 | /** 25 | * Entity UUID in hyphenated hexadecimal format. 26 | * 27 | * Should be valid UUID. TODO : validate? 28 | */ 29 | @NonNull 30 | private String id; 31 | /** 32 | * Name to display as the entity. 33 | * 34 | * This is optional and will be hidden if null. 35 | */ 36 | private BaseComponent name; 37 | 38 | @Override 39 | public HoverEvent.Action requiredAction() 40 | { 41 | return HoverEvent.Action.SHOW_ENTITY; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ClearTitles.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class ClearTitles extends DefinedPacket 17 | { 18 | 19 | private boolean reset; 20 | 21 | @Override 22 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | reset = buf.readBoolean(); 25 | } 26 | 27 | @Override 28 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 29 | { 30 | buf.writeBoolean( reset ); 31 | } 32 | 33 | @Override 34 | public void handle(AbstractPacketHandler handler) throws Exception 35 | { 36 | handler.handle( this ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardDisplay.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class ScoreboardDisplay extends DefinedPacket 16 | { 17 | 18 | /** 19 | * 0 = list, 1 = side, 2 = below. 20 | */ 21 | private byte position; 22 | private String name; 23 | 24 | @Override 25 | public void read(ByteBuf buf) 26 | { 27 | position = buf.readByte(); 28 | name = readString( buf ); 29 | } 30 | 31 | @Override 32 | public void write(ByteBuf buf) 33 | { 34 | buf.writeByte( position ); 35 | writeString( name, buf ); 36 | } 37 | 38 | @Override 39 | public void handle(AbstractPacketHandler handler) throws Exception 40 | { 41 | handler.handle( this ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/command/CommandReload.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import net.md_5.bungee.BungeeCord; 4 | import net.md_5.bungee.api.ChatColor; 5 | import net.md_5.bungee.api.CommandSender; 6 | import net.md_5.bungee.api.event.ProxyReloadEvent; 7 | import net.md_5.bungee.api.plugin.Command; 8 | 9 | public class CommandReload extends Command 10 | { 11 | 12 | public CommandReload() 13 | { 14 | super( "greload", "bungeecord.command.reload" ); 15 | } 16 | 17 | @Override 18 | public void execute(CommandSender sender, String[] args) 19 | { 20 | BungeeCord.getInstance().config.load(); 21 | BungeeCord.getInstance().reloadMessages(); 22 | BungeeCord.getInstance().stopListeners(); 23 | BungeeCord.getInstance().startListeners(); 24 | BungeeCord.getInstance().getPluginManager().callEvent( new ProxyReloadEvent( sender ) ); 25 | 26 | sender.sendMessage( ChatColor.BOLD.toString() + ChatColor.RED.toString() + "BungeeCord has been reloaded." 27 | + " This is NOT advisable and you will not be supported with any issues that arise! Please restart BungeeCord ASAP." ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /api/src/test/java/net/md_5/bungee/util/CaseInsensitiveTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class CaseInsensitiveTest 7 | { 8 | 9 | @Test 10 | public void testMaps() 11 | { 12 | Object obj = new Object(); 13 | CaseInsensitiveMap map = new CaseInsensitiveMap<>(); 14 | 15 | map.put( "FOO", obj ); 16 | Assert.assertTrue( map.contains( "foo" ) ); // Assert that contains is case insensitive 17 | Assert.assertTrue( map.entrySet().iterator().next().getKey().equals( "FOO" ) ); // Assert that case is preserved 18 | 19 | // Assert that remove is case insensitive 20 | map.remove( "FoO" ); 21 | Assert.assertFalse( map.contains( "foo" ) ); 22 | } 23 | 24 | @Test 25 | public void testSets() 26 | { 27 | CaseInsensitiveSet set = new CaseInsensitiveSet(); 28 | 29 | set.add( "FOO" ); 30 | Assert.assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive 31 | set.remove( "FoO" ); 32 | Assert.assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/SetCompression.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class SetCompression extends DefinedPacket 17 | { 18 | 19 | private int threshold; 20 | 21 | @Override 22 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | threshold = DefinedPacket.readVarInt( buf ); 25 | } 26 | 27 | @Override 28 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 29 | { 30 | DefinedPacket.writeVarInt( threshold, buf ); 31 | } 32 | 33 | @Override 34 | public void handle(AbstractPacketHandler handler) throws Exception 35 | { 36 | handler.handle( this ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /native/src/main/c/net_md_5_bungee_jni_cipher_NativeCipherImpl.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class net_md_5_bungee_jni_cipher_NativeCipherImpl */ 4 | 5 | #ifndef _Included_net_md_5_bungee_jni_cipher_NativeCipherImpl 6 | #define _Included_net_md_5_bungee_jni_cipher_NativeCipherImpl 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: net_md_5_bungee_jni_cipher_NativeCipherImpl 12 | * Method: init 13 | * Signature: (Z[B)J 14 | */ 15 | JNIEXPORT jlong JNICALL Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_init 16 | (JNIEnv *, jobject, jboolean, jbyteArray); 17 | 18 | /* 19 | * Class: net_md_5_bungee_jni_cipher_NativeCipherImpl 20 | * Method: free 21 | * Signature: (J)V 22 | */ 23 | JNIEXPORT void JNICALL Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_free 24 | (JNIEnv *, jobject, jlong); 25 | 26 | /* 27 | * Class: net_md_5_bungee_jni_cipher_NativeCipherImpl 28 | * Method: cipher 29 | * Signature: (JJJI)V 30 | */ 31 | JNIEXPORT void JNICALL Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_cipher 32 | (JNIEnv *, jobject, jlong, jlong, jlong, jint); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | #endif 38 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityStatus.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class EntityStatus extends DefinedPacket 16 | { 17 | 18 | public static final byte DEBUG_INFO_REDUCED = 22; 19 | public static final byte DEBUG_INFO_NORMAL = 23; 20 | // 21 | private int entityId; 22 | private byte status; 23 | 24 | @Override 25 | public void read(ByteBuf buf) 26 | { 27 | entityId = buf.readInt(); 28 | status = buf.readByte(); 29 | } 30 | 31 | @Override 32 | public void write(ByteBuf buf) 33 | { 34 | buf.writeInt( entityId ); 35 | buf.writeByte( status ); 36 | } 37 | 38 | @Override 39 | public void handle(AbstractPacketHandler handler) throws Exception 40 | { 41 | handler.handle( this ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/TabCompleteEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import java.util.List; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.ToString; 7 | import net.md_5.bungee.api.connection.Connection; 8 | import net.md_5.bungee.api.plugin.Cancellable; 9 | 10 | /** 11 | * Event called when a player uses tab completion. 12 | */ 13 | @Data 14 | @ToString(callSuper = true) 15 | @EqualsAndHashCode(callSuper = true) 16 | public class TabCompleteEvent extends TargetedEvent implements Cancellable 17 | { 18 | 19 | /** 20 | * Cancelled state. 21 | */ 22 | private boolean cancelled; 23 | /** 24 | * The message the player has already entered. 25 | */ 26 | private final String cursor; 27 | /** 28 | * The suggestions that will be sent to the client. This list is mutable. If 29 | * this list is empty, the request will be forwarded to the server. 30 | */ 31 | private final List suggestions; 32 | 33 | public TabCompleteEvent(Connection sender, Connection receiver, String cursor, List suggestions) 34 | { 35 | super( sender, receiver ); 36 | this.cursor = cursor; 37 | this.suggestions = suggestions; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/ReconnectHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api; 2 | 3 | import net.md_5.bungee.api.config.ServerInfo; 4 | import net.md_5.bungee.api.connection.ProxiedPlayer; 5 | 6 | public interface ReconnectHandler 7 | { 8 | 9 | /** 10 | * Gets the initial server name for a connecting player. 11 | * 12 | * @param player the connecting player 13 | * @return the server to connect to 14 | */ 15 | ServerInfo getServer(ProxiedPlayer player); 16 | 17 | /** 18 | * Save the server of this player before they disconnect so it can be 19 | * retrieved later. 20 | * 21 | * @param player the player to save 22 | */ 23 | void setServer(ProxiedPlayer player); // TOOD: String + String arguments? 24 | 25 | /** 26 | * Save all pending reconnect locations. Whilst not used for database 27 | * connections, this method will be called at a predefined interval to allow 28 | * the saving of reconnect files. 29 | */ 30 | void save(); 31 | 32 | /** 33 | * Close all connections indicating that the proxy is about to shutdown and 34 | * all data should be saved. No new requests will be made after this method 35 | * has been called. 36 | * 37 | */ 38 | void close(); 39 | } 40 | -------------------------------------------------------------------------------- /log/src/main/java/net/md_5/bungee/log/LogDispatcher.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.log; 2 | 3 | import java.util.concurrent.BlockingQueue; 4 | import java.util.concurrent.LinkedBlockingQueue; 5 | import java.util.logging.LogRecord; 6 | 7 | public class LogDispatcher extends Thread 8 | { 9 | 10 | private final BungeeLogger logger; 11 | private final BlockingQueue queue = new LinkedBlockingQueue<>(); 12 | 13 | public LogDispatcher(BungeeLogger logger) 14 | { 15 | super( "BungeeCord Logger Thread" ); 16 | this.logger = logger; 17 | } 18 | 19 | @Override 20 | public void run() 21 | { 22 | while ( !isInterrupted() ) 23 | { 24 | LogRecord record; 25 | try 26 | { 27 | record = queue.take(); 28 | } catch ( InterruptedException ex ) 29 | { 30 | continue; 31 | } 32 | 33 | logger.doLog( record ); 34 | } 35 | for ( LogRecord record : queue ) 36 | { 37 | logger.doLog( record ); 38 | } 39 | } 40 | 41 | public void queue(LogRecord record) 42 | { 43 | if ( !isInterrupted() ) 44 | { 45 | queue.add( record ); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /module/cmd-find/src/main/java/net/md_5/bungee/module/cmd/find/CommandFind.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.find; 2 | 3 | import net.md_5.bungee.api.CommandSender; 4 | import net.md_5.bungee.api.ProxyServer; 5 | import net.md_5.bungee.api.connection.ProxiedPlayer; 6 | import net.md_5.bungee.command.PlayerCommand; 7 | 8 | public class CommandFind extends PlayerCommand 9 | { 10 | 11 | public CommandFind() 12 | { 13 | super( "find", "bungeecord.command.find" ); 14 | } 15 | 16 | @Override 17 | public void execute(CommandSender sender, String[] args) 18 | { 19 | if ( args.length != 1 ) 20 | { 21 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "username_needed" ) ); 22 | } else 23 | { 24 | ProxiedPlayer player = ProxyServer.getInstance().getPlayer( args[0] ); 25 | if ( player == null || player.getServer() == null ) 26 | { 27 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) ); 28 | } else 29 | { 30 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_online_at", player.getName(), player.getServer().getInfo().getName() ) ); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/SystemChat.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class SystemChat extends DefinedPacket 17 | { 18 | 19 | private String message; 20 | private int position; 21 | 22 | @Override 23 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | message = readString( buf, 262144 ); 26 | position = readVarInt( buf ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeString( message, buf ); 33 | writeVarInt( position, buf ); 34 | } 35 | 36 | @Override 37 | public void handle(AbstractPacketHandler handler) throws Exception 38 | { 39 | handler.handle( this ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/TitleTimes.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import net.md_5.bungee.protocol.AbstractPacketHandler; 8 | import net.md_5.bungee.protocol.DefinedPacket; 9 | import net.md_5.bungee.protocol.ProtocolConstants; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @EqualsAndHashCode(callSuper = false) 14 | public class TitleTimes extends DefinedPacket 15 | { 16 | 17 | private int fadeIn; 18 | private int stay; 19 | private int fadeOut; 20 | 21 | @Override 22 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | fadeIn = buf.readInt(); 25 | stay = buf.readInt(); 26 | fadeOut = buf.readInt(); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | buf.writeInt( fadeIn ); 33 | buf.writeInt( stay ); 34 | buf.writeInt( fadeOut ); 35 | } 36 | 37 | @Override 38 | public void handle(AbstractPacketHandler handler) throws Exception 39 | { 40 | handler.handle( this ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListHeaderFooter.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class PlayerListHeaderFooter extends DefinedPacket 17 | { 18 | 19 | private String header; 20 | private String footer; 21 | 22 | @Override 23 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | header = readString( buf ); 26 | footer = readString( buf ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeString( header, buf ); 33 | writeString( footer, buf ); 34 | } 35 | 36 | @Override 37 | public void handle(AbstractPacketHandler handler) throws Exception 38 | { 39 | handler.handle( this ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /chat/src/test/java/net/md_5/bungee/api/chat/TranslatableComponentTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | import net.md_5.bungee.chat.ComponentSerializer; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class TranslatableComponentTest 8 | { 9 | 10 | @Test 11 | public void testMissingPlaceholdersAdded() 12 | { 13 | TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholders: %s", 2, "aoeu" ); 14 | Assert.assertEquals( "Test string with 2 placeholders: aoeu", testComponent.toPlainText() ); 15 | Assert.assertEquals( "§fTest string with §f2§f placeholders: §faoeu", testComponent.toLegacyText() ); 16 | } 17 | 18 | @Test 19 | public void testJsonSerialisation() 20 | { 21 | TranslatableComponent testComponent = new TranslatableComponent( "Test string with %s placeholder", "a" ); 22 | String jsonString = ComponentSerializer.toString( testComponent ); 23 | BaseComponent[] baseComponents = ComponentSerializer.parse( jsonString ); 24 | 25 | Assert.assertEquals( "Test string with a placeholder", TextComponent.toPlainText( baseComponents ) ); 26 | Assert.assertEquals( "§fTest string with §fa§f placeholder", TextComponent.toLegacyText( baseComponents ) ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-slf4j 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-SLF4J 19 | Wrapper over SLF4J for BungeeCord purposes. 20 | 21 | 22 | true 23 | true 24 | true 25 | 26 | 27 | 28 | 29 | org.slf4j 30 | slf4j-api 31 | 1.7.32 32 | compile 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/forge/IForgeServerPacketHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.forge; 2 | 3 | import net.md_5.bungee.UserConnection; 4 | import net.md_5.bungee.netty.ChannelWrapper; 5 | import net.md_5.bungee.protocol.packet.PluginMessage; 6 | 7 | /** 8 | * An interface that defines a Forge Handshake Server packet. 9 | * 10 | * @param The State to transition to. 11 | */ 12 | public interface IForgeServerPacketHandler 13 | { 14 | 15 | /** 16 | * Handles any {@link net.md_5.bungee.protocol.packet.PluginMessage} 17 | * packets. 18 | * 19 | * @param message The {@link net.md_5.bungee.protocol.packet.PluginMessage} 20 | * to handle. 21 | * @param ch The {@link ChannelWrapper} to send packets to. 22 | * @return The state to transition to. 23 | */ 24 | public S handle(PluginMessage message, ChannelWrapper ch); 25 | 26 | /** 27 | * Sends any {@link net.md_5.bungee.protocol.packet.PluginMessage} packets. 28 | * 29 | * @param message The {@link net.md_5.bungee.protocol.packet.PluginMessage} 30 | * to send. 31 | * @param con The {@link net.md_5.bungee.UserConnection} to send packets to 32 | * or read from. 33 | * @return The state to transition to. 34 | */ 35 | public S send(PluginMessage message, UserConnection con); 36 | } 37 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/TabCompleteResponseEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import java.util.List; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.ToString; 7 | import net.md_5.bungee.api.connection.Connection; 8 | import net.md_5.bungee.api.plugin.Cancellable; 9 | 10 | /** 11 | * Event called when a backend server sends a response to a player asking to 12 | * tab-complete a chat message or command. Note that this is not called when 13 | * BungeeCord or a plugin responds to a tab-complete request. Use 14 | * {@link TabCompleteEvent} for that. 15 | */ 16 | @Data 17 | @ToString(callSuper = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class TabCompleteResponseEvent extends TargetedEvent implements Cancellable 20 | { 21 | 22 | /** 23 | * Whether the event is cancelled. 24 | */ 25 | private boolean cancelled; 26 | 27 | /** 28 | * Mutable list of suggestions sent back to the player. If this list is 29 | * empty, an empty list is sent back to the client. 30 | */ 31 | private final List suggestions; 32 | 33 | public TabCompleteResponseEvent(Connection sender, Connection receiver, List suggestions) 34 | { 35 | super( sender, receiver ); 36 | this.suggestions = suggestions; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/Varint21LengthFieldPrepender.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandler; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.MessageToByteEncoder; 7 | 8 | @ChannelHandler.Sharable 9 | public class Varint21LengthFieldPrepender extends MessageToByteEncoder 10 | { 11 | 12 | @Override 13 | protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception 14 | { 15 | int bodyLen = msg.readableBytes(); 16 | int headerLen = varintSize( bodyLen ); 17 | out.ensureWritable( headerLen + bodyLen ); 18 | 19 | DefinedPacket.writeVarInt( bodyLen, out ); 20 | out.writeBytes( msg ); 21 | } 22 | 23 | private static int varintSize(int paramInt) 24 | { 25 | if ( ( paramInt & 0xFFFFFF80 ) == 0 ) 26 | { 27 | return 1; 28 | } 29 | if ( ( paramInt & 0xFFFFC000 ) == 0 ) 30 | { 31 | return 2; 32 | } 33 | if ( ( paramInt & 0xFFE00000 ) == 0 ) 34 | { 35 | return 3; 36 | } 37 | if ( ( paramInt & 0xF0000000 ) == 0 ) 38 | { 39 | return 4; 40 | } 41 | return 5; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /query/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-query 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Query 19 | Minecraft query implementation based on the BungeeCord API. 20 | 21 | 22 | 23 | io.netty 24 | netty-transport 25 | ${netty.version} 26 | compile 27 | 28 | 29 | net.md-5 30 | bungeecord-api 31 | ${project.version} 32 | compile 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/Handshake.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @EqualsAndHashCode(callSuper = false) 15 | public class Handshake extends DefinedPacket 16 | { 17 | 18 | private int protocolVersion; 19 | private String host; 20 | private int port; 21 | private int requestedProtocol; 22 | 23 | @Override 24 | public void read(ByteBuf buf) 25 | { 26 | protocolVersion = readVarInt( buf ); 27 | host = readString( buf, 255 ); 28 | port = buf.readUnsignedShort(); 29 | requestedProtocol = readVarInt( buf ); 30 | } 31 | 32 | @Override 33 | public void write(ByteBuf buf) 34 | { 35 | writeVarInt( protocolVersion, buf ); 36 | writeString( host, buf ); 37 | buf.writeShort( port ); 38 | writeVarInt( requestedProtocol, buf ); 39 | } 40 | 41 | @Override 42 | public void handle(AbstractPacketHandler handler) throws Exception 43 | { 44 | handler.handle( this ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/module/TravisCiModuleSource.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module; 2 | 3 | 4 | import com.google.common.io.ByteStreams; 5 | import com.google.common.io.Files; 6 | import java.io.IOException; 7 | import java.net.URL; 8 | import java.net.URLConnection; 9 | import lombok.Data; 10 | import net.md_5.bungee.Util; 11 | 12 | 13 | @Data 14 | public class TravisCiModuleSource implements ModuleSource 15 | { 16 | 17 | @Override 18 | public void retrieve(ModuleSpec module, ModuleVersion version) 19 | { 20 | System.out.println( "Attempting to download Tracis-CI module " + module.getName() + " v" + version.getBuild() ); 21 | try 22 | { 23 | URL website = new URL( "https://github.com/HexagonMC/BungeeCord/releases/download/v" + version.getBuild() + "/" + module.getName() + ".jar" ); 24 | URLConnection con = website.openConnection(); 25 | // 15 second timeout at various stages 26 | con.setConnectTimeout( 15000 ); 27 | con.setReadTimeout( 15000 ); 28 | 29 | Files.write( ByteStreams.toByteArray( con.getInputStream() ), module.getFile() ); 30 | System.out.println( "Download complete" ); 31 | } catch ( IOException ex ) 32 | { 33 | System.out.println( "Failed to download: " + Util.exception( ex ) ); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/util/AllowedCharacters.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | 6 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 7 | public final class AllowedCharacters 8 | { 9 | 10 | public static boolean isChatAllowedCharacter(char character) 11 | { 12 | // Section symbols, control sequences, and deletes are not allowed 13 | return character != '\u00A7' && character >= ' ' && character != 127; 14 | } 15 | 16 | private static boolean isNameAllowedCharacter(char c, boolean onlineMode) 17 | { 18 | if ( onlineMode ) 19 | { 20 | return ( c >= 'a' && c <= 'z' ) || ( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' || c == '.' || c == '-'; 21 | } else 22 | { 23 | // Don't allow spaces, Yaml config doesn't support them 24 | return isChatAllowedCharacter( c ) && c != ' '; 25 | } 26 | } 27 | 28 | public static boolean isValidName(String name, boolean onlineMode) 29 | { 30 | for ( int index = 0, len = name.length(); index < len; index++ ) 31 | { 32 | if ( !isNameAllowedCharacter( name.charAt( index ), onlineMode ) ) 33 | { 34 | return false; 35 | } 36 | } 37 | return true; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/module/JenkinsModuleSource.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module; 2 | 3 | import com.google.common.io.ByteStreams; 4 | import com.google.common.io.Files; 5 | import java.io.IOException; 6 | import java.net.URL; 7 | import java.net.URLConnection; 8 | import lombok.Data; 9 | import net.md_5.bungee.Util; 10 | 11 | @Data 12 | public class JenkinsModuleSource implements ModuleSource 13 | { 14 | 15 | @Override 16 | public void retrieve(ModuleSpec module, ModuleVersion version) 17 | { 18 | System.out.println( "Attempting to Jenkins download module " + module.getName() + " v" + version.getBuild() ); 19 | try 20 | { 21 | URL website = new URL( "https://ci.md-5.net/job/BungeeCord/" + version.getBuild() + "/artifact/module/" + module.getName().replace( '_', '-' ) + "/target/" + module.getName() + ".jar" ); 22 | URLConnection con = website.openConnection(); 23 | // 15 second timeout at various stages 24 | con.setConnectTimeout( 15000 ); 25 | con.setReadTimeout( 15000 ); 26 | 27 | Files.write( ByteStreams.toByteArray( con.getInputStream() ), module.getFile() ); 28 | System.out.println( "Download complete" ); 29 | } catch ( IOException ex ) 30 | { 31 | System.out.println( "Failed to download: " + Util.exception( ex ) ); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /log/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-log 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Log 19 | Simplistic and performant java.util.Logger based logger and console API designed for use with BungeeCord and Minecraft related applications. 20 | 21 | 22 | 23 | jline 24 | jline 25 | 2.12.1 26 | compile 27 | 28 | 29 | net.md-5 30 | bungeecord-chat 31 | ${project.version} 32 | compile 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/http/HttpInitializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.http; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelInitializer; 5 | import io.netty.handler.codec.http.HttpClientCodec; 6 | import io.netty.handler.ssl.SslContextBuilder; 7 | import io.netty.handler.ssl.SslHandler; 8 | import io.netty.handler.timeout.ReadTimeoutHandler; 9 | import java.util.concurrent.TimeUnit; 10 | import javax.net.ssl.SSLEngine; 11 | import lombok.RequiredArgsConstructor; 12 | import net.md_5.bungee.api.Callback; 13 | 14 | @RequiredArgsConstructor 15 | public class HttpInitializer extends ChannelInitializer 16 | { 17 | 18 | private final Callback callback; 19 | private final boolean ssl; 20 | private final String host; 21 | private final int port; 22 | 23 | @Override 24 | protected void initChannel(Channel ch) throws Exception 25 | { 26 | ch.pipeline().addLast( "timeout", new ReadTimeoutHandler( HttpClient.TIMEOUT, TimeUnit.MILLISECONDS ) ); 27 | if ( ssl ) 28 | { 29 | SSLEngine engine = SslContextBuilder.forClient().build().newEngine( ch.alloc(), host, port ); 30 | 31 | ch.pipeline().addLast( "ssl", new SslHandler( engine ) ); 32 | } 33 | ch.pipeline().addLast( "http", new HttpClientCodec() ); 34 | ch.pipeline().addLast( "handler", new HttpHandler( callback ) ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-config 15 | 1.19-R0.1-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Config 19 | Generic java configuration API intended for use with BungeeCord 20 | 21 | 22 | 23 | com.google.code.gson 24 | gson 25 | 2.8.8 26 | compile 27 | true 28 | 29 | 30 | org.yaml 31 | snakeyaml 32 | 1.30 33 | compile 34 | true 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/compress/PacketCompressor.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.compress; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | import java.util.zip.Deflater; 7 | import lombok.Setter; 8 | import net.md_5.bungee.jni.zlib.BungeeZlib; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | public class PacketCompressor extends MessageToByteEncoder 12 | { 13 | 14 | private final BungeeZlib zlib = CompressFactory.zlib.newInstance(); 15 | @Setter 16 | private int threshold = 256; 17 | 18 | @Override 19 | public void handlerAdded(ChannelHandlerContext ctx) throws Exception 20 | { 21 | zlib.init( true, Deflater.DEFAULT_COMPRESSION ); 22 | } 23 | 24 | @Override 25 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception 26 | { 27 | zlib.free(); 28 | } 29 | 30 | @Override 31 | protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception 32 | { 33 | int origSize = msg.readableBytes(); 34 | if ( origSize < threshold ) 35 | { 36 | DefinedPacket.writeVarInt( 0, out ); 37 | out.writeBytes( msg ); 38 | } else 39 | { 40 | DefinedPacket.writeVarInt( origSize, out ); 41 | 42 | zlib.process( msg, out ); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.plugin; 2 | 3 | import java.io.File; 4 | import java.util.HashSet; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import java.util.Set; 8 | import lombok.AllArgsConstructor; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | /** 13 | * POJO representing the plugin.yml file. 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class PluginDescription 19 | { 20 | 21 | /** 22 | * Friendly name of the plugin. 23 | */ 24 | private String name; 25 | /** 26 | * Plugin main class. Needs to extend {@link Plugin}. 27 | */ 28 | private String main; 29 | /** 30 | * Plugin version. 31 | */ 32 | private String version; 33 | /** 34 | * Plugin author. 35 | */ 36 | private String author; 37 | /** 38 | * Plugin hard dependencies. 39 | */ 40 | private Set depends = new HashSet<>(); 41 | /** 42 | * Plugin soft dependencies. 43 | */ 44 | private Set softDepends = new HashSet<>(); 45 | /** 46 | * File we were loaded from. 47 | */ 48 | private File file = null; 49 | /** 50 | * Optional description. 51 | */ 52 | private String description = null; 53 | /** 54 | * Optional libraries. 55 | */ 56 | private List libraries = new LinkedList<>(); 57 | } 58 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/hover/content/TextSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat.hover.content; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonParseException; 7 | import com.google.gson.JsonSerializationContext; 8 | import com.google.gson.JsonSerializer; 9 | import java.lang.reflect.Type; 10 | import net.md_5.bungee.api.chat.BaseComponent; 11 | 12 | public class TextSerializer implements JsonSerializer, JsonDeserializer 13 | { 14 | 15 | @Override 16 | public Text deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException 17 | { 18 | if ( element.isJsonArray() ) 19 | { 20 | return new Text( context.deserialize( element, BaseComponent[].class ) ); 21 | } else if ( element.isJsonPrimitive() ) 22 | { 23 | return new Text( element.getAsJsonPrimitive().getAsString() ); 24 | } else 25 | { 26 | return new Text( new BaseComponent[] 27 | { 28 | context.deserialize( element, BaseComponent.class ) 29 | } ); 30 | } 31 | } 32 | 33 | @Override 34 | public JsonElement serialize(Text content, Type type, JsonSerializationContext context) 35 | { 36 | return context.serialize( content.getValue() ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/MinecraftOutput.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.Unpooled; 5 | import java.nio.charset.Charset; 6 | import java.util.Arrays; 7 | 8 | public class MinecraftOutput 9 | { 10 | 11 | private final ByteBuf buf; 12 | 13 | public MinecraftOutput() 14 | { 15 | buf = Unpooled.buffer(); 16 | } 17 | 18 | public byte[] toArray() 19 | { 20 | if ( buf.hasArray() ) 21 | { 22 | return Arrays.copyOfRange( buf.array(), buf.arrayOffset(), buf.arrayOffset() + buf.writerIndex() ); 23 | } else 24 | { 25 | byte[] b = new byte[ buf.writerIndex() ]; 26 | buf.readBytes( b ); 27 | return b; 28 | } 29 | } 30 | 31 | public MinecraftOutput writeByte(byte b) 32 | { 33 | buf.writeByte( b ); 34 | return this; 35 | } 36 | 37 | public void writeInt(int i) 38 | { 39 | buf.writeInt( i ); 40 | } 41 | 42 | public void writeString(String s) 43 | { 44 | char[] cc = s.toCharArray(); 45 | buf.writeShort( cc.length ); 46 | for ( char c : cc ) 47 | { 48 | buf.writeChar( c ); 49 | } 50 | } 51 | 52 | public void writeStringUTF8WithoutLengthHeaderBecauseDinnerboneStuffedUpTheMCBrandPacket(String s) 53 | { 54 | buf.writeBytes( s.getBytes( Charset.forName( "UTF-8" ) ) ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/command/ConsoleCommandCompleter.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Locale; 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | import jline.console.completer.Completer; 9 | import lombok.RequiredArgsConstructor; 10 | import net.md_5.bungee.api.ProxyServer; 11 | 12 | @RequiredArgsConstructor 13 | public class ConsoleCommandCompleter implements Completer 14 | { 15 | 16 | private final ProxyServer proxy; 17 | 18 | @Override 19 | public int complete(String buffer, int cursor, List candidates) 20 | { 21 | int lastSpace = buffer.lastIndexOf( ' ' ); 22 | if ( lastSpace == -1 ) 23 | { 24 | String lowerCase = buffer.toLowerCase( Locale.ROOT ); 25 | candidates.addAll( proxy.getPluginManager().getCommands().stream() 26 | .map( Map.Entry::getKey ) 27 | .filter( (name) -> name.toLowerCase( Locale.ROOT ).startsWith( lowerCase ) ) 28 | .collect( Collectors.toList() ) ); 29 | } else 30 | { 31 | List suggestions = new ArrayList<>(); 32 | proxy.getPluginManager().dispatchCommand( proxy.getConsole(), buffer, suggestions ); 33 | candidates.addAll( suggestions ); 34 | } 35 | 36 | return ( lastSpace == -1 ) ? cursor - buffer.length() : cursor - ( buffer.length() - lastSpace - 1 ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginPayloadRequest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.OverflowPacketException; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class LoginPayloadRequest extends DefinedPacket 17 | { 18 | 19 | private int id; 20 | private String channel; 21 | private byte[] data; 22 | 23 | @Override 24 | public void read(ByteBuf buf) 25 | { 26 | id = readVarInt( buf ); 27 | channel = readString( buf ); 28 | 29 | int len = buf.readableBytes(); 30 | if ( len > 1048576 ) 31 | { 32 | throw new OverflowPacketException( "Payload may not be larger than 1048576 bytes" ); 33 | } 34 | data = new byte[ len ]; 35 | buf.readBytes( data ); 36 | } 37 | 38 | @Override 39 | public void write(ByteBuf buf) 40 | { 41 | writeVarInt( id, buf ); 42 | writeString( channel, buf ); 43 | buf.writeBytes( data ); 44 | } 45 | 46 | @Override 47 | public void handle(AbstractPacketHandler handler) throws Exception 48 | { 49 | handler.handle( this ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/hover/content/Text.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat.hover.content; 2 | 3 | import java.util.Arrays; 4 | import lombok.Getter; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.chat.BaseComponent; 7 | import net.md_5.bungee.api.chat.HoverEvent; 8 | 9 | @Getter 10 | @ToString 11 | public class Text extends Content 12 | { 13 | 14 | /** 15 | * The value. 16 | * 17 | * May be a component or raw text depending on constructor used. 18 | */ 19 | private final Object value; 20 | 21 | public Text(BaseComponent[] value) 22 | { 23 | this.value = value; 24 | } 25 | 26 | public Text(String value) 27 | { 28 | this.value = value; 29 | } 30 | 31 | @Override 32 | public HoverEvent.Action requiredAction() 33 | { 34 | return HoverEvent.Action.SHOW_TEXT; 35 | } 36 | 37 | @Override 38 | public boolean equals(Object o) 39 | { 40 | if ( value instanceof BaseComponent[] ) 41 | { 42 | return o instanceof Text 43 | && ( (Text) o ).value instanceof BaseComponent[] 44 | && Arrays.equals( (BaseComponent[]) value, (BaseComponent[]) ( (Text) o ).value ); 45 | } else 46 | { 47 | return value.equals( o ); 48 | } 49 | } 50 | 51 | @Override 52 | public int hashCode() 53 | { 54 | return ( value instanceof BaseComponent[] ) ? Arrays.hashCode( (BaseComponent[]) value ) : value.hashCode(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginRequest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.PlayerPublicKey; 11 | import net.md_5.bungee.protocol.ProtocolConstants; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @EqualsAndHashCode(callSuper = false) 17 | public class LoginRequest extends DefinedPacket 18 | { 19 | 20 | private String data; 21 | private PlayerPublicKey publicKey; 22 | 23 | @Override 24 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 25 | { 26 | data = readString( buf, 16 ); 27 | if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) 28 | { 29 | publicKey = readPublicKey( buf ); 30 | } 31 | } 32 | 33 | @Override 34 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 35 | { 36 | writeString( data, buf ); 37 | if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) 38 | { 39 | writePublicKey( publicKey, buf ); 40 | } 41 | } 42 | 43 | @Override 44 | public void handle(AbstractPacketHandler handler) throws Exception 45 | { 46 | handler.handle( this ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/chat/TextComponentSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.chat; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.JsonSerializationContext; 9 | import com.google.gson.JsonSerializer; 10 | import java.lang.reflect.Type; 11 | import net.md_5.bungee.api.chat.TextComponent; 12 | 13 | public class TextComponentSerializer extends BaseComponentSerializer implements JsonSerializer, JsonDeserializer 14 | { 15 | 16 | @Override 17 | public TextComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException 18 | { 19 | TextComponent component = new TextComponent(); 20 | JsonObject object = json.getAsJsonObject(); 21 | if ( !object.has( "text" ) ) 22 | { 23 | throw new JsonParseException( "Could not parse JSON: missing 'text' property" ); 24 | } 25 | component.setText( object.get( "text" ).getAsString() ); 26 | deserialize( object, component, context ); 27 | return component; 28 | } 29 | 30 | @Override 31 | public JsonElement serialize(TextComponent src, Type typeOfSrc, JsonSerializationContext context) 32 | { 33 | JsonObject object = new JsonObject(); 34 | serialize( object, src, context ); 35 | object.addProperty( "text", src.getText() ); 36 | return object; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.Unpooled; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.ByteToMessageDecoder; 7 | import java.util.List; 8 | import net.md_5.bungee.protocol.packet.LegacyHandshake; 9 | import net.md_5.bungee.protocol.packet.LegacyPing; 10 | 11 | public class LegacyDecoder extends ByteToMessageDecoder 12 | { 13 | 14 | @Override 15 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception 16 | { 17 | // See check in Varint21FrameDecoder for more details 18 | if ( !ctx.channel().isActive() ) 19 | { 20 | in.skipBytes( in.readableBytes() ); 21 | return; 22 | } 23 | 24 | if ( !in.isReadable() ) 25 | { 26 | return; 27 | } 28 | 29 | in.markReaderIndex(); 30 | short packetID = in.readUnsignedByte(); 31 | 32 | if ( packetID == 0xFE ) 33 | { 34 | out.add( new PacketWrapper( new LegacyPing( in.isReadable() && in.readUnsignedByte() == 0x01 ), Unpooled.EMPTY_BUFFER ) ); 35 | return; 36 | } else if ( packetID == 0x02 && in.isReadable() ) 37 | { 38 | in.skipBytes( in.readableBytes() ); 39 | out.add( new PacketWrapper( new LegacyHandshake(), Unpooled.EMPTY_BUFFER ) ); 40 | return; 41 | } 42 | 43 | in.resetReaderIndex(); 44 | ctx.pipeline().remove( this ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/CommandAlert.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.alert; 2 | 3 | import net.md_5.bungee.api.ChatColor; 4 | import net.md_5.bungee.api.CommandSender; 5 | import net.md_5.bungee.api.ProxyServer; 6 | import net.md_5.bungee.api.chat.TextComponent; 7 | import net.md_5.bungee.api.plugin.Command; 8 | 9 | public class CommandAlert extends Command 10 | { 11 | 12 | public CommandAlert() 13 | { 14 | super( "alert", "bungeecord.command.alert" ); 15 | } 16 | 17 | @Override 18 | public void execute(CommandSender sender, String[] args) 19 | { 20 | if ( args.length == 0 ) 21 | { 22 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "message_needed" ) ); 23 | } else 24 | { 25 | StringBuilder builder = new StringBuilder(); 26 | if ( args[0].startsWith( "&h" ) ) 27 | { 28 | // Remove &h 29 | args[0] = args[0].substring( 2, args[0].length() ); 30 | } else 31 | { 32 | builder.append( ProxyServer.getInstance().getTranslation( "alert" ) ); 33 | } 34 | 35 | for ( String s : args ) 36 | { 37 | builder.append( ChatColor.translateAlternateColorCodes( '&', s ) ); 38 | builder.append( " " ); 39 | } 40 | 41 | String message = builder.substring( 0, builder.length() - 1 ); 42 | 43 | ProxyServer.getInstance().broadcast( TextComponent.fromLegacyText( message ) ); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, md_5. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | The name of the author may not be used to endorse or promote products derived 14 | from this software without specific prior written permission. 15 | 16 | You may not use the software for commercial software hosting services without 17 | written permission from the author. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientChat.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class ClientChat extends DefinedPacket 17 | { 18 | 19 | private String message; 20 | private long timestamp; 21 | private long salt; 22 | private byte[] signature; 23 | private boolean signedPreview; 24 | 25 | @Override 26 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 27 | { 28 | message = readString( buf, 256 ); 29 | timestamp = buf.readLong(); 30 | salt = buf.readLong(); 31 | signature = readArray( buf ); 32 | signedPreview = buf.readBoolean(); 33 | } 34 | 35 | @Override 36 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 37 | { 38 | writeString( message, buf ); 39 | buf.writeLong( timestamp ); 40 | buf.writeLong( salt ); 41 | writeArray( signature, buf ); 42 | buf.writeBoolean( signedPreview ); 43 | } 44 | 45 | @Override 46 | public void handle(AbstractPacketHandler handler) throws Exception 47 | { 48 | handler.handle( this ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/chat/SelectorComponentSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.chat; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.JsonSerializationContext; 9 | import com.google.gson.JsonSerializer; 10 | import java.lang.reflect.Type; 11 | import net.md_5.bungee.api.chat.SelectorComponent; 12 | 13 | public class SelectorComponentSerializer extends BaseComponentSerializer implements JsonSerializer, JsonDeserializer 14 | { 15 | 16 | @Override 17 | public SelectorComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException 18 | { 19 | JsonObject object = element.getAsJsonObject(); 20 | if ( !object.has( "selector" ) ) 21 | { 22 | throw new JsonParseException( "Could not parse JSON: missing 'selector' property" ); 23 | } 24 | SelectorComponent component = new SelectorComponent( object.get( "selector" ).getAsString() ); 25 | deserialize( object, component, context ); 26 | return component; 27 | } 28 | 29 | @Override 30 | public JsonElement serialize(SelectorComponent component, Type type, JsonSerializationContext context) 31 | { 32 | JsonObject object = new JsonObject(); 33 | serialize( object, component, context ); 34 | object.addProperty( "selector", component.getSelector() ); 35 | return object; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/chat/KeybindComponentSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.chat; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.JsonSerializationContext; 9 | import com.google.gson.JsonSerializer; 10 | import java.lang.reflect.Type; 11 | import net.md_5.bungee.api.chat.KeybindComponent; 12 | 13 | public class KeybindComponentSerializer extends BaseComponentSerializer implements JsonSerializer, JsonDeserializer 14 | { 15 | 16 | @Override 17 | public KeybindComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException 18 | { 19 | JsonObject object = json.getAsJsonObject(); 20 | if ( !object.has( "keybind" ) ) 21 | { 22 | throw new JsonParseException( "Could not parse JSON: missing 'keybind' property" ); 23 | } 24 | KeybindComponent component = new KeybindComponent(); 25 | deserialize( object, component, context ); 26 | component.setKeybind( object.get( "keybind" ).getAsString() ); 27 | return component; 28 | } 29 | 30 | @Override 31 | public JsonElement serialize(KeybindComponent src, Type typeOfSrc, JsonSerializationContext context) 32 | { 33 | JsonObject object = new JsonObject(); 34 | serialize( object, src, context ); 35 | object.addProperty( "keybind", src.getKeybind() ); 36 | return object; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/AbstractReconnectHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api; 2 | 3 | import com.google.common.base.Preconditions; 4 | import net.md_5.bungee.api.config.ServerInfo; 5 | import net.md_5.bungee.api.connection.PendingConnection; 6 | import net.md_5.bungee.api.connection.ProxiedPlayer; 7 | 8 | public abstract class AbstractReconnectHandler implements ReconnectHandler 9 | { 10 | 11 | @Override 12 | public ServerInfo getServer(ProxiedPlayer player) 13 | { 14 | ServerInfo server = getForcedHost( player.getPendingConnection() ); 15 | if ( server == null ) 16 | { 17 | server = getStoredServer( player ); 18 | if ( server == null ) 19 | { 20 | server = ProxyServer.getInstance().getServerInfo( player.getPendingConnection().getListener().getDefaultServer() ); 21 | } 22 | 23 | Preconditions.checkState( server != null, "Default server not defined" ); 24 | } 25 | 26 | return server; 27 | } 28 | 29 | public static ServerInfo getForcedHost(PendingConnection con) 30 | { 31 | if ( con.getVirtualHost() == null ) 32 | { 33 | return null; 34 | } 35 | 36 | String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() ); 37 | 38 | if ( forced == null && con.getListener().isForceDefault() ) 39 | { 40 | forced = con.getListener().getDefaultServer(); 41 | } 42 | return ProxyServer.getInstance().getServerInfo( forced ); 43 | } 44 | 45 | protected abstract ServerInfo getStoredServer(ProxiedPlayer player); 46 | } 47 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginPayloadResponse.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.OverflowPacketException; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class LoginPayloadResponse extends DefinedPacket 17 | { 18 | 19 | private int id; 20 | private byte[] data; 21 | 22 | @Override 23 | public void read(ByteBuf buf) 24 | { 25 | id = readVarInt( buf ); 26 | 27 | if ( buf.readBoolean() ) 28 | { 29 | int len = buf.readableBytes(); 30 | if ( len > 1048576 ) 31 | { 32 | throw new OverflowPacketException( "Payload may not be larger than 1048576 bytes" ); 33 | } 34 | data = new byte[ len ]; 35 | buf.readBytes( data ); 36 | } 37 | } 38 | 39 | @Override 40 | public void write(ByteBuf buf) 41 | { 42 | writeVarInt( id, buf ); 43 | if ( data != null ) 44 | { 45 | buf.writeBoolean( true ); 46 | buf.writeBytes( data ); 47 | } else 48 | { 49 | buf.writeBoolean( false ); 50 | } 51 | } 52 | 53 | @Override 54 | public void handle(AbstractPacketHandler handler) throws Exception 55 | { 56 | handler.handle( this ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/hover/content/EntitySerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat.hover.content; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.JsonSerializationContext; 9 | import com.google.gson.JsonSerializer; 10 | import java.lang.reflect.Type; 11 | import net.md_5.bungee.api.chat.BaseComponent; 12 | 13 | public class EntitySerializer implements JsonSerializer, JsonDeserializer 14 | { 15 | 16 | @Override 17 | public Entity deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException 18 | { 19 | JsonObject value = element.getAsJsonObject(); 20 | 21 | return new Entity( 22 | ( value.has( "type" ) ) ? value.get( "type" ).getAsString() : null, 23 | value.get( "id" ).getAsString(), 24 | ( value.has( "name" ) ) ? context.deserialize( value.get( "name" ), BaseComponent.class ) : null 25 | ); 26 | } 27 | 28 | @Override 29 | public JsonElement serialize(Entity content, Type type, JsonSerializationContext context) 30 | { 31 | JsonObject object = new JsonObject(); 32 | object.addProperty( "type", ( content.getType() != null ) ? content.getType() : "minecraft:pig" ); 33 | object.addProperty( "id", content.getId() ); 34 | if ( content.getName() != null ) 35 | { 36 | object.add( "name", context.serialize( content.getName() ) ); 37 | } 38 | return object; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /native/src/main/c/net_md_5_bungee_jni_zlib_NativeCompressImpl.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class net_md_5_bungee_jni_zlib_NativeCompressImpl */ 4 | 5 | #ifndef _Included_net_md_5_bungee_jni_zlib_NativeCompressImpl 6 | #define _Included_net_md_5_bungee_jni_zlib_NativeCompressImpl 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: net_md_5_bungee_jni_zlib_NativeCompressImpl 12 | * Method: initFields 13 | * Signature: ()V 14 | */ 15 | JNIEXPORT void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_initFields 16 | (JNIEnv *, jclass); 17 | 18 | /* 19 | * Class: net_md_5_bungee_jni_zlib_NativeCompressImpl 20 | * Method: end 21 | * Signature: (JZ)V 22 | */ 23 | JNIEXPORT void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_end 24 | (JNIEnv *, jobject, jlong, jboolean); 25 | 26 | /* 27 | * Class: net_md_5_bungee_jni_zlib_NativeCompressImpl 28 | * Method: reset 29 | * Signature: (JZ)V 30 | */ 31 | JNIEXPORT void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_reset 32 | (JNIEnv *, jobject, jlong, jboolean); 33 | 34 | /* 35 | * Class: net_md_5_bungee_jni_zlib_NativeCompressImpl 36 | * Method: init 37 | * Signature: (ZI)J 38 | */ 39 | JNIEXPORT jlong JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_init 40 | (JNIEnv *, jobject, jboolean, jint); 41 | 42 | /* 43 | * Class: net_md_5_bungee_jni_zlib_NativeCompressImpl 44 | * Method: process 45 | * Signature: (JJIJIZ)I 46 | */ 47 | JNIEXPORT jint JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_process 48 | (JNIEnv *, jobject, jlong, jlong, jint, jlong, jint, jboolean); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif 54 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/command/PlayerCommand.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.command; 2 | 3 | import com.google.common.base.Function; 4 | import com.google.common.base.Predicate; 5 | import com.google.common.collect.Iterables; 6 | import java.util.Locale; 7 | import net.md_5.bungee.api.CommandSender; 8 | import net.md_5.bungee.api.ProxyServer; 9 | import net.md_5.bungee.api.connection.ProxiedPlayer; 10 | import net.md_5.bungee.api.plugin.Command; 11 | import net.md_5.bungee.api.plugin.TabExecutor; 12 | 13 | /** 14 | * @deprecated internal use only 15 | */ 16 | @Deprecated 17 | public abstract class PlayerCommand extends Command implements TabExecutor 18 | { 19 | 20 | public PlayerCommand(String name) 21 | { 22 | super( name ); 23 | } 24 | 25 | public PlayerCommand(String name, String permission, String... aliases) 26 | { 27 | super( name, permission, aliases ); 28 | } 29 | 30 | @Override 31 | public Iterable onTabComplete(CommandSender sender, String[] args) 32 | { 33 | final String lastArg = ( args.length > 0 ) ? args[args.length - 1].toLowerCase( Locale.ROOT ) : ""; 34 | return Iterables.transform( Iterables.filter( ProxyServer.getInstance().getPlayers(), new Predicate() 35 | { 36 | @Override 37 | public boolean apply(ProxiedPlayer player) 38 | { 39 | return player.getName().toLowerCase( Locale.ROOT ).startsWith( lastArg ); 40 | } 41 | } ), new Function() 42 | { 43 | @Override 44 | public String apply(ProxiedPlayer player) 45 | { 46 | return player.getName(); 47 | } 48 | } ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /module/cmd-list/src/main/java/net/md_5/bungee/module/cmd/list/CommandList.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.list; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import net.md_5.bungee.Util; 7 | import net.md_5.bungee.api.ChatColor; 8 | import net.md_5.bungee.api.CommandSender; 9 | import net.md_5.bungee.api.ProxyServer; 10 | import net.md_5.bungee.api.config.ServerInfo; 11 | import net.md_5.bungee.api.connection.ProxiedPlayer; 12 | import net.md_5.bungee.api.plugin.Command; 13 | 14 | /** 15 | * Command to list all players connected to the proxy. 16 | */ 17 | public class CommandList extends Command 18 | { 19 | 20 | public CommandList() 21 | { 22 | super( "glist", "bungeecord.command.list" ); 23 | } 24 | 25 | @Override 26 | public void execute(CommandSender sender, String[] args) 27 | { 28 | for ( ServerInfo server : ProxyServer.getInstance().getServers().values() ) 29 | { 30 | if ( !server.canAccess( sender ) ) 31 | { 32 | continue; 33 | } 34 | 35 | List players = new ArrayList<>(); 36 | for ( ProxiedPlayer player : server.getPlayers() ) 37 | { 38 | players.add( player.getDisplayName() ); 39 | } 40 | Collections.sort( players, String.CASE_INSENSITIVE_ORDER ); 41 | 42 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_list", server.getName(), server.getPlayers().size(), Util.format( players, ChatColor.RESET + ", " ) ) ); 43 | } 44 | 45 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "total_players", ProxyServer.getInstance().getOnlineCount() ) ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/ClickEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.ToString; 7 | 8 | @Getter 9 | @ToString 10 | @EqualsAndHashCode 11 | @RequiredArgsConstructor 12 | public final class ClickEvent 13 | { 14 | 15 | /** 16 | * The type of action to perform on click. 17 | */ 18 | private final Action action; 19 | /** 20 | * Depends on the action. 21 | * 22 | * @see Action 23 | */ 24 | private final String value; 25 | 26 | public enum Action 27 | { 28 | 29 | /** 30 | * Open a url at the path given by 31 | * {@link net.md_5.bungee.api.chat.ClickEvent#value}. 32 | */ 33 | OPEN_URL, 34 | /** 35 | * Open a file at the path given by 36 | * {@link net.md_5.bungee.api.chat.ClickEvent#value}. 37 | */ 38 | OPEN_FILE, 39 | /** 40 | * Run the command given by 41 | * {@link net.md_5.bungee.api.chat.ClickEvent#value}. 42 | */ 43 | RUN_COMMAND, 44 | /** 45 | * Inserts the string given by 46 | * {@link net.md_5.bungee.api.chat.ClickEvent#value} into the player's 47 | * text box. 48 | */ 49 | SUGGEST_COMMAND, 50 | /** 51 | * Change to the page number given by 52 | * {@link net.md_5.bungee.api.chat.ClickEvent#value} in a book. 53 | */ 54 | CHANGE_PAGE, 55 | /** 56 | * Copy the string given by 57 | * {@link net.md_5.bungee.api.chat.ClickEvent#value} into the player's 58 | * clipboard. 59 | */ 60 | COPY_TO_CLIPBOARD 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | @Getter 10 | @Setter 11 | @ToString 12 | @NoArgsConstructor 13 | @EqualsAndHashCode(callSuper = true) 14 | public final class KeybindComponent extends BaseComponent 15 | { 16 | 17 | /** 18 | * The keybind identifier to use. 19 | *
20 | * Will be replaced with the actual key the client is using. 21 | */ 22 | private String keybind; 23 | 24 | /** 25 | * Creates a keybind component from the original to clone it. 26 | * 27 | * @param original the original for the new keybind component. 28 | */ 29 | public KeybindComponent(KeybindComponent original) 30 | { 31 | super( original ); 32 | setKeybind( original.getKeybind() ); 33 | } 34 | 35 | /** 36 | * Creates a keybind component with the passed internal keybind value. 37 | * 38 | * @param keybind the keybind value 39 | * @see Keybinds 40 | */ 41 | public KeybindComponent(String keybind) 42 | { 43 | setKeybind( keybind ); 44 | } 45 | 46 | @Override 47 | public KeybindComponent duplicate() 48 | { 49 | return new KeybindComponent( this ); 50 | } 51 | 52 | @Override 53 | protected void toPlainText(StringBuilder builder) 54 | { 55 | builder.append( getKeybind() ); 56 | super.toPlainText( builder ); 57 | } 58 | 59 | @Override 60 | protected void toLegacyText(StringBuilder builder) 61 | { 62 | addFormat( builder ); 63 | builder.append( getKeybind() ); 64 | super.toLegacyText( builder ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/KeepAlive.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class KeepAlive extends DefinedPacket 17 | { 18 | 19 | private long randomId; 20 | 21 | @Override 22 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_12_2 ) 25 | { 26 | randomId = buf.readLong(); 27 | } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_8 ) 28 | { 29 | randomId = readVarInt( buf ); 30 | } else 31 | { 32 | randomId = buf.readInt(); 33 | } 34 | } 35 | 36 | @Override 37 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 38 | { 39 | if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_12_2 ) 40 | { 41 | buf.writeLong( randomId ); 42 | } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_8 ) 43 | { 44 | writeVarInt( (int) randomId, buf ); 45 | } else 46 | { 47 | buf.writeInt( (int) randomId ); 48 | } 49 | } 50 | 51 | @Override 52 | public void handle(AbstractPacketHandler handler) throws Exception 53 | { 54 | handler.handle( this ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/compress/PacketDecompressor.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.compress; 2 | 3 | import com.google.common.base.Preconditions; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.MessageToMessageDecoder; 7 | import java.util.List; 8 | import net.md_5.bungee.jni.zlib.BungeeZlib; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | 11 | public class PacketDecompressor extends MessageToMessageDecoder 12 | { 13 | 14 | private final BungeeZlib zlib = CompressFactory.zlib.newInstance(); 15 | 16 | @Override 17 | public void handlerAdded(ChannelHandlerContext ctx) throws Exception 18 | { 19 | zlib.init( false, 0 ); 20 | } 21 | 22 | @Override 23 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception 24 | { 25 | zlib.free(); 26 | } 27 | 28 | @Override 29 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception 30 | { 31 | int size = DefinedPacket.readVarInt( in ); 32 | if ( size == 0 ) 33 | { 34 | out.add( in.retain() ); 35 | } else 36 | { 37 | ByteBuf decompressed = ctx.alloc().directBuffer(); 38 | 39 | try 40 | { 41 | zlib.process( in, decompressed ); 42 | Preconditions.checkState( decompressed.readableBytes() == size, "Decompressed packet size mismatch" ); 43 | 44 | out.add( decompressed ); 45 | decompressed = null; 46 | } finally 47 | { 48 | if ( decompressed != null ) 49 | { 50 | decompressed.release(); 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/Keybinds.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | /** 4 | * All keybind values supported by vanilla Minecraft. 5 | *
6 | * Values may be removed if they are no longer supported. 7 | * 8 | * @see KeybindComponent 9 | */ 10 | public interface Keybinds 11 | { 12 | 13 | String JUMP = "key.jump"; 14 | String SNEAK = "key.sneak"; 15 | String SPRINT = "key.sprint"; 16 | String LEFT = "key.left"; 17 | String RIGHT = "key.right"; 18 | String BACK = "key.back"; 19 | String FORWARD = "key.forward"; 20 | 21 | String ATTACK = "key.attack"; 22 | String PICK_ITEM = "key.pickItem"; 23 | String USE = "key.use"; 24 | 25 | String DROP = "key.drop"; 26 | String HOTBAR_1 = "key.hotbar.1"; 27 | String HOTBAR_2 = "key.hotbar.2"; 28 | String HOTBAR_3 = "key.hotbar.3"; 29 | String HOTBAR_4 = "key.hotbar.4"; 30 | String HOTBAR_5 = "key.hotbar.5"; 31 | String HOTBAR_6 = "key.hotbar.6"; 32 | String HOTBAR_7 = "key.hotbar.7"; 33 | String HOTBAR_8 = "key.hotbar.8"; 34 | String HOTBAR_9 = "key.hotbar.9"; 35 | String INVENTORY = "key.inventory"; 36 | String SWAP_HANDS = "key.swapHands"; 37 | 38 | String LOAD_TOOLBAR_ACTIVATOR = "key.loadToolbarActivator"; 39 | String SAVE_TOOLBAR_ACTIVATOR = "key.saveToolbarActivator"; 40 | 41 | String PLAYERLIST = "key.playerlist"; 42 | String CHAT = "key.chat"; 43 | String COMMAND = "key.command"; 44 | String SOCIAL_INTERACTIONS = "key.socialInteractions"; 45 | 46 | String ADVANCEMENTS = "key.advancements"; 47 | String SPECTATOR_OUTLINES = "key.spectatorOutlines"; 48 | String SCREENSHOT = "key.screenshot"; 49 | String SMOOTH_CAMERA = "key.smoothCamera"; 50 | String FULLSCREEN = "key.fullscreen"; 51 | String TOGGLE_PERSPECTIVE = "key.togglePerspective"; 52 | } 53 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | dist: trusty 3 | language: java 4 | jdk: 5 | - oraclejdk8 6 | branches: 7 | except: 8 | - /^v[0-9]*/ 9 | notifications: 10 | email: false 11 | irc: 12 | channels: 13 | - "irc.spi.gt#hexagonmc" 14 | use_notice: true 15 | skip_join: true 16 | install: 17 | - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dbuild.number=$TRAVIS_BUILD_NUMBER -B -V 18 | after_success: 19 | # CREATE GIT TAG 20 | - git config --global user.email "builds@travis-ci.com" 21 | - git config --global user.name "Travis CI" 22 | - export GIT_TAG=v$TRAVIS_BUILD_NUMBER 23 | - echo -n $GIT_TAG > VERSION 24 | - git commit -m "Set build VERSION number" VERSION 25 | - git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" 26 | - git push --quiet https://$GITHUBKEY@github.com/dev-confidence/example-backend-api $GIT_TAG > /dev/null 2>&1 27 | deploy: 28 | provider: releases 29 | skip_cleanup: true 30 | api_key: 31 | secure: ljpg29wmo0yPs+qXBVj1vHnY4WPXB1hNMDnHMxhXbPRhK5l9kCqJWy4YjJ6BbEb4keU5dMmt+cyB+Njr3IomJMoupVu0Osut/SNz4g0UZFTYYJQjvrurdmGxoh9E7xmc6Pcly+Pw99RSpqK+yD8SDDepTleHDv/8pC0d4Z5NZIJ9JJUeY2in1RXpStj7rJtmSN5XWFpWBGpHElFQqaSDfh62zn3bvb7J9oVA+NtBDXgpY1Km1Q76Evt4PuijOgdWx4rcNpi7UOd6XurkYuo4/igBEUE8HQSEIqgC0jxJg0gxtLbymPvW4sPXmEPhZwIUvoYFjX0DvlIqU8hbr/2CPtcHiKqnqTU92wgFFnf3Xvn2mdoCrgHDOcSA2JWsR70077bPzv+llNHN17mDlGE7vIiv54jNBkJpem8OBgDNIU2lDnhwZQr3ifZJ0ydhdhkYK7Kp1lAZtEZwbqs6cetlwLiuBH6wd3dErBduPQNLnl22qdhQQJFBXPkj+vHBAt9uSB3irWWME0XsR6G9OpzDYoO64vkkHnz1k7VK37ud2pe7yKYuUr+MUbyBnzycbKOhYRufPkMv8RJIbRH6lChRrZOamqbZTa1FFYsemgcJ9NG990tE0zJHw0G3vU+emxPY35UPIMZrSbzQ8mCOlwKfhAtubZRNe+V0ohJFvVx/dhI= 32 | file: 33 | - bootstrap/target/BungeeCord.jar 34 | - module/*/target/*.jar 35 | file_glob: true 36 | on: 37 | branch: master 38 | cache: 39 | directories: 40 | - $HOME/.m2 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Note: This project is no longer maintained! Please switch to BungeeCord, Waterfall or Velocity! 2 | 3 | 4 | BungeeCord for 1.7/1.8/1.9/1.10/1.11/1.12/1.13/1.14/1.15/1.16/1.17/1.18/1.19 5 | ========== 6 | [![Build Status](https://travis-ci.org/HexagonMC/BungeeCord.svg?branch=master)](https://travis-ci.org/HexagonMC/BungeeCord) 7 | 8 | This is a fork of md_5's BungeeCord 9 | https://www.spigotmc.org/threads/1-8-1-9-bungeecord.392/ 10 | 11 | This version reimplements Minecraft 1.7.10 and basic 1.7.10 Forge support. 12 | 13 | Since release 134+, SpongePls is no longer needed when using Sponge-servers within your network! 14 | 15 | IMPORTANT: We WON'T fix any 1.7 bugs. 16 | This fork is designed for keeping your old servers in your network, until your modpacks are available for more recent mc versions. 17 | Most of them are, so get rid of 1.7 fast and move to newer modpacks asap. 18 | 19 | PLEASE: Only use this fork if really needed.(1.7 legacy servers.) If you dont need 1.7 or Sponge support, grab original BungeeCord. Link is above. 20 | 21 | 22 | ### Security warning 23 | 24 | As your Minecraft servers have to run without authentication (online-mode=false) for BungeeCord to work, this poses a new security risk. Users may connect to your servers directly, under any username they wish to use. The kick "If you wish to use IP forwarding, please enable it in your BungeeCord config as well!" does not protect your Spigot servers. 25 | 26 | To combat this, you need to restrict access to these servers for example with a firewall (please see [firewall guide](https://www.spigotmc.org/wiki/firewall-guide/)). 27 | 28 | 29 | This version is maintained by https://hexagonmc.eu 30 | 31 | ### Releases can be downloaded here: [Releases](https://github.com/HexagonMC/BungeeCord/releases) 32 | ``` 33 | Modules are automatically downloaded from the releases page. 34 | ``` 35 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/PlayerSkinConfiguration.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import net.md_5.bungee.api.SkinConfiguration; 6 | 7 | /* 8 | * Bitmask, displayed Skin Parts flags: 9 | * 10 | * Bit 0 (0x01 ): Cape enabled 11 | * Bit 1 (0x02): Jacket enabled 12 | * Bit 2 (0x04): Left Sleeve enabled 13 | * Bit 3 (0x08): Right Sleeve enabled 14 | * Bit 4 (0x10): Left Pants Leg enabled 15 | * Bit 5 (0x20): Right Pants Leg enabled 16 | * Bit 6 (0x40): Hat enabled 17 | * The most significant bit (bit 7, 0x80) appears to be unused. 18 | */ 19 | @AllArgsConstructor(access = AccessLevel.PUBLIC) 20 | public class PlayerSkinConfiguration implements SkinConfiguration 21 | { 22 | 23 | // 127 = 01111111 24 | static final SkinConfiguration SKIN_SHOW_ALL = new PlayerSkinConfiguration( (byte) 127 ); 25 | // 26 | private final byte bitmask; 27 | 28 | @Override 29 | public boolean hasCape() 30 | { 31 | return ( ( bitmask >> 0 ) & 1 ) == 1; 32 | } 33 | 34 | @Override 35 | public boolean hasJacket() 36 | { 37 | return ( ( bitmask >> 1 ) & 1 ) == 1; 38 | } 39 | 40 | @Override 41 | public boolean hasLeftSleeve() 42 | { 43 | return ( ( bitmask >> 2 ) & 1 ) == 1; 44 | } 45 | 46 | @Override 47 | public boolean hasRightSleeve() 48 | { 49 | return ( ( bitmask >> 3 ) & 1 ) == 1; 50 | } 51 | 52 | @Override 53 | public boolean hasLeftPants() 54 | { 55 | return ( ( bitmask >> 4 ) & 1 ) == 1; 56 | } 57 | 58 | @Override 59 | public boolean hasRightPants() 60 | { 61 | return ( ( bitmask >> 5 ) & 1 ) == 1; 62 | } 63 | 64 | @Override 65 | public boolean hasHat() 66 | { 67 | return ( ( bitmask >> 6 ) & 1 ) == 1; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /native/src/main/c/NativeCipherImpl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include "net_md_5_bungee_jni_cipher_NativeCipherImpl.h" 6 | 7 | // Support for CentOS 6 8 | __asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); 9 | extern "C" void *__wrap_memcpy(void *dest, const void *src, size_t n) { 10 | return memcpy(dest, src, n); 11 | } 12 | 13 | typedef unsigned char byte; 14 | 15 | struct crypto_context { 16 | int mode; 17 | mbedtls_aes_context cipher; 18 | byte *key; 19 | }; 20 | 21 | jlong JNICALL Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_init(JNIEnv* env, jobject obj, jboolean forEncryption, jbyteArray key) { 22 | jsize keyLen = env->GetArrayLength(key); 23 | jbyte *keyBytes = env->GetByteArrayElements(key, NULL); 24 | 25 | crypto_context *crypto = (crypto_context*) malloc(sizeof (crypto_context)); 26 | mbedtls_aes_init(&crypto->cipher); 27 | 28 | mbedtls_aes_setkey_enc(&crypto->cipher, (byte*) keyBytes, keyLen * 8); 29 | 30 | crypto->key = (byte*) malloc(keyLen); 31 | memcpy(crypto->key, keyBytes, keyLen); 32 | 33 | crypto->mode = (forEncryption) ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT; 34 | 35 | env->ReleaseByteArrayElements(key, keyBytes, JNI_ABORT); 36 | return (jlong) crypto; 37 | } 38 | 39 | void Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_free(JNIEnv* env, jobject obj, jlong ctx) { 40 | crypto_context *crypto = (crypto_context*) ctx; 41 | 42 | mbedtls_aes_free(&crypto->cipher); 43 | free(crypto->key); 44 | free(crypto); 45 | } 46 | 47 | void Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_cipher(JNIEnv* env, jobject obj, jlong ctx, jlong in, jlong out, jint length) { 48 | crypto_context *crypto = (crypto_context*) ctx; 49 | 50 | mbedtls_aes_crypt_cfb8(&crypto->cipher, crypto->mode, length, crypto->key, (byte*) in, (byte*) out); 51 | } 52 | -------------------------------------------------------------------------------- /module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.19-R0.1-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module 15 | 1.19-R0.1-SNAPSHOT 16 | pom 17 | 18 | BungeeCord Modules 19 | Parent project for all BungeeCord modules. 20 | 21 | 22 | cmd-alert 23 | cmd-find 24 | cmd-list 25 | cmd-send 26 | cmd-server 27 | reconnect-yaml 28 | 29 | 30 | 31 | SpigotMC 32 | true 33 | true 34 | 35 | 36 | 37 | 38 | net.md-5 39 | bungeecord-api 40 | ${project.version} 41 | compile 42 | 43 | 44 | 45 | 46 | ${project.name} 47 | 48 | 49 | true 50 | ${basedir}/src/main/resources 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionRequest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.DefinedPacket; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | @EqualsAndHashCode(callSuper = false) 16 | public class EncryptionRequest extends DefinedPacket 17 | { 18 | 19 | private String serverId; 20 | private byte[] publicKey; 21 | private byte[] verifyToken; 22 | 23 | @Override 24 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 25 | { 26 | serverId = readString( buf ); 27 | if ( protocolVersion < ProtocolConstants.MINECRAFT_1_8 ) 28 | { 29 | publicKey = readArrayLegacy( buf ); 30 | verifyToken = readArrayLegacy( buf ); 31 | } else 32 | { 33 | publicKey = readArray( buf ); 34 | verifyToken = readArray( buf ); 35 | } 36 | } 37 | 38 | @Override 39 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 40 | { 41 | writeString( serverId, buf ); 42 | if ( protocolVersion < ProtocolConstants.MINECRAFT_1_8 ) 43 | { 44 | writeArrayLegacy( publicKey, buf, false ); 45 | writeArrayLegacy( verifyToken, buf, false ); 46 | } else 47 | { 48 | writeArray( publicKey, buf ); 49 | writeArray( verifyToken, buf ); 50 | } 51 | } 52 | 53 | @Override 54 | public void handle(AbstractPacketHandler handler) throws Exception 55 | { 56 | handler.handle( this ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.JsonSerializationContext; 9 | import com.google.gson.JsonSerializer; 10 | import java.lang.reflect.Type; 11 | import java.util.UUID; 12 | import net.md_5.bungee.api.ServerPing; 13 | 14 | public class PlayerInfoSerializer implements JsonSerializer, JsonDeserializer 15 | { 16 | private final int protocol; 17 | 18 | public PlayerInfoSerializer(int protocol) 19 | { 20 | this.protocol = protocol; 21 | } 22 | 23 | @Override 24 | public ServerPing.PlayerInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException 25 | { 26 | JsonObject js = json.getAsJsonObject(); 27 | ServerPing.PlayerInfo info = new ServerPing.PlayerInfo( js.get( "name" ).getAsString(), (UUID) null ); 28 | String id = js.get( "id" ).getAsString(); 29 | if ( protocol == 4 || !id.contains( "-" ) ) 30 | { 31 | info.setId( id ); 32 | } else 33 | { 34 | info.setUniqueId( UUID.fromString( id ) ); 35 | } 36 | return info; 37 | } 38 | 39 | @Override 40 | public JsonElement serialize(ServerPing.PlayerInfo src, Type typeOfSrc, JsonSerializationContext context) 41 | { 42 | JsonObject out = new JsonObject(); 43 | out.addProperty( "name", src.getName() ); 44 | if ( protocol == 4 ) 45 | { 46 | out.addProperty( "id", src.getId() ); 47 | } else 48 | { 49 | out.addProperty( "id", src.getUniqueId().toString() ); 50 | } 51 | return out; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/zlib/NativeZlib.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.zlib; 2 | 3 | import com.google.common.base.Preconditions; 4 | import io.netty.buffer.ByteBuf; 5 | import java.util.zip.DataFormatException; 6 | import lombok.Getter; 7 | 8 | public class NativeZlib implements BungeeZlib 9 | { 10 | 11 | @Getter 12 | private final NativeCompressImpl nativeCompress = new NativeCompressImpl(); 13 | /*============================================================================*/ 14 | private boolean compress; 15 | private long ctx; 16 | 17 | @Override 18 | public void init(boolean compress, int level) 19 | { 20 | free(); 21 | 22 | this.compress = compress; 23 | this.ctx = nativeCompress.init( compress, level ); 24 | } 25 | 26 | @Override 27 | public void free() 28 | { 29 | if ( ctx != 0 ) 30 | { 31 | nativeCompress.end( ctx, compress ); 32 | ctx = 0; 33 | } 34 | 35 | nativeCompress.consumed = 0; 36 | nativeCompress.finished = false; 37 | } 38 | 39 | @Override 40 | public void process(ByteBuf in, ByteBuf out) throws DataFormatException 41 | { 42 | // Smoke tests 43 | in.memoryAddress(); 44 | out.memoryAddress(); 45 | Preconditions.checkState( ctx != 0, "Invalid pointer to compress!" ); 46 | 47 | while ( !nativeCompress.finished && ( compress || in.isReadable() ) ) 48 | { 49 | out.ensureWritable( 8192 ); 50 | 51 | int processed = nativeCompress.process( ctx, in.memoryAddress() + in.readerIndex(), in.readableBytes(), out.memoryAddress() + out.writerIndex(), out.writableBytes(), compress ); 52 | 53 | in.readerIndex( in.readerIndex() + nativeCompress.consumed ); 54 | out.writerIndex( out.writerIndex() + processed ); 55 | } 56 | 57 | nativeCompress.reset( ctx, compress ); 58 | nativeCompress.consumed = 0; 59 | nativeCompress.finished = false; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /config/src/main/java/net/md_5/bungee/config/ConfigurationProvider.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.config; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.Reader; 7 | import java.io.Writer; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | public abstract class ConfigurationProvider 12 | { 13 | 14 | private static final Map, ConfigurationProvider> providers = new HashMap<>(); 15 | 16 | static 17 | { 18 | try 19 | { 20 | providers.put( YamlConfiguration.class, new YamlConfiguration() ); 21 | } catch ( NoClassDefFoundError ex ) 22 | { 23 | // Ignore, no SnakeYAML 24 | } 25 | 26 | try 27 | { 28 | providers.put( JsonConfiguration.class, new JsonConfiguration() ); 29 | } catch ( NoClassDefFoundError ex ) 30 | { 31 | // Ignore, no Gson 32 | } 33 | } 34 | 35 | public static ConfigurationProvider getProvider(Class provider) 36 | { 37 | return providers.get( provider ); 38 | } 39 | 40 | /*------------------------------------------------------------------------*/ 41 | public abstract void save(Configuration config, File file) throws IOException; 42 | 43 | public abstract void save(Configuration config, Writer writer); 44 | 45 | public abstract Configuration load(File file) throws IOException; 46 | 47 | public abstract Configuration load(File file, Configuration defaults) throws IOException; 48 | 49 | public abstract Configuration load(Reader reader); 50 | 51 | public abstract Configuration load(Reader reader, Configuration defaults); 52 | 53 | public abstract Configuration load(InputStream is); 54 | 55 | public abstract Configuration load(InputStream is, Configuration defaults); 56 | 57 | public abstract Configuration load(String string); 58 | 59 | public abstract Configuration load(String string, Configuration defaults); 60 | } 61 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/zlib/JavaZlib.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.zlib; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import java.util.zip.DataFormatException; 5 | import java.util.zip.Deflater; 6 | import java.util.zip.Inflater; 7 | 8 | public class JavaZlib implements BungeeZlib 9 | { 10 | 11 | private final byte[] buffer = new byte[ 8192 ]; 12 | // 13 | private boolean compress; 14 | private Deflater deflater; 15 | private Inflater inflater; 16 | 17 | @Override 18 | public void init(boolean compress, int level) 19 | { 20 | this.compress = compress; 21 | free(); 22 | 23 | if ( compress ) 24 | { 25 | deflater = new Deflater( level ); 26 | } else 27 | { 28 | inflater = new Inflater(); 29 | } 30 | } 31 | 32 | @Override 33 | public void free() 34 | { 35 | if ( deflater != null ) 36 | { 37 | deflater.end(); 38 | } 39 | if ( inflater != null ) 40 | { 41 | inflater.end(); 42 | } 43 | } 44 | 45 | @Override 46 | public void process(ByteBuf in, ByteBuf out) throws DataFormatException 47 | { 48 | byte[] inData = new byte[ in.readableBytes() ]; 49 | in.readBytes( inData ); 50 | 51 | if ( compress ) 52 | { 53 | deflater.setInput( inData ); 54 | deflater.finish(); 55 | 56 | while ( !deflater.finished() ) 57 | { 58 | int count = deflater.deflate( buffer ); 59 | out.writeBytes( buffer, 0, count ); 60 | } 61 | 62 | deflater.reset(); 63 | } else 64 | { 65 | inflater.setInput( inData ); 66 | 67 | while ( !inflater.finished() && inflater.getTotalIn() < inData.length ) 68 | { 69 | int count = inflater.inflate( buffer ); 70 | out.writeBytes( buffer, 0, count ); 71 | } 72 | 73 | inflater.reset(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /log/src/main/java/net/md_5/bungee/log/BungeeLogger.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.log; 2 | 3 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 4 | import java.io.IOException; 5 | import java.util.logging.FileHandler; 6 | import java.util.logging.Level; 7 | import java.util.logging.LogRecord; 8 | import java.util.logging.Logger; 9 | import jline.console.ConsoleReader; 10 | 11 | public class BungeeLogger extends Logger 12 | { 13 | 14 | private final LogDispatcher dispatcher = new LogDispatcher( this ); 15 | 16 | // CHECKSTYLE:OFF 17 | @SuppressWarnings( 18 | { 19 | "CallToPrintStackTrace", "CallToThreadStartDuringObjectConstruction" 20 | }) 21 | // CHECKSTYLE:ON 22 | @SuppressFBWarnings("SC_START_IN_CTOR") 23 | public BungeeLogger(String loggerName, String filePattern, ConsoleReader reader) 24 | { 25 | super( loggerName, null ); 26 | setLevel( Level.ALL ); 27 | 28 | try 29 | { 30 | FileHandler fileHandler = new FileHandler( filePattern, 1 << 24, 8, true ); 31 | fileHandler.setLevel( Level.parse( System.getProperty( "net.md_5.bungee.file-log-level", "INFO" ) ) ); 32 | fileHandler.setFormatter( new ConciseFormatter( false ) ); 33 | addHandler( fileHandler ); 34 | 35 | ColouredWriter consoleHandler = new ColouredWriter( reader ); 36 | consoleHandler.setLevel( Level.parse( System.getProperty( "net.md_5.bungee.console-log-level", "INFO" ) ) ); 37 | consoleHandler.setFormatter( new ConciseFormatter( true ) ); 38 | addHandler( consoleHandler ); 39 | } catch ( IOException ex ) 40 | { 41 | System.err.println( "Could not register logger!" ); 42 | ex.printStackTrace(); 43 | } 44 | 45 | dispatcher.start(); 46 | } 47 | 48 | @Override 49 | public void log(LogRecord record) 50 | { 51 | dispatcher.queue( record ); 52 | } 53 | 54 | void doLog(LogRecord record) 55 | { 56 | super.log( record ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/SelectorComponent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | 9 | /** 10 | * This component processes a target selector into a pre-formatted set of 11 | * discovered names. 12 | *
13 | * Multiple targets may be obtained, and with commas separating each one and a 14 | * final "and" for the last target. The resulting format cannot be overwritten. 15 | * This includes all styling from team prefixes, insertions, click events, and 16 | * hover events. 17 | *
18 | * These values are filled in by the server-side implementation. 19 | *
20 | * As of 1.12.2, a bug ( MC-56373 ) prevents full usage within hover events. 21 | */ 22 | @Getter 23 | @Setter 24 | @ToString 25 | @AllArgsConstructor 26 | @EqualsAndHashCode(callSuper = true) 27 | public final class SelectorComponent extends BaseComponent 28 | { 29 | 30 | /** 31 | * An entity target selector (@p, @a, @r, @e, or @s) and, optionally, 32 | * selector arguments (e.g. @e[r=10,type=Creeper]). 33 | */ 34 | private String selector; 35 | 36 | /** 37 | * Creates a selector component from the original to clone it. 38 | * 39 | * @param original the original for the new selector component 40 | */ 41 | public SelectorComponent(SelectorComponent original) 42 | { 43 | super( original ); 44 | setSelector( original.getSelector() ); 45 | } 46 | 47 | @Override 48 | public SelectorComponent duplicate() 49 | { 50 | return new SelectorComponent( this ); 51 | } 52 | 53 | @Override 54 | protected void toPlainText(StringBuilder builder) 55 | { 56 | builder.append( this.selector ); 57 | super.toPlainText( builder ); 58 | } 59 | 60 | @Override 61 | protected void toLegacyText(StringBuilder builder) 62 | { 63 | addFormat( builder ); 64 | builder.append( this.selector ); 65 | super.toLegacyText( builder ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/chat/TranslatableComponentSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.chat; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.JsonSerializationContext; 9 | import com.google.gson.JsonSerializer; 10 | import java.lang.reflect.Type; 11 | import java.util.Arrays; 12 | import net.md_5.bungee.api.chat.BaseComponent; 13 | import net.md_5.bungee.api.chat.TranslatableComponent; 14 | 15 | public class TranslatableComponentSerializer extends BaseComponentSerializer implements JsonSerializer, JsonDeserializer 16 | { 17 | 18 | @Override 19 | public TranslatableComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException 20 | { 21 | TranslatableComponent component = new TranslatableComponent(); 22 | JsonObject object = json.getAsJsonObject(); 23 | deserialize( object, component, context ); 24 | if ( !object.has( "translate" ) ) 25 | { 26 | throw new JsonParseException( "Could not parse JSON: missing 'translate' property" ); 27 | } 28 | component.setTranslate( object.get( "translate" ).getAsString() ); 29 | if ( object.has( "with" ) ) 30 | { 31 | component.setWith( Arrays.asList( context.deserialize( object.get( "with" ), BaseComponent[].class ) ) ); 32 | } 33 | return component; 34 | } 35 | 36 | @Override 37 | public JsonElement serialize(TranslatableComponent src, Type typeOfSrc, JsonSerializationContext context) 38 | { 39 | JsonObject object = new JsonObject(); 40 | serialize( object, src, context ); 41 | object.addProperty( "translate", src.getTranslate() ); 42 | if ( src.getWith() != null ) 43 | { 44 | object.add( "with", context.serialize( src.getWith() ) ); 45 | } 46 | return object; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.forge; 2 | 3 | import java.util.regex.Pattern; 4 | import net.md_5.bungee.protocol.packet.PluginMessage; 5 | 6 | public class ForgeConstants 7 | { 8 | 9 | // Forge 10 | public static final String FORGE_REGISTER = "FORGE"; 11 | 12 | // FML 13 | public static final String FML_TAG = "FML"; 14 | public static final String FML_HANDSHAKE_TAG = "FML|HS"; 15 | public static final String FML_REGISTER = "REGISTER"; 16 | 17 | // Game profile key 18 | public static final String FML_LOGIN_PROFILE = "forgeClient"; 19 | public static final String EXTRA_DATA = "extraData"; 20 | 21 | /** 22 | * The FML 1.8 handshake token. 23 | */ 24 | public static final String FML_HANDSHAKE_TOKEN = "\0FML\0"; 25 | 26 | public static final PluginMessage FML_RESET_HANDSHAKE = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] 27 | { 28 | -2, 0 29 | }, false ); 30 | public static final PluginMessage FML_ACK = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] 31 | { 32 | -1, 0 33 | }, false ); 34 | public static final PluginMessage FML_START_CLIENT_HANDSHAKE = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] 35 | { 36 | 0, 1 37 | }, false ); 38 | public static final PluginMessage FML_START_SERVER_HANDSHAKE = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] 39 | { 40 | 1, 1 41 | }, false ); 42 | public static final PluginMessage FML_EMPTY_MOD_LIST = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] 43 | { 44 | 2, 0 45 | }, false ); 46 | 47 | /** 48 | * The minimum Forge version required to use Forge features. TODO: When the 49 | * FML branch gets pulled, update this number to be the build that includes 50 | * the change. 51 | */ 52 | public static final int FML_MIN_BUILD_VERSION = 1209; 53 | 54 | /** 55 | * Regex to use to scrape the version information from a FML handshake. 56 | */ 57 | public static final Pattern FML_HANDSHAKE_VERSION_REGEX = Pattern.compile( "(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)" ); 58 | } 59 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | import net.md_5.bungee.api.CommandSender; 7 | import net.md_5.bungee.api.ProxyServer; 8 | import net.md_5.bungee.api.connection.Connection; 9 | import net.md_5.bungee.api.plugin.Cancellable; 10 | import net.md_5.bungee.api.plugin.PluginManager; 11 | 12 | /** 13 | * Event called when a player sends a message to a server. 14 | */ 15 | @Data 16 | @ToString(callSuper = true) 17 | @EqualsAndHashCode(callSuper = true) 18 | public class ChatEvent extends TargetedEvent implements Cancellable 19 | { 20 | 21 | /** 22 | * Cancelled state. 23 | */ 24 | private boolean cancelled; 25 | /** 26 | * Text contained in this chat. 27 | */ 28 | private String message; 29 | 30 | public ChatEvent(Connection sender, Connection receiver, String message) 31 | { 32 | super( sender, receiver ); 33 | this.message = message; 34 | } 35 | 36 | /** 37 | * Checks whether this message is valid as a command 38 | * 39 | * @return if this message is a command 40 | */ 41 | public boolean isCommand() 42 | { 43 | return message.length() > 0 && message.charAt( 0 ) == '/'; 44 | } 45 | 46 | /** 47 | * Checks whether this message is run on this proxy server. 48 | * 49 | * @return if this command runs on the proxy 50 | * @see PluginManager#isExecutableCommand(java.lang.String, 51 | * net.md_5.bungee.api.CommandSender) 52 | */ 53 | public boolean isProxyCommand() 54 | { 55 | if ( !isCommand() ) 56 | { 57 | return false; 58 | } 59 | 60 | int index = message.indexOf( " " ); 61 | String commandName = ( index == -1 ) ? message.substring( 1 ) : message.substring( 1, index ); 62 | CommandSender sender = ( getSender() instanceof CommandSender ) ? (CommandSender) getSender() : null; 63 | 64 | return ProxyServer.getInstance().getPluginManager().isExecutableCommand( commandName, sender ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/LoginEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | import net.md_5.bungee.api.Callback; 9 | import net.md_5.bungee.api.chat.BaseComponent; 10 | import net.md_5.bungee.api.chat.TextComponent; 11 | import net.md_5.bungee.api.connection.PendingConnection; 12 | import net.md_5.bungee.api.plugin.Cancellable; 13 | 14 | /** 15 | * Event called to represent a player logging in. 16 | */ 17 | @Data 18 | @ToString(callSuper = false) 19 | @EqualsAndHashCode(callSuper = false) 20 | public class LoginEvent extends AsyncEvent implements Cancellable 21 | { 22 | 23 | /** 24 | * Cancelled state. 25 | */ 26 | private boolean cancelled; 27 | /** 28 | * Message to use when kicking if this event is canceled. 29 | */ 30 | @Setter(AccessLevel.NONE) 31 | private BaseComponent[] cancelReasonComponents; 32 | /** 33 | * Connection attempting to login. 34 | */ 35 | private final PendingConnection connection; 36 | 37 | public LoginEvent(PendingConnection connection, Callback done) 38 | { 39 | super( done ); 40 | this.connection = connection; 41 | } 42 | 43 | /** 44 | * @return reason to be displayed 45 | * @deprecated Use component methods instead. 46 | */ 47 | @Deprecated 48 | public String getCancelReason() 49 | { 50 | return BaseComponent.toLegacyText( getCancelReasonComponents() ); 51 | } 52 | 53 | /** 54 | * @param cancelReason reason to be displayed 55 | * @deprecated Use 56 | * {@link #setCancelReason(net.md_5.bungee.api.chat.BaseComponent...)} 57 | * instead. 58 | */ 59 | @Deprecated 60 | public void setCancelReason(String cancelReason) 61 | { 62 | setCancelReason( TextComponent.fromLegacyText( cancelReason ) ); 63 | } 64 | 65 | public void setCancelReason(BaseComponent... cancelReason) 66 | { 67 | this.cancelReasonComponents = cancelReason; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/ItemTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonDeserializer; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonParseException; 7 | import com.google.gson.JsonSerializationContext; 8 | import com.google.gson.JsonSerializer; 9 | import java.lang.reflect.Type; 10 | import lombok.AccessLevel; 11 | import lombok.Builder; 12 | import lombok.EqualsAndHashCode; 13 | import lombok.Getter; 14 | import lombok.Setter; 15 | import lombok.ToString; 16 | 17 | /** 18 | * Metadata for use in conjunction with {@link HoverEvent.Action#SHOW_ITEM} 19 | */ 20 | @Builder(builderClassName = "Builder", access = AccessLevel.PRIVATE) 21 | @ToString(of = "nbt") 22 | @EqualsAndHashCode(of = "nbt") 23 | @Setter 24 | public final class ItemTag 25 | { 26 | 27 | @Getter 28 | private final String nbt; 29 | 30 | /* 31 | TODO 32 | private BaseComponent name; 33 | @Singular("ench") 34 | private List enchantments; 35 | @Singular("lore") 36 | private List lore; 37 | private Boolean unbreakable; 38 | 39 | @RequiredArgsConstructor 40 | public static class Enchantment 41 | { 42 | 43 | private final int level; 44 | private final int id; 45 | } 46 | */ 47 | 48 | private ItemTag(String nbt) 49 | { 50 | this.nbt = nbt; 51 | } 52 | 53 | public static ItemTag ofNbt(String nbt) 54 | { 55 | return new ItemTag( nbt ); 56 | } 57 | 58 | public static class Serializer implements JsonSerializer, JsonDeserializer 59 | { 60 | 61 | @Override 62 | public ItemTag deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException 63 | { 64 | return ItemTag.ofNbt( element.getAsJsonPrimitive().getAsString() ); 65 | } 66 | 67 | @Override 68 | public JsonElement serialize(ItemTag itemTag, Type type, JsonSerializationContext context) 69 | { 70 | return context.serialize( itemTag.getNbt() ); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/ServerConnectRequest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | import lombok.NonNull; 6 | import lombok.Setter; 7 | import net.md_5.bungee.api.config.ServerInfo; 8 | import net.md_5.bungee.api.event.ServerConnectEvent; 9 | 10 | /** 11 | * A request to connect a server. 12 | */ 13 | @Getter 14 | @Builder(builderClassName = "Builder") 15 | public class ServerConnectRequest 16 | { 17 | 18 | /** 19 | * The result from this callback after request has been executed by proxy. 20 | */ 21 | public enum Result 22 | { 23 | 24 | /** 25 | * ServerConnectEvent to the new server was canceled. 26 | */ 27 | EVENT_CANCEL, 28 | /** 29 | * Already connected to target server. 30 | */ 31 | ALREADY_CONNECTED, 32 | /** 33 | * Already connecting to target server. 34 | */ 35 | ALREADY_CONNECTING, 36 | /** 37 | * Successfully connected to server. 38 | */ 39 | SUCCESS, 40 | /** 41 | * Connection failed, error can be accessed from callback method handle. 42 | */ 43 | FAIL 44 | } 45 | 46 | /** 47 | * Target server to connect to. 48 | */ 49 | @NonNull 50 | private final ServerInfo target; 51 | /** 52 | * Reason for connecting to server. 53 | */ 54 | @NonNull 55 | private final ServerConnectEvent.Reason reason; 56 | /** 57 | * Callback to execute post request. 58 | */ 59 | private final Callback callback; 60 | /** 61 | * Timeout in milliseconds for request. 62 | */ 63 | @Setter 64 | private int connectTimeout; 65 | /** 66 | * Should the player be attempted to connect to the next server in their 67 | * queue if the initial request fails. 68 | */ 69 | @Setter 70 | private boolean retry; 71 | 72 | /** 73 | * Class that sets default properties/adds methods to the lombok builder 74 | * generated class. 75 | */ 76 | public static class Builder 77 | { 78 | 79 | private int connectTimeout = ProxyServer.getInstance().getConfig().getServerConnectTimeout(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/CommandAlertRaw.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.alert; 2 | 3 | import com.google.common.base.Joiner; 4 | import net.md_5.bungee.api.ChatColor; 5 | import net.md_5.bungee.api.CommandSender; 6 | import net.md_5.bungee.api.ProxyServer; 7 | import net.md_5.bungee.api.chat.ComponentBuilder; 8 | import net.md_5.bungee.api.chat.HoverEvent; 9 | import net.md_5.bungee.api.connection.ProxiedPlayer; 10 | import net.md_5.bungee.api.plugin.Command; 11 | import net.md_5.bungee.chat.ComponentSerializer; 12 | 13 | public class CommandAlertRaw extends Command 14 | { 15 | 16 | public CommandAlertRaw() 17 | { 18 | super( "alertraw", "bungeecord.command.alert" ); 19 | } 20 | 21 | @Override 22 | public void execute(CommandSender sender, String[] args) 23 | { 24 | if ( args.length == 0 ) 25 | { 26 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "message_needed" ) ); 27 | } else 28 | { 29 | String message = Joiner.on( ' ' ).join( args ); 30 | 31 | try 32 | { 33 | ProxyServer.getInstance().broadcast( ComponentSerializer.parse( message ) ); 34 | } catch ( Exception e ) 35 | { 36 | Throwable error = e; 37 | while ( error.getCause() != null ) 38 | { 39 | error = error.getCause(); 40 | } 41 | if ( sender instanceof ProxiedPlayer ) 42 | { 43 | sender.sendMessage( new ComponentBuilder( ProxyServer.getInstance().getTranslation( "error_occurred_player" ) ) 44 | .event( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( error.getMessage() ) 45 | .color( ChatColor.RED ) 46 | .create() ) ) 47 | .create() 48 | ); 49 | } else 50 | { 51 | sender.sendMessage( ProxyServer.getInstance().getTranslation( "error_occurred_console", error.getMessage() ) ); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /proxy/src/test/java/net/md_5/bungee/ThrottleTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee; 2 | 3 | import com.google.common.base.Ticker; 4 | import java.net.InetAddress; 5 | import java.net.InetSocketAddress; 6 | import java.net.UnknownHostException; 7 | import java.util.concurrent.TimeUnit; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | 11 | public class ThrottleTest 12 | { 13 | 14 | private class FixedTicker extends Ticker 15 | { 16 | 17 | private long value; 18 | 19 | @Override 20 | public long read() 21 | { 22 | return value; 23 | } 24 | } 25 | 26 | @Test 27 | public void testThrottle() throws InterruptedException, UnknownHostException 28 | { 29 | FixedTicker ticker = new FixedTicker(); 30 | ConnectionThrottle throttle = new ConnectionThrottle( ticker, 10, 3 ); 31 | InetSocketAddress address; 32 | 33 | try 34 | { 35 | address = new InetSocketAddress( InetAddress.getLocalHost(), 0 ); 36 | } catch ( UnknownHostException ex ) 37 | { 38 | address = new InetSocketAddress( InetAddress.getByName( null ), 0 ); 39 | } 40 | 41 | Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 1 42 | Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 2 43 | Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 3 44 | Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) ); // The 3rd one must be throttled, but also increased the count to 4 45 | 46 | throttle.unthrottle( address ); // We are back at 3, next attempt will make it 4 and throttle 47 | throttle.unthrottle( address ); // Now we are at 2, will not be throttled 48 | Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 3 49 | Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) ); // 4 50 | 51 | // Now test expiration 52 | ticker.value += TimeUnit.MILLISECONDS.toNanos( 50 ); 53 | Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientCommand.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import com.google.common.base.Preconditions; 4 | import io.netty.buffer.ByteBuf; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.NoArgsConstructor; 11 | import net.md_5.bungee.protocol.AbstractPacketHandler; 12 | import net.md_5.bungee.protocol.DefinedPacket; 13 | import net.md_5.bungee.protocol.ProtocolConstants; 14 | 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @EqualsAndHashCode(callSuper = false) 19 | public class ClientCommand extends DefinedPacket 20 | { 21 | 22 | private String command; 23 | private long timestamp; 24 | private long salt; 25 | private Map signatures; 26 | private boolean signedPreview; 27 | 28 | @Override 29 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 30 | { 31 | command = readString( buf ); 32 | timestamp = buf.readLong(); 33 | salt = buf.readLong(); 34 | 35 | int cnt = readVarInt( buf ); 36 | Preconditions.checkArgument( cnt <= 8, "Too many signatures" ); 37 | signatures = new HashMap<>( cnt ); 38 | for ( int i = 0; i < cnt; i++ ) 39 | { 40 | signatures.put( readString( buf, 16 ), readArray( buf ) ); 41 | } 42 | 43 | signedPreview = buf.readBoolean(); 44 | } 45 | 46 | @Override 47 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 48 | { 49 | writeString( command, buf ); 50 | buf.writeLong( timestamp ); 51 | buf.writeLong( salt ); 52 | 53 | writeVarInt( signatures.size(), buf ); 54 | for ( Map.Entry entry : signatures.entrySet() ) 55 | { 56 | writeString( entry.getKey(), buf ); 57 | writeArray( entry.getValue(), buf ); 58 | } 59 | 60 | buf.writeBoolean( signedPreview ); 61 | } 62 | 63 | @Override 64 | public void handle(AbstractPacketHandler handler) throws Exception 65 | { 66 | handler.handle( this ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToMessageDecoder; 6 | import java.util.List; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Setter; 9 | 10 | @AllArgsConstructor 11 | public class MinecraftDecoder extends MessageToMessageDecoder 12 | { 13 | 14 | @Setter 15 | private Protocol protocol; 16 | private final boolean server; 17 | @Setter 18 | private int protocolVersion; 19 | 20 | @Override 21 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception 22 | { 23 | // See Varint21FrameDecoder for the general reasoning. We add this here as ByteToMessageDecoder#handlerRemoved() 24 | // will fire any cumulated data through the pipeline, so we want to try and stop it here. 25 | if ( !ctx.channel().isActive() ) 26 | { 27 | return; 28 | } 29 | 30 | Protocol.DirectionData prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT; 31 | ByteBuf slice = in.copy(); // Can't slice this one due to EntityMap :( 32 | 33 | try 34 | { 35 | int packetId = DefinedPacket.readVarInt( in ); 36 | 37 | DefinedPacket packet = prot.createPacket( packetId, protocolVersion ); 38 | if ( packet != null ) 39 | { 40 | packet.read( in, prot.getDirection(), protocolVersion ); 41 | 42 | if ( in.isReadable() ) 43 | { 44 | throw new BadPacketException( "Packet " + protocol + ":" + prot.getDirection() + "/" + packetId + " (" + packet.getClass().getSimpleName() + ") larger than expected, extra bytes: " + in.readableBytes() ); 45 | } 46 | } else 47 | { 48 | in.skipBytes( in.readableBytes() ); 49 | } 50 | 51 | out.add( new PacketWrapper( packet, slice ) ); 52 | slice = null; 53 | } finally 54 | { 55 | if ( slice != null ) 56 | { 57 | slice.release(); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /log/src/main/java/net/md_5/bungee/log/ConciseFormatter.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.log; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.text.DateFormat; 6 | import java.text.SimpleDateFormat; 7 | import java.util.logging.Formatter; 8 | import java.util.logging.Level; 9 | import java.util.logging.LogRecord; 10 | import lombok.RequiredArgsConstructor; 11 | import net.md_5.bungee.api.ChatColor; 12 | 13 | @RequiredArgsConstructor 14 | public class ConciseFormatter extends Formatter 15 | { 16 | 17 | private final DateFormat date = new SimpleDateFormat( System.getProperty( "net.md_5.bungee.log-date-format", "HH:mm:ss" ) ); 18 | private final boolean coloured; 19 | 20 | @Override 21 | @SuppressWarnings("ThrowableResultIgnored") 22 | public String format(LogRecord record) 23 | { 24 | StringBuilder formatted = new StringBuilder(); 25 | 26 | formatted.append( date.format( record.getMillis() ) ); 27 | formatted.append( " [" ); 28 | appendLevel( formatted, record.getLevel() ); 29 | formatted.append( "] " ); 30 | formatted.append( formatMessage( record ) ); 31 | formatted.append( '\n' ); 32 | 33 | if ( record.getThrown() != null ) 34 | { 35 | StringWriter writer = new StringWriter(); 36 | record.getThrown().printStackTrace( new PrintWriter( writer ) ); 37 | formatted.append( writer ); 38 | } 39 | 40 | return formatted.toString(); 41 | } 42 | 43 | private void appendLevel(StringBuilder builder, Level level) 44 | { 45 | if ( !coloured ) 46 | { 47 | builder.append( level.getLocalizedName() ); 48 | return; 49 | } 50 | 51 | ChatColor color; 52 | 53 | if ( level == Level.INFO ) 54 | { 55 | color = ChatColor.BLUE; 56 | } else if ( level == Level.WARNING ) 57 | { 58 | color = ChatColor.YELLOW; 59 | } else if ( level == Level.SEVERE ) 60 | { 61 | color = ChatColor.RED; 62 | } else 63 | { 64 | color = ChatColor.AQUA; 65 | } 66 | 67 | builder.append( color ).append( level.getLocalizedName() ).append( ChatColor.RESET ); 68 | } 69 | } 70 | --------------------------------------------------------------------------------