├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── dependabot.yml └── workflows │ └── maven.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── api ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ ├── Util.java │ │ ├── api │ │ ├── AbstractReconnectHandler.java │ │ ├── Callback.java │ │ ├── CommandSender.java │ │ ├── Favicon.java │ │ ├── ProxyConfig.java │ │ ├── ProxyServer.java │ │ ├── ReconnectHandler.java │ │ ├── ServerConnectRequest.java │ │ ├── ServerPing.java │ │ ├── SkinConfiguration.java │ │ ├── Title.java │ │ ├── config │ │ │ ├── ConfigurationAdapter.java │ │ │ ├── ListenerInfo.java │ │ │ └── ServerInfo.java │ │ ├── connection │ │ │ ├── ConnectedPlayer.java │ │ │ ├── Connection.java │ │ │ ├── PendingConnection.java │ │ │ ├── ProxiedPlayer.java │ │ │ └── Server.java │ │ ├── event │ │ │ ├── AsyncEvent.java │ │ │ ├── ChatEvent.java │ │ │ ├── ClientConnectEvent.java │ │ │ ├── CustomClickEvent.java │ │ │ ├── LoginEvent.java │ │ │ ├── PermissionCheckEvent.java │ │ │ ├── PlayerDisconnectEvent.java │ │ │ ├── PlayerHandshakeEvent.java │ │ │ ├── PluginMessageEvent.java │ │ │ ├── PostLoginEvent.java │ │ │ ├── PreLoginEvent.java │ │ │ ├── ProxyPingEvent.java │ │ │ ├── ProxyReloadEvent.java │ │ │ ├── ServerConnectEvent.java │ │ │ ├── ServerConnectedEvent.java │ │ │ ├── ServerDisconnectEvent.java │ │ │ ├── ServerKickEvent.java │ │ │ ├── ServerSwitchEvent.java │ │ │ ├── SettingsChangedEvent.java │ │ │ ├── TabCompleteEvent.java │ │ │ ├── TabCompleteResponseEvent.java │ │ │ └── TargetedEvent.java │ │ ├── plugin │ │ │ ├── Cancellable.java │ │ │ ├── Command.java │ │ │ ├── Event.java │ │ │ ├── LibraryLoader.java │ │ │ ├── Listener.java │ │ │ ├── Plugin.java │ │ │ ├── PluginClassloader.java │ │ │ ├── PluginDescription.java │ │ │ ├── PluginLogger.java │ │ │ ├── PluginManager.java │ │ │ └── TabExecutor.java │ │ ├── scheduler │ │ │ ├── GroupedThreadFactory.java │ │ │ ├── ScheduledTask.java │ │ │ └── TaskScheduler.java │ │ └── score │ │ │ ├── Objective.java │ │ │ ├── Position.java │ │ │ ├── Score.java │ │ │ ├── Scoreboard.java │ │ │ └── Team.java │ │ ├── command │ │ └── PlayerCommand.java │ │ └── util │ │ ├── CaseInsensitiveHashingStrategy.java │ │ ├── CaseInsensitiveMap.java │ │ └── CaseInsensitiveSet.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ ├── api │ └── ServerConnectRequestTest.java │ └── util │ ├── AddressParseTest.java │ ├── CaseInsensitiveTest.java │ └── UUIDTest.java ├── bootstrap ├── nb-configuration.xml ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── md_5 │ └── bungee │ └── Bootstrap.java ├── chat ├── nb-configuration.xml ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── md_5 │ │ └── bungee │ │ ├── api │ │ ├── ChatColor.java │ │ ├── ChatMessageType.java │ │ └── chat │ │ │ ├── BaseComponent.java │ │ │ ├── ClickEvent.java │ │ │ ├── ClickEventCustom.java │ │ │ ├── ComponentBuilder.java │ │ │ ├── ComponentStyle.java │ │ │ ├── ComponentStyleBuilder.java │ │ │ ├── HoverEvent.java │ │ │ ├── ItemTag.java │ │ │ ├── KeybindComponent.java │ │ │ ├── Keybinds.java │ │ │ ├── ScoreComponent.java │ │ │ ├── SelectorComponent.java │ │ │ ├── TextComponent.java │ │ │ ├── TranslatableComponent.java │ │ │ ├── TranslationProvider.java │ │ │ └── hover │ │ │ └── content │ │ │ ├── Content.java │ │ │ ├── Entity.java │ │ │ ├── Item.java │ │ │ └── Text.java │ │ └── chat │ │ └── TranslationRegistry.java │ └── resources │ └── mojang-translations │ ├── en_US.properties │ └── en_us.json ├── checkstyle.xml ├── config ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── config │ │ ├── Configuration.java │ │ ├── ConfigurationProvider.java │ │ ├── JsonConfiguration.java │ │ └── YamlConfiguration.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ └── config │ ├── CompoundConfigurationTest.java │ └── DefaultConfigurationTest.java ├── dialog ├── LICENSE ├── README.md ├── nb-configuration.xml ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── md_5 │ └── bungee │ └── api │ └── dialog │ ├── ConfirmationDialog.java │ ├── Dialog.java │ ├── DialogBase.java │ ├── DialogListDialog.java │ ├── MultiActionDialog.java │ ├── NoticeDialog.java │ ├── ServerLinksDialog.java │ ├── action │ ├── Action.java │ ├── ActionButton.java │ ├── CustomClickAction.java │ ├── RunCommandAction.java │ ├── StaticAction.java │ └── package-info.java │ ├── body │ ├── DialogBody.java │ ├── PlainMessageBody.java │ └── package-info.java │ ├── chat │ ├── ShowDialogClickEvent.java │ └── package-info.java │ ├── input │ ├── BooleanInput.java │ ├── DialogInput.java │ ├── InputOption.java │ ├── NumberRangeInput.java │ ├── SingleOptionInput.java │ ├── TextInput.java │ └── package-info.java │ └── package-info.java ├── event ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── event │ │ ├── EventBus.java │ │ ├── EventHandler.java │ │ ├── EventHandlerMethod.java │ │ └── EventPriority.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ └── event │ ├── EventBusTest.java │ ├── EventPriorityTest.java │ ├── SubclassTest.java │ └── UnregisteringListenerTest.java ├── log ├── nb-configuration.xml ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── md_5 │ └── bungee │ └── log │ ├── BungeeLogger.java │ ├── ColouredWriter.java │ ├── ConciseFormatter.java │ ├── LogDispatcher.java │ ├── LoggingForwardHandler.java │ └── LoggingOutputStream.java ├── module ├── cmd-alert │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── alert │ │ │ ├── CommandAlert.java │ │ │ ├── CommandAlertRaw.java │ │ │ └── PluginAlert.java │ │ └── resources │ │ └── plugin.yml ├── cmd-find │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── find │ │ │ ├── CommandFind.java │ │ │ └── PluginFind.java │ │ └── resources │ │ └── plugin.yml ├── cmd-kick │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── kick │ │ │ ├── CommandKick.java │ │ │ └── PluginKick.java │ │ └── resources │ │ └── plugin.yml ├── cmd-list │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── list │ │ │ ├── CommandList.java │ │ │ └── PluginList.java │ │ └── resources │ │ └── plugin.yml ├── cmd-send │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── send │ │ │ ├── CommandSend.java │ │ │ └── PluginSend.java │ │ └── resources │ │ └── plugin.yml ├── cmd-server │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── module │ │ │ └── cmd │ │ │ └── server │ │ │ ├── CommandServer.java │ │ │ └── PluginServer.java │ │ └── resources │ │ └── plugin.yml ├── pom.xml └── reconnect-yaml │ ├── nb-configuration.xml │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── module │ │ └── reconnect │ │ └── yaml │ │ ├── PluginYaml.java │ │ └── YamlReconnectHandler.java │ └── resources │ └── plugin.yml ├── native ├── compile-native-arm.sh ├── compile-native.sh ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ ├── c │ │ ├── NativeCipherImpl.c │ │ ├── NativeCompressImpl.c │ │ ├── cpuid_helper.h │ │ ├── mbedtls_custom_config.h │ │ ├── net_md_5_bungee_jni_cipher_NativeCipherImpl.h │ │ ├── net_md_5_bungee_jni_zlib_NativeCompressImpl.h │ │ ├── shared.c │ │ └── shared.h │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ └── jni │ │ │ ├── NativeCode.java │ │ │ ├── NativeCodeException.java │ │ │ ├── cipher │ │ │ ├── BungeeCipher.java │ │ │ ├── JavaCipher.java │ │ │ ├── NativeCipher.java │ │ │ └── NativeCipherImpl.java │ │ │ └── zlib │ │ │ ├── BungeeZlib.java │ │ │ ├── JavaZlib.java │ │ │ ├── NativeCompressImpl.java │ │ │ └── NativeZlib.java │ └── resources │ │ ├── native-cipher-arm.so │ │ ├── native-cipher.so │ │ ├── native-compress-arm.so │ │ └── native-compress.so │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ ├── NativeCipherTest.java │ └── NativeZlibTest.java ├── nb-configuration.xml ├── nbt ├── LICENSE ├── README.md ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── nbt │ │ ├── NamedTag.java │ │ ├── Tag.java │ │ ├── TypedTag.java │ │ ├── exception │ │ ├── NBTException.java │ │ ├── NBTFormatException.java │ │ └── NBTLimitException.java │ │ ├── limit │ │ └── NBTLimiter.java │ │ └── type │ │ ├── ByteArrayTag.java │ │ ├── ByteTag.java │ │ ├── CompoundTag.java │ │ ├── DoubleTag.java │ │ ├── EndTag.java │ │ ├── FloatTag.java │ │ ├── IntArrayTag.java │ │ ├── IntTag.java │ │ ├── ListTag.java │ │ ├── LongArrayTag.java │ │ ├── LongTag.java │ │ ├── ShortTag.java │ │ └── StringTag.java │ └── test │ ├── java │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── nbt │ │ ├── NBTLimiterTest.java │ │ ├── NBTTagTest.java │ │ └── PlayerDataTest.java │ └── resources │ └── playerdata.nbt ├── pom.xml ├── protocol ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ └── protocol │ │ ├── AbstractPacketHandler.java │ │ ├── BadPacketException.java │ │ ├── ChatChain.java │ │ ├── ChatSerializer.java │ │ ├── DefinedPacket.java │ │ ├── Either.java │ │ ├── KickStringWriter.java │ │ ├── LegacyDecoder.java │ │ ├── Location.java │ │ ├── MinecraftDecoder.java │ │ ├── MinecraftEncoder.java │ │ ├── NumberFormat.java │ │ ├── OverflowPacketException.java │ │ ├── PacketWrapper.java │ │ ├── PlayerPublicKey.java │ │ ├── Property.java │ │ ├── Protocol.java │ │ ├── ProtocolConstants.java │ │ ├── SeenMessages.java │ │ ├── TagUtil.java │ │ ├── Varint21FrameDecoder.java │ │ ├── channel │ │ ├── BungeeChannelInitializer.java │ │ └── ChannelAcceptor.java │ │ └── packet │ │ ├── BossBar.java │ │ ├── Chat.java │ │ ├── ClearDialog.java │ │ ├── ClearTitles.java │ │ ├── ClientChat.java │ │ ├── ClientCommand.java │ │ ├── ClientSettings.java │ │ ├── ClientStatus.java │ │ ├── Commands.java │ │ ├── CookieRequest.java │ │ ├── CookieResponse.java │ │ ├── CustomClickAction.java │ │ ├── DisconnectReportDetails.java │ │ ├── EncryptionRequest.java │ │ ├── EncryptionResponse.java │ │ ├── EntityStatus.java │ │ ├── FinishConfiguration.java │ │ ├── GameState.java │ │ ├── Handshake.java │ │ ├── KeepAlive.java │ │ ├── Kick.java │ │ ├── LegacyHandshake.java │ │ ├── LegacyPing.java │ │ ├── Login.java │ │ ├── LoginAcknowledged.java │ │ ├── LoginPayloadRequest.java │ │ ├── LoginPayloadResponse.java │ │ ├── LoginRequest.java │ │ ├── LoginSuccess.java │ │ ├── PingPacket.java │ │ ├── PlayerListHeaderFooter.java │ │ ├── PlayerListItem.java │ │ ├── PlayerListItemRemove.java │ │ ├── PlayerListItemUpdate.java │ │ ├── PluginMessage.java │ │ ├── Respawn.java │ │ ├── ScoreboardDisplay.java │ │ ├── ScoreboardObjective.java │ │ ├── ScoreboardScore.java │ │ ├── ScoreboardScoreReset.java │ │ ├── ServerData.java │ │ ├── ServerLinks.java │ │ ├── SetCompression.java │ │ ├── ShowDialog.java │ │ ├── ShowDialogDirect.java │ │ ├── StartConfiguration.java │ │ ├── StatusRequest.java │ │ ├── StatusResponse.java │ │ ├── StoreCookie.java │ │ ├── Subtitle.java │ │ ├── SystemChat.java │ │ ├── TabCompleteRequest.java │ │ ├── TabCompleteResponse.java │ │ ├── Team.java │ │ ├── Title.java │ │ ├── TitleTimes.java │ │ ├── Transfer.java │ │ ├── UnsignedClientCommand.java │ │ └── ViewDistance.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ └── protocol │ ├── TagUtilTest.java │ └── packet │ └── PluginMessageTest.java ├── proxy ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── md_5 │ │ │ └── bungee │ │ │ ├── BungeeCord.java │ │ │ ├── BungeeCordLauncher.java │ │ │ ├── BungeeServerInfo.java │ │ │ ├── BungeeTitle.java │ │ │ ├── ConnectionThrottle.java │ │ │ ├── EncryptionUtil.java │ │ │ ├── Metrics.java │ │ │ ├── PlayerInfoSerializer.java │ │ │ ├── PlayerSkinConfiguration.java │ │ │ ├── ServerConnection.java │ │ │ ├── ServerConnector.java │ │ │ ├── UserConnection.java │ │ │ ├── command │ │ │ ├── CommandBungee.java │ │ │ ├── CommandEnd.java │ │ │ ├── CommandIP.java │ │ │ ├── CommandPerms.java │ │ │ ├── CommandReload.java │ │ │ ├── ConsoleCommandCompleter.java │ │ │ └── ConsoleCommandSender.java │ │ │ ├── compress │ │ │ ├── CompressFactory.java │ │ │ └── PacketDecompressor.java │ │ │ ├── conf │ │ │ ├── Configuration.java │ │ │ └── YamlConfig.java │ │ │ ├── connection │ │ │ ├── CancelSendSignal.java │ │ │ ├── DownstreamBridge.java │ │ │ ├── InitialHandler.java │ │ │ ├── LoginResult.java │ │ │ ├── PingHandler.java │ │ │ └── UpstreamBridge.java │ │ │ ├── entitymap │ │ │ ├── EntityMap.java │ │ │ ├── EntityMap_1_10.java │ │ │ ├── EntityMap_1_11.java │ │ │ ├── EntityMap_1_12.java │ │ │ ├── EntityMap_1_12_1.java │ │ │ ├── EntityMap_1_13.java │ │ │ ├── EntityMap_1_14.java │ │ │ ├── EntityMap_1_15.java │ │ │ ├── EntityMap_1_16.java │ │ │ ├── EntityMap_1_16_2.java │ │ │ ├── EntityMap_1_8.java │ │ │ ├── EntityMap_1_9.java │ │ │ └── EntityMap_1_9_4.java │ │ │ ├── forge │ │ │ ├── ForgeClientHandler.java │ │ │ ├── ForgeClientHandshakeState.java │ │ │ ├── ForgeConstants.java │ │ │ ├── ForgeLogger.java │ │ │ ├── ForgeServerHandler.java │ │ │ ├── ForgeServerHandshakeState.java │ │ │ ├── ForgeUtils.java │ │ │ ├── IForgeClientPacketHandler.java │ │ │ └── IForgeServerPacketHandler.java │ │ │ ├── http │ │ │ ├── HttpClient.java │ │ │ ├── HttpHandler.java │ │ │ └── HttpInitializer.java │ │ │ ├── module │ │ │ ├── JenkinsModuleSource.java │ │ │ ├── ModuleManager.java │ │ │ ├── ModuleSource.java │ │ │ ├── ModuleSpec.java │ │ │ └── ModuleVersion.java │ │ │ ├── netty │ │ │ ├── ChannelWrapper.java │ │ │ ├── HandlerBoss.java │ │ │ ├── LengthPrependerAndCompressor.java │ │ │ ├── PacketHandler.java │ │ │ ├── PipelineUtils.java │ │ │ └── cipher │ │ │ │ ├── CipherDecoder.java │ │ │ │ └── CipherEncoder.java │ │ │ ├── scheduler │ │ │ ├── BungeeScheduler.java │ │ │ └── BungeeTask.java │ │ │ ├── tab │ │ │ ├── ServerUnique.java │ │ │ └── TabList.java │ │ │ └── util │ │ │ ├── AddressUtil.java │ │ │ ├── AllowedCharacters.java │ │ │ ├── BufUtil.java │ │ │ ├── ChatComponentTransformer.java │ │ │ ├── PacketLimiter.java │ │ │ └── QuietException.java │ └── resources │ │ ├── messages.properties │ │ └── yggdrasil_session_pubkey.der │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ ├── ThrottleTest.java │ ├── api │ └── plugin │ │ └── DummyPlugin.java │ ├── scheduler │ └── SchedulerTest.java │ └── util │ └── AddressUtilTest.java ├── query ├── nb-configuration.xml ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── md_5 │ └── bungee │ └── query │ ├── QueryHandler.java │ └── RemoteQuery.java ├── serializer ├── nb-configuration.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── net │ │ └── md_5 │ │ └── bungee │ │ ├── api │ │ └── chat │ │ │ └── hover │ │ │ └── content │ │ │ ├── EntitySerializer.java │ │ │ ├── ItemSerializer.java │ │ │ └── TextSerializer.java │ │ ├── chat │ │ ├── BaseComponentSerializer.java │ │ ├── ChatVersion.java │ │ ├── ClickEventSerializer.java │ │ ├── ComponentSerializer.java │ │ ├── ComponentStyleSerializer.java │ │ ├── KeybindComponentSerializer.java │ │ ├── ScoreComponentSerializer.java │ │ ├── SelectorComponentSerializer.java │ │ ├── TextComponentSerializer.java │ │ ├── TranslatableComponentSerializer.java │ │ └── VersionedComponentSerializer.java │ │ └── serializer │ │ └── dialog │ │ ├── DialogActionSerializer.java │ │ ├── DialogSerializer.java │ │ └── ShowDialogClickEventSerializer.java │ └── test │ └── java │ └── net │ └── md_5 │ └── bungee │ ├── api │ └── chat │ │ ├── ComponentsTest.java │ │ └── TranslatableComponentTest.java │ └── dialog │ └── SimpleTest.java └── slf4j ├── nb-configuration.xml ├── pom.xml └── src └── main ├── java └── org │ └── slf4j │ └── jul │ ├── JDK14LoggerAdapter.java │ ├── JDK14LoggerFactory.java │ └── JULServiceProvider.java └── resources └── META-INF └── services └── org.slf4j.spi.SLF4JServiceProvider /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Configuration help 4 | url: https://www.spigotmc.org/forums/bungeecord-help.70/create-thread 5 | about: Help for configuring bungeecord will only be answered in spigotmc.org forums. 6 | - name: I have a problem with a bungee plugin 7 | url: https://www.spigotmc.org/forums/bungeecord-plugin-help.71/create-thread 8 | about: Help about plugins can be recieved in spigotmc.org forums. 9 | - name: Questions and discussions 10 | url: https://www.spigotmc.org/forums/bungeecord-discussion.21/create-thread 11 | about: spigotmc.org forums are the best place to ask your questions regarding bungeecord. 12 | - name: Plugin creation help 13 | url: https://www.spigotmc.org/forums/bungeecord-plugin-development.23/create-thread 14 | about: Plugin creation help for bungee plugins can be recieved in spigotmc.org forums. 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest a feature which bungeecord should include. 3 | body: 4 | - type: textarea 5 | id: the-feature 6 | attributes: 7 | label: Feature description 8 | description: Please describe your feature or improvement. Please include **details**. 9 | validations: 10 | required: true 11 | - type: textarea 12 | id: goal 13 | attributes: 14 | label: Goal of the feature 15 | description: What is the goal of your feature? 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: alternatives 20 | attributes: 21 | label: Unfitting alternatives 22 | description: What alternatives have you considered and why are they not sufficient for your use case? 23 | validations: 24 | required: true 25 | - type: checkboxes 26 | id: checkboxes 27 | attributes: 28 | label: Checking 29 | options: 30 | - label: This is not a question or plugin creation help request. 31 | required: true 32 | - label: This is a **feature or improvement request**. 33 | required: true 34 | - label: I have not read these checkboxes and therefore I just ticked them all. 35 | - label: I did not use this form to report a bug. 36 | required: true 37 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "maven" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | open-pull-requests-limit: 50 9 | ignore: 10 | # Synchronised with Minecraft 11 | - dependency-name: "com.google.code.gson:gson" 12 | # 9.x has performance issues (see, eg, checkstyle/checkstyle#10934) and 10.x is incompatible 13 | - dependency-name: "com.puppycrawl.tools:checkstyle" 14 | # Newer versions have issues, see #1909 and #2050 15 | - dependency-name: "jline:jline" 16 | # Needs to be synchronised with maven-resolver-provider dependencies 17 | - dependency-name: "org.apache.maven.resolver:maven-resolver-connector-basic" 18 | - dependency-name: "org.apache.maven.resolver:maven-resolver-transport-http" 19 | # Used with maven-resolver dependencies; 2.0 update breaks other providers 20 | - dependency-name: "org.slf4j:slf4j-api" 21 | update-types: ["version-update:semver-major"] 22 | 23 | - package-ecosystem: "github-actions" 24 | directory: "/" 25 | schedule: 26 | interval: "daily" 27 | open-pull-requests-limit: 50 28 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Maven Build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-24.04 8 | 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | java: [8, 11, 17, 21, 25-ea] 13 | 14 | name: Java ${{ matrix.java }} 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: actions/setup-java@v4 19 | with: 20 | distribution: zulu 21 | java-version: ${{ matrix.java }} 22 | - run: java -version && mvn --version 23 | - run: mvn --activate-profiles dist --no-transfer-progress package 24 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BungeeCord 2 | ========== 3 | Layer 7 proxy designed to link Minecraft servers. 4 | -------------------------------------------------- 5 | 6 | BungeeCord is a sophisticated proxy and API designed mainly to teleport players between multiple Minecraft servers. It is the latest incarnation of similar software written by the author from 2011-present. 7 | 8 | Information 9 | ----------- 10 | BungeeCord is maintained by [SpigotMC](https://www.spigotmc.org/) and has its own [discussion thread](https://www.spigotmc.org/go/bungeecord) with plenty of helpful information and links. 11 | 12 | ### Security warning 13 | 14 | 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. 15 | 16 | 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/)). 17 | 18 | Source 19 | ------ 20 | Source code is currently available on [GitHub](https://www.spigotmc.org/go/bungeecord-git). 21 | 22 | Binaries 23 | -------- 24 | Precompiled binaries are available for end users on [Jenkins](https://www.spigotmc.org/go/bungeecord-dl). 25 | 26 | (c) 2012-2025 SpigotMC Pty. Ltd. 27 | -------------------------------------------------------------------------------- /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 | String forced = ( con.getVirtualHost() == null ) ? null : con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() ); 32 | 33 | if ( forced == null && con.getListener().isForceDefault() ) 34 | { 35 | forced = con.getListener().getDefaultServer(); 36 | } 37 | return ( forced == null ) ? null : ProxyServer.getInstance().getServerInfo( forced ); 38 | } 39 | 40 | protected abstract ServerInfo getStoredServer(ProxiedPlayer player); 41 | } 42 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/api/event/CustomClickEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.event; 2 | 3 | import com.google.gson.JsonElement; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.ToString; 7 | import net.md_5.bungee.api.connection.ProxiedPlayer; 8 | import net.md_5.bungee.api.plugin.Cancellable; 9 | import net.md_5.bungee.api.plugin.Event; 10 | import org.jetbrains.annotations.ApiStatus; 11 | 12 | /** 13 | * Called after a {@link ProxiedPlayer} runs a custom action from a chat event 14 | * or form submission. 15 | */ 16 | @Data 17 | @ToString(callSuper = false) 18 | @EqualsAndHashCode(callSuper = false) 19 | @ApiStatus.Experimental 20 | public class CustomClickEvent extends Event implements Cancellable 21 | { 22 | 23 | /** 24 | * Player who clicked. 25 | */ 26 | private final ProxiedPlayer player; 27 | /** 28 | * Custom action ID. 29 | */ 30 | private final String id; 31 | /** 32 | * The data as submitted. 33 | */ 34 | private final JsonElement data; 35 | /** 36 | * Cancelled state. 37 | */ 38 | private boolean cancelled; 39 | } 40 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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.Callback; 7 | import net.md_5.bungee.api.config.ServerInfo; 8 | import net.md_5.bungee.api.connection.ProxiedPlayer; 9 | 10 | /** 11 | * Event called as soon as a connection has a {@link ProxiedPlayer} and is ready 12 | * to be connected to a server. 13 | */ 14 | @Data 15 | @ToString(callSuper = false) 16 | @EqualsAndHashCode(callSuper = false) 17 | public class PostLoginEvent extends AsyncEvent 18 | { 19 | 20 | /** 21 | * The player involved with this event. 22 | */ 23 | private final ProxiedPlayer player; 24 | /** 25 | * The server to which the player will initially be connected. 26 | */ 27 | private ServerInfo target; 28 | 29 | public PostLoginEvent(ProxiedPlayer player, ServerInfo target, Callback done) 30 | { 31 | super( done ); 32 | this.player = player; 33 | this.target = target; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /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 queried for status 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 | -------------------------------------------------------------------------------- /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 lombok.ToString; 7 | import net.md_5.bungee.api.CommandSender; 8 | import net.md_5.bungee.api.plugin.Event; 9 | 10 | /** 11 | * Called when somebody reloads BungeeCord 12 | */ 13 | @Getter 14 | @ToString(callSuper = false) 15 | @AllArgsConstructor 16 | @EqualsAndHashCode(callSuper = false) 17 | public class ProxyReloadEvent extends Event 18 | { 19 | 20 | /** 21 | * Creator of the action. 22 | */ 23 | private final CommandSender sender; 24 | } 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | /** 13 | * Called when the player is disconnected from a server, for example during 14 | * server switching. 15 | * 16 | * If the player is kicked from a server, {@link ServerKickEvent} will be called 17 | * instead. 18 | */ 19 | @Data 20 | @AllArgsConstructor 21 | @ToString(callSuper = false) 22 | @EqualsAndHashCode(callSuper = false) 23 | public class ServerDisconnectEvent extends Event 24 | { 25 | 26 | /** 27 | * Player disconnecting from a server. 28 | */ 29 | @NonNull 30 | private final ProxiedPlayer player; 31 | /** 32 | * Server the player is disconnecting from. 33 | */ 34 | @NonNull 35 | private final ServerInfo target; 36 | } 37 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/util/CaseInsensitiveHashingStrategy.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import it.unimi.dsi.fastutil.Hash; 4 | import java.util.Locale; 5 | 6 | class CaseInsensitiveHashingStrategy implements Hash.Strategy 7 | { 8 | 9 | static final CaseInsensitiveHashingStrategy INSTANCE = new CaseInsensitiveHashingStrategy(); 10 | 11 | @Override 12 | public int hashCode(String object) 13 | { 14 | if ( object == null ) 15 | { 16 | return 0; 17 | } 18 | 19 | return object.toLowerCase( Locale.ROOT ).hashCode(); 20 | } 21 | 22 | @Override 23 | public boolean equals(String o1, String o2) 24 | { 25 | if ( o1 == o2 ) 26 | { 27 | return true; 28 | } 29 | 30 | if ( o1 == null || o2 == null ) 31 | { 32 | return false; 33 | } 34 | 35 | return o1.equals( o2 ) || o1.toLowerCase( Locale.ROOT ).equals( o2.toLowerCase( Locale.ROOT ) ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/util/CaseInsensitiveMap.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; 4 | import java.util.Map; 5 | 6 | public class CaseInsensitiveMap extends Object2ObjectOpenCustomHashMap 7 | { 8 | 9 | public CaseInsensitiveMap() 10 | { 11 | super( CaseInsensitiveHashingStrategy.INSTANCE ); 12 | } 13 | 14 | public CaseInsensitiveMap(Map map) 15 | { 16 | super( map, CaseInsensitiveHashingStrategy.INSTANCE ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/net/md_5/bungee/util/CaseInsensitiveSet.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; 4 | import java.util.Collection; 5 | 6 | public class CaseInsensitiveSet extends ObjectOpenCustomHashSet 7 | { 8 | 9 | public CaseInsensitiveSet() 10 | { 11 | super( CaseInsensitiveHashingStrategy.INSTANCE ); 12 | } 13 | 14 | public CaseInsensitiveSet(Collection collection) 15 | { 16 | super( collection, CaseInsensitiveHashingStrategy.INSTANCE ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/src/test/java/net/md_5/bungee/util/CaseInsensitiveTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import org.junit.jupiter.api.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 | assertTrue( map.containsKey( "foo" ) ); // Assert that contains is case insensitive 17 | 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 | assertFalse( map.containsKey( "foo" ) ); 22 | } 23 | 24 | @Test 25 | public void testSets() 26 | { 27 | CaseInsensitiveSet set = new CaseInsensitiveSet(); 28 | 29 | set.add( "FOO" ); 30 | assertTrue( set.contains( "foo" ) ); // Assert that contains is case insensitive 31 | set.remove( "FoO" ); 32 | assertFalse( set.contains( "foo" ) ); // Assert that remove is case insensitive 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /api/src/test/java/net/md_5/bungee/util/UUIDTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import java.util.UUID; 5 | import net.md_5.bungee.Util; 6 | import org.junit.jupiter.api.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 | 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 | assertEquals( expected, actual, "Could not parse UUID " + expected ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /chat/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-chat 15 | 1.21-R0.3-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.11.0 26 | compile 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/ClickEventCustom.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.ToString; 6 | 7 | /** 8 | * Click event which sends a custom payload to the server. 9 | */ 10 | @Data 11 | @ToString(callSuper = true) 12 | @EqualsAndHashCode(callSuper = true) 13 | public class ClickEventCustom extends ClickEvent 14 | { 15 | 16 | /** 17 | * The custom payload. 18 | */ 19 | private final String payload; 20 | 21 | /** 22 | * @param id identifier for the event (lower case, no special characters) 23 | * @param payload custom payload 24 | */ 25 | public ClickEventCustom(String id, String payload) 26 | { 27 | super( ClickEvent.Action.CUSTOM, id ); 28 | this.payload = payload; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /chat/src/main/java/net/md_5/bungee/api/chat/TranslationProvider.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.chat; 2 | 3 | /** 4 | * An object capable of being translated by the client in a 5 | * {@link TranslatableComponent}. 6 | */ 7 | public interface TranslationProvider 8 | { 9 | 10 | /** 11 | * Get the translation key. 12 | * 13 | * @return the translation key 14 | */ 15 | String getTranslationKey(); 16 | 17 | /** 18 | * Get this translatable object as a {@link TranslatableComponent}. 19 | * 20 | * @return the translatable component 21 | */ 22 | default TranslatableComponent asTranslatableComponent() 23 | { 24 | return asTranslatableComponent( (Object[]) null ); 25 | } 26 | 27 | /** 28 | * Get this translatable object as a {@link TranslatableComponent}. 29 | * 30 | * @param with the {@link String Strings} and 31 | * {@link BaseComponent BaseComponents} to use in the translation 32 | * @return the translatable component 33 | */ 34 | default TranslatableComponent asTranslatableComponent(Object... with) 35 | { 36 | return new TranslatableComponent( this, with ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-config 15 | 1.21-R0.3-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.11.0 26 | compile 27 | true 28 | 29 | 30 | org.yaml 31 | snakeyaml 32 | 2.2 33 | compile 34 | true 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /config/src/test/java/net/md_5/bungee/config/DefaultConfigurationTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.config; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import org.junit.jupiter.api.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 | assertEquals( 10, actualConfig.getInt( "setting" ) ); 20 | assertEquals( 11, actualConfig.getInt( "nested.setting" ) ); 21 | assertEquals( 12, actualConfig.getInt( "double.nested.setting" ) ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dialog/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2025, SpigotMC Pty. Ltd. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 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 ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /dialog/README.md: -------------------------------------------------------------------------------- 1 | BungeeCord-Dialog 2 | ================= 3 | 4 | Highly experimental API, subject to breakage. All contributions welcome, including major refactors/design changes. 5 | 6 | Sample Plugin 7 | ------------- 8 | 9 | ```java 10 | private class TestCommand extends Command 11 | { 12 | 13 | public TestCommand() 14 | { 15 | super( "btest" ); 16 | } 17 | 18 | @Override 19 | public void execute(CommandSender sender, String[] args) 20 | { 21 | ProxiedPlayer player = (ProxiedPlayer) sender; 22 | 23 | Dialog notice = new NoticeDialog( new DialogBase( new ComponentBuilder( "Hello" ).color( ChatColor.RED ).build() ) ); 24 | player.showDialog( notice ); 25 | 26 | notice = new NoticeDialog( 27 | new DialogBase( new ComponentBuilder( "Hello" ).color( ChatColor.RED ).build() ) 28 | .inputs( 29 | Arrays.asList( new TextInput( "first", new ComponentBuilder( "First" ).build() ), 30 | new TextInput( "second", new ComponentBuilder( "Second" ).build() ) 31 | ) 32 | ) ) 33 | .action( new ActionButton( new ComponentBuilder( "Submit Button" ).build(), new CustomClickAction( "customform" ) ) ); 34 | 35 | player.sendMessage( new ComponentBuilder( "click me" ).event( new ShowDialogClickEvent( notice ) ).build() ); 36 | } 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /dialog/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-dialog 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Dialog 19 | Minecraft dialog API intended for use with BungeeCord 20 | 21 | 22 | BSD-3-Clause 23 | https://github.com/SpigotMC/BungeeCord/blob/master/dialog/LICENSE 24 | repo 25 | 26 | 27 | 28 | 29 | 30 | net.md-5 31 | bungeecord-chat 32 | ${project.version} 33 | compile 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/ConfirmationDialog.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NonNull; 7 | import lombok.ToString; 8 | import lombok.experimental.Accessors; 9 | import net.md_5.bungee.api.dialog.action.ActionButton; 10 | 11 | /** 12 | * Represents a simple dialog with text and two actions at the bottom (default: 13 | * "yes", "no"). 14 | */ 15 | @Data 16 | @ToString 17 | @EqualsAndHashCode 18 | @AllArgsConstructor 19 | @Accessors(fluent = true) 20 | public final class ConfirmationDialog implements Dialog 21 | { 22 | 23 | @NonNull 24 | @Accessors(fluent = false) 25 | private DialogBase base; 26 | /** 27 | * The "yes" click action / bottom (appears on the left). 28 | */ 29 | private ActionButton yes; 30 | /** 31 | * The "no" click action / bottom (appears on the right). 32 | */ 33 | private ActionButton no; 34 | 35 | public ConfirmationDialog(@NonNull DialogBase base) 36 | { 37 | this( base, null, null ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/Dialog.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog; 2 | 3 | import org.jetbrains.annotations.ApiStatus; 4 | 5 | /** 6 | * Represents a dialog GUI. 7 | */ 8 | public interface Dialog 9 | { 10 | 11 | /** 12 | * Gets the dialog base which contains the dialog title and other options 13 | * common to all types of dialogs. 14 | * 15 | * @return mutable reference to the dialog base 16 | */ 17 | DialogBase getBase(); 18 | 19 | /** 20 | * Sets the dialog base. 21 | *
22 | * For internal use only as this is mandatory and should be specified in the 23 | * constructor. 24 | * 25 | * @param base the new dialog base 26 | */ 27 | @ApiStatus.Internal 28 | void setBase(DialogBase base); 29 | } 30 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/NoticeDialog.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NonNull; 7 | import lombok.ToString; 8 | import lombok.experimental.Accessors; 9 | import net.md_5.bungee.api.dialog.action.ActionButton; 10 | 11 | /** 12 | * Represents a simple dialog with text and one action at the bottom (default: 13 | * "OK"). 14 | */ 15 | @Data 16 | @ToString 17 | @EqualsAndHashCode 18 | @AllArgsConstructor 19 | @Accessors(fluent = true) 20 | public final class NoticeDialog implements Dialog 21 | { 22 | 23 | @NonNull 24 | @Accessors(fluent = false) 25 | private DialogBase base; 26 | /** 27 | * The "OK" action button for the dialog. 28 | */ 29 | private ActionButton action; 30 | 31 | public NoticeDialog(DialogBase base) 32 | { 33 | this( base, null ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/action/Action.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.action; 2 | 3 | public interface Action 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/action/ActionButton.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.action; 2 | 3 | import com.google.common.base.Preconditions; 4 | import lombok.Data; 5 | import lombok.NonNull; 6 | import lombok.experimental.Accessors; 7 | import net.md_5.bungee.api.chat.BaseComponent; 8 | 9 | /** 10 | * Represents a dialog action which will usually appear as a button. 11 | */ 12 | @Data 13 | @Accessors(fluent = true) 14 | public class ActionButton 15 | { 16 | 17 | /** 18 | * The text label of the button, mandatory. 19 | */ 20 | @NonNull 21 | private BaseComponent label; 22 | /** 23 | * The hover tooltip of the button. 24 | */ 25 | private BaseComponent tooltip; 26 | /** 27 | * The width of the button (default: 150, minimum: 1, maximum: 1024). 28 | */ 29 | private Integer width; 30 | /** 31 | * The action to take. 32 | */ 33 | @NonNull 34 | private Action action; 35 | 36 | public ActionButton(@NonNull BaseComponent label, BaseComponent tooltip, Integer width, @NonNull Action action) 37 | { 38 | this.label = label; 39 | this.tooltip = tooltip; 40 | setWidth( width ); 41 | this.action = action; 42 | } 43 | 44 | public ActionButton(@NonNull BaseComponent label, @NonNull Action action) 45 | { 46 | this( label, null, null, action ); 47 | } 48 | 49 | public void setWidth(Integer width) 50 | { 51 | Preconditions.checkArgument( width == null || ( width >= 1 && width <= 1024 ), "width must be between 1 and 1024" ); 52 | this.width = width; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/action/CustomClickAction.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.action; 2 | 3 | import com.google.gson.JsonElement; 4 | import lombok.Data; 5 | import lombok.NonNull; 6 | import lombok.ToString; 7 | import lombok.experimental.Accessors; 8 | 9 | /** 10 | * Submits the dialog with the given ID and values as a payload. 11 | */ 12 | @Data 13 | @Accessors(fluent = true) 14 | @ToString(callSuper = true) 15 | public class CustomClickAction implements Action 16 | { 17 | 18 | /** 19 | * The namespaced key of the submission. 20 | */ 21 | @NonNull 22 | private String id; 23 | /** 24 | * Fields to be added to the submission payload. 25 | */ 26 | private JsonElement additions; 27 | } 28 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/action/RunCommandAction.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.action; 2 | 3 | import lombok.Data; 4 | import lombok.NonNull; 5 | import lombok.ToString; 6 | import lombok.experimental.Accessors; 7 | 8 | /** 9 | * Executes a command. If the command requires a permission 10 | * higher than 0, a confirmation dialog will be shown by the client. 11 | */ 12 | @Data 13 | @Accessors(fluent = true) 14 | @ToString(callSuper = true) 15 | public class RunCommandAction implements Action 16 | { 17 | 18 | /** 19 | * The template to be applied, where variables of the form 20 | * $(key) will be replaced by their 21 | * {@link net.md_5.bungee.api.dialog.input.DialogInput#key} value. 22 | */ 23 | @NonNull 24 | private String template; 25 | } 26 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/action/StaticAction.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.action; 2 | 3 | import lombok.Data; 4 | import lombok.NonNull; 5 | import lombok.ToString; 6 | import lombok.experimental.Accessors; 7 | import net.md_5.bungee.api.chat.ClickEvent; 8 | 9 | /** 10 | * Represents a static dialog action. 11 | */ 12 | @Data 13 | @Accessors(fluent = true) 14 | @ToString(callSuper = true) 15 | public class StaticAction implements Action 16 | { 17 | 18 | @NonNull 19 | private ClickEvent clickEvent; 20 | } 21 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/action/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains the different actions/buttons for a {@link net.md_5.bungee.api.dialog.Dialog}. 3 | */ 4 | package net.md_5.bungee.api.dialog.action; 5 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/body/DialogBody.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.body; 2 | 3 | import lombok.Data; 4 | import lombok.NonNull; 5 | import org.jetbrains.annotations.ApiStatus; 6 | 7 | /** 8 | * Represents the body content of a {@link net.md_5.bungee.api.dialog.Dialog}. 9 | */ 10 | @Data 11 | public abstract class DialogBody 12 | { 13 | 14 | /** 15 | * The internal body type. 16 | */ 17 | @NonNull 18 | @ApiStatus.Internal 19 | private final String type; 20 | } 21 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/body/PlainMessageBody.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.body; 2 | 3 | import com.google.common.base.Preconditions; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NonNull; 7 | import lombok.ToString; 8 | import lombok.experimental.Accessors; 9 | import net.md_5.bungee.api.chat.BaseComponent; 10 | 11 | /** 12 | * Represents a dialog body which consists of text constrained to a certain 13 | * width. 14 | */ 15 | @Data 16 | @Accessors(fluent = true) 17 | @ToString(callSuper = true) 18 | @EqualsAndHashCode(callSuper = true) 19 | public class PlainMessageBody extends DialogBody 20 | { 21 | 22 | /** 23 | * The text body. 24 | */ 25 | @NonNull 26 | private BaseComponent contents; 27 | /** 28 | * The maximum width (default: 200, minimum: 1, maximum: 1024). 29 | */ 30 | private Integer width; 31 | 32 | public PlainMessageBody(@NonNull BaseComponent contents) 33 | { 34 | this( contents, null ); 35 | } 36 | 37 | public PlainMessageBody(@NonNull BaseComponent contents, Integer width) 38 | { 39 | super( "minecraft:plain_message" ); 40 | this.contents = contents; 41 | width( width ); 42 | } 43 | 44 | public void width(Integer width) 45 | { 46 | Preconditions.checkArgument( width == null || ( width >= 1 && width <= 1024 ), "width must be between 1 and 1024" ); 47 | this.width = width; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/body/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains the different {@link net.md_5.bungee.api.dialog.Dialog} body content 3 | * types. 4 | */ 5 | package net.md_5.bungee.api.dialog.body; 6 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/chat/ShowDialogClickEvent.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.chat; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | import net.md_5.bungee.api.chat.ClickEvent; 6 | import net.md_5.bungee.api.dialog.Dialog; 7 | 8 | /** 9 | * Click event which displays either a pre-existing dialog by key or a custom 10 | * dialog. 11 | */ 12 | @Data 13 | @EqualsAndHashCode(callSuper = false) 14 | public class ShowDialogClickEvent extends ClickEvent 15 | { 16 | 17 | /** 18 | * Key for a pre-existing dialog to show. 19 | */ 20 | private String reference; 21 | /** 22 | * Dialog to show. 23 | */ 24 | private Dialog dialog; 25 | 26 | public ShowDialogClickEvent(String reference) 27 | { 28 | this( reference, null ); 29 | } 30 | 31 | public ShowDialogClickEvent(Dialog dialog) 32 | { 33 | this( null, dialog ); 34 | } 35 | 36 | private ShowDialogClickEvent(String reference, Dialog dialog) 37 | { 38 | super( Action.SHOW_DIALOG, null ); 39 | this.reference = reference; 40 | this.dialog = dialog; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/chat/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains dialog extensions to the chat API. 3 | */ 4 | package net.md_5.bungee.api.dialog.chat; 5 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/input/DialogInput.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.input; 2 | 3 | import lombok.Data; 4 | import lombok.NonNull; 5 | import lombok.experimental.Accessors; 6 | import org.jetbrains.annotations.ApiStatus; 7 | 8 | /** 9 | * Represents a type of input which may be displayed/submitted with a form 10 | * dialog. 11 | */ 12 | @Data 13 | @Accessors(fluent = true) 14 | public class DialogInput 15 | { 16 | 17 | /** 18 | * The internal input type. 19 | */ 20 | @NonNull 21 | @ApiStatus.Internal 22 | private final String type; 23 | /** 24 | * The key corresponding to this input and associated with the value 25 | * submitted. 26 | */ 27 | @NonNull 28 | private final String key; 29 | } 30 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/input/InputOption.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.api.dialog.input; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NonNull; 6 | import lombok.experimental.Accessors; 7 | import net.md_5.bungee.api.chat.BaseComponent; 8 | 9 | /** 10 | * Represents an option choice which may form part of a 11 | * {@link SingleOptionInput}. 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @Accessors(fluent = true) 16 | public class InputOption 17 | { 18 | 19 | /** 20 | * The string value associated with this option, to be submitted when 21 | * selected. 22 | */ 23 | @NonNull 24 | private String id; 25 | /** 26 | * The text to display for this option. 27 | */ 28 | private BaseComponent display; 29 | /** 30 | * Whether this option is the one initially selected. Only one option may 31 | * have this value as true (default: first option). 32 | */ 33 | private Boolean initial; 34 | 35 | public InputOption(@NonNull String id) 36 | { 37 | this( id, null, null ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/input/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the various input controls which may be present on form dialogs. 3 | */ 4 | package net.md_5.bungee.api.dialog.input; 5 | -------------------------------------------------------------------------------- /dialog/src/main/java/net/md_5/bungee/api/dialog/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains the core classes for the display of a {@link net.md_5.bungee.api.dialog.Dialog}. 3 | */ 4 | package net.md_5.bungee.api.dialog; 5 | -------------------------------------------------------------------------------- /event/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-event 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Event 19 | Generic java event dispatching API intended for use with BungeeCord 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /event/src/test/java/net/md_5/bungee/event/EventBusTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import java.util.concurrent.CountDownLatch; 5 | import org.junit.jupiter.api.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 | assertEquals( 0, latch.getCount() ); 19 | } 20 | 21 | @EventHandler 22 | public void firstListener(FirstEvent event) 23 | { 24 | bus.post( new SecondEvent() ); 25 | 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 | -------------------------------------------------------------------------------- /event/src/test/java/net/md_5/bungee/event/SubclassTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import java.util.concurrent.CountDownLatch; 5 | import org.junit.jupiter.api.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 | assertEquals( 0, latch.getCount() ); 18 | } 19 | 20 | @EventHandler 21 | protected void extraListener(FirstEvent event) 22 | { 23 | assertEquals( 1, latch.getCount() ); 24 | latch.countDown(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /event/src/test/java/net/md_5/bungee/event/UnregisteringListenerTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.event; 2 | 3 | import static org.junit.jupiter.api.Assertions.fail; 4 | import org.junit.jupiter.api.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 | fail( "Event listener wasn't unregistered" ); 23 | } 24 | 25 | public static class TestEvent 26 | { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /log/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-log 15 | 1.21-R0.3-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 | org.jline 24 | jline 25 | 3.30.4 26 | compile 27 | 28 | 29 | net.md-5 30 | bungeecord-chat 31 | ${project.version} 32 | compile 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /log/src/main/java/net/md_5/bungee/log/LoggingForwardHandler.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.log; 2 | 3 | import java.util.logging.Handler; 4 | import java.util.logging.LogRecord; 5 | import java.util.logging.Logger; 6 | import lombok.RequiredArgsConstructor; 7 | 8 | @RequiredArgsConstructor 9 | public class LoggingForwardHandler extends Handler 10 | { 11 | 12 | private final Logger logger; 13 | 14 | @Override 15 | public void publish(LogRecord record) 16 | { 17 | logger.log( record ); 18 | } 19 | 20 | @Override 21 | public void flush() 22 | { 23 | } 24 | 25 | @Override 26 | public void close() throws SecurityException 27 | { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /log/src/main/java/net/md_5/bungee/log/LoggingOutputStream.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.log; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.nio.charset.StandardCharsets; 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( StandardCharsets.UTF_8.name() ); 23 | super.reset(); 24 | if ( !contents.isEmpty() && !contents.equals( separator ) ) 25 | { 26 | logger.logp( level, "", "", contents ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /module/cmd-alert/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-alert 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | cmd_alert 19 | Provides the alert and alertraw commands 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /module/cmd-find/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-find 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | cmd_find 19 | Provides the find command 20 | 21 | -------------------------------------------------------------------------------- /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-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-kick/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-kick 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | cmd_kick 19 | Provides the gkick command 20 | 21 | -------------------------------------------------------------------------------- /module/cmd-kick/src/main/java/net/md_5/bungee/module/cmd/kick/PluginKick.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.module.cmd.kick; 2 | 3 | import net.md_5.bungee.api.plugin.Plugin; 4 | 5 | public class PluginKick extends Plugin 6 | { 7 | 8 | @Override 9 | public void onEnable() 10 | { 11 | getProxy().getPluginManager().registerCommand( this, new CommandKick() ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /module/cmd-kick/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ${project.name} 2 | main: net.md_5.bungee.module.cmd.kick.PluginKick 3 | version: ${describe} 4 | description: ${project.description} 5 | author: ${module.author} 6 | -------------------------------------------------------------------------------- /module/cmd-list/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-list 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | cmd_list 19 | Provides the glist command 20 | 21 | -------------------------------------------------------------------------------- /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-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/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-send 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | cmd_send 19 | Provides the gsend command 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-cmd-server 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | cmd_server 19 | Provides the server command 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-module 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-module-reconnect-yaml 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | reconnect_yaml 19 | Provides reconnect location functionality in locations.yml 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /native/compile-native-arm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | CWD=$(pwd) 6 | 7 | echo "Compiling mbedtls" 8 | (cd mbedtls && CFLAGS="-fPIC -I$CWD/src/main/c -DMBEDTLS_USER_CONFIG_FILE=''" make CC=aarch64-linux-gnu-gcc AR=aarch64-linux-gnu-ar no_test) 9 | 10 | echo "Compiling zlib" 11 | (cd zlib && CFLAGS="-fPIC -DNO_GZIP" CC=aarch64-linux-gnu-gcc CHOST=arm64 ./configure --target="aarch64" --static && make CFLAGS="-fPIC -march=armv8-a+crc" CC=aarch64-linux-gnu-gcc AR=aarch64-linux-gnu-ar) 12 | 13 | CC="aarch64-linux-gnu-gcc" 14 | CFLAGS="-c -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" 15 | LDFLAGS="-shared" 16 | 17 | echo "Compiling bungee" 18 | $CC $CFLAGS -o shared.o src/main/c/shared.c 19 | $CC $CFLAGS -Imbedtls/include -o NativeCipherImpl.o src/main/c/NativeCipherImpl.c 20 | $CC $CFLAGS -Izlib -o NativeCompressImpl.o src/main/c/NativeCompressImpl.c 21 | 22 | echo "Linking native-cipher-arm.so" 23 | $CC $LDFLAGS -o src/main/resources/native-cipher-arm.so shared.o NativeCipherImpl.o mbedtls/library/libmbedcrypto.a 24 | 25 | echo "Linking native-compress-arm.so" 26 | $CC $LDFLAGS -o src/main/resources/native-compress-arm.so shared.o NativeCompressImpl.o zlib/libz.a 27 | 28 | echo "Cleaning up" 29 | rm shared.o NativeCipherImpl.o NativeCompressImpl.o 30 | -------------------------------------------------------------------------------- /native/compile-native.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | CWD=$(pwd) 6 | 7 | echo "Compiling mbedtls" 8 | (cd mbedtls && CFLAGS="-fPIC -I$CWD/src/main/c -DMBEDTLS_USER_CONFIG_FILE=''" make no_test) 9 | 10 | echo "Compiling zlib" 11 | (cd zlib && CFLAGS="-fPIC -DNO_GZIP" ./configure --static && make) 12 | 13 | CC="gcc" 14 | CFLAGS="-c -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" 15 | LDFLAGS="-shared" 16 | 17 | echo "Compiling bungee" 18 | $CC $CFLAGS -o shared.o src/main/c/shared.c 19 | $CC $CFLAGS -Imbedtls/include -o NativeCipherImpl.o src/main/c/NativeCipherImpl.c 20 | $CC $CFLAGS -Izlib -o NativeCompressImpl.o src/main/c/NativeCompressImpl.c 21 | 22 | echo "Linking native-cipher.so" 23 | $CC $LDFLAGS -o src/main/resources/native-cipher.so shared.o NativeCipherImpl.o mbedtls/library/libmbedcrypto.a 24 | 25 | echo "Linking native-compress.so" 26 | $CC $LDFLAGS -o src/main/resources/native-compress.so shared.o NativeCompressImpl.o zlib/libz.a 27 | 28 | echo "Cleaning up" 29 | rm shared.o NativeCipherImpl.o NativeCompressImpl.o 30 | -------------------------------------------------------------------------------- /native/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-native 15 | 1.21-R0.3-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 | compile 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /native/src/main/c/cpuid_helper.h: -------------------------------------------------------------------------------- 1 | // Header to check for SSE 2, SSSE 3, and SSE 4.2 support in compression natives 2 | // GCC only! 3 | 4 | #ifndef _INCLUDE_CPUID_HELPER_H 5 | #define _INCLUDE_CPUID_HELPER_H 6 | 7 | #include 8 | #include 9 | 10 | static inline bool checkCompressionNativesSupport() { 11 | unsigned int eax, ebx, ecx, edx; 12 | if(__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { 13 | return (edx & bit_SSE2) != 0 && (ecx & bit_SSSE3) != 0 && (ecx & bit_SSE4_2) != 0; 14 | }else { 15 | return false; 16 | } 17 | } 18 | 19 | #endif // _INCLUDE_CPUID_HELPER_H 20 | -------------------------------------------------------------------------------- /native/src/main/c/mbedtls_custom_config.h: -------------------------------------------------------------------------------- 1 | 2 | // This is a hack to deal with a glitch that happens when mbedtls is compiled against glibc 3 | // but then run on a linux distro that uses musl libc. This implementation of the zeroize 4 | // is compatible with both glibc and musl without requiring the library to be recompiled. 5 | 6 | // I checked with a disassembler and for BungeeCord's usage of the library, implementing 7 | // this function as a static function only resulted in 2 different subroutines referencing 8 | // different versions of memset_func, so we might as well keep things simple and use a 9 | // static function here instead of requiring the mbedtls makefile to be modified to add 10 | // additional source files. 11 | 12 | #ifndef _INCLUDE_MBEDTLS_CUSTOM_CONFIG_H 13 | #define _INCLUDE_MBEDTLS_CUSTOM_CONFIG_H 14 | 15 | #include 16 | 17 | #define MBEDTLS_PLATFORM_ZEROIZE_ALT 18 | 19 | #define mbedtls_platform_zeroize mbedtls_platform_zeroize_impl 20 | 21 | // hack to prevent compilers from optimizing the memset away 22 | static void *(*const volatile memset_func)(void *, int, size_t) = memset; 23 | 24 | static void mbedtls_platform_zeroize_impl(void *buf, size_t len) { 25 | if (len > 0) { 26 | memset_func(buf, 0, len); 27 | } 28 | } 29 | 30 | #endif // _INCLUDE_MBEDTLS_CUSTOM_CONFIG_H 31 | 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /native/src/main/c/shared.c: -------------------------------------------------------------------------------- 1 | #include "shared.h" 2 | #include 3 | #include 4 | 5 | void throwOutOfMemoryError(JNIEnv* env, const char* msg) { 6 | jclass exceptionClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); 7 | if (!exceptionClass) { 8 | // If the proxy ran out of memory, loading this class may fail 9 | fprintf(stderr, "OUT OF MEMORY: %s\n", msg); 10 | fprintf(stderr, "Could not load class java.lang.OutOfMemoryError!\n"); 11 | exit(-1); 12 | return; 13 | } 14 | (*env)->ThrowNew(env, exceptionClass, msg); 15 | } 16 | -------------------------------------------------------------------------------- /native/src/main/c/shared.h: -------------------------------------------------------------------------------- 1 | // This header contains functions to be shared between both native libraries 2 | 3 | #include 4 | 5 | #ifndef _INCLUDE_SHARED_H 6 | #define _INCLUDE_SHARED_H 7 | 8 | void throwOutOfMemoryError(JNIEnv* env, const char* msg); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/NativeCodeException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni; 2 | 3 | public class NativeCodeException extends RuntimeException 4 | { 5 | 6 | public NativeCodeException(String message, int reason) 7 | { 8 | super( message + " : " + reason ); 9 | } 10 | 11 | public NativeCodeException(String message) 12 | { 13 | super( message ); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /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 | /* 23 | * This indicates whether the input ByteBuf is allowed to be a CompositeByteBuf. 24 | * If you need access to a memory address, you should not allow composite buffers. 25 | */ 26 | boolean allowComposite(); 27 | } 28 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | public static final int OUTPUT_BUFFER_SIZE = 8192; 10 | 11 | void init(boolean compress, int level); 12 | 13 | void free(); 14 | 15 | void process(ByteBuf in, ByteBuf out) throws DataFormatException; 16 | 17 | /* 18 | * This indicates whether the input ByteBuf is allowed to be a CompositeByteBuf. 19 | * If you need access to a memory address, you should not allow composite buffers. 20 | */ 21 | boolean allowComposite(); 22 | } 23 | -------------------------------------------------------------------------------- /native/src/main/java/net/md_5/bungee/jni/zlib/NativeCompressImpl.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.jni.zlib; 2 | 3 | import net.md_5.bungee.jni.NativeCodeException; 4 | 5 | public class NativeCompressImpl 6 | { 7 | 8 | int consumed; 9 | boolean finished; 10 | 11 | static 12 | { 13 | initFields(); 14 | } 15 | 16 | static native void initFields(); 17 | 18 | native boolean checkSupported(); 19 | 20 | native void end(long ctx, boolean compress); 21 | 22 | native void reset(long ctx, boolean compress); 23 | 24 | native long init(boolean compress, int compressionLevel); 25 | 26 | native int process(long ctx, long in, int inLength, long out, int outLength, boolean compress); 27 | 28 | NativeCodeException makeException(String message, int err) 29 | { 30 | return new NativeCodeException( message, err ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /native/src/main/resources/native-cipher-arm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpigotMC/BungeeCord/93508d508328d082c5892cde37d2af9ff6af82de/native/src/main/resources/native-cipher-arm.so -------------------------------------------------------------------------------- /native/src/main/resources/native-cipher.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpigotMC/BungeeCord/93508d508328d082c5892cde37d2af9ff6af82de/native/src/main/resources/native-cipher.so -------------------------------------------------------------------------------- /native/src/main/resources/native-compress-arm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpigotMC/BungeeCord/93508d508328d082c5892cde37d2af9ff6af82de/native/src/main/resources/native-compress-arm.so -------------------------------------------------------------------------------- /native/src/main/resources/native-compress.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpigotMC/BungeeCord/93508d508328d082c5892cde37d2af9ff6af82de/native/src/main/resources/native-compress.so -------------------------------------------------------------------------------- /nbt/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2025, SpigotMC Pty. Ltd. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 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 ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /nbt/README.md: -------------------------------------------------------------------------------- 1 | BungeeCord-NBT 2 | ================= 3 | 4 | Minimal implementation of NBT for use in BungeeCord 5 | -------------------------------------------------------------------------------- /nbt/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-nbt 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-NBT 19 | Minimal implementation of NBT for use in BungeeCord 20 | 21 | 22 | BSD-3-Clause 23 | https://github.com/SpigotMC/BungeeCord/blob/master/nbt/LICENSE 24 | repo 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/TypedTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt; 2 | 3 | public interface TypedTag extends Tag 4 | { 5 | 6 | /** 7 | * Gets the id of this tag's type. 8 | * 9 | * @return the id related to this tag's type 10 | */ 11 | byte getId(); 12 | } 13 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/exception/NBTException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.exception; 2 | 3 | public class NBTException extends RuntimeException 4 | { 5 | 6 | public NBTException(String message) 7 | { 8 | super( message ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/exception/NBTFormatException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.exception; 2 | 3 | public class NBTFormatException extends NBTException 4 | { 5 | 6 | public NBTFormatException(String message) 7 | { 8 | super( message ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/exception/NBTLimitException.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.exception; 2 | 3 | public class NBTLimitException extends NBTException 4 | { 5 | 6 | public NBTLimitException(String message) 7 | { 8 | super( message ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/ByteArrayTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import com.google.common.base.Preconditions; 4 | import java.io.DataInput; 5 | import java.io.DataOutput; 6 | import java.io.IOException; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import net.md_5.bungee.nbt.Tag; 11 | import net.md_5.bungee.nbt.TypedTag; 12 | import net.md_5.bungee.nbt.limit.NBTLimiter; 13 | 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class ByteArrayTag implements TypedTag 18 | { 19 | 20 | private byte[] value; 21 | 22 | @Override 23 | public void read(DataInput input, NBTLimiter limiter) throws IOException 24 | { 25 | limiter.countBytes( OBJECT_HEADER + ARRAY_HEADER + Integer.BYTES ); 26 | int length = input.readInt(); 27 | limiter.countBytes( length, Byte.BYTES ); 28 | input.readFully( value = new byte[ length ] ); 29 | } 30 | 31 | @Override 32 | public void write(DataOutput output) throws IOException 33 | { 34 | Preconditions.checkNotNull( value, "byte array value cannot be null" ); 35 | output.writeInt( value.length ); 36 | output.write( value ); 37 | } 38 | 39 | @Override 40 | public byte getId() 41 | { 42 | return Tag.BYTE_ARRAY; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/ByteTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import net.md_5.bungee.nbt.Tag; 10 | import net.md_5.bungee.nbt.TypedTag; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class ByteTag implements TypedTag 17 | { 18 | 19 | private byte value; 20 | 21 | @Override 22 | public void read(DataInput input, NBTLimiter limiter) throws IOException 23 | { 24 | limiter.countBytes( OBJECT_HEADER + Byte.BYTES ); 25 | value = input.readByte(); 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException 30 | { 31 | output.write( value ); 32 | } 33 | 34 | @Override 35 | public byte getId() 36 | { 37 | return Tag.BYTE; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/DoubleTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import net.md_5.bungee.nbt.Tag; 10 | import net.md_5.bungee.nbt.TypedTag; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class DoubleTag implements TypedTag 17 | { 18 | 19 | private double value; 20 | 21 | @Override 22 | public void read(DataInput input, NBTLimiter limiter) throws IOException 23 | { 24 | limiter.countBytes( OBJECT_HEADER + Double.BYTES ); 25 | value = input.readDouble(); 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException 30 | { 31 | output.writeDouble( value ); 32 | } 33 | 34 | @Override 35 | public byte getId() 36 | { 37 | return Tag.DOUBLE; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/EndTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import net.md_5.bungee.nbt.Tag; 8 | import net.md_5.bungee.nbt.TypedTag; 9 | import net.md_5.bungee.nbt.limit.NBTLimiter; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | public class EndTag implements TypedTag 14 | { 15 | 16 | public static final EndTag INSTANCE = new EndTag(); 17 | 18 | @Override 19 | public void read(DataInput input, NBTLimiter limiter) 20 | { 21 | limiter.countBytes( OBJECT_HEADER ); 22 | } 23 | 24 | @Override 25 | public void write(DataOutput output) 26 | { 27 | } 28 | 29 | @Override 30 | public byte getId() 31 | { 32 | return Tag.END; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/FloatTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import net.md_5.bungee.nbt.Tag; 10 | import net.md_5.bungee.nbt.TypedTag; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class FloatTag implements TypedTag 17 | { 18 | 19 | private float value; 20 | 21 | @Override 22 | public void read(DataInput input, NBTLimiter limiter) throws IOException 23 | { 24 | limiter.countBytes( OBJECT_HEADER + Float.BYTES ); 25 | value = input.readFloat(); 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException 30 | { 31 | output.writeFloat( value ); 32 | } 33 | 34 | @Override 35 | public byte getId() 36 | { 37 | return Tag.FLOAT; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/IntArrayTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import com.google.common.base.Preconditions; 4 | import java.io.DataInput; 5 | import java.io.DataOutput; 6 | import java.io.IOException; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import net.md_5.bungee.nbt.Tag; 11 | import net.md_5.bungee.nbt.TypedTag; 12 | import net.md_5.bungee.nbt.limit.NBTLimiter; 13 | 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class IntArrayTag implements TypedTag 18 | { 19 | 20 | private int[] value; 21 | 22 | @Override 23 | public void read(DataInput input, NBTLimiter limiter) throws IOException 24 | { 25 | limiter.countBytes( OBJECT_HEADER + ARRAY_HEADER + Integer.BYTES ); 26 | int length = input.readInt(); 27 | limiter.countBytes( length, Integer.BYTES ); 28 | int[] data = new int[ length ]; 29 | for ( int i = 0; i < length; i++ ) 30 | { 31 | data[i] = input.readInt(); 32 | } 33 | value = data; 34 | } 35 | 36 | @Override 37 | public void write(DataOutput output) throws IOException 38 | { 39 | Preconditions.checkNotNull( value, "int array value cannot be null" ); 40 | output.writeInt( value.length ); 41 | for ( int i : value ) 42 | { 43 | output.writeInt( i ); 44 | } 45 | } 46 | 47 | @Override 48 | public byte getId() 49 | { 50 | return Tag.INT_ARRAY; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/IntTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import net.md_5.bungee.nbt.Tag; 10 | import net.md_5.bungee.nbt.TypedTag; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class IntTag implements TypedTag 17 | { 18 | 19 | private int value; 20 | 21 | @Override 22 | public void read(DataInput input, NBTLimiter limiter) throws IOException 23 | { 24 | limiter.countBytes( OBJECT_HEADER + Integer.BYTES ); 25 | value = input.readInt(); 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException 30 | { 31 | output.writeInt( value ); 32 | } 33 | 34 | @Override 35 | public byte getId() 36 | { 37 | return Tag.INT; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/LongArrayTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import com.google.common.base.Preconditions; 4 | import java.io.DataInput; 5 | import java.io.DataOutput; 6 | import java.io.IOException; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import net.md_5.bungee.nbt.Tag; 11 | import net.md_5.bungee.nbt.TypedTag; 12 | import net.md_5.bungee.nbt.limit.NBTLimiter; 13 | 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class LongArrayTag implements TypedTag 18 | { 19 | 20 | private long[] value; 21 | 22 | @Override 23 | public void read(DataInput input, NBTLimiter limiter) throws IOException 24 | { 25 | limiter.countBytes( OBJECT_HEADER + ARRAY_HEADER + Integer.BYTES ); 26 | int length = input.readInt(); 27 | limiter.countBytes( length, Long.BYTES ); 28 | long[] data = new long[ length ]; 29 | for ( int i = 0; i < length; i++ ) 30 | { 31 | data[i] = input.readLong(); 32 | } 33 | value = data; 34 | } 35 | 36 | @Override 37 | public void write(DataOutput output) throws IOException 38 | { 39 | Preconditions.checkNotNull( value, "long array value cannot be null" ); 40 | 41 | output.writeInt( value.length ); 42 | for ( long i : value ) 43 | { 44 | output.writeLong( i ); 45 | } 46 | } 47 | 48 | @Override 49 | public byte getId() 50 | { 51 | return Tag.LONG_ARRAY; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/LongTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import net.md_5.bungee.nbt.Tag; 10 | import net.md_5.bungee.nbt.TypedTag; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class LongTag implements TypedTag 17 | { 18 | 19 | private long value; 20 | 21 | @Override 22 | public void read(DataInput input, NBTLimiter limiter) throws IOException 23 | { 24 | limiter.countBytes( OBJECT_HEADER + Long.BYTES ); 25 | value = input.readLong(); 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException 30 | { 31 | output.writeLong( value ); 32 | } 33 | 34 | @Override 35 | public byte getId() 36 | { 37 | return Tag.LONG; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/ShortTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import net.md_5.bungee.nbt.Tag; 10 | import net.md_5.bungee.nbt.TypedTag; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class ShortTag implements TypedTag 17 | { 18 | 19 | private short value; 20 | 21 | @Override 22 | public void read(DataInput input, NBTLimiter limiter) throws IOException 23 | { 24 | limiter.countBytes( OBJECT_HEADER + Short.BYTES ); 25 | value = input.readShort(); 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException 30 | { 31 | output.writeShort( value ); 32 | } 33 | 34 | @Override 35 | public byte getId() 36 | { 37 | return Tag.SHORT; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nbt/src/main/java/net/md_5/bungee/nbt/type/StringTag.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt.type; 2 | 3 | import com.google.common.base.Preconditions; 4 | import java.io.DataInput; 5 | import java.io.DataOutput; 6 | import java.io.IOException; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import net.md_5.bungee.nbt.Tag; 11 | import net.md_5.bungee.nbt.TypedTag; 12 | import net.md_5.bungee.nbt.limit.NBTLimiter; 13 | 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class StringTag implements TypedTag 18 | { 19 | 20 | private String value; 21 | 22 | @Override 23 | public void read(DataInput input, NBTLimiter limiter) throws IOException 24 | { 25 | limiter.countBytes( OBJECT_HEADER + STRING_SIZE ); 26 | String string = input.readUTF(); 27 | limiter.countBytes( string.length(), Character.BYTES ); 28 | value = string; 29 | } 30 | 31 | @Override 32 | public void write(DataOutput output) throws IOException 33 | { 34 | Preconditions.checkNotNull( value, "string value cannot be null" ); 35 | 36 | output.writeUTF( value ); 37 | } 38 | 39 | @Override 40 | public byte getId() 41 | { 42 | return Tag.STRING; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nbt/src/test/java/net/md_5/bungee/nbt/PlayerDataTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.nbt; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertInstanceOf; 5 | import java.io.DataInputStream; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.IOException; 9 | import java.net.URISyntaxException; 10 | import java.util.Objects; 11 | import net.md_5.bungee.nbt.limit.NBTLimiter; 12 | import net.md_5.bungee.nbt.type.CompoundTag; 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class PlayerDataTest 16 | { 17 | 18 | @Test 19 | public void testPlayerData() throws URISyntaxException, IOException 20 | { 21 | ClassLoader classLoader = PlayerDataTest.class.getClassLoader(); 22 | File file = new File( Objects.requireNonNull( classLoader.getResource( "playerdata.nbt" ) ).toURI() ); 23 | FileInputStream fileInputStream = new FileInputStream( file ); 24 | DataInputStream dis = new DataInputStream( fileInputStream ); 25 | NamedTag namedTag = new NamedTag(); 26 | namedTag.read( dis, NBTLimiter.unlimitedSize() ); 27 | assertInstanceOf( CompoundTag.class, namedTag.getTag() ); 28 | assertEquals( namedTag.getName(), "" ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /nbt/src/test/resources/playerdata.nbt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpigotMC/BungeeCord/93508d508328d082c5892cde37d2af9ff6af82de/nbt/src/test/resources/playerdata.nbt -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/ChatSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import net.md_5.bungee.chat.ChatVersion; 4 | import net.md_5.bungee.chat.VersionedComponentSerializer; 5 | 6 | public class ChatSerializer 7 | { 8 | 9 | public static VersionedComponentSerializer forVersion(int protocolVersion) 10 | { 11 | if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_21_5 ) 12 | { 13 | return VersionedComponentSerializer.forVersion( ChatVersion.V1_21_5 ); 14 | } else 15 | { 16 | return VersionedComponentSerializer.forVersion( ChatVersion.V1_16 ); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/Either.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import java.util.function.Function; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | 8 | @Data 9 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 10 | public final class Either 11 | { 12 | 13 | private final L left; 14 | private final R right; 15 | 16 | public boolean isLeft() 17 | { 18 | return this.left != null; 19 | } 20 | 21 | public boolean isRight() 22 | { 23 | return this.right != null; 24 | } 25 | 26 | public static Either left(L left) 27 | { 28 | return new Either<>( left, null ); 29 | } 30 | 31 | public static Either right(R right) 32 | { 33 | return new Either<>( null, right ); 34 | } 35 | 36 | public L getLeftOrCompute(Function function) 37 | { 38 | if ( isLeft() ) 39 | { 40 | return left; 41 | } else 42 | { 43 | return function.apply( right ); 44 | } 45 | } 46 | 47 | public R getRightOrCompute(Function function) 48 | { 49 | if ( isRight() ) 50 | { 51 | return right; 52 | } else 53 | { 54 | return function.apply( left ); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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, Protocol.STATUS ) ); 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, Protocol.STATUS ) ); 40 | return; 41 | } 42 | 43 | in.resetReaderIndex(); 44 | ctx.pipeline().remove( this ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.Getter; 8 | import lombok.Setter; 9 | 10 | @AllArgsConstructor 11 | public class MinecraftEncoder extends MessageToByteEncoder 12 | { 13 | 14 | @Getter 15 | @Setter 16 | private Protocol protocol; 17 | private boolean server; 18 | @Getter 19 | @Setter 20 | private int protocolVersion; 21 | 22 | @Override 23 | protected void encode(ChannelHandlerContext ctx, DefinedPacket msg, ByteBuf out) throws Exception 24 | { 25 | Protocol.DirectionData prot = ( server ) ? protocol.TO_CLIENT : protocol.TO_SERVER; 26 | DefinedPacket.writeVarInt( prot.getId( msg.getClass(), protocolVersion ), out ); 27 | msg.write( out, protocol, prot.getDirection(), protocolVersion ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/NumberFormat.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class NumberFormat 7 | { 8 | 9 | private final Type type; 10 | private final Object value; 11 | 12 | public enum Type 13 | { 14 | BLANK, 15 | STYLED, 16 | FIXED; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /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/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 | public final Protocol protocol; 14 | @Setter 15 | private boolean released; 16 | 17 | public void trySingleRelease() 18 | { 19 | if ( !released ) 20 | { 21 | buf.release(); 22 | released = true; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/SeenMessages.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import java.util.BitSet; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @EqualsAndHashCode(callSuper = false) 14 | public class SeenMessages extends DefinedPacket 15 | { 16 | 17 | private int offset; 18 | private BitSet acknowledged; 19 | 20 | @Override 21 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 22 | { 23 | offset = DefinedPacket.readVarInt( buf ); 24 | acknowledged = DefinedPacket.readFixedBitSet( 20, buf ); 25 | } 26 | 27 | @Override 28 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 29 | { 30 | DefinedPacket.writeVarInt( offset, buf ); 31 | DefinedPacket.writeFixedBitSet( acknowledged, 20, buf ); 32 | } 33 | 34 | @Override 35 | public void handle(AbstractPacketHandler handler) throws Exception 36 | { 37 | throw new UnsupportedOperationException( "Not supported." ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/channel/ChannelAcceptor.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.channel; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | @FunctionalInterface 6 | public interface ChannelAcceptor 7 | { 8 | 9 | /** 10 | * Inside this method the pipeline should be initialized. 11 | * 12 | * @param channel the channel to be accepted and initialized 13 | * @return if the channel was accepted 14 | */ 15 | boolean accept(Channel channel); 16 | } 17 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ClearDialog.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 ClearDialog extends DefinedPacket 15 | { 16 | 17 | @Override 18 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 19 | { 20 | } 21 | 22 | @Override 23 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | } 26 | 27 | @Override 28 | public void handle(AbstractPacketHandler handler) throws Exception 29 | { 30 | handler.handle( this ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/CookieRequest.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 CookieRequest extends DefinedPacket 17 | { 18 | 19 | private String cookie; 20 | 21 | @Override 22 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | cookie = readString( buf ); 25 | } 26 | 27 | @Override 28 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 29 | { 30 | writeString( cookie, buf ); 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/CookieResponse.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 CookieResponse extends DefinedPacket 17 | { 18 | 19 | private String cookie; 20 | private byte[] data; 21 | 22 | @Override 23 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | cookie = readString( buf ); 26 | data = readNullable( read -> DefinedPacket.readArray( read, 5120 ), buf ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeString( cookie, buf ); 33 | writeNullable( data, DefinedPacket::writeArray, 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/CustomClickAction.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.nbt.TypedTag; 9 | import net.md_5.bungee.protocol.AbstractPacketHandler; 10 | import net.md_5.bungee.protocol.DefinedPacket; 11 | import net.md_5.bungee.protocol.Protocol; 12 | import net.md_5.bungee.protocol.ProtocolConstants; 13 | 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | @EqualsAndHashCode(callSuper = false) 18 | public class CustomClickAction extends DefinedPacket 19 | { 20 | 21 | private String id; 22 | private TypedTag data; 23 | 24 | @Override 25 | public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) 26 | { 27 | id = readString( buf ); 28 | data = readNullable( (buf0) -> (TypedTag) readTag( buf0, protocolVersion ), buf ); 29 | } 30 | 31 | @Override 32 | public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) 33 | { 34 | writeString( id, buf ); 35 | writeNullable( data, (data0, buf0) -> writeTag( data0, buf0, protocolVersion ), buf ); 36 | } 37 | 38 | @Override 39 | public void write(ByteBuf buf) 40 | { 41 | } 42 | 43 | @Override 44 | public void handle(AbstractPacketHandler handler) throws Exception 45 | { 46 | handler.handle( this ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/FinishConfiguration.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 net.md_5.bungee.protocol.AbstractPacketHandler; 7 | import net.md_5.bungee.protocol.DefinedPacket; 8 | import net.md_5.bungee.protocol.Protocol; 9 | import net.md_5.bungee.protocol.ProtocolConstants; 10 | 11 | @Data 12 | @EqualsAndHashCode(callSuper = false) 13 | public class FinishConfiguration extends DefinedPacket 14 | { 15 | 16 | @Override 17 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 18 | { 19 | } 20 | 21 | @Override 22 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | } 25 | 26 | @Override 27 | public Protocol nextProtocol() 28 | { 29 | return Protocol.GAME; 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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | randomId = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_12_2 ) ? buf.readLong() : readVarInt( buf ); 25 | } 26 | 27 | @Override 28 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 29 | { 30 | if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_12_2 ) 31 | { 32 | buf.writeLong( randomId ); 33 | } else 34 | { 35 | writeVarInt( (int) randomId, buf ); 36 | } 37 | } 38 | 39 | @Override 40 | public void handle(AbstractPacketHandler handler) throws Exception 41 | { 42 | handler.handle( this ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /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/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/LoginAcknowledged.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 net.md_5.bungee.protocol.AbstractPacketHandler; 7 | import net.md_5.bungee.protocol.DefinedPacket; 8 | import net.md_5.bungee.protocol.Protocol; 9 | import net.md_5.bungee.protocol.ProtocolConstants; 10 | 11 | @Data 12 | @EqualsAndHashCode(callSuper = false) 13 | public class LoginAcknowledged extends DefinedPacket 14 | { 15 | 16 | @Override 17 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 18 | { 19 | } 20 | 21 | @Override 22 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | } 25 | 26 | @Override 27 | public Protocol nextProtocol() 28 | { 29 | return Protocol.CONFIGURATION; 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/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 | -------------------------------------------------------------------------------- /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/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.api.chat.BaseComponent; 9 | import net.md_5.bungee.protocol.AbstractPacketHandler; 10 | import net.md_5.bungee.protocol.DefinedPacket; 11 | import net.md_5.bungee.protocol.ProtocolConstants; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @EqualsAndHashCode(callSuper = false) 17 | public class PlayerListHeaderFooter extends DefinedPacket 18 | { 19 | 20 | private BaseComponent header; 21 | private BaseComponent footer; 22 | 23 | @Override 24 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 25 | { 26 | header = readBaseComponent( buf, protocolVersion ); 27 | footer = readBaseComponent( buf, protocolVersion ); 28 | } 29 | 30 | @Override 31 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 32 | { 33 | writeBaseComponent( header, buf, protocolVersion ); 34 | writeBaseComponent( footer, buf, protocolVersion ); 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/PlayerListItemRemove.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import java.util.UUID; 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 | @EqualsAndHashCode(callSuper = false) 15 | public class PlayerListItemRemove extends DefinedPacket 16 | { 17 | 18 | private UUID[] uuids; 19 | 20 | @Override 21 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 22 | { 23 | uuids = new UUID[ DefinedPacket.readVarInt( buf ) ]; 24 | for ( int i = 0; i < uuids.length; i++ ) 25 | { 26 | uuids[i] = DefinedPacket.readUUID( buf ); 27 | } 28 | } 29 | 30 | @Override 31 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 32 | { 33 | DefinedPacket.writeVarInt( uuids.length, buf ); 34 | for ( UUID uuid : uuids ) 35 | { 36 | DefinedPacket.writeUUID( uuid, buf ); 37 | } 38 | } 39 | 40 | @Override 41 | public void handle(AbstractPacketHandler handler) throws Exception 42 | { 43 | handler.handle( this ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardScoreReset.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 ScoreboardScoreReset extends DefinedPacket 17 | { 18 | 19 | private String itemName; 20 | private String scoreName; 21 | 22 | @Override 23 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | itemName = readString( buf ); 26 | scoreName = readNullable( DefinedPacket::readString, buf ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeString( itemName, buf ); 33 | writeNullable( scoreName, DefinedPacket::writeString, 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/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 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/ShowDialogDirect.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.api.dialog.Dialog; 8 | import net.md_5.bungee.protocol.AbstractPacketHandler; 9 | import net.md_5.bungee.protocol.Either; 10 | import net.md_5.bungee.protocol.ProtocolConstants; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @EqualsAndHashCode(callSuper = true) 15 | public class ShowDialogDirect extends ShowDialog 16 | { 17 | 18 | public ShowDialogDirect(Dialog dialog) 19 | { 20 | super( Either.right( dialog ) ); 21 | } 22 | 23 | @Override 24 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 25 | { 26 | dialog = Either.right( readDialog( buf, direction, protocolVersion ) ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeDialog( dialog.getRight(), buf, direction, protocolVersion ); 33 | } 34 | 35 | @Override 36 | public void handle(AbstractPacketHandler handler) throws Exception 37 | { 38 | handler.handle( this ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/StartConfiguration.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 net.md_5.bungee.protocol.AbstractPacketHandler; 7 | import net.md_5.bungee.protocol.DefinedPacket; 8 | import net.md_5.bungee.protocol.Protocol; 9 | import net.md_5.bungee.protocol.ProtocolConstants; 10 | 11 | @Data 12 | @EqualsAndHashCode(callSuper = false) 13 | public class StartConfiguration extends DefinedPacket 14 | { 15 | 16 | @Override 17 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 18 | { 19 | } 20 | 21 | @Override 22 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | } 25 | 26 | @Override 27 | public Protocol nextProtocol() 28 | { 29 | return Protocol.CONFIGURATION; 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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /protocol/src/main/java/net/md_5/bungee/protocol/packet/StoreCookie.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 StoreCookie extends DefinedPacket 17 | { 18 | 19 | private String key; 20 | private byte[] data; 21 | 22 | @Override 23 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | key = readString( buf ); 26 | data = readArray( buf, 5120 ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeString( key, buf ); 33 | writeArray( data, 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/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.api.chat.BaseComponent; 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 | @EqualsAndHashCode(callSuper = false) 15 | public class Subtitle extends DefinedPacket 16 | { 17 | 18 | private BaseComponent text; 19 | 20 | @Override 21 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 22 | { 23 | text = readBaseComponent( buf, protocolVersion ); 24 | } 25 | 26 | @Override 27 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 28 | { 29 | writeBaseComponent( text, buf, protocolVersion ); 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/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/Transfer.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 Transfer extends DefinedPacket 17 | { 18 | 19 | private String host; 20 | private int port; 21 | 22 | @Override 23 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 24 | { 25 | host = readString( buf ); 26 | port = readVarInt( buf ); 27 | } 28 | 29 | @Override 30 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 31 | { 32 | writeString( host, buf ); 33 | writeVarInt( port, 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/UnsignedClientCommand.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 UnsignedClientCommand extends DefinedPacket 17 | { 18 | 19 | private String command; 20 | 21 | @Override 22 | public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 23 | { 24 | command = readString( buf ); 25 | } 26 | 27 | @Override 28 | public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) 29 | { 30 | writeString( command, buf ); 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/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 | -------------------------------------------------------------------------------- /protocol/src/test/java/net/md_5/bungee/protocol/packet/PluginMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.protocol.packet; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class PluginMessageTest 7 | { 8 | 9 | @Test 10 | public void testModerniseChannel() 11 | { 12 | assertEquals( PluginMessage.BUNGEE_CHANNEL_MODERN, PluginMessage.MODERNISE.apply( PluginMessage.BUNGEE_CHANNEL_LEGACY ) ); 13 | assertEquals( PluginMessage.BUNGEE_CHANNEL_LEGACY, PluginMessage.MODERNISE.apply( PluginMessage.BUNGEE_CHANNEL_MODERN ) ); 14 | assertEquals( "legacy:foo", PluginMessage.MODERNISE.apply( "FoO" ) ); 15 | assertEquals( "foo:bar", PluginMessage.MODERNISE.apply( "foo:bar" ) ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /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 | 17 | @Override 18 | public ServerPing.PlayerInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException 19 | { 20 | JsonObject js = json.getAsJsonObject(); 21 | ServerPing.PlayerInfo info = new ServerPing.PlayerInfo( js.get( "name" ).getAsString(), (UUID) null ); 22 | String id = js.get( "id" ).getAsString(); 23 | if ( !id.contains( "-" ) ) 24 | { 25 | info.setId( id ); 26 | } else 27 | { 28 | info.setUniqueId( UUID.fromString( id ) ); 29 | } 30 | return info; 31 | } 32 | 33 | @Override 34 | public JsonElement serialize(ServerPing.PlayerInfo src, Type typeOfSrc, JsonSerializationContext context) 35 | { 36 | JsonObject out = new JsonObject(); 37 | out.addProperty( "name", src.getName() ); 38 | out.addProperty( "id", src.getUniqueId().toString() ); 39 | return out; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /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 BungeeCord version " + ProxyServer.getInstance().getVersion() + " by md_5" ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 lombok.RequiredArgsConstructor; 9 | import net.md_5.bungee.api.ProxyServer; 10 | import org.jline.reader.Candidate; 11 | import org.jline.reader.Completer; 12 | import org.jline.reader.LineReader; 13 | import org.jline.reader.ParsedLine; 14 | 15 | @RequiredArgsConstructor 16 | public class ConsoleCommandCompleter implements Completer 17 | { 18 | 19 | private final ProxyServer proxy; 20 | 21 | @Override 22 | public void complete(LineReader reader, ParsedLine line, List candidates) 23 | { 24 | List suggestions; 25 | String buffer = line.line(); 26 | 27 | int lastSpace = buffer.lastIndexOf( ' ' ); 28 | if ( lastSpace == -1 ) 29 | { 30 | String lowerCase = buffer.toLowerCase( Locale.ROOT ); 31 | suggestions = proxy.getPluginManager().getCommands().stream() 32 | .map( Map.Entry::getKey ) 33 | .filter( (name) -> name.toLowerCase( Locale.ROOT ).startsWith( lowerCase ) ) 34 | .collect( Collectors.toList() ); 35 | } else 36 | { 37 | suggestions = new ArrayList<>(); 38 | proxy.getPluginManager().dispatchCommand( proxy.getConsole(), buffer, suggestions ); 39 | } 40 | 41 | suggestions.stream().map( Candidate::new ).forEach( (candidate) -> candidates.add( candidate ) ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /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, true ); 12 | } 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/connection/LoginResult.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.connection; 2 | 3 | import com.google.gson.Gson; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import net.md_5.bungee.protocol.Property; 7 | 8 | @Data 9 | @AllArgsConstructor 10 | public class LoginResult 11 | { 12 | 13 | public static final Gson GSON = new Gson(); 14 | // 15 | private String id; 16 | private String name; 17 | private Property[] properties; 18 | } 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | import net.md_5.bungee.api.ProxyServer; 11 | 12 | @Data 13 | public class JenkinsModuleSource implements ModuleSource 14 | { 15 | 16 | @Override 17 | public void retrieve(ModuleSpec module, ModuleVersion version) 18 | { 19 | ProxyServer.getInstance().getLogger().info( "Attempting to Jenkins download module " + module.getName() + " v" + version.getBuild() ); 20 | try 21 | { 22 | URL website = new URL( "https://ci.md-5.net/job/BungeeCord/" + version.getBuild() + "/artifact/module/" + module.getName().replace( '_', '-' ) + "/target/" + module.getName() + ".jar" ); 23 | URLConnection con = website.openConnection(); 24 | // 15 second timeout at various stages 25 | con.setConnectTimeout( 15000 ); 26 | con.setReadTimeout( 15000 ); 27 | 28 | Files.write( ByteStreams.toByteArray( con.getInputStream() ), module.getFile() ); 29 | ProxyServer.getInstance().getLogger().info( "Download complete" ); 30 | } catch ( IOException ex ) 31 | { 32 | ProxyServer.getInstance().getLogger().warning( "Failed to download: " + Util.exception( ex ) ); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.Getter; 7 | import lombok.RequiredArgsConstructor; 8 | import net.md_5.bungee.jni.cipher.BungeeCipher; 9 | 10 | @RequiredArgsConstructor 11 | public class CipherEncoder extends MessageToByteEncoder 12 | { 13 | 14 | @Getter 15 | private final BungeeCipher cipher; 16 | 17 | @Override 18 | protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception 19 | { 20 | cipher.cipher( in, out ); 21 | } 22 | 23 | @Override 24 | public void handlerRemoved(ChannelHandlerContext ctx) throws Exception 25 | { 26 | cipher.free(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/util/AddressUtil.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import com.google.common.base.Preconditions; 4 | import java.net.Inet6Address; 5 | import java.net.InetSocketAddress; 6 | import lombok.AccessLevel; 7 | import lombok.NoArgsConstructor; 8 | 9 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 10 | public class AddressUtil 11 | { 12 | 13 | public static String sanitizeAddress(InetSocketAddress addr) 14 | { 15 | Preconditions.checkArgument( !addr.isUnresolved(), "Unresolved address" ); 16 | String string = addr.getAddress().getHostAddress(); 17 | 18 | // Remove IPv6 scope if present 19 | if ( addr.getAddress() instanceof Inet6Address ) 20 | { 21 | int strip = string.indexOf( '%' ); 22 | return ( strip == -1 ) ? string : string.substring( 0, strip ); 23 | } else 24 | { 25 | return string; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /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 == '_'; 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 | if ( name.isEmpty() || name.length() > 16 ) 31 | { 32 | return false; 33 | } 34 | 35 | for ( int index = 0, len = name.length(); index < len; index++ ) 36 | { 37 | if ( !isNameAllowedCharacter( name.charAt( index ), onlineMode ) ) 38 | { 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /proxy/src/main/java/net/md_5/bungee/util/PacketLimiter.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | @RequiredArgsConstructor 7 | public class PacketLimiter 8 | { 9 | 10 | // max amount of packets allowed per second 11 | private final int limit; 12 | // max amount of data allowed per second 13 | private final int dataLimit; 14 | 15 | @Getter 16 | private int counter; 17 | @Getter 18 | private int dataCounter; 19 | private long nextSecond; 20 | 21 | /** 22 | * Counts the received packet amount and size. 23 | * 24 | * @param size size of the packet 25 | * @return return false if the player should be kicked 26 | */ 27 | public boolean incrementAndCheck(int size) 28 | { 29 | counter++; 30 | dataCounter += size; 31 | 32 | if ( ( limit > 0 && counter > limit ) || ( dataLimit > 0 && dataCounter > dataLimit ) ) 33 | { 34 | long now = System.currentTimeMillis(); 35 | if ( nextSecond > now ) 36 | { 37 | return false; 38 | } 39 | nextSecond = now + 1000; 40 | counter = 0; 41 | dataCounter = 0; 42 | } 43 | return true; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /proxy/src/main/resources/yggdrasil_session_pubkey.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpigotMC/BungeeCord/93508d508328d082c5892cde37d2af9ff6af82de/proxy/src/main/resources/yggdrasil_session_pubkey.der -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /proxy/src/test/java/net/md_5/bungee/util/AddressUtilTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import java.net.InetSocketAddress; 5 | import org.junit.jupiter.api.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 | 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 | assertEquals( "0:0:0:0:0:0:0:1", AddressUtil.sanitizeAddress( addr2 ) ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /query/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-query 15 | 1.21-R0.3-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 | compile 26 | 27 | 28 | net.md-5 29 | bungeecord-api 30 | ${project.version} 31 | compile 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /serializer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-serializer 15 | 1.21-R0.3-SNAPSHOT 16 | jar 17 | 18 | BungeeCord-Serializer 19 | Minecraft JSON serializer intended for use with BungeeCord 20 | 21 | 22 | 23 | com.google.code.gson 24 | gson 25 | 2.11.0 26 | compile 27 | 28 | 29 | ${project.groupId} 30 | bungeecord-chat 31 | ${project.version} 32 | compile 33 | 34 | 35 | ${project.groupId} 36 | bungeecord-dialog 37 | ${project.version} 38 | compile 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /serializer/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 | -------------------------------------------------------------------------------- /serializer/src/main/java/net/md_5/bungee/chat/ChatVersion.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.chat; 2 | 3 | import org.jetbrains.annotations.ApiStatus; 4 | 5 | @ApiStatus.Internal 6 | public enum ChatVersion 7 | { 8 | V1_16, 9 | V1_21_5; 10 | } 11 | -------------------------------------------------------------------------------- /serializer/src/main/java/net/md_5/bungee/serializer/dialog/ShowDialogClickEventSerializer.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.serializer.dialog; 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.JsonPrimitive; 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.dialog.Dialog; 12 | import net.md_5.bungee.api.dialog.chat.ShowDialogClickEvent; 13 | 14 | public class ShowDialogClickEventSerializer implements JsonDeserializer, JsonSerializer 15 | { 16 | 17 | @Override 18 | public ShowDialogClickEvent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException 19 | { 20 | if ( json.isJsonPrimitive() && json.getAsJsonPrimitive().isString() ) 21 | { 22 | return new ShowDialogClickEvent( json.getAsJsonPrimitive().getAsString() ); 23 | } 24 | 25 | return new ShowDialogClickEvent( (Dialog) context.deserialize( json, Dialog.class ) ); 26 | } 27 | 28 | @Override 29 | public JsonElement serialize(ShowDialogClickEvent src, Type typeOfSrc, JsonSerializationContext context) 30 | { 31 | if ( src.getReference() != null ) 32 | { 33 | return new JsonPrimitive( src.getReference() ); 34 | } 35 | 36 | return context.serialize( src.getDialog(), Dialog.class ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /serializer/src/test/java/net/md_5/bungee/dialog/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package net.md_5.bungee.dialog; 2 | 3 | import net.md_5.bungee.api.ChatColor; 4 | import net.md_5.bungee.api.chat.ComponentBuilder; 5 | import net.md_5.bungee.api.dialog.Dialog; 6 | import net.md_5.bungee.api.dialog.DialogBase; 7 | import net.md_5.bungee.api.dialog.NoticeDialog; 8 | import net.md_5.bungee.chat.VersionedComponentSerializer; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class SimpleTest 12 | { 13 | 14 | @Test 15 | public void testNotice() 16 | { 17 | String json = "{type:\"minecraft:notice\",title:\"Hello\"}"; 18 | Dialog deserialized = VersionedComponentSerializer.getDefault().getDialogSerializer().deserialize( json ); 19 | System.err.println( deserialized ); 20 | 21 | Dialog notice = new NoticeDialog( new DialogBase( new ComponentBuilder( "Hello" ).color( ChatColor.RED ).build() ) ); 22 | String newJson = VersionedComponentSerializer.getDefault().getDialogSerializer().toString( notice ); 23 | System.err.println( newJson ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /slf4j/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | net.md-5 8 | bungeecord-parent 9 | 1.21-R0.3-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | net.md-5 14 | bungeecord-slf4j 15 | 1.21-R0.3-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 | 2.0.17 32 | compile 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /slf4j/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider: -------------------------------------------------------------------------------- 1 | org.slf4j.jul.JULServiceProvider --------------------------------------------------------------------------------